design: implement dynamic theme-based app icons for system tray and taskbar
This commit is contained in:
4
frontend/assets-build/icons/latte.svg
Normal file
4
frontend/assets-build/icons/latte.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="512" height="512" rx="64" fill="#EFF1F5"/>
|
||||
<path d="M256 64C150.13 64 64 150.13 64 256C64 361.87 150.13 448 256 448C361.87 448 448 361.87 448 256C448 150.13 375.73 64 256 64ZM256 405.33C173.6 405.33 106.67 338.4 106.67 256C106.67 221.33 118.4 189.33 138.13 164.27L347.73 373.87C322.67 393.6 290.67 405.33 256 405.33ZM373.87 347.73L164.27 138.13C189.33 118.4 221.33 106.67 256 106.67C338.4 106.67 405.33 173.6 405.33 256C405.33 290.67 393.6 322.67 373.87 347.73Z" fill="#1E66F5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 603 B |
4
frontend/assets-build/icons/mocha.svg
Normal file
4
frontend/assets-build/icons/mocha.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="512" height="512" rx="64" fill="#1E1E2E"/>
|
||||
<path d="M256 64C150.13 64 64 150.13 64 256C64 361.87 150.13 448 256 448C361.87 448 448 361.87 448 256C448 150.13 375.73 64 256 64ZM256 405.33C173.6 405.33 106.67 338.4 106.67 256C106.67 221.33 118.4 189.33 138.13 164.27L347.73 373.87C322.67 393.6 290.67 405.33 256 405.33ZM373.87 347.73L164.27 138.13C189.33 118.4 221.33 106.67 256 106.67C338.4 106.67 405.33 173.6 405.33 256C405.33 290.67 393.6 322.67 373.87 347.73Z" fill="#B4BEFE"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 603 B |
4
frontend/assets-build/icons/nord.svg
Normal file
4
frontend/assets-build/icons/nord.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="512" height="512" rx="64" fill="#2E3440"/>
|
||||
<path d="M256 64C150.13 64 64 150.13 64 256C64 361.87 150.13 448 256 448C361.87 448 448 361.87 448 256C448 150.13 375.73 64 256 64ZM256 405.33C173.6 405.33 106.67 338.4 106.67 256C106.67 221.33 118.4 189.33 138.13 164.27L347.73 373.87C322.67 393.6 290.67 405.33 256 405.33ZM373.87 347.73L164.27 138.13C189.33 118.4 221.33 106.67 256 106.67C338.4 106.67 405.33 173.6 405.33 256C405.33 290.67 393.6 322.67 373.87 347.73Z" fill="#88C0D0"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 603 B |
4
frontend/assets-build/icons/steam.svg
Normal file
4
frontend/assets-build/icons/steam.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="512" height="512" rx="64" fill="#171A21"/>
|
||||
<path d="M256 64C150.13 64 64 150.13 64 256C64 361.87 150.13 448 256 448C361.87 448 448 361.87 448 256C448 150.13 375.73 64 256 64ZM256 405.33C173.6 405.33 106.67 338.4 106.67 256C106.67 221.33 118.4 189.33 138.13 164.27L347.73 373.87C322.67 393.6 290.67 405.33 256 405.33ZM373.87 347.73L164.27 138.13C189.33 118.4 221.33 106.67 256 106.67C338.4 106.67 405.33 173.6 405.33 256C405.33 290.67 393.6 322.67 373.87 347.73Z" fill="#66C0F4"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 603 B |
4
frontend/assets-build/icons/tokyo.svg
Normal file
4
frontend/assets-build/icons/tokyo.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="512" height="512" rx="64" fill="#1A1B26"/>
|
||||
<path d="M256 64C150.13 64 64 150.13 64 256C64 361.87 150.13 448 256 448C361.87 448 448 361.87 448 256C448 150.13 375.73 64 256 64ZM256 405.33C173.6 405.33 106.67 338.4 106.67 256C106.67 221.33 118.4 189.33 138.13 164.27L347.73 373.87C322.67 393.6 290.67 405.33 256 405.33ZM373.87 347.73L164.27 138.13C189.33 118.4 221.33 106.67 256 106.67C338.4 106.67 405.33 173.6 405.33 256C405.33 290.67 393.6 322.67 373.87 347.73Z" fill="#7AA2F7"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 603 B |
@@ -135,7 +135,14 @@ const createTray = () => {
|
||||
tray = new Tray(icon);
|
||||
tray.setToolTip('Ultimate Ban Tracker');
|
||||
tray.on('click', () => { if (mainWindow) { mainWindow.show(); mainWindow.focus(); } });
|
||||
updateTrayMenu();
|
||||
|
||||
// Load initial themed icon
|
||||
const config = store.get('serverConfig');
|
||||
if (config?.theme) {
|
||||
setAppIcon(config.theme);
|
||||
} else {
|
||||
updateTrayMenu(); // Fallback to refresh menu
|
||||
}
|
||||
} catch (e) { }
|
||||
};
|
||||
|
||||
@@ -162,6 +169,25 @@ const updateTrayMenu = () => {
|
||||
tray.setContextMenu(contextMenu);
|
||||
};
|
||||
|
||||
const setAppIcon = (themeName: string = 'steam') => {
|
||||
const assetsDir = path.join(__dirname, '..', 'assets-build', 'icons');
|
||||
const iconPath = path.join(assetsDir, `${themeName}.svg`);
|
||||
|
||||
if (!fs.existsSync(iconPath)) return;
|
||||
|
||||
const icon = nativeImage.createFromPath(iconPath);
|
||||
|
||||
// Update Tray
|
||||
if (tray) {
|
||||
tray.setImage(icon.resize({ width: 16, height: 16 }));
|
||||
}
|
||||
|
||||
// Update Main Window
|
||||
if (mainWindow) {
|
||||
mainWindow.setIcon(icon);
|
||||
}
|
||||
};
|
||||
|
||||
// --- Steam Logic ---
|
||||
const killSteam = async () => {
|
||||
return new Promise<void>((resolve) => {
|
||||
@@ -571,6 +597,13 @@ ipcMain.handle('admin-delete-user', async (event, userId: string) => { initBacke
|
||||
ipcMain.handle('admin-get-accounts', async () => { initBackend(); return backend ? await backend.getAdminAccounts() : []; });
|
||||
ipcMain.handle('admin-remove-account', async (event, steamId: string) => { initBackend(); if (backend) await backend.forceRemoveAccount(steamId); return true; });
|
||||
|
||||
ipcMain.handle('force-sync', async () => { await syncAccounts(true); return true; });
|
||||
|
||||
ipcMain.handle('update-app-icon', (event, themeName: string) => {
|
||||
setAppIcon(themeName);
|
||||
return true;
|
||||
});
|
||||
|
||||
ipcMain.handle('switch-account', async (event, loginName: string) => {
|
||||
if (!loginName) return false;
|
||||
try {
|
||||
|
||||
@@ -10,6 +10,7 @@ contextBridge.exposeInMainWorld('electronAPI', {
|
||||
revokeAccountAccess: (steamId: string, targetSteamId: string) => ipcRenderer.invoke('revoke-account-access', steamId, targetSteamId),
|
||||
revokeAllAccountAccess: (steamId: string) => ipcRenderer.invoke('revoke-all-account-access', steamId),
|
||||
openExternal: (url: string) => ipcRenderer.invoke('open-external', url),
|
||||
updateAppIcon: (theme: string) => ipcRenderer.invoke('update-app-icon', theme),
|
||||
openSteamAppLogin: () => ipcRenderer.invoke('open-steam-app-login'),
|
||||
openSteamLogin: (steamId: string) => ipcRenderer.invoke('open-steam-login', steamId),
|
||||
|
||||
|
||||
@@ -31,8 +31,18 @@ export const AppThemeProvider: React.FC<{ children: React.ReactNode }> = ({ chil
|
||||
if (api?.updateServerConfig) {
|
||||
await api.updateServerConfig({ theme });
|
||||
}
|
||||
if (api?.updateAppIcon) {
|
||||
await api.updateAppIcon(theme);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const api = (window as any).electronAPI;
|
||||
if (api?.updateAppIcon && currentTheme) {
|
||||
api.updateAppIcon(currentTheme);
|
||||
}
|
||||
}, [currentTheme]);
|
||||
|
||||
const theme = useMemo(() => getTheme(currentTheme), [currentTheme]);
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user