Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: monochrome tray icon #836

Merged
merged 3 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified img/icons/icon-tray-mac.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified img/icons/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/icons/icon-tray-win32-dark.ico
Binary file not shown.
Binary file added img/icons/icon-tray-win32-light.ico
Binary file not shown.
27 changes: 23 additions & 4 deletions scripts/generate-icons.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ async function generateIcons() {
name: 'icon',
sizes: [16, 24, 32, 48, 256],
},
// Linux (PNG)
// Linux + Mac (PNG)
favicon: {
name: 'icon',
pngSizes: [32, 512],
pngSizes: [16, 32, 512],
icoSizes: [],
},
})
Expand All @@ -55,13 +55,32 @@ async function generateIcons() {
},
})

// Tray icon - Windows monochrome
await icongen(originalMacTrayLightPath, outputPath, {
ico: {
name: 'icon-tray-win32-light',
sizes: [16, 24, 32, 48, 256],
},
})
await icongen(originalMacTrayDarkPath, outputPath, {
ico: {
name: 'icon-tray-win32-dark',
sizes: [16, 24, 32, 48, 256],
},
})

// Rename icon512.png -> icon.png
await fs.rename(path.join(outputPath, 'icon512.png'), path.join(outputPath, 'icon.png'))
// Rename icon32.png -> icon-tray-linux.png
await fs.rename(path.join(outputPath, 'icon32.png'), path.join(outputPath, 'icon-tray-linux.png'))
// Rename icon16.png -> icon-tray-mac.png
// Rename icon32.png -> icon-tray-linux.png + [email protected]
await fs.cp(path.join(outputPath, 'icon32.png'), path.join(outputPath, 'icon-tray-linux.png'))
await fs.cp(path.join(outputPath, 'icon16.png'), path.join(outputPath, 'icon-tray-mac.png'))
await fs.cp(path.join(outputPath, 'icon32.png'), path.join(outputPath, '[email protected]'))

// Remove unused favicon
await fs.unlink(path.join(outputPath, 'favicon.ico'))
await fs.unlink(path.join(outputPath, 'icon16.png'))
await fs.unlink(path.join(outputPath, 'icon32.png'))

// Rename icon-tray-mac-(light|dark)16.png -> icon-tray-mac-(light|dark).png, icon-tray-mac-(light|dark)32.png -> icon-tray-mac-(light|dark)@2x.png
await fs.rename(path.join(outputPath, 'icon-tray-mac-light16.png'), path.join(outputPath, 'icon-tray-mac-light.png'))
Expand Down
8 changes: 7 additions & 1 deletion src/app/AppConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { join } from 'node:path'
import { readFile, writeFile } from 'node:fs/promises'
import { app } from 'electron'
import { isLinux } from '../shared/os.utils.js'
import { isLinux, isMac } from '../shared/os.utils.js'

const APP_CONFIG_FILE_NAME = 'config.json'

Expand Down Expand Up @@ -40,6 +40,11 @@ export type AppConfig = {
* Default: true on Linux, false otherwise.
*/
systemTitleBar: boolean
/**
* Whether to use a monochrome tray icon.
* Default: true on macOS, false otherwise.
*/
monochromeTrayIcon: boolean

// ----------------
// Privacy settings
Expand All @@ -60,6 +65,7 @@ export type AppConfig = {
const defaultAppConfig: AppConfig = {
theme: 'default',
systemTitleBar: isLinux(),
monochromeTrayIcon: isMac(),
}

/** Local cache of the config file mixed with the default values */
Expand Down
45 changes: 24 additions & 21 deletions src/shared/icons.utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
*/

const { app, nativeTheme } = require('electron')
const { isLinux } = require('./os.utils.js')
const { isLinux, getPlatform } = require('./os.utils.js')
const path = require('path')
const { getAppConfig } = require('../app/AppConfig.ts')

const icons = {
// Executable's icon is used by default
Expand All @@ -15,38 +16,40 @@ const icons = {

tray: {
darwin: {
default: require('../../img/icons/icon-tray-mac.png'),
light: require('../../img/icons/icon-tray-mac-light.png'),
dark: require('../../img/icons/icon-tray-mac-dark.png'),
// These properties are not used, but the import is required to add the icon to the bundle
// It will be used by electron internally
default2x: require('../../img/icons/[email protected]'),
light2x: require('../../img/icons/[email protected]'),
dark2x: require('../../img/icons/[email protected]'),
},

// This property is not used, but import is required to add the icon to the bundle.
// It will be used by electron internally
darwin_x2: {
win32: {
default: require('../../img/icons/icon.ico'),
light: require('../../img/icons/icon-tray-win32-light.ico'),
dark: require('../../img/icons/icon-tray-win32-dark.ico'),
},

linux: {
default: require('../../img/icons/icon-tray-linux.png'),
light: require('../../img/icons/[email protected]'),
dark: require('../../img/icons/[email protected]'),
},

win32: require('../../img/icons/icon.ico'),

linux: require('../../img/icons/icon-tray-linux.png'),
},
}

/**
* Get tray icon for the given platform
*
* @param {'darwin'|'win32'|'cygwin'|string} [platform] platform otherwise current process.platform is used
* @param {'light'|'dark'} [theme] theme for the darwin platform
* Get tray icon
*/
function getTrayIcon(platform, theme) {
switch (platform ?? process.platform) {
case 'darwin':
return nativeTheme.shouldUseDarkColors || theme === 'dark' ? icons.tray.darwin.dark : icons.tray.darwin.light
case 'win32':
return icons.tray.win32
default:
return icons.tray.linux
}
function getTrayIcon() {
const platform = getPlatform()
const monochrome = getAppConfig('monochromeTrayIcon')
const theme = nativeTheme.shouldUseDarkColors ? 'dark' : 'light'
const kind = monochrome ? theme : 'default'

return icons.tray[platform][kind]
}

/**
Expand Down
13 changes: 13 additions & 0 deletions src/shared/os.utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@

const os = require('os')

/**
* Get "process.platform", but with simplified to 'win32'|'darwin'|'linux'
* @return {'win32'|'darwin'|'linux'} platform
*/
function getPlatform() {
return (process.platform === 'win32' && 'win32')
|| (process.platform === 'darwin' && 'darwin')
|| 'linux'
}

/**
* Returns a string representing OS version
*
Expand Down Expand Up @@ -76,6 +86,7 @@ function isWayland() {
* @property {boolean} isWindows - Is Windows?
* @property {boolean} isWayland - Is Linux with Wayland window communication protocol?
* @property {string} version - Full string representation of OS version
* @property {string} platform - Simplified platform name
*/

/**
Expand All @@ -90,10 +101,12 @@ function getOs() {
isWindows: isWindows(),
isWayland: isWayland(),
version: getOsVersion(),
platform: getPlatform(),
}
}

module.exports = {
getPlatform,
getOsVersion,
getOsTitle,
isLinux,
Expand Down
5 changes: 5 additions & 0 deletions src/talk/renderer/Settings/DesktopSettingsSection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const themeOptions = [
const themeOption = useNcSelectModel(theme, themeOptions)

const systemTitleBar = useAppConfigValue('systemTitleBar')
const monochromeTrayIcon = useAppConfigValue('monochromeTrayIcon')

/**
* Restart the app
Expand Down Expand Up @@ -58,6 +59,10 @@ function relaunch() {
{{ t('talk_desktop', 'Theme') }}
</SettingsSelect>

<NcCheckboxRadioSwitch :checked.sync="monochromeTrayIcon" type="switch">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requires a restart for me to take effect

Copy link
Contributor Author

@ShGKme ShGKme Oct 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be good now, you can merge)

{{ t('talk_desktop', 'Use monochrome tray icon') }}
</NcCheckboxRadioSwitch>

<NcCheckboxRadioSwitch :checked.sync="systemTitleBar" type="switch">
{{ t('talk_desktop', 'Use system title bar') }}
</NcCheckboxRadioSwitch>
Expand Down
2 changes: 1 addition & 1 deletion src/talk/renderer/Settings/appConfig.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { applyBodyThemeAttrs } from '../../../shared/theme.utils.js'
export const useAppConfig = defineStore('appConfig', () => {
const appConfig: Ref<AppConfig> = ref(getAppConfig())
const isRelaunchRequired = ref(false)
const relaunchRequiredConfigs = ['systemTitleBar'] as const
const relaunchRequiredConfigs = ['systemTitleBar', 'monochromeTrayIcon'] as const

const unwatchRelaunch = watch(
() => relaunchRequiredConfigs.map((key) => appConfig.value[key]),
Expand Down
10 changes: 7 additions & 3 deletions src/talk/talk.window.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

const { BrowserWindow, screen } = require('electron')
const { BrowserWindow, screen, nativeTheme } = require('electron')
const { applyExternalLinkHandler } = require('../app/externalLinkHandlers.js')
const { applyContextMenu } = require('../app/applyContextMenu.js')
const { applyDownloadNotification } = require('../app/applyDownloadNotification.js')
const { applyWheelZoom } = require('../app/applyWheelZoom.js')
const { setupTray } = require('../app/app.tray.js')
const { getBrowserWindowIcon } = require('../shared/icons.utils.js')
const { getBrowserWindowIcon, getTrayIcon } = require('../shared/icons.utils.js')
const { TITLE_BAR_HEIGHT } = require('../constants.js')
const { getAppConfig } = require('../app/AppConfig.ts')

Expand Down Expand Up @@ -65,7 +65,11 @@ function createTalkWindow() {
applyContextMenu(window)
applyDownloadNotification(window)
applyWheelZoom(window)
setupTray(window)

const tray = setupTray(window)
nativeTheme.on('updated', () => {
tray.setImage(getTrayIcon())
})

window.loadURL(TALK_WINDOW_WEBPACK_ENTRY)

Expand Down