Settings view modals and categories

pull/717/head
Vincent 5 years ago
parent 589f77a85f
commit e7d3bc6d35

@ -1162,6 +1162,14 @@
"message": "Delete Account", "message": "Delete Account",
"description": "Text for button in settings view to 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": { "deleteContact": {
"message": "Delete Contact", "message": "Delete Contact",
"description": "description":
@ -1341,7 +1349,7 @@
"description": "Text describing what the clear data button will do." "description": "Text describing what the clear data button will do."
}, },
"clearDataButton": { "clearDataButton": {
"message": "Clear data", "message": "Clear Data",
"description": "description":
"Button in the settings dialog starting process to delete all data" "Button in the settings dialog starting process to delete all data"
}, },
@ -2471,5 +2479,29 @@
}, },
"decline": { "decline": {
"message": "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."
} }
} }

@ -807,15 +807,21 @@
el: $('#session-confirm-container'), el: $('#session-confirm-container'),
title: params.title, title: params.title,
message: params.message, message: params.message,
messageSub: params.messageSub || undefined,
resolve: params.resolve || undefined, resolve: params.resolve || undefined,
reject: params.reject || undefined, reject: params.reject || undefined,
okText: params.okText || undefined, okText: params.okText || undefined,
okTheme: params.okTheme || undefined,
closeTheme: params.closeTheme || undefined,
cancelText: params.cancelText || undefined, cancelText: params.cancelText || undefined,
hideCancel: params.hideCancel || false, hideCancel: params.hideCancel || false,
}); });
confirmDialog.render(); confirmDialog.render();
}; };
window.showSeedDialog = window.owsDesktopApp.appView.showSeedDialog;
window.generateID = () => window.generateID = () =>
Math.random() Math.random()
.toString(36) .toString(36)
@ -866,6 +872,13 @@
return toastID; 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) => { window.sendGroupInvitations = (serverInfo, pubkeys) => {
pubkeys.forEach(async pubkey => { pubkeys.forEach(async pubkey => {
const convo = await ConversationController.getOrCreateAndWait( const convo = await ConversationController.getOrCreateAndWait(
@ -1132,10 +1145,8 @@
}); });
Whisper.events.on('showSeedDialog', async () => { Whisper.events.on('showSeedDialog', async () => {
const manager = await getAccountManager(); if (appView) {
if (appView && manager) { appView.showSeedDialog();
const seed = manager.getCurrentMnemonic();
appView.showSeedDialog(seed);
} }
}); });

@ -15,6 +15,8 @@
this.applyTheme(); this.applyTheme();
this.applyHideMenu(); this.applyHideMenu();
this.showSeedDialog = this.showSeedDialog.bind(this);
}, },
events: { events: {
'click .openInstaller': 'openInstaller', // NetworkStatusView has this button 'click .openInstaller': 'openInstaller', // NetworkStatusView has this button
@ -200,8 +202,8 @@
const dialog = Whisper.PasswordDialogView(); const dialog = Whisper.PasswordDialogView();
this.el.append(dialog.el); this.el.append(dialog.el);
}, },
showSeedDialog(seed) { showSeedDialog() {
const dialog = new Whisper.SeedDialogView({ seed }); const dialog = new Whisper.SeedDialogView();
this.el.append(dialog.el); this.el.append(dialog.el);
}, },
showQRDialog(string) { showQRDialog(string) {

@ -11,12 +11,15 @@
this.props = { this.props = {
title: options.title, title: options.title,
message: options.message, message: options.message,
messageSub: options.messageSub,
onClickOk: this.ok.bind(this), onClickOk: this.ok.bind(this),
onClickClose: this.cancel.bind(this), onClickClose: this.cancel.bind(this),
resolve: options.resolve, resolve: options.resolve,
reject: options.reject, reject: options.reject,
okText: options.okText, okText: options.okText,
cancelText: options.cancelText, cancelText: options.cancelText,
okTheme: options.okTheme,
closeTheme: options.closeTheme,
hideCancel: options.hideCancel, hideCancel: options.hideCancel,
}; };
}, },

@ -579,6 +579,7 @@ label {
font-size: 15px; font-size: 15px;
line-height: 13px; line-height: 13px;
margin-bottom: $session-margin-sm; margin-bottom: $session-margin-sm;
padding-top: 0px;
color: $session-color-white; 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 { .session-toggle {
width: 51px; width: 51px;
height: 31px; height: 31px;
@ -899,4 +915,3 @@ label {
.messages li { .messages li {
transition: $session-transition-duration !important; transition: $session-transition-duration !important;
} }

@ -265,8 +265,7 @@ $session-compose-margin: 20px;
.session-button.square-outline.square.green, .session-button.square-outline.square.green,
.session-button.square-outline.square.white, .session-button.square-outline.square.white,
.session-button.square-outline.square.danger .session-button.square-outline.square.danger {
{
flex-grow: 1; flex-grow: 1;
border: 1px solid $session-shade-7; border: 1px solid $session-shade-7;
height: 50px; height: 50px;
@ -342,13 +341,13 @@ $session-compose-margin: 20px;
} }
} }
.left-pane-setting { .left-pane-setting {
&-bottom-buttons { &-bottom-buttons {
@include bottom-buttons(); @include bottom-buttons();
} }
&-content, &-section { &-content,
&-section {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
@ -364,22 +363,20 @@ $session-compose-margin: 20px;
padding: 0px 12px; padding: 0px 12px;
cursor: pointer; cursor: pointer;
transition: $session-transition-duration !important; transition: $session-transition-duration !important;
&>div { & > div {
display: block; display: block;
} }
&.active{ &.active {
background-color: $session-shade-9; background-color: $session-shade-9;
} }
&:hover{ &:hover {
background-color: $session-shade-7; background-color: $session-shade-7;
} }
&__buttons { &__buttons {
display: flex; display: flex;
@ -392,8 +389,11 @@ $session-compose-margin: 20px;
} }
} }
} }
}
&-input-group {
display: inline-flex;
}
}
.panel-text-divider { .panel-text-divider {
width: 100%; width: 100%;

@ -240,12 +240,8 @@ export class LeftPane extends React.Component<Props, State> {
} }
private renderSettingSection() { private renderSettingSection() {
const { const {} = this.props;
} = this.props;
return ( return <LeftPaneSettingSection />;
<LeftPaneSettingSection
/>
);
} }
} }

@ -148,7 +148,7 @@ export class LeftPaneContactSection extends React.Component<Props, any> {
return; return;
} }
// reset our pubKeyPasted, we can either have a pasted sessionID or a sessionID got from a search
this.setState({ pubKeyPasted: '' }, () => { this.setState({ pubKeyPasted: '' }, () => {
window.Session.emptyContentEditableDivs(); window.Session.emptyContentEditableDivs();
}); });
@ -171,7 +171,6 @@ export class LeftPaneContactSection extends React.Component<Props, any> {
public clearSearch() { public clearSearch() {
this.props.clearSearch(); this.props.clearSearch();
//this.setFocus();
} }
public search() { public search() {

@ -9,47 +9,48 @@ import {
SessionButtonType, SessionButtonType,
} from './SessionButton'; } from './SessionButton';
import { import { SessionIcon, SessionIconSize, SessionIconType } from './icon';
SessionIcon, import { SessionSearchInput } from './SessionSearchInput';
SessionIconSize, import { Session } from 'inspector';
SessionIconType,
} from './icon';
export enum SessionSettingCategory { export enum SessionSettingCategory {
Account = 'account',
Privacy = 'privacy', Privacy = 'privacy',
Notifications = 'notifications', Notifications = 'notifications',
Devices = 'devices', Devices = 'devices',
} }
export interface Props { export interface Props {}
}
export interface State { export interface State {
settingCategory: SessionSettingCategory; settingCategory: SessionSettingCategory;
searchQuery: string;
} }
export class LeftPaneSettingSection extends React.Component<Props, State> { export class LeftPaneSettingSection extends React.Component<Props, State> {
//private readonly updateSearchBound: (searchedString: string) => void;
public constructor(props: Props) { public constructor(props: Props) {
super(props); super(props);
this.state = { this.state = {
settingCategory: SessionSettingCategory.Privacy, settingCategory: SessionSettingCategory.Privacy,
searchQuery: '',
}; };
this.setCategory = this.setCategory.bind(this); this.setCategory = this.setCategory.bind(this);
this.renderRows = this.renderRows.bind(this); this.renderRows = this.renderRows.bind(this);
//this.updateSearchBound = this.updateSearch.bind(this);
} }
public render(): JSX.Element { public render(): JSX.Element {
return ( return (
<div className="left-pane-setting-section"> <div className="left-pane-setting-section">
{this.renderHeader()} {this.renderHeader()}
{this.renderSettings()} {this.renderSettings()}
</div> </div>
); );
} }
@ -62,67 +63,78 @@ export class LeftPaneSettingSection extends React.Component<Props, State> {
null, null,
undefined, undefined,
undefined, undefined,
undefined, undefined
); );
} }
public renderRows () { public renderRows(): JSX.Element {
const categories = this.getCategories(); const categories = this.getCategories();
return ( return (
<> <>
{categories.map((item) => ( {categories.map(item => (
<div <div
key={item.id} key={item.id}
className={classNames('left-pane-setting-category-list-item', item.id === this.state.settingCategory ? 'active' : '')} className={classNames(
onClick={() => this.setCategory(item.id)} 'left-pane-setting-category-list-item',
> item.id === this.state.settingCategory ? 'active' : ''
<div> )}
<strong>{ item.title }</strong> onClick={() => this.setCategory(item.id)}
<br/> >
<span className="text-subtle"> <div>
{item.description } <strong>{item.title}</strong>
</span> <br />
</div> <span className="text-subtle">{item.description}</span>
<div>
{ item.id === this.state.settingCategory &&
<SessionIcon
iconSize={SessionIconSize.Medium}
iconType={SessionIconType.Chevron}
iconRotation={270}
/>
}
</div>
</div> </div>
))}
<div>
{item.id === this.state.settingCategory && (
<SessionIcon
iconSize={SessionIconSize.Medium}
iconType={SessionIconType.Chevron}
iconRotation={270}
/>
)}
</div>
</div>
))}
</> </>
); );
} }
public renderCategories() { public renderCategories(): JSX.Element {
return ( return (
<div className="module-left-pane__list" key={0}> <div className="module-left-pane__list" key={0}>
<div className="left-pane-setting-category-list"> <div className="left-pane-setting-category-list">
{this.renderRows()} {this.renderRows()}
</div> </div>
</div> </div>
) );
} }
public renderSettings(): JSX.Element { public renderSettings(): JSX.Element {
return ( return (
<div className="left-pane-setting-content"> <div className="left-pane-setting-content">
<div className="left-pane-setting-input-group">
<SessionSearchInput
searchString={this.state.searchQuery}
onChange={() => null}
placeholder=''
/>
<div className="left-pane-setting-input-button">
<SessionButton
buttonType={SessionButtonType.Square}
buttonColor={SessionButtonColor.Green}
text={'>'}
/>
</div>
</div>
{this.renderCategories()} {this.renderCategories()}
{this.renderBottomButtons()} {this.renderBottomButtons()}
</div> </div>
); );
} }
public renderBottomButtons(): JSX.Element { public renderBottomButtons(): JSX.Element {
const deleteAccount = window.i18n('deleteAccount'); const deleteAccount = window.i18n('deleteAccount');
const showSeed = window.i18n('showSeed'); const showSeed = window.i18n('showSeed');
@ -133,33 +145,54 @@ export class LeftPaneSettingSection extends React.Component<Props, State> {
text={deleteAccount} text={deleteAccount}
buttonType={SessionButtonType.SquareOutline} buttonType={SessionButtonType.SquareOutline}
buttonColor={SessionButtonColor.Danger} buttonColor={SessionButtonColor.Danger}
onClick={this.onDeleteAccount}
/> />
<SessionButton <SessionButton
text={showSeed} text={showSeed}
buttonType={SessionButtonType.SquareOutline} buttonType={SessionButtonType.SquareOutline}
buttonColor={SessionButtonColor.White} buttonColor={SessionButtonColor.White}
onClick={window.showSeedDialog}
/> />
</div> </div>
); );
} }
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 [ return [
{
id: SessionSettingCategory.Account,
title: window.i18n('accountSettingsTitle'),
description: window.i18n('accountSettingsDescription'),
},
{ {
id: SessionSettingCategory.Privacy, id: SessionSettingCategory.Privacy,
title: 'Privacy', title: window.i18n('privacySettingsTitle'),
description: 'Privacy description', description: window.i18n('privacySettingsDescription'),
}, },
{ {
id: SessionSettingCategory.Notifications, id: SessionSettingCategory.Notifications,
title: 'Notifications', title: window.i18n('notificationSettingsTitle'),
description: "Choose what you're notified about." description: window.i18n('notificationSettingsDescription'),
}, },
{ {
id: SessionSettingCategory.Devices, id: SessionSettingCategory.Devices,
title: 'Linked Devices', title: window.i18n('devicesSettingsTitle'),
description: "Managed linked devices." description: window.i18n('devicesSettingsDescription'),
} },
]; ];
} }
@ -168,4 +201,34 @@ export class LeftPaneSettingSection extends React.Component<Props, State> {
settingCategory: category, 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);
// }
} }

@ -1,9 +1,10 @@
import React from 'react'; import React from 'react';
import { SessionModal } from './SessionModal'; import { SessionModal } from './SessionModal';
import { SessionButton } from './SessionButton'; import { SessionButton, SessionButtonColor } from './SessionButton';
interface Props { interface Props {
message: string; message: string;
messageSub: string;
title: string; title: string;
onOk?: any; onOk?: any;
onClose?: any; onClose?: any;
@ -12,11 +13,16 @@ interface Props {
okText?: string; okText?: string;
cancelText?: string; cancelText?: string;
hideCancel: boolean; hideCancel: boolean;
okTheme: SessionButtonColor;
closeTheme: SessionButtonColor;
} }
export class SessionConfirm extends React.Component<Props> { export class SessionConfirm extends React.Component<Props> {
public static defaultProps = { public static defaultProps = {
title: '', title: '',
messageSub: '',
okTheme: SessionButtonColor.Primary,
closeTheme: SessionButtonColor.Primary,
hideCancel: false, hideCancel: false,
}; };
@ -25,7 +31,7 @@ export class SessionConfirm extends React.Component<Props> {
} }
public render() { 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 okText = this.props.okText || window.i18n('ok');
const cancelText = this.props.cancelText || window.i18n('cancel'); const cancelText = this.props.cancelText || window.i18n('cancel');
@ -42,19 +48,31 @@ export class SessionConfirm extends React.Component<Props> {
{!showHeader && <div className="spacer-lg" />} {!showHeader && <div className="spacer-lg" />}
<div className="session-modal__centered"> <div className="session-modal__centered">
<span className="text-subtle">{message}</span> <span className={ messageSub ? "session-confirm-main-message" : "text-subtle" }>{message}</span>
{ messageSub && (
<span className="session-confirm-sub-message text-subtle">{messageSub}</span>
)}
</div> </div>
<div className="spacer-lg" /> <div className="spacer-lg" />
<div className="session-modal__button-group"> <div className="session-modal__button-group">
<SessionButton text={okText} onClick={onClickOk} /> <SessionButton
text={okText}
buttonColor={okTheme}
onClick={onClickOk}
/>
{!hideCancel && ( {!hideCancel && (
<SessionButton text={cancelText} onClick={onClickClose} /> <SessionButton
text={cancelText}
buttonColor={closeTheme}
onClick={onClickClose}
/>
)} )}
</div> </div>
</SessionModal> </SessionModal>
); );
} }
} }

@ -32,7 +32,7 @@ export class SessionQRModal extends React.Component<Props> {
<div className="spacer-sm" /> <div className="spacer-sm" />
<div className="qr-dialog__description text-subtle"> <div className="qr-dialog__description text-subtle">
<SessionHtmlRenderer html={window.i18n('QRCodeDescription')} /> <SessionHtmlRenderer html={window.i18n('QRCodeDescription')} />
</div> </div>
<div className="spacer-lg" /> <div className="spacer-lg" />

@ -213,6 +213,7 @@ export class SessionSeedModal extends React.Component<Props, State> {
title: window.i18n('copiedMnemonic'), title: window.i18n('copiedMnemonic'),
type: 'success', type: 'success',
id: 'copySeedToast', id: 'copySeedToast',
shouldFade: false,
}); });
} }

@ -20,7 +20,6 @@ interface Props {
id?: string; id?: string;
type?: SessionToastType; type?: SessionToastType;
description?: string; description?: string;
fadeToast: any;
closeToast: any; closeToast: any;
} }

4
ts/global.d.ts vendored

@ -1,5 +1,7 @@
interface Window { interface Window {
Events: any; Events: any;
deleteAllData: any;
deleteAccount: any;
getAccountManager: any; getAccountManager: any;
mnemonic: any; mnemonic: any;
clipboard: any; clipboard: any;
@ -19,6 +21,8 @@ interface Window {
generateID: any; generateID: any;
storage: any; storage: any;
pushToast: any; pushToast: any;
confirmationDialog: any;
showSeedDialog: any;
} }
interface Promise<T> { interface Promise<T> {

Loading…
Cancel
Save