import React from 'react'; import classNames from 'classnames'; import { SessionIcon } from './icon'; import { withTheme } from 'styled-components'; import autoBind from 'auto-bind'; import { SessionButton, SessionButtonColor } from './basic/SessionButton'; import { Constants } from '../session'; import { SessionSpinner } from './basic/SessionSpinner'; interface State { error: string; errorCount: number; clearDataView: boolean; loading: boolean; } export const MAX_LOGIN_TRIES = 3; const TextPleaseWait = (props: { isLoading: boolean }) => { if (!props.isLoading) { return null; } return
{window.i18n('pleaseWaitOpenAndOptimizeDb')}
; }; class SessionPasswordPromptInner extends React.PureComponent<{}, State> { private inputRef?: any; constructor(props: any) { super(props); this.state = { error: '', errorCount: 0, clearDataView: false, loading: false, }; autoBind(this); } public componentDidMount() { setTimeout(() => { this.inputRef?.focus(); }, 100); } public render() { const showResetElements = this.state.errorCount >= MAX_LOGIN_TRIES; const isLoading = this.state.loading; const wrapperClass = this.state.clearDataView ? 'clear-data-wrapper' : 'password-prompt-wrapper'; const containerClass = this.state.clearDataView ? 'clear-data-container' : 'password-prompt-container'; const infoAreaClass = this.state.clearDataView ? 'warning-info-area' : 'password-info-area'; const infoTitle = this.state.clearDataView ? window.i18n('clearAllData') : window.i18n('passwordViewTitle'); const buttonGroup = this.state.clearDataView ? this.renderClearDataViewButtons() : this.renderPasswordViewButtons(); const featureElement = this.state.clearDataView ? (

{window.i18n('deleteAccountWarning')}

) : ( { this.inputRef = input; }} /> ); const infoIcon = this.state.clearDataView ? ( ) : ( ); const errorSection = !this.state.clearDataView && (
{this.state.error && ( <> {showResetElements ? (
{window.i18n('maxPasswordAttempts')}
) : (
{this.state.error}
)} )}
); const spinner = isLoading ? : null; return (
{infoIcon}

{infoTitle}

{spinner || featureElement} {errorSection} {buttonGroup}
); } public onKeyUp(event: any) { switch (event.key) { case 'Enter': this.initLogin(); break; default: } event.preventDefault(); } public async onLogin(passPhrase: string) { const passPhraseTrimmed = passPhrase.trim(); try { await window.onLogin(passPhraseTrimmed); } catch (error) { // Increment the error counter and show the button if necessary this.setState({ errorCount: this.state.errorCount + 1, }); this.setState({ error }); global.setTimeout(() => { document.getElementById('password-prompt-input')?.focus(); }, 50); } this.setState({ loading: false, }); } private initLogin() { this.setState({ loading: true, }); const passPhrase = String((this.inputRef as HTMLInputElement).value); // this is to make sure a render has the time to happen before we lock the thread with all of the db work // this might be removed once we get the db operations to a worker thread global.setTimeout(() => this.onLogin(passPhrase), 100); } private initClearDataView() { this.setState({ error: '', errorCount: 0, clearDataView: true, }); } private renderPasswordViewButtons(): JSX.Element { const showResetElements = this.state.errorCount >= MAX_LOGIN_TRIES; return (
{showResetElements && ( <> )}
); } private renderClearDataViewButtons(): JSX.Element { return (
{ this.setState({ clearDataView: false }); }} />
); } } export const SessionPasswordPrompt = withTheme(SessionPasswordPromptInner);