From 497f311522f88f9a9ab5be854fc944555e592da3 Mon Sep 17 00:00:00 2001 From: ktmouk Date: Tue, 30 Nov 2021 17:10:49 +0900 Subject: [PATCH] Add openAtLogin option --- .../renderer/pages/settings/general.spec.js | 28 +++++++++++++++++++ src/main/config/index.ts | 17 +++++++++-- src/main/config/migrations/1.5.0.ts | 17 +++++++++++ src/main/handlers/auto-launcher.ts | 12 ++++++++ src/main/modules/mixpanel-client.ts | 10 ++----- src/main/modules/universal-analytics.ts | 2 +- src/main/preloads/common/config.ts | 15 +++------- src/main/tsconfig.json | 1 + src/main/windows/mini-timer.ts | 2 +- .../locales/pages/settings/general.json | 6 ++-- src/renderer/pages/settings/general.vue | 10 +++++++ 11 files changed, 95 insertions(+), 25 deletions(-) create mode 100644 src/main/config/migrations/1.5.0.ts create mode 100644 src/main/handlers/auto-launcher.ts diff --git a/__tests__/src/renderer/pages/settings/general.spec.js b/__tests__/src/renderer/pages/settings/general.spec.js index 0de40e0e..4c1495aa 100644 --- a/__tests__/src/renderer/pages/settings/general.spec.js +++ b/__tests__/src/renderer/pages/settings/general.spec.js @@ -157,4 +157,32 @@ describe('General', () => { expect(global.electron.mixpanel.syncConfig).toHaveBeenCalled() }) }) + + describe('when click open-at-login', () => { + beforeEach(() => { + wrapper = factory() + wrapper.find(testId('open-at-login')).trigger('click') + }) + + it('toggles openAtLogin', () => { + expect(global.electron.config.set).toHaveBeenCalledWith( + 'openAtLogin', + true + ) + }) + + it('sends mixpanel event', () => { + expect(global.electron.mixpanel.sendEvent).toHaveBeenCalledWith( + 'Toggle openAtLogin', + { + component: 'general', + enabled: true, + } + ) + }) + + it('syncs mixpanel config', () => { + expect(global.electron.mixpanel.syncConfig).toHaveBeenCalled() + }) + }) }) diff --git a/src/main/config/index.ts b/src/main/config/index.ts index ac9abf29..ddf069cb 100644 --- a/src/main/config/index.ts +++ b/src/main/config/index.ts @@ -1,7 +1,7 @@ import * as path from 'path' -import * as Store from 'electron-store' +import Store from 'electron-store' import { sort as semverSort } from 'semver' -import { TypedStore } from '~/config/migrations/1.4.0' +import { TypedStore } from '~/config/migrations/1.5.0' const schema: Store.Schema = { stopTimerOnSuspend: { @@ -19,6 +19,9 @@ const schema: Store.Schema = { showMiniTimer: { type: 'boolean', }, + openAtLogin: { + type: 'boolean', + }, } const defaults: TypedStore = { @@ -27,8 +30,18 @@ const defaults: TypedStore = { remindTimerOnUnlocked: true, alwaysOnTop: false, showMiniTimer: true, + openAtLogin: true, } +export const trackingConfigKeys: (keyof TypedStore)[] = [ + 'stopTimerOnSuspend', + 'stopTimerOnShutdown', + 'remindTimerOnUnlocked', + 'alwaysOnTop', + 'showMiniTimer', + 'openAtLogin', +] + function getMigrationVersions(filePaths: string[]): string[] { const versions = filePaths.map((filePath) => path.parse(filePath).name) return semverSort(versions) diff --git a/src/main/config/migrations/1.5.0.ts b/src/main/config/migrations/1.5.0.ts new file mode 100644 index 00000000..4254589b --- /dev/null +++ b/src/main/config/migrations/1.5.0.ts @@ -0,0 +1,17 @@ +import Conf from 'conf/dist/source' +import { TypedStore as PrevTypedStore } from './1.4.0' + +export type TypedStore = { + stopTimerOnSuspend: boolean + stopTimerOnShutdown: boolean + remindTimerOnUnlocked: boolean + alwaysOnTop: boolean + showMiniTimer: boolean + openAtLogin: boolean +} + +export const migration = ( + store: Conf> +): void => { + store.set('openAtLogin', true) +} diff --git a/src/main/handlers/auto-launcher.ts b/src/main/handlers/auto-launcher.ts new file mode 100644 index 00000000..4fb61a44 --- /dev/null +++ b/src/main/handlers/auto-launcher.ts @@ -0,0 +1,12 @@ +import { app } from 'electron' +import { config } from '~/config' + +async function syncEnabled() { + app.setLoginItemSettings({ + openAtLogin: config.get('openAtLogin'), + }) +} + +app.on('ready', syncEnabled) + +config.onDidChange('openAtLogin', syncEnabled) diff --git a/src/main/modules/mixpanel-client.ts b/src/main/modules/mixpanel-client.ts index 9ddb6f2c..850b7427 100644 --- a/src/main/modules/mixpanel-client.ts +++ b/src/main/modules/mixpanel-client.ts @@ -1,6 +1,6 @@ import * as Mixpanel from 'mixpanel' import { v4 as uuidv4 } from 'uuid' -import { config } from '../config' +import { trackingConfigKeys, config } from '~/config' export class MixpanelClient { private uuid: string @@ -36,13 +36,7 @@ export class MixpanelClient { public syncConfig(): void { const props = { - ...this.generateConfigProps([ - 'stopTimerOnSuspend', - 'stopTimerOnShutdown', - 'remindTimerOnUnlocked', - 'alwaysOnTop', - 'showMiniTimer', - ]), + ...this.generateConfigProps(trackingConfigKeys), release: process.env.npm_package_version, platform: process.platform, } diff --git a/src/main/modules/universal-analytics.ts b/src/main/modules/universal-analytics.ts index b7888700..d5e5e4d5 100644 --- a/src/main/modules/universal-analytics.ts +++ b/src/main/modules/universal-analytics.ts @@ -1,4 +1,4 @@ -import * as ua from 'universal-analytics' +import ua from 'universal-analytics' import { v4 as uuidv4 } from 'uuid' export function createVisitor(): ua.Visitor { diff --git a/src/main/preloads/common/config.ts b/src/main/preloads/common/config.ts index 34436bc7..db085e94 100644 --- a/src/main/preloads/common/config.ts +++ b/src/main/preloads/common/config.ts @@ -5,29 +5,22 @@ const namespace = 'config' const prefix = createPrefixer(namespace) const missingKeyError = new Error('Requested key is missing') -const readables = [ - 'stopTimerOnSuspend', - 'stopTimerOnShutdown', - 'remindTimerOnUnlocked', - 'alwaysOnTop', - 'showMiniTimer', -] - -const settables = [ +const accessibleKeys = [ 'stopTimerOnSuspend', 'stopTimerOnShutdown', 'remindTimerOnUnlocked', 'alwaysOnTop', 'showMiniTimer', + 'openAtLogin', ] export const config = { get(key: string): Promise { - if (!readables.includes(key)) throw missingKeyError + if (!accessibleKeys.includes(key)) throw missingKeyError return invoke(prefix('get'), key) }, set(key: string, value: string): void { - if (!settables.includes(key)) throw missingKeyError + if (!accessibleKeys.includes(key)) throw missingKeyError invoke(prefix('set'), key, value) }, } diff --git a/src/main/tsconfig.json b/src/main/tsconfig.json index 5d95dfe7..05baabba 100644 --- a/src/main/tsconfig.json +++ b/src/main/tsconfig.json @@ -6,6 +6,7 @@ "strict": true, "typeRoots": ["./types"], "types": ["node", "webpack-env"], + "esModuleInterop": true, "paths": { "~/*": ["./*"] } diff --git a/src/main/windows/mini-timer.ts b/src/main/windows/mini-timer.ts index c46d7461..f326a23c 100644 --- a/src/main/windows/mini-timer.ts +++ b/src/main/windows/mini-timer.ts @@ -1,5 +1,5 @@ import { BrowserWindow } from 'electron' -import * as Positioner from 'electron-positioner' +import Positioner from 'electron-positioner' import { getWindowUrl, buildWindowOptions } from '~/modules/window' let window: BrowserWindow | undefined diff --git a/src/renderer/assets/locales/pages/settings/general.json b/src/renderer/assets/locales/pages/settings/general.json index 1a1ebf5f..0ea2dc85 100644 --- a/src/renderer/assets/locales/pages/settings/general.json +++ b/src/renderer/assets/locales/pages/settings/general.json @@ -5,7 +5,8 @@ "stopTimerOnShutdown": "Stop a timer on shutdown", "remindTimerOnUnlocked": "Show reminder notification on resumed", "alwaysOnTop": "Keep the window always on top", - "showMiniTimer": "Show the timer at the bottom right of the screen" + "showMiniTimer": "Show the timer at the bottom right of the screen", + "openAtLogin": "Open the app at login" }, "ja": { "title": "一般", @@ -13,6 +14,7 @@ "stopTimerOnShutdown": "PCのシャットダウン時に計測を停止", "remindTimerOnUnlocked": "PCの再開時に計測のリマインドを通知", "alwaysOnTop": "ウィンドウを最前面に表示", - "showMiniTimer": "画面右下に経過時間を表示" + "showMiniTimer": "画面右下に経過時間を表示", + "openAtLogin": "ログイン時にアプリを自動的に起動" } } diff --git a/src/renderer/pages/settings/general.vue b/src/renderer/pages/settings/general.vue index 161a02de..6d535ede 100644 --- a/src/renderer/pages/settings/general.vue +++ b/src/renderer/pages/settings/general.vue @@ -47,6 +47,14 @@ />{{ $t('showMiniTimer') }} BETA + @@ -67,6 +75,7 @@ export default { remindTimerOnUnlocked: false, alwaysOnTop: false, showMiniTimer: false, + openAtLogin: false, } }, async mounted() { @@ -77,6 +86,7 @@ export default { ) this.alwaysOnTop = await electron.config.get('alwaysOnTop') this.showMiniTimer = await electron.config.get('showMiniTimer') + this.openAtLogin = await electron.config.get('openAtLogin') }, methods: { toggleChecked(key) {