diff --git a/lib/app.jsx b/lib/app.jsx index 8af19890d..3441d9618 100644 --- a/lib/app.jsx +++ b/lib/app.jsx @@ -517,7 +517,13 @@ export const App = connect(mapStateToProps, mapDispatchToProps)( throw new Error('Unknown dialog type.'); } - return ; + return ( + + ); }, }) ); diff --git a/lib/dialogs/settings.jsx b/lib/dialogs/settings.jsx index cb1c142a7..8bd654661 100644 --- a/lib/dialogs/settings.jsx +++ b/lib/dialogs/settings.jsx @@ -13,6 +13,7 @@ export const SettingsDialog = React.createClass({ propTypes: { actions: PropTypes.object.isRequired, onSignOut: PropTypes.func.isRequired, + isElectron: PropTypes.bool.isRequired, }, onDone() { @@ -37,6 +38,72 @@ export const SettingsDialog = React.createClass({ }); }, + onSignOutRequested() { + // Safety first! Check for any unsynced notes before signing out. + const { onSignOut, noteBucket } = this.props; + const { notes } = this.props.appState; + const { getVersion } = noteBucket; + + noteBucket.hasLocalChanges((error, hasChanges) => { + if (hasChanges) { + this.showUnsyncedWarning(); + return; + } + + // Also check persisted store for any notes with version 0 + const noteHasSynced = note => + new Promise((resolve, reject) => + getVersion(note.id, (e, v) => (e || v === 0 ? reject() : resolve())) + ); + + Promise.all(notes.map(noteHasSynced)).then( + () => onSignOut(), // All good, sign out now! + () => this.showUnsyncedWarning() // Show a warning to the user + ); + }); + }, + + showUnsyncedWarning() { + const { isElectron } = this.props; + isElectron ? this.showElectronWarningDialog() : this.showWebWarningDialog(); + }, + + showElectronWarningDialog() { + const { onSignOut } = this.props; + const dialog = __non_webpack_require__('electron').remote.dialog; // eslint-disable-line no-undef + dialog.showMessageBox( + { + type: 'warning', + buttons: ['Delete Notes', 'Cancel', 'Visit Web App'], + title: 'Unsynced Notes Detected', + message: + 'Logging out will delete any unsynced notes. You can verify your ' + + 'synced notes by logging in to the Web App.', + }, + response => { + if (response === 0) { + onSignOut(); + } else if (response === 2) { + viewExternalUrl('https://app.simplenote.com'); + } + } + ); + }, + + showWebWarningDialog() { + const { onSignOut } = this.props; + const shouldReallySignOut = confirm( + 'Warning: Unsynced notes were detected.\n\n' + + 'Logging out will delete any notes that have not synced. ' + + 'Check your connection and visit app.simplenote.com to verify synced notes.' + + '\n\nClick OK to delete unsynced notes and Log Out.' + ); + + if (shouldReallySignOut) { + onSignOut(); + } + }, + render() { var dialog = this.props.dialog; @@ -91,7 +158,7 @@ export const SettingsDialog = React.createClass({ diff --git a/package.json b/package.json index be4c090e0..c3e4e0bfa 100644 --- a/package.json +++ b/package.json @@ -14,19 +14,19 @@ "build": "NODE_ENV=development npm run build:dll && npm run build:app", "build:app": "webpack --config ./webpack.config.js", "build:dll": "webpack --config ./webpack.config.dll.js", - "build:prod": - "NODE_ENV=production webpack -p --config ./webpack.config.dll.js && webpack -p --config ./webpack.config.js", + "build:prod": "NODE_ENV=production webpack -p --config ./webpack.config.dll.js && webpack -p --config ./webpack.config.js", "format": "prettier --write {desktop,lib,sass}/{**/,*}.{js,json,jsx,sass}", "lint": "eslint --ext .js --ext .jsx lib", - "start": - "NODE_ENV=hot npm run build && webpack-dev-server --config ./webpack.config.js --content-base dist --host 0.0.0.0 --port 4000 --hot --inline" + "start": "NODE_ENV=hot npm run build && webpack-dev-server --config ./webpack.config.js --content-base dist --host 0.0.0.0 --port 4000 --hot --inline" }, "license": "ISC", "engines": { "node": "7.9.0", "npm": "4.2.0" }, - "browserslist": ["Chrome >= 58"], + "browserslist": [ + "Chrome >= 58" + ], "jest": { "rootDir": "lib", "testRegex": "(/test/.*\\.jsx?)|(test\\.jsx?)$" @@ -99,7 +99,7 @@ "serve-favicon": "2.4.3", "showdown": "1.7.2", "showdown-xss-filter": "0.2.0", - "simperium": "0.2.9" + "simperium": "0.3.1" }, "optionalDependencies": { "appdmg": "0.4.5"