|
|
@ -3,7 +3,6 @@ import React from 'react';
|
|
|
|
import { SettingsHeader } from './SessionSettingsHeader';
|
|
|
|
import { SettingsHeader } from './SessionSettingsHeader';
|
|
|
|
import { SessionSettingListItem } from './SessionSettingListItem';
|
|
|
|
import { SessionSettingListItem } from './SessionSettingListItem';
|
|
|
|
import { SessionButtonColor } from '../SessionButton';
|
|
|
|
import { SessionButtonColor } from '../SessionButton';
|
|
|
|
import { SessionLinkedDeviceListItem } from './SessionLinkedDeviceListItem';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export enum SessionSettingCategory {
|
|
|
|
export enum SessionSettingCategory {
|
|
|
|
General = 'general',
|
|
|
|
General = 'general',
|
|
|
@ -30,6 +29,19 @@ interface State {
|
|
|
|
linkedPubKeys: Array<any>;
|
|
|
|
linkedPubKeys: Array<any>;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
interface LocalSettingType {
|
|
|
|
|
|
|
|
category: SessionSettingCategory;
|
|
|
|
|
|
|
|
description: string | undefined;
|
|
|
|
|
|
|
|
comparisonValue: string | undefined;
|
|
|
|
|
|
|
|
id: any;
|
|
|
|
|
|
|
|
content: any | undefined;
|
|
|
|
|
|
|
|
hidden: any;
|
|
|
|
|
|
|
|
title: string;
|
|
|
|
|
|
|
|
type: SessionSettingType | undefined;
|
|
|
|
|
|
|
|
setFn: any;
|
|
|
|
|
|
|
|
onClick: any;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export class SettingsView extends React.Component<SettingsViewProps, State> {
|
|
|
|
export class SettingsView extends React.Component<SettingsViewProps, State> {
|
|
|
|
public settingsViewRef: React.RefObject<HTMLDivElement>;
|
|
|
|
public settingsViewRef: React.RefObject<HTMLDivElement>;
|
|
|
|
|
|
|
|
|
|
|
@ -48,30 +60,160 @@ export class SettingsView extends React.Component<SettingsViewProps, State> {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public componentWillMount() {
|
|
|
|
public componentWillMount() {
|
|
|
|
const ourPubKey = window.textsecure.storage.user.getNumber();
|
|
|
|
const { category } = this.props;
|
|
|
|
|
|
|
|
if (category === SessionSettingCategory.Devices) {
|
|
|
|
|
|
|
|
const ourPubKey = window.textsecure.storage.user.getNumber();
|
|
|
|
|
|
|
|
|
|
|
|
window.libloki.storage.getSecondaryDevicesFor(ourPubKey).then((pubKeys: any) => {
|
|
|
|
window.libloki.storage.getSecondaryDevicesFor(ourPubKey).then((pubKeys: any) => {
|
|
|
|
this.setState({
|
|
|
|
this.setState({
|
|
|
|
linkedPubKeys: pubKeys,
|
|
|
|
linkedPubKeys: pubKeys,
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* tslint:disable-next-line:max-func-body-length */
|
|
|
|
/* tslint:disable-next-line:max-func-body-length */
|
|
|
|
public renderSettingInCategory(): JSX.Element {
|
|
|
|
public renderSettingInCategory(): JSX.Element {
|
|
|
|
const { category } = this.props;
|
|
|
|
const { category } = this.props;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let settings: Array<LocalSettingType>;
|
|
|
|
|
|
|
|
|
|
|
|
if (category === SessionSettingCategory.Devices) {
|
|
|
|
if (category === SessionSettingCategory.Devices) {
|
|
|
|
// special case for linked devices
|
|
|
|
// special case for linked devices
|
|
|
|
|
|
|
|
settings = this.getLinkedDeviceSettings();
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// Grab initial values from database on startup
|
|
|
|
|
|
|
|
// ID corresponds to installGetter parameters in preload.js
|
|
|
|
|
|
|
|
// They are NOT arbitrary; add with caution
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
settings = this.getLocalSettings();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<>
|
|
|
|
|
|
|
|
{this.state.hasPassword !== null &&
|
|
|
|
|
|
|
|
settings.map(setting => {
|
|
|
|
|
|
|
|
const { category } = this.props;
|
|
|
|
|
|
|
|
const content = setting.content || undefined;
|
|
|
|
|
|
|
|
const shouldRenderSettings = setting.category === category;
|
|
|
|
|
|
|
|
const description = setting.description || '';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const comparisonValue = setting.comparisonValue || null;
|
|
|
|
|
|
|
|
const value =
|
|
|
|
|
|
|
|
window.getSettingValue(setting.id, comparisonValue) ||
|
|
|
|
|
|
|
|
setting.content && setting.content.defaultValue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const sliderFn =
|
|
|
|
|
|
|
|
setting.type === SessionSettingType.Slider
|
|
|
|
|
|
|
|
? (settingValue: any) =>
|
|
|
|
|
|
|
|
window.setSettingValue(setting.id, settingValue)
|
|
|
|
|
|
|
|
: () => null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const onClickFn =
|
|
|
|
|
|
|
|
setting.onClick ||
|
|
|
|
|
|
|
|
(() => {
|
|
|
|
|
|
|
|
this.updateSetting(setting);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<div key={setting.id}>
|
|
|
|
|
|
|
|
{shouldRenderSettings &&
|
|
|
|
|
|
|
|
!setting.hidden && (
|
|
|
|
|
|
|
|
<SessionSettingListItem
|
|
|
|
|
|
|
|
title={setting.title}
|
|
|
|
|
|
|
|
description={description}
|
|
|
|
|
|
|
|
type={setting.type}
|
|
|
|
|
|
|
|
value={value}
|
|
|
|
|
|
|
|
onClick={onClickFn}
|
|
|
|
|
|
|
|
onSliderChange={sliderFn}
|
|
|
|
|
|
|
|
content={content}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
})}
|
|
|
|
|
|
|
|
</>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public render() {
|
|
|
|
|
|
|
|
const { category } = this.props;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<div className="session-settings">
|
|
|
|
|
|
|
|
<SettingsHeader category={category} />
|
|
|
|
|
|
|
|
<div ref={this.settingsViewRef} className="session-settings-list">
|
|
|
|
|
|
|
|
{this.renderSettingInCategory()}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public setOptionsSetting(settingID: string) {
|
|
|
|
|
|
|
|
const selectedValue = $(`#${settingID} .session-radio input:checked`).val();
|
|
|
|
|
|
|
|
window.setSettingValue(settingID, selectedValue);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public hasPassword() {
|
|
|
|
|
|
|
|
const hashPromise = window.Signal.Data.getPasswordHash();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
hashPromise.then((hash: any) => {
|
|
|
|
|
|
|
|
this.setState({
|
|
|
|
|
|
|
|
hasPassword: !!hash,
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public updateSetting(item: any) {
|
|
|
|
|
|
|
|
// If there's a custom afterClick function,
|
|
|
|
|
|
|
|
// execute it instead of automatically updating settings
|
|
|
|
|
|
|
|
if (item.setFn) {
|
|
|
|
|
|
|
|
item.setFn();
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
if (item.type === SessionSettingType.Toggle) {
|
|
|
|
|
|
|
|
// If no custom afterClick function given, alter values in storage here
|
|
|
|
|
|
|
|
// Switch to opposite state
|
|
|
|
|
|
|
|
const newValue = ! window.getSettingValue(item.id);
|
|
|
|
|
|
|
|
window.setSettingValue(item.id, newValue);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public onPasswordUpdated(action: string) {
|
|
|
|
|
|
|
|
if (action === 'set') {
|
|
|
|
|
|
|
|
this.setState({
|
|
|
|
|
|
|
|
hasPassword: true,
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return this.renderLinkedDevicesCategory();
|
|
|
|
if (action === 'remove') {
|
|
|
|
|
|
|
|
this.setState({
|
|
|
|
|
|
|
|
hasPassword: false,
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private getPubkeyName(pubKey: string | null) {
|
|
|
|
|
|
|
|
if (!pubKey) {
|
|
|
|
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const secretWords = window.mnemonic.pubkey_to_secret_words(pubKey);
|
|
|
|
|
|
|
|
const conv = window.ConversationController.get(pubKey);
|
|
|
|
|
|
|
|
const deviceAlias = conv ? conv.getNickname() : 'Unnamed Device';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return { deviceAlias, secretWords };
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// tslint:disable-next-line: max-func-body-length
|
|
|
|
|
|
|
|
private getLocalSettings() : Array<LocalSettingType> {
|
|
|
|
const { Settings } = window.Signal.Types;
|
|
|
|
const { Settings } = window.Signal.Types;
|
|
|
|
|
|
|
|
|
|
|
|
// Grab initial values from database on startup
|
|
|
|
return [
|
|
|
|
// ID corresponds to instalGetter parameters in preload.js
|
|
|
|
|
|
|
|
// They are NOT arbitrary; add with caution
|
|
|
|
|
|
|
|
const localSettings = [
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
id: 'theme-setting',
|
|
|
|
id: 'theme-setting',
|
|
|
|
title: window.i18n('themeToggleTitle'),
|
|
|
|
title: window.i18n('themeToggleTitle'),
|
|
|
@ -81,7 +223,8 @@ export class SettingsView extends React.Component<SettingsViewProps, State> {
|
|
|
|
type: SessionSettingType.Toggle,
|
|
|
|
type: SessionSettingType.Toggle,
|
|
|
|
category: SessionSettingCategory.General,
|
|
|
|
category: SessionSettingCategory.General,
|
|
|
|
setFn: window.toggleTheme,
|
|
|
|
setFn: window.toggleTheme,
|
|
|
|
content: {},
|
|
|
|
content: undefined,
|
|
|
|
|
|
|
|
onClick: undefined,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
|
id: 'hide-menu-bar',
|
|
|
|
id: 'hide-menu-bar',
|
|
|
@ -91,7 +234,9 @@ export class SettingsView extends React.Component<SettingsViewProps, State> {
|
|
|
|
type: SessionSettingType.Toggle,
|
|
|
|
type: SessionSettingType.Toggle,
|
|
|
|
category: SessionSettingCategory.General,
|
|
|
|
category: SessionSettingCategory.General,
|
|
|
|
setFn: window.toggleMenuBar,
|
|
|
|
setFn: window.toggleMenuBar,
|
|
|
|
content: {},
|
|
|
|
content: undefined,
|
|
|
|
|
|
|
|
comparisonValue: undefined,
|
|
|
|
|
|
|
|
onClick: undefined,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
|
id: 'spell-check',
|
|
|
|
id: 'spell-check',
|
|
|
@ -101,7 +246,9 @@ export class SettingsView extends React.Component<SettingsViewProps, State> {
|
|
|
|
type: SessionSettingType.Toggle,
|
|
|
|
type: SessionSettingType.Toggle,
|
|
|
|
category: SessionSettingCategory.General,
|
|
|
|
category: SessionSettingCategory.General,
|
|
|
|
setFn: window.toggleSpellCheck,
|
|
|
|
setFn: window.toggleSpellCheck,
|
|
|
|
content: {},
|
|
|
|
content: undefined,
|
|
|
|
|
|
|
|
comparisonValue: undefined,
|
|
|
|
|
|
|
|
onClick: undefined,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
|
id: 'link-preview-setting',
|
|
|
|
id: 'link-preview-setting',
|
|
|
@ -111,13 +258,19 @@ export class SettingsView extends React.Component<SettingsViewProps, State> {
|
|
|
|
type: SessionSettingType.Toggle,
|
|
|
|
type: SessionSettingType.Toggle,
|
|
|
|
category: SessionSettingCategory.General,
|
|
|
|
category: SessionSettingCategory.General,
|
|
|
|
setFn: window.toggleLinkPreview,
|
|
|
|
setFn: window.toggleLinkPreview,
|
|
|
|
content: {},
|
|
|
|
content: undefined,
|
|
|
|
|
|
|
|
comparisonValue: undefined,
|
|
|
|
|
|
|
|
onClick: undefined,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
|
id: 'notification-setting',
|
|
|
|
id: 'notification-setting',
|
|
|
|
title: window.i18n('notificationSettingsDialog'),
|
|
|
|
title: window.i18n('notificationSettingsDialog'),
|
|
|
|
type: SessionSettingType.Options,
|
|
|
|
type: SessionSettingType.Options,
|
|
|
|
category: SessionSettingCategory.Notifications,
|
|
|
|
category: SessionSettingCategory.Notifications,
|
|
|
|
|
|
|
|
comparisonValue: undefined,
|
|
|
|
|
|
|
|
description: undefined,
|
|
|
|
|
|
|
|
hidden: undefined,
|
|
|
|
|
|
|
|
onClick: undefined,
|
|
|
|
setFn: () => {
|
|
|
|
setFn: () => {
|
|
|
|
this.setOptionsSetting('notification-setting');
|
|
|
|
this.setOptionsSetting('notification-setting');
|
|
|
|
},
|
|
|
|
},
|
|
|
@ -154,7 +307,9 @@ export class SettingsView extends React.Component<SettingsViewProps, State> {
|
|
|
|
type: SessionSettingType.Toggle,
|
|
|
|
type: SessionSettingType.Toggle,
|
|
|
|
category: SessionSettingCategory.Permissions,
|
|
|
|
category: SessionSettingCategory.Permissions,
|
|
|
|
setFn: window.toggleMediaPermissions,
|
|
|
|
setFn: window.toggleMediaPermissions,
|
|
|
|
content: {},
|
|
|
|
content: undefined,
|
|
|
|
|
|
|
|
comparisonValue: undefined,
|
|
|
|
|
|
|
|
onClick: undefined,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
|
id: 'message-ttl',
|
|
|
|
id: 'message-ttl',
|
|
|
@ -164,6 +319,8 @@ export class SettingsView extends React.Component<SettingsViewProps, State> {
|
|
|
|
type: SessionSettingType.Slider,
|
|
|
|
type: SessionSettingType.Slider,
|
|
|
|
category: SessionSettingCategory.Privacy,
|
|
|
|
category: SessionSettingCategory.Privacy,
|
|
|
|
setFn: undefined,
|
|
|
|
setFn: undefined,
|
|
|
|
|
|
|
|
comparisonValue: undefined,
|
|
|
|
|
|
|
|
onClick: undefined,
|
|
|
|
content: {
|
|
|
|
content: {
|
|
|
|
defaultValue: 24,
|
|
|
|
defaultValue: 24,
|
|
|
|
},
|
|
|
|
},
|
|
|
@ -176,6 +333,7 @@ export class SettingsView extends React.Component<SettingsViewProps, State> {
|
|
|
|
type: SessionSettingType.Button,
|
|
|
|
type: SessionSettingType.Button,
|
|
|
|
category: SessionSettingCategory.Privacy,
|
|
|
|
category: SessionSettingCategory.Privacy,
|
|
|
|
setFn: undefined,
|
|
|
|
setFn: undefined,
|
|
|
|
|
|
|
|
comparisonValue: undefined,
|
|
|
|
content: {
|
|
|
|
content: {
|
|
|
|
buttonText: window.i18n('setPassword'),
|
|
|
|
buttonText: window.i18n('setPassword'),
|
|
|
|
buttonColor: SessionButtonColor.Primary,
|
|
|
|
buttonColor: SessionButtonColor.Primary,
|
|
|
@ -194,6 +352,7 @@ export class SettingsView extends React.Component<SettingsViewProps, State> {
|
|
|
|
type: SessionSettingType.Button,
|
|
|
|
type: SessionSettingType.Button,
|
|
|
|
category: SessionSettingCategory.Privacy,
|
|
|
|
category: SessionSettingCategory.Privacy,
|
|
|
|
setFn: undefined,
|
|
|
|
setFn: undefined,
|
|
|
|
|
|
|
|
comparisonValue: undefined,
|
|
|
|
content: {
|
|
|
|
content: {
|
|
|
|
buttonText: window.i18n('changePassword'),
|
|
|
|
buttonText: window.i18n('changePassword'),
|
|
|
|
buttonColor: SessionButtonColor.Primary,
|
|
|
|
buttonColor: SessionButtonColor.Primary,
|
|
|
@ -212,6 +371,7 @@ export class SettingsView extends React.Component<SettingsViewProps, State> {
|
|
|
|
type: SessionSettingType.Button,
|
|
|
|
type: SessionSettingType.Button,
|
|
|
|
category: SessionSettingCategory.Privacy,
|
|
|
|
category: SessionSettingCategory.Privacy,
|
|
|
|
setFn: undefined,
|
|
|
|
setFn: undefined,
|
|
|
|
|
|
|
|
comparisonValue: undefined,
|
|
|
|
content: {
|
|
|
|
content: {
|
|
|
|
buttonText: window.i18n('removePassword'),
|
|
|
|
buttonText: window.i18n('removePassword'),
|
|
|
|
buttonColor: SessionButtonColor.Danger,
|
|
|
|
buttonColor: SessionButtonColor.Danger,
|
|
|
@ -223,158 +383,79 @@ export class SettingsView extends React.Component<SettingsViewProps, State> {
|
|
|
|
}),
|
|
|
|
}),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
];
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<>
|
|
|
|
|
|
|
|
{this.state.hasPassword !== null &&
|
|
|
|
|
|
|
|
localSettings.map(setting => {
|
|
|
|
|
|
|
|
const { category } = this.props;
|
|
|
|
|
|
|
|
const content = setting.content || undefined;
|
|
|
|
|
|
|
|
const shouldRenderSettings = setting.category === category;
|
|
|
|
|
|
|
|
const description = setting.description || '';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const comparisonValue = setting.comparisonValue || null;
|
|
|
|
|
|
|
|
const value =
|
|
|
|
|
|
|
|
window.getSettingValue(setting.id, comparisonValue) ||
|
|
|
|
|
|
|
|
setting.content.defaultValue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const sliderFn =
|
|
|
|
|
|
|
|
setting.type === SessionSettingType.Slider
|
|
|
|
|
|
|
|
? (settingValue: any) =>
|
|
|
|
|
|
|
|
window.setSettingValue(setting.id, settingValue)
|
|
|
|
|
|
|
|
: () => null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const onClickFn =
|
|
|
|
|
|
|
|
setting.onClick ||
|
|
|
|
|
|
|
|
(() => {
|
|
|
|
|
|
|
|
this.updateSetting(setting);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<div key={setting.id}>
|
|
|
|
|
|
|
|
{shouldRenderSettings &&
|
|
|
|
|
|
|
|
!setting.hidden && (
|
|
|
|
|
|
|
|
<SessionSettingListItem
|
|
|
|
|
|
|
|
title={setting.title}
|
|
|
|
|
|
|
|
description={description}
|
|
|
|
|
|
|
|
type={setting.type}
|
|
|
|
|
|
|
|
value={value}
|
|
|
|
|
|
|
|
onClick={onClickFn}
|
|
|
|
|
|
|
|
onSliderChange={sliderFn}
|
|
|
|
|
|
|
|
content={content}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
})}
|
|
|
|
|
|
|
|
</>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public hasPassword() {
|
|
|
|
|
|
|
|
const hashPromise = window.Signal.Data.getPasswordHash();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
hashPromise.then((hash: any) => {
|
|
|
|
|
|
|
|
this.setState({
|
|
|
|
|
|
|
|
hasPassword: !!hash,
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public render() {
|
|
|
|
|
|
|
|
const { category } = this.props;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<div className="session-settings">
|
|
|
|
|
|
|
|
<SettingsHeader category={category} />
|
|
|
|
|
|
|
|
<div ref={this.settingsViewRef} className="session-settings-list">
|
|
|
|
|
|
|
|
{this.renderSettingInCategory()}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public updateSetting(item: any) {
|
|
|
|
|
|
|
|
// If there's a custom afterClick function,
|
|
|
|
|
|
|
|
// execute it instead of automatically updating settings
|
|
|
|
|
|
|
|
if (item.setFn) {
|
|
|
|
|
|
|
|
item.setFn();
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
if (item.type === SessionSettingType.Toggle) {
|
|
|
|
|
|
|
|
// If no custom afterClick function given, alter values in storage here
|
|
|
|
|
|
|
|
// Switch to opposite state
|
|
|
|
|
|
|
|
const newValue = ! window.getSettingValue(item.id);
|
|
|
|
|
|
|
|
window.setSettingValue(item.id, newValue);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public setOptionsSetting(settingID: string) {
|
|
|
|
|
|
|
|
const selectedValue = $(`#${settingID} .session-radio input:checked`).val();
|
|
|
|
|
|
|
|
window.setSettingValue(settingID, selectedValue);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public onPasswordUpdated(action: string) {
|
|
|
|
|
|
|
|
if (action === 'set') {
|
|
|
|
|
|
|
|
this.setState({
|
|
|
|
|
|
|
|
hasPassword: true,
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (action === 'remove') {
|
|
|
|
|
|
|
|
this.setState({
|
|
|
|
|
|
|
|
hasPassword: false,
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private getPubkeyName(pubKey: string | null) {
|
|
|
|
|
|
|
|
if (!pubKey) {
|
|
|
|
|
|
|
|
return {};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const secretWords = window.mnemonic.pubkey_to_secret_words(pubKey);
|
|
|
|
|
|
|
|
const conv = window.ConversationController.get(pubKey);
|
|
|
|
|
|
|
|
const deviceAlias = conv ? conv.getNickname() : 'Unnamed Device';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return { deviceAlias, secretWords };
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private renderLinkedDevicesCategory(): JSX.Element {
|
|
|
|
private getLinkedDeviceSettings() : Array<LocalSettingType> {
|
|
|
|
const { linkedPubKeys } = this.state;
|
|
|
|
const { linkedPubKeys } = this.state;
|
|
|
|
|
|
|
|
|
|
|
|
/*const li = $('<li>').html(name);
|
|
|
|
|
|
|
|
if (window.lokiFeatureFlags.multiDeviceUnpairing) {
|
|
|
|
|
|
|
|
const link = $('<a>')
|
|
|
|
|
|
|
|
.text('Unpair')
|
|
|
|
|
|
|
|
.attr('href', '#');
|
|
|
|
|
|
|
|
link.on('click', () => this.requestUnpairDevice(x));
|
|
|
|
|
|
|
|
li.append(' - ');
|
|
|
|
|
|
|
|
li.append(link);
|
|
|
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (linkedPubKeys && linkedPubKeys.length > 0) {
|
|
|
|
if (linkedPubKeys && linkedPubKeys.length > 0) {
|
|
|
|
//this.$('#startPairing').attr('disabled', true);
|
|
|
|
return linkedPubKeys.map((pubkey: any) => {
|
|
|
|
const items = linkedPubKeys.map((pubkey: any) => {
|
|
|
|
|
|
|
|
const { deviceAlias, secretWords } = this.getPubkeyName(pubkey);
|
|
|
|
const { deviceAlias, secretWords } = this.getPubkeyName(pubkey);
|
|
|
|
const description = `${secretWords} ${window.shortenPubkey(pubkey)}`;
|
|
|
|
const description = `${secretWords} ${window.shortenPubkey(pubkey)}`;
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
return {
|
|
|
|
<SessionLinkedDeviceListItem onClick={() => {}} title={deviceAlias} key={pubkey} description={description} />
|
|
|
|
id: pubkey,
|
|
|
|
);
|
|
|
|
title: deviceAlias,
|
|
|
|
|
|
|
|
description: description,
|
|
|
|
|
|
|
|
type: SessionSettingType.Button,
|
|
|
|
|
|
|
|
category: SessionSettingCategory.Devices,
|
|
|
|
|
|
|
|
content: {
|
|
|
|
|
|
|
|
buttonColor: SessionButtonColor.Danger,
|
|
|
|
|
|
|
|
buttonText: window.i18n('unpairDevice'),
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
comparisonValue: undefined,
|
|
|
|
|
|
|
|
onClick: undefined,
|
|
|
|
|
|
|
|
setFn: undefined,
|
|
|
|
|
|
|
|
hidden: undefined,
|
|
|
|
|
|
|
|
};
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
|
|
|
{items}
|
|
|
|
|
|
|
|
</div>);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
//this.$('#startPairing').removeAttr('disabled');
|
|
|
|
return [{
|
|
|
|
//this.$('#pairedPubKeys').append('<li>No paired devices</li>');
|
|
|
|
id: 'no-linked-device',
|
|
|
|
|
|
|
|
title: window.i18n('noPairedDevices'),
|
|
|
|
return (<li>No paired devices</li>);
|
|
|
|
type: undefined,
|
|
|
|
|
|
|
|
description: '',
|
|
|
|
|
|
|
|
category: SessionSettingCategory.Devices,
|
|
|
|
|
|
|
|
content: {},
|
|
|
|
|
|
|
|
comparisonValue: undefined,
|
|
|
|
|
|
|
|
setFn: undefined,
|
|
|
|
|
|
|
|
hidden: undefined,
|
|
|
|
|
|
|
|
onClick: undefined,
|
|
|
|
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// /*const li = $('<li>').html(name);
|
|
|
|
|
|
|
|
// if (window.lokiFeatureFlags.multiDeviceUnpairing) {
|
|
|
|
|
|
|
|
// const link = $('<a>')
|
|
|
|
|
|
|
|
// .text('Unpair')
|
|
|
|
|
|
|
|
// .attr('href', '#');
|
|
|
|
|
|
|
|
// link.on('click', () => this.requestUnpairDevice(x));
|
|
|
|
|
|
|
|
// li.append(' - ');
|
|
|
|
|
|
|
|
// li.append(link);
|
|
|
|
|
|
|
|
// }*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if (linkedPubKeys && linkedPubKeys.length > 0) {
|
|
|
|
|
|
|
|
// //this.$('#startPairing').attr('disabled', true);
|
|
|
|
|
|
|
|
// const items = linkedPubKeys.map((pubkey: any) => {
|
|
|
|
|
|
|
|
// const { deviceAlias, secretWords } = this.getPubkeyName(pubkey);
|
|
|
|
|
|
|
|
// const description = `${secretWords} ${window.shortenPubkey(pubkey)}`;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// return (
|
|
|
|
|
|
|
|
// <SessionLinkedDeviceListItem onClick={() => {}} title={deviceAlias} key={pubkey} description={description} />
|
|
|
|
|
|
|
|
// );
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// return (
|
|
|
|
|
|
|
|
// <div>
|
|
|
|
|
|
|
|
// {items}
|
|
|
|
|
|
|
|
// </div>);
|
|
|
|
|
|
|
|
// } else {
|
|
|
|
|
|
|
|
// //this.$('#startPairing').removeAttr('disabled');
|
|
|
|
|
|
|
|
// //this.$('#pairedPubKeys').append('<li>No paired devices</li>');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// return (<li>No paired devices</li>);
|
|
|
|
|
|
|
|
// }
|
|
|
|