import { observer } from 'mobx-react-lite'; import { toDirective } from '@/components/utils'; import { AppState } from '@/ui_models/app_state'; import { WebApplication } from '@/ui_models/application'; import { useEffect, useRef, useState } from 'preact/hooks'; import { User } from '@standardnotes/snjs/dist/@types/services/api/responses'; import { isDesktopApplication } from '@/utils'; import { storage, StorageKey } from '@Services/localStorage'; import { disableErrorReporting, enableErrorReporting, errorReportingId } from '@Services/errorReporting'; import { ConfirmSignoutDirective } from '@/components/ConfirmSignoutModal'; // eslint-disable-next-line @typescript-eslint/no-empty-interface // interface Props {} // TODO: Vardan: implement props and remove `eslint-disable` type Props = { appState: AppState; application: WebApplication; }; // const HistoryMenu = observer((props: Props) => { // const AccountMenu = observer((props) => { const AccountMenu = observer(({ appState, application }: Props) => { const passcodeInput = useRef(); // const { user, formData } = application; // const [user, setUser] = useState(null); // TODO: Vardan: set correct type and initial value const [user, setUser] = useState(undefined); // TODO: Vardan: set correct type and initial value // TODO: Vardan `showLogin` and `showRegister` were in `formData` in Angular code, check whether I need to write similarly const [showLogin, setShowLogin] = useState(false); const [showRegister, setShowRegister] = useState(false); const [showAdvanced, setShowAdvanced] = useState(false); const [isAuthenticating, setIsAuthenticating] = useState(false); const [password, setPassword] = useState(undefined); const [passwordConfirmation, setPasswordConfirmation] = useState(undefined); const [status, setStatus] = useState(''); const [syncError, setSyncError] = useState(''); const [server, setServer] = useState(''); const [notesAndTagsCount, setNotesAndTagsCount] = useState(0); const [isEncryptionEnabled, setIsEncryptionEnabled] = useState(false); const [encryptionStatusString, setEncryptionStatusString] = useState(''); const [hasProtections, setHasProtections] = useState(false); const [protectionsDisabledUntil, setProtectionsDisabledUntil] = useState(null); const [hasPasscode, setHasPasscode] = useState(false); const [canAddPasscode, setCanAddPasscode] = useState(false); const [showPasscodeForm, setShowPasscodeForm] = useState(false); const [keyStorageInfo, setKeyStorageInfo] = useState(null); const [passcodeAutoLockOptions, setPasscodeAutoLockOptions] = useState<{value: number; label: string}[]>([]); const [selectedAutoLockInterval, setSelectedAutoLockInterval] = useState(null); const [isLoading, setIsLoading] = useState(false); const [isErrorReportingEnabled, setIsErrorReportingEnabled] = useState(false); const [appVersion, setAppVersion] = useState(''); // TODO: Vardan: figure out how to get `appVersion` similar to original code const [showBetaWarning, setShowBetaWarning] = useState(false); // TODO: Vardan: in original code initial value of `backupEncrypted` is `hasUser || hasPasscode` - // once I have those values here, set them as initial value const [isBackupEncrypted, setIsBackupEncrypted] = useState(false); const [isSyncInProgress, setIsSyncInProgress] = useState(false); const errorReportingIdValue = errorReportingId(); /* const displayRegistrationForm = () => { console.log('display registration form!'); }; */ const handleFormSubmit = () => { // TODO: Vardan: there is `novalidate` in Angular code, need to understand how to apply it here console.log('form submit'); }; const handleHostInputChange = () => { console.log('handle host input change'); }; const handleKeyPressKeyDown = (event: KeyboardEvent) => { if (event.key === 'Enter') { handleFormSubmit(); } }; const handleChangeStrictSignIn = () => { console.log('handleChangeStrictSignIn'); }; const handlePasswordChange = () => { console.log('handlePasswordChange'); }; const handlePasswordConfirmationChange = () => { console.log('handlePasswordConfirmationChange'); }; const handleChangeEphemeral = () => { console.log('change ephemeral'); // TODO: Vardan: perhaps need to set some "global" value here }; const handleMergeLocalData = () => { console.log('handleMergeLocalData'); }; const openPasswordWizard = () => { console.log('openPasswordWizard'); }; const openSessionsModal = () => { console.log('openSessionsModal'); }; const getEncryptionStatusForNotes = () => { console.log('implement `getEncryptionStatusForNotes`'); return ''; }; const enableProtections = () => { console.log('enableProtections'); }; const handleAddPassCode = () => { console.log('handleAddPassCode'); }; const submitPasscodeForm = () => { console.log('submitPasscodeForm'); }; const handlePasscodeChange = () => { console.log('handlePasscodeChange'); }; const handleConfirmPasscodeChange = () => { console.log('handleConfirmPasscodeChange'); }; const selectAutoLockInterval = (interval: number) => { console.log('selectAutoLockInterval', interval); }; const disableBetaWarning = () => { console.log('disableBetaWarning'); }; const hidePasswordForm = () => { setShowLogin(false); setShowRegister(false); setPassword(undefined); setPasswordConfirmation(undefined); }; const signOut = () => { console.log('signOut'); }; // TODO: Vardan: the name `changePasscodePressed` comes from original code; it is very similar to my `handlePasscodeChange`. // Check if `handlePasscodeChange` is not required, remove it and rename `changePasscodePressed` to `handlePasscodeChange` const changePasscodePressed = () => { console.log('changePasscodePressed'); }; // TODO: Vardan: the name `removePasscodePressed` comes from original code; // Check if I rename`changePasscodePressed` to `handlePasscodeChange`, also rename `removePasscodePressed` to `handleRemovePasscode` const removePasscodePressed = () => { console.log('removePasscodePressed'); }; const downloadDataArchive = () => { console.log('downloadDataArchive'); }; const importFileSelected = () => { console.log('importFileSelected'); }; const toggleErrorReportingEnabled = () => { if (isErrorReportingEnabled) { disableErrorReporting(); } else { enableErrorReporting(); } if (!isSyncInProgress) { window.location.reload(); } }; const openErrorReportingDialog = () => { console.log('openErrorReportingDialog'); }; const handleClose = () => { console.log('close this'); }; useEffect(() => { // TODO: Vardan: get the real count setNotesAndTagsCount(1); }, []); useEffect(() => { setIsErrorReportingEnabled( storage.get(StorageKey.DisableErrorReporting) === false); }, []); /* useEffect(() => { setAppVersion(`v${((window as any).electronAppVersion || appVersion)}`); }, [appVersion]); */ /* const { searchOptions } = appState; const { includeProtectedContents, includeArchived, includeTrashed, } = searchOptions; */ return (
Account
Close
{!user && !showLogin && !showRegister && (
Sign in or register to enable sync and end-to-end encryption.
Standard Notes is free on every platform, and comes
standard with sync and encryption.
)} {(showLogin || showRegister) && (
{showLogin ? 'Sign In' : 'Register'}
{/* TODO: Vardan: there are `should-focus` and `sn-autofocus`, implement them */} {showRegister && } {showAdvanced && (
Advanced Options
{showLogin && ( )}
)} {!isAuthenticating && (
)} {showRegister && (
No Password Reset.
Because your notes are encrypted using your password,
Standard Notes does not have a password reset option.
You cannot forget your password.
)} {status && (
{status}
)} {!isAuthenticating && (
{notesAndTagsCount > 0 && ( )}
)}
)} {!showLogin && !showRegister && (
{user && ( <>
{syncError && ( <>
Sync Unreachable
Hmm...we can't seem to sync your account.
The reason: {syncError}
Need help?
{user.email}
{server}
Encryption
{isEncryptionEnabled && (
{getEncryptionStatusForNotes()}
)}

{encryptionStatusString}

{hasProtections && (
Protections
{protectionsDisabledUntil && (
Protections are disabled until {protectionsDisabledUntil}
)} {!protectionsDisabledUntil && (
Protections are enabled
)}

Actions like viewing protected notes, exporting decrypted backups,
or revoking an active session, require additional authentication
like entering your account password or application passcode.

{protectionsDisabledUntil && (
)}
)}
Passcode Lock
{!hasPasscode && (
{canAddPasscode && ( <> {showPasscodeForm && (
)}

Add a passcode to lock the application and
encrypt on-device key storage.

{keyStorageInfo && (

{keyStorageInfo}

)} )} {!canAddPasscode && (

Adding a passcode is not supported in temporary sessions. Please sign
out, then sign back in with the "Stay signed in" option checked.

)}
)} {showPasscodeForm && (
{/* TODO: Vardan: there are `should-focus` and `sn-autofocus`, implement them */} )} {hasPasscode && !showPasscodeForm && ( <>
Passcode lock is enabled
Options
Autolock
{passcodeAutoLockOptions.map(option => { return ( selectAutoLockInterval(option.value)}> {option.label} ); })}
The autolock timer begins when the window or tab loses focus.
)}
{!isLoading && (
Data Backups
Download a backup of all your data.
{isEncryptionEnabled && (
)}
{isDesktopApplication && (

Backups are automatically created on desktop and can be managed
via the "Backups" top-level menu.

)}
{isLoading && (
)}
)}
Error Reporting
Automatic error reporting is {isErrorReportingEnabled ? 'enabled' : 'disabled'}

Help us improve Standard Notes by automatically submitting
anonymized error reports.

{errorReportingIdValue && ( <>

Your random identifier is
strong {errorReportingIdValue}

Disabling error reporting will remove that identifier from your
local storage, and a new identifier will be created should you
decide to enable error reporting again in the future.

)}
)}
)}
{ // TODO: Vardan: check whether this works () => ConfirmSignoutDirective }
{appVersion} {showBetaWarning && ( Hide beta warning )}
{(showLogin || showRegister) && ( Cancel )} {!showLogin && !showRegister && ( {user ? "Sign out" : "Clear session data"} )}
); }); export const AccountMenu2 = toDirective( AccountMenu );