From b3e5ca340d913b9b1c2212da286dcb685ba417e3 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Wed, 23 Sep 2020 22:33:33 -0500 Subject: [PATCH] feat: improve strings, challenges, and template readiness --- .../javascripts/directives/views/accountMenu.ts | 2 +- .../javascripts/directives/views/actionsMenu.ts | 6 +++--- app/assets/javascripts/services/alertService.ts | 2 +- .../javascripts/services/autolock_service.ts | 17 ++++++----------- app/assets/javascripts/services/themeManager.ts | 1 - app/assets/javascripts/strings.ts | 8 +++----- app/assets/javascripts/ui_models/application.ts | 17 ----------------- .../views/abstract/pure_view_ctrl.ts | 8 +++++++- .../views/application/application_view.ts | 2 -- .../views/challenge_modal/challenge-modal.pug | 10 +++++----- .../views/challenge_modal/challenge_modal.ts | 14 -------------- .../javascripts/views/footer/footer_view.ts | 2 +- .../javascripts/views/notes/note_utils.ts | 2 +- app/assets/stylesheets/_modals.scss | 3 ++- app/assets/stylesheets/_ui.scss | 4 ++++ .../javascripts/services/autolock_service.d.ts | 7 +++---- dist/@types/app/assets/javascripts/strings.d.ts | 5 +++-- .../javascripts/ui_models/application.d.ts | 1 - .../views/abstract/pure_view_ctrl.d.ts | 5 +++++ package-lock.json | 4 ++-- package.json | 2 +- 21 files changed, 48 insertions(+), 74 deletions(-) diff --git a/app/assets/javascripts/directives/views/accountMenu.ts b/app/assets/javascripts/directives/views/accountMenu.ts index 1f77902ca..8d9e334ab 100644 --- a/app/assets/javascripts/directives/views/accountMenu.ts +++ b/app/assets/javascripts/directives/views/accountMenu.ts @@ -1,5 +1,5 @@ import { WebDirective } from './../../types'; -import { isDesktopApplication, isNullOrUndefined, preventRefreshing } from '@/utils'; +import { isDesktopApplication, preventRefreshing } from '@/utils'; import template from '%/directives/account-menu.pug'; import { ProtectedAction, ContentType } from 'snjs'; import { PureViewCtrl } from '@Views/abstract/pure_view_ctrl'; diff --git a/app/assets/javascripts/directives/views/actionsMenu.ts b/app/assets/javascripts/directives/views/actionsMenu.ts index 80dec8457..42a7cb5fe 100644 --- a/app/assets/javascripts/directives/views/actionsMenu.ts +++ b/app/assets/javascripts/directives/views/actionsMenu.ts @@ -3,7 +3,7 @@ import { WebDirective } from './../../types'; import template from '%/directives/actions-menu.pug'; import { PureViewCtrl } from '@Views/abstract/pure_view_ctrl'; import { SNItem, Action, SNActionsExtension, UuidString } from 'snjs/dist/@types'; -import { ActionResponse } from 'snjs/dist/@types/services/actions_service'; +import { ActionResponse } from 'snjs'; import { ActionsExtensionMutator } from 'snjs/dist/@types/models/app/extension'; type ActionsMenuScope = { @@ -144,8 +144,8 @@ class ActionsMenuCtrl extends PureViewCtrl<{}, ActionsMenuState> implements Acti } private async updateAction( - action: Action, - extension: SNActionsExtension, + action: Action, + extension: SNActionsExtension, params: UpdateActionParams ) { const updatedExtension = await this.application.changeItem(extension.uuid, (mutator) => { diff --git a/app/assets/javascripts/services/alertService.ts b/app/assets/javascripts/services/alertService.ts index 0e5ae1bec..38c0d457a 100644 --- a/app/assets/javascripts/services/alertService.ts +++ b/app/assets/javascripts/services/alertService.ts @@ -1,5 +1,5 @@ /* eslint-disable prefer-promise-reject-errors */ -import { SNAlertService, ButtonType, DismissBlockingDialog } from 'snjs'; +import { SNAlertService, ButtonType } from 'snjs'; import { SKAlert } from 'sn-stylekit'; /** @returns a promise resolving to true if the user confirmed, false if they canceled */ diff --git a/app/assets/javascripts/services/autolock_service.ts b/app/assets/javascripts/services/autolock_service.ts index 81b6f5db1..22e3d1d8f 100644 --- a/app/assets/javascripts/services/autolock_service.ts +++ b/app/assets/javascripts/services/autolock_service.ts @@ -1,4 +1,4 @@ -import { ApplicationGroup } from './../ui_models/application_group'; +import { ApplicationService } from 'snjs'; import { WebApplication } from '@/ui_models/application'; import { isDesktopApplication } from '@/utils'; import { AppStateEvent } from '@/ui_models/app_state'; @@ -13,26 +13,21 @@ const LOCK_INTERVAL_ONE_HOUR = 3600 * MILLISECONDS_PER_SECOND; const STORAGE_KEY_AUTOLOCK_INTERVAL = "AutoLockIntervalKey"; -export class AutolockService { +export class AutolockService extends ApplicationService { - private application: WebApplication private unsubState: any private pollFocusInterval: any private lastFocusState?: 'hidden' | 'visible' private lockAfterDate?: Date private lockTimeout?: any - constructor( - application: WebApplication - ) { - this.application = application; - setTimeout(() => { - this.observeVisibility(); - }, 0); + onAppLaunch() { + this.observeVisibility(); + return super.onAppLaunch(); } observeVisibility() { - this.unsubState = this.application.getAppState().addObserver( + this.unsubState = (this.application as WebApplication).getAppState().addObserver( async (eventName) => { if (eventName === AppStateEvent.WindowDidBlur) { this.documentVisibilityChanged(false); diff --git a/app/assets/javascripts/services/themeManager.ts b/app/assets/javascripts/services/themeManager.ts index d223beb01..487b4f7bb 100644 --- a/app/assets/javascripts/services/themeManager.ts +++ b/app/assets/javascripts/services/themeManager.ts @@ -1,5 +1,4 @@ import { WebApplication } from '@/ui_models/application'; -import _ from 'lodash'; import { StorageValueModes, EncryptionIntent, diff --git a/app/assets/javascripts/strings.ts b/app/assets/javascripts/strings.ts index 88261996d..d80dd225d 100644 --- a/app/assets/javascripts/strings.ts +++ b/app/assets/javascripts/strings.ts @@ -46,8 +46,6 @@ export const STRING_INVALID_IMPORT_FILE = "Unable to open file. Ensure it is a p export function StringImportError(errorCount: number) { return `Import complete. ${errorCount} items were not imported because there was an error decrypting them. Make sure the password is correct and try again.`; } -export const STRING_STORAGE_UPDATE = 'Storage Update'; -export const STRING_AUTHENTICATION_REQUIRED = 'Authentication Required'; export const STRING_UNSUPPORTED_BACKUP_FILE_VERSION = 'This backup file was created using an unsupported version of the application and cannot be imported here. Please update your application and try again.'; /** @password_change */ @@ -67,8 +65,8 @@ export const STRING_CONFIRM_APP_QUIT_DURING_PASSCODE_REMOVAL = export const STRING_UPGRADE_ACCOUNT_CONFIRM_TITLE = 'Encryption upgrade available'; export const STRING_UPGRADE_ACCOUNT_CONFIRM_TEXT = - 'Encryption version 004 is available for your account and local data storage. ' + - 'This version strengthens the encryption algorithms for your account and ' + - 'disk use. To learn more about this upgrade, visit our ' + + 'Encryption version 004 is available. ' + + 'This version strengthens the encryption algorithms your account and ' + + 'local storage use. To learn more about this upgrade, visit our ' + 'Security Upgrade page.'; export const STRING_UPGRADE_ACCOUNT_CONFIRM_BUTTON = 'Upgrade'; diff --git a/app/assets/javascripts/ui_models/application.ts b/app/assets/javascripts/ui_models/application.ts index b6ecce1c9..57b3d0bdf 100644 --- a/app/assets/javascripts/ui_models/application.ts +++ b/app/assets/javascripts/ui_models/application.ts @@ -4,9 +4,7 @@ import { EditorGroup } from '@/ui_models/editor_group'; import { InputModalScope } from '@/directives/views/inputModal'; import { PasswordWizardType, PasswordWizardScope } from '@/types'; import { - Environment, SNApplication, - SNAlertService, platformFromString, Challenge, ProtectedAction @@ -167,21 +165,6 @@ export class WebApplication extends SNApplication { angular.element(document.body).append(el); } - async performProtocolUpgrade() { - const result = await this.upgradeProtocolVersion(); - if (result.success) { - this.alertService!.alert( - "Success! Your encryption version has been upgraded." + - " You'll be asked to enter your credentials again on other devices you're signed into." - ); - } else if (result.error) { - console.error(result.error); - this.alertService!.alert( - "Unable to upgrade encryption version. Please try again." - ); - } - } - async presentPrivilegesModal( action: ProtectedAction, onSuccess?: any, diff --git a/app/assets/javascripts/views/abstract/pure_view_ctrl.ts b/app/assets/javascripts/views/abstract/pure_view_ctrl.ts index e73224cf4..81734b617 100644 --- a/app/assets/javascripts/views/abstract/pure_view_ctrl.ts +++ b/app/assets/javascripts/views/abstract/pure_view_ctrl.ts @@ -12,6 +12,11 @@ export class PureViewCtrl

{ private unsubApp: any private unsubState: any private stateTimeout?: ng.IPromise + /** + * Subclasses can optionally add an ng-if=ctrl.templateReady to make sure that + * no Angular handlebars/syntax render in the UI before display data is ready. + */ + protected templateReady = false /* @ngInject */ constructor( @@ -28,6 +33,7 @@ export class PureViewCtrl

{ } this.addAppEventObserver(); this.addAppStateObserver(); + this.templateReady = true; } deinit() { @@ -114,7 +120,7 @@ export class PureViewCtrl

{ await this.onAppLaunch(); } else if (eventName === ApplicationEvent.CompletedIncrementalSync) { this.onAppIncrementalSync(); - } else if (eventName === ApplicationEvent.CompletedFullSync) { + } else if (eventName === ApplicationEvent.CompletedFullSync) { this.onAppFullSync(); } else if (eventName === ApplicationEvent.KeyStatusChanged) { this.onAppKeyChange(); diff --git a/app/assets/javascripts/views/application/application_view.ts b/app/assets/javascripts/views/application/application_view.ts index df0862162..9a36f37eb 100644 --- a/app/assets/javascripts/views/application/application_view.ts +++ b/app/assets/javascripts/views/application/application_view.ts @@ -10,12 +10,10 @@ import { PANEL_NAME_TAGS } from '@/views/constants'; import { - STRING_SESSION_EXPIRED, STRING_DEFAULT_FILE_ERROR } from '@/strings'; import { PureViewCtrl } from '@Views/abstract/pure_view_ctrl'; import { PermissionDialog } from 'snjs/dist/@types/services/component_manager'; -import { alertDialog } from '@/services/alertService'; class ApplicationViewCtrl extends PureViewCtrl { private $compile?: ng.ICompileService diff --git a/app/assets/javascripts/views/challenge_modal/challenge-modal.pug b/app/assets/javascripts/views/challenge_modal/challenge-modal.pug index b7b2595ed..a54e5d766 100644 --- a/app/assets/javascripts/views/challenge_modal/challenge-modal.pug +++ b/app/assets/javascripts/views/challenge_modal/challenge-modal.pug @@ -1,15 +1,15 @@ .sk-modal-background(ng-click="ctrl.cancel()") -.challenge-modal.sk-modal-content +.challenge-modal.sk-modal-content(ng-if='ctrl.templateReady') .sn-component .sk-panel .sk-panel-header - .sk-panel-header-title {{ctrl.modalTitle}} + .sk-panel-header-title {{ctrl.challenge.modalTitle}} .sk-panel-content .sk-panel-section .sk-p.sk-panel-row.centered.prompt - strong {{ctrl.state.title}} - .sk-p.sk-panel-row.centered.subprompt(ng-if='ctrl.state.subtitle') - | {{ctrl.state.subtitle}} + strong {{ctrl.challenge.heading}} + .sk-p.sk-panel-row.centered.subprompt(ng-if='ctrl.challenge.subheading') + | {{ctrl.challenge.subheading}} .sk-panel-section div(ng-repeat="prompt in ctrl.state.prompts track by prompt.id") .sk-panel-row diff --git a/app/assets/javascripts/views/challenge_modal/challenge_modal.ts b/app/assets/javascripts/views/challenge_modal/challenge_modal.ts index d73dc415e..4356cfbcc 100644 --- a/app/assets/javascripts/views/challenge_modal/challenge_modal.ts +++ b/app/assets/javascripts/views/challenge_modal/challenge_modal.ts @@ -12,8 +12,6 @@ import { WebDirective } from '@/types'; import { confirmDialog } from '@/services/alertService'; import { STRING_SIGN_OUT_CONFIRMATION, - STRING_STORAGE_UPDATE, - STRING_AUTHENTICATION_REQUIRED, } from '@/strings'; type InputValue = { @@ -32,8 +30,6 @@ type ChallengeModalState = { showForgotPasscodeLink: boolean, processingPrompts: ChallengePrompt[], hasAccount: boolean, - title: string, - subtitle: string } class ChallengeModalCtrl extends PureViewCtrl<{}, ChallengeModalState> { @@ -93,8 +89,6 @@ class ChallengeModalCtrl extends PureViewCtrl<{}, ChallengeModalState> { forgotPasscode: false, showForgotPasscodeLink, hasAccount: this.application.hasAccount(), - title: this.challenge.title, - subtitle: this.challenge.subtitle, processingPrompts: [] }); this.application.addChallengeObserver( @@ -137,14 +131,6 @@ class ChallengeModalCtrl extends PureViewCtrl<{}, ChallengeModalState> { }); } - get modalTitle(): string { - if (this.challenge.reason === ChallengeReason.Migration) { - return STRING_STORAGE_UPDATE; - } else { - return STRING_AUTHENTICATION_REQUIRED; - } - } - async destroyLocalData() { if (await confirmDialog({ text: STRING_SIGN_OUT_CONFIRMATION, diff --git a/app/assets/javascripts/views/footer/footer_view.ts b/app/assets/javascripts/views/footer/footer_view.ts index b42deab33..b6ff6ff21 100644 --- a/app/assets/javascripts/views/footer/footer_view.ts +++ b/app/assets/javascripts/views/footer/footer_view.ts @@ -347,7 +347,7 @@ class FooterViewCtrl extends PureViewCtrl<{}, { confirmButtonText: STRING_UPGRADE_ACCOUNT_CONFIRM_BUTTON, })) { preventRefreshing(STRING_CONFIRM_APP_QUIT_DURING_UPGRADE, async () => { - await this.application.performProtocolUpgrade(); + await this.application.upgradeProtocolVersion(); }); } } diff --git a/app/assets/javascripts/views/notes/note_utils.ts b/app/assets/javascripts/views/notes/note_utils.ts index 6d763ccef..2c7577b5f 100644 --- a/app/assets/javascripts/views/notes/note_utils.ts +++ b/app/assets/javascripts/views/notes/note_utils.ts @@ -1,4 +1,4 @@ -import { SNNote, SNTag } from 'snjs'; +import { SNNote } from 'snjs'; export enum NoteSortKey { CreatedAt = 'created_at', diff --git a/app/assets/stylesheets/_modals.scss b/app/assets/stylesheets/_modals.scss index 8220d1fdf..cb7668d37 100644 --- a/app/assets/stylesheets/_modals.scss +++ b/app/assets/stylesheets/_modals.scss @@ -13,8 +13,9 @@ .challenge-modal { max-width: 480px; + min-width: 400px !important; - .prompt { + .prompt, .subprompt { text-align: center; } .sk-panel .sk-panel-header { diff --git a/app/assets/stylesheets/_ui.scss b/app/assets/stylesheets/_ui.scss index 29ab8cb69..116518d37 100644 --- a/app/assets/stylesheets/_ui.scss +++ b/app/assets/stylesheets/_ui.scss @@ -57,6 +57,10 @@ $screen-md-max: ($screen-lg-min - 1) !default; } } +[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { + display: none !important; +} + .selectable { user-select: text !important; cursor: text; diff --git a/dist/@types/app/assets/javascripts/services/autolock_service.d.ts b/dist/@types/app/assets/javascripts/services/autolock_service.d.ts index 7a0d92401..4ac99fcae 100644 --- a/dist/@types/app/assets/javascripts/services/autolock_service.d.ts +++ b/dist/@types/app/assets/javascripts/services/autolock_service.d.ts @@ -1,12 +1,11 @@ -import { WebApplication } from '@/ui_models/application'; -export declare class AutolockService { - private application; +import { ApplicationService } from 'snjs'; +export declare class AutolockService extends ApplicationService { private unsubState; private pollFocusInterval; private lastFocusState?; private lockAfterDate?; private lockTimeout?; - constructor(application: WebApplication); + onAppLaunch(): Promise; observeVisibility(): void; deinit(): void; private lockApplication; diff --git a/dist/@types/app/assets/javascripts/strings.d.ts b/dist/@types/app/assets/javascripts/strings.d.ts index be22b76a0..ffcada422 100644 --- a/dist/@types/app/assets/javascripts/strings.d.ts +++ b/dist/@types/app/assets/javascripts/strings.d.ts @@ -32,11 +32,12 @@ export declare const STRING_GENERATING_LOGIN_KEYS = "Generating Login Keys..."; export declare const STRING_GENERATING_REGISTER_KEYS = "Generating Account Keys..."; export declare const STRING_INVALID_IMPORT_FILE = "Unable to open file. Ensure it is a proper JSON file and try again."; export declare function StringImportError(errorCount: number): string; -export declare const STRING_STORAGE_UPDATE = "Storage Update"; -export declare const STRING_AUTHENTICATION_REQUIRED = "Authentication Required"; export declare const STRING_UNSUPPORTED_BACKUP_FILE_VERSION = "This backup file was created using an unsupported version of the application and cannot be imported here. Please update your application and try again."; /** @password_change */ export declare const STRING_FAILED_PASSWORD_CHANGE = "There was an error re-encrypting your items. Your password was changed, but not all your items were properly re-encrypted and synced. You should try syncing again. If all else fails, you should restore your notes from backup."; export declare const STRING_CONFIRM_APP_QUIT_DURING_UPGRADE: string; export declare const STRING_CONFIRM_APP_QUIT_DURING_PASSCODE_CHANGE: string; export declare const STRING_CONFIRM_APP_QUIT_DURING_PASSCODE_REMOVAL: string; +export declare const STRING_UPGRADE_ACCOUNT_CONFIRM_TITLE = "Encryption upgrade available"; +export declare const STRING_UPGRADE_ACCOUNT_CONFIRM_TEXT: string; +export declare const STRING_UPGRADE_ACCOUNT_CONFIRM_BUTTON = "Upgrade"; diff --git a/dist/@types/app/assets/javascripts/ui_models/application.d.ts b/dist/@types/app/assets/javascripts/ui_models/application.d.ts index 12223b172..264e854da 100644 --- a/dist/@types/app/assets/javascripts/ui_models/application.d.ts +++ b/dist/@types/app/assets/javascripts/ui_models/application.d.ts @@ -42,7 +42,6 @@ export declare class WebApplication extends SNApplication { checkForSecurityUpdate(): Promise; presentPasswordWizard(type: PasswordWizardType): void; promptForChallenge(challenge: Challenge): void; - performProtocolUpgrade(): Promise; presentPrivilegesModal(action: ProtectedAction, onSuccess?: any, onCancel?: any): Promise; presentPrivilegesManagementModal(): void; authenticationInProgress(): boolean; diff --git a/dist/@types/app/assets/javascripts/views/abstract/pure_view_ctrl.d.ts b/dist/@types/app/assets/javascripts/views/abstract/pure_view_ctrl.d.ts index 38387e19a..937a04176 100644 --- a/dist/@types/app/assets/javascripts/views/abstract/pure_view_ctrl.d.ts +++ b/dist/@types/app/assets/javascripts/views/abstract/pure_view_ctrl.d.ts @@ -12,6 +12,11 @@ export declare class PureViewCtrl

{ private unsubApp; private unsubState; private stateTimeout?; + /** + * Subclasses can optionally add an ng-if=ctrl.templateReady to make sure that + * no Angular handlebars/syntax render in the UI before display data is ready. + */ + protected templateReady: boolean; constructor($timeout: ng.ITimeoutService, props?: P); $onInit(): void; deinit(): void; diff --git a/package-lock.json b/package-lock.json index 1a2377da0..78154b4d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10956,8 +10956,8 @@ "from": "github:standardnotes/sncrypto#8794c88daa967eaae493cd5fdec7506d52b257ad" }, "snjs": { - "version": "github:standardnotes/snjs#6a0e03eaca106ffda7bce7d87761a29fd8f8420d", - "from": "github:standardnotes/snjs#6a0e03eaca106ffda7bce7d87761a29fd8f8420d" + "version": "github:standardnotes/snjs#723200296d6481b8835a8a3651130e38a9eaf449", + "from": "github:standardnotes/snjs#723200296d6481b8835a8a3651130e38a9eaf449" }, "sockjs": { "version": "0.3.20", diff --git a/package.json b/package.json index eff192948..b18fa112a 100644 --- a/package.json +++ b/package.json @@ -68,6 +68,6 @@ }, "dependencies": { "sncrypto": "github:standardnotes/sncrypto#8794c88daa967eaae493cd5fdec7506d52b257ad", - "snjs": "github:standardnotes/snjs#6a0e03eaca106ffda7bce7d87761a29fd8f8420d" + "snjs": "github:standardnotes/snjs#723200296d6481b8835a8a3651130e38a9eaf449" } }