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,
 | 
						|
      });
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 |