diff --git a/app/scripts/ui-old/settings/settings-general-view.js b/app/scripts/ui-old/settings/settings-general-view.js index 0ded5c5a..7126b958 100644 --- a/app/scripts/ui-old/settings/settings-general-view.js +++ b/app/scripts/ui-old/settings/settings-general-view.js @@ -3,68 +3,12 @@ import { View } from 'framework/views/view'; import { Storage } from 'storage'; import { Updater } from 'comp/app/updater'; import { Launcher } from 'comp/launcher'; -import { Alerts } from 'comp/ui/alerts'; import { Links } from 'const/links'; import { AppSettingsModel } from 'models/app-settings-model'; -import { Locale } from 'util/locale'; -import { SettingsLogsView } from 'views/settings/settings-logs-view'; import { minmax } from 'util/fn'; import { NativeModules } from 'comp/launcher/native-modules'; -import template from 'templates/settings/settings-general.hbs'; class SettingsGeneralView extends View { - template = template; - - events = { - 'click .settings__general-theme': 'changeTheme', - 'click .settings__general-auto-switch-theme': 'changeAuthSwitchTheme', - 'change .settings__general-locale': 'changeLocale', - 'change .settings__general-font-size': 'changeFontSize', - 'change .settings__general-expand': 'changeExpandGroups', - 'change .settings__general-auto-update': 'changeAutoUpdate', - 'change .settings__general-idle-minutes': 'changeIdleMinutes', - 'change .settings__general-clipboard': 'changeClipboard', - 'change .settings__general-auto-save': 'changeAutoSave', - 'change .settings__general-auto-save-interval': 'changeAutoSaveInterval', - 'change .settings__general-remember-key-files': 'changeRememberKeyFiles', - 'change .settings__general-minimize': 'changeMinimize', - 'change .settings__general-minimize-on-field-copy': 'changeMinimizeOnFieldCopy', - 'change .settings__general-audit-passwords': 'changeAuditPasswords', - 'change .settings__general-audit-password-entropy': 'changeAuditPasswordEntropy', - 'change .settings__general-exclude-pins-from-audit': 'changeExcludePinsFromAudit', - 'change .settings__general-check-passwords-on-hibp': 'changeCheckPasswordsOnHIBP', - 'click .settings__general-toggle-help-hibp': 'clickToggleHelpHIBP', - 'change .settings__general-audit-password-age': 'changeAuditPasswordAge', - 'change .settings__general-lock-on-minimize': 'changeLockOnMinimize', - 'change .settings__general-lock-on-copy': 'changeLockOnCopy', - 'change .settings__general-lock-on-auto-type': 'changeLockOnAutoType', - 'change .settings__general-lock-on-os-lock': 'changeLockOnOsLock', - 'change .settings__general-table-view': 'changeTableView', - 'change .settings__general-colorful-icons': 'changeColorfulIcons', - 'change .settings__general-use-markdown': 'changeUseMarkdown', - 'change .settings__general-use-group-icon-for-entries': 'changeUseGroupIconForEntries', - 'change .settings__general-direct-autotype': 'changeDirectAutotype', - 'change .settings__general-autotype-title-filter': 'changeAutoTypeTitleFilter', - 'change .settings__general-field-label-dblclick-autotype': - 'changeFieldLabelDblClickAutoType', - 'change .settings__general-device-owner-auth': 'changeDeviceOwnerAuth', - 'change .settings__general-device-owner-auth-timeout': 'changeDeviceOwnerAuthTimeout', - 'change .settings__general-titlebar-style': 'changeTitlebarStyle', - 'click .settings__general-update-btn': 'checkUpdate', - 'click .settings__general-restart-btn': 'installUpdateAndRestart', - 'click .settings__general-download-update-btn': 'downloadUpdate', - 'click .settings__general-update-found-btn': 'installFoundUpdate', - 'change .settings__general-disable-offline-storage': 'changeDisableOfflineStorage', - 'change .settings__general-short-lived-storage-token': 'changeShortLivedStorageToken', - 'change .settings__general-prv-check': 'changeStorageEnabled', - 'click .settings__general-prv-logout': 'logoutFromStorage', - 'click .settings__general-show-advanced': 'showAdvancedSettings', - 'click .settings__general-dev-tools-link': 'openDevTools', - 'click .settings__general-try-beta-link': 'tryBeta', - 'click .settings__general-show-logs-link': 'showLogs', - 'click .settings__general-reload-app-link': 'reloadApp' - }; - changeClipboard(e) { const clipboardSeconds = +e.target.value; AppSettingsModel.clipboardSeconds = clipboardSeconds; @@ -270,47 +214,6 @@ class SettingsGeneralView extends View { $(e.target).remove(); } } - - showAdvancedSettings() { - this.$el - .find('.settings__general-show-advanced, .settings__general-advanced') - .toggleClass('hide'); - this.scrollToBottom(); - } - - openDevTools() { - if (Launcher) { - Launcher.openDevTools(); - } - } - - tryBeta() { - if (this.appModel.files.hasUnsavedFiles()) { - Alerts.info({ - header: Locale.setGenTryBetaWarning, - body: Locale.setGenTryBetaWarningBody - }); - } else { - location.href = Links.BetaWebApp; - } - } - - showLogs() { - if (this.views.logView) { - this.views.logView.remove(); - } - this.views.logView = new SettingsLogsView(); - this.views.logView.render(); - this.scrollToBottom(); - } - - reloadApp() { - location.reload(); - } - - scrollToBottom() { - this.$el.closest('.scroller').scrollTop(this.$el.height()); - } } export { SettingsGeneralView }; diff --git a/app/scripts/ui-old/settings/settings-logs-view.js b/app/scripts/ui-old/settings/settings-logs-view.js deleted file mode 100644 index c12e5ec7..00000000 --- a/app/scripts/ui-old/settings/settings-logs-view.js +++ /dev/null @@ -1,57 +0,0 @@ -import { View } from 'framework/views/view'; -import { StringFormat } from 'util/formatting/string-format'; -import { Logger } from 'util/logger'; -import template from 'templates/settings/settings-logs-view.hbs'; - -class SettingsLogsView extends View { - parent = '.settings__general-advanced'; - template = template; - levelToColor = { debug: 'muted', warn: 'yellow', error: 'red' }; - - render() { - const logs = Logger.getLast().map((item) => ({ - level: item.level, - color: this.levelToColor[item.level], - msg: - '[' + - StringFormat.padStr(item.level.toUpperCase(), 5) + - '] ' + - item.args.map((arg) => this.mapArg(arg)).join(' ') - })); - super.render({ logs }); - } - - mapArg(arg) { - if (arg === null) { - return 'null'; - } - if (arg === undefined) { - return 'undefined'; - } - if (arg === '') { - return '""'; - } - if (!arg || !arg.toString() || typeof arg !== 'object') { - return arg ? arg.toString() : arg; - } - if (arg instanceof Array) { - return '[' + arg.map((item) => this.mapArg(item)).join(', ') + ']'; - } - let str = arg.toString(); - if (str === '[object Object]') { - const cache = []; - str = JSON.stringify(arg, (key, value) => { - if (typeof value === 'object' && value !== null) { - if (cache.indexOf(value) !== -1) { - return; - } - cache.push(value); - } - return value; - }); - } - return str; - } -} - -export { SettingsLogsView }; diff --git a/app/scripts/ui/settings/general/settings-general-advanced.ts b/app/scripts/ui/settings/general/settings-general-advanced.ts index 2deb74af..7acef4a1 100644 --- a/app/scripts/ui/settings/general/settings-general-advanced.ts +++ b/app/scripts/ui/settings/general/settings-general-advanced.ts @@ -2,10 +2,53 @@ import { FunctionComponent, h } from 'preact'; import { SettingsGeneralAdvancedView } from 'views/settings/general/settings-general-advanced-view'; import { Launcher } from 'comp/launcher'; import { Features } from 'util/features'; +import { useState } from 'preact/hooks'; +import { Alerts } from 'comp/ui/alerts'; +import { Locale } from 'util/locale'; +import { Links } from 'const/links'; +import { FileManager } from 'models/file-manager'; export const SettingsGeneralAdvanced: FunctionComponent = () => { + const [showAdvanced, setShowAdvanced] = useState(false); + const [showAppLogs, setShowAppLogs] = useState(false); + + const showAdvancedChanged = () => { + setShowAdvanced(!showAdvanced); + }; + + const reloadAppClicked = () => { + location.reload(); + }; + + const showDevToolsClicked = () => { + Launcher?.ipcRenderer.invoke('show-devtools'); + }; + + const tryBetaClicked = () => { + if (FileManager.hasUnsavedFiles) { + Alerts.info({ + header: Locale.setGenTryBetaWarning, + body: Locale.setGenTryBetaWarningBody + }); + } else { + location.href = Links.BetaWebApp; + } + }; + + const showAppLogsClicked = () => { + setShowAppLogs(!showAppLogs); + }; + return h(SettingsGeneralAdvancedView, { + showAdvanced, + showAppLogs, devTools: !!Launcher, - showReloadApp: Features.isStandalone + showReloadApp: Features.isStandalone, + + showAdvancedChanged, + reloadAppClicked, + showDevToolsClicked, + tryBetaClicked, + showAppLogsClicked }); }; diff --git a/app/scripts/ui/settings/general/settings-general-app-logs.ts b/app/scripts/ui/settings/general/settings-general-app-logs.ts new file mode 100644 index 00000000..252397ae --- /dev/null +++ b/app/scripts/ui/settings/general/settings-general-app-logs.ts @@ -0,0 +1,67 @@ +import { FunctionComponent, h } from 'preact'; +import { SettingsGeneralAppLogsView } from 'views/settings/general/settings-general-app-logs-view'; +import { Logger, LoggerLevel } from 'util/logger'; +import { StringFormat } from 'util/formatting/string-format'; + +const LevelToColor: Partial> = { + [LoggerLevel.Debug]: 'muted', + [LoggerLevel.Warn]: 'yellow', + [LoggerLevel.Error]: 'red' +}; + +const LevelToString: Record = { + [LoggerLevel.Off]: 'OFF', + [LoggerLevel.All]: 'ALL', + [LoggerLevel.Debug]: 'DEBUG', + [LoggerLevel.Warn]: 'WARN', + [LoggerLevel.Info]: 'INFO', + [LoggerLevel.Error]: 'ERROR' +}; + +function mapArg(arg: unknown): string { + if (arg === null) { + return 'null'; + } + if (arg === undefined) { + return 'undefined'; + } + if (arg === '') { + return '""'; + } + if (!arg || !String(arg) || typeof arg !== 'object') { + return arg ? String(arg) : ''; + } + if (arg instanceof Array) { + return '[' + arg.map((item) => mapArg(item)).join(', ') + ']'; + } + let str = String(arg); + if (str === '[object Object]') { + const cache = new Set(); + str = JSON.stringify(arg, (key, value) => { + if (typeof value === 'object' && value !== null) { + if (cache.has(value)) { + return; + } + cache.add(value); + } + return value as unknown; + }); + } + return str; +} + +export const SettingsGeneralAppLogs: FunctionComponent = () => { + const logs = Logger.getLast().map((item) => ({ + level: LevelToString[item.level], + color: LevelToColor[item.level], + msg: + '[' + + StringFormat.padStr(LevelToString[item.level], 5) + + '] ' + + item.args.map((arg) => mapArg(arg)).join(' ') + })); + + return h(SettingsGeneralAppLogsView, { + logs + }); +}; diff --git a/app/scripts/util/logger.ts b/app/scripts/util/logger.ts index 24c38a55..76734cbb 100644 --- a/app/scripts/util/logger.ts +++ b/app/scripts/util/logger.ts @@ -12,7 +12,7 @@ enum Level { const MaxLogsToSave = 100; interface LogItem { - level: string; + level: Level; args: unknown[]; } @@ -50,7 +50,7 @@ class Logger { debug(...args: unknown[]): void { args[0] = `${this.getPrefix()}${String(args[0])}`; if (this.level >= Level.Debug) { - Logger.saveLast('debug', args); + Logger.saveLast(Level.Debug, args); console.log(...args); } } @@ -58,7 +58,7 @@ class Logger { info(...args: unknown[]): void { args[0] = `${this.getPrefix()}${String(args[0])}`; if (this.level >= Level.Info) { - Logger.saveLast('info', args); + Logger.saveLast(Level.Info, args); console.info(...args); } } @@ -66,7 +66,7 @@ class Logger { warn(...args: unknown[]): void { args[0] = `${this.getPrefix()}${String(args[0])}`; if (this.level >= Level.Warn) { - Logger.saveLast('warn', args); + Logger.saveLast(Level.Warn, args); console.warn(...args); } } @@ -74,12 +74,12 @@ class Logger { error(...args: unknown[]): void { args[0] = `${this.getPrefix()}${String(args[0])}`; if (this.level >= Level.Error) { - Logger.saveLast('error', args); + Logger.saveLast(Level.Error, args); console.error(...args); } } - static saveLast(level: string, args: unknown[]): void { + static saveLast(level: Level, args: unknown[]): void { lastLogs.push({ level, args: Array.prototype.slice.call(args) }); if (lastLogs.length > MaxLogsToSave) { lastLogs.shift(); @@ -91,4 +91,4 @@ class Logger { } } -export { Logger }; +export { Logger, Level as LoggerLevel }; diff --git a/app/scripts/views/settings/general/settings-general-advanced-view.tsx b/app/scripts/views/settings/general/settings-general-advanced-view.tsx index a307a65c..7ca799bd 100644 --- a/app/scripts/views/settings/general/settings-general-advanced-view.tsx +++ b/app/scripts/views/settings/general/settings-general-advanced-view.tsx @@ -1,34 +1,73 @@ import { FunctionComponent } from 'preact'; import { Locale } from 'util/locale'; +import { SettingsGeneralAppLogs } from 'ui/settings/general/settings-general-app-logs'; export const SettingsGeneralAdvancedView: FunctionComponent<{ + showAdvanced: boolean; devTools: boolean; showReloadApp: boolean; -}> = ({ devTools, showReloadApp }) => { + showAppLogs: boolean; + + showAdvancedChanged: () => void; + reloadAppClicked: () => void; + showDevToolsClicked: () => void; + tryBetaClicked: () => void; + showAppLogsClicked: () => void; +}> = ({ + showAdvanced, + devTools, + showReloadApp, + showAppLogs, + + showAdvancedChanged, + reloadAppClicked, + showDevToolsClicked, + tryBetaClicked, + showAppLogsClicked +}) => { return ( <>

{Locale.advanced}

- {Locale.setGenShowAdvanced} -
- {devTools ? ( - <> - + + + ) : null} + {showReloadApp ? ( + - - - ) : null} - {showReloadApp ? ( - - ) : null} - -
+ {showAppLogs ? : null} + + ) : null} ); }; diff --git a/app/scripts/views/settings/general/settings-general-app-logs-view.tsx b/app/scripts/views/settings/general/settings-general-app-logs-view.tsx new file mode 100644 index 00000000..94da1c23 --- /dev/null +++ b/app/scripts/views/settings/general/settings-general-app-logs-view.tsx @@ -0,0 +1,37 @@ +import { FunctionComponent } from 'preact'; +import { classes } from 'util/ui/classes'; +import { useLayoutEffect, useRef } from 'preact/hooks'; + +interface LogItem { + level: string; + msg: string; + color?: string; +} + +export const SettingsGeneralAppLogsView: FunctionComponent<{ + logs: LogItem[]; +}> = ({ logs }) => { + const lastLine = useRef(); + + useLayoutEffect(() => { + lastLine.current.scrollIntoView(); + }, []); + + return ( +
+ {logs.map((log, ix) => ( +
+                    {log.msg}
+                
+ ))} +
+
+ ); +}; diff --git a/app/templates/settings/settings-logs-view.hbs b/app/templates/settings/settings-logs-view.hbs deleted file mode 100644 index 2f7905a2..00000000 --- a/app/templates/settings/settings-logs-view.hbs +++ /dev/null @@ -1,5 +0,0 @@ -
- {{#each logs as |log|}} -
{{msg}}
- {{/each}} -
diff --git a/desktop/desktop-ipc.d.ts b/desktop/desktop-ipc.d.ts index 78e1a02e..d6ef4d9d 100644 --- a/desktop/desktop-ipc.d.ts +++ b/desktop/desktop-ipc.d.ts @@ -119,4 +119,5 @@ export interface DesktopIpcMainCalls { 'minimize-main-window': () => void; 'maximize-main-window': () => void; 'restore-main-window': () => void; + 'show-devtools': () => void; }