From e7d3bc6d350dfc8829ef27a94f6a920f4b22a9df Mon Sep 17 00:00:00 2001 From: Vincent Date: Wed, 8 Jan 2020 17:21:39 +1100 Subject: [PATCH] Settings view modals and categories --- _locales/en/messages.json | 34 +++- js/background.js | 19 +- js/views/app_view.js | 6 +- js/views/session_confirm_view.js | 3 + stylesheets/_session.scss | 17 +- .../_session_theme_dark_left_pane.scss | 22 +-- ts/components/LeftPane.tsx | 8 +- .../session/LeftPaneContactSection.tsx | 3 +- .../session/LeftPaneSettingSection.tsx | 171 ++++++++++++------ ts/components/session/SessionConfirm.tsx | 28 ++- ts/components/session/SessionQRModal.tsx | 2 +- ts/components/session/SessionSeedModal.tsx | 1 + ts/components/session/SessionToast.tsx | 1 - ts/global.d.ts | 4 + 14 files changed, 231 insertions(+), 88 deletions(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 771ea4681..46d15bc9e 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -1162,6 +1162,14 @@ "message": "Delete Account", "description": "Text for button in settings view to delete account" }, + "deleteAccountWarning": { + "message": "Are you sure you want to delete your account?", + "description": "Warning for account deletion in settings view" + }, + "deleteAccountWarningSub": { + "message": "This is completely irreversible and will leave no trace.", + "description": "Warning for account deletion in settings view" + }, "deleteContact": { "message": "Delete Contact", "description": @@ -1341,7 +1349,7 @@ "description": "Text describing what the clear data button will do." }, "clearDataButton": { - "message": "Clear data", + "message": "Clear Data", "description": "Button in the settings dialog starting process to delete all data" }, @@ -2471,5 +2479,29 @@ }, "decline": { "message": "Decline" + }, + "accountSettingsTitle": { + "message": "Account" + }, + "accountSettingsDescription": { + "message": "Manage your account" + }, + "privacySettingsTitle": { + "message": "Privacy" + }, + "privacySettingsDescription": { + "message": "Privacy description" + }, + "notificationSettingsTitle": { + "message": "Notifications" + }, + "notificationSettingsDescription": { + "message": "Choose what you're notified about." + }, + "devicesSettingsTitle": { + "message": "Devices" + }, + "devicesSettingsDescription": { + "message": "Managed linked devices." } } diff --git a/js/background.js b/js/background.js index 7d08eee07..7c0dd6455 100644 --- a/js/background.js +++ b/js/background.js @@ -807,15 +807,21 @@ el: $('#session-confirm-container'), title: params.title, message: params.message, + messageSub: params.messageSub || undefined, resolve: params.resolve || undefined, reject: params.reject || undefined, okText: params.okText || undefined, + okTheme: params.okTheme || undefined, + closeTheme: params.closeTheme || undefined, cancelText: params.cancelText || undefined, hideCancel: params.hideCancel || false, }); + confirmDialog.render(); }; + window.showSeedDialog = window.owsDesktopApp.appView.showSeedDialog; + window.generateID = () => Math.random() .toString(36) @@ -866,6 +872,13 @@ return toastID; }; + window.deleteAccount = () => { + // Delete local data + // TOOD. MAKE THIS PROCESS SECURED WITH rm-secure + // https://www.npmjs.com/package/secure-rm + alert('YOUR ACCOUNT HAS BEEN DELETED'); + } + window.sendGroupInvitations = (serverInfo, pubkeys) => { pubkeys.forEach(async pubkey => { const convo = await ConversationController.getOrCreateAndWait( @@ -1132,10 +1145,8 @@ }); Whisper.events.on('showSeedDialog', async () => { - const manager = await getAccountManager(); - if (appView && manager) { - const seed = manager.getCurrentMnemonic(); - appView.showSeedDialog(seed); + if (appView) { + appView.showSeedDialog(); } }); diff --git a/js/views/app_view.js b/js/views/app_view.js index 2b2fb0fb6..d984250d1 100644 --- a/js/views/app_view.js +++ b/js/views/app_view.js @@ -15,6 +15,8 @@ this.applyTheme(); this.applyHideMenu(); + + this.showSeedDialog = this.showSeedDialog.bind(this); }, events: { 'click .openInstaller': 'openInstaller', // NetworkStatusView has this button @@ -200,8 +202,8 @@ const dialog = Whisper.PasswordDialogView(); this.el.append(dialog.el); }, - showSeedDialog(seed) { - const dialog = new Whisper.SeedDialogView({ seed }); + showSeedDialog() { + const dialog = new Whisper.SeedDialogView(); this.el.append(dialog.el); }, showQRDialog(string) { diff --git a/js/views/session_confirm_view.js b/js/views/session_confirm_view.js index 4fc0335c8..42084513a 100644 --- a/js/views/session_confirm_view.js +++ b/js/views/session_confirm_view.js @@ -11,12 +11,15 @@ this.props = { title: options.title, message: options.message, + messageSub: options.messageSub, onClickOk: this.ok.bind(this), onClickClose: this.cancel.bind(this), resolve: options.resolve, reject: options.reject, okText: options.okText, cancelText: options.cancelText, + okTheme: options.okTheme, + closeTheme: options.closeTheme, hideCancel: options.hideCancel, }; }, diff --git a/stylesheets/_session.scss b/stylesheets/_session.scss index c04e01e5b..29d8922e1 100644 --- a/stylesheets/_session.scss +++ b/stylesheets/_session.scss @@ -579,6 +579,7 @@ label { font-size: 15px; line-height: 13px; margin-bottom: $session-margin-sm; + padding-top: 0px; color: $session-color-white; } @@ -698,6 +699,21 @@ label { } } +.session-confirm { + &-wrapper { + .session-modal__body .session-modal__centered{ + margin: $session-margin-lg + } + } + + &-main-message{ + font-size: 15px; + } + &-sub-message { + margin-top: 5px; + } +} + .session-toggle { width: 51px; height: 31px; @@ -899,4 +915,3 @@ label { .messages li { transition: $session-transition-duration !important; } - diff --git a/stylesheets/_session_theme_dark_left_pane.scss b/stylesheets/_session_theme_dark_left_pane.scss index e13e55ff7..c74f53288 100644 --- a/stylesheets/_session_theme_dark_left_pane.scss +++ b/stylesheets/_session_theme_dark_left_pane.scss @@ -265,8 +265,7 @@ $session-compose-margin: 20px; .session-button.square-outline.square.green, .session-button.square-outline.square.white, - .session-button.square-outline.square.danger - { + .session-button.square-outline.square.danger { flex-grow: 1; border: 1px solid $session-shade-7; height: 50px; @@ -342,13 +341,13 @@ $session-compose-margin: 20px; } } - .left-pane-setting { &-bottom-buttons { @include bottom-buttons(); } - &-content, &-section { + &-content, + &-section { display: flex; flex-direction: column; } @@ -364,22 +363,20 @@ $session-compose-margin: 20px; padding: 0px 12px; cursor: pointer; - transition: $session-transition-duration !important; + transition: $session-transition-duration !important; - &>div { + & > div { display: block; } - &.active{ + &.active { background-color: $session-shade-9; } - &:hover{ + &:hover { background-color: $session-shade-7; } - - &__buttons { display: flex; @@ -392,8 +389,11 @@ $session-compose-margin: 20px; } } } -} + &-input-group { + display: inline-flex; + } +} .panel-text-divider { width: 100%; diff --git a/ts/components/LeftPane.tsx b/ts/components/LeftPane.tsx index e88d8db3b..c41c6c11d 100644 --- a/ts/components/LeftPane.tsx +++ b/ts/components/LeftPane.tsx @@ -240,12 +240,8 @@ export class LeftPane extends React.Component { } private renderSettingSection() { - const { - } = this.props; + const {} = this.props; - return ( - - ); + return ; } } diff --git a/ts/components/session/LeftPaneContactSection.tsx b/ts/components/session/LeftPaneContactSection.tsx index 978427070..a265c04b0 100644 --- a/ts/components/session/LeftPaneContactSection.tsx +++ b/ts/components/session/LeftPaneContactSection.tsx @@ -148,7 +148,7 @@ export class LeftPaneContactSection extends React.Component { return; } - // reset our pubKeyPasted, we can either have a pasted sessionID or a sessionID got from a search + this.setState({ pubKeyPasted: '' }, () => { window.Session.emptyContentEditableDivs(); }); @@ -171,7 +171,6 @@ export class LeftPaneContactSection extends React.Component { public clearSearch() { this.props.clearSearch(); - //this.setFocus(); } public search() { diff --git a/ts/components/session/LeftPaneSettingSection.tsx b/ts/components/session/LeftPaneSettingSection.tsx index f94725da5..ae07f9504 100644 --- a/ts/components/session/LeftPaneSettingSection.tsx +++ b/ts/components/session/LeftPaneSettingSection.tsx @@ -9,47 +9,48 @@ import { SessionButtonType, } from './SessionButton'; -import { - SessionIcon, - SessionIconSize, - SessionIconType, -} from './icon'; +import { SessionIcon, SessionIconSize, SessionIconType } from './icon'; +import { SessionSearchInput } from './SessionSearchInput'; +import { Session } from 'inspector'; export enum SessionSettingCategory { + Account = 'account', Privacy = 'privacy', Notifications = 'notifications', Devices = 'devices', } -export interface Props { - -} +export interface Props {} export interface State { settingCategory: SessionSettingCategory; + searchQuery: string; } export class LeftPaneSettingSection extends React.Component { - + //private readonly updateSearchBound: (searchedString: string) => void; + public constructor(props: Props) { super(props); this.state = { settingCategory: SessionSettingCategory.Privacy, + searchQuery: '', }; this.setCategory = this.setCategory.bind(this); this.renderRows = this.renderRows.bind(this); + //this.updateSearchBound = this.updateSearch.bind(this); } public render(): JSX.Element { return (
- {this.renderHeader()} - - {this.renderSettings()} + {this.renderHeader()} + + {this.renderSettings()}
); } @@ -62,67 +63,78 @@ export class LeftPaneSettingSection extends React.Component { null, undefined, undefined, - undefined, + undefined ); } - public renderRows () { - + public renderRows(): JSX.Element { const categories = this.getCategories(); return ( <> - {categories.map((item) => ( -
this.setCategory(item.id)} - > -
- { item.title } -
- - {item.description } - -
- -
- { item.id === this.state.settingCategory && - - } -
+ {categories.map(item => ( +
this.setCategory(item.id)} + > +
+ {item.title} +
+ {item.description}
- ))} +
+ {item.id === this.state.settingCategory && ( + + )} +
+
+ ))} ); } - public renderCategories() { - + public renderCategories(): JSX.Element { return (
-
- {this.renderRows()} -
+
+ {this.renderRows()} +
- ) + ); } public renderSettings(): JSX.Element { return (
+
+ null} + placeholder='' + /> +
+ '} + /> +
+
{this.renderCategories()} {this.renderBottomButtons()}
); } - public renderBottomButtons(): JSX.Element { const deleteAccount = window.i18n('deleteAccount'); const showSeed = window.i18n('showSeed'); @@ -133,33 +145,54 @@ export class LeftPaneSettingSection extends React.Component { text={deleteAccount} buttonType={SessionButtonType.SquareOutline} buttonColor={SessionButtonColor.Danger} + onClick={this.onDeleteAccount} />
); } - public getCategories(){ + public onDeleteAccount() { + + const params = { + title: window.i18n('deleteAccount'), + message: window.i18n('deleteAccountWarning'), + messageSub: window.i18n('deleteAccountWarningSub'), + resolve: window.deleteAccount, + okTheme: 'danger', + }; + + window.confirmationDialog(params); + + } + + public getCategories() { return [ + { + id: SessionSettingCategory.Account, + title: window.i18n('accountSettingsTitle'), + description: window.i18n('accountSettingsDescription'), + }, { id: SessionSettingCategory.Privacy, - title: 'Privacy', - description: 'Privacy description', + title: window.i18n('privacySettingsTitle'), + description: window.i18n('privacySettingsDescription'), }, { id: SessionSettingCategory.Notifications, - title: 'Notifications', - description: "Choose what you're notified about." + title: window.i18n('notificationSettingsTitle'), + description: window.i18n('notificationSettingsDescription'), }, { id: SessionSettingCategory.Devices, - title: 'Linked Devices', - description: "Managed linked devices." - } + title: window.i18n('devicesSettingsTitle'), + description: window.i18n('devicesSettingsDescription'), + }, ]; } @@ -168,4 +201,34 @@ export class LeftPaneSettingSection extends React.Component { settingCategory: category, }); } + + // public updateSearch(searchTerm: string) { + // const { updateSearchTerm, clearSearch } = this.props; + + // if (!searchTerm) { + // clearSearch(); + + // return; + // } + // // reset our pubKeyPasted, we can either have a pasted sessionID or a sessionID got from a search + // this.setState({ pubKeyPasted: '' }, () => { + // window.Session.emptyContentEditableDivs(); + // }); + + // if (updateSearchTerm) { + // updateSearchTerm(searchTerm); + // } + + // if (searchTerm.length < 2) { + // return; + // } + + // const cleanedTerm = cleanSearchTerm(searchTerm); + // if (!cleanedTerm) { + // return; + // } + + // this.debouncedSearch(cleanedTerm); + // } + } diff --git a/ts/components/session/SessionConfirm.tsx b/ts/components/session/SessionConfirm.tsx index b473e6d34..d1d798144 100644 --- a/ts/components/session/SessionConfirm.tsx +++ b/ts/components/session/SessionConfirm.tsx @@ -1,9 +1,10 @@ import React from 'react'; import { SessionModal } from './SessionModal'; -import { SessionButton } from './SessionButton'; +import { SessionButton, SessionButtonColor } from './SessionButton'; interface Props { message: string; + messageSub: string; title: string; onOk?: any; onClose?: any; @@ -12,11 +13,16 @@ interface Props { okText?: string; cancelText?: string; hideCancel: boolean; + okTheme: SessionButtonColor; + closeTheme: SessionButtonColor; } export class SessionConfirm extends React.Component { public static defaultProps = { title: '', + messageSub: '', + okTheme: SessionButtonColor.Primary, + closeTheme: SessionButtonColor.Primary, hideCancel: false, }; @@ -25,7 +31,7 @@ export class SessionConfirm extends React.Component { } public render() { - const { title, message, onClickOk, onClickClose, hideCancel } = this.props; + const { title, message, messageSub, okTheme, closeTheme, onClickOk, onClickClose, hideCancel } = this.props; const okText = this.props.okText || window.i18n('ok'); const cancelText = this.props.cancelText || window.i18n('cancel'); @@ -42,19 +48,31 @@ export class SessionConfirm extends React.Component { {!showHeader &&
}
- {message} + {message} + { messageSub && ( + {messageSub} + )}
- + {!hideCancel && ( - + )}
); } + } diff --git a/ts/components/session/SessionQRModal.tsx b/ts/components/session/SessionQRModal.tsx index e0f124b93..b930daf0d 100644 --- a/ts/components/session/SessionQRModal.tsx +++ b/ts/components/session/SessionQRModal.tsx @@ -32,7 +32,7 @@ export class SessionQRModal extends React.Component {
- +
diff --git a/ts/components/session/SessionSeedModal.tsx b/ts/components/session/SessionSeedModal.tsx index 38208a0ce..3b0bbb149 100644 --- a/ts/components/session/SessionSeedModal.tsx +++ b/ts/components/session/SessionSeedModal.tsx @@ -213,6 +213,7 @@ export class SessionSeedModal extends React.Component { title: window.i18n('copiedMnemonic'), type: 'success', id: 'copySeedToast', + shouldFade: false, }); } diff --git a/ts/components/session/SessionToast.tsx b/ts/components/session/SessionToast.tsx index 49b5cba61..f33b5f8f6 100644 --- a/ts/components/session/SessionToast.tsx +++ b/ts/components/session/SessionToast.tsx @@ -20,7 +20,6 @@ interface Props { id?: string; type?: SessionToastType; description?: string; - fadeToast: any; closeToast: any; } diff --git a/ts/global.d.ts b/ts/global.d.ts index 335d7db69..3f0a3aa9e 100644 --- a/ts/global.d.ts +++ b/ts/global.d.ts @@ -1,5 +1,7 @@ interface Window { Events: any; + deleteAllData: any; + deleteAccount: any; getAccountManager: any; mnemonic: any; clipboard: any; @@ -19,6 +21,8 @@ interface Window { generateID: any; storage: any; pushToast: any; + confirmationDialog: any; + showSeedDialog: any; } interface Promise {