import { WebApplication } from '@/ui_models/application'; import { AppState } from '@/ui_models/app_state'; import { isDev } from '@/utils'; import { observer } from 'mobx-react-lite'; import { FunctionComponent } from 'preact'; import { useCallback, useEffect, useRef, useState } from 'preact/hooks'; import { AccountMenuPane } from '.'; import { Button } from '../Button'; import { Checkbox } from '../Checkbox'; import { DecoratedInput } from '../DecoratedInput'; import { DecoratedPasswordInput } from '../DecoratedPasswordInput'; import { Icon } from '../Icon'; import { IconButton } from '../IconButton'; import { AdvancedOptions } from './AdvancedOptions'; type Props = { appState: AppState; application: WebApplication; setMenuPane: (pane: AccountMenuPane) => void; }; export const SignInPane: FunctionComponent = observer( ({ application, appState, setMenuPane }) => { const { notesAndTagsCount } = appState.accountMenu; const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [error, setError] = useState(''); const [isEphemeral, setIsEphemeral] = useState(false); const [isStrictSignin, setIsStrictSignin] = useState(false); const [isSigningIn, setIsSigningIn] = useState(false); const [shouldMergeLocal, setShouldMergeLocal] = useState(true); const [isVault, setIsVault] = useState(false); const emailInputRef = useRef(null); const passwordInputRef = useRef(null); useEffect(() => { if (emailInputRef?.current) { emailInputRef.current?.focus(); } if (isDev && window.devAccountEmail) { setEmail(window.devAccountEmail); setPassword(window.devAccountPassword as string); } }, []); const resetInvalid = () => { if (error.length) { setError(''); } }; const handleEmailChange = (text: string) => { setEmail(text); }; const handlePasswordChange = (text: string) => { if (error.length) { setError(''); } setPassword(text); }; const handleEphemeralChange = () => { setIsEphemeral(!isEphemeral); }; const handleStrictSigninChange = () => { setIsStrictSignin(!isStrictSignin); }; const handleShouldMergeChange = () => { setShouldMergeLocal(!shouldMergeLocal); }; const signIn = () => { setIsSigningIn(true); emailInputRef?.current?.blur(); passwordInputRef?.current?.blur(); application .signIn(email, password, isStrictSignin, isEphemeral, shouldMergeLocal) .then((res) => { if (res.error) { throw new Error(res.error.message); } appState.accountMenu.closeAccountMenu(); }) .catch((err) => { console.error(err); setError(err.message ?? err.toString()); setPassword(''); passwordInputRef?.current?.blur(); }) .finally(() => { setIsSigningIn(false); }); }; const handleKeyDown = (e: KeyboardEvent) => { if (e.key === 'Enter') { handleSignInFormSubmit(e); } }; const onVaultChange = useCallback( (newIsVault: boolean, vaultedEmail?: string) => { setIsVault(newIsVault); if (newIsVault && vaultedEmail) { setEmail(vaultedEmail); } }, [setEmail] ); const handleSignInFormSubmit = (e: Event) => { e.preventDefault(); if (!email || email.length === 0) { emailInputRef?.current?.focus(); return; } if (!password || password.length === 0) { passwordInputRef?.current?.focus(); return; } signIn(); }; return ( <>
setMenuPane(AccountMenuPane.GeneralMenu)} focusable={true} disabled={isSigningIn} />
Sign in
]} type="email" placeholder="Email" value={email} onChange={handleEmailChange} onFocus={resetInvalid} onKeyDown={handleKeyDown} disabled={isSigningIn || isVault} ref={emailInputRef} /> ]} onChange={handlePasswordChange} onFocus={resetInvalid} onKeyDown={handleKeyDown} placeholder="Password" ref={passwordInputRef} value={password} /> {error ?
{error}
: null}
); } );