settings toggling abstraction
This commit is contained in:
parent
b97c9ec8e4
commit
b0658ba7ed
|
@ -1317,23 +1317,30 @@
|
|||
"message": "Permissions",
|
||||
"description": "Header for permissions section of settings"
|
||||
},
|
||||
"mediaPermissionsDescription": {
|
||||
"message": "Allow access to camera and microphone",
|
||||
"description": "Description of the media permission description"
|
||||
},
|
||||
"general": {
|
||||
"message": "General",
|
||||
"description": "Header for general options on the settings screen"
|
||||
},
|
||||
"linkPreviews": {
|
||||
"linkPreviewsTitle": {
|
||||
"message": "Link Previews",
|
||||
"description":
|
||||
"Option to control creation and send of link previews in setting screen"
|
||||
},
|
||||
"linkPreviewsSettingDescription": {
|
||||
"linkPreviewDescription": {
|
||||
"message": "Enable link previews",
|
||||
"description": "Description shown for the Link Preview option "
|
||||
},
|
||||
"mediaPermissionsTitle": {
|
||||
"message": "Microphone and Camera"
|
||||
},
|
||||
"mediaPermissionsDescription": {
|
||||
"message": "Allow access to camera and microphone",
|
||||
"description": "Description of the media permission description"
|
||||
},
|
||||
"spellCheckTitle": {
|
||||
"message": "Spell Check",
|
||||
"description": "Description of the media permission description"
|
||||
},
|
||||
"spellCheckDescription": {
|
||||
"message": "Enable spell check of text entered in message composition box",
|
||||
"description": "Description of the media permission description"
|
||||
|
@ -1399,7 +1406,7 @@
|
|||
"description": "Warning for the time to live setting"
|
||||
},
|
||||
"notificationSettingsDialog": {
|
||||
"message": "When messages arrive, display notifications that reveal:",
|
||||
"message": "When messages arrive, display notifications that reveal...",
|
||||
"description": "Explain the purpose of the notification settings"
|
||||
},
|
||||
"disableNotifications": {
|
||||
|
@ -1836,12 +1843,22 @@
|
|||
"message": "Dark",
|
||||
"description": "Label text for dark theme"
|
||||
},
|
||||
"themeToggleTitle" : {
|
||||
"message": "Light Mode"
|
||||
},
|
||||
"themeToggleDescription" : {
|
||||
"message": "Choose the theme best suited to you"
|
||||
},
|
||||
"noteToSelf": {
|
||||
"message": "Note to Self",
|
||||
"description": "Name for the conversation with your own phone number"
|
||||
},
|
||||
"hideMenuBar": {
|
||||
"message": "Hide menu bar",
|
||||
"hideMenuBarTitle": {
|
||||
"message": "Hide Menu Bar",
|
||||
"description": "Label text for menu bar visibility setting"
|
||||
},
|
||||
"hideMenuBarDescription": {
|
||||
"message": "Toggle system menu bar visibility",
|
||||
"description": "Label text for menu bar visibility setting"
|
||||
},
|
||||
"startConversation": {
|
||||
|
@ -2481,7 +2498,7 @@
|
|||
"message": "Decline"
|
||||
},
|
||||
"generalSettingsTitle": {
|
||||
"message": "Generals"
|
||||
"message": "General"
|
||||
},
|
||||
"generalSettingsDescription": {
|
||||
"message": "General settings and configuration"
|
||||
|
@ -2492,11 +2509,17 @@
|
|||
"accountSettingsDescription": {
|
||||
"message": "Manage your account"
|
||||
},
|
||||
"permissionSettingsTitle": {
|
||||
"message": "Permissions"
|
||||
},
|
||||
"permissionSettingsDescription": {
|
||||
"message": "Set Session's permissions"
|
||||
},
|
||||
"privacySettingsTitle": {
|
||||
"message": "Privacy"
|
||||
},
|
||||
"privacySettingsDescription": {
|
||||
"message": "Privacy description"
|
||||
"message": "Manage your privacy settings"
|
||||
},
|
||||
"notificationSettingsTitle": {
|
||||
"message": "Notifications"
|
||||
|
|
|
@ -911,6 +911,20 @@
|
|||
window.Events.setHideMenuBar(newValue);
|
||||
}
|
||||
|
||||
window.toggleSpellCheck = () => {
|
||||
const newValue = ! window.getSettingValue('spell-check');
|
||||
window.Events.setSpellCheck(newValue);
|
||||
}
|
||||
|
||||
window.toggleLinkPreview = () => {
|
||||
const newValue = ! window.getSettingValue('link-preview-setting');
|
||||
window.Events.setLinkPreviewSetting(newValue);
|
||||
}
|
||||
|
||||
window.toggleMediaPermissions= () => {
|
||||
|
||||
}
|
||||
|
||||
window.sendGroupInvitations = (serverInfo, pubkeys) => {
|
||||
pubkeys.forEach(async pubkey => {
|
||||
const convo = await ConversationController.getOrCreateAndWait(
|
||||
|
|
|
@ -249,8 +249,8 @@
|
|||
spellCheckHeader: i18n('spellCheck'),
|
||||
spellCheckDescription: i18n('spellCheckDescription'),
|
||||
blockedHeader: 'Blocked Users',
|
||||
linkPreviews: i18n('linkPreviews'),
|
||||
linkPreviewsSettingDescription: i18n('linkPreviewsSettingDescription'),
|
||||
linkPreviews: i18n('linkPreviewsTitle'),
|
||||
linkPreviewsSettingDescription: i18n('linkPreviewsDescription'),
|
||||
};
|
||||
},
|
||||
onClose() {
|
||||
|
|
|
@ -1002,6 +1002,8 @@ label {
|
|||
|
||||
&__title {
|
||||
line-height: 1.7;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&__description {
|
||||
|
@ -1009,6 +1011,12 @@ label {
|
|||
font-weight: 100;
|
||||
@include session-color-subtle($session-color-white);
|
||||
}
|
||||
|
||||
&__content{
|
||||
label {
|
||||
@include session-color-subtle($session-color-white);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1068,12 +1076,24 @@ label {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
.session-radio-group fieldset {
|
||||
border: none;
|
||||
margin-left: $session-margin-sm;
|
||||
margin-top: $session-margin-sm;
|
||||
|
||||
.session-radio {
|
||||
padding: $session-margin-xs 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.session-radio {
|
||||
input[type="radio"] {
|
||||
border: 0;
|
||||
opacity: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
label {
|
||||
|
@ -1085,10 +1105,10 @@ label {
|
|||
display: inline-block;
|
||||
width: 0.5em;
|
||||
height: 0.5em;
|
||||
margin-right: 0.5em;
|
||||
margin-right: 0.80em;
|
||||
border-radius: 100%;
|
||||
vertical-align: -3px;
|
||||
border: 2px solid $session-color-white;
|
||||
border: 2px solid rgba($session-color-white, 0.6);
|
||||
padding: 0.2em;
|
||||
background-color: transparent;
|
||||
background-clip: content-box;
|
||||
|
@ -1106,4 +1126,5 @@ label {
|
|||
label:before {
|
||||
transition: all $session-transition-duration ease;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -173,26 +173,21 @@ export class LeftPaneSettingSection extends React.Component<Props, State> {
|
|||
title: window.i18n('generalSettingsTitle'),
|
||||
description: window.i18n('generalSettingsDescription'),
|
||||
},
|
||||
{
|
||||
id: SessionSettingCategory.Account,
|
||||
title: window.i18n('accountSettingsTitle'),
|
||||
description: window.i18n('accountSettingsDescription'),
|
||||
},
|
||||
{
|
||||
id: SessionSettingCategory.Privacy,
|
||||
title: window.i18n('privacySettingsTitle'),
|
||||
description: window.i18n('privacySettingsDescription'),
|
||||
},
|
||||
{
|
||||
id: SessionSettingCategory.Permissions,
|
||||
title: window.i18n('permissionSettingsTitle'),
|
||||
description: window.i18n('permissionSettingsDescription'),
|
||||
},
|
||||
{
|
||||
id: SessionSettingCategory.Notifications,
|
||||
title: window.i18n('notificationSettingsTitle'),
|
||||
description: window.i18n('notificationSettingsDescription'),
|
||||
},
|
||||
{
|
||||
id: SessionSettingCategory.Devices,
|
||||
title: window.i18n('devicesSettingsTitle'),
|
||||
description: window.i18n('devicesSettingsDescription'),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
|
||||
interface Props {
|
||||
label: string;
|
||||
value: string;
|
||||
active: boolean;
|
||||
group?: string;
|
||||
onClick: any;
|
||||
}
|
||||
|
||||
interface State {
|
||||
|
@ -12,6 +13,10 @@ interface State {
|
|||
}
|
||||
|
||||
export class SessionRadio extends React.PureComponent<Props, State> {
|
||||
public static defaultProps = {
|
||||
onClick: () => null,
|
||||
}
|
||||
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
this.clickHandler = this.clickHandler.bind(this);
|
||||
|
@ -23,20 +28,32 @@ export class SessionRadio extends React.PureComponent<Props, State> {
|
|||
|
||||
public render() {
|
||||
const active = this.state.active;
|
||||
const { label } = this.props;
|
||||
const { label, group, value } = this.props;
|
||||
|
||||
|
||||
return (
|
||||
<div className={classNames('session-radio', active && 'checked')}>
|
||||
<input type="radio" />
|
||||
<div className='session-radio'>
|
||||
<input
|
||||
type="radio"
|
||||
name={group || ''}
|
||||
value={value}
|
||||
defaultChecked={ active }
|
||||
onClick={this.clickHandler}
|
||||
/>
|
||||
<label>{ label } </label>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private clickHandler() {
|
||||
this.setState({
|
||||
active: !this.state.active,
|
||||
});
|
||||
private clickHandler(e: any) {
|
||||
if (this.props.onClick) {
|
||||
e.stopPropagation();
|
||||
this.props.onClick();
|
||||
|
||||
this.setState({
|
||||
active: !this.state.active,
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { SessionRadio } from './SessionRadio';
|
||||
|
||||
interface Props {
|
||||
activeItem: Number;
|
||||
initalItem: string;
|
||||
items: Array<any>;
|
||||
group: string;
|
||||
onClick?: any;
|
||||
}
|
||||
|
||||
interface State {
|
||||
activeItem: Number;
|
||||
activeItem: string;
|
||||
}
|
||||
|
||||
export class SessionRadioGroup extends React.PureComponent<Props, State> {
|
||||
|
@ -17,23 +21,41 @@ export class SessionRadioGroup extends React.PureComponent<Props, State> {
|
|||
constructor(props: any) {
|
||||
super(props);
|
||||
this.clickHandler = this.clickHandler.bind(this);
|
||||
|
||||
this.state = {
|
||||
activeItem: this.props.initalItem,
|
||||
}
|
||||
}
|
||||
|
||||
public render() {
|
||||
const { items, group } = this.props;
|
||||
|
||||
return (
|
||||
<div
|
||||
className='session-radio-group'
|
||||
onClick={this.clickHandler}
|
||||
>
|
||||
<label className="radio-container">Four
|
||||
<input type="checkbox"/>>
|
||||
<span className="radio-checkmark"></span>
|
||||
</label>
|
||||
<fieldset id={group}>
|
||||
{ items.map(item => {
|
||||
return (
|
||||
<SessionRadio
|
||||
key={item.value}
|
||||
label={item.label}
|
||||
active={item.value === this.state.activeItem}
|
||||
value={item.value}
|
||||
group={group}
|
||||
onClick={this.clickHandler}
|
||||
/>
|
||||
);
|
||||
})
|
||||
}
|
||||
</fieldset>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private clickHandler(e: any) {
|
||||
return;
|
||||
private clickHandler() {
|
||||
if (this.props.onClick) {
|
||||
this.props.onClick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,10 @@ import React from 'react';
|
|||
import classNames from 'classnames';
|
||||
|
||||
import { SessionToggle } from '../SessionToggle';
|
||||
import { SessionButton, SessionButtonColor } from '../SessionButton';
|
||||
import { SessionButton } from '../SessionButton';
|
||||
import { SessionSettingType } from './SessionSettings';
|
||||
|
||||
import { SessionRadio } from '../SessionRadio';
|
||||
import { SessionRadioGroup } from '../SessionRadioGroup';
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
|
@ -14,9 +14,7 @@ interface Props {
|
|||
value: any;
|
||||
options?: Array<any>;
|
||||
onClick?: any;
|
||||
inline?: boolean;
|
||||
buttonText?: string;
|
||||
buttonColor?: SessionButtonColor;
|
||||
content: any;
|
||||
}
|
||||
|
||||
export class SessionSettingListItem extends React.Component<Props> {
|
||||
|
@ -37,15 +35,15 @@ export class SessionSettingListItem extends React.Component<Props> {
|
|||
description,
|
||||
type,
|
||||
value,
|
||||
inline,
|
||||
buttonText,
|
||||
buttonColor,
|
||||
content,
|
||||
} = this.props;
|
||||
|
||||
const inline = ![SessionSettingType.Options, SessionSettingType.Slider].includes(type);
|
||||
|
||||
return (
|
||||
<div className="session-settings-item">
|
||||
<div className="session-settings-item__info">
|
||||
<div className={classNames('session-settings-item__title', inline && 'inline')}>{title}</div>
|
||||
<div className={classNames('session-settings-item', inline && 'inline')}>
|
||||
<div className='session-settings-item__info'>
|
||||
<div className='session-settings-item__title'>{title}</div>
|
||||
|
||||
{description && (
|
||||
<div className="session-settings-item__description">
|
||||
|
@ -54,26 +52,30 @@ export class SessionSettingListItem extends React.Component<Props> {
|
|||
)}
|
||||
</div>
|
||||
|
||||
{type === SessionSettingType.Toggle && (
|
||||
<div className="session-sessings-item__selection">
|
||||
<SessionToggle active={Boolean(value)} onClick={this.handleClick} />
|
||||
</div>
|
||||
)}
|
||||
<div className="session-settings-item__content">
|
||||
{type === SessionSettingType.Toggle && (
|
||||
<div className="session-sessings-item__selection">
|
||||
<SessionToggle active={Boolean(value)} onClick={this.handleClick} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{type === SessionSettingType.Button && (
|
||||
<SessionButton
|
||||
text={buttonText}
|
||||
buttonColor={buttonColor}
|
||||
onClick={this.handleClick}
|
||||
/>
|
||||
)}
|
||||
{type === SessionSettingType.Button && (
|
||||
<SessionButton
|
||||
text={content.buttonText}
|
||||
buttonColor={content.buttonColor}
|
||||
onClick={this.handleClick}
|
||||
/>
|
||||
)}
|
||||
|
||||
{type === SessionSettingType.Options && (
|
||||
<SessionRadio
|
||||
label="Both sender name and message"
|
||||
active={false}
|
||||
/>
|
||||
)}
|
||||
{type === SessionSettingType.Options && (
|
||||
<SessionRadioGroup
|
||||
initalItem={content.options.initalItem}
|
||||
group={content.options.group}
|
||||
items={content.options.items}
|
||||
onClick={this.handleClick}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -3,11 +3,11 @@ import React from 'react';
|
|||
import { SettingsHeader } from './SessionSettingsHeader';
|
||||
import { SessionSettingListItem } from './SessionSettingListItem';
|
||||
|
||||
|
||||
export enum SessionSettingCategory {
|
||||
General = 'general',
|
||||
Account = 'account',
|
||||
Privacy = 'privacy',
|
||||
Permissions = 'permissions',
|
||||
Notifications = 'notifications',
|
||||
Devices = 'devices',
|
||||
}
|
||||
|
@ -42,54 +42,86 @@ export class SettingsView extends React.Component<SettingsViewProps> {
|
|||
const localSettings = [
|
||||
{
|
||||
id: 'theme-setting',
|
||||
title: 'Light Mode',
|
||||
title: window.i18n('themeToggleTitle'),
|
||||
description: 'Choose the theme best suited to you',
|
||||
hidden: true,
|
||||
comparisonValue: 'light',
|
||||
type: SessionSettingType.Options,
|
||||
type: SessionSettingType.Toggle,
|
||||
category: SessionSettingCategory.General,
|
||||
setFn: window.toggleTheme,
|
||||
childProps: {},
|
||||
content: {},
|
||||
},
|
||||
{
|
||||
id: 'hide-menu-bar',
|
||||
title: 'Hide Menu Bar',
|
||||
description: 'Toggle system menu bar visibi',
|
||||
title: window.i18n('hideMenuBarTitle'),
|
||||
description: window.i18n('hideMenuBarDescription'),
|
||||
hidden: !Settings.isHideMenuBarSupported(),
|
||||
type: SessionSettingType.Toggle,
|
||||
category: SessionSettingCategory.General,
|
||||
setFn: window.toggleMenuBar,
|
||||
childProps: {},
|
||||
content: {},
|
||||
},
|
||||
{
|
||||
id: 'spell-check',
|
||||
title: window.i18n('spellCheckTitle'),
|
||||
description: window.i18n('spellCheckDescription'),
|
||||
hidden: false,
|
||||
type: SessionSettingType.Toggle,
|
||||
category: SessionSettingCategory.General,
|
||||
setFn: window.toggleSpellCheck,
|
||||
content: {},
|
||||
},
|
||||
{
|
||||
id: 'link-preview-setting',
|
||||
title: window.i18n('linkPreviewsTitle'),
|
||||
description: window.i18n('linkPreviewDescription'),
|
||||
hidden: false,
|
||||
type: SessionSettingType.Toggle,
|
||||
category: SessionSettingCategory.General,
|
||||
setFn: window.toggleLinkPreview,
|
||||
content: {},
|
||||
},
|
||||
|
||||
{
|
||||
id: 'notification-setting',
|
||||
title: 'Notifications',
|
||||
description: 'When messages arive, display notifications that reveal:',
|
||||
title: window.i18n('notificationSettingsDialog'),
|
||||
type: SessionSettingType.Options,
|
||||
category: SessionSettingCategory.Notifications,
|
||||
setFn: () => window.setSettingValue(this.getNotificationPreference()),
|
||||
childProps: {
|
||||
options: [
|
||||
{
|
||||
id: 'default',
|
||||
desc: 'Both sender name and message',
|
||||
},
|
||||
{
|
||||
id: 'name',
|
||||
desc: 'Only sender name',
|
||||
},
|
||||
{
|
||||
id: 'count',
|
||||
desc: 'Neither name nor messsage',
|
||||
},
|
||||
{
|
||||
id: 'off',
|
||||
desc: 'Disable notificationss',
|
||||
},
|
||||
],
|
||||
activeIndex: 0
|
||||
setFn: () => this.setOptionsSetting('notification-setting'),
|
||||
content: {
|
||||
options: {
|
||||
group: 'notification-setting',
|
||||
initalItem: window.getSettingValue('notification-setting'),
|
||||
items: [{
|
||||
label: window.i18n('nameAndMessage'),
|
||||
value: 'message'
|
||||
},{
|
||||
label: window.i18n('nameOnly'),
|
||||
value: 'name'
|
||||
},{
|
||||
label: window.i18n('noNameOrMessage'),
|
||||
value: 'count'
|
||||
},{
|
||||
label: window.i18n('disableNotifications'),
|
||||
value: 'off'
|
||||
}],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
id: 'media-permissions',
|
||||
title: window.i18n('mediaPermissionsTitle'),
|
||||
description: window.i18n('mediaPermissionsDescription'),
|
||||
hidden: false,
|
||||
type: SessionSettingType.Toggle,
|
||||
category: SessionSettingCategory.Permissions,
|
||||
setFn: window.toggleMediaPermissions,
|
||||
content: {},
|
||||
},
|
||||
|
||||
|
||||
];
|
||||
|
||||
return (
|
||||
|
@ -103,14 +135,13 @@ export class SettingsView extends React.Component<SettingsViewProps> {
|
|||
{renderSettings && !(setting.hidden) && (
|
||||
<SessionSettingListItem
|
||||
title={setting.title}
|
||||
description={setting.description}
|
||||
description={setting.description || ''}
|
||||
type={setting.type}
|
||||
value={ window.getSettingValue(setting.id, setting.comparisonValue || null) }
|
||||
onClick={() => {
|
||||
this.updateSetting(setting);
|
||||
}}
|
||||
buttonText={setting.childProps.buttonText || undefined}
|
||||
buttonColor={setting.childProps.buttonColor || undefined}
|
||||
content={setting.content || undefined}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
@ -134,27 +165,25 @@ export class SettingsView extends React.Component<SettingsViewProps> {
|
|||
}
|
||||
|
||||
public updateSetting(item: any) {
|
||||
if (item.type === SessionSettingType.Toggle) {
|
||||
// If no custom afterClick function given, alter values in storage here
|
||||
if (!item.setFn) {
|
||||
// Switch to opposite state
|
||||
const newValue = !window.getSettingValue(item.id);
|
||||
window.setSettingValue(item.id, newValue);
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
public getNotificationPreference(){
|
||||
const value = window.getSettingValue('notification-setting');
|
||||
return value || 'default';
|
||||
public setOptionsSetting(settingID: string){
|
||||
const selectedValue = $(`#${settingID} .session-radio input:checked`).val();
|
||||
window.setSettingValue(settingID, selectedValue);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,6 +26,9 @@ interface Window {
|
|||
deleteAccount: any;
|
||||
toggleTheme: any;
|
||||
toggleMenuBar: any;
|
||||
toggleSpellCheck: any;
|
||||
toggleLinkPreview: any;
|
||||
toggleMediaPermissions: any;
|
||||
getSettingValue: any;
|
||||
setSettingValue: any;
|
||||
|
||||
|
|
Loading…
Reference in New Issue