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 { AppState } from '@/ui_models/app_state';
import { observer } from 'mobx-react-lite'; import { observer } from 'mobx-react-lite';
import { Icon } from '../Icon'; 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 { SyncQueueStrategy } from '@standardnotes/snjs';
import { STRING_GENERIC_SYNC_ERROR } from '@/strings'; import { STRING_GENERIC_SYNC_ERROR } from '@/strings';
import { useState } from 'preact/hooks'; import { useState } from 'preact/hooks';
import { AccountMenuPane } from '.'; import { AccountMenuPane } from '.';
import { FunctionComponent } from 'preact'; import { FunctionComponent } from 'preact';
import { Menu } from '../menu/Menu'; import { Menu } from '../Menu/Menu';
import { MenuItem, MenuItemSeparator, MenuItemType } from '../menu/MenuItem'; import { MenuItem, MenuItemSeparator, MenuItemType } from '../Menu/MenuItem';
type Props = { type Props = {
appState: AppState; appState: AppState;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
import { FunctionComponent } from 'preact'; import { FunctionComponent } from 'preact';
import { HorizontalSeparator } from '@/components/shared/HorizontalSeparator'; import { HorizontalSeparator } from '@/components/Shared/HorizontalSeparator';
const HorizontalLine: FunctionComponent<{ index: number; length: number }> = ({ const HorizontalLine: FunctionComponent<{ index: number; length: number }> = ({
index, 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="flex-grow flex flex-col py-6 items-center">
<div className="w-125 max-w-125 flex flex-col"> <div className="w-125 max-w-125 flex flex-col">
{children != undefined && Array.isArray(children) {children != undefined && Array.isArray(children)
? children ? children.filter((child) => child != undefined)
.filter((child) => child != undefined)
: children} : children}
</div> </div>
</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, Credentials,
SignOutWrapper, SignOutWrapper,
Authentication, Authentication,
} from '@/preferences/panes/account'; } from '@/components/Preferences/panes/account';
import { PreferencesPane } from '@/preferences/components'; import { PreferencesPane } from '@/components/Preferences/components';
import { observer } from 'mobx-react-lite'; import { observer } from 'mobx-react-lite';
import { WebApplication } from '@/ui_models/application'; import { WebApplication } from '@/ui_models/application';
import { AppState } from '@/ui_models/app_state'; import { AppState } from '@/ui_models/app_state';

View File

@@ -1,7 +1,7 @@
import { Dropdown, DropdownItem } from '@/components/Dropdown'; import { Dropdown, DropdownItem } from '@/components/Dropdown';
import { usePremiumModal } from '@/components/Premium'; import { usePremiumModal } from '@/components/Premium';
import { sortThemes } from '@/components/QuickSettingsMenu/QuickSettingsMenu'; import { sortThemes } from '@/components/QuickSettingsMenu/QuickSettingsMenu';
import { HorizontalSeparator } from '@/components/shared/HorizontalSeparator'; import { HorizontalSeparator } from '@/components/Shared/HorizontalSeparator';
import { Switch } from '@/components/Switch'; import { Switch } from '@/components/Switch';
import { WebApplication } from '@/ui_models/application'; import { WebApplication } from '@/ui_models/application';
import { GetFeatures } from '@standardnotes/features'; 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 { WebApplication } from '@/ui_models/application';
import { ComponentViewer, SNComponent } from '@standardnotes/snjs'; import { ComponentViewer, SNComponent } from '@standardnotes/snjs';
import { FeatureIdentifier } from '@standardnotes/features'; import { FeatureIdentifier } from '@standardnotes/features';
@@ -7,7 +10,7 @@ import { FunctionComponent } from 'preact';
import { ExtensionItem } from './extensions-segments'; import { ExtensionItem } from './extensions-segments';
import { ComponentView } from '@/components/ComponentView'; import { ComponentView } from '@/components/ComponentView';
import { AppState } from '@/ui_models/app_state'; import { AppState } from '@/ui_models/app_state';
import { PreferencesMenu } from '@/preferences/PreferencesMenu'; import { PreferencesMenu } from '@/components/Preferences/PreferencesMenu';
import { useEffect, useState } from 'preact/hooks'; import { useEffect, useState } from 'preact/hooks';
interface IProps { interface IProps {

View File

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

View File

@@ -104,7 +104,11 @@ export const HelpAndFeedback: FunctionComponent = () => (
<Text> <Text>
Send an email to help@standardnotes.com and well sort it out. Send an email to help@standardnotes.com and well sort it out.
</Text> </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> </PreferencesSegment>
</PreferencesGroup> </PreferencesGroup>
</PreferencesPane> </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, PreferencesSegment,
Text, Text,
Title, Title,
} from '@/preferences/components'; } from '@/components/Preferences/components';
import { WebApplication } from '@/ui_models/application'; import { WebApplication } from '@/ui_models/application';
import { AppState } from '@/ui_models/app_state'; import { AppState } from '@/ui_models/app_state';
import { observer } from 'mobx-react-lite'; import { observer } from 'mobx-react-lite';

View File

@@ -4,14 +4,14 @@ import {
Subtitle, Subtitle,
Text, Text,
Title, Title,
} from '@/preferences/components'; } from '@/components/Preferences/components';
import { Button } from '@/components/Button'; import { Button } from '@/components/Button';
import { WebApplication } from '@/ui_models/application'; import { WebApplication } from '@/ui_models/application';
import { observer } from '@node_modules/mobx-react-lite'; 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 { dateToLocalizedString } from '@standardnotes/snjs';
import { useCallback, useState } from 'preact/hooks'; 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 { FunctionComponent, render } from 'preact';
import { AppState } from '@/ui_models/app_state'; import { AppState } from '@/ui_models/app_state';
import { PasswordWizard } from '@/components/PasswordWizard'; import { PasswordWizard } from '@/components/PasswordWizard';

View File

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

View File

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

View File

@@ -3,9 +3,12 @@ import { FunctionalComponent } from 'preact';
export const ChangeEmailSuccess: FunctionalComponent = () => { export const ChangeEmailSuccess: FunctionalComponent = () => {
return ( return (
<div> <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'}> <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> </p>
</div> </div>
); );

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -6,13 +6,13 @@ import {
Subtitle, Subtitle,
Text, Text,
Title, Title,
} from '@/preferences/components'; } from '@/components/Preferences/components';
import { WebApplication } from '@/ui_models/application'; import { WebApplication } from '@/ui_models/application';
import { FeatureIdentifier, FeatureStatus } from '@standardnotes/snjs'; import { FeatureIdentifier, FeatureStatus } from '@standardnotes/snjs';
import { FunctionComponent } from 'preact'; import { FunctionComponent } from 'preact';
import { useCallback, useEffect, useState } from 'preact/hooks'; import { useCallback, useEffect, useState } from 'preact/hooks';
import { usePremiumModal } from '@/components/Premium'; import { usePremiumModal } from '@/components/Premium';
import { HorizontalSeparator } from '@/components/shared/HorizontalSeparator'; import { HorizontalSeparator } from '@/components/Shared/HorizontalSeparator';
type ExperimentalFeatureItem = { type ExperimentalFeatureItem = {
identifier: FeatureIdentifier; 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 { Switch } from '@/components/Switch';
import { import {
PreferencesGroup, PreferencesGroup,
@@ -6,7 +6,7 @@ import {
Subtitle, Subtitle,
Text, Text,
Title, Title,
} from '@/preferences/components'; } from '@/components/Preferences/components';
import { WebApplication } from '@/ui_models/application'; import { WebApplication } from '@/ui_models/application';
import { PrefKey } from '@standardnotes/snjs'; import { PrefKey } from '@standardnotes/snjs';
import { observer } from 'mobx-react-lite'; import { observer } from 'mobx-react-lite';

View File

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

View File

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

View File

@@ -3,5 +3,7 @@ import { FunctionComponent } from 'preact';
export const Bullet: FunctionComponent<{ className?: string }> = ({ export const Bullet: FunctionComponent<{ className?: string }> = ({
className = '', 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 { FunctionComponent } from 'preact';
import { IconButton } from '../../../components/IconButton'; import { IconButton } from '../../../IconButton';
import { useState } from 'preact/hooks'; import { useState } from 'preact/hooks';

View File

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

View File

@@ -12,7 +12,7 @@ import {
ModalDialogButtons, ModalDialogButtons,
ModalDialogDescription, ModalDialogDescription,
ModalDialogLabel, ModalDialogLabel,
} from '@/components/shared/ModalDialog'; } from '@/components/Shared/ModalDialog';
import { CopyButton } from './CopyButton'; import { CopyButton } from './CopyButton';
import { Bullet } from './Bullet'; import { Bullet } from './Bullet';
@@ -26,7 +26,11 @@ export const ScanQRCode: FunctionComponent<{
</ModalDialogLabel> </ModalDialogLabel>
<ModalDialogDescription className="h-33"> <ModalDialogDescription className="h-33">
<div className="w-25 h-25 flex items-center justify-center bg-info"> <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>
<div className="min-w-5" /> <div className="min-w-5" />
<div className="flex-grow flex flex-col"> <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 { action, makeAutoObservable, observable } from 'mobx';
import { TwoFactorActivation } from './TwoFactorActivation'; import { TwoFactorActivation } from './TwoFactorActivation';

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -3,8 +3,8 @@ import { observer } from 'mobx-react-lite';
import { FunctionComponent } from 'preact'; import { FunctionComponent } from 'preact';
import { useCallback, useEffect, useRef } from 'preact/hooks'; import { useCallback, useEffect, useRef } from 'preact/hooks';
import { Icon } from '../Icon'; import { Icon } from '../Icon';
import { Menu } from '../menu/Menu'; import { Menu } from '../Menu/Menu';
import { MenuItem, MenuItemType } from '../menu/MenuItem'; import { MenuItem, MenuItemType } from '../Menu/MenuItem';
import { usePremiumModal } from '../Premium'; import { usePremiumModal } from '../Premium';
import { useCloseOnBlur } from '../utils'; import { useCloseOnBlur } from '../utils';
import { SNTag } from '@standardnotes/snjs'; 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'; import { action, computed, makeObservable, observable } from 'mobx';
const DEFAULT_PANE = 'account'; 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 { action, makeObservable, observable } from 'mobx';
import { WebApplication } from '../application'; import { WebApplication } from '../application';