aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/Tray.js
diff options
context:
space:
mode:
authorLibravatar muhamedsalih-tw <104364298+muhamedsalih-tw@users.noreply.github.com>2022-11-06 10:36:51 +0530
committerLibravatar GitHub <noreply@github.com>2022-11-06 05:06:51 +0000
commite7dbea5bc6d7e6b121dbc94b21b759a29f16e0c0 (patch)
tree958d6dad84687352af27c19c50bdcac345bc3a79 /src/lib/Tray.js
parent6.2.1-nightly.39 [skip ci] (diff)
downloadferdium-app-e7dbea5bc6d7e6b121dbc94b21b759a29f16e0c0.tar.gz
ferdium-app-e7dbea5bc6d7e6b121dbc94b21b759a29f16e0c0.tar.zst
ferdium-app-e7dbea5bc6d7e6b121dbc94b21b759a29f16e0c0.zip
Transform tray & menu files to typescript (#740)
Diffstat (limited to 'src/lib/Tray.js')
-rw-r--r--src/lib/Tray.js251
1 files changed, 0 insertions, 251 deletions
diff --git a/src/lib/Tray.js b/src/lib/Tray.js
deleted file mode 100644
index fffdec64d..000000000
--- a/src/lib/Tray.js
+++ /dev/null
@@ -1,251 +0,0 @@
1import {
2 app,
3 Menu,
4 nativeImage,
5 nativeTheme,
6 systemPreferences,
7 Tray,
8 ipcMain,
9 BrowserWindow,
10} from 'electron';
11import { join } from 'path';
12import macosVersion from 'macos-version';
13import { isMac, isWindows, isLinux } from '../environment';
14
15const FILE_EXTENSION = isWindows ? 'ico' : 'png';
16const INDICATOR_TRAY_PLAIN = 'tray';
17const INDICATOR_TRAY_UNREAD = 'tray-unread';
18const INDICATOR_TRAY_INDIRECT = 'tray-indirect';
19
20// TODO: Need to support i18n for a lot of the hard-coded strings in this file
21export default class TrayIcon {
22 trayIcon = null;
23
24 indicator = 0;
25
26 themeChangeSubscriberId = null;
27
28 trayMenu = null;
29
30 visible = false;
31
32 isAppMuted = false;
33
34 mainWindow = null;
35
36 trayMenuTemplate = tray => [
37 {
38 label:
39 tray.mainWindow.isVisible() && tray.mainWindow.isFocused()
40 ? 'Hide Ferdium'
41 : 'Show Ferdium',
42 click() {
43 tray._toggleWindow();
44 },
45 },
46 {
47 label: tray.isAppMuted
48 ? 'Enable Notifications && Audio'
49 : 'Disable Notifications && Audio',
50 click() {
51 if (!tray.mainWindow) return;
52 tray.mainWindow.webContents.send('muteApp');
53 },
54 },
55 {
56 label: 'Quit Ferdium',
57 click() {
58 app.quit();
59 },
60 },
61 ];
62
63 constructor() {
64 ipcMain.on('initialAppSettings', (event, appSettings) => {
65 this._updateTrayMenu(appSettings);
66 });
67 ipcMain.on('updateAppSettings', (event, appSettings) => {
68 this._updateTrayMenu(appSettings);
69 });
70
71 this.mainWindow = BrowserWindow.getAllWindows()[0];
72
73 // listen to window events to be able to set correct string
74 // to tray menu ('Hide Ferdium' / 'Show Ferdium')
75 this.mainWindow.on('hide', () => {
76 this._updateTrayMenu(null);
77 });
78 this.mainWindow.on('restore', () => {
79 this._updateTrayMenu(null);
80 });
81 this.mainWindow.on('minimize', () => {
82 this._updateTrayMenu(null);
83 });
84 this.mainWindow.on('show', () => {
85 this._updateTrayMenu(null);
86 });
87 this.mainWindow.on('focus', () => {
88 this._updateTrayMenu(null);
89 });
90 this.mainWindow.on('blur', () => {
91 this._updateTrayMenu(null);
92 });
93 }
94
95 _updateTrayMenu(appSettings) {
96 if (!this.trayIcon) return;
97
98 if (appSettings && appSettings.type === 'app') {
99 this.isAppMuted = appSettings.data.isAppMuted; // save current state after a change
100 }
101
102 this.trayMenu = Menu.buildFromTemplate(this.trayMenuTemplate(this));
103 if (isLinux) {
104 this.trayIcon.setContextMenu(this.trayMenu);
105 }
106 }
107
108 show() {
109 this.visible = true;
110 this._show();
111 }
112
113 _show() {
114 if (this.trayIcon) return;
115
116 this.trayIcon = new Tray(this._getAsset('tray', INDICATOR_TRAY_PLAIN));
117 this.trayIcon.setToolTip('Ferdium');
118
119 this.trayMenu = Menu.buildFromTemplate(this.trayMenuTemplate(this));
120 if (isLinux) {
121 this.trayIcon.setContextMenu(this.trayMenu);
122 }
123
124 this.trayIcon.on('click', () => {
125 this._toggleWindow();
126 });
127
128 if (isMac || isWindows) {
129 this.trayIcon.on('right-click', () => {
130 this.trayIcon.popUpContextMenu(this.trayMenu);
131 });
132 }
133
134 if (isMac) {
135 this.themeChangeSubscriberId = systemPreferences.subscribeNotification(
136 'AppleInterfaceThemeChangedNotification',
137 () => {
138 this._refreshIcon();
139 },
140 );
141 }
142 }
143
144 _toggleWindow() {
145 const mainWindow = BrowserWindow.getAllWindows()[0];
146 if (!mainWindow) return;
147
148 if (mainWindow.isMinimized()) {
149 mainWindow.restore();
150 } else if (mainWindow.isVisible() && mainWindow.isFocused()) {
151 if (isMac && mainWindow.isFullScreen()) {
152 mainWindow.once('show', () => mainWindow?.setFullScreen(true));
153 mainWindow.once('leave-full-screen', () => mainWindow?.hide());
154 mainWindow.setFullScreen(false);
155 } else {
156 mainWindow.hide();
157 }
158 } else {
159 mainWindow.show();
160 mainWindow.focus();
161 }
162 }
163
164 hide() {
165 this.visible = false;
166 this._hide();
167 }
168
169 _hide() {
170 if (!this.trayIcon) return;
171
172 this.trayIcon.destroy();
173 this.trayIcon = null;
174
175 if (isMac && this.themeChangeSubscriberId) {
176 systemPreferences.unsubscribeNotification(this.themeChangeSubscriberId);
177 this.themeChangeSubscriberId = null;
178 }
179 }
180
181 recreateIfVisible() {
182 if (this.visible) {
183 this._hide();
184 setTimeout(() => {
185 if (this.visible) {
186 this._show();
187 }
188 }, 100);
189 }
190 }
191
192 setIndicator(indicator) {
193 this.indicator = indicator;
194 this._refreshIcon();
195 }
196
197 _getAssetFromIndicator(indicator) {
198 if (indicator === '•') {
199 return INDICATOR_TRAY_INDIRECT;
200 }
201 if (indicator !== 0) {
202 return INDICATOR_TRAY_UNREAD;
203 }
204 return INDICATOR_TRAY_PLAIN;
205 }
206
207 _refreshIcon() {
208 if (!this.trayIcon) return;
209
210 this.trayIcon.setImage(
211 this._getAsset('tray', this._getAssetFromIndicator(this.indicator)),
212 );
213
214 if (isMac && !macosVersion.isGreaterThanOrEqualTo('11')) {
215 this.trayIcon.setPressedImage(
216 this._getAsset(
217 'tray',
218 `${this._getAssetFromIndicator(this.indicator)}-active`,
219 ),
220 );
221 }
222 }
223
224 _getAsset(type, asset) {
225 let { platform } = process;
226
227 if (isMac && macosVersion.isGreaterThanOrEqualTo('11')) {
228 platform = `${platform}-20`;
229 } else if (isMac && nativeTheme.shouldUseDarkColors) {
230 platform = `${platform}-dark`;
231 }
232
233 const trayImg = nativeImage.createFromPath(
234 join(
235 __dirname,
236 '..',
237 'assets',
238 'images',
239 type,
240 platform,
241 `${asset}.${FILE_EXTENSION}`,
242 ),
243 );
244
245 if (isMac && macosVersion.isGreaterThanOrEqualTo('11')) {
246 trayImg.setTemplateImage(true);
247 }
248
249 return trayImg;
250 }
251}