feat: get editor icons and their colors from snjs (#828)
* feat: get editor icons and their colors from snjs * feat: get icons and their tints from snjs * fix: use IconType from snjs
This commit is contained in:
@@ -8,7 +8,8 @@ import {
|
|||||||
} from '@reach/listbox';
|
} from '@reach/listbox';
|
||||||
import VisuallyHidden from '@reach/visually-hidden';
|
import VisuallyHidden from '@reach/visually-hidden';
|
||||||
import { FunctionComponent } from 'preact';
|
import { FunctionComponent } from 'preact';
|
||||||
import { IconType, Icon } from './Icon';
|
import { Icon } from './Icon';
|
||||||
|
import { IconType } from '@standardnotes/snjs';
|
||||||
|
|
||||||
export type DropdownItem = {
|
export type DropdownItem = {
|
||||||
icon?: IconType;
|
icon?: IconType;
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ import MenuArrowDownAlt from '../../icons/ic-menu-arrow-down-alt.svg';
|
|||||||
import MenuArrowRight from '../../icons/ic-menu-arrow-right.svg';
|
import MenuArrowRight from '../../icons/ic-menu-arrow-right.svg';
|
||||||
|
|
||||||
import { FunctionalComponent } from 'preact';
|
import { FunctionalComponent } from 'preact';
|
||||||
|
import { IconType } from '@standardnotes/snjs';
|
||||||
|
|
||||||
const ICONS = {
|
const ICONS = {
|
||||||
editor: EditorIcon,
|
editor: EditorIcon,
|
||||||
@@ -137,8 +138,6 @@ const ICONS = {
|
|||||||
'premium-feature': PremiumFeatureIcon,
|
'premium-feature': PremiumFeatureIcon,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type IconType = keyof typeof ICONS;
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
type: IconType;
|
type: IconType;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { FunctionComponent } from 'preact';
|
import { FunctionComponent } from 'preact';
|
||||||
import { Icon, IconType } from './Icon';
|
import { Icon } from './Icon';
|
||||||
|
import { IconType } from '@standardnotes/snjs';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { FunctionComponent, Ref } from 'preact';
|
import { FunctionComponent, Ref } from 'preact';
|
||||||
import { JSXInternal } from 'preact/src/jsx';
|
import { JSXInternal } from 'preact/src/jsx';
|
||||||
import { forwardRef } from 'preact/compat';
|
import { forwardRef } from 'preact/compat';
|
||||||
import { Icon, IconType } from './Icon';
|
import { Icon } from './Icon';
|
||||||
import { IconButton } from './IconButton';
|
import { IconButton } from './IconButton';
|
||||||
|
import { IconType } from '@standardnotes/snjs';
|
||||||
|
|
||||||
type ToggleProps = {
|
type ToggleProps = {
|
||||||
toggleOnIcon: IconType;
|
toggleOnIcon: IconType;
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { getIconAndTintForEditor } from '@/preferences/panes/general-segments';
|
|
||||||
import { WebApplication } from '@/ui_models/application';
|
import { WebApplication } from '@/ui_models/application';
|
||||||
import {
|
import {
|
||||||
CollectionSort,
|
CollectionSort,
|
||||||
@@ -74,7 +73,9 @@ export const NotesListItem: FunctionComponent<Props> = ({
|
|||||||
const showModifiedDate = sortedBy === CollectionSort.UpdatedAt;
|
const showModifiedDate = sortedBy === CollectionSort.UpdatedAt;
|
||||||
const editorForNote = application.componentManager.editorForNote(note);
|
const editorForNote = application.componentManager.editorForNote(note);
|
||||||
const editorName = editorForNote?.name ?? 'Plain editor';
|
const editorName = editorForNote?.name ?? 'Plain editor';
|
||||||
const [icon, tint] = getIconAndTintForEditor(editorForNote?.identifier);
|
const [icon, tint] = application.iconsController.getIconAndTintForEditor(
|
||||||
|
editorForNote?.identifier
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import {
|
|||||||
} from '@reach/disclosure';
|
} from '@reach/disclosure';
|
||||||
import {
|
import {
|
||||||
ComponentArea,
|
ComponentArea,
|
||||||
|
IconType,
|
||||||
ItemMutator,
|
ItemMutator,
|
||||||
NoteMutator,
|
NoteMutator,
|
||||||
PrefKey,
|
PrefKey,
|
||||||
@@ -27,7 +28,7 @@ import {
|
|||||||
} from '@standardnotes/snjs';
|
} from '@standardnotes/snjs';
|
||||||
import { FunctionComponent } from 'preact';
|
import { FunctionComponent } from 'preact';
|
||||||
import { useEffect, useRef, useState } from 'preact/hooks';
|
import { useEffect, useRef, useState } from 'preact/hooks';
|
||||||
import { Icon, IconType } from '../Icon';
|
import { Icon } from '../Icon';
|
||||||
import { PremiumModalProvider } from '../Premium';
|
import { PremiumModalProvider } from '../Premium';
|
||||||
import { createEditorMenuGroups } from './changeEditor/createEditorMenuGroups';
|
import { createEditorMenuGroups } from './changeEditor/createEditorMenuGroups';
|
||||||
import { EditorAccordionMenu } from './changeEditor/EditorAccordionMenu';
|
import { EditorAccordionMenu } from './changeEditor/EditorAccordionMenu';
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { FunctionComponent } from 'preact';
|
import { FunctionComponent } from 'preact';
|
||||||
import { Icon, IconType } from './Icon';
|
import { Icon } from './Icon';
|
||||||
|
import { IconType } from '@standardnotes/snjs';
|
||||||
|
|
||||||
type ButtonType = 'normal' | 'primary';
|
type ButtonType = 'normal' | 'primary';
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ export const Switch: FunctionalComponent<SwitchProps> = (
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<label
|
<label
|
||||||
className={`sn-component flex justify-between items-center cursor-pointer px-3 ${className} ${isDisabled ? 'faded' : ''}`}
|
className={`sn-component flex justify-between items-center cursor-pointer px-3 ${className} ${
|
||||||
|
isDisabled ? 'faded' : ''
|
||||||
|
}`}
|
||||||
{...(props.role ? { role: props.role } : {})}
|
{...(props.role ? { role: props.role } : {})}
|
||||||
>
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
@@ -51,8 +53,9 @@ export const Switch: FunctionalComponent<SwitchProps> = (
|
|||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
aria-hidden
|
aria-hidden
|
||||||
className={`sn-switch-handle ${checked ? 'sn-switch-handle--right' : ''
|
className={`sn-switch-handle ${
|
||||||
}`}
|
checked ? 'sn-switch-handle--right' : ''
|
||||||
|
}`}
|
||||||
/>
|
/>
|
||||||
</CustomCheckboxContainer>
|
</CustomCheckboxContainer>
|
||||||
</label>
|
</label>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { Icon, IconType } from '@/components/Icon';
|
import { Icon } from '@/components/Icon';
|
||||||
import { FeaturesState } from '@/ui_models/app_state/features_state';
|
import { FeaturesState } from '@/ui_models/app_state/features_state';
|
||||||
import { TagsState } from '@/ui_models/app_state/tags_state';
|
import { TagsState } from '@/ui_models/app_state/tags_state';
|
||||||
import '@reach/tooltip/styles.css';
|
import '@reach/tooltip/styles.css';
|
||||||
import { SNSmartTag } from '@standardnotes/snjs';
|
import { SNSmartTag, IconType } from '@standardnotes/snjs';
|
||||||
import { observer } from 'mobx-react-lite';
|
import { observer } from 'mobx-react-lite';
|
||||||
import { FunctionComponent } from 'preact';
|
import { FunctionComponent } from 'preact';
|
||||||
import { useCallback, useEffect, useRef, useState } from 'preact/hooks';
|
import { useCallback, useEffect, useRef, useState } from 'preact/hooks';
|
||||||
|
|||||||
@@ -6,8 +6,9 @@ import {
|
|||||||
} from 'preact';
|
} from 'preact';
|
||||||
import { forwardRef, Ref } from 'preact/compat';
|
import { forwardRef, Ref } from 'preact/compat';
|
||||||
import { JSXInternal } from 'preact/src/jsx';
|
import { JSXInternal } from 'preact/src/jsx';
|
||||||
import { Icon, IconType } from '../Icon';
|
import { Icon } from '../Icon';
|
||||||
import { Switch, SwitchProps } from '../Switch';
|
import { Switch, SwitchProps } from '../Switch';
|
||||||
|
import { IconType } from '@standardnotes/snjs';
|
||||||
|
|
||||||
export enum MenuItemType {
|
export enum MenuItemType {
|
||||||
IconButton,
|
IconButton,
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { IconType } from '@/components/Icon';
|
|
||||||
import { action, makeAutoObservable, observable } from 'mobx';
|
import { action, makeAutoObservable, observable } from 'mobx';
|
||||||
import { ExtensionsLatestVersions } from '@/preferences/panes/extensions-segments';
|
import { ExtensionsLatestVersions } from '@/preferences/panes/extensions-segments';
|
||||||
import {
|
import {
|
||||||
@@ -6,6 +5,7 @@ import {
|
|||||||
ContentType,
|
ContentType,
|
||||||
FeatureIdentifier,
|
FeatureIdentifier,
|
||||||
SNComponent,
|
SNComponent,
|
||||||
|
IconType,
|
||||||
} from '@standardnotes/snjs';
|
} from '@standardnotes/snjs';
|
||||||
import { WebApplication } from '@/ui_models/application';
|
import { WebApplication } from '@/ui_models/application';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Icon, IconType } from '@/components/Icon';
|
import { Icon } from '@/components/Icon';
|
||||||
import { FunctionComponent } from 'preact';
|
import { FunctionComponent } from 'preact';
|
||||||
|
import { IconType } from '@standardnotes/snjs';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
iconType: IconType;
|
iconType: IconType;
|
||||||
|
|||||||
@@ -142,7 +142,8 @@ const AppearancePane: FunctionComponent<Props> = observer(({ application }) => {
|
|||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<Subtitle>Use system color scheme</Subtitle>
|
<Subtitle>Use system color scheme</Subtitle>
|
||||||
<Text>
|
<Text>
|
||||||
Automatically change active theme based on your system settings.
|
Automatically change active theme based on your system
|
||||||
|
settings.
|
||||||
</Text>
|
</Text>
|
||||||
</div>
|
</div>
|
||||||
<Switch
|
<Switch
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
import { convertStringifiedBooleanToBoolean, isDesktopApplication } from '@/utils';
|
import {
|
||||||
|
convertStringifiedBooleanToBoolean,
|
||||||
|
isDesktopApplication,
|
||||||
|
} from '@/utils';
|
||||||
import { STRING_FAILED_TO_UPDATE_USER_SETTING } from '@/strings';
|
import { STRING_FAILED_TO_UPDATE_USER_SETTING } from '@/strings';
|
||||||
import { useCallback, useEffect, useState } from 'preact/hooks';
|
import { useCallback, useEffect, useState } from 'preact/hooks';
|
||||||
import { WebApplication } from '@/ui_models/application';
|
import { WebApplication } from '@/ui_models/application';
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
CloudProvider,
|
CloudProvider,
|
||||||
DropboxBackupFrequency,
|
DropboxBackupFrequency,
|
||||||
GoogleDriveBackupFrequency,
|
GoogleDriveBackupFrequency,
|
||||||
OneDriveBackupFrequency
|
OneDriveBackupFrequency,
|
||||||
} from '@standardnotes/settings';
|
} from '@standardnotes/settings';
|
||||||
import { WebApplication } from '@/ui_models/application';
|
import { WebApplication } from '@/ui_models/application';
|
||||||
import { Button } from '@/components/Button';
|
import { Button } from '@/components/Button';
|
||||||
@@ -20,9 +20,9 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const CloudBackupProvider: FunctionComponent<Props> = ({
|
export const CloudBackupProvider: FunctionComponent<Props> = ({
|
||||||
application,
|
application,
|
||||||
providerName
|
providerName,
|
||||||
}) => {
|
}) => {
|
||||||
const [authBegan, setAuthBegan] = useState(false);
|
const [authBegan, setAuthBegan] = useState(false);
|
||||||
const [successfullyInstalled, setSuccessfullyInstalled] = useState(false);
|
const [successfullyInstalled, setSuccessfullyInstalled] = useState(false);
|
||||||
const [backupFrequency, setBackupFrequency] = useState<string | null>(null);
|
const [backupFrequency, setBackupFrequency] = useState<string | null>(null);
|
||||||
@@ -32,14 +32,13 @@ export const CloudBackupProvider: FunctionComponent<Props> = ({
|
|||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const shouldDisable = await application.alertService
|
const shouldDisable = await application.alertService.confirm(
|
||||||
.confirm(
|
'Are you sure you want to disable this integration?',
|
||||||
'Are you sure you want to disable this integration?',
|
'Disable?',
|
||||||
'Disable?',
|
'Disable',
|
||||||
'Disable',
|
ButtonType.Danger,
|
||||||
ButtonType.Danger,
|
'Cancel'
|
||||||
'Cancel'
|
);
|
||||||
);
|
|
||||||
if (shouldDisable) {
|
if (shouldDisable) {
|
||||||
await application.deleteSetting(backupFrequencySettingName);
|
await application.deleteSetting(backupFrequencySettingName);
|
||||||
await application.deleteSetting(backupTokenSettingName);
|
await application.deleteSetting(backupTokenSettingName);
|
||||||
@@ -54,7 +53,10 @@ export const CloudBackupProvider: FunctionComponent<Props> = ({
|
|||||||
const installIntegration = (event: Event) => {
|
const installIntegration = (event: Event) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
const authUrl = application.getCloudProviderIntegrationUrl(providerName, isDev);
|
const authUrl = application.getCloudProviderIntegrationUrl(
|
||||||
|
providerName,
|
||||||
|
isDev
|
||||||
|
);
|
||||||
openInNewTab(authUrl);
|
openInNewTab(authUrl);
|
||||||
setAuthBegan(true);
|
setAuthBegan(true);
|
||||||
};
|
};
|
||||||
@@ -62,7 +64,10 @@ export const CloudBackupProvider: FunctionComponent<Props> = ({
|
|||||||
const performBackupNow = async () => {
|
const performBackupNow = async () => {
|
||||||
// A backup is performed anytime the setting is updated with the integration token, so just update it here
|
// A backup is performed anytime the setting is updated with the integration token, so just update it here
|
||||||
try {
|
try {
|
||||||
await application.updateSetting(backupFrequencySettingName, backupFrequency as string);
|
await application.updateSetting(
|
||||||
|
backupFrequencySettingName,
|
||||||
|
backupFrequency as string
|
||||||
|
);
|
||||||
application.alertService.alert(
|
application.alertService.alert(
|
||||||
'A backup has been triggered for this provider. Please allow a couple minutes for your backup to be processed.'
|
'A backup has been triggered for this provider. Please allow a couple minutes for your backup to be processed.'
|
||||||
);
|
);
|
||||||
@@ -77,20 +82,24 @@ export const CloudBackupProvider: FunctionComponent<Props> = ({
|
|||||||
[CloudProvider.Dropbox]: {
|
[CloudProvider.Dropbox]: {
|
||||||
backupTokenSettingName: SettingName.DropboxBackupToken,
|
backupTokenSettingName: SettingName.DropboxBackupToken,
|
||||||
backupFrequencySettingName: SettingName.DropboxBackupFrequency,
|
backupFrequencySettingName: SettingName.DropboxBackupFrequency,
|
||||||
defaultBackupFrequency: DropboxBackupFrequency.Daily
|
defaultBackupFrequency: DropboxBackupFrequency.Daily,
|
||||||
},
|
},
|
||||||
[CloudProvider.Google]: {
|
[CloudProvider.Google]: {
|
||||||
backupTokenSettingName: SettingName.GoogleDriveBackupToken,
|
backupTokenSettingName: SettingName.GoogleDriveBackupToken,
|
||||||
backupFrequencySettingName: SettingName.GoogleDriveBackupFrequency,
|
backupFrequencySettingName: SettingName.GoogleDriveBackupFrequency,
|
||||||
defaultBackupFrequency: GoogleDriveBackupFrequency.Daily
|
defaultBackupFrequency: GoogleDriveBackupFrequency.Daily,
|
||||||
},
|
},
|
||||||
[CloudProvider.OneDrive]: {
|
[CloudProvider.OneDrive]: {
|
||||||
backupTokenSettingName: SettingName.OneDriveBackupToken,
|
backupTokenSettingName: SettingName.OneDriveBackupToken,
|
||||||
backupFrequencySettingName: SettingName.OneDriveBackupFrequency,
|
backupFrequencySettingName: SettingName.OneDriveBackupFrequency,
|
||||||
defaultBackupFrequency: OneDriveBackupFrequency.Daily
|
defaultBackupFrequency: OneDriveBackupFrequency.Daily,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
const { backupTokenSettingName, backupFrequencySettingName, defaultBackupFrequency } = backupSettingsData[providerName];
|
const {
|
||||||
|
backupTokenSettingName,
|
||||||
|
backupFrequencySettingName,
|
||||||
|
defaultBackupFrequency,
|
||||||
|
} = backupSettingsData[providerName];
|
||||||
|
|
||||||
const getCloudProviderIntegrationTokenFromUrl = (url: URL) => {
|
const getCloudProviderIntegrationTokenFromUrl = (url: URL) => {
|
||||||
const urlSearchParams = new URLSearchParams(url.search);
|
const urlSearchParams = new URLSearchParams(url.search);
|
||||||
@@ -123,8 +132,14 @@ export const CloudBackupProvider: FunctionComponent<Props> = ({
|
|||||||
if (!cloudProviderToken) {
|
if (!cloudProviderToken) {
|
||||||
throw new Error();
|
throw new Error();
|
||||||
}
|
}
|
||||||
await application.updateSetting(backupTokenSettingName, cloudProviderToken);
|
await application.updateSetting(
|
||||||
await application.updateSetting(backupFrequencySettingName, defaultBackupFrequency);
|
backupTokenSettingName,
|
||||||
|
cloudProviderToken
|
||||||
|
);
|
||||||
|
await application.updateSetting(
|
||||||
|
backupFrequencySettingName,
|
||||||
|
defaultBackupFrequency
|
||||||
|
);
|
||||||
|
|
||||||
setBackupFrequency(defaultBackupFrequency);
|
setBackupFrequency(defaultBackupFrequency);
|
||||||
|
|
||||||
@@ -174,15 +189,15 @@ export const CloudBackupProvider: FunctionComponent<Props> = ({
|
|||||||
</div>
|
</div>
|
||||||
{authBegan && (
|
{authBegan && (
|
||||||
<div>
|
<div>
|
||||||
<p className='sk-panel-row'>
|
<p className="sk-panel-row">
|
||||||
Complete authentication from the newly opened window. Upon
|
Complete authentication from the newly opened window. Upon
|
||||||
completion, a confirmation code will be displayed. Enter this code
|
completion, a confirmation code will be displayed. Enter this code
|
||||||
below:
|
below:
|
||||||
</p>
|
</p>
|
||||||
<div className={`mt-1`}>
|
<div className={`mt-1`}>
|
||||||
<input
|
<input
|
||||||
className='sk-input sk-base center-text'
|
className="sk-input sk-base center-text"
|
||||||
placeholder='Enter confirmation code'
|
placeholder="Enter confirmation code"
|
||||||
value={confirmation}
|
value={confirmation}
|
||||||
onKeyPress={handleKeyPress}
|
onKeyPress={handleKeyPress}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
@@ -193,8 +208,8 @@ export const CloudBackupProvider: FunctionComponent<Props> = ({
|
|||||||
{shouldShowEnableButton && (
|
{shouldShowEnableButton && (
|
||||||
<div>
|
<div>
|
||||||
<Button
|
<Button
|
||||||
type='normal'
|
type="normal"
|
||||||
label='Enable'
|
label="Enable"
|
||||||
className={'px-1 text-xs min-w-40'}
|
className={'px-1 text-xs min-w-40'}
|
||||||
onClick={installIntegration}
|
onClick={installIntegration}
|
||||||
/>
|
/>
|
||||||
@@ -204,15 +219,15 @@ export const CloudBackupProvider: FunctionComponent<Props> = ({
|
|||||||
{backupFrequency && (
|
{backupFrequency && (
|
||||||
<div className={'flex flex-col items-end'}>
|
<div className={'flex flex-col items-end'}>
|
||||||
<Button
|
<Button
|
||||||
className='min-w-40 mb-2'
|
className="min-w-40 mb-2"
|
||||||
type='normal'
|
type="normal"
|
||||||
label='Perform Backup'
|
label="Perform Backup"
|
||||||
onClick={performBackupNow}
|
onClick={performBackupNow}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
className='min-w-40'
|
className="min-w-40"
|
||||||
type='normal'
|
type="normal"
|
||||||
label='Disable'
|
label="Disable"
|
||||||
onClick={disable}
|
onClick={disable}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,26 +4,34 @@ import { useCallback, useEffect, useState } from 'preact/hooks';
|
|||||||
import { WebApplication } from '@/ui_models/application';
|
import { WebApplication } from '@/ui_models/application';
|
||||||
import {
|
import {
|
||||||
PreferencesGroup,
|
PreferencesGroup,
|
||||||
PreferencesSegment, Subtitle,
|
PreferencesSegment,
|
||||||
|
Subtitle,
|
||||||
Text,
|
Text,
|
||||||
Title
|
Title,
|
||||||
} from '@/preferences/components';
|
} from '@/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';
|
||||||
import { CloudProvider, EmailBackupFrequency, SettingName } from '@standardnotes/settings';
|
import {
|
||||||
|
CloudProvider,
|
||||||
|
EmailBackupFrequency,
|
||||||
|
SettingName,
|
||||||
|
} from '@standardnotes/settings';
|
||||||
import { Switch } from '@/components/Switch';
|
import { Switch } from '@/components/Switch';
|
||||||
import { convertStringifiedBooleanToBoolean } from '@/utils';
|
import { convertStringifiedBooleanToBoolean } from '@/utils';
|
||||||
import { STRING_FAILED_TO_UPDATE_USER_SETTING } from '@/strings';
|
import { STRING_FAILED_TO_UPDATE_USER_SETTING } from '@/strings';
|
||||||
|
|
||||||
const providerData = [{
|
const providerData = [
|
||||||
name: CloudProvider.Dropbox
|
{
|
||||||
}, {
|
name: CloudProvider.Dropbox,
|
||||||
name: CloudProvider.Google
|
},
|
||||||
}, {
|
{
|
||||||
name: CloudProvider.OneDrive
|
name: CloudProvider.Google,
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
name: CloudProvider.OneDrive,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@@ -31,8 +39,10 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const CloudLink: FunctionComponent<Props> = ({ application }) => {
|
export const CloudLink: FunctionComponent<Props> = ({ application }) => {
|
||||||
const [isEntitledForCloudBackups, setIsEntitledForCloudBackups] = useState(false);
|
const [isEntitledForCloudBackups, setIsEntitledForCloudBackups] =
|
||||||
const [isFailedCloudBackupEmailMuted, setIsFailedCloudBackupEmailMuted] = useState(true);
|
useState(false);
|
||||||
|
const [isFailedCloudBackupEmailMuted, setIsFailedCloudBackupEmailMuted] =
|
||||||
|
useState(true);
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
const loadIsFailedCloudBackupEmailMutedSetting = useCallback(async () => {
|
const loadIsFailedCloudBackupEmailMutedSetting = useCallback(async () => {
|
||||||
@@ -98,12 +108,12 @@ export const CloudLink: FunctionComponent<Props> = ({ application }) => {
|
|||||||
A <span className={'font-bold'}>Plus</span> or{' '}
|
A <span className={'font-bold'}>Plus</span> or{' '}
|
||||||
<span className={'font-bold'}>Pro</span> subscription plan is
|
<span className={'font-bold'}>Pro</span> subscription plan is
|
||||||
required to enable Cloud Backups.{' '}
|
required to enable Cloud Backups.{' '}
|
||||||
<a target='_blank' href='https://standardnotes.com/features'>
|
<a target="_blank" href="https://standardnotes.com/features">
|
||||||
Learn more
|
Learn more
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</Text>
|
</Text>
|
||||||
<HorizontalSeparator classes='mt-3 mb-3' />
|
<HorizontalSeparator classes="mt-3 mb-3" />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<div
|
<div
|
||||||
@@ -122,7 +132,10 @@ export const CloudLink: FunctionComponent<Props> = ({ application }) => {
|
|||||||
<div>
|
<div>
|
||||||
{providerData.map(({ name }) => (
|
{providerData.map(({ name }) => (
|
||||||
<>
|
<>
|
||||||
<CloudBackupProvider application={application} providerName={name} />
|
<CloudBackupProvider
|
||||||
|
application={application}
|
||||||
|
providerName={name}
|
||||||
|
/>
|
||||||
<HorizontalSeparator classes={'mt-3 mb-3'} />
|
<HorizontalSeparator classes={'mt-3 mb-3'} />
|
||||||
</>
|
</>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { Dropdown, DropdownItem } from '@/components/Dropdown';
|
import { Dropdown, DropdownItem } from '@/components/Dropdown';
|
||||||
import { IconType } from '@/components/Icon';
|
|
||||||
import { FeatureIdentifier, PrefKey } from '@standardnotes/snjs';
|
import { FeatureIdentifier, PrefKey } from '@standardnotes/snjs';
|
||||||
import {
|
import {
|
||||||
PreferencesGroup,
|
PreferencesGroup,
|
||||||
@@ -27,31 +26,6 @@ type EditorOption = DropdownItem & {
|
|||||||
value: FeatureIdentifier | 'plain-editor';
|
value: FeatureIdentifier | 'plain-editor';
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getIconAndTintForEditor = (
|
|
||||||
identifier: FeatureIdentifier | undefined
|
|
||||||
): [IconType, number] => {
|
|
||||||
switch (identifier) {
|
|
||||||
case FeatureIdentifier.BoldEditor:
|
|
||||||
case FeatureIdentifier.PlusEditor:
|
|
||||||
return ['rich-text', 1];
|
|
||||||
case FeatureIdentifier.MarkdownBasicEditor:
|
|
||||||
case FeatureIdentifier.MarkdownMathEditor:
|
|
||||||
case FeatureIdentifier.MarkdownMinimistEditor:
|
|
||||||
case FeatureIdentifier.MarkdownProEditor:
|
|
||||||
return ['markdown', 2];
|
|
||||||
case FeatureIdentifier.TokenVaultEditor:
|
|
||||||
return ['authenticator', 6];
|
|
||||||
case FeatureIdentifier.SheetsEditor:
|
|
||||||
return ['spreadsheets', 5];
|
|
||||||
case FeatureIdentifier.TaskEditor:
|
|
||||||
return ['tasks', 3];
|
|
||||||
case FeatureIdentifier.CodeEditor:
|
|
||||||
return ['code', 4];
|
|
||||||
default:
|
|
||||||
return ['plain-text', 1];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const makeEditorDefault = (
|
const makeEditorDefault = (
|
||||||
application: WebApplication,
|
application: WebApplication,
|
||||||
component: SNComponent,
|
component: SNComponent,
|
||||||
@@ -103,7 +77,8 @@ export const Defaults: FunctionComponent<Props> = ({ application }) => {
|
|||||||
.componentsForArea(ComponentArea.Editor)
|
.componentsForArea(ComponentArea.Editor)
|
||||||
.map((editor): EditorOption => {
|
.map((editor): EditorOption => {
|
||||||
const identifier = editor.package_info.identifier;
|
const identifier = editor.package_info.identifier;
|
||||||
const [iconType, tint] = getIconAndTintForEditor(identifier);
|
const [iconType, tint] =
|
||||||
|
application.iconsController.getIconAndTintForEditor(identifier);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
label: editor.name,
|
label: editor.name,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Icon, IconType } from '@/components/Icon';
|
import { Icon } from '@/components/Icon';
|
||||||
import {
|
import {
|
||||||
Disclosure,
|
Disclosure,
|
||||||
DisclosureButton,
|
DisclosureButton,
|
||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
import { FunctionComponent } from 'preact';
|
import { FunctionComponent } from 'preact';
|
||||||
import { MouseEventHandler } from 'react';
|
import { MouseEventHandler } from 'react';
|
||||||
import { useState, useRef, useEffect } from 'preact/hooks';
|
import { useState, useRef, useEffect } from 'preact/hooks';
|
||||||
|
import { IconType } from '@standardnotes/snjs';
|
||||||
|
|
||||||
const DisclosureIconButton: FunctionComponent<{
|
const DisclosureIconButton: FunctionComponent<{
|
||||||
className?: string;
|
className?: string;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
SNApplication,
|
SNApplication,
|
||||||
NoteGroupController,
|
NoteGroupController,
|
||||||
removeFromArray,
|
removeFromArray,
|
||||||
|
IconsController,
|
||||||
} from '@standardnotes/snjs';
|
} from '@standardnotes/snjs';
|
||||||
|
|
||||||
type WebServices = {
|
type WebServices = {
|
||||||
@@ -39,6 +40,7 @@ export class WebApplication extends SNApplication {
|
|||||||
private webServices!: WebServices;
|
private webServices!: WebServices;
|
||||||
public noteControllerGroup: NoteGroupController;
|
public noteControllerGroup: NoteGroupController;
|
||||||
private webEventObservers: WebEventObserver[] = [];
|
private webEventObservers: WebEventObserver[] = [];
|
||||||
|
public iconsController: IconsController;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
deviceInterface: WebDeviceInterface,
|
deviceInterface: WebDeviceInterface,
|
||||||
@@ -64,6 +66,7 @@ export class WebApplication extends SNApplication {
|
|||||||
);
|
);
|
||||||
deviceInterface.setApplication(this);
|
deviceInterface.setApplication(this);
|
||||||
this.noteControllerGroup = new NoteGroupController(this);
|
this.noteControllerGroup = new NoteGroupController(this);
|
||||||
|
this.iconsController = new IconsController();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
@@ -76,6 +79,7 @@ export class WebApplication extends SNApplication {
|
|||||||
}
|
}
|
||||||
this.webServices = {} as WebServices;
|
this.webServices = {} as WebServices;
|
||||||
this.noteControllerGroup.deinit();
|
this.noteControllerGroup.deinit();
|
||||||
|
this.iconsController.deinit();
|
||||||
this.webEventObservers.length = 0;
|
this.webEventObservers.length = 0;
|
||||||
/**
|
/**
|
||||||
* Allow any pending renders to complete before destroying the global
|
* Allow any pending renders to complete before destroying the global
|
||||||
|
|||||||
@@ -84,7 +84,7 @@
|
|||||||
"@reach/tooltip": "^0.16.2",
|
"@reach/tooltip": "^0.16.2",
|
||||||
"@standardnotes/components": "1.4.4",
|
"@standardnotes/components": "1.4.4",
|
||||||
"@standardnotes/features": "1.26.1",
|
"@standardnotes/features": "1.26.1",
|
||||||
"@standardnotes/snjs": "2.44.3",
|
"@standardnotes/snjs": "2.45.0",
|
||||||
"@standardnotes/settings": "^1.10.0",
|
"@standardnotes/settings": "^1.10.0",
|
||||||
"@standardnotes/sncrypto-web": "1.6.0",
|
"@standardnotes/sncrypto-web": "1.6.0",
|
||||||
"mobx": "^6.3.5",
|
"mobx": "^6.3.5",
|
||||||
|
|||||||
18
yarn.lock
18
yarn.lock
@@ -2636,10 +2636,10 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@standardnotes/settings/-/settings-1.10.0.tgz#b46d4805c9a1cfb3fa3d9b3915daae9dd5661789"
|
resolved "https://registry.yarnpkg.com/@standardnotes/settings/-/settings-1.10.0.tgz#b46d4805c9a1cfb3fa3d9b3915daae9dd5661789"
|
||||||
integrity sha512-FUy4RDI7nFnbOGAaX5wMvBz+6Yto5tXGXDAi7bnWALZByTIlN8bkFZ2CNk2skjpzeOxBjqhCRi+GRCcuMqZ70A==
|
integrity sha512-FUy4RDI7nFnbOGAaX5wMvBz+6Yto5tXGXDAi7bnWALZByTIlN8bkFZ2CNk2skjpzeOxBjqhCRi+GRCcuMqZ70A==
|
||||||
|
|
||||||
"@standardnotes/settings@^1.11.0":
|
"@standardnotes/settings@^1.11.1":
|
||||||
version "1.11.0"
|
version "1.11.1"
|
||||||
resolved "https://registry.yarnpkg.com/@standardnotes/settings/-/settings-1.11.0.tgz#8bdb987a9ebb8b480ee9e32ad67c4e0ac7d9f0fe"
|
resolved "https://registry.yarnpkg.com/@standardnotes/settings/-/settings-1.11.1.tgz#62e0df52820534c67041c99ed7f2c3a277158f39"
|
||||||
integrity sha512-4a4408m+afO00fsp/Pxcyx2N8BOWpvKHqv9u3PisKBy3xZTUdman7ah/KHPvUd7MFEYbY7frB/DoHN3tiokArQ==
|
integrity sha512-uZChaTlIV63fYn7ODzVd/IB0nvrgyo/DwVaNgkjjHd3doGYqBMzzdfhs0RT0Ffpy0LOQhLpLBYqyJAryl1c4EA==
|
||||||
|
|
||||||
"@standardnotes/sncrypto-common@^1.6.0":
|
"@standardnotes/sncrypto-common@^1.6.0":
|
||||||
version "1.6.0"
|
version "1.6.0"
|
||||||
@@ -2655,16 +2655,16 @@
|
|||||||
buffer "^6.0.3"
|
buffer "^6.0.3"
|
||||||
libsodium-wrappers "^0.7.9"
|
libsodium-wrappers "^0.7.9"
|
||||||
|
|
||||||
"@standardnotes/snjs@2.44.3":
|
"@standardnotes/snjs@2.45.0":
|
||||||
version "2.44.3"
|
version "2.45.0"
|
||||||
resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.44.3.tgz#bb16aca691d24f2a7fea6f94a929f0a241ebcfc0"
|
resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.45.0.tgz#d123434b959d279af2ffe00acf2e9e6784cf497c"
|
||||||
integrity sha512-54rjz1s+pDdB4fRS69QE3DLNbebC+1DCw/+j5/2EOqdelj+/Ce7bQyiNxwYj4cqE0Z0zYEeJl7oAxVecOBCQZw==
|
integrity sha512-gTlOG3wd4zYaBeReypQiz+ASEnVCKaB8kWtKF61nkV9j3vFgYh3krsvdhOi6lMXBk+CijEefeLhrmooOtv08Xg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@standardnotes/auth" "^3.15.3"
|
"@standardnotes/auth" "^3.15.3"
|
||||||
"@standardnotes/common" "^1.8.0"
|
"@standardnotes/common" "^1.8.0"
|
||||||
"@standardnotes/domain-events" "^2.20.1"
|
"@standardnotes/domain-events" "^2.20.1"
|
||||||
"@standardnotes/features" "^1.26.1"
|
"@standardnotes/features" "^1.26.1"
|
||||||
"@standardnotes/settings" "^1.11.0"
|
"@standardnotes/settings" "^1.11.1"
|
||||||
"@standardnotes/sncrypto-common" "^1.6.0"
|
"@standardnotes/sncrypto-common" "^1.6.0"
|
||||||
|
|
||||||
"@svgr/babel-plugin-add-jsx-attribute@^5.4.0":
|
"@svgr/babel-plugin-add-jsx-attribute@^5.4.0":
|
||||||
|
|||||||
Reference in New Issue
Block a user