You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			246 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			TypeScript
		
	
			
		
		
	
	
			246 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			TypeScript
		
	
| import { shell } from 'electron';
 | |
| import React from 'react';
 | |
| import autoBind from 'auto-bind';
 | |
| import styled from 'styled-components';
 | |
| 
 | |
| import { SettingsHeader } from './SessionSettingsHeader';
 | |
| 
 | |
| import { SessionIconButton } from '../icon';
 | |
| 
 | |
| import { SessionNotificationGroupSettings } from './SessionNotificationGroupSettings';
 | |
| 
 | |
| import { CategoryConversations } from './section/CategoryConversations';
 | |
| import { SettingsCategoryPrivacy } from './section/CategoryPrivacy';
 | |
| import { SettingsCategoryAppearance } from './section/CategoryAppearance';
 | |
| import { Data } from '../../data/data';
 | |
| import { SettingsCategoryPermissions } from './section/CategoryPermissions';
 | |
| import { SettingsCategoryHelp } from './section/CategoryHelp';
 | |
| import { sessionPassword } from '../../state/ducks/modalDialog';
 | |
| import { PasswordAction } from '../dialog/SessionPasswordDialog';
 | |
| import { SectionType, showLeftPaneSection } from '../../state/ducks/section';
 | |
| 
 | |
| export function displayPasswordModal(
 | |
|   passwordAction: PasswordAction,
 | |
|   onPasswordUpdated: (action: string) => void
 | |
| ) {
 | |
|   window.inboxStore?.dispatch(
 | |
|     sessionPassword({
 | |
|       passwordAction,
 | |
|       onOk: () => {
 | |
|         onPasswordUpdated(passwordAction);
 | |
|       },
 | |
|     })
 | |
|   );
 | |
| }
 | |
| 
 | |
| export function getMediaPermissionsSettings() {
 | |
|   return window.getSettingValue('media-permissions');
 | |
| }
 | |
| 
 | |
| export function getCallMediaPermissionsSettings() {
 | |
|   return window.getSettingValue('call-media-permissions');
 | |
| }
 | |
| 
 | |
| export enum SessionSettingCategory {
 | |
|   Privacy = 'privacy',
 | |
|   Notifications = 'notifications',
 | |
|   Conversations = 'conversations',
 | |
|   MessageRequests = 'messageRequests',
 | |
|   Appearance = 'appearance',
 | |
|   Permissions = 'permissions',
 | |
|   Help = 'help',
 | |
|   RecoveryPhrase = 'recoveryPhrase',
 | |
|   ClearData = 'ClearData',
 | |
| }
 | |
| 
 | |
| export interface SettingsViewProps {
 | |
|   category: SessionSettingCategory;
 | |
| }
 | |
| 
 | |
| interface State {
 | |
|   hasPassword: boolean | null;
 | |
|   shouldLockSettings: boolean | null;
 | |
| }
 | |
| 
 | |
| const StyledVersionInfo = styled.div`
 | |
|   display: flex;
 | |
|   justify-content: space-between;
 | |
| 
 | |
|   padding: var(--margins-sm) var(--margins-md);
 | |
|   background: none;
 | |
|   font-size: var(--font-size-xs);
 | |
| `;
 | |
| 
 | |
| const StyledSpanSessionInfo = styled.span`
 | |
|   opacity: 0.4;
 | |
|   transition: var(--default-duration);
 | |
|   user-select: text;
 | |
|   cursor: pointer;
 | |
| 
 | |
|   &:hover {
 | |
|     opacity: 1;
 | |
|   }
 | |
| `;
 | |
| 
 | |
| const SessionInfo = () => {
 | |
|   return (
 | |
|     <StyledVersionInfo>
 | |
|       <StyledSpanSessionInfo
 | |
|         onClick={() => {
 | |
|           void shell.openExternal(
 | |
|             `https://github.com/oxen-io/session-desktop/releases/tag/v${window.versionInfo.version}`
 | |
|           );
 | |
|         }}
 | |
|       >
 | |
|         v{window.versionInfo.version}
 | |
|       </StyledSpanSessionInfo>
 | |
|       <StyledSpanSessionInfo>
 | |
|         <SessionIconButton
 | |
|           iconSize="medium"
 | |
|           iconType="oxen"
 | |
|           onClick={() => {
 | |
|             void shell.openExternal('https://oxen.io/');
 | |
|           }}
 | |
|         />
 | |
|       </StyledSpanSessionInfo>
 | |
|       <StyledSpanSessionInfo>{window.versionInfo.commitHash}</StyledSpanSessionInfo>
 | |
|     </StyledVersionInfo>
 | |
|   );
 | |
| };
 | |
| 
 | |
| const SettingInCategory = (props: {
 | |
|   category: SessionSettingCategory;
 | |
|   hasPassword: boolean;
 | |
|   onPasswordUpdated: (action: string) => void;
 | |
| }) => {
 | |
|   const { category, hasPassword, onPasswordUpdated } = props;
 | |
| 
 | |
|   if (hasPassword === null) {
 | |
|     return null;
 | |
|   }
 | |
|   switch (category) {
 | |
|     // special case for blocked user
 | |
|     case SessionSettingCategory.Conversations:
 | |
|       return <CategoryConversations />;
 | |
|     case SessionSettingCategory.Appearance:
 | |
|       return <SettingsCategoryAppearance hasPassword={hasPassword} />;
 | |
|     case SessionSettingCategory.Notifications:
 | |
|       return <SessionNotificationGroupSettings hasPassword={hasPassword} />;
 | |
|     case SessionSettingCategory.Privacy:
 | |
|       return (
 | |
|         <SettingsCategoryPrivacy onPasswordUpdated={onPasswordUpdated} hasPassword={hasPassword} />
 | |
|       );
 | |
|     case SessionSettingCategory.Help:
 | |
|       return <SettingsCategoryHelp hasPassword={hasPassword} />;
 | |
|     case SessionSettingCategory.Permissions:
 | |
|       return <SettingsCategoryPermissions hasPassword={hasPassword} />;
 | |
| 
 | |
|     // these three down there have no options, they are just a button
 | |
|     case SessionSettingCategory.ClearData:
 | |
|     case SessionSettingCategory.MessageRequests:
 | |
|     case SessionSettingCategory.RecoveryPhrase:
 | |
|     default:
 | |
|       return null;
 | |
|   }
 | |
| };
 | |
| 
 | |
| const StyledSettingsView = styled.div`
 | |
|   flex-grow: 1;
 | |
|   display: flex;
 | |
|   flex-direction: column;
 | |
|   justify-content: space-between;
 | |
|   overflow: hidden;
 | |
| `;
 | |
| 
 | |
| const StyledSettingsList = styled.div`
 | |
|   overflow-y: auto;
 | |
|   overflow-x: hidden;
 | |
|   display: flex;
 | |
|   flex-direction: column;
 | |
| `;
 | |
| 
 | |
| export class SessionSettingsView extends React.Component<SettingsViewProps, State> {
 | |
|   public settingsViewRef: React.RefObject<HTMLDivElement>;
 | |
| 
 | |
|   public constructor(props: any) {
 | |
|     super(props);
 | |
| 
 | |
|     this.state = {
 | |
|       hasPassword: null,
 | |
|       shouldLockSettings: true,
 | |
|     };
 | |
| 
 | |
|     this.settingsViewRef = React.createRef();
 | |
|     autoBind(this);
 | |
| 
 | |
|     // eslint-disable-next-line more/no-then
 | |
|     void Data.getPasswordHash().then(hash => {
 | |
|       this.setState({
 | |
|         hasPassword: !!hash,
 | |
|       });
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   public componentDidUpdate(_: SettingsViewProps, _prevState: State) {
 | |
|     const oldShouldRenderPasswordLock = _prevState.shouldLockSettings && _prevState.hasPassword;
 | |
|     const newShouldRenderPasswordLock = this.state.shouldLockSettings && this.state.hasPassword;
 | |
| 
 | |
|     if (
 | |
|       newShouldRenderPasswordLock &&
 | |
|       newShouldRenderPasswordLock !== oldShouldRenderPasswordLock
 | |
|     ) {
 | |
|       displayPasswordModal('enter', action => {
 | |
|         if (action === 'enter') {
 | |
|           // Unlocked settings
 | |
|           this.setState({
 | |
|             shouldLockSettings: false,
 | |
|           });
 | |
|         }
 | |
|       });
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   public render() {
 | |
|     const { category } = this.props;
 | |
|     const shouldRenderPasswordLock = this.state.shouldLockSettings && this.state.hasPassword;
 | |
| 
 | |
|     return (
 | |
|       <div className="session-settings">
 | |
|         {shouldRenderPasswordLock ? (
 | |
|           <></>
 | |
|         ) : (
 | |
|           <>
 | |
|             <SettingsHeader category={category} />
 | |
|             <StyledSettingsView>
 | |
|               <StyledSettingsList ref={this.settingsViewRef}>
 | |
|                 <SettingInCategory
 | |
|                   category={category}
 | |
|                   onPasswordUpdated={this.onPasswordUpdated}
 | |
|                   hasPassword={Boolean(this.state.hasPassword)}
 | |
|                 />
 | |
|               </StyledSettingsList>
 | |
|               <SessionInfo />
 | |
|             </StyledSettingsView>
 | |
|           </>
 | |
|         )}
 | |
|       </div>
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   public onPasswordUpdated(action: string) {
 | |
|     if (action === 'set' || action === 'change') {
 | |
|       this.setState({
 | |
|         hasPassword: true,
 | |
|         shouldLockSettings: true,
 | |
|       });
 | |
|       window.inboxStore?.dispatch(showLeftPaneSection(SectionType.Message));
 | |
|     }
 | |
| 
 | |
|     if (action === 'remove') {
 | |
|       this.setState({
 | |
|         hasPassword: false,
 | |
|       });
 | |
|     }
 | |
|   }
 | |
| }
 |