diff --git a/assets/headphones.png b/assets/headphonesTemplate@1x.png similarity index 100% rename from assets/headphones.png rename to assets/headphonesTemplate@1x.png diff --git a/assets/headphonesTemplate@2x.png b/assets/headphonesTemplate@2x.png new file mode 100644 index 0000000..5621a52 Binary files /dev/null and b/assets/headphonesTemplate@2x.png differ diff --git a/assets/icon_white.ico b/assets/icon_white.ico new file mode 100644 index 0000000..b59a845 Binary files /dev/null and b/assets/icon_white.ico differ diff --git a/package-lock.json b/package-lock.json index 95dd0e2..3323166 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,8 @@ "license": "MIT", "dependencies": { "arctis-usb-finder": "^0.0.19", - "electron-squirrel-startup": "^1.0.0" + "electron-squirrel-startup": "^1.0.0", + "winreg": "^1.2.4" }, "devDependencies": { "@electron-forge/cli": "^6.1.1", @@ -21,6 +22,7 @@ "@electron-forge/maker-zip": "^6.1.1", "@electron-forge/publisher-github": "^6.1.1", "@types/node-hid": "^1.3.1", + "@types/winreg": "^1.2.32", "@typescript-eslint/eslint-plugin": "^5.59.6", "@typescript-eslint/parser": "^5.59.6", "electron": "^26.1.0", @@ -1189,6 +1191,12 @@ "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", "dev": true }, + "node_modules/@types/winreg": { + "version": "1.2.32", + "resolved": "https://registry.npmjs.org/@types/winreg/-/winreg-1.2.32.tgz", + "integrity": "sha512-+TgocDdajdQVGVDw0XxaOH2rn2YTb8zHqDKdcqj9bHiE0NZaU1KL9StdApF74bNvMx+itYabv9NT6E/iB94N/A==", + "dev": true + }, "node_modules/@types/yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", @@ -7067,6 +7075,11 @@ "string-width": "^1.0.2 || 2 || 3 || 4" } }, + "node_modules/winreg": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.4.tgz", + "integrity": "sha512-IHpzORub7kYlb8A43Iig3reOvlcBJGX9gZ0WycHhghHtA65X0LYnMRuJs+aH1abVnMJztQkvQNlltnbPi5aGIA==" + }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", diff --git a/package.json b/package.json index c225fd0..c0245a7 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "@electron-forge/maker-zip": "^6.1.1", "@electron-forge/publisher-github": "^6.1.1", "@types/node-hid": "^1.3.1", + "@types/winreg": "^1.2.32", "@typescript-eslint/eslint-plugin": "^5.59.6", "@typescript-eslint/parser": "^5.59.6", "electron": "^26.1.0", @@ -37,6 +38,7 @@ }, "dependencies": { "arctis-usb-finder": "^0.0.19", - "electron-squirrel-startup": "^1.0.0" + "electron-squirrel-startup": "^1.0.0", + "winreg": "^1.2.4" } } diff --git a/src/headphone_view.ts b/src/headphone_view.ts index d341fe8..e8cf5f9 100644 --- a/src/headphone_view.ts +++ b/src/headphone_view.ts @@ -17,18 +17,20 @@ function exportView(mainTray: any, headphone: SimpleHeadphone) { mainTray.setToolTip(`${text}`); mainTray.setTitle(` ${percentage}%`); - if (headphone.isCharging) { - text += ' 🔋 '; + if (percentage === 100) { + text += ' \uD83D\uDD0B '; + } else if (headphone.isCharging) { + text += ' \uD83D\uDD0B '; } if (headphone.isDischarging) { - text += ' đŸĒĢ '; + text += ' \uD83E\uDEAB '; } if (headphone.isMuted) { - text += ' 🔇 '; + text += ' \uD83D\uDD07 '; } else { - text += ' 🔊 '; + text += ' \uD83D\uDD0A '; } return new MenuItem({ label: text }); diff --git a/src/main.ts b/src/main.ts index 81129aa..ecbff27 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,11 +1,9 @@ import { app, BrowserWindow } from 'electron'; import createTray from './tray'; -import path = require('path'); - if (require('electron-squirrel-startup')) app.quit(); -let mainWindow: any; +let mainWindow: BrowserWindow; const createWindow = () => { mainWindow = new BrowserWindow({ @@ -30,13 +28,9 @@ const createWindow = () => { // Don't show the app in the doc app.dock?.hide(); -function handleQuit() { - app.quit(); -} - app.whenReady().then(() => { createWindow(); - createTray(path); + createTray(); }); // Quit the app when the window is closed diff --git a/src/tray.ts b/src/tray.ts index 6a49687..21ac08e 100644 --- a/src/tray.ts +++ b/src/tray.ts @@ -1,13 +1,18 @@ +import path = require('path'); + import { Tray, Menu, MenuItem } from 'electron'; import SimpleHeadphone from 'arctis-usb-finder/dist/interfaces/simple_headphone'; +import Host from 'arctis-usb-finder/dist/utils/host'; import exportView from './headphone_view'; import debugMenu from './menu_items/debug'; import helpMenuItem from './menu_items/help'; import quitMenuItem from './menu_items/quit'; import HeadphoneManager from './headphone_manager'; +import HandleThemes from './windows/handle_themes'; +import iconPicker from './windows/icon_picker'; -let mainTray: any; +let mainTray: Tray; const headphoneManager = new HeadphoneManager(); const buildTrayMenu = (force: boolean = false, debug: boolean = false) => { @@ -31,9 +36,24 @@ const buildTrayMenu = (force: boolean = false, debug: boolean = false) => { mainTray.setContextMenu(contextMenu); }; -const createTray = (path: any) => { +const icon = (): string => { const assetsDirectory = path.join(__dirname, '../assets'); - mainTray = new Tray(path.join(assetsDirectory, 'headphones.png')); + + if (Host.isMac()) { + return path.join(assetsDirectory, 'headphonesTemplate.png'); + } else { + return path.join(assetsDirectory, 'headphonesTemplate@2x.png'); + } +}; + +const createTray = async () => { + if (Host.isWin()) { + const handleThemes = new HandleThemes(); + mainTray = new Tray(iconPicker(await handleThemes.isUsedSystemLightTheme())); + handleThemes.tray = mainTray; + } else { + mainTray = new Tray(icon()); + } const contextMenu = Menu.buildFromTemplate([ { label: 'No Headphones USB devices plugged in', type: 'normal' }, diff --git a/src/windows/handle_themes.ts b/src/windows/handle_themes.ts new file mode 100644 index 0000000..08b64bd --- /dev/null +++ b/src/windows/handle_themes.ts @@ -0,0 +1,31 @@ +import { Tray, nativeTheme } from 'electron'; +import Registry = require('winreg'); +import iconPicker from './icon_picker'; + +export default class HandleThemes { + tray: Tray; + + constructor() { + nativeTheme.on('updated', () => this.handleThemeChange()); + } + + async isUsedSystemLightTheme(): Promise { + const reg = new Registry({ + hive: Registry.HKCU, + key: '\\Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize', + }); + return new Promise((resolve) => + reg.get('SystemUsesLightTheme', (err: any, item: { value: string }) => { + if (!err) return resolve(item.value === '0x1'); + resolve(false); + }) + ); + } + + async handleThemeChange() { + const isLightTheme = await this.isUsedSystemLightTheme(); + console.log('in updated', isLightTheme); + + this.tray.setImage(iconPicker(isLightTheme)); + } +} diff --git a/src/windows/icon_picker.ts b/src/windows/icon_picker.ts new file mode 100644 index 0000000..c913538 --- /dev/null +++ b/src/windows/icon_picker.ts @@ -0,0 +1,14 @@ +import path = require('path'); + +const iconPicker = (lightTheme: boolean) => { + const assetsDirectory = path.join(__dirname, '../../assets'); + + console.log('icon', lightTheme); + if (lightTheme) { + return path.join(assetsDirectory, 'icon.ico'); + } else { + return path.join(assetsDirectory, 'icon_white.ico'); + } +}; + +export default iconPicker;