diff --git a/src/app/accounts/settings.component.html b/src/app/accounts/settings.component.html index ffc57907d5..e7c9965e71 100644 --- a/src/app/accounts/settings.component.html +++ b/src/app/accounts/settings.component.html @@ -113,30 +113,50 @@ - {{'enableMinToTrayDesc' | i18n}} + {{enableMinToTrayDescText}} -
+
- {{'enableCloseToTrayDesc' | i18n}} + {{enableCloseToTrayDescText}}
-
+
- {{'startToTrayDesc' | i18n}} + {{startToTrayDescText}} +
+
+
+ +
+ {{'openAtLoginDesc' | i18n}} +
+
+
+ +
+ {{'alwaysShowDockDesc' | i18n}}
diff --git a/src/app/accounts/settings.component.ts b/src/app/accounts/settings.component.ts index 9064b3724b..5a949b7611 100644 --- a/src/app/accounts/settings.component.ts +++ b/src/app/accounts/settings.component.ts @@ -47,21 +47,45 @@ export class SettingsComponent implements OnInit { themeOptions: any[]; clearClipboard: number; clearClipboardOptions: any[]; - enableTrayText: string; - enableTrayDescText: string; supportsBiometric: boolean; biometric: boolean; biometricText: string; + alwaysShowDock: boolean; + showAlwaysShowDock: boolean = false; + openAtLogin: boolean; + + enableTrayText: string; + enableTrayDescText: string; + enableMinToTrayText: string; + enableMinToTrayDescText: string; + enableCloseToTrayText: string; + enableCloseToTrayDescText: string; + startToTrayText: string; + startToTrayDescText: string; constructor(private analytics: Angulartics2, private toasterService: ToasterService, private i18nService: I18nService, private platformUtilsService: PlatformUtilsService, private storageService: StorageService, private vaultTimeoutService: VaultTimeoutService, private stateService: StateService, private messagingService: MessagingService, private userService: UserService, private cryptoService: CryptoService) { - const trayKey = this.platformUtilsService.getDevice() === DeviceType.MacOsDesktop ? - 'enableMenuBar' : 'enableTray'; + const isMac = this.platformUtilsService.getDevice() === DeviceType.MacOsDesktop; + + const trayKey = isMac ? 'enableMenuBar' : 'enableTray'; this.enableTrayText = this.i18nService.t(trayKey); this.enableTrayDescText = this.i18nService.t(trayKey + 'Desc'); + + const minToTrayKey = isMac ? 'enableMinToMenuBar' : 'enableMinToTray'; + this.enableMinToTrayText = this.i18nService.t(minToTrayKey) + this.enableMinToTrayDescText = this.i18nService.t(minToTrayKey + 'Desc'); + + const closeToTrayKey = isMac ? 'enableCloseToMenuBar' : 'enableCloseToTray'; + this.enableCloseToTrayText = this.i18nService.t(closeToTrayKey) + this.enableCloseToTrayDescText = this.i18nService.t(closeToTrayKey + 'Desc'); + + const startToTrayKey = isMac ? 'startToMenuBar' : 'startToTray'; + this.startToTrayText = this.i18nService.t(startToTrayKey) + this.startToTrayDescText = this.i18nService.t(startToTrayKey + 'Desc'); + this.vaultTimeouts = [ // { name: i18nService.t('immediately'), value: 0 }, { name: i18nService.t('oneMinute'), value: 1 }, @@ -114,7 +138,7 @@ export class SettingsComponent implements OnInit { } async ngOnInit() { - this.showMinToTray = this.platformUtilsService.getDevice() === DeviceType.WindowsDesktop; + this.showMinToTray = this.platformUtilsService.getDevice() !== DeviceType.LinuxDesktop; this.vaultTimeout = await this.storageService.get(ConstantsService.vaultTimeoutKey); this.vaultTimeoutAction = await this.storageService.get(ConstantsService.vaultTimeoutActionKey); const pinSet = await this.vaultTimeoutService.isPinLockSet(); @@ -133,6 +157,9 @@ export class SettingsComponent implements OnInit { this.supportsBiometric = await this.platformUtilsService.supportsBiometric(); this.biometric = await this.vaultTimeoutService.isBiometricLockSet(); this.biometricText = await this.storageService.get(ConstantsService.biometricText); + this.alwaysShowDock = await this.storageService.get(ElectronConstants.alwaysShowDock); + this.showAlwaysShowDock = this.platformUtilsService.getDevice() === DeviceType.MacOsDesktop; + this.openAtLogin = await this.storageService.get(ElectronConstants.openAtLogin); } async saveVaultTimeoutOptions() { @@ -279,6 +306,15 @@ export class SettingsComponent implements OnInit { }); } + async saveAlwaysShowDock() { + await this.storageService.save(ElectronConstants.alwaysShowDock, this.alwaysShowDock); + } + + async saveOpenAtLogin() { + this.storageService.save(ElectronConstants.openAtLogin, this.openAtLogin); + this.messagingService.send(this.openAtLogin ? 'addOpenAtLogin' : 'removeOpenAtLogin'); + } + async saveBrowserIntegration() { await this.storageService.save(ElectronConstants.enableBrowserIntegration, this.enableBrowserIntegration); this.messagingService.send(this.enableBrowserIntegration ? 'enableBrowserIntegration' : 'disableBrowserIntegration'); diff --git a/src/locales/en/messages.json b/src/locales/en/messages.json index ef069d0348..525e9da141 100644 --- a/src/locales/en/messages.json +++ b/src/locales/en/messages.json @@ -852,12 +852,24 @@ "enableMinToTrayDesc": { "message": "When minimizing the window, show an icon in the system tray instead." }, + "enableMinToMenuBar": { + "message": "Minimize to menu bar" + }, + "enableMinToMenuBarDesc": { + "message": "When minimizing the window, show an icon in the menu bar instead." + }, "enableCloseToTray": { "message": "Close to Tray Icon" }, "enableCloseToTrayDesc": { "message": "When closing the window, show an icon in the system tray instead." }, + "enableCloseToMenuBar": { + "message": "Close to menu bar" + }, + "enableCloseToMenuBarDesc": { + "message": "When closing the window, show an icon in the menu bar instead." + }, "enableTray": { "message": "Enable Tray Icon" }, @@ -870,6 +882,24 @@ "startToTrayDesc": { "message": "When the application is first started, only show an icon in the system tray." }, + "startToMenuBar": { + "message": "Start to menu bar" + }, + "startToMenuBarDesc": { + "message": "When the application is first started, only show an icon in the menu bar." + }, + "openAtLogin": { + "message": "Start automatically on login" + }, + "openAtLoginDesc": { + "message": "Start the Bitwarden Desktop application automatically on login." + }, + "alwaysShowDock": { + "message": "Always show in the Dock" + }, + "alwaysShowDockDesc": { + "message": "Show the Bitwarden icon in the Dock even when minimized to the menu bar." + }, "language": { "message": "Language" }, diff --git a/src/main/messaging.main.ts b/src/main/messaging.main.ts index 5cfe87f6c8..02981422f4 100644 --- a/src/main/messaging.main.ts +++ b/src/main/messaging.main.ts @@ -1,4 +1,6 @@ -import { ipcMain } from 'electron'; +import { app, ipcMain } from 'electron'; +import * as fs from 'fs'; +import * as path from 'path'; import { Main } from '../main'; @@ -15,6 +17,12 @@ export class MessagingMain { init() { this.scheduleNextSync(); + if (process.platform === 'linux') { + this.storageService.save(ElectronConstants.openAtLogin, fs.existsSync(this.linuxStartupFile())); + } else { + const loginSettings = app.getLoginItemSettings(); + this.storageService.save(ElectronConstants.openAtLogin, loginSettings.openAtLogin); + } ipcMain.on('messagingService', async (event: any, message: any) => this.onMessage(message)); } @@ -44,6 +52,11 @@ export class MessagingMain { case 'hideToTray': this.main.trayMain.hideToTray(); break; + case 'addOpenAtLogin': + this.addOpenAtLogin(); + break; + case 'removeOpenAtLogin': + this.removeOpenAtLogin(); case 'setFocus': this.setFocus(); break; @@ -86,6 +99,41 @@ export class MessagingMain { } } + private addOpenAtLogin() { + if (process.platform === 'linux') { + const data = `[Desktop Entry] + Type=Application + Version=${app.getVersion()} + Name=Bitwarden + Comment=Bitwarden startup script + Exec=${app.getPath('exe')} + StartupNotify=false + Terminal=false`; + + const dir = path.dirname(this.linuxStartupFile()); + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir); + } + fs.writeFileSync(this.linuxStartupFile(), data); + } else { + app.setLoginItemSettings({openAtLogin: true}); + } + } + + private removeOpenAtLogin() { + if (process.platform === 'linux') { + if (fs.existsSync(this.linuxStartupFile())) { + fs.unlinkSync(this.linuxStartupFile()); + } + } else { + app.setLoginItemSettings({openAtLogin: false}); + } + } + + private linuxStartupFile(): string { + return path.join(app.getPath('home'), '.config', 'autostart', 'bitwarden.desktop'); + } + private setFocus() { this.main.trayMain.restoreFromTray(); this.main.windowMain.win.focusOnWebView();