chore: move all components into Components dir with pascal case (#934)

This commit is contained in:
Mo
2022-03-17 11:38:45 -05:00
committed by GitHub
parent 42b84ef9b1
commit c29e45795d
89 changed files with 370 additions and 259 deletions

View File

@@ -2,14 +2,14 @@ import { WebApplication } from '@/ui_models/application';
import { AppState } from '@/ui_models/app_state';
import { observer } from 'mobx-react-lite';
import { Icon } from '../Icon';
import { formatLastSyncDate } from '@/preferences/panes/account/Sync';
import { formatLastSyncDate } from '@/components/Preferences/panes/account/Sync';
import { SyncQueueStrategy } from '@standardnotes/snjs';
import { STRING_GENERIC_SYNC_ERROR } from '@/strings';
import { useState } from 'preact/hooks';
import { AccountMenuPane } from '.';
import { FunctionComponent } from 'preact';
import { Menu } from '../menu/Menu';
import { MenuItem, MenuItemSeparator, MenuItemType } from '../menu/MenuItem';
import { Menu } from '../Menu/Menu';
import { MenuItem, MenuItemSeparator, MenuItemType } from '../Menu/MenuItem';
type Props = {
appState: AppState;

View File

@@ -16,10 +16,10 @@ import { NotesView } from '@/components/NotesView';
import { NoteGroupView } from '@/components/NoteGroupView';
import { Footer } from '@/components/Footer';
import { SessionsModal } from '@/components/SessionsModal';
import { PreferencesViewWrapper } from '@/preferences/PreferencesViewWrapper';
import { PreferencesViewWrapper } from '@/components/Preferences/PreferencesViewWrapper';
import { ChallengeModal } from '@/components/ChallengeModal';
import { NotesContextMenu } from '@/components/NotesContextMenu';
import { PurchaseFlowWrapper } from '@/purchaseFlow/PurchaseFlowWrapper';
import { PurchaseFlowWrapper } from '@/components/PurchaseFlow/PurchaseFlowWrapper';
import { render } from 'preact';
import { PermissionsModal } from './PermissionsModal';
import { RevisionHistoryModalWrapper } from './RevisionHistoryModal/RevisionHistoryModalWrapper';

View File

@@ -4,8 +4,8 @@ import { observer } from 'mobx-react-lite';
import { FunctionComponent } from 'preact';
import { useRef, useState } from 'preact/hooks';
import { Icon } from './Icon';
import { Menu } from './menu/Menu';
import { MenuItem, MenuItemSeparator, MenuItemType } from './menu/MenuItem';
import { Menu } from './Menu/Menu';
import { MenuItem, MenuItemSeparator, MenuItemType } from './Menu/MenuItem';
type Props = {
application: WebApplication;

View File

@@ -1,6 +1,6 @@
import { Icon } from '@/components/Icon';
import { Menu } from '@/components/menu/Menu';
import { MenuItem, MenuItemType } from '@/components/menu/MenuItem';
import { Menu } from '@/components/Menu/Menu';
import { MenuItem, MenuItemType } from '@/components/Menu/MenuItem';
import {
reloadFont,
transactionForAssociateComponentWithCurrentNote,

View File

@@ -1,5 +1,5 @@
import { action, makeAutoObservable, observable } from 'mobx';
import { ExtensionsLatestVersions } from '@/preferences/panes/extensions-segments';
import { ExtensionsLatestVersions } from '@/components/Preferences/panes/extensions-segments';
import {
ComponentArea,
ContentType,

View File

@@ -17,7 +17,7 @@ import { MfaProps } from './panes/two-factor-auth/MfaProps';
import { AppState } from '@/ui_models/app_state';
import { useEffect, useMemo } from 'preact/hooks';
import { ExtensionPane } from './panes/ExtensionPane';
import { Backups } from '@/preferences/panes/Backups';
import { Backups } from '@/components/Preferences/panes/Backups';
import { Appearance } from './panes/Appearance';
interface PreferencesProps extends MfaProps {

View File

@@ -1,5 +1,5 @@
import { FunctionComponent } from 'preact';
import { HorizontalSeparator } from '@/components/shared/HorizontalSeparator';
import { HorizontalSeparator } from '@/components/Shared/HorizontalSeparator';
const HorizontalLine: FunctionComponent<{ index: number; length: number }> = ({
index,

View File

@@ -5,8 +5,7 @@ export const PreferencesPane: FunctionComponent = ({ children }) => (
<div className="flex-grow flex flex-col py-6 items-center">
<div className="w-125 max-w-125 flex flex-col">
{children != undefined && Array.isArray(children)
? children
.filter((child) => child != undefined)
? children.filter((child) => child != undefined)
: children}
</div>
</div>

View File

@@ -0,0 +1,9 @@
import { FunctionComponent } from 'preact';
type Props = {
classes?: string;
};
export const PreferencesSegment: FunctionComponent<Props> = ({
children,
classes = '',
}) => <div className={`flex flex-col ${classes}`}>{children}</div>;

View File

@@ -4,8 +4,8 @@ import {
Credentials,
SignOutWrapper,
Authentication,
} from '@/preferences/panes/account';
import { PreferencesPane } from '@/preferences/components';
} from '@/components/Preferences/panes/account';
import { PreferencesPane } from '@/components/Preferences/components';
import { observer } from 'mobx-react-lite';
import { WebApplication } from '@/ui_models/application';
import { AppState } from '@/ui_models/app_state';

View File

@@ -1,7 +1,7 @@
import { Dropdown, DropdownItem } from '@/components/Dropdown';
import { usePremiumModal } from '@/components/Premium';
import { sortThemes } from '@/components/QuickSettingsMenu/QuickSettingsMenu';
import { HorizontalSeparator } from '@/components/shared/HorizontalSeparator';
import { HorizontalSeparator } from '@/components/Shared/HorizontalSeparator';
import { Switch } from '@/components/Switch';
import { WebApplication } from '@/ui_models/application';
import { GetFeatures } from '@standardnotes/features';

View File

@@ -1,4 +1,7 @@
import { PreferencesGroup, PreferencesSegment } from '@/preferences/components';
import {
PreferencesGroup,
PreferencesSegment,
} from '@/components/Preferences/components';
import { WebApplication } from '@/ui_models/application';
import { ComponentViewer, SNComponent } from '@standardnotes/snjs';
import { FeatureIdentifier } from '@standardnotes/features';
@@ -7,7 +10,7 @@ import { FunctionComponent } from 'preact';
import { ExtensionItem } from './extensions-segments';
import { ComponentView } from '@/components/ComponentView';
import { AppState } from '@/ui_models/app_state';
import { PreferencesMenu } from '@/preferences/PreferencesMenu';
import { PreferencesMenu } from '@/components/Preferences/PreferencesMenu';
import { useEffect, useState } from 'preact/hooks';
interface IProps {

View File

@@ -3,8 +3,8 @@ import { AppState } from '@/ui_models/app_state';
import { FunctionComponent } from 'preact';
import { PreferencesPane } from '../components';
import { Tools, Defaults, LabsPane } from './general-segments';
import { ExtensionsLatestVersions } from '@/preferences/panes/extensions-segments';
import { Advanced } from '@/preferences/panes/account';
import { ExtensionsLatestVersions } from '@/components/Preferences/panes/extensions-segments';
import { Advanced } from '@/components/Preferences/panes/account';
import { observer } from 'mobx-react-lite';
interface GeneralProps {

View File

@@ -104,7 +104,11 @@ export const HelpAndFeedback: FunctionComponent = () => (
<Text>
Send an email to help@standardnotes.com and well sort it out.
</Text>
<LinkButton className="mt-3" link="mailto: help@standardnotes.com" label="Email us" />
<LinkButton
className="mt-3"
link="mailto: help@standardnotes.com"
label="Email us"
/>
</PreferencesSegment>
</PreferencesGroup>
</PreferencesPane>

View File

@@ -0,0 +1,44 @@
import { FunctionalComponent } from 'preact';
import {
PreferencesGroup,
PreferencesSegment,
} from '@/components/Preferences/components';
import { OfflineSubscription } from '@/components/Preferences/panes/account/offlineSubscription';
import { WebApplication } from '@/ui_models/application';
import { observer } from 'mobx-react-lite';
import { AppState } from '@/ui_models/app_state';
import { Extensions } from '@/components/Preferences/panes/Extensions';
import { ExtensionsLatestVersions } from '@/components/Preferences/panes/extensions-segments';
import { AccordionItem } from '@/components/Shared/AccordionItem';
interface IProps {
application: WebApplication;
appState: AppState;
extensionsLatestVersions: ExtensionsLatestVersions;
}
export const Advanced: FunctionalComponent<IProps> = observer(
({ application, appState, extensionsLatestVersions }) => {
return (
<PreferencesGroup>
<PreferencesSegment>
<AccordionItem title={'Advanced Settings'}>
<div className="flex flex-row items-center">
<div className="flex-grow flex flex-col">
<OfflineSubscription
application={application}
appState={appState}
/>
<Extensions
className={'mt-3'}
application={application}
extensionsLatestVersions={extensionsLatestVersions}
/>
</div>
</div>
</AccordionItem>
</PreferencesSegment>
</PreferencesGroup>
);
}
);

View File

@@ -5,7 +5,7 @@ import {
PreferencesSegment,
Text,
Title,
} from '@/preferences/components';
} from '@/components/Preferences/components';
import { WebApplication } from '@/ui_models/application';
import { AppState } from '@/ui_models/app_state';
import { observer } from 'mobx-react-lite';

View File

@@ -4,14 +4,14 @@ import {
Subtitle,
Text,
Title,
} from '@/preferences/components';
} from '@/components/Preferences/components';
import { Button } from '@/components/Button';
import { WebApplication } from '@/ui_models/application';
import { observer } from '@node_modules/mobx-react-lite';
import { HorizontalSeparator } from '@/components/shared/HorizontalSeparator';
import { HorizontalSeparator } from '@/components/Shared/HorizontalSeparator';
import { dateToLocalizedString } from '@standardnotes/snjs';
import { useCallback, useState } from 'preact/hooks';
import { ChangeEmail } from '@/preferences/panes/account/changeEmail';
import { ChangeEmail } from '@/components/Preferences/panes/account/changeEmail';
import { FunctionComponent, render } from 'preact';
import { AppState } from '@/ui_models/app_state';
import { PasswordWizard } from '@/components/PasswordWizard';

View File

@@ -6,7 +6,7 @@ import {
Subtitle,
Text,
Title,
} from '@/preferences/components';
} from '@/components/Preferences/components';
import { WebApplication } from '@/ui_models/application';
import { AppState } from '@/ui_models/app_state';
import { observer } from 'mobx-react-lite';

View File

@@ -3,7 +3,7 @@ import {
PreferencesSegment,
Text,
Title,
} from '@/preferences/components';
} from '@/components/Preferences/components';
import { Button } from '@/components/Button';
import { SyncQueueStrategy, dateToLocalizedString } from '@standardnotes/snjs';
import { STRING_GENERIC_SYNC_ERROR } from '@/strings';

View File

@@ -3,9 +3,12 @@ import { FunctionalComponent } from 'preact';
export const ChangeEmailSuccess: FunctionalComponent = () => {
return (
<div>
<div className={'sk-label sk-bold info mt-2'}>Your email has been successfully changed.</div>
<div className={'sk-label sk-bold info mt-2'}>
Your email has been successfully changed.
</div>
<p className={'sk-p'}>
Please ensure you are running the latest version of Standard Notes on all platforms to ensure maximum compatibility.
Please ensure you are running the latest version of Standard Notes on
all platforms to ensure maximum compatibility.
</p>
</div>
);

View File

@@ -4,7 +4,7 @@ import {
ModalDialogButtons,
ModalDialogDescription,
ModalDialogLabel,
} from '@/components/shared/ModalDialog';
} from '@/components/Shared/ModalDialog';
import { Button } from '@/components/Button';
import { FunctionalComponent } from 'preact';
import { WebApplication } from '@/ui_models/application';

View File

@@ -1,5 +1,5 @@
import { FunctionalComponent } from 'preact';
import { Subtitle } from '@/preferences/components';
import { Subtitle } from '@/components/Preferences/components';
import { DecoratedInput } from '@/components/DecoratedInput';
import { Button } from '@/components/Button';
import { JSXInternal } from '@node_modules/preact/src/jsx';
@@ -10,7 +10,7 @@ import { AppState } from '@/ui_models/app_state';
import { observer } from 'mobx-react-lite';
import { STRING_REMOVE_OFFLINE_KEY_CONFIRMATION } from '@/strings';
import { ButtonType, ClientDisplayableError } from '@standardnotes/snjs';
import { HorizontalSeparator } from '@/components/shared/HorizontalSeparator';
import { HorizontalSeparator } from '@/components/Shared/HorizontalSeparator';
interface IProps {
application: WebApplication;

View File

@@ -1,9 +1,9 @@
import { FunctionalComponent } from 'preact';
import { LinkButton, Text } from '@/preferences/components';
import { LinkButton, Text } from '@/components/Preferences/components';
import { Button } from '@/components/Button';
import { WebApplication } from '@/ui_models/application';
import { useState } from 'preact/hooks';
import { loadPurchaseFlowUrl } from '@/purchaseFlow/PurchaseFlowWrapper';
import { loadPurchaseFlowUrl } from '@/components/PurchaseFlow/PurchaseFlowWrapper';
export const NoSubscription: FunctionalComponent<{
application: WebApplication;

View File

@@ -2,7 +2,7 @@ import {
PreferencesGroup,
PreferencesSegment,
Title,
} from '@/preferences/components';
} from '@/components/Preferences/components';
import { WebApplication } from '@/ui_models/application';
import { SubscriptionInformation } from './SubscriptionInformation';
import { NoSubscription } from './NoSubscription';

View File

@@ -1,6 +1,6 @@
import { observer } from 'mobx-react-lite';
import { SubscriptionState } from '../../../../ui_models/app_state/subscription_state';
import { Text } from '@/preferences/components';
import { SubscriptionState } from '../../../../../ui_models/app_state/subscription_state';
import { Text } from '@/components/Preferences/components';
import { Button } from '@/components/Button';
import { WebApplication } from '@/ui_models/application';
import { openSubscriptionDashboard } from '@/hooks/manageSubscription';

View File

@@ -16,7 +16,7 @@ import {
import { EmailBackupFrequency, SettingName } from '@standardnotes/settings';
import { Dropdown, DropdownItem } from '@/components/Dropdown';
import { Switch } from '@/components/Switch';
import { HorizontalSeparator } from '@/components/shared/HorizontalSeparator';
import { HorizontalSeparator } from '@/components/Shared/HorizontalSeparator';
import { FeatureIdentifier } from '@standardnotes/features';
import { FeatureStatus } from '@standardnotes/snjs';

View File

@@ -10,7 +10,7 @@ import {
import { WebApplication } from '@/ui_models/application';
import { Button } from '@/components/Button';
import { isDev, openInNewTab } from '@/utils';
import { Subtitle } from '@/preferences/components';
import { Subtitle } from '@/components/Preferences/components';
import { KeyboardKey } from '@Services/ioService';
import { FunctionComponent } from 'preact';

View File

@@ -8,8 +8,8 @@ import {
Subtitle,
Text,
Title,
} from '@/preferences/components';
import { HorizontalSeparator } from '@/components/shared/HorizontalSeparator';
} from '@/components/Preferences/components';
import { HorizontalSeparator } from '@/components/Shared/HorizontalSeparator';
import { FeatureIdentifier } from '@standardnotes/features';
import { FeatureStatus } from '@standardnotes/snjs';
import { FunctionComponent } from 'preact';

View File

@@ -1,42 +1,36 @@
import { displayStringForContentType, SNComponent } from '@standardnotes/snjs';
import { Button } from '@/components/Button';
import { FunctionComponent } from 'preact';
import {
Title,
Text,
Subtitle,
PreferencesSegment,
} from '../../components';
import { Title, Text, Subtitle, PreferencesSegment } from '../../components';
export const ConfirmCustomExtension: FunctionComponent<{
component: SNComponent,
callback: (confirmed: boolean) => void
component: SNComponent;
callback: (confirmed: boolean) => void;
}> = ({ component, callback }) => {
const fields = [
{
label: 'Name',
value: component.package_info.name
value: component.package_info.name,
},
{
label: 'Description',
value: component.package_info.description
value: component.package_info.description,
},
{
label: 'Version',
value: component.package_info.version
value: component.package_info.version,
},
{
label: 'Hosted URL',
value: component.thirdPartyPackageInfo.url
value: component.thirdPartyPackageInfo.url,
},
{
label: 'Download URL',
value: component.package_info.download_url
value: component.package_info.download_url,
},
{
label: 'Extension Type',
value: displayStringForContentType(component.content_type)
value: displayStringForContentType(component.content_type),
},
];
@@ -45,7 +39,9 @@ export const ConfirmCustomExtension: FunctionComponent<{
<Title>Confirm Extension</Title>
{fields.map((field) => {
if (!field.value) { return undefined; }
if (!field.value) {
return undefined;
}
return (
<>
<Subtitle>{field.label}</Subtitle>
@@ -74,7 +70,6 @@ export const ConfirmCustomExtension: FunctionComponent<{
onClick={() => callback(true)}
/>
</div>
</PreferencesSegment>
);
};

View File

@@ -4,7 +4,7 @@ import {
PreferencesSegment,
SubtitleLight,
Title,
} from '@/preferences/components';
} from '@/components/Preferences/components';
import { Switch } from '@/components/Switch';
import { WebApplication } from '@/ui_models/application';
import { useState } from 'preact/hooks';

View File

@@ -1,11 +1,13 @@
import { FunctionComponent } from "preact";
import { useState, useRef, useEffect } from "preact/hooks";
import { FunctionComponent } from 'preact';
import { useState, useRef, useEffect } from 'preact/hooks';
export const RenameExtension: FunctionComponent<{
extensionName: string, changeName: (newName: string) => void
extensionName: string;
changeName: (newName: string) => void;
}> = ({ extensionName, changeName }) => {
const [isRenaming, setIsRenaming] = useState(false);
const [newExtensionName, setNewExtensionName] = useState<string>(extensionName);
const [newExtensionName, setNewExtensionName] =
useState<string>(extensionName);
const inputRef = useRef<HTMLInputElement>(null);
@@ -38,21 +40,30 @@ export const RenameExtension: FunctionComponent<{
<input
ref={inputRef}
disabled={!isRenaming}
autocomplete='off'
autocomplete="off"
className="flex-grow text-base font-bold no-border bg-default px-0 color-text"
type="text"
value={newExtensionName}
onChange={({ target: input }) => setNewExtensionName((input as HTMLInputElement)?.value)}
onChange={({ target: input }) =>
setNewExtensionName((input as HTMLInputElement)?.value)
}
/>
<div className="min-w-3" />
{isRenaming ?
{isRenaming ? (
<>
<a className="pt-1 cursor-pointer" onClick={confirmRename}>Confirm</a>
<a className="pt-1 cursor-pointer" onClick={confirmRename}>
Confirm
</a>
<div className="min-w-3" />
<a className="pt-1 cursor-pointer" onClick={cancelRename}>Cancel</a>
</> :
<a className="pt-1 cursor-pointer" onClick={startRenaming}>Rename</a>
}
<a className="pt-1 cursor-pointer" onClick={cancelRename}>
Cancel
</a>
</>
) : (
<a className="pt-1 cursor-pointer" onClick={startRenaming}>
Rename
</a>
)}
</div>
);
};

View File

@@ -6,7 +6,7 @@ import {
Subtitle,
Text,
Title,
} from '@/preferences/components';
} from '@/components/Preferences/components';
import { WebApplication } from '@/ui_models/application';
import {
ComponentArea,
@@ -15,7 +15,7 @@ import {
} from '@standardnotes/snjs';
import { FunctionComponent } from 'preact';
import { useEffect, useState } from 'preact/hooks';
import { HorizontalSeparator } from '@/components/shared/HorizontalSeparator';
import { HorizontalSeparator } from '@/components/Shared/HorizontalSeparator';
import { Switch } from '@/components/Switch';
type Props = {

View File

@@ -6,13 +6,13 @@ import {
Subtitle,
Text,
Title,
} from '@/preferences/components';
} from '@/components/Preferences/components';
import { WebApplication } from '@/ui_models/application';
import { FeatureIdentifier, FeatureStatus } from '@standardnotes/snjs';
import { FunctionComponent } from 'preact';
import { useCallback, useEffect, useState } from 'preact/hooks';
import { usePremiumModal } from '@/components/Premium';
import { HorizontalSeparator } from '@/components/shared/HorizontalSeparator';
import { HorizontalSeparator } from '@/components/Shared/HorizontalSeparator';
type ExperimentalFeatureItem = {
identifier: FeatureIdentifier;

View File

@@ -1,4 +1,4 @@
import { HorizontalSeparator } from '@/components/shared/HorizontalSeparator';
import { HorizontalSeparator } from '@/components/Shared/HorizontalSeparator';
import { Switch } from '@/components/Switch';
import {
PreferencesGroup,
@@ -6,7 +6,7 @@ import {
Subtitle,
Text,
Title,
} from '@/preferences/components';
} from '@/components/Preferences/components';
import { WebApplication } from '@/ui_models/application';
import { PrefKey } from '@standardnotes/snjs';
import { observer } from 'mobx-react-lite';

View File

@@ -1,5 +1,5 @@
import { HorizontalSeparator } from '@/components/shared/HorizontalSeparator';
import { LinkButton, Subtitle } from '@/preferences/components';
import { HorizontalSeparator } from '@/components/Shared/HorizontalSeparator';
import { LinkButton, Subtitle } from '@/components/Preferences/components';
import { WebApplication } from '@/ui_models/application';
import { ListedAccount, ListedAccountInfo } from '@standardnotes/snjs';
import { FunctionalComponent } from 'preact';

View File

@@ -0,0 +1,97 @@
import { DecoratedInput } from '@/components/DecoratedInput';
import { Icon } from '@/components/Icon';
import {
STRING_E2E_ENABLED,
STRING_ENC_NOT_ENABLED,
STRING_LOCAL_ENC_ENABLED,
} from '@/strings';
import { AppState } from '@/ui_models/app_state';
import { observer } from 'mobx-react-lite';
import { FunctionComponent } from 'preact';
import {
PreferencesGroup,
PreferencesSegment,
Text,
Title,
} from '../../components';
const formatCount = (count: number, itemType: string) =>
`${count} / ${count} ${itemType}`;
const EncryptionEnabled: FunctionComponent<{ appState: AppState }> = observer(
({ appState }) => {
const count = appState.accountMenu.structuredNotesAndTagsCount;
const notes = formatCount(count.notes, 'notes');
const tags = formatCount(count.tags, 'tags');
const archived = formatCount(count.archived, 'archived notes');
const deleted = formatCount(count.deleted, 'trashed notes');
const checkIcon = (
<Icon className="success min-w-4 min-h-4" type="check-bold" />
);
const noteIcon = <Icon type="rich-text" className="min-w-5 min-h-5" />;
const tagIcon = <Icon type="hashtag" className="min-w-5 min-h-5" />;
const archiveIcon = <Icon type="archive" className="min-w-5 min-h-5" />;
const trashIcon = <Icon type="trash" className="min-w-5 min-h-5" />;
return (
<>
<div className="flex flex-row pb-1 pt-1.5">
<DecoratedInput
disabled={true}
text={notes}
right={[checkIcon]}
left={[noteIcon]}
/>
<div className="min-w-3" />
<DecoratedInput
disabled={true}
text={tags}
right={[checkIcon]}
left={[tagIcon]}
/>
</div>
<div className="flex flex-row">
<DecoratedInput
disabled={true}
text={archived}
right={[checkIcon]}
left={[archiveIcon]}
/>
<div className="min-w-3" />
<DecoratedInput
disabled={true}
text={deleted}
right={[checkIcon]}
left={[trashIcon]}
/>
</div>
</>
);
}
);
export const Encryption: FunctionComponent<{ appState: AppState }> = observer(
({ appState }) => {
const app = appState.application;
const hasUser = app.hasAccount();
const hasPasscode = app.hasPasscode();
const isEncryptionEnabled = app.isEncryptionAvailable();
const encryptionStatusString = hasUser
? STRING_E2E_ENABLED
: hasPasscode
? STRING_LOCAL_ENC_ENABLED
: STRING_ENC_NOT_ENABLED;
return (
<PreferencesGroup>
<PreferencesSegment>
<Title>Encryption</Title>
<Text>{encryptionStatusString}</Text>
{isEncryptionEnabled && <EncryptionEnabled appState={appState} />}
</PreferencesSegment>
</PreferencesGroup>
);
}
);

View File

@@ -1,9 +1,12 @@
import {
STRING_CONFIRM_APP_QUIT_DURING_PASSCODE_CHANGE,
STRING_CONFIRM_APP_QUIT_DURING_PASSCODE_REMOVAL, STRING_E2E_ENABLED, STRING_ENC_NOT_ENABLED, STRING_LOCAL_ENC_ENABLED,
STRING_CONFIRM_APP_QUIT_DURING_PASSCODE_REMOVAL,
STRING_E2E_ENABLED,
STRING_ENC_NOT_ENABLED,
STRING_LOCAL_ENC_ENABLED,
STRING_NON_MATCHING_PASSCODES,
StringUtils,
Strings
Strings,
} from '@/strings';
import { WebApplication } from '@/ui_models/application';
import { preventRefreshing } from '@/utils';
@@ -15,7 +18,12 @@ import { useCallback, useEffect, useRef, useState } from 'preact/hooks';
import { ApplicationEvent } from '@standardnotes/snjs';
import { observer } from 'mobx-react-lite';
import { AppState } from '@/ui_models/app_state';
import { PreferencesSegment, Title, Text, PreferencesGroup } from '@/preferences/components';
import {
PreferencesSegment,
Title,
Text,
PreferencesGroup,
} from '@/components/Preferences/components';
import { Button } from '@/components/Button';
type Props = {
@@ -23,23 +31,31 @@ type Props = {
appState: AppState;
};
export const PasscodeLock = observer(({
application,
appState,
}: Props) => {
export const PasscodeLock = observer(({ application, appState }: Props) => {
const keyStorageInfo = StringUtils.keyStorageInfo(application);
const passcodeAutoLockOptions = application.getAutolockService().getAutoLockIntervalOptions();
const passcodeAutoLockOptions = application
.getAutolockService()
.getAutoLockIntervalOptions();
const { setIsEncryptionEnabled, setIsBackupEncrypted, setEncryptionStatusString } = appState.accountMenu;
const {
setIsEncryptionEnabled,
setIsBackupEncrypted,
setEncryptionStatusString,
} = appState.accountMenu;
const passcodeInputRef = useRef<HTMLInputElement>(null);
const [passcode, setPasscode] = useState<string | undefined>(undefined);
const [passcodeConfirmation, setPasscodeConfirmation] = useState<string | undefined>(undefined);
const [selectedAutoLockInterval, setSelectedAutoLockInterval] = useState<unknown>(null);
const [passcodeConfirmation, setPasscodeConfirmation] = useState<
string | undefined
>(undefined);
const [selectedAutoLockInterval, setSelectedAutoLockInterval] =
useState<unknown>(null);
const [isPasscodeFocused, setIsPasscodeFocused] = useState(false);
const [showPasscodeForm, setShowPasscodeForm] = useState(false);
const [canAddPasscode, setCanAddPasscode] = useState(!application.isEphemeralSession());
const [canAddPasscode, setCanAddPasscode] = useState(
!application.isEphemeralSession()
);
const [hasPasscode, setHasPasscode] = useState(application.hasPasscode());
const handleAddPassCode = () => {
@@ -52,7 +68,9 @@ export const PasscodeLock = observer(({
};
const reloadAutoLockInterval = useCallback(async () => {
const interval = await application.getAutolockService().getAutoLockInterval();
const interval = await application
.getAutolockService()
.getAutoLockInterval();
setSelectedAutoLockInterval(interval);
}, [application]);
@@ -67,13 +85,18 @@ export const PasscodeLock = observer(({
const encryptionStatusString = hasUser
? STRING_E2E_ENABLED
: hasPasscode
? STRING_LOCAL_ENC_ENABLED
: STRING_ENC_NOT_ENABLED;
? STRING_LOCAL_ENC_ENABLED
: STRING_ENC_NOT_ENABLED;
setEncryptionStatusString(encryptionStatusString);
setIsEncryptionEnabled(encryptionEnabled);
setIsBackupEncrypted(encryptionEnabled);
}, [application, setEncryptionStatusString, setIsBackupEncrypted, setIsEncryptionEnabled]);
}, [
application,
setEncryptionStatusString,
setIsBackupEncrypted,
setIsEncryptionEnabled,
]);
const selectAutoLockInterval = async (interval: number) => {
if (!(await application.authorizeAutolockIntervalChange())) {
@@ -88,9 +111,7 @@ export const PasscodeLock = observer(({
STRING_CONFIRM_APP_QUIT_DURING_PASSCODE_REMOVAL,
async () => {
if (await application.removePasscode()) {
await application
.getAutolockService()
.deleteAutolockPreference();
await application.getAutolockService().deleteAutolockPreference();
await reloadAutoLockInterval();
refreshEncryptionStatus();
}
@@ -103,12 +124,18 @@ export const PasscodeLock = observer(({
setPasscode(value);
};
const handleConfirmPasscodeChange = (event: TargetedEvent<HTMLInputElement>) => {
const handleConfirmPasscodeChange = (
event: TargetedEvent<HTMLInputElement>
) => {
const { value } = event.target as HTMLInputElement;
setPasscodeConfirmation(value);
};
const submitPasscodeForm = async (event: TargetedEvent<HTMLFormElement> | TargetedMouseEvent<HTMLButtonElement>) => {
const submitPasscodeForm = async (
event:
| TargetedEvent<HTMLFormElement>
| TargetedMouseEvent<HTMLButtonElement>
) => {
event.preventDefault();
if (!passcode || passcode.length === 0) {
@@ -119,7 +146,7 @@ export const PasscodeLock = observer(({
if (passcode !== passcodeConfirmation) {
await alertDialog({
text: STRING_NON_MATCHING_PASSCODES
text: STRING_NON_MATCHING_PASSCODES,
});
setIsPasscodeFocused(true);
return;
@@ -186,27 +213,28 @@ export const PasscodeLock = observer(({
{!hasPasscode && canAddPasscode && (
<>
<Text className="mb-3">
Add a passcode to lock the application and
encrypt on-device key storage.
Add a passcode to lock the application and encrypt on-device key
storage.
</Text>
{keyStorageInfo && (
<Text className="mb-3">{keyStorageInfo}</Text>
)}
{keyStorageInfo && <Text className="mb-3">{keyStorageInfo}</Text>}
{!showPasscodeForm && (
<Button label="Add Passcode" onClick={handleAddPassCode} type="primary" />
<Button
label="Add Passcode"
onClick={handleAddPassCode}
type="primary"
/>
)}
</>
)}
{!hasPasscode && !canAddPasscode && (
<Text>
Adding a passcode is not supported in temporary sessions. Please sign
out, then sign back in with the "Stay signed in" option checked.
Adding a passcode is not supported in temporary sessions. Please
sign out, then sign back in with the "Stay signed in" option
checked.
</Text>
)}
@@ -229,8 +257,17 @@ export const PasscodeLock = observer(({
placeholder="Confirm Passcode"
/>
<div className="min-h-2" />
<Button type="primary" onClick={submitPasscodeForm} label="Set Passcode" className="mr-3" />
<Button type="normal" onClick={() => setShowPasscodeForm(false)} label="Cancel" />
<Button
type="primary"
onClick={submitPasscodeForm}
label="Set Passcode"
className="mr-3"
/>
<Button
type="normal"
onClick={() => setShowPasscodeForm(false)}
label="Cancel"
/>
</form>
)}
@@ -238,11 +275,20 @@ export const PasscodeLock = observer(({
<>
<Text>Passcode lock is enabled.</Text>
<div className="flex flex-row mt-3">
<Button type="normal" label="Change Passcode" onClick={changePasscodePressed} className="mr-3" />
<Button type="danger" label="Remove Passcode" onClick={removePasscodePressed} />
<Button
type="normal"
label="Change Passcode"
onClick={changePasscodePressed}
className="mr-3"
/>
<Button
type="danger"
label="Remove Passcode"
onClick={removePasscodePressed}
/>
</div>
</>)}
</>
)}
</PreferencesSegment>
</PreferencesGroup>
@@ -252,19 +298,23 @@ export const PasscodeLock = observer(({
<PreferencesGroup>
<PreferencesSegment>
<Title>Autolock</Title>
<Text className="mb-3">The autolock timer begins when the window or tab loses focus.</Text>
<Text className="mb-3">
The autolock timer begins when the window or tab loses focus.
</Text>
<div className="flex flex-row items-center">
{passcodeAutoLockOptions.map(option => {
{passcodeAutoLockOptions.map((option) => {
return (
<a
className={`sk-a info mr-3 ${option.value === selectedAutoLockInterval ? 'boxed' : ''}`}
onClick={() => selectAutoLockInterval(option.value)}>
className={`sk-a info mr-3 ${
option.value === selectedAutoLockInterval ? 'boxed' : ''
}`}
onClick={() => selectAutoLockInterval(option.value)}
>
{option.label}
</a>
);
})}
</div>
</PreferencesSegment>
</PreferencesGroup>
</>

View File

@@ -9,7 +9,7 @@ import {
PreferencesSegment,
Title,
Text,
} from '@/preferences/components';
} from '@/components/Preferences/components';
import { Button } from '@/components/Button';
type Props = {

View File

@@ -3,5 +3,7 @@ import { FunctionComponent } from 'preact';
export const Bullet: FunctionComponent<{ className?: string }> = ({
className = '',
}) => (
<div className={`min-w-1 min-h-1 rounded-full bg-inverted-default ${className} mr-2`} />
<div
className={`min-w-1 min-h-1 rounded-full bg-inverted-default ${className} mr-2`}
/>
);

View File

@@ -1,6 +1,6 @@
import { FunctionComponent } from 'preact';
import { IconButton } from '../../../components/IconButton';
import { IconButton } from '../../../IconButton';
import { useState } from 'preact/hooks';

View File

@@ -12,7 +12,7 @@ import {
ModalDialogButtons,
ModalDialogDescription,
ModalDialogLabel,
} from '@/components/shared/ModalDialog';
} from '@/components/Shared/ModalDialog';
export const SaveSecretKey: FunctionComponent<{
activation: TwoFactorActivation;

View File

@@ -12,7 +12,7 @@ import {
ModalDialogButtons,
ModalDialogDescription,
ModalDialogLabel,
} from '@/components/shared/ModalDialog';
} from '@/components/Shared/ModalDialog';
import { CopyButton } from './CopyButton';
import { Bullet } from './Bullet';
@@ -26,7 +26,11 @@ export const ScanQRCode: FunctionComponent<{
</ModalDialogLabel>
<ModalDialogDescription className="h-33">
<div className="w-25 h-25 flex items-center justify-center bg-info">
<QRCode className="border-neutral-contrast-bg border-solid border-2" value={act.qrCode} size={100} />
<QRCode
className="border-neutral-contrast-bg border-solid border-2"
value={act.qrCode}
size={100}
/>
</div>
<div className="min-w-5" />
<div className="flex-grow flex flex-col">

View File

@@ -1,4 +1,4 @@
import { MfaProvider, UserProvider } from '@/preferences/providers';
import { MfaProvider, UserProvider } from '@/components/Preferences/providers';
import { action, makeAutoObservable, observable } from 'mobx';
import { TwoFactorActivation } from './TwoFactorActivation';

View File

@@ -5,7 +5,7 @@ import {
PreferencesGroup,
PreferencesSegment,
} from '../../components';
import { Switch } from '../../../components/Switch';
import { Switch } from '../../../Switch';
import { observer } from 'mobx-react-lite';
import { is2FAActivation, is2FADisabled, TwoFactorAuth } from './TwoFactorAuth';
import { TwoFactorActivationView } from './TwoFactorActivationView';
@@ -54,12 +54,8 @@ const TwoFactorSwitch: FunctionComponent<{ auth: TwoFactorAuth }> = observer(
}
return (
<Switch
checked={!is2FADisabled(auth.status)}
onChange={auth.toggle2FA}
/>
<Switch checked={!is2FADisabled(auth.status)} onChange={auth.toggle2FA} />
);
}
);

View File

@@ -3,8 +3,8 @@ import ModalDialog, {
ModalDialogButtons,
ModalDialogDescription,
ModalDialogLabel,
} from '@/components/shared/ModalDialog';
import { Subtitle } from '@/preferences/components';
} from '@/components/Shared/ModalDialog';
import { Subtitle } from '@/components/Preferences/components';
import { observer } from 'mobx-react-lite';
import { FunctionComponent } from 'preact';
import { TwoFactorActivation } from './TwoFactorActivation';

View File

@@ -9,7 +9,7 @@ import {
ModalDialogButtons,
ModalDialogDescription,
ModalDialogLabel,
} from '@/components/shared/ModalDialog';
} from '@/components/Shared/ModalDialog';
export const Verification: FunctionComponent<{
activation: TwoFactorActivation;

View File

@@ -1,7 +1,7 @@
import { FunctionalComponent } from 'preact';
import { useRef, useState } from 'preact/hooks';
import { ArrowDownCheckmarkIcon } from '@standardnotes/stylekit';
import { Title } from '@/preferences/components';
import { Title } from '@/components/Preferences/components';
type Props = {
title: string | JSX.Element;

View File

@@ -48,14 +48,15 @@ export const ModalDialogLabel: FunctionComponent<{
</AlertDialogLabel>
);
export const ModalDialogDescription: FunctionComponent<{ className?: string }> =
({ children, className = '' }) => (
<AlertDialogDescription
className={`px-4 py-4 flex flex-row items-center ${className}`}
>
{children}
</AlertDialogDescription>
);
export const ModalDialogDescription: FunctionComponent<{
className?: string;
}> = ({ children, className = '' }) => (
<AlertDialogDescription
className={`px-4 py-4 flex flex-row items-center ${className}`}
>
{children}
</AlertDialogDescription>
);
export const ModalDialogButtons: FunctionComponent<{ className?: string }> = ({
children,

View File

@@ -3,8 +3,8 @@ import { observer } from 'mobx-react-lite';
import { FunctionComponent } from 'preact';
import { useCallback, useEffect, useRef } from 'preact/hooks';
import { Icon } from '../Icon';
import { Menu } from '../menu/Menu';
import { MenuItem, MenuItemType } from '../menu/MenuItem';
import { Menu } from '../Menu/Menu';
import { MenuItem, MenuItemType } from '../Menu/MenuItem';
import { usePremiumModal } from '../Premium';
import { useCloseOnBlur } from '../utils';
import { SNTag } from '@standardnotes/snjs';

View File

@@ -1,11 +0,0 @@
import { FunctionComponent } from 'preact';
type Props = {
classes?: string;
}
export const PreferencesSegment: FunctionComponent<Props> = ({
children,
classes = ''
}) => (
<div className={`flex flex-col ${classes}`}>{children}</div>
);

View File

@@ -1,34 +0,0 @@
import { FunctionalComponent } from 'preact';
import { PreferencesGroup, PreferencesSegment } from '@/preferences/components';
import { OfflineSubscription } from '@/preferences/panes/account/offlineSubscription';
import { WebApplication } from '@/ui_models/application';
import { observer } from 'mobx-react-lite';
import { AppState } from '@/ui_models/app_state';
import { Extensions } from '@/preferences/panes/Extensions';
import { ExtensionsLatestVersions } from '@/preferences/panes/extensions-segments';
import { AccordionItem } from '@/components/shared/AccordionItem';
interface IProps {
application: WebApplication;
appState: AppState;
extensionsLatestVersions: ExtensionsLatestVersions;
}
export const Advanced: FunctionalComponent<IProps> = observer(
({ application, appState, extensionsLatestVersions }) => {
return (
<PreferencesGroup>
<PreferencesSegment>
<AccordionItem title={'Advanced Settings'}>
<div className='flex flex-row items-center'>
<div className='flex-grow flex flex-col'>
<OfflineSubscription application={application} appState={appState} />
<Extensions className={'mt-3'} application={application} extensionsLatestVersions={extensionsLatestVersions} />
</div>
</div>
</AccordionItem>
</PreferencesSegment>
</PreferencesGroup>
);
}
);

View File

@@ -1,62 +0,0 @@
import { DecoratedInput } from "@/components/DecoratedInput";
import { Icon } from "@/components/Icon";
import { STRING_E2E_ENABLED, STRING_ENC_NOT_ENABLED, STRING_LOCAL_ENC_ENABLED } from "@/strings";
import { AppState } from "@/ui_models/app_state";
import { observer } from "mobx-react-lite";
import { FunctionComponent } from "preact";
import { PreferencesGroup, PreferencesSegment, Text, Title } from "../../components";
const formatCount = (count: number, itemType: string) => `${count} / ${count} ${itemType}`;
const EncryptionEnabled: FunctionComponent<{ appState: AppState }> = observer(({ appState }) => {
const count = appState.accountMenu.structuredNotesAndTagsCount;
const notes = formatCount(count.notes, 'notes');
const tags = formatCount(count.tags, 'tags');
const archived = formatCount(count.archived, 'archived notes');
const deleted = formatCount(count.deleted, 'trashed notes');
const checkIcon = <Icon className="success min-w-4 min-h-4" type="check-bold" />;
const noteIcon = <Icon type="rich-text" className="min-w-5 min-h-5" />;
const tagIcon = <Icon type="hashtag" className="min-w-5 min-h-5" />;
const archiveIcon = <Icon type="archive" className="min-w-5 min-h-5" />;
const trashIcon = <Icon type="trash" className="min-w-5 min-h-5" />;
return (
<>
<div className="flex flex-row pb-1 pt-1.5" >
<DecoratedInput disabled={true} text={notes} right={[checkIcon]} left={[noteIcon]} />
<div className="min-w-3" />
<DecoratedInput disabled={true} text={tags} right={[checkIcon]} left={[tagIcon]} />
</div>
<div className="flex flex-row" >
<DecoratedInput disabled={true} text={archived} right={[checkIcon]} left={[archiveIcon]} />
<div className="min-w-3" />
<DecoratedInput disabled={true} text={deleted} right={[checkIcon]} left={[trashIcon]} />
</div>
</>
);
});
export const Encryption: FunctionComponent<{ appState: AppState }> = observer(({ appState }) => {
const app = appState.application;
const hasUser = app.hasAccount();
const hasPasscode = app.hasPasscode();
const isEncryptionEnabled = app.isEncryptionAvailable();
const encryptionStatusString = hasUser
? STRING_E2E_ENABLED
: hasPasscode
? STRING_LOCAL_ENC_ENABLED
: STRING_ENC_NOT_ENABLED;
return (
<PreferencesGroup>
<PreferencesSegment>
<Title>Encryption</Title>
<Text>{encryptionStatusString}</Text>
{isEncryptionEnabled &&
<EncryptionEnabled appState={appState} />}
</PreferencesSegment>
</PreferencesGroup>
);
});

View File

@@ -1,4 +1,4 @@
import { PreferenceId } from '@/preferences/PreferencesMenu';
import { PreferenceId } from '@/components/Preferences/PreferencesMenu';
import { action, computed, makeObservable, observable } from 'mobx';
const DEFAULT_PANE = 'account';

View File

@@ -1,4 +1,4 @@
import { loadPurchaseFlowUrl } from '@/purchaseFlow/PurchaseFlowWrapper';
import { loadPurchaseFlowUrl } from '@/components/PurchaseFlow/PurchaseFlowWrapper';
import { action, makeObservable, observable } from 'mobx';
import { WebApplication } from '../application';