cinny/src/app/organisms/settings/Settings.jsx

243 lines
7.6 KiB
React
Raw Normal View History

2021-08-01 16:00:35 +02:00
import React, { useState } from 'react';
2021-07-28 15:15:52 +02:00
import PropTypes from 'prop-types';
import './Settings.scss';
2021-07-31 10:21:19 +02:00
import initMatrix from '../../../client/initMatrix';
import cons from '../../../client/state/cons';
2021-07-28 15:15:52 +02:00
import settings from '../../../client/state/settings';
import { toggleSystemTheme, toggleMarkdown, toggleMembershipEvents, toggleNickAvatarEvents } from '../../../client/action/settings';
import logout from '../../../client/action/logout';
2021-07-28 15:15:52 +02:00
import Text from '../../atoms/text/Text';
import IconButton from '../../atoms/button/IconButton';
2021-07-31 18:20:15 +02:00
import Button from '../../atoms/button/Button';
2021-08-11 09:41:55 +02:00
import Toggle from '../../atoms/button/Toggle';
2021-07-28 15:15:52 +02:00
import SegmentedControls from '../../atoms/segmented-controls/SegmentedControls';
2021-07-31 16:23:08 +02:00
import PopupWindow, { PWContentSelector } from '../../molecules/popup-window/PopupWindow';
2021-07-28 15:15:52 +02:00
import SettingTile from '../../molecules/setting-tile/SettingTile';
2021-12-06 05:52:45 +01:00
import ImportE2ERoomKeys from '../../molecules/import-export-e2e-room-keys/ImportE2ERoomKeys';
import ExportE2ERoomKeys from '../../molecules/import-export-e2e-room-keys/ExportE2ERoomKeys';
2021-07-28 15:15:52 +02:00
2021-09-13 05:25:58 +02:00
import ProfileEditor from '../profile-editor/ProfileEditor';
import SettingsIC from '../../../../public/res/ic/outlined/settings.svg';
2021-07-31 16:23:08 +02:00
import SunIC from '../../../../public/res/ic/outlined/sun.svg';
import LockIC from '../../../../public/res/ic/outlined/lock.svg';
import InfoIC from '../../../../public/res/ic/outlined/info.svg';
import PowerIC from '../../../../public/res/ic/outlined/power.svg';
2021-07-28 15:15:52 +02:00
import CrossIC from '../../../../public/res/ic/outlined/cross.svg';
2021-07-31 18:20:15 +02:00
import CinnySVG from '../../../../public/res/svg/cinny.svg';
2021-09-09 07:47:26 +02:00
function GeneralSection() {
return (
<div className="settings-content">
<SettingTile
title=""
2021-09-09 07:47:26 +02:00
content={(
<ProfileEditor userId={initMatrix.matrixClient.getUserId()} />
)}
/>
</div>
);
}
2021-07-31 16:23:08 +02:00
function AppearanceSection() {
2021-08-11 09:41:55 +02:00
const [, updateState] = useState({});
2021-07-31 16:23:08 +02:00
return (
<div className="settings-content">
<SettingTile
title="Follow system theme"
options={(
<Toggle
isActive={settings.useSystemTheme}
onToggle={() => { toggleSystemTheme(); updateState({}); }}
2021-07-31 16:23:08 +02:00
/>
)}
content={<Text variant="b3">Use light or dark mode based on the system's settings.</Text>}
2021-07-31 16:23:08 +02:00
/>
{(() => {
if (!settings.useSystemTheme) {
return <SettingTile
title="Theme"
content={(
<SegmentedControls
selected={settings.getThemeIndex()}
segments={[
{ text: 'Light' },
{ text: 'Silver' },
{ text: 'Dark' },
{ text: 'Butter' },
]}
onSelect={(index) => settings.setTheme(index)}
/>
)}
/>
}
})()}
2021-08-11 09:41:55 +02:00
<SettingTile
title="Markdown formatting"
options={(
<Toggle
isActive={settings.isMarkdown}
onToggle={() => { toggleMarkdown(); updateState({}); }}
2021-08-11 09:41:55 +02:00
/>
)}
content={<Text variant="b3">Format messages with markdown syntax before sending.</Text>}
/>
<SettingTile
title="Hide membership events"
options={(
<Toggle
isActive={settings.hideMembershipEvents}
onToggle={() => { toggleMembershipEvents(); updateState({}); }}
/>
)}
content={<Text variant="b3">Hide membership change messages from room timeline. (Join, Leave, Invite, Kick and Ban)</Text>}
/>
<SettingTile
title="Hide nick/avatar events"
options={(
<Toggle
isActive={settings.hideNickAvatarEvents}
onToggle={() => { toggleNickAvatarEvents(); updateState({}); }}
/>
)}
content={<Text variant="b3">Hide nick and avatar change messages from room timeline.</Text>}
/>
2021-07-31 16:23:08 +02:00
</div>
);
}
function SecuritySection() {
2021-07-31 18:20:15 +02:00
return (
2021-08-01 16:00:35 +02:00
<div className="set-security settings-content">
<SettingTile
title={`Device ID: ${initMatrix.matrixClient.getDeviceId()}`}
2021-08-19 18:54:09 +02:00
/>
<SettingTile
title={`Device key: ${initMatrix.matrixClient.getDeviceEd25519Key().match(/.{1,4}/g).join(' ')}`}
content={<Text variant="b3">Use this device ID-key combo to verify or manage this session from Element client.</Text>}
2021-08-01 16:00:35 +02:00
/>
2021-12-06 05:52:45 +01:00
<SettingTile
title="Export E2E room keys"
content={(
<>
<Text variant="b3">Export end-to-end encryption room keys to decrypt old messages in other session. In order to encrypt keys you need to set a password, which will be used while importing.</Text>
<ExportE2ERoomKeys />
</>
)}
/>
2021-08-01 16:00:35 +02:00
<SettingTile
title="Import E2E room keys"
content={(
<>
2021-08-07 03:05:10 +02:00
<Text variant="b3">{'To decrypt older messages, Export E2EE room keys from Element (Settings > Security & Privacy > Encryption > Cryptography) and import them here. Imported keys are encrypted so you\'ll have to enter the password you set in order to decrypt it.'}</Text>
2021-08-01 16:00:35 +02:00
<ImportE2ERoomKeys />
</>
)}
/>
2021-07-31 18:20:15 +02:00
</div>
);
2021-07-31 16:23:08 +02:00
}
function AboutSection() {
return (
2021-07-31 18:20:15 +02:00
<div className="settings-content settings__about">
2021-08-01 16:00:35 +02:00
<div className="set-about__branding">
2021-07-31 18:20:15 +02:00
<img width="60" height="60" src={CinnySVG} alt="Cinny logo" />
<div>
<Text variant="h2">
Cinny
<span className="text text-b3" style={{ margin: '0 var(--sp-extra-tight)' }}>{`v${cons.version}`}</span>
2021-07-31 18:20:15 +02:00
</Text>
<Text>Yet another matrix client</Text>
2021-08-01 16:00:35 +02:00
<div className="set-about__btns">
2021-07-31 18:20:15 +02:00
<Button onClick={() => window.open('https://github.com/ajbura/cinny')}>Source code</Button>
<Button onClick={() => window.open('https://cinny.in/#sponsor')}>Support</Button>
2021-07-31 18:20:15 +02:00
</div>
</div>
</div>
2021-07-31 16:23:08 +02:00
</div>
);
}
2021-07-28 15:15:52 +02:00
function Settings({ isOpen, onRequestClose }) {
2021-07-31 16:23:08 +02:00
const settingSections = [{
2021-09-09 07:47:26 +02:00
name: 'General',
2021-09-13 05:25:58 +02:00
iconSrc: SettingsIC,
2021-09-09 07:47:26 +02:00
render() {
return <GeneralSection />;
},
}, {
2021-07-31 16:23:08 +02:00
name: 'Appearance',
iconSrc: SunIC,
render() {
return <AppearanceSection />;
},
}, {
name: 'Security & Privacy',
iconSrc: LockIC,
render() {
return <SecuritySection />;
},
}, {
name: 'Help & About',
iconSrc: InfoIC,
render() {
return <AboutSection />;
},
}];
const [selectedSection, setSelectedSection] = useState(settingSections[0]);
const handleLogout = () => {
if (confirm('Confirm logout')) logout();
};
2021-07-28 15:15:52 +02:00
return (
<PopupWindow
className="settings-window"
isOpen={isOpen}
onRequestClose={onRequestClose}
title="Settings"
2021-07-31 16:23:08 +02:00
contentTitle={selectedSection.name}
drawer={(
<>
{
settingSections.map((section) => (
<PWContentSelector
key={section.name}
selected={selectedSection.name === section.name}
onClick={() => setSelectedSection(section)}
iconSrc={section.iconSrc}
>
{section.name}
</PWContentSelector>
))
}
2021-07-31 16:23:08 +02:00
<PWContentSelector
variant="danger"
onClick={handleLogout}
iconSrc={PowerIC}
2021-07-31 16:23:08 +02:00
>
Logout
2021-07-31 16:23:08 +02:00
</PWContentSelector>
</>
)}
2021-07-28 15:15:52 +02:00
contentOptions={<IconButton src={CrossIC} onClick={onRequestClose} tooltip="Close" />}
>
2021-07-31 16:23:08 +02:00
{selectedSection.render()}
2021-07-28 15:15:52 +02:00
</PopupWindow>
);
}
Settings.propTypes = {
isOpen: PropTypes.bool.isRequired,
onRequestClose: PropTypes.func.isRequired,
};
export default Settings;