mirror of
https://github.com/samuelthomas2774/nxapi.git
synced 2026-04-26 00:13:08 -05:00
Add open hidden at login option for Windows and Linux
https://github.com/samuelthomas2774/nxapi/issues/19
This commit is contained in:
parent
0192529020
commit
e6e1e73bdc
|
|
@ -22,11 +22,11 @@ export default function Preferences(props: PreferencesProps) {
|
||||||
const [login_item, ,, forceRefreshLoginItem] = useAsync(useCallback(() => ipc.getLoginItemSettings(), [ipc]));
|
const [login_item, ,, forceRefreshLoginItem] = useAsync(useCallback(() => ipc.getLoginItemSettings(), [ipc]));
|
||||||
|
|
||||||
const setOpenAtLogin = useCallback(async (open_at_login: boolean | 'mixed') => {
|
const setOpenAtLogin = useCallback(async (open_at_login: boolean | 'mixed') => {
|
||||||
await ipc.setLoginItemSettings({...login_item, openAtLogin: !!open_at_login});
|
await ipc.setLoginItemSettings({...login_item!, startup_enabled: !!open_at_login});
|
||||||
forceRefreshLoginItem();
|
forceRefreshLoginItem();
|
||||||
}, [ipc, login_item]);
|
}, [ipc, login_item]);
|
||||||
const setOpenAsHidden = useCallback(async (open_as_hidden: boolean | 'mixed') => {
|
const setOpenAsHidden = useCallback(async (open_as_hidden: boolean | 'mixed') => {
|
||||||
await ipc.setLoginItemSettings({...login_item, openAsHidden: !!open_as_hidden});
|
await ipc.setLoginItemSettings({...login_item!, startup_hidden: !!open_as_hidden});
|
||||||
forceRefreshLoginItem();
|
forceRefreshLoginItem();
|
||||||
}, [ipc, login_item]);
|
}, [ipc, login_item]);
|
||||||
|
|
||||||
|
|
@ -114,7 +114,7 @@ export default function Preferences(props: PreferencesProps) {
|
||||||
<View style={styles.main}>
|
<View style={styles.main}>
|
||||||
{/* <Text style={theme.text}>Preferences</Text> */}
|
{/* <Text style={theme.text}>Preferences</Text> */}
|
||||||
|
|
||||||
{ipc.platform === 'darwin' || ipc.platform === 'win32' ? <View style={styles.section}>
|
{login_item.supported || login_item.startup_enabled ? <View style={styles.section}>
|
||||||
<View style={styles.sectionLeft}>
|
<View style={styles.sectionLeft}>
|
||||||
<Text style={[styles.label, theme.text]}>Startup</Text>
|
<Text style={[styles.label, theme.text]}>Startup</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|
@ -124,32 +124,33 @@ export default function Preferences(props: PreferencesProps) {
|
||||||
|
|
||||||
<View style={styles.checkboxContainer}>
|
<View style={styles.checkboxContainer}>
|
||||||
<CheckBox
|
<CheckBox
|
||||||
value={login_item.openAtLogin}
|
value={login_item.startup_enabled}
|
||||||
onValueChange={setOpenAtLogin}
|
onValueChange={setOpenAtLogin}
|
||||||
|
disabled={!login_item.supported}
|
||||||
color={'#' + (accent_colour ?? DEFAULT_ACCENT_COLOUR)}
|
color={'#' + (accent_colour ?? DEFAULT_ACCENT_COLOUR)}
|
||||||
style={styles.checkbox}
|
style={styles.checkbox}
|
||||||
/>
|
/>
|
||||||
<TouchableOpacity style={styles.checkboxLabel} onPress={() => setOpenAtLogin(!login_item.openAtLogin)}>
|
<TouchableOpacity disabled={!login_item.supported} style={styles.checkboxLabel} onPress={() => setOpenAtLogin(!login_item.startup_enabled)}>
|
||||||
<Text style={[styles.checkboxLabelText, theme.text]}>Open at login</Text>
|
<Text style={[styles.checkboxLabelText, theme.text]}>Open at login</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
{ipc.platform === 'darwin' ? <View
|
<View
|
||||||
style={[styles.checkboxContainer, !login_item.openAtLogin ? styles.disabled : null]}
|
style={[styles.checkboxContainer, !login_item.startup_enabled ? styles.disabled : null]}
|
||||||
>
|
>
|
||||||
<CheckBox
|
<CheckBox
|
||||||
value={login_item.openAsHidden}
|
value={login_item.startup_hidden}
|
||||||
onValueChange={setOpenAsHidden}
|
onValueChange={setOpenAsHidden}
|
||||||
disabled={!login_item.openAtLogin}
|
disabled={!login_item.startup_enabled}
|
||||||
color={'#' + (accent_colour ?? DEFAULT_ACCENT_COLOUR)}
|
color={'#' + (accent_colour ?? DEFAULT_ACCENT_COLOUR)}
|
||||||
style={styles.checkbox}
|
style={styles.checkbox}
|
||||||
/>
|
/>
|
||||||
<TouchableOpacity disabled={!login_item.openAtLogin} style={styles.checkboxLabel}
|
<TouchableOpacity disabled={!login_item.startup_enabled} style={styles.checkboxLabel}
|
||||||
onPress={() => setOpenAsHidden(!login_item.openAsHidden)}
|
onPress={() => setOpenAsHidden(!login_item.startup_hidden)}
|
||||||
>
|
>
|
||||||
<Text style={[styles.checkboxLabelText, theme.text]}>Open in background</Text>
|
<Text style={[styles.checkboxLabelText, theme.text]}>Open in background</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View> : null}
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View> : null}
|
</View> : null}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,3 +47,10 @@ export interface DiscordPresenceSourceUrl {
|
||||||
export interface DiscordPresenceExternalMonitorsConfiguration {
|
export interface DiscordPresenceExternalMonitorsConfiguration {
|
||||||
enable_splatnet3_monitoring?: boolean;
|
enable_splatnet3_monitoring?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface LoginItem {
|
||||||
|
supported: boolean;
|
||||||
|
startup_enabled: boolean;
|
||||||
|
startup_hidden: boolean;
|
||||||
|
}
|
||||||
|
export type LoginItemOptions = Omit<LoginItem, 'supported'>;
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import MenuApp from './menu.js';
|
||||||
import { handleOpenWebServiceUri } from './webservices.js';
|
import { handleOpenWebServiceUri } from './webservices.js';
|
||||||
import { EmbeddedPresenceMonitor, PresenceMonitorManager } from './monitor.js';
|
import { EmbeddedPresenceMonitor, PresenceMonitorManager } from './monitor.js';
|
||||||
import { createWindow } from './windows.js';
|
import { createWindow } from './windows.js';
|
||||||
import { DiscordPresenceConfiguration, WindowType } from '../common/types.js';
|
import { DiscordPresenceConfiguration, LoginItem, LoginItemOptions, WindowType } from '../common/types.js';
|
||||||
import { initStorage, paths } from '../../util/storage.js';
|
import { initStorage, paths } from '../../util/storage.js';
|
||||||
import { checkUpdates, UpdateCacheData } from '../../common/update.js';
|
import { checkUpdates, UpdateCacheData } from '../../common/update.js';
|
||||||
import Users, { CoralUser } from '../../common/users.js';
|
import Users, { CoralUser } from '../../common/users.js';
|
||||||
|
|
@ -29,10 +29,28 @@ export const protocol_registration_options = dev && process.platform === 'win32'
|
||||||
path.join(dir, 'dist', 'app', 'app-entry.cjs'),
|
path.join(dir, 'dist', 'app', 'app-entry.cjs'),
|
||||||
],
|
],
|
||||||
} : null;
|
} : null;
|
||||||
export const login_item_options: LoginItemSettingsOptions = {};
|
export const login_item_options: LoginItemSettingsOptions = {
|
||||||
|
path: process.execPath,
|
||||||
|
args: dev ? [
|
||||||
|
path.join(dir, 'dist', 'app', 'app-entry.cjs'),
|
||||||
|
'--app-open-at-login=1',
|
||||||
|
] : [
|
||||||
|
'--app-open-at-login=1',
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
enum LoginItemType {
|
||||||
|
NATIVE,
|
||||||
|
NATIVE_PARTIAL,
|
||||||
|
NOT_SUPPORTED,
|
||||||
|
}
|
||||||
|
const login_item_type: LoginItemType =
|
||||||
|
process.platform === 'darwin' ? LoginItemType.NATIVE :
|
||||||
|
process.platform === 'win32' ? LoginItemType.NATIVE_PARTIAL :
|
||||||
|
LoginItemType.NOT_SUPPORTED;
|
||||||
|
|
||||||
debug('Protocol registration options', protocol_registration_options);
|
debug('Protocol registration options', protocol_registration_options);
|
||||||
debug('Login item registration options', login_item_options);
|
debug('Login item registration options', LoginItemType[login_item_type], login_item_options);
|
||||||
|
|
||||||
export class App {
|
export class App {
|
||||||
readonly store: Store;
|
readonly store: Store;
|
||||||
|
|
@ -184,7 +202,11 @@ export async function init() {
|
||||||
|
|
||||||
debug('App started');
|
debug('App started');
|
||||||
|
|
||||||
if (!app.getLoginItemSettings(login_item_options).wasOpenedAsHidden) {
|
const should_hide =
|
||||||
|
login_item_type === LoginItemType.NATIVE ? app.getLoginItemSettings(login_item_options).wasOpenedAsHidden :
|
||||||
|
process.argv.includes('--app-open-at-login=1') && (await appinstance.store.getLoginItem()).startup_hidden;
|
||||||
|
|
||||||
|
if (!should_hide) {
|
||||||
appinstance.showMainWindow();
|
appinstance.showMainWindow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -254,6 +276,10 @@ class Updater {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface SavedStartupOptions {
|
||||||
|
hide: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
interface SavedMonitorState {
|
interface SavedMonitorState {
|
||||||
users: {
|
users: {
|
||||||
/** Nintendo Account ID */
|
/** Nintendo Account ID */
|
||||||
|
|
@ -277,6 +303,63 @@ export class Store extends EventEmitter {
|
||||||
this.users = Users.coral(this, process.env.ZNC_PROXY_URL, false);
|
this.users = Users.coral(this, process.env.ZNC_PROXY_URL, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getLoginItem(): Promise<LoginItem> {
|
||||||
|
const settings = app.getLoginItemSettings(login_item_options);
|
||||||
|
|
||||||
|
if (login_item_type === LoginItemType.NATIVE) {
|
||||||
|
// Fully supported
|
||||||
|
return {
|
||||||
|
supported: true,
|
||||||
|
startup_enabled: settings.openAtLogin,
|
||||||
|
startup_hidden: settings.openAsHidden,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const startup_options: SavedStartupOptions | undefined = await this.storage.getItem('StartupOptions');
|
||||||
|
const was_opened_at_login = process.argv.includes('--app-open-at-login=1');
|
||||||
|
|
||||||
|
if (login_item_type === LoginItemType.NATIVE_PARTIAL) {
|
||||||
|
// Partial native support
|
||||||
|
return {
|
||||||
|
supported: true,
|
||||||
|
startup_enabled: settings.openAtLogin,
|
||||||
|
startup_hidden: startup_options?.hide ?? false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
supported: false,
|
||||||
|
startup_enabled: was_opened_at_login,
|
||||||
|
startup_hidden: startup_options?.hide ?? false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async setLoginItem(settings: LoginItemOptions) {
|
||||||
|
if (login_item_type === LoginItemType.NATIVE) {
|
||||||
|
// Fully supported
|
||||||
|
app.setLoginItemSettings({
|
||||||
|
...login_item_options,
|
||||||
|
openAtLogin: settings.startup_enabled,
|
||||||
|
openAsHidden: settings.startup_hidden,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (login_item_type === LoginItemType.NATIVE_PARTIAL) {
|
||||||
|
// Partial native support
|
||||||
|
app.setLoginItemSettings({
|
||||||
|
...login_item_options,
|
||||||
|
openAtLogin: settings.startup_enabled,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const startup_options: SavedStartupOptions = {
|
||||||
|
hide: settings.startup_hidden,
|
||||||
|
};
|
||||||
|
|
||||||
|
await this.storage.setItem('StartupOptions', startup_options);
|
||||||
|
}
|
||||||
|
|
||||||
async saveMonitorState(monitors: PresenceMonitorManager) {
|
async saveMonitorState(monitors: PresenceMonitorManager) {
|
||||||
const users = new Set();
|
const users = new Set();
|
||||||
const state: SavedMonitorState = {
|
const state: SavedMonitorState = {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import { app, BrowserWindow, clipboard, dialog, IpcMain, KeyboardEvent, LoginItemSettings, Menu, MenuItem, Settings, ShareMenu, SharingItem, shell, systemPreferences } from './electron.js';
|
import { app, BrowserWindow, clipboard, dialog, IpcMain, KeyboardEvent, Menu, MenuItem, Settings, ShareMenu, SharingItem, shell, systemPreferences } from './electron.js';
|
||||||
import * as util from 'node:util';
|
import * as util from 'node:util';
|
||||||
import createDebug from 'debug';
|
import createDebug from 'debug';
|
||||||
import { User } from 'discord-rpc';
|
import { User } from 'discord-rpc';
|
||||||
import openWebService, { QrCodeReaderOptions, WebServiceIpc, WebServiceValidationError } from './webservices.js';
|
import openWebService, { QrCodeReaderOptions, WebServiceIpc, WebServiceValidationError } from './webservices.js';
|
||||||
import { createWindow, getWindowConfiguration } from './windows.js';
|
import { createWindow, getWindowConfiguration } from './windows.js';
|
||||||
import { DiscordPresenceConfiguration, DiscordPresenceSource, WindowType } from '../common/types.js';
|
import { DiscordPresenceConfiguration, DiscordPresenceSource, LoginItemOptions, WindowType } from '../common/types.js';
|
||||||
import { CurrentUser, Friend, Game, PresenceState, WebService } from '../../api/coral-types.js';
|
import { CurrentUser, Friend, Game, PresenceState, WebService } from '../../api/coral-types.js';
|
||||||
import { askAddNsoAccount, askAddPctlAccount } from './na-auth.js';
|
import { askAddNsoAccount, askAddPctlAccount } from './na-auth.js';
|
||||||
import { App, login_item_options } from './index.js';
|
import { App, login_item_options } from './index.js';
|
||||||
|
|
@ -40,8 +40,8 @@ export function setupIpc(appinstance: App, ipcMain: IpcMain) {
|
||||||
sendToAllWindows('nxapi:systemPreferences:accent-colour', accent_colour);
|
sendToAllWindows('nxapi:systemPreferences:accent-colour', accent_colour);
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle('nxapi:systemPreferences:getloginitem', () => app.getLoginItemSettings(login_item_options));
|
ipcMain.handle('nxapi:systemPreferences:getloginitem', () => appinstance.store.getLoginItem());
|
||||||
ipcMain.handle('nxapi:systemPreferences:setloginitem', (e, settings: Settings) => app.setLoginItemSettings({...login_item_options, ...settings}));
|
ipcMain.handle('nxapi:systemPreferences:setloginitem', (e, settings: LoginItemOptions) => appinstance.store.setLoginItem(settings));
|
||||||
|
|
||||||
ipcMain.handle('nxapi:update:get', () => appinstance.updater.cache ?? appinstance.updater.check());
|
ipcMain.handle('nxapi:update:get', () => appinstance.updater.cache ?? appinstance.updater.check());
|
||||||
ipcMain.handle('nxapi:update:check', () => appinstance.updater.check());
|
ipcMain.handle('nxapi:update:check', () => appinstance.updater.check());
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ import { contextBridge, ipcRenderer } from 'electron';
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import createDebug from 'debug';
|
import createDebug from 'debug';
|
||||||
import type { User } from 'discord-rpc';
|
import type { User } from 'discord-rpc';
|
||||||
import type { LoginItemSettings, Settings, SharingItem } from '../main/electron.js';
|
import type { SharingItem } from '../main/electron.js';
|
||||||
import type { DiscordPresenceConfiguration, DiscordPresenceSource, WindowConfiguration } from '../common/types.js';
|
import type { DiscordPresenceConfiguration, DiscordPresenceSource, LoginItem, LoginItemOptions, WindowConfiguration } from '../common/types.js';
|
||||||
import type { SavedToken } from '../../common/auth/coral.js';
|
import type { SavedToken } from '../../common/auth/coral.js';
|
||||||
import type { SavedMoonToken } from '../../common/auth/moon.js';
|
import type { SavedMoonToken } from '../../common/auth/moon.js';
|
||||||
import type { UpdateCacheData } from '../../common/update.js';
|
import type { UpdateCacheData } from '../../common/update.js';
|
||||||
|
|
@ -30,8 +30,8 @@ events.setMaxListeners(0);
|
||||||
const ipc = {
|
const ipc = {
|
||||||
getWindowData: () => invSync<WindowConfiguration>('browser:getwindowdata'),
|
getWindowData: () => invSync<WindowConfiguration>('browser:getwindowdata'),
|
||||||
|
|
||||||
getLoginItemSettings: () => inv<LoginItemSettings>('systemPreferences:getloginitem'),
|
getLoginItemSettings: () => inv<LoginItem>('systemPreferences:getloginitem'),
|
||||||
setLoginItemSettings: (settings: Settings) => inv('systemPreferences:setloginitem', settings),
|
setLoginItemSettings: (settings: LoginItemOptions) => inv('systemPreferences:setloginitem', settings),
|
||||||
|
|
||||||
getUpdateData: () => inv<UpdateCacheData | null>('update:get'),
|
getUpdateData: () => inv<UpdateCacheData | null>('update:get'),
|
||||||
checkUpdates: () => inv<UpdateCacheData | null>('update:check'),
|
checkUpdates: () => inv<UpdateCacheData | null>('update:check'),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user