From cbe53edb823fbca803f7e1e1582df153a0d63db4 Mon Sep 17 00:00:00 2001 From: Baptiste Grob <60621355+baptiste-grob@users.noreply.github.com> Date: Thu, 7 Jan 2021 16:54:59 +0100 Subject: [PATCH 1/9] fix: restrict max reach dialog width --- app/assets/stylesheets/_reach-sub.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/assets/stylesheets/_reach-sub.scss b/app/assets/stylesheets/_reach-sub.scss index b6a9446cf..af80a7ccf 100644 --- a/app/assets/stylesheets/_reach-sub.scss +++ b/app/assets/stylesheets/_reach-sub.scss @@ -25,6 +25,7 @@ position: relative; overflow: unset; flex-basis: 0; + max-width: 600px; } [data-reach-dialog-content] .sk-modal-content, From a39d8ed72ed3edaafda51f356e5c2a0a54027293 Mon Sep 17 00:00:00 2001 From: Baptiste Grob <60621355+baptiste-grob@users.noreply.github.com> Date: Thu, 7 Jan 2021 17:39:25 +0100 Subject: [PATCH 2/9] feat: remove account menu sync spinner --- app/assets/javascripts/directives/views/accountMenu.ts | 4 +--- app/assets/templates/directives/account-menu.pug | 10 ---------- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/app/assets/javascripts/directives/views/accountMenu.ts b/app/assets/javascripts/directives/views/accountMenu.ts index 21ed1a884..8f1e0b757 100644 --- a/app/assets/javascripts/directives/views/accountMenu.ts +++ b/app/assets/javascripts/directives/views/accountMenu.ts @@ -68,7 +68,6 @@ type AccountMenuState = { errorReportingEnabled: boolean; syncInProgress: boolean; syncError: string; - syncPercentage: string; showSessions: boolean; } @@ -143,7 +142,6 @@ class AccountMenuCtrl extends PureViewCtrl<{}, AccountMenuState> { this.setState({ syncInProgress: sync.inProgress, syncError: sync.errorMessage, - syncPercentage: sync.humanReadablePercentage, }); }) this.removeBetaWarningListener = autorun(() => { @@ -636,7 +634,7 @@ class AccountMenuCtrl extends PureViewCtrl<{}, AccountMenuState> { } else { storage.set(StorageKey.DisableErrorReporting, false); } - if (!this.application.getSyncStatus().syncInProgress) { + if (!this.state.syncInProgress) { window.location.reload(); } } diff --git a/app/assets/templates/directives/account-menu.pug b/app/assets/templates/directives/account-menu.pug index 6c3572309..d891f114a 100644 --- a/app/assets/templates/directives/account-menu.pug +++ b/app/assets/templates/directives/account-menu.pug @@ -150,16 +150,6 @@ .sk-panel-column .sk-h1.sk-bold.wrap {{self.state.user.email}} .sk-subtitle.subtle.normal {{self.state.server}} - .sk-horizontal-group( - delay='1000', - delay-hide='true', - show='self.state.syncInProgress' - ) - .sk-spinner.small.info - .sk-sublabel - | Syncing - span(ng-if='self.state.syncPercentage') - | ({{self.state.syncPercentage}}) .sk-panel-row a.sk-a.info.sk-panel-row.condensed( ng-click="self.openPasswordWizard()" From d44748fcad6e353839295d6b9dd17419a329ab47 Mon Sep 17 00:00:00 2001 From: Baptiste Grob <60621355+baptiste-grob@users.noreply.github.com> Date: Mon, 11 Jan 2021 13:17:41 +0100 Subject: [PATCH 3/9] feat: make error reporting opt-in --- .../javascripts/directives/views/accountMenu.ts | 2 +- app/assets/javascripts/services/errorReporting.ts | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/directives/views/accountMenu.ts b/app/assets/javascripts/directives/views/accountMenu.ts index 8f1e0b757..7d73e82ab 100644 --- a/app/assets/javascripts/directives/views/accountMenu.ts +++ b/app/assets/javascripts/directives/views/accountMenu.ts @@ -100,7 +100,7 @@ class AccountMenuCtrl extends PureViewCtrl<{}, AccountMenuState> { }, mutable: {}, showBetaWarning: false, - errorReportingEnabled: !storage.get(StorageKey.DisableErrorReporting), + errorReportingEnabled: storage.get(StorageKey.DisableErrorReporting) === false, showSessions: false, } as AccountMenuState; } diff --git a/app/assets/javascripts/services/errorReporting.ts b/app/assets/javascripts/services/errorReporting.ts index 50c439db5..0a309e3ab 100644 --- a/app/assets/javascripts/services/errorReporting.ts +++ b/app/assets/javascripts/services/errorReporting.ts @@ -1,4 +1,4 @@ -import { SNLog } from '@standardnotes/snjs'; +import { isNullOrUndefined, SNLog } from '@standardnotes/snjs'; import { isDesktopApplication, isDev } from '@/utils'; import { storage, StorageKey } from './localStorage'; import Bugsnag from '@bugsnag/js'; @@ -6,6 +6,7 @@ import Bugsnag from '@bugsnag/js'; declare const __VERSION__: string; declare global { interface Window { + // eslint-disable-next-line camelcase _bugsnag_api_key?: string; } } @@ -21,8 +22,15 @@ function redactFilePath(line: string): string { } export function startErrorReporting() { + const disableErrorReporting = storage.get(StorageKey.DisableErrorReporting); if ( - storage.get(StorageKey.DisableErrorReporting) || + /** + * Error reporting used to be opt-out, but is now opt-in, so + * treat the absence of an error reporting preference as an indication + * to disable error reporting. + */ + isNullOrUndefined(disableErrorReporting) || + disableErrorReporting || !window._bugsnag_api_key ) { SNLog.onError = console.error; From 5a3b810896e98741dff27c766a2dc4573b4d57ee Mon Sep 17 00:00:00 2001 From: Baptiste Grob <60621355+baptiste-grob@users.noreply.github.com> Date: Mon, 11 Jan 2021 13:18:00 +0100 Subject: [PATCH 4/9] fix: eslint config --- .eslintrc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.eslintrc b/.eslintrc index 657cd2c81..91b24e84a 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,11 +1,15 @@ { - "extends": ["eslint:recommended", "semistandard", "prettier"], - "parser": "babel-eslint", + "extends": ["eslint:recommended", "prettier"], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "project": "./app/assets/javascripts/tsconfig.json" + }, "rules": { "standard/no-callback-literal": 0, // Disable this as we have too many callbacks relying on literals "no-throw-literal": 0, - // "no-console": "error", - "semi": 1 + "no-console": "warn", + "semi": 1, + "camelcase": "warn" }, "env": { "browser": true From ff85c9c6401a74c415885caebc7b84457d95d918 Mon Sep 17 00:00:00 2001 From: Baptiste Grob <60621355+baptiste-grob@users.noreply.github.com> Date: Mon, 11 Jan 2021 17:19:10 +0100 Subject: [PATCH 5/9] chore(deps): upgrade snjs --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 1659fd071..5ea684dc0 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "@reach/alert-dialog": "^0.12.1", "@reach/dialog": "^0.12.1", "@standardnotes/sncrypto-web": "^1.2.9", - "@standardnotes/snjs": "^2.0.35", + "@standardnotes/snjs": "^2.0.38", "babel-loader": "^8.2.2", "mobx": "^6.0.4", "preact": "^10.5.7" diff --git a/yarn.lock b/yarn.lock index 556ffb807..2bf6585af 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1045,10 +1045,10 @@ "@standardnotes/sncrypto-common" "^1.2.7" libsodium-wrappers "^0.7.8" -"@standardnotes/snjs@^2.0.35": - version "2.0.35" - resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.0.35.tgz#9e9c3058ebbfc9af7a5fc3ae18497f02a9b1e71b" - integrity sha512-uA4HXorgiV8yFGN1dtO52istUudnc3ZzEQiFLgf0bkKvA0wH3Xt+R9bBviYAdIBkTBKHCyGsBdsCiKr1QS/X9g== +"@standardnotes/snjs@^2.0.38": + version "2.0.38" + resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.0.38.tgz#3edbdc6c04926f2f4940aea8ebb6c7007f6d4235" + integrity sha512-cr+jdtDOyrwKlad/SRCy/D/cIsEQdShEsuazSIajpvXhwo9ixkj/wv/o0r3GrHug6CgXLOQRgzuZ9eZvi0PM9g== dependencies: "@standardnotes/sncrypto-common" "^1.2.9" From e1f590f2f04119dba3a1d12a8c981c0c25d4a14c Mon Sep 17 00:00:00 2001 From: Baptiste Grob <60621355+baptiste-grob@users.noreply.github.com> Date: Mon, 11 Jan 2021 17:42:35 +0100 Subject: [PATCH 6/9] fix: TypeScript errors after upgrading SNJS --- .eslintrc | 2 +- .../javascripts/services/archiveManager.ts | 40 +++++++++---------- .../javascripts/services/desktopManager.ts | 20 +++++----- 3 files changed, 30 insertions(+), 32 deletions(-) diff --git a/.eslintrc b/.eslintrc index 91b24e84a..aaf9f4170 100644 --- a/.eslintrc +++ b/.eslintrc @@ -7,7 +7,7 @@ "rules": { "standard/no-callback-literal": 0, // Disable this as we have too many callbacks relying on literals "no-throw-literal": 0, - "no-console": "warn", + "no-console": "off", "semi": 1, "camelcase": "warn" }, diff --git a/app/assets/javascripts/services/archiveManager.ts b/app/assets/javascripts/services/archiveManager.ts index c1b183dbd..eaa800f3e 100644 --- a/app/assets/javascripts/services/archiveManager.ts +++ b/app/assets/javascripts/services/archiveManager.ts @@ -1,5 +1,5 @@ import { WebApplication } from '@/ui_models/application'; -import { EncryptionIntent, ProtectedAction, SNItem, ContentType, SNNote } from '@standardnotes/snjs'; +import { EncryptionIntent, ProtectedAction, SNItem, ContentType, SNNote, BackupFile } from '@standardnotes/snjs'; function zippableTxtName(name: string, suffix = ""): string { const sanitizedName = name @@ -22,22 +22,27 @@ export class ArchiveManager { } public async downloadBackup(encrypted: boolean) { - const items = this.application.allItems(); - const run = async () => { - // download in Standard Notes format const intent = encrypted ? EncryptionIntent.FileEncrypted : EncryptionIntent.FileDecrypted; + + const data = await this.application.createBackupFile(intent); + if (!data) { + return; + } + const blobData = new Blob( + [JSON.stringify(data, null, 2)], + { type: 'text/json' } + ); if (encrypted) { - const data = await this.itemsData(items, intent); this.downloadData( - data!, + blobData, `Standard Notes Encrypted Backup and Import File - ${this.formattedDate()}.txt` ); } else { /** download as zipped plain text files */ - this.downloadZippedItems(items); + this.downloadZippedDecryptedItems(data); } }; @@ -65,15 +70,6 @@ export class ArchiveManager { return string; } - private async itemsData(items: SNItem[], intent: EncryptionIntent) { - const data = await this.application.createBackupFile(items, intent); - if (!data) { - return undefined; - } - const blobData = new Blob([data], { type: 'text/json' }); - return blobData; - } - private get zip() { return (window as any).zip; } @@ -95,17 +91,19 @@ export class ArchiveManager { }); } - private async downloadZippedItems( - items: SNItem[] + private async downloadZippedDecryptedItems( + data: BackupFile ) { await this.loadZip(); + const items = data.items; this.zip.createWriter( new this.zip.BlobWriter('application/zip'), async (zipWriter: any) => { - - const data = await this.application.createBackupFile(items, EncryptionIntent.FileDecrypted); await new Promise((resolve) => { - const blob = new Blob([data!], { type: 'text/plain' }); + const blob = new Blob( + [JSON.stringify(data, null, 2)], + { type: 'text/plain' } + ); const fileName = zippableTxtName( 'Standard Notes Backup and Import File.txt' ); diff --git a/app/assets/javascripts/services/desktopManager.ts b/app/assets/javascripts/services/desktopManager.ts index baae0aca2..a0663676f 100644 --- a/app/assets/javascripts/services/desktopManager.ts +++ b/app/assets/javascripts/services/desktopManager.ts @@ -9,8 +9,8 @@ import { Bridge } from './bridge'; type UpdateObserverCallback = (component: SNComponent) => void type ComponentActivationCallback = (payload: PurePayload) => void type ComponentActivationObserver = { - id: string, - callback: ComponentActivationCallback + id: string; + callback: ComponentActivationCallback; } export class DesktopManager extends ApplicationService { @@ -19,8 +19,9 @@ export class DesktopManager extends ApplicationService { $timeout: ng.ITimeoutService componentActivationObservers: ComponentActivationObserver[] = [] updateObservers: { - callback: UpdateObserverCallback - }[] = [] + callback: UpdateObserverCallback; + }[] = []; + isDesktop = isDesktopApplication(); dataLoaded = false @@ -187,12 +188,11 @@ export class DesktopManager extends ApplicationService { }); } - desktop_requestBackupFile() { - return this.application!.createBackupFile( - undefined, - undefined, - true - ); + async desktop_requestBackupFile() { + const data = this.application!.createBackupFile(EncryptionIntent.FileEncrypted); + if (data) { + return JSON.stringify(data, null, 2); + } } desktop_didBeginBackup() { From 4d3bb22a8bbf0842c8943545f0cc15ec0f77f8d8 Mon Sep 17 00:00:00 2001 From: Baptiste Grob <60621355+baptiste-grob@users.noreply.github.com> Date: Tue, 12 Jan 2021 11:44:01 +0100 Subject: [PATCH 7/9] fix: lint errors --- .eslintrc | 3 ++- app/assets/javascripts/services/desktopManager.ts | 2 +- .../javascripts/views/challenge_modal/challenge_modal.ts | 6 +++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.eslintrc b/.eslintrc index aaf9f4170..c88737d79 100644 --- a/.eslintrc +++ b/.eslintrc @@ -9,7 +9,8 @@ "no-throw-literal": 0, "no-console": "off", "semi": 1, - "camelcase": "warn" + "camelcase": "warn", + "sort-imports": "off" }, "env": { "browser": true diff --git a/app/assets/javascripts/services/desktopManager.ts b/app/assets/javascripts/services/desktopManager.ts index a0663676f..c7e2d8665 100644 --- a/app/assets/javascripts/services/desktopManager.ts +++ b/app/assets/javascripts/services/desktopManager.ts @@ -157,7 +157,7 @@ export class DesktopManager extends ApplicationService { undefined ); } - }) + }); this.$timeout(() => { for (const observer of this.updateObservers) { diff --git a/app/assets/javascripts/views/challenge_modal/challenge_modal.ts b/app/assets/javascripts/views/challenge_modal/challenge_modal.ts index a605dac9f..0291a41a9 100644 --- a/app/assets/javascripts/views/challenge_modal/challenge_modal.ts +++ b/app/assets/javascripts/views/challenge_modal/challenge_modal.ts @@ -15,9 +15,9 @@ import { } from '@/strings'; type InputValue = { - prompt: ChallengePrompt - value: string - invalid: boolean + prompt: ChallengePrompt; + value: string; + invalid: boolean; } type Values = Record From 3fa8cc103b78f9ebd49d115fb9f446fc99100c29 Mon Sep 17 00:00:00 2001 From: Baptiste Grob <60621355+baptiste-grob@users.noreply.github.com> Date: Tue, 12 Jan 2021 18:17:34 +0100 Subject: [PATCH 8/9] fix: reload document once if tab is hidden in firefox --- app/assets/javascripts/app.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/app/assets/javascripts/app.ts b/app/assets/javascripts/app.ts index 69cb4fcab..4051a7883 100644 --- a/app/assets/javascripts/app.ts +++ b/app/assets/javascripts/app.ts @@ -59,10 +59,35 @@ import { StartApplication } from './startApplication'; import { Bridge } from './services/bridge'; import { SessionsModalDirective } from './directives/views/sessionsModal'; + +function reloadHiddenFirefoxTab(): boolean { + /** + * For Firefox pinned tab issue: + * When a new browser session is started, and SN is in a pinned tab, + * SN exhibits strange behavior until the tab is reloaded. + */ + if ( + document.hidden && + navigator.userAgent.toLowerCase().includes('firefox') && + !localStorage.getItem('reloading') + ) { + localStorage.setItem('reloading', 'true'); + location.reload(); + return true; + } else { + localStorage.removeItem('reloading'); + return false; + } +} + const startApplication: StartApplication = async function startApplication( defaultSyncServerHost: string, bridge: Bridge ) { + if (reloadHiddenFirefoxTab()) { + return; + } + SNLog.onLog = console.log; startErrorReporting(); From 5dfdade3ca30d03e56a3367f32fa75997b30fab3 Mon Sep 17 00:00:00 2001 From: Baptiste Grob <60621355+baptiste-grob@users.noreply.github.com> Date: Wed, 13 Jan 2021 12:11:09 +0100 Subject: [PATCH 9/9] chore(version): 3.5.15 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5ea684dc0..d12100e3f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "standard-notes-web", - "version": "3.5.14", + "version": "3.5.15", "license": "AGPL-3.0-or-later", "repository": { "type": "git",