1use ksni::TrayMethods;
9use tokio::sync::watch;
10
11#[derive(Debug)]
13pub struct MimickTray {
14 pub settings_tx: watch::Sender<bool>,
17 pub library_tx: watch::Sender<bool>,
19 pub quit_tx: watch::Sender<bool>,
21 pub pause_tx: watch::Sender<bool>,
23 pub sync_now_tx: watch::Sender<bool>,
25 pub library_view_enabled: bool,
27}
28
29impl ksni::Tray for MimickTray {
30 fn id(&self) -> String {
31 "mimick_tray".to_string()
32 }
33
34 fn icon_name(&self) -> String {
35 "dev.nicx.mimick".to_string()
36 }
37
38 fn title(&self) -> String {
39 "Mimick Sync".into()
40 }
41
42 fn menu(&self) -> Vec<ksni::MenuItem<Self>> {
43 use ksni::menu::*;
44 let library_enabled = self.library_view_enabled;
45 let mut items: Vec<ksni::MenuItem<Self>> = Vec::new();
46 if library_enabled {
47 items.push(
48 StandardItem {
49 label: "Library".into(),
50 activate: Box::new(|tray: &mut Self| {
51 let _ = tray.library_tx.send(true);
52 }),
53 ..Default::default()
54 }
55 .into(),
56 );
57 }
58 items.extend(vec![
59 StandardItem {
60 label: "Settings".into(),
61 activate: Box::new(|tray: &mut Self| {
62 let _ = tray.settings_tx.send(true);
64 }),
65 ..Default::default()
66 }
67 .into(),
68 StandardItem {
69 label: "Pause / Resume".into(),
70 activate: Box::new(|tray: &mut Self| {
71 let _ = tray.pause_tx.send(true);
72 }),
73 ..Default::default()
74 }
75 .into(),
76 StandardItem {
77 label: "Sync Now".into(),
78 activate: Box::new(|tray: &mut Self| {
79 let _ = tray.sync_now_tx.send(true);
80 }),
81 ..Default::default()
82 }
83 .into(),
84 MenuItem::Separator,
85 StandardItem {
86 label: "Quit".into(),
87 activate: Box::new(|tray: &mut Self| {
88 let _ = tray.quit_tx.send(true);
89 }),
90 ..Default::default()
91 }
92 .into(),
93 ]);
94 items
95 }
96}
97
98pub struct TrayHandles {
100 pub handle: ksni::Handle<MimickTray>,
102 pub settings_rx: watch::Receiver<bool>,
104 pub library_rx: watch::Receiver<bool>,
106 pub quit_rx: watch::Receiver<bool>,
108 pub pause_rx: watch::Receiver<bool>,
110 pub sync_now_rx: watch::Receiver<bool>,
112}
113
114pub async fn build_tray(library_view_enabled: bool) -> Result<TrayHandles, ksni::Error> {
116 let (settings_tx, settings_rx) = watch::channel(false);
117 let (library_tx, library_rx) = watch::channel(false);
118 let (quit_tx, quit_rx) = watch::channel(false);
119 let (pause_tx, pause_rx) = watch::channel(false);
120 let (sync_now_tx, sync_now_rx) = watch::channel(false);
121 let tray = MimickTray {
122 settings_tx,
123 library_tx,
124 quit_tx,
125 pause_tx,
126 sync_now_tx,
127 library_view_enabled,
128 };
129 let handle = if ashpd::is_sandboxed() {
130 tray.disable_dbus_name(true).spawn().await?
133 } else {
134 tray.spawn().await?
135 };
136 Ok(TrayHandles {
137 handle,
138 settings_rx,
139 library_rx,
140 quit_rx,
141 pause_rx,
142 sync_now_rx,
143 })
144}