mirror of
https://github.com/jeffvli/feishin.git
synced 2024-11-20 06:27:09 +01:00
Add tray settings (#49)
This commit is contained in:
parent
eecbcddea3
commit
2b1c1d5e59
BIN
assets/pause-circle.png
Normal file
BIN
assets/pause-circle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 896 B |
BIN
assets/play-circle.png
Normal file
BIN
assets/play-circle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 971 B |
BIN
assets/skip-next.png
Normal file
BIN
assets/skip-next.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 479 B |
BIN
assets/skip-previous.png
Normal file
BIN
assets/skip-previous.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 524 B |
163
src/main/main.ts
163
src/main/main.ts
@ -9,7 +9,16 @@
|
||||
* `./src/main.js` using webpack. This gives us some performance wins.
|
||||
*/
|
||||
import path from 'path';
|
||||
import { app, BrowserWindow, shell, ipcMain, globalShortcut } from 'electron';
|
||||
import {
|
||||
app,
|
||||
BrowserWindow,
|
||||
shell,
|
||||
ipcMain,
|
||||
globalShortcut,
|
||||
Tray,
|
||||
Menu,
|
||||
nativeImage,
|
||||
} from 'electron';
|
||||
import electronLocalShortcut from 'electron-localshortcut';
|
||||
import log from 'electron-log';
|
||||
import { autoUpdater } from 'electron-updater';
|
||||
@ -18,7 +27,7 @@ import MpvAPI from 'node-mpv';
|
||||
import { disableMediaKeys, enableMediaKeys } from './features/core/player/media-keys';
|
||||
import { store } from './features/core/settings/index';
|
||||
import MenuBuilder from './menu';
|
||||
import { resolveHtmlPath } from './utils';
|
||||
import { isLinux, isMacOS, isWindows, resolveHtmlPath } from './utils';
|
||||
import './features';
|
||||
|
||||
declare module 'node-mpv';
|
||||
@ -36,6 +45,9 @@ if (store.get('ignore_ssl')) {
|
||||
}
|
||||
|
||||
let mainWindow: BrowserWindow | null = null;
|
||||
let tray: Tray | null = null;
|
||||
let exitFromTray = false;
|
||||
let forceQuit = false;
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
const sourceMapSupport = require('source-map-support');
|
||||
@ -67,19 +79,105 @@ if (!singleInstance) {
|
||||
app.quit();
|
||||
}
|
||||
|
||||
const RESOURCES_PATH = app.isPackaged
|
||||
? path.join(process.resourcesPath, 'assets')
|
||||
: path.join(__dirname, '../../assets');
|
||||
|
||||
const getAssetPath = (...paths: string[]): string => {
|
||||
return path.join(RESOURCES_PATH, ...paths);
|
||||
};
|
||||
|
||||
export const getMainWindow = () => {
|
||||
return mainWindow;
|
||||
};
|
||||
|
||||
const createWinThumbarButtons = () => {
|
||||
if (isWindows()) {
|
||||
console.log('setting buttons');
|
||||
getMainWindow()?.setThumbarButtons([
|
||||
{
|
||||
click: () => getMainWindow()?.webContents.send('renderer-player-previous'),
|
||||
icon: nativeImage.createFromPath(getAssetPath('skip-previous.png')),
|
||||
tooltip: 'Previous Track',
|
||||
},
|
||||
{
|
||||
click: () => getMainWindow()?.webContents.send('renderer-player-play-pause'),
|
||||
icon: nativeImage.createFromPath(getAssetPath('play-circle.png')),
|
||||
tooltip: 'Play/Pause',
|
||||
},
|
||||
{
|
||||
click: () => getMainWindow()?.webContents.send('renderer-player-next'),
|
||||
icon: nativeImage.createFromPath(getAssetPath('skip-next.png')),
|
||||
tooltip: 'Next Track',
|
||||
},
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
const createTray = () => {
|
||||
if (isMacOS()) {
|
||||
return;
|
||||
}
|
||||
|
||||
tray = isLinux() ? new Tray(getAssetPath('icon.png')) : new Tray(getAssetPath('icon.ico'));
|
||||
const contextMenu = Menu.buildFromTemplate([
|
||||
{
|
||||
click: () => {
|
||||
getMainWindow()?.webContents.send('renderer-player-play-pause');
|
||||
},
|
||||
label: 'Play/Pause',
|
||||
},
|
||||
{
|
||||
click: () => {
|
||||
getMainWindow()?.webContents.send('renderer-player-next');
|
||||
},
|
||||
label: 'Next Track',
|
||||
},
|
||||
{
|
||||
click: () => {
|
||||
getMainWindow()?.webContents.send('renderer-player-previous');
|
||||
},
|
||||
label: 'Previous Track',
|
||||
},
|
||||
{
|
||||
click: () => {
|
||||
getMainWindow()?.webContents.send('renderer-player-stop');
|
||||
},
|
||||
label: 'Stop',
|
||||
},
|
||||
{
|
||||
type: 'separator',
|
||||
},
|
||||
{
|
||||
click: () => {
|
||||
mainWindow?.show();
|
||||
createWinThumbarButtons();
|
||||
},
|
||||
label: 'Open main window',
|
||||
},
|
||||
{
|
||||
click: () => {
|
||||
exitFromTray = true;
|
||||
app.quit();
|
||||
},
|
||||
label: 'Quit',
|
||||
},
|
||||
]);
|
||||
|
||||
tray.on('double-click', () => {
|
||||
mainWindow?.show();
|
||||
createWinThumbarButtons();
|
||||
});
|
||||
|
||||
tray.setToolTip('Feishin');
|
||||
tray.setContextMenu(contextMenu);
|
||||
};
|
||||
|
||||
const createWindow = async () => {
|
||||
if (isDevelopment) {
|
||||
await installExtensions();
|
||||
}
|
||||
|
||||
const RESOURCES_PATH = app.isPackaged
|
||||
? path.join(process.resourcesPath, 'assets')
|
||||
: path.join(__dirname, '../../assets');
|
||||
|
||||
const getAssetPath = (...paths: string[]): string => {
|
||||
return path.join(RESOURCES_PATH, ...paths);
|
||||
};
|
||||
|
||||
mainWindow = new BrowserWindow({
|
||||
frame: false,
|
||||
height: 900,
|
||||
@ -153,14 +251,41 @@ const createWindow = async () => {
|
||||
mainWindow.minimize();
|
||||
} else {
|
||||
mainWindow.show();
|
||||
createWinThumbarButtons();
|
||||
}
|
||||
});
|
||||
|
||||
mainWindow.on('closed', () => {
|
||||
// mainWindow?.webContents.send('renderer-player-quit');
|
||||
mainWindow = null;
|
||||
});
|
||||
|
||||
mainWindow.on('close', (event) => {
|
||||
if (!exitFromTray && store.get('window_exit_to_tray')) {
|
||||
if (isMacOS() && !forceQuit) {
|
||||
exitFromTray = true;
|
||||
}
|
||||
event.preventDefault();
|
||||
mainWindow?.hide();
|
||||
}
|
||||
});
|
||||
|
||||
mainWindow.on('minimize', (event: any) => {
|
||||
if (store.get('window_minimize_to_tray') === true) {
|
||||
event.preventDefault();
|
||||
mainWindow?.hide();
|
||||
}
|
||||
});
|
||||
|
||||
if (isWindows()) {
|
||||
app.setAppUserModelId(process.execPath);
|
||||
}
|
||||
|
||||
if (isMacOS()) {
|
||||
app.on('before-quit', () => {
|
||||
forceQuit = true;
|
||||
});
|
||||
}
|
||||
|
||||
const menuBuilder = new MenuBuilder(mainWindow);
|
||||
menuBuilder.buildMenu();
|
||||
|
||||
@ -175,16 +300,8 @@ const createWindow = async () => {
|
||||
new AppUpdater();
|
||||
};
|
||||
|
||||
/**
|
||||
* Add event listeners...
|
||||
*/
|
||||
|
||||
app.commandLine.appendSwitch('disable-features', 'HardwareMediaKeyHandling,MediaSessionService');
|
||||
|
||||
export const getMainWindow = () => {
|
||||
return mainWindow;
|
||||
};
|
||||
|
||||
const MPV_BINARY_PATH = store.get('mpv_path') as string | undefined;
|
||||
const MPV_PARAMETERS = store.get('mpv_parameters') as Array<string> | undefined;
|
||||
|
||||
@ -267,11 +384,10 @@ app.on('window-all-closed', () => {
|
||||
|
||||
// Respect the OSX convention of having the application in memory even
|
||||
// after all windows have been closed
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit();
|
||||
} else {
|
||||
mpv.stop();
|
||||
if (isMacOS()) {
|
||||
mainWindow = null;
|
||||
} else {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
|
||||
@ -279,6 +395,7 @@ app
|
||||
.whenReady()
|
||||
.then(() => {
|
||||
createWindow();
|
||||
createTray();
|
||||
app.on('activate', () => {
|
||||
// On macOS it's common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { lazy } from 'react';
|
||||
import { Tabs } from '/@/renderer/components';
|
||||
import { useSettingsStore, useSettingsStoreActions } from '/@/renderer/store/settings.store';
|
||||
import isElectron from 'is-electron';
|
||||
import styled from 'styled-components';
|
||||
|
||||
const GeneralTab = lazy(() =>
|
||||
@ -44,7 +45,7 @@ export const SettingsContent = () => {
|
||||
<Tabs.List>
|
||||
<Tabs.Tab value="general">General</Tabs.Tab>
|
||||
<Tabs.Tab value="playback">Playback</Tabs.Tab>
|
||||
<Tabs.Tab value="window">Window</Tabs.Tab>
|
||||
{isElectron() && <Tabs.Tab value="window">Window</Tabs.Tab>}
|
||||
</Tabs.List>
|
||||
<Tabs.Panel value="general">
|
||||
<GeneralTab />
|
||||
@ -52,9 +53,11 @@ export const SettingsContent = () => {
|
||||
<Tabs.Panel value="playback">
|
||||
<PlaybackTab />
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel value="window">
|
||||
<ApplicationTab />
|
||||
</Tabs.Panel>
|
||||
{isElectron() && (
|
||||
<Tabs.Panel value="window">
|
||||
<ApplicationTab />
|
||||
</Tabs.Panel>
|
||||
)}
|
||||
</Tabs>
|
||||
</TabContainer>
|
||||
);
|
||||
|
@ -5,7 +5,7 @@ import {
|
||||
SettingsSection,
|
||||
SettingOption,
|
||||
} from '/@/renderer/features/settings/components/settings-section';
|
||||
import { Select } from '/@/renderer/components';
|
||||
import { Select, Switch } from '/@/renderer/components';
|
||||
|
||||
const WINDOW_BAR_OPTIONS = [
|
||||
{ label: 'Web (hidden)', value: Platform.WEB },
|
||||
@ -13,6 +13,8 @@ const WINDOW_BAR_OPTIONS = [
|
||||
{ label: 'macOS', value: Platform.MACOS },
|
||||
];
|
||||
|
||||
const localSettings = isElectron() ? window.electron.localSettings : null;
|
||||
|
||||
export const WindowSettings = () => {
|
||||
const settings = useWindowSettings();
|
||||
const { setSettings } = useSettingsStoreActions();
|
||||
@ -39,6 +41,50 @@ export const WindowSettings = () => {
|
||||
isHidden: !isElectron(),
|
||||
title: 'Window bar style',
|
||||
},
|
||||
{
|
||||
control: (
|
||||
<Switch
|
||||
aria-label="Toggle minimize to tray"
|
||||
defaultChecked={settings.exitToTray}
|
||||
disabled={!isElectron()}
|
||||
onChange={(e) => {
|
||||
if (!e) return;
|
||||
localSettings?.set('window_minimize_to_tray', e.currentTarget.checked);
|
||||
setSettings({
|
||||
window: {
|
||||
...settings,
|
||||
minimizeToTray: e.currentTarget.checked,
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
),
|
||||
description: 'Minimize the application to the system tray',
|
||||
isHidden: !isElectron(),
|
||||
title: 'Minimize to tray',
|
||||
},
|
||||
{
|
||||
control: (
|
||||
<Switch
|
||||
aria-label="Toggle exit to tray"
|
||||
defaultChecked={settings.exitToTray}
|
||||
disabled={!isElectron()}
|
||||
onChange={(e) => {
|
||||
if (!e) return;
|
||||
localSettings?.set('window_exit_to_tray', e.currentTarget.checked);
|
||||
setSettings({
|
||||
window: {
|
||||
...settings,
|
||||
exitToTray: e.currentTarget.checked,
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
),
|
||||
description: 'Exit the application to the system tray',
|
||||
isHidden: !isElectron(),
|
||||
title: 'Exit to tray',
|
||||
},
|
||||
];
|
||||
|
||||
return <SettingsSection options={windowOptions} />;
|
||||
|
@ -71,6 +71,8 @@ export interface SettingsState {
|
||||
songs: DataTableProps;
|
||||
};
|
||||
window: {
|
||||
exitToTray: boolean;
|
||||
minimizeToTray: boolean;
|
||||
windowBarStyle: Platform;
|
||||
};
|
||||
}
|
||||
@ -243,6 +245,8 @@ export const useSettingsStore = create<SettingsSlice>()(
|
||||
},
|
||||
},
|
||||
window: {
|
||||
exitToTray: false,
|
||||
minimizeToTray: false,
|
||||
windowBarStyle: Platform.WEB,
|
||||
},
|
||||
})),
|
||||
|
Loading…
Reference in New Issue
Block a user