finish cleaning up Settings page

pull/1978/head
Audric Ackermann 4 years ago
parent a596531c57
commit 0ae23875b7
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4

@ -4,9 +4,9 @@ import { useAppIsFocused } from '../hooks/useAppFocused';
import { getFocusedSettingsSection } from '../state/selectors/section';
import { SmartSessionConversation } from '../state/smart/SessionConversation';
import { SmartSettingsView } from './session/settings/SessionSettings';
import { SessionSettingsView } from './session/settings/SessionSettings';
const FilteredSettingsView = SmartSettingsView as any;
const FilteredSettingsView = SessionSettingsView as any;
export const SessionMainPanel = () => {
const focusedSettingsSection = useSelector(getFocusedSettingsSection);

@ -1,28 +1,17 @@
import React from 'react';
import { SettingsHeader } from './SessionSettingsHeader';
import { SessionSettingButtonItem, SessionToggleWithDescription } from './SessionSettingListItem';
import { SessionButton, SessionButtonColor, SessionButtonType } from '../SessionButton';
import { PasswordUtil } from '../../../util';
import { useDispatch, useSelector } from 'react-redux';
import {
createOrUpdateItem,
getPasswordHash,
hasLinkPreviewPopupBeenDisplayed,
} from '../../../../ts/data/data';
import { ipcRenderer, shell } from 'electron';
import { getPasswordHash } from '../../../../ts/data/data';
import { shell } from 'electron';
import { SessionIconButton } from '../icon';
import autoBind from 'auto-bind';
import { SessionNotificationGroupSettings } from './SessionNotificationGroupSettings';
import { sessionPassword, updateConfirmModal } from '../../../state/ducks/modalDialog';
import { ToastUtils } from '../../../session/utils';
import { getAudioAutoplay } from '../../../state/selectors/userConfig';
import { toggleAudioAutoplay } from '../../../state/ducks/userConfig';
// tslint:disable-next-line: no-submodule-imports
import useUpdate from 'react-use/lib/useUpdate';
import { PasswordAction } from '../../dialog/SessionPasswordDialog';
import { BlockedUserSettings } from './BlockedUserSettings';
import { ZoomingSessionSlider } from './ZoomingSessionSlider';
import { SettingsCategoryPrivacy } from './section/CategoryPrivacy';
import { SettingsCategoryAppearance } from './section/CategoryAppearance';
export function getMediaPermissionsSettings() {
return window.getSettingValue('media-permissions');
@ -51,6 +40,21 @@ interface State {
shouldLockSettings: boolean | null;
}
const SessionInfo = () => {
const openOxenWebsite = () => {
void shell.openExternal('https://oxen.io/');
};
return (
<div className="session-settings__version-info">
<span className="text-selectable">v{window.versionInfo.version}</span>
<span>
<SessionIconButton iconSize={'medium'} iconType="oxen" onClick={openOxenWebsite} />
</span>
<span className="text-selectable">{window.versionInfo.commitHash}</span>
</div>
);
};
export const PasswordLock = ({
pwdLockError,
validatePasswordLock,
@ -77,268 +81,7 @@ export const PasswordLock = ({
);
};
const SessionInfo = () => {
const openOxenWebsite = () => {
void shell.openExternal('https://oxen.io/');
};
return (
<div className="session-settings__version-info">
<span className="text-selectable">v{window.versionInfo.version}</span>
<span>
<SessionIconButton iconSize={'medium'} iconType="oxen" onClick={openOxenWebsite} />
</span>
<span className="text-selectable">{window.versionInfo.commitHash}</span>
</div>
);
};
async function toggleLinkPreviews() {
const newValue = !window.getSettingValue('link-preview-setting');
window.setSettingValue('link-preview-setting', newValue);
if (!newValue) {
await createOrUpdateItem({ id: hasLinkPreviewPopupBeenDisplayed, value: false });
} else {
window.inboxStore?.dispatch(
updateConfirmModal({
title: window.i18n('linkPreviewsTitle'),
message: window.i18n('linkPreviewsConfirmMessage'),
okTheme: SessionButtonColor.Danger,
})
);
}
}
async function toggleStartInTray() {
try {
const newValue = !(await window.getStartInTray());
// make sure to write it here too, as this is the value used on the UI to mark the toggle as true/false
window.setSettingValue('start-in-tray-setting', newValue);
await window.setStartInTray(newValue);
if (!newValue) {
ToastUtils.pushRestartNeeded();
}
} catch (e) {
window.log.warn('start in tray change error:', e);
}
}
const toggleCallMediaPermissions = async (triggerUIUpdate: () => void) => {
const currentValue = window.getCallMediaPermissions();
if (!currentValue) {
window.inboxStore?.dispatch(
updateConfirmModal({
message: window.i18n('callMediaPermissionsDialogContent'),
okTheme: SessionButtonColor.Green,
onClickOk: async () => {
await window.toggleCallMediaPermissionsTo(true);
triggerUIUpdate();
},
onClickCancel: async () => {
await window.toggleCallMediaPermissionsTo(false);
triggerUIUpdate();
},
})
);
} else {
await window.toggleCallMediaPermissionsTo(false);
triggerUIUpdate();
}
};
const SettingsCategoryAppearance = (props: { hasPassword: boolean | null }) => {
const dispatch = useDispatch();
const forceUpdate = useUpdate();
const audioAutoPlay = useSelector(getAudioAutoplay);
if (props.hasPassword !== null) {
const isHideMenuBarActive =
window.getSettingValue('hide-menu-bar') === undefined
? true
: window.getSettingValue('hide-menu-bar');
const isSpellCheckActive =
window.getSettingValue('spell-check') === undefined
? true
: window.getSettingValue('spell-check');
const isLinkPreviewsOn = Boolean(window.getSettingValue('link-preview-setting'));
const isStartInTrayActive = Boolean(window.getSettingValue('start-in-tray-setting'));
return (
<>
{window.Signal.Types.Settings.isHideMenuBarSupported() && (
<SessionToggleWithDescription
onClickToggle={() => {
window.toggleMenuBar();
forceUpdate();
}}
title={window.i18n('hideMenuBarTitle')}
description={window.i18n('hideMenuBarDescription')}
active={isHideMenuBarActive}
/>
)}
<SessionToggleWithDescription
onClickToggle={() => {
window.toggleSpellCheck();
forceUpdate();
}}
title={window.i18n('spellCheckTitle')}
description={window.i18n('spellCheckDescription')}
active={isSpellCheckActive}
/>
<SessionToggleWithDescription
onClickToggle={async () => {
await toggleLinkPreviews();
forceUpdate();
}}
title={window.i18n('linkPreviewsTitle')}
description={window.i18n('linkPreviewDescription')}
active={isLinkPreviewsOn}
/>
<SessionToggleWithDescription
onClickToggle={async () => {
await toggleStartInTray();
forceUpdate();
}}
title={window.i18n('startInTrayTitle')}
description={window.i18n('startInTrayDescription')}
active={isStartInTrayActive}
/>
<SessionToggleWithDescription
onClickToggle={() => {
dispatch(toggleAudioAutoplay());
forceUpdate();
}}
title={window.i18n('audioMessageAutoplayTitle')}
description={window.i18n('audioMessageAutoplayDescription')}
active={audioAutoPlay}
/>
<ZoomingSessionSlider />
<SessionSettingButtonItem
title={window.i18n('surveyTitle')}
onClick={() => void shell.openExternal('https://getsession.org/survey')}
buttonColor={SessionButtonColor.Primary}
buttonText={window.i18n('goToOurSurvey')}
/>
<SessionSettingButtonItem
title={window.i18n('helpUsTranslateSession')}
onClick={() => void shell.openExternal('https://crowdin.com/project/session-desktop/')}
buttonColor={SessionButtonColor.Primary}
buttonText={window.i18n('translation')}
/>
<SessionSettingButtonItem
onClick={() => {
ipcRenderer.send('show-debug-log');
}}
buttonColor={SessionButtonColor.Primary}
buttonText={window.i18n('showDebugLog')}
/>
</>
);
}
return null;
};
const SettingsCategoryPrivacy = (props: {
hasPassword: boolean | null;
onPasswordUpdated: (action: string) => void;
}) => {
const forceUpdate = useUpdate();
if (props.hasPassword !== null) {
return (
<>
<SessionToggleWithDescription
onClickToggle={async () => {
await window.toggleMediaPermissions();
forceUpdate();
}}
title={window.i18n('mediaPermissionsTitle')}
description={window.i18n('mediaPermissionsDescription')}
active={Boolean(window.getSettingValue('media-permissions'))}
/>
<SessionToggleWithDescription
onClickToggle={async () => {
await toggleCallMediaPermissions(forceUpdate);
forceUpdate();
}}
title={window.i18n('callMediaPermissionsTitle')}
description={window.i18n('callMediaPermissionsDescription')}
active={Boolean(window.getCallMediaPermissions())}
/>
<SessionToggleWithDescription
onClickToggle={() => {
const old = Boolean(window.getSettingValue('read-receipt-setting'));
window.setSettingValue('read-receipt-setting', !old);
forceUpdate();
}}
title={window.i18n('readReceiptSettingTitle')}
description={window.i18n('readReceiptSettingDescription')}
active={window.getSettingValue('read-receipt-setting')}
/>
<SessionToggleWithDescription
onClickToggle={() => {
const old = Boolean(window.getSettingValue('typing-indicators-setting'));
window.setSettingValue('typing-indicators-setting', !old);
forceUpdate();
}}
title={window.i18n('typingIndicatorsSettingTitle')}
description={window.i18n('typingIndicatorsSettingDescription')}
active={Boolean(window.getSettingValue('typing-indicators-setting'))}
/>
<SessionToggleWithDescription
onClickToggle={() => {
const old = Boolean(window.getSettingValue('auto-update'));
window.setSettingValue('auto-update', !old);
forceUpdate();
}}
title={window.i18n('autoUpdateSettingTitle')}
description={window.i18n('autoUpdateSettingDescription')}
active={Boolean(window.getSettingValue('auto-update'))}
/>
{!props.hasPassword && (
<SessionSettingButtonItem
title={window.i18n('setAccountPasswordTitle')}
description={window.i18n('setAccountPasswordDescription')}
onClick={() => {
displayPasswordModal('set', props.onPasswordUpdated);
}}
buttonColor={SessionButtonColor.Primary}
buttonText={window.i18n('setPassword')}
/>
)}
{props.hasPassword && (
<SessionSettingButtonItem
title={window.i18n('changeAccountPasswordTitle')}
description={window.i18n('changeAccountPasswordDescription')}
onClick={() => {
displayPasswordModal('change', props.onPasswordUpdated);
}}
buttonColor={SessionButtonColor.Primary}
buttonText={window.i18n('changePassword')}
/>
)}
{props.hasPassword && (
<SessionSettingButtonItem
title={window.i18n('removeAccountPasswordTitle')}
description={window.i18n('removeAccountPasswordDescription')}
onClick={() => {
displayPasswordModal('remove', props.onPasswordUpdated);
}}
buttonColor={SessionButtonColor.Danger}
buttonText={window.i18n('removePassword')}
/>
)}
</>
);
}
return null;
};
export class SmartSettingsView extends React.Component<SettingsViewProps, State> {
export class SessionSettingsView extends React.Component<SettingsViewProps, State> {
public settingsViewRef: React.RefObject<HTMLDivElement>;
public constructor(props: any) {
@ -372,13 +115,6 @@ export class SmartSettingsView extends React.Component<SettingsViewProps, State>
window.removeEventListener('keyup', this.onKeyUp);
}
public renderSettingsPrivacy() {
if (this.state.hasPassword !== null) {
return <SessionNotificationGroupSettings hasPassword={this.state.hasPassword} />;
}
return null;
}
/* tslint:disable-next-line:max-func-body-length */
public renderSettingInCategory() {
const { category } = this.props;
@ -407,7 +143,7 @@ export class SmartSettingsView extends React.Component<SettingsViewProps, State>
/>
);
}
return <SessionNotificationGroupSettings hasPassword={this.state.hasPassword} />;
return null;
}
public async validatePasswordLock() {
@ -502,17 +238,3 @@ export class SmartSettingsView extends React.Component<SettingsViewProps, State>
event.preventDefault();
}
}
function displayPasswordModal(
passwordAction: PasswordAction,
onPasswordUpdated: (action: string) => void
) {
window.inboxStore?.dispatch(
sessionPassword({
passwordAction,
onOk: () => {
onPasswordUpdated(passwordAction);
},
})
);
}

@ -0,0 +1,144 @@
import { ipcRenderer, shell } from 'electron';
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
// tslint:disable-next-line: no-submodule-imports
import useUpdate from 'react-use/lib/useUpdate';
import { createOrUpdateItem, hasLinkPreviewPopupBeenDisplayed } from '../../../../data/data';
import { ToastUtils } from '../../../../session/utils';
import { updateConfirmModal } from '../../../../state/ducks/modalDialog';
import { toggleAudioAutoplay } from '../../../../state/ducks/userConfig';
import { getAudioAutoplay } from '../../../../state/selectors/userConfig';
import { SessionButtonColor } from '../../SessionButton';
import { SessionSettingButtonItem, SessionToggleWithDescription } from '../SessionSettingListItem';
import { ZoomingSessionSlider } from '../ZoomingSessionSlider';
async function toggleLinkPreviews() {
const newValue = !window.getSettingValue('link-preview-setting');
window.setSettingValue('link-preview-setting', newValue);
if (!newValue) {
await createOrUpdateItem({ id: hasLinkPreviewPopupBeenDisplayed, value: false });
} else {
window.inboxStore?.dispatch(
updateConfirmModal({
title: window.i18n('linkPreviewsTitle'),
message: window.i18n('linkPreviewsConfirmMessage'),
okTheme: SessionButtonColor.Danger,
})
);
}
}
async function toggleStartInTray() {
try {
const newValue = !(await window.getStartInTray());
// make sure to write it here too, as this is the value used on the UI to mark the toggle as true/false
window.setSettingValue('start-in-tray-setting', newValue);
await window.setStartInTray(newValue);
if (!newValue) {
ToastUtils.pushRestartNeeded();
}
} catch (e) {
window.log.warn('start in tray change error:', e);
}
}
const settingsMenuBar = 'hide-menu-bar';
const settingsSpellCheck = 'spell-check';
const settingsLinkPreview = 'link-preview-setting';
const settingsStartInTray = 'start-in-tray-setting';
export const SettingsCategoryAppearance = (props: { hasPassword: boolean | null }) => {
const dispatch = useDispatch();
const forceUpdate = useUpdate();
const audioAutoPlay = useSelector(getAudioAutoplay);
if (props.hasPassword !== null) {
const isHideMenuBarActive =
window.getSettingValue(settingsMenuBar) === undefined
? true
: window.getSettingValue(settingsMenuBar);
const isSpellCheckActive =
window.getSettingValue(settingsSpellCheck) === undefined
? true
: window.getSettingValue(settingsSpellCheck);
const isLinkPreviewsOn = Boolean(window.getSettingValue(settingsLinkPreview));
const isStartInTrayActive = Boolean(window.getSettingValue(settingsStartInTray));
return (
<>
{window.Signal.Types.Settings.isHideMenuBarSupported() && (
<SessionToggleWithDescription
onClickToggle={() => {
window.toggleMenuBar();
forceUpdate();
}}
title={window.i18n('hideMenuBarTitle')}
description={window.i18n('hideMenuBarDescription')}
active={isHideMenuBarActive}
/>
)}
<SessionToggleWithDescription
onClickToggle={() => {
window.toggleSpellCheck();
forceUpdate();
}}
title={window.i18n('spellCheckTitle')}
description={window.i18n('spellCheckDescription')}
active={isSpellCheckActive}
/>
<SessionToggleWithDescription
onClickToggle={async () => {
await toggleLinkPreviews();
forceUpdate();
}}
title={window.i18n('linkPreviewsTitle')}
description={window.i18n('linkPreviewDescription')}
active={isLinkPreviewsOn}
/>
<SessionToggleWithDescription
onClickToggle={async () => {
await toggleStartInTray();
forceUpdate();
}}
title={window.i18n('startInTrayTitle')}
description={window.i18n('startInTrayDescription')}
active={isStartInTrayActive}
/>
<SessionToggleWithDescription
onClickToggle={() => {
dispatch(toggleAudioAutoplay());
forceUpdate();
}}
title={window.i18n('audioMessageAutoplayTitle')}
description={window.i18n('audioMessageAutoplayDescription')}
active={audioAutoPlay}
/>
<ZoomingSessionSlider />
<SessionSettingButtonItem
title={window.i18n('surveyTitle')}
onClick={() => void shell.openExternal('https://getsession.org/survey')}
buttonColor={SessionButtonColor.Primary}
buttonText={window.i18n('goToOurSurvey')}
/>
<SessionSettingButtonItem
title={window.i18n('helpUsTranslateSession')}
onClick={() => void shell.openExternal('https://crowdin.com/project/session-desktop/')}
buttonColor={SessionButtonColor.Primary}
buttonText={window.i18n('translation')}
/>
<SessionSettingButtonItem
onClick={() => {
ipcRenderer.send('show-debug-log');
}}
buttonColor={SessionButtonColor.Primary}
buttonText={window.i18n('showDebugLog')}
/>
</>
);
}
return null;
};

@ -0,0 +1,145 @@
import React from 'react';
// tslint:disable-next-line: no-submodule-imports
import useUpdate from 'react-use/lib/useUpdate';
import { sessionPassword, updateConfirmModal } from '../../../../state/ducks/modalDialog';
import { PasswordAction } from '../../../dialog/SessionPasswordDialog';
import { SessionButtonColor } from '../../SessionButton';
import { SessionSettingButtonItem, SessionToggleWithDescription } from '../SessionSettingListItem';
const settingsReadReceipt = 'read-receipt-setting';
const settingsTypingIndicator = 'typing-indicators-setting';
const settingsAutoUpdate = 'auto-update';
const toggleCallMediaPermissions = async (triggerUIUpdate: () => void) => {
const currentValue = window.getCallMediaPermissions();
if (!currentValue) {
window.inboxStore?.dispatch(
updateConfirmModal({
message: window.i18n('callMediaPermissionsDialogContent'),
okTheme: SessionButtonColor.Danger,
onClickOk: async () => {
await window.toggleCallMediaPermissionsTo(true);
triggerUIUpdate();
},
onClickCancel: async () => {
await window.toggleCallMediaPermissionsTo(false);
triggerUIUpdate();
},
})
);
} else {
await window.toggleCallMediaPermissionsTo(false);
triggerUIUpdate();
}
};
function displayPasswordModal(
passwordAction: PasswordAction,
onPasswordUpdated: (action: string) => void
) {
window.inboxStore?.dispatch(
sessionPassword({
passwordAction,
onOk: () => {
onPasswordUpdated(passwordAction);
},
})
);
}
export const SettingsCategoryPrivacy = (props: {
hasPassword: boolean | null;
onPasswordUpdated: (action: string) => void;
}) => {
const forceUpdate = useUpdate();
if (props.hasPassword !== null) {
return (
<>
<SessionToggleWithDescription
onClickToggle={async () => {
await window.toggleMediaPermissions();
forceUpdate();
}}
title={window.i18n('mediaPermissionsTitle')}
description={window.i18n('mediaPermissionsDescription')}
active={Boolean(window.getSettingValue('media-permissions'))}
/>
<SessionToggleWithDescription
onClickToggle={async () => {
await toggleCallMediaPermissions(forceUpdate);
forceUpdate();
}}
title={window.i18n('callMediaPermissionsTitle')}
description={window.i18n('callMediaPermissionsDescription')}
active={Boolean(window.getCallMediaPermissions())}
/>
<SessionToggleWithDescription
onClickToggle={() => {
const old = Boolean(window.getSettingValue(settingsReadReceipt));
window.setSettingValue(settingsReadReceipt, !old);
forceUpdate();
}}
title={window.i18n('readReceiptSettingTitle')}
description={window.i18n('readReceiptSettingDescription')}
active={window.getSettingValue(settingsReadReceipt)}
/>
<SessionToggleWithDescription
onClickToggle={() => {
const old = Boolean(window.getSettingValue(settingsTypingIndicator));
window.setSettingValue(settingsTypingIndicator, !old);
forceUpdate();
}}
title={window.i18n('typingIndicatorsSettingTitle')}
description={window.i18n('typingIndicatorsSettingDescription')}
active={Boolean(window.getSettingValue(settingsTypingIndicator))}
/>
<SessionToggleWithDescription
onClickToggle={() => {
const old = Boolean(window.getSettingValue(settingsAutoUpdate));
window.setSettingValue(settingsAutoUpdate, !old);
forceUpdate();
}}
title={window.i18n('autoUpdateSettingTitle')}
description={window.i18n('autoUpdateSettingDescription')}
active={Boolean(window.getSettingValue(settingsAutoUpdate))}
/>
{!props.hasPassword && (
<SessionSettingButtonItem
title={window.i18n('setAccountPasswordTitle')}
description={window.i18n('setAccountPasswordDescription')}
onClick={() => {
displayPasswordModal('set', props.onPasswordUpdated);
}}
buttonColor={SessionButtonColor.Primary}
buttonText={window.i18n('setPassword')}
/>
)}
{props.hasPassword && (
<SessionSettingButtonItem
title={window.i18n('changeAccountPasswordTitle')}
description={window.i18n('changeAccountPasswordDescription')}
onClick={() => {
displayPasswordModal('change', props.onPasswordUpdated);
}}
buttonColor={SessionButtonColor.Primary}
buttonText={window.i18n('changePassword')}
/>
)}
{props.hasPassword && (
<SessionSettingButtonItem
title={window.i18n('removeAccountPasswordTitle')}
description={window.i18n('removeAccountPasswordDescription')}
onClick={() => {
displayPasswordModal('remove', props.onPasswordUpdated);
}}
buttonColor={SessionButtonColor.Danger}
buttonText={window.i18n('removePassword')}
/>
)}
</>
);
}
return null;
};

@ -646,7 +646,7 @@ export async function handleCallTypeOffer(
if (!getCallMediaPermissionsSettings()) {
await handleMissedCall(sender, incomingOfferTimestamp);
// TODO audric show where to turn it on
debugger;
throw new Error('TODO AUDRIC');
return;
}

2
ts/window.d.ts vendored

@ -35,7 +35,7 @@ declare global {
friends: any;
getConversations: any;
getFriendsFromContacts: any;
getSettingValue: (id: string) => any;
getSettingValue: (id: string, comparisonValue?: any) => any;
setSettingValue: (id: string, value: any) => void;
i18n: LocalizerType;

Loading…
Cancel
Save