diff --git a/.env.sample b/.env.sample index 195dd62c9..42ed60a38 100644 --- a/.env.sample +++ b/.env.sample @@ -2,21 +2,22 @@ RAILS_ENV=development PORT=3001 WEB_CONCURRENCY=0 RAILS_LOG_TO_STDOUT=true + # Log Level options: "INFO" | "DEBUG" | "INFO" | "WARN" | "ERROR" | "FATAL" RAILS_LOG_LEVEL=INFO + RAILS_SERVE_STATIC_FILES=true SECRET_KEY_BASE=test +BUGSNAG_API_KEY= + APP_HOST=http://localhost:3001 PURCHASE_URL=https://standardnotes.com/purchase PLANS_URL=https://standardnotes.com/plans DASHBOARD_URL=http://standardnotes.com/dashboard - DEFAULT_SYNC_SERVER=http://localhost:3000 +WEBSOCKET_URL=wss://sockets-dev.standardnotes.com -# Development options -DEV_DEFAULT_SYNC_SERVER=https://api.standardnotes.com ENABLE_UNFINISHED_FEATURES=false -DEV_WEBSOCKET_URL=wss://sockets-dev.standardnotes.com # NewRelic (Optional) NEW_RELIC_ENABLED=false diff --git a/app/assets/javascripts/app.tsx b/app/assets/javascripts/app.tsx index d83d12c0e..07beabdc2 100644 --- a/app/assets/javascripts/app.tsx +++ b/app/assets/javascripts/app.tsx @@ -2,25 +2,18 @@ declare global { interface Window { - // eslint-disable-next-line camelcase - _bugsnag_api_key?: string; - // eslint-disable-next-line camelcase - _purchase_url?: string; - // eslint-disable-next-line camelcase - _plans_url?: string; - // eslint-disable-next-line camelcase - _dashboard_url?: string; - // eslint-disable-next-line camelcase - _default_sync_server: string; - // eslint-disable-next-line camelcase - _enable_unfinished_features: boolean; - // eslint-disable-next-line camelcase - _websocket_url: string; + bugsnagApiKey?: string; + dashboardUrl?: string; + defaultFilesHost: string; + defaultSyncServer: string; + devAccountEmail?: string; + devAccountPassword?: string; + devAccountServer?: string; + enabledUnfinishedFeatures: boolean; + plansUrl?: string; + purchaseUrl?: string; startApplication?: StartApplication; - - _devAccountEmail?: string; - _devAccountPassword?: string; - _devAccountServer?: string; + websocketUrl: string; } } @@ -37,6 +30,7 @@ import { isDev } from './utils'; const startApplication: StartApplication = async function startApplication( defaultSyncServerHost: string, + defaultFilesHostHost: string, bridge: Bridge, enableUnfinishedFeatures: boolean, webSocketUrl: string @@ -46,6 +40,7 @@ const startApplication: StartApplication = async function startApplication( const mainApplicationGroup = new ApplicationGroup( defaultSyncServerHost, + defaultFilesHostHost, bridge, enableUnfinishedFeatures ? Runtime.Dev : Runtime.Prod, webSocketUrl @@ -79,10 +74,11 @@ const startApplication: StartApplication = async function startApplication( if (IsWebPlatform) { startApplication( - window._default_sync_server, + window.defaultSyncServer, + window.defaultFilesHost, new BrowserBridge(WebAppVersion), - window._enable_unfinished_features, - window._websocket_url + window.enabledUnfinishedFeatures, + window.websocketUrl ); } else { window.startApplication = startApplication; diff --git a/app/assets/javascripts/components/AccountMenu/ConfirmPassword.tsx b/app/assets/javascripts/components/AccountMenu/ConfirmPassword.tsx index b4d780545..25dd2c317 100644 --- a/app/assets/javascripts/components/AccountMenu/ConfirmPassword.tsx +++ b/app/assets/javascripts/components/AccountMenu/ConfirmPassword.tsx @@ -3,7 +3,7 @@ import { WebApplication } from '@/ui_models/application'; import { AppState } from '@/ui_models/app_state'; import { observer } from 'mobx-react-lite'; import { FunctionComponent } from 'preact'; -import { StateUpdater, useEffect, useRef, useState } from 'preact/hooks'; +import { useEffect, useRef, useState } from 'preact/hooks'; import { AccountMenuPane } from '.'; import { Button } from '../Button'; import { Checkbox } from '../Checkbox'; @@ -17,22 +17,22 @@ type Props = { setMenuPane: (pane: AccountMenuPane) => void; email: string; password: string; - setPassword: StateUpdater; }; export const ConfirmPassword: FunctionComponent = observer( - ({ application, appState, setMenuPane, email, password, setPassword }) => { + ({ application, appState, setMenuPane, email, password }) => { const { notesAndTagsCount } = appState.accountMenu; const [confirmPassword, setConfirmPassword] = useState(''); const [showPassword, setShowPassword] = useState(false); const [isRegistering, setIsRegistering] = useState(false); const [isEphemeral, setIsEphemeral] = useState(false); const [shouldMergeLocal, setShouldMergeLocal] = useState(true); + const [error, setError] = useState(''); const passwordInputRef = useRef(null); useEffect(() => { - passwordInputRef?.current?.focus(); + passwordInputRef.current?.focus(); }, []); const handlePasswordChange = (e: Event) => { @@ -50,6 +50,9 @@ export const ConfirmPassword: FunctionComponent = observer( }; const handleKeyDown = (e: KeyboardEvent) => { + if (error.length) { + setError(''); + } if (e.key === 'Enter') { handleConfirmFormSubmit(e); } @@ -59,7 +62,7 @@ export const ConfirmPassword: FunctionComponent = observer( e.preventDefault(); if (!password) { - passwordInputRef?.current!.focus(); + passwordInputRef.current?.focus(); return; } @@ -76,21 +79,15 @@ export const ConfirmPassword: FunctionComponent = observer( }) .catch((err) => { console.error(err); - application.alertService.alert(err).finally(() => { - setPassword(''); - handleGoBack(); - }); + setError(err.message); }) .finally(() => { setIsRegistering(false); }); } else { - application.alertService - .alert(STRING_NON_MATCHING_PASSWORDS) - .finally(() => { - setConfirmPassword(''); - passwordInputRef?.current!.focus(); - }); + setError(STRING_NON_MATCHING_PASSWORDS); + setConfirmPassword(''); + passwordInputRef.current?.focus(); } }; @@ -138,6 +135,7 @@ export const ConfirmPassword: FunctionComponent = observer( ref={passwordInputRef} disabled={isRegistering} /> + {error ?
{error}
: null} + ); +}; + +type ListedActionsMenuProps = { + application: WebApplication; + note: SNNote; + recalculateMenuStyle: () => void; +}; + +const ListedActionsMenu: FunctionComponent = ({ + application, + note, + recalculateMenuStyle, +}) => { + const [menuGroups, setMenuGroups] = useState([]); + const [isFetchingAccounts, setIsFetchingAccounts] = useState(true); + + const reloadMenuGroup = async (group: ListedMenuGroup) => { + const updatedAccountInfo = await application.getListedAccountInfo( + group.account, + note.uuid + ); + + if (!updatedAccountInfo) { + return; + } + + const updatedGroup: ListedMenuGroup = { + name: updatedAccountInfo.display_name, + account: group.account, + actions: updatedAccountInfo.actions, + }; + + const updatedGroups = menuGroups.map((group) => { + if (updatedGroup.account.authorId === group.account.authorId) { + return updatedGroup; + } else { + return group; + } + }); + + setMenuGroups(updatedGroups); + }; + + useEffect(() => { + const fetchListedAccounts = async () => { + if (!application.hasAccount()) { + setIsFetchingAccounts(false); + return; + } + + try { + const listedAccountEntries = await application.getListedAccounts(); + + if (!listedAccountEntries.length) { + throw new Error('No Listed accounts found'); + } + + const menuGroups: ListedMenuGroup[] = []; + + await Promise.all( + listedAccountEntries.map(async (account) => { + const accountInfo = await application.getListedAccountInfo( + account, + note.uuid + ); + + if (accountInfo) { + menuGroups.push({ + name: accountInfo.display_name, + account, + actions: accountInfo.actions, + }); + } else { + menuGroups.push({ + name: account.authorId, + account, + actions: [], + }); + } + }) + ); + + setMenuGroups( + menuGroups.sort((a, b) => { + return a.name.toString().toLowerCase() < + b.name.toString().toLowerCase() + ? -1 + : 1; + }) + ); + } catch (err) { + console.error(err); + } finally { + setIsFetchingAccounts(false); + setTimeout(() => { + recalculateMenuStyle(); + }); + } + }; + + fetchListedAccounts(); + }, [application, note.uuid, recalculateMenuStyle]); + + return ( + <> + {isFetchingAccounts && ( +
+
+
+ )} + {!isFetchingAccounts && menuGroups.length ? ( + <> + {menuGroups.map((group, index) => ( + +
+ {group.name} +
+ {group.actions.length ? ( + group.actions.map((action) => ( + + )) + ) : ( +
+ No actions available +
+ )} +
+ ))} + + ) : null} + {!isFetchingAccounts && !menuGroups.length ? ( +
+
+ No Listed accounts found +
+
+ ) : null} + + ); +}; + +export const ListedActionsOption: FunctionComponent = ({ + application, + note, + closeOnBlur, +}) => { + const menuRef = useRef(null); + const menuButtonRef = useRef(null); + + const [isMenuOpen, setIsMenuOpen] = useState(false); + const [menuStyle, setMenuStyle] = useState({ + right: 0, + bottom: 0, + maxHeight: 'auto', + }); + + const toggleListedMenu = () => { + if (!isMenuOpen) { + const menuPosition = calculateSubmenuStyle(menuButtonRef.current); + if (menuPosition) { + setMenuStyle(menuPosition); + } + } + + setIsMenuOpen(!isMenuOpen); + }; + + const recalculateMenuStyle = useCallback(() => { + const newMenuPosition = calculateSubmenuStyle( + menuButtonRef.current, + menuRef.current + ); + + if (newMenuPosition) { + setMenuStyle(newMenuPosition); + } + }, []); + + useEffect(() => { + if (isMenuOpen) { + setTimeout(() => { + recalculateMenuStyle(); + }); + } + }, [isMenuOpen, recalculateMenuStyle]); + + return ( + + +
+ + Listed actions +
+ +
+ + {isMenuOpen && ( + + )} + +
+ ); +}; diff --git a/app/assets/javascripts/components/NotesOptions/NotesOptions.tsx b/app/assets/javascripts/components/NotesOptions/NotesOptions.tsx index 323b12746..8a00573b2 100644 --- a/app/assets/javascripts/components/NotesOptions/NotesOptions.tsx +++ b/app/assets/javascripts/components/NotesOptions/NotesOptions.tsx @@ -18,6 +18,7 @@ import { MAX_MENU_SIZE_MULTIPLIER, BYTES_IN_ONE_MEGABYTE, } from '@/constants'; +import { ListedActionsOption } from './ListedActionsOption'; export type NotesOptionsProps = { application: WebApplication; @@ -602,6 +603,12 @@ export const NotesOptions = observer( )} {notes.length === 1 ? ( <> +
+
diff --git a/app/assets/javascripts/components/NotesOptions/changeEditor/ChangeEditorMenu.tsx b/app/assets/javascripts/components/NotesOptions/changeEditor/ChangeEditorMenu.tsx index ac4a0631d..b6578bdba 100644 --- a/app/assets/javascripts/components/NotesOptions/changeEditor/ChangeEditorMenu.tsx +++ b/app/assets/javascripts/components/NotesOptions/changeEditor/ChangeEditorMenu.tsx @@ -26,6 +26,7 @@ import { PLAIN_EDITOR_NAME } from './createEditorMenuGroups'; type ChangeEditorMenuProps = { application: WebApplication; closeOnBlur: (event: { relatedTarget: EventTarget | null }) => void; + closeMenu: () => void; groups: EditorMenuGroup[]; isOpen: boolean; currentEditor: SNComponent | undefined; @@ -39,6 +40,7 @@ const getGroupId = (group: EditorMenuGroup) => export const ChangeEditorMenu: FunctionComponent = ({ application, closeOnBlur, + closeMenu, groups, isOpen, currentEditor, @@ -169,6 +171,8 @@ export const ChangeEditorMenu: FunctionComponent = ({ if (shouldSelectEditor) { selectComponent(itemToBeSelected.component ?? null, note); } + + closeMenu(); }; return ( diff --git a/app/assets/javascripts/components/NotesOptions/changeEditor/createEditorMenuGroups.ts b/app/assets/javascripts/components/NotesOptions/changeEditor/createEditorMenuGroups.ts index 2a9b16907..c2a56e096 100644 --- a/app/assets/javascripts/components/NotesOptions/changeEditor/createEditorMenuGroups.ts +++ b/app/assets/javascripts/components/NotesOptions/changeEditor/createEditorMenuGroups.ts @@ -76,7 +76,7 @@ export const createEditorMenuGroups = ( name: editor.name, component: editor, isEntitled: - application.getFeatureStatus(editor.identifier) === + application.features.getFeatureStatus(editor.identifier) === FeatureStatus.Entitled, }; diff --git a/app/assets/javascripts/components/Premium/usePremiumModal.tsx b/app/assets/javascripts/components/Premium/usePremiumModal.tsx index 2c9b3652f..16cec58aa 100644 --- a/app/assets/javascripts/components/Premium/usePremiumModal.tsx +++ b/app/assets/javascripts/components/Premium/usePremiumModal.tsx @@ -1,4 +1,5 @@ -import { FeaturesState } from '@/ui_models/app_state/features_state'; +import { WebApplication } from '@/ui_models/application'; +import { AppState } from '@/ui_models/app_state'; import { observer } from 'mobx-react-lite'; import { FunctionalComponent } from 'preact'; import { useContext } from 'preact/hooks'; @@ -24,24 +25,33 @@ export const usePremiumModal = (): PremiumModalContextData => { }; interface Props { - state: FeaturesState; + application: WebApplication; + appState: AppState; } export const PremiumModalProvider: FunctionalComponent = observer( - ({ state, children }) => { - const featureName = state._premiumAlertFeatureName; - const activate = state.showPremiumAlert; - const close = state.closePremiumAlert; + ({ application, appState, children }) => { + const featureName = appState.features._premiumAlertFeatureName; + const activate = appState.features.showPremiumAlert; + const close = appState.features.closePremiumAlert; const showModal = !!featureName; + const hasSubscription = Boolean( + appState.subscription.userSubscription && + !appState.subscription.isUserSubscriptionExpired && + !appState.subscription.isUserSubscriptionCanceled + ); + return ( <> {showModal && ( )} diff --git a/app/assets/javascripts/components/PremiumFeaturesModal.tsx b/app/assets/javascripts/components/PremiumFeaturesModal.tsx index e61e8eab1..c261e8231 100644 --- a/app/assets/javascripts/components/PremiumFeaturesModal.tsx +++ b/app/assets/javascripts/components/PremiumFeaturesModal.tsx @@ -7,23 +7,31 @@ import { FunctionalComponent } from 'preact'; import { Icon } from './Icon'; import { PremiumIllustration } from '@standardnotes/stylekit'; import { useRef } from 'preact/hooks'; +import { WebApplication } from '@/ui_models/application'; +import { openSubscriptionDashboard } from '@/hooks/manageSubscription'; type Props = { + application: WebApplication; featureName: string; + hasSubscription: boolean; onClose: () => void; showModal: boolean; }; export const PremiumFeaturesModal: FunctionalComponent = ({ + application, featureName, + hasSubscription, onClose, showModal, }) => { const plansButtonRef = useRef(null); - const onClickPlans = () => { - if (window._plans_url) { - window.location.assign(window._plans_url); + const handleClick = () => { + if (hasSubscription) { + openSubscriptionDashboard(application); + } else if (window.plansUrl) { + window.location.assign(window.plansUrl); } }; @@ -61,11 +69,11 @@ export const PremiumFeaturesModal: FunctionalComponent = ({
diff --git a/app/assets/javascripts/components/QuickSettingsMenu/FocusModeSwitch.tsx b/app/assets/javascripts/components/QuickSettingsMenu/FocusModeSwitch.tsx index 102e07776..7d38f1c16 100644 --- a/app/assets/javascripts/components/QuickSettingsMenu/FocusModeSwitch.tsx +++ b/app/assets/javascripts/components/QuickSettingsMenu/FocusModeSwitch.tsx @@ -22,7 +22,7 @@ export const FocusModeSwitch: FunctionComponent = ({ }) => { const premiumModal = usePremiumModal(); const isEntitled = - application.getFeatureStatus(FeatureIdentifier.FocusMode) === + application.features.getFeatureStatus(FeatureIdentifier.FocusMode) === FeatureStatus.Entitled; const toggle = useCallback( diff --git a/app/assets/javascripts/components/QuickSettingsMenu/ThemesMenuButton.tsx b/app/assets/javascripts/components/QuickSettingsMenu/ThemesMenuButton.tsx index b874aa1b2..57859bb43 100644 --- a/app/assets/javascripts/components/QuickSettingsMenu/ThemesMenuButton.tsx +++ b/app/assets/javascripts/components/QuickSettingsMenu/ThemesMenuButton.tsx @@ -22,12 +22,13 @@ export const ThemesMenuButton: FunctionComponent = ({ const premiumModal = usePremiumModal(); const isThirdPartyTheme = useMemo( - () => application.isThirdPartyFeature(item.identifier), + () => application.features.isThirdPartyFeature(item.identifier), [application, item.identifier] ); const isEntitledToTheme = useMemo( () => - application.getFeatureStatus(item.identifier) === FeatureStatus.Entitled, + application.features.getFeatureStatus(item.identifier) === + FeatureStatus.Entitled, [application, item.identifier] ); const canActivateTheme = useMemo( diff --git a/app/assets/javascripts/components/RevisionHistoryModal/HistoryListContainer.tsx b/app/assets/javascripts/components/RevisionHistoryModal/HistoryListContainer.tsx index 8aafed274..55748187a 100644 --- a/app/assets/javascripts/components/RevisionHistoryModal/HistoryListContainer.tsx +++ b/app/assets/javascripts/components/RevisionHistoryModal/HistoryListContainer.tsx @@ -155,7 +155,9 @@ export const HistoryListContainer: FunctionComponent = observer( async (revisionListEntry: RevisionListEntry) => { setShowContentLockedScreen(false); - if (application.hasMinimumRole(revisionListEntry.required_role)) { + if ( + application.features.hasMinimumRole(revisionListEntry.required_role) + ) { setIsFetchingSelectedRevision(true); setSelectedRevision(undefined); setSelectedRemoteEntry(undefined); @@ -202,7 +204,6 @@ export const HistoryListContainer: FunctionComponent = observer(
{selectedTab === RevisionListTabType.Session && ( = observer( remoteHistory={remoteHistory} isFetchingRemoteHistory={isFetchingRemoteHistory} fetchAndSetRemoteRevision={fetchAndSetRemoteRevision} - selectedTab={selectedTab} /> )} {selectedTab === RevisionListTabType.Legacy && ( = ({ legacyHistory, - selectedTab, setSelectedRevision, setSelectedRemoteEntry, fetchAndSetLegacyRevision, @@ -56,13 +53,6 @@ export const LegacyHistoryList: FunctionComponent = ({ } }, [firstEntry, selectFirstEntry, selectedItemUrl, setSelectedRevision]); - useEffect(() => { - if (selectedTab === RevisionListTabType.Legacy) { - selectFirstEntry(); - legacyHistoryListRef.current?.focus(); - } - }, [selectFirstEntry, selectedTab]); - return (
Promise; - selectedTab: RevisionListTabType; }; export const RemoteHistoryList: FunctionComponent = @@ -32,7 +30,6 @@ export const RemoteHistoryList: FunctionComponent = remoteHistory, isFetchingRemoteHistory, fetchAndSetRemoteRevision, - selectedTab, }) => { const remoteHistoryListRef = useRef(null); @@ -69,13 +66,6 @@ export const RemoteHistoryList: FunctionComponent = selectedEntryUuid.length, ]); - useEffect(() => { - if (selectedTab === RevisionListTabType.Remote) { - selectFirstEntry(); - remoteHistoryListRef.current?.focus(); - } - }, [selectFirstEntry, selectedTab]); - return (
= >
{previewHistoryEntryTitle(entry)}
- {!application.hasMinimumRole(entry.required_role) && ( - - )} + {!application.features.hasMinimumRole( + entry.required_role + ) && }
))} diff --git a/app/assets/javascripts/components/RevisionHistoryModal/RevisionContentLocked.tsx b/app/assets/javascripts/components/RevisionHistoryModal/RevisionContentLocked.tsx index 33fc75c5c..3f73c3f23 100644 --- a/app/assets/javascripts/components/RevisionHistoryModal/RevisionContentLocked.tsx +++ b/app/assets/javascripts/components/RevisionHistoryModal/RevisionContentLocked.tsx @@ -49,8 +49,8 @@ export const RevisionContentLocked: FunctionComponent<{ type="primary" label="Discover plans" onClick={() => { - if (window._plans_url) { - window.location.assign(window._plans_url); + if (window.plansUrl) { + window.location.assign(window.plansUrl); } }} /> diff --git a/app/assets/javascripts/components/RevisionHistoryModal/SessionHistoryList.tsx b/app/assets/javascripts/components/RevisionHistoryModal/SessionHistoryList.tsx index 35e8bb3cb..75593da29 100644 --- a/app/assets/javascripts/components/RevisionHistoryModal/SessionHistoryList.tsx +++ b/app/assets/javascripts/components/RevisionHistoryModal/SessionHistoryList.tsx @@ -13,12 +13,10 @@ import { useState, } from 'preact/hooks'; import { useListKeyboardNavigation } from '../utils'; -import { RevisionListTabType } from './HistoryListContainer'; import { HistoryListItem } from './HistoryListItem'; import { LegacyHistoryEntry, ListGroup } from './utils'; type Props = { - selectedTab: RevisionListTabType; sessionHistory: ListGroup[]; setSelectedRevision: StateUpdater< HistoryEntry | LegacyHistoryEntry | undefined @@ -28,7 +26,6 @@ type Props = { export const SessionHistoryList: FunctionComponent = ({ sessionHistory, - selectedTab, setSelectedRevision, setSelectedRemoteEntry, }) => { @@ -67,13 +64,6 @@ export const SessionHistoryList: FunctionComponent = ({ setSelectedRevision, ]); - useEffect(() => { - if (selectedTab === RevisionListTabType.Session) { - selectFirstEntry(); - sessionHistoryListRef.current?.focus(); - } - }, [selectFirstEntry, selectedTab]); - return (
= observer( +export const SmartViewsList: FunctionComponent = observer( ({ appState }) => { - const allTags = appState.tags.smartTags; + const allViews = appState.tags.smartViews; return ( <> - {allTags.map((tag) => { + {allViews.map((view) => { return ( - diff --git a/app/assets/javascripts/components/Tags/SmartTagsListItem.tsx b/app/assets/javascripts/components/Tags/SmartViewsListItem.tsx similarity index 69% rename from app/assets/javascripts/components/Tags/SmartTagsListItem.tsx rename to app/assets/javascripts/components/Tags/SmartViewsListItem.tsx index d6405fd7d..841c7c540 100644 --- a/app/assets/javascripts/components/Tags/SmartTagsListItem.tsx +++ b/app/assets/javascripts/components/Tags/SmartViewsListItem.tsx @@ -2,13 +2,18 @@ import { Icon } from '@/components/Icon'; import { FeaturesState } from '@/ui_models/app_state/features_state'; import { TagsState } from '@/ui_models/app_state/tags_state'; import '@reach/tooltip/styles.css'; -import { SNSmartTag, IconType } from '@standardnotes/snjs'; +import { + SmartView, + SystemViewId, + IconType, + isSystemView, +} from '@standardnotes/snjs'; import { observer } from 'mobx-react-lite'; import { FunctionComponent } from 'preact'; import { useCallback, useEffect, useRef, useState } from 'preact/hooks'; type Props = { - tag: SNSmartTag; + view: SmartView; tagsState: TagsState; features: FeaturesState; }; @@ -16,40 +21,44 @@ type Props = { const PADDING_BASE_PX = 14; const PADDING_PER_LEVEL_PX = 21; -const smartTagIconType = (tag: SNSmartTag): IconType => { - if (tag.isAllTag) { +const smartViewIconType = (view: SmartView): IconType => { + if (view.uuid === SystemViewId.AllNotes) { return 'notes'; } - if (tag.isArchiveTag) { + if (view.uuid === SystemViewId.ArchivedNotes) { return 'archive'; } - if (tag.isTrashTag) { + if (view.uuid === SystemViewId.TrashedNotes) { return 'trash'; } + if (view.uuid === SystemViewId.UntaggedNotes) { + return 'hashtag-off'; + } + return 'hashtag'; }; -export const SmartTagsListItem: FunctionComponent = observer( - ({ tag, tagsState, features }) => { - const [title, setTitle] = useState(tag.title || ''); +export const SmartViewsListItem: FunctionComponent = observer( + ({ view, tagsState }) => { + const [title, setTitle] = useState(view.title || ''); const inputRef = useRef(null); const level = 0; - const isSelected = tagsState.selected === tag; - const isEditing = tagsState.editingTag === tag; + const isSelected = tagsState.selected === view; + const isEditing = tagsState.editingTag === view; useEffect(() => { - setTitle(tag.title || ''); - }, [setTitle, tag]); + setTitle(view.title || ''); + }, [setTitle, view]); const selectCurrentTag = useCallback(() => { - tagsState.selected = tag; - }, [tagsState, tag]); + tagsState.selected = view; + }, [tagsState, view]); const onBlur = useCallback(() => { - tagsState.save(tag, title); - setTitle(tag.title); - }, [tagsState, tag, title, setTitle]); + tagsState.save(view, title); + setTitle(view.title); + }, [tagsState, view, title, setTitle]); const onInput = useCallback( (e: Event) => { @@ -76,19 +85,19 @@ export const SmartTagsListItem: FunctionComponent = observer( }, [inputRef, isEditing]); const onClickRename = useCallback(() => { - tagsState.editingTag = tag; - }, [tagsState, tag]); + tagsState.editingTag = view; + }, [tagsState, view]); const onClickSave = useCallback(() => { inputRef.current?.blur(); }, [inputRef]); const onClickDelete = useCallback(() => { - tagsState.remove(tag, true); - }, [tagsState, tag]); + tagsState.remove(view, true); + }, [tagsState, view]); - const isFaded = !tag.isAllTag; - const iconType = smartTagIconType(tag); + const isFaded = false; + const iconType = smartViewIconType(view); return ( <> @@ -101,7 +110,7 @@ export const SmartTagsListItem: FunctionComponent = observer( paddingLeft: `${level * PADDING_PER_LEVEL_PX + PADDING_BASE_PX}px`, }} > - {!tag.errorDecrypting ? ( + {!view.errorDecrypting ? (
= observer( = observer( ref={inputRef} />
- {tag.isAllTag && tagsState.allNotesCount} + {view.uuid === SystemViewId.AllNotes && tagsState.allNotesCount}
) : null} - {!tag.isSystemSmartTag && ( + {!isSystemView(view) && (
- {tag.conflictOf && ( + {view.conflictOf && (
- Conflicted Copy {tag.conflictOf} + Conflicted Copy {view.conflictOf}
)} - {tag.errorDecrypting && !tag.waitingForKey && ( + {view.errorDecrypting && !view.waitingForKey && (
Missing Keys
)} - {tag.errorDecrypting && tag.waitingForKey && ( + {view.errorDecrypting && view.waitingForKey && (
Waiting For Keys
diff --git a/app/assets/javascripts/components/Tags/SmartTagsSection.tsx b/app/assets/javascripts/components/Tags/SmartViewsSection.tsx similarity index 61% rename from app/assets/javascripts/components/Tags/SmartTagsSection.tsx rename to app/assets/javascripts/components/Tags/SmartViewsSection.tsx index 2032aa6ce..6aedcd1f5 100644 --- a/app/assets/javascripts/components/Tags/SmartTagsSection.tsx +++ b/app/assets/javascripts/components/Tags/SmartViewsSection.tsx @@ -1,17 +1,17 @@ import { AppState } from '@/ui_models/app_state'; import { observer } from 'mobx-react-lite'; import { FunctionComponent } from 'preact'; -import { SmartTagsList } from './SmartTagsList'; +import { SmartViewsList } from './SmartViewsList'; type Props = { appState: AppState; }; -export const SmartTagsSection: FunctionComponent = observer( +export const SmartViewsSection: FunctionComponent = observer( ({ appState }) => { return (
- +
); } diff --git a/app/assets/javascripts/components/Tags/TagContextMenu.tsx b/app/assets/javascripts/components/Tags/TagContextMenu.tsx index 51054d34e..04c2a5ca6 100644 --- a/app/assets/javascripts/components/Tags/TagContextMenu.tsx +++ b/app/assets/javascripts/components/Tags/TagContextMenu.tsx @@ -7,6 +7,7 @@ import { Menu } from '../menu/Menu'; import { MenuItem, MenuItemType } from '../menu/MenuItem'; import { usePremiumModal } from '../Premium'; import { useCloseOnBlur } from '../utils'; +import { SNTag } from '@standardnotes/snjs'; type Props = { appState: AppState; @@ -17,7 +18,7 @@ export const TagsContextMenu: FunctionComponent = observer( const premiumModal = usePremiumModal(); const selectedTag = appState.tags.selected; - if (!selectedTag) { + if (!selectedTag || !(selectedTag instanceof SNTag)) { return null; } diff --git a/app/assets/javascripts/hooks/manageSubscription.ts b/app/assets/javascripts/hooks/manageSubscription.ts index 5cf561035..8af7197a5 100644 --- a/app/assets/javascripts/hooks/manageSubscription.ts +++ b/app/assets/javascripts/hooks/manageSubscription.ts @@ -5,8 +5,6 @@ export function openSubscriptionDashboard(application: SNApplication): void { if (!token) { return; } - window.open( - `${window._dashboard_url}?subscription_token=${token}` - ); + window.open(`${window.dashboardUrl}?subscription_token=${token}`); }); } diff --git a/app/assets/javascripts/preferences/panes/Appearance.tsx b/app/assets/javascripts/preferences/panes/Appearance.tsx index 85c7f56ce..854c66fdc 100644 --- a/app/assets/javascripts/preferences/panes/Appearance.tsx +++ b/app/assets/javascripts/preferences/panes/Appearance.tsx @@ -32,7 +32,7 @@ export const Appearance: FunctionComponent = observer( ({ application }) => { const premiumModal = usePremiumModal(); const isEntitledToMidnightTheme = - application.getFeatureStatus(FeatureIdentifier.MidnightTheme) === + application.features.getFeatureStatus(FeatureIdentifier.MidnightTheme) === FeatureStatus.Entitled; const [themeItems, setThemeItems] = useState([]); diff --git a/app/assets/javascripts/preferences/panes/Extensions.tsx b/app/assets/javascripts/preferences/panes/Extensions.tsx index ae8f6756c..b70f06e73 100644 --- a/app/assets/javascripts/preferences/panes/Extensions.tsx +++ b/app/assets/javascripts/preferences/panes/Extensions.tsx @@ -58,7 +58,7 @@ export const Extensions: FunctionComponent<{ }; const submitExtensionUrl = async (url: string) => { - const component = await application.downloadExternalFeature(url); + const component = await application.features.downloadExternalFeature(url); if (component) { setConfirmableExtension(component); } diff --git a/app/assets/javascripts/preferences/panes/account/offlineSubscription.tsx b/app/assets/javascripts/preferences/panes/account/offlineSubscription.tsx index 5744600c3..7d9e83f9e 100644 --- a/app/assets/javascripts/preferences/panes/account/offlineSubscription.tsx +++ b/app/assets/javascripts/preferences/panes/account/offlineSubscription.tsx @@ -27,15 +27,17 @@ export const OfflineSubscription: FunctionalComponent = observer( useState(false); useEffect(() => { - if (application.hasOfflineRepo()) { + if (application.features.hasOfflineRepo()) { setHasUserPreviouslyStoredCode(true); } }, [application]); const shouldShowOfflineSubscription = () => { - return !application.hasAccount() || + return ( + !application.hasAccount() || application.isThirdPartyHostUsed() || - hasUserPreviouslyStoredCode; + hasUserPreviouslyStoredCode + ); }; const handleSubscriptionCodeSubmit = async ( @@ -43,7 +45,9 @@ export const OfflineSubscription: FunctionalComponent = observer( ) => { event.preventDefault(); - const result = await application.setOfflineFeaturesCode(activationCode); + const result = await application.features.setOfflineFeaturesCode( + activationCode + ); if (result?.error) { await application.alertService.alert(result.error); @@ -55,7 +59,7 @@ export const OfflineSubscription: FunctionalComponent = observer( }; const handleRemoveOfflineKey = async () => { - await application.deleteOfflineFeatureRepo(); + await application.features.deleteOfflineFeatureRepo(); setIsSuccessfullyActivated(false); setHasUserPreviouslyStoredCode(false); diff --git a/app/assets/javascripts/preferences/panes/account/subscription/NoSubscription.tsx b/app/assets/javascripts/preferences/panes/account/subscription/NoSubscription.tsx index b2196a42f..9c2baa668 100644 --- a/app/assets/javascripts/preferences/panes/account/subscription/NoSubscription.tsx +++ b/app/assets/javascripts/preferences/panes/account/subscription/NoSubscription.tsx @@ -1,21 +1,24 @@ -import { FunctionalComponent } from "preact"; +import { FunctionalComponent } from 'preact'; import { LinkButton, Text } from '@/preferences/components'; import { Button } from '@/components/Button'; -import { WebApplication } from "@/ui_models/application"; -import { useState } from "preact/hooks"; -import { loadPurchaseFlowUrl } from "@/purchaseFlow/PurchaseFlowWrapper"; +import { WebApplication } from '@/ui_models/application'; +import { useState } from 'preact/hooks'; +import { loadPurchaseFlowUrl } from '@/purchaseFlow/PurchaseFlowWrapper'; export const NoSubscription: FunctionalComponent<{ application: WebApplication; }> = ({ application }) => { const [isLoadingPurchaseFlow, setIsLoadingPurchaseFlow] = useState(false); - const [purchaseFlowError, setPurchaseFlowError] = useState(undefined); + const [purchaseFlowError, setPurchaseFlowError] = useState< + string | undefined + >(undefined); const onPurchaseClick = async () => { - const errorMessage = 'There was an error when attempting to redirect you to the subscription page.'; + const errorMessage = + 'There was an error when attempting to redirect you to the subscription page.'; setIsLoadingPurchaseFlow(true); try { - if (!await loadPurchaseFlowUrl(application)) { + if (!(await loadPurchaseFlowUrl(application))) { setPurchaseFlowError(errorMessage); } } catch (e) { @@ -29,29 +32,25 @@ export const NoSubscription: FunctionalComponent<{ <> You don't have a Standard Notes subscription yet. {isLoadingPurchaseFlow && ( - - Redirecting you to the subscription page... - + Redirecting you to the subscription page... )} {purchaseFlowError && ( - - {purchaseFlowError} - + {purchaseFlowError} )}
- {application.hasAccount() && + {application.hasAccount() && (
); diff --git a/app/assets/javascripts/preferences/panes/backups-segments/EmailBackups.tsx b/app/assets/javascripts/preferences/panes/backups-segments/EmailBackups.tsx index 804e0d98b..edc124389 100644 --- a/app/assets/javascripts/preferences/panes/backups-segments/EmailBackups.tsx +++ b/app/assets/javascripts/preferences/panes/backups-segments/EmailBackups.tsx @@ -62,7 +62,7 @@ export const EmailBackups = observer(({ application }: Props) => { }, [application]); useEffect(() => { - const emailBackupsFeatureStatus = application.getFeatureStatus( + const emailBackupsFeatureStatus = application.features.getFeatureStatus( FeatureIdentifier.DailyEmailBackup ); setIsEntitledToEmailBackups( diff --git a/app/assets/javascripts/preferences/panes/backups-segments/cloud-backups/index.tsx b/app/assets/javascripts/preferences/panes/backups-segments/cloud-backups/index.tsx index 65f768e8f..7ac3e6fd7 100644 --- a/app/assets/javascripts/preferences/panes/backups-segments/cloud-backups/index.tsx +++ b/app/assets/javascripts/preferences/panes/backups-segments/cloud-backups/index.tsx @@ -65,13 +65,13 @@ export const CloudLink: FunctionComponent = ({ application }) => { }, [application]); useEffect(() => { - const dailyDropboxBackupStatus = application.getFeatureStatus( + const dailyDropboxBackupStatus = application.features.getFeatureStatus( FeatureIdentifier.DailyDropboxBackup ); - const dailyGdriveBackupStatus = application.getFeatureStatus( + const dailyGdriveBackupStatus = application.features.getFeatureStatus( FeatureIdentifier.DailyGDriveBackup ); - const dailyOneDriveBackupStatus = application.getFeatureStatus( + const dailyOneDriveBackupStatus = application.features.getFeatureStatus( FeatureIdentifier.DailyOneDriveBackup ); const isCloudBackupsAllowed = [ diff --git a/app/assets/javascripts/preferences/panes/extensions-segments/ExtensionItem.tsx b/app/assets/javascripts/preferences/panes/extensions-segments/ExtensionItem.tsx index c6f343bbf..7e231b761 100644 --- a/app/assets/javascripts/preferences/panes/extensions-segments/ExtensionItem.tsx +++ b/app/assets/javascripts/preferences/panes/extensions-segments/ExtensionItem.tsx @@ -74,7 +74,9 @@ export const ExtensionItem: FunctionComponent = ({ }; const localInstallable = extension.package_info.download_url; - const isThirParty = application.isThirdPartyFeature(extension.identifier); + const isThirParty = application.features.isThirdPartyFeature( + extension.identifier + ); return ( diff --git a/app/assets/javascripts/purchaseFlow/PurchaseFlowWrapper.tsx b/app/assets/javascripts/purchaseFlow/PurchaseFlowWrapper.tsx index d3fb5f302..3e77e77e5 100644 --- a/app/assets/javascripts/purchaseFlow/PurchaseFlowWrapper.tsx +++ b/app/assets/javascripts/purchaseFlow/PurchaseFlowWrapper.tsx @@ -16,11 +16,11 @@ export const getPurchaseFlowUrl = async ( const currentUrl = window.location.origin; const successUrl = isDesktopApplication() ? `standardnotes://` : currentUrl; if (application.noAccount()) { - return `${window._purchase_url}/offline?&success_url=${successUrl}`; + return `${window.purchaseUrl}/offline?&success_url=${successUrl}`; } const token = await application.getNewSubscriptionToken(); if (token) { - return `${window._purchase_url}?subscription_token=${token}&success_url=${successUrl}`; + return `${window.purchaseUrl}?subscription_token=${token}&success_url=${successUrl}`; } return undefined; }; diff --git a/app/assets/javascripts/services/alertService.ts b/app/assets/javascripts/services/alertService.ts index 5eec432ac..b67bef491 100644 --- a/app/assets/javascripts/services/alertService.ts +++ b/app/assets/javascripts/services/alertService.ts @@ -99,6 +99,7 @@ export class AlertService implements SNAlertService { const alert = new SKAlert({ title: title && sanitizeHtmlString(title), text: sanitizeHtmlString(text), + buttons: [], }); alert.present(); return () => { diff --git a/app/assets/javascripts/services/desktopManager.ts b/app/assets/javascripts/services/desktopManager.ts index 342fe5046..f5f8c3e02 100644 --- a/app/assets/javascripts/services/desktopManager.ts +++ b/app/assets/javascripts/services/desktopManager.ts @@ -14,6 +14,7 @@ import { import { WebAppEvent, WebApplication } from '@/ui_models/application'; import { isDesktopApplication } from '@/utils'; import { Bridge, ElectronDesktopCallbacks } from './bridge'; +import { InternalEventBus } from '@standardnotes/services'; /** * An interface used by the Desktop application to interact with SN @@ -31,7 +32,7 @@ export class DesktopManager lastSearchedText?: string; constructor(application: WebApplication, private bridge: Bridge) { - super(application); + super(application, new InternalEventBus()); } get webApplication() { diff --git a/app/assets/javascripts/services/errorReporting.ts b/app/assets/javascripts/services/errorReporting.ts index e265d2e20..577769740 100644 --- a/app/assets/javascripts/services/errorReporting.ts +++ b/app/assets/javascripts/services/errorReporting.ts @@ -25,7 +25,7 @@ export function startErrorReporting(): void { */ isNullOrUndefined(disableErrorReporting) || disableErrorReporting || - !window._bugsnag_api_key + !window.bugsnagApiKey ) { SNLog.onError = console.error; return; @@ -41,7 +41,7 @@ export function startErrorReporting(): void { } Bugsnag.start({ - apiKey: window._bugsnag_api_key, + apiKey: window.bugsnagApiKey, appType: isDesktopApplication() ? 'desktop' : 'web', appVersion: getDesktopVersion() || WebAppVersion, collectUserIp: false, diff --git a/app/assets/javascripts/services/themeManager.ts b/app/assets/javascripts/services/themeManager.ts index 11d0262c8..81cb3218c 100644 --- a/app/assets/javascripts/services/themeManager.ts +++ b/app/assets/javascripts/services/themeManager.ts @@ -12,6 +12,7 @@ import { PayloadSource, PrefKey, } from '@standardnotes/snjs'; +import { InternalEventBus } from '@standardnotes/services'; const CACHED_THEMES_KEY = 'cachedThemes'; @@ -21,7 +22,7 @@ export class ThemeManager extends ApplicationService { private unregisterStream!: () => void; constructor(application: WebApplication) { - super(application); + super(application, new InternalEventBus()); this.colorSchemeEventHandler = this.colorSchemeEventHandler.bind(this); } @@ -127,7 +128,9 @@ export class ThemeManager extends ApplicationService { this.deactivateTheme(themeUuid); hasChange = true; } else { - const status = this.application.getFeatureStatus(theme.identifier); + const status = this.application.features.getFeatureStatus( + theme.identifier + ); if (status !== FeatureStatus.Entitled) { if (theme.active) { this.application.toggleTheme(theme); @@ -212,7 +215,7 @@ export class ThemeManager extends ApplicationService { if ( !skipEntitlementCheck && - this.application.getFeatureStatus(theme.identifier) !== + this.application.features.getFeatureStatus(theme.identifier) !== FeatureStatus.Entitled ) { return; diff --git a/app/assets/javascripts/startApplication.ts b/app/assets/javascripts/startApplication.ts index 334973948..11afdfc4c 100644 --- a/app/assets/javascripts/startApplication.ts +++ b/app/assets/javascripts/startApplication.ts @@ -1,8 +1,9 @@ -import { Bridge } from "./services/bridge"; +import { Bridge } from './services/bridge'; export type StartApplication = ( defaultSyncServerHost: string, + defaultFilesHostHost: string, bridge: Bridge, enableUnfinishedFeatures: boolean, - webSocketUrl: string, + webSocketUrl: string ) => Promise; diff --git a/app/assets/javascripts/typings/stylekit.d.ts b/app/assets/javascripts/typings/stylekit.d.ts deleted file mode 100644 index 44b004f93..000000000 --- a/app/assets/javascripts/typings/stylekit.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare module '@standardnotes/stylekit'; diff --git a/app/assets/javascripts/ui_models/app_state/account_menu_state.ts b/app/assets/javascripts/ui_models/app_state/account_menu_state.ts index dbf7c5389..8360511b5 100644 --- a/app/assets/javascripts/ui_models/app_state/account_menu_state.ts +++ b/app/assets/javascripts/ui_models/app_state/account_menu_state.ts @@ -75,9 +75,9 @@ export class AccountMenuState { this.appEventListeners.push( this.application.addEventObserver(async () => { runInAction(() => { - if (isDev && window._devAccountServer) { - this.setServer(window._devAccountServer); - this.application.setCustomHost(window._devAccountServer); + if (isDev && window.devAccountServer) { + this.setServer(window.devAccountServer); + this.application.setCustomHost(window.devAccountServer); } else { this.setServer(this.application.getHost()); } diff --git a/app/assets/javascripts/ui_models/app_state/app_state.ts b/app/assets/javascripts/ui_models/app_state/app_state.ts index f406fec30..2e86701e9 100644 --- a/app/assets/javascripts/ui_models/app_state/app_state.ts +++ b/app/assets/javascripts/ui_models/app_state/app_state.ts @@ -11,8 +11,9 @@ import { PayloadSource, PrefKey, SNNote, - SNSmartTag, + SmartView, SNTag, + SystemViewId, } from '@standardnotes/snjs'; import pull from 'lodash/pull'; import { @@ -62,7 +63,7 @@ type ObserverCallback = (event: AppStateEvent, data?: any) => Promise; export class AppState { readonly enableUnfinishedFeatures: boolean = - window?._enable_unfinished_features; + window?.enabledUnfinishedFeatures; application: WebApplication; observers: ObserverCallback[] = []; @@ -241,7 +242,9 @@ export class AppState { const selectedTag = this.selectedTag; const activeRegularTagUuid = - selectedTag && !selectedTag.isSmartTag ? selectedTag.uuid : undefined; + selectedTag && selectedTag instanceof SNTag + ? selectedTag.uuid + : undefined; await this.application.noteControllerGroup.createNoteView( undefined, @@ -313,11 +316,11 @@ export class AppState { ); } - public get selectedTag(): SNTag | SNSmartTag | undefined { + public get selectedTag(): SNTag | SmartView | undefined { return this.tags.selected; } - public set selectedTag(tag: SNTag | SNSmartTag | undefined) { + public set selectedTag(tag: SNTag | SmartView | undefined) { this.tags.selected = tag; } @@ -341,13 +344,19 @@ export class AppState { this.closeNoteController(noteController); } else if ( note.trashed && - !selectedTag?.isTrashTag && + !( + selectedTag instanceof SmartView && + selectedTag.uuid === SystemViewId.TrashedNotes + ) && !this.searchOptions.includeTrashed ) { this.closeNoteController(noteController); } else if ( note.archived && - !selectedTag?.isArchiveTag && + !( + selectedTag instanceof SmartView && + selectedTag.uuid === SystemViewId.ArchivedNotes + ) && !this.searchOptions.includeArchived && !this.application.getPreference(PrefKey.NotesShowArchived, false) ) { diff --git a/app/assets/javascripts/ui_models/app_state/features_state.ts b/app/assets/javascripts/ui_models/app_state/features_state.ts index 25ad9026f..67b47a9b0 100644 --- a/app/assets/javascripts/ui_models/app_state/features_state.ts +++ b/app/assets/javascripts/ui_models/app_state/features_state.ts @@ -25,22 +25,22 @@ export const SMART_TAGS_FEATURE_NAME = 'Smart Tags'; */ export class FeaturesState { readonly enableUnfinishedFeatures: boolean = - window?._enable_unfinished_features; + window?.enabledUnfinishedFeatures; _hasFolders = false; - _hasSmartTags = false; + _hasSmartViews = false; _premiumAlertFeatureName: string | undefined; private unsub: () => void; constructor(private application: WebApplication) { this._hasFolders = this.hasNativeFolders(); - this._hasSmartTags = this.hasNativeSmartTags(); + this._hasSmartViews = this.hasNativeSmartViews(); this._premiumAlertFeatureName = undefined; makeObservable(this, { _hasFolders: observable, - _hasSmartTags: observable, + _hasSmartViews: observable, hasFolders: computed, _premiumAlertFeatureName: observable, showPremiumAlert: action, @@ -56,7 +56,7 @@ export class FeaturesState { case ApplicationEvent.Launched: runInAction(() => { this._hasFolders = this.hasNativeFolders(); - this._hasSmartTags = this.hasNativeSmartTags(); + this._hasSmartViews = this.hasNativeSmartViews(); }); break; default: @@ -73,8 +73,8 @@ export class FeaturesState { return this._hasFolders; } - public get hasSmartTags(): boolean { - return this._hasSmartTags; + public get hasSmartViews(): boolean { + return this._hasSmartViews; } public async showPremiumAlert(featureName: string): Promise { @@ -87,15 +87,15 @@ export class FeaturesState { } private hasNativeFolders(): boolean { - const status = this.application.getFeatureStatus( + const status = this.application.features.getFeatureStatus( FeatureIdentifier.TagNesting ); return status === FeatureStatus.Entitled; } - private hasNativeSmartTags(): boolean { - const status = this.application.getFeatureStatus( + private hasNativeSmartViews(): boolean { + const status = this.application.features.getFeatureStatus( FeatureIdentifier.SmartFilters ); diff --git a/app/assets/javascripts/ui_models/app_state/notes_view_state.ts b/app/assets/javascripts/ui_models/app_state/notes_view_state.ts index ec26fc710..c22e3ce1c 100644 --- a/app/assets/javascripts/ui_models/app_state/notes_view_state.ts +++ b/app/assets/javascripts/ui_models/app_state/notes_view_state.ts @@ -5,8 +5,10 @@ import { findInArray, NotesDisplayCriteria, PrefKey, + SmartView, SNNote, SNTag, + SystemViewId, UuidString, } from '@standardnotes/snjs'; import { @@ -79,7 +81,10 @@ export class NotesViewState { const discarded = activeNote.deleted || activeNote.trashed; if ( discarded && - !this.appState?.selectedTag?.isTrashTag && + !( + this.appState.selectedTag instanceof SmartView && + this.appState.selectedTag?.uuid === SystemViewId.TrashedNotes + ) && !this.appState?.searchOptions.includeTrashed ) { this.selectNextOrCreateNew(); @@ -116,7 +121,8 @@ export class NotesViewState { this.reloadNotes(); if ( this.notes.length === 0 && - this.appState.selectedTag?.isAllTag && + this.appState.selectedTag instanceof SmartView && + this.appState.selectedTag.uuid === SystemViewId.AllNotes && this.noteFilterText === '' && !this.appState.notes.activeNoteController ) { @@ -246,7 +252,8 @@ export class NotesViewState { const criteria = NotesDisplayCriteria.Create({ sortProperty: this.displayOptions.sortBy as CollectionSort, sortDirection: this.displayOptions.sortReverse ? 'asc' : 'dsc', - tags: tag ? [tag] : [], + tags: tag instanceof SNTag ? [tag] : [], + views: tag instanceof SmartView ? [tag] : [], includeArchived, includeTrashed, includePinned: !this.displayOptions.hidePinned, @@ -353,7 +360,11 @@ export class NotesViewState { createPlaceholderNote = () => { const selectedTag = this.appState.selectedTag; - if (selectedTag && selectedTag.isSmartTag && !selectedTag.isAllTag) { + if ( + selectedTag && + selectedTag instanceof SmartView && + selectedTag.uuid !== SystemViewId.AllNotes + ) { return; } return this.createNewNote(); diff --git a/app/assets/javascripts/ui_models/app_state/tags_state.ts b/app/assets/javascripts/ui_models/app_state/tags_state.ts index 4ba4c12b6..05dac66bb 100644 --- a/app/assets/javascripts/ui_models/app_state/tags_state.ts +++ b/app/assets/javascripts/ui_models/app_state/tags_state.ts @@ -9,10 +9,11 @@ import { ContentType, MessageData, SNApplication, - SNSmartTag, + SmartView, SNTag, TagMutator, UuidString, + isSystemView, } from '@standardnotes/snjs'; import { action, @@ -25,7 +26,7 @@ import { import { WebApplication } from '../application'; import { FeaturesState, SMART_TAGS_FEATURE_NAME } from './features_state'; -type AnyTag = SNTag | SNSmartTag; +type AnyTag = SNTag | SmartView; const rootTags = (application: SNApplication): SNTag[] => { const hasNoParent = (tag: SNTag) => !application.getTagParent(tag); @@ -71,11 +72,11 @@ const isValidFutureSiblings = ( export class TagsState { tags: SNTag[] = []; - smartTags: SNSmartTag[] = []; + smartViews: SmartView[] = []; allNotesCount_ = 0; selected_: AnyTag | undefined; previouslySelected_: AnyTag | undefined; - editing_: SNTag | undefined; + editing_: SNTag | SmartView | undefined; addingSubtagTo: SNTag | undefined; contextMenuOpen = false; @@ -100,12 +101,12 @@ export class TagsState { this.editing_ = undefined; this.addingSubtagTo = undefined; - this.smartTags = this.application.getSmartTags(); - this.selected_ = this.smartTags[0]; + this.smartViews = this.application.getSmartViews(); + this.selected_ = this.smartViews[0]; makeObservable(this, { tags: observable.ref, - smartTags: observable.ref, + smartViews: observable.ref, hasAtLeastOneFolder: computed, allNotesCount_: observable, allNotesCount: computed, @@ -144,28 +145,28 @@ export class TagsState { appEventListeners.push( this.application.streamItems( - [ContentType.Tag, ContentType.SmartTag], + [ContentType.Tag, ContentType.SmartView], (items) => { runInAction(() => { - this.tags = this.application.getDisplayableItems( + this.tags = this.application.getDisplayableItems( ContentType.Tag - ) as SNTag[]; - this.smartTags = this.application.getSmartTags(); + ); + this.smartViews = this.application.getSmartViews(); const selectedTag = this.selected_; - if (selectedTag) { + if (selectedTag && !isSystemView(selectedTag as SmartView)) { const matchingTag = items.find( (candidate) => candidate.uuid === selectedTag.uuid - ); + ) as AnyTag; if (matchingTag) { if (matchingTag.deleted) { - this.selected_ = this.smartTags[0]; + this.selected_ = this.smartViews[0]; } else { - this.selected_ = matchingTag as AnyTag; + this.selected_ = matchingTag; } } } else { - this.selected_ = this.smartTags[0]; + this.selected_ = this.smartViews[0]; } }); } @@ -193,7 +194,9 @@ export class TagsState { return; } - const createdTag = await this.application.createTagOrSmartTag(title); + const createdTag = (await this.application.createTagOrSmartView( + title + )) as SNTag; const futureSiblings = this.application.getTagChildren(parent); @@ -294,7 +297,10 @@ export class TagsState { } public get allLocalRootTags(): SNTag[] { - if (this.editing_ && this.application.isTemplateItem(this.editing_)) { + if ( + this.editing_ instanceof SNTag && + this.application.isTemplateItem(this.editing_) + ) { return [this.editing_, ...this.rootTags]; } return this.rootTags; @@ -309,9 +315,7 @@ export class TagsState { return []; } - const children = this.application - .getTagChildren(tag) - .filter((tag) => !tag.isSmartTag); + const children = this.application.getTagChildren(tag); const childrenUuids = children.map((childTag) => childTag.uuid); const childrenTags = this.tags.filter((tag) => @@ -414,11 +418,11 @@ export class TagsState { return this.selected_?.uuid; } - public get editingTag(): SNTag | undefined { + public get editingTag(): SNTag | SmartView | undefined { return this.editing_; } - public set editingTag(editingTag: SNTag | undefined) { + public set editingTag(editingTag: SNTag | SmartView | undefined) { this.editing_ = editingTag; this.selected = editingTag; } @@ -442,11 +446,11 @@ export class TagsState { public undoCreateNewTag() { this.editing_ = undefined; - const previousTag = this.previouslySelected_ || this.smartTags[0]; + const previousTag = this.previouslySelected_ || this.smartViews[0]; this.selected = previousTag; } - public async remove(tag: SNTag, userTriggered: boolean) { + public async remove(tag: SNTag | SmartView, userTriggered: boolean) { let shouldDelete = !userTriggered; if (userTriggered) { shouldDelete = await confirmDialog({ @@ -456,16 +460,17 @@ export class TagsState { } if (shouldDelete) { this.application.deleteItem(tag); - this.selected = this.smartTags[0]; + this.selected = this.smartViews[0]; } } - public async save(tag: SNTag, newTitle: string) { + public async save(tag: SNTag | SmartView, newTitle: string) { const hasEmptyTitle = newTitle.length === 0; const hasNotChangedTitle = newTitle === tag.title; const isTemplateChange = this.application.isTemplateItem(tag); - const siblings = tagSiblings(this.application, tag); + const siblings = + tag instanceof SNTag ? tagSiblings(this.application, tag) : []; const hasDuplicatedTitle = siblings.some( (other) => other.title.toLowerCase() === newTitle.toLowerCase() ); @@ -492,16 +497,16 @@ export class TagsState { } if (isTemplateChange) { - const isSmartTagTitle = this.application.isSmartTagTitle(newTitle); + const isSmartViewTitle = this.application.isSmartViewTitle(newTitle); - if (isSmartTagTitle) { - if (!this.features.hasSmartTags) { + if (isSmartViewTitle) { + if (!this.features.hasSmartViews) { await this.features.showPremiumAlert(SMART_TAGS_FEATURE_NAME); return; } } - const insertedTag = await this.application.createTagOrSmartTag(newTitle); + const insertedTag = await this.application.createTagOrSmartView(newTitle); this.application.sync(); runInAction(() => { this.selected = insertedTag as SNTag; @@ -529,7 +534,7 @@ export class TagsState { if ( item.content_type === ContentType.Tag || - item.content_type === ContentType.SmartTag + item.content_type === ContentType.SmartView ) { const matchingTag = this.application.findItem(item.uuid); @@ -539,7 +544,7 @@ export class TagsState { } } } else if (action === ComponentAction.ClearSelection) { - this.selected = this.smartTags[0]; + this.selected = this.smartViews[0]; } } diff --git a/app/assets/javascripts/ui_models/application.ts b/app/assets/javascripts/ui_models/application.ts index 32b5f24a5..54254e3fe 100644 --- a/app/assets/javascripts/ui_models/application.ts +++ b/app/assets/javascripts/ui_models/application.ts @@ -48,23 +48,24 @@ export class WebApplication extends SNApplication { platform: Platform, identifier: string, defaultSyncServerHost: string, + defaultFilesHostHost: string, public bridge: Bridge, webSocketUrl: string, runtime: Runtime ) { - super( - bridge.environment, - platform, - deviceInterface, - WebCrypto, - new AlertService(), + super({ + environment: bridge.environment, + platform: platform, + deviceInterface: deviceInterface, + crypto: WebCrypto, + alertService: new AlertService(), identifier, - [], - defaultSyncServerHost, - bridge.appVersion, - webSocketUrl, - runtime - ); + defaultHost: defaultSyncServerHost, + defaultFilesHost: defaultFilesHostHost, + appVersion: bridge.appVersion, + webSocketUrl: webSocketUrl, + runtime, + }); deviceInterface.setApplication(this); this.noteControllerGroup = new NoteGroupController(this); this.iconsController = new IconsController(); diff --git a/app/assets/javascripts/ui_models/application_group.ts b/app/assets/javascripts/ui_models/application_group.ts index d12fdc0c4..d062d0a24 100644 --- a/app/assets/javascripts/ui_models/application_group.ts +++ b/app/assets/javascripts/ui_models/application_group.ts @@ -16,10 +16,12 @@ import { IOService } from '@/services/ioService'; import { AutolockService } from '@/services/autolock_service'; import { StatusManager } from '@/services/statusManager'; import { ThemeManager } from '@/services/themeManager'; +import { InternalEventBus } from '@standardnotes/services'; export class ApplicationGroup extends SNApplicationGroup { constructor( private defaultSyncServerHost: string, + private defaultFilesHostHost: string, private bridge: Bridge, private runtime: Runtime, private webSocketUrl: string @@ -50,6 +52,7 @@ export class ApplicationGroup extends SNApplicationGroup { platform, descriptor.identifier, this.defaultSyncServerHost, + this.defaultFilesHostHost, this.bridge, this.webSocketUrl, this.runtime @@ -60,7 +63,10 @@ export class ApplicationGroup extends SNApplicationGroup { const io = new IOService( platform === Platform.MacWeb || platform === Platform.MacDesktop ); - const autolockService = new AutolockService(application); + const autolockService = new AutolockService( + application, + new InternalEventBus() + ); const statusManager = new StatusManager(); const themeService = new ThemeManager(application); application.setWebServices({ diff --git a/app/assets/javascripts/utils/calculateSubmenuStyle.tsx b/app/assets/javascripts/utils/calculateSubmenuStyle.tsx new file mode 100644 index 000000000..f6791f2a4 --- /dev/null +++ b/app/assets/javascripts/utils/calculateSubmenuStyle.tsx @@ -0,0 +1,77 @@ +import { + MAX_MENU_SIZE_MULTIPLIER, + MENU_MARGIN_FROM_APP_BORDER, +} from '@/constants'; + +export type SubmenuStyle = { + top?: number | 'auto'; + right?: number | 'auto'; + bottom: number | 'auto'; + left?: number | 'auto'; + visibility?: 'hidden' | 'visible'; + maxHeight: number | 'auto'; +}; + +export const calculateSubmenuStyle = ( + button: HTMLButtonElement | null, + menu?: HTMLDivElement | null +): SubmenuStyle | undefined => { + const defaultFontSize = window.getComputedStyle( + document.documentElement + ).fontSize; + const maxChangeEditorMenuSize = + parseFloat(defaultFontSize) * MAX_MENU_SIZE_MULTIPLIER; + const { clientWidth, clientHeight } = document.documentElement; + const buttonRect = button?.getBoundingClientRect(); + const buttonParentRect = button?.parentElement?.getBoundingClientRect(); + const menuBoundingRect = menu?.getBoundingClientRect(); + const footerElementRect = document + .getElementById('footer-bar') + ?.getBoundingClientRect(); + const footerHeightInPx = footerElementRect?.height ?? 0; + + let position: SubmenuStyle = { + bottom: 'auto', + maxHeight: 'auto', + }; + + if (buttonRect && buttonParentRect) { + let positionBottom = + clientHeight - buttonRect.bottom - buttonRect.height / 2; + + if (positionBottom < footerHeightInPx) { + positionBottom = footerHeightInPx + MENU_MARGIN_FROM_APP_BORDER; + } + + position = { + bottom: positionBottom, + visibility: 'hidden', + maxHeight: 'auto', + }; + + if (buttonRect.right + maxChangeEditorMenuSize > clientWidth) { + position.right = clientWidth - buttonRect.left; + } else { + position.left = buttonRect.right; + } + } + + if (menuBoundingRect?.height && buttonRect && position.bottom !== 'auto') { + position.visibility = 'visible'; + + if (menuBoundingRect.y < MENU_MARGIN_FROM_APP_BORDER) { + position.bottom = + position.bottom + menuBoundingRect.y - MENU_MARGIN_FROM_APP_BORDER * 2; + } + + if (footerElementRect && menuBoundingRect.height > footerElementRect.y) { + position.bottom = footerElementRect.height + MENU_MARGIN_FROM_APP_BORDER; + position.maxHeight = + clientHeight - + footerElementRect.height - + MENU_MARGIN_FROM_APP_BORDER * 2; + } + } + + return position; +}; diff --git a/app/assets/stylesheets/_editor.scss b/app/assets/stylesheets/_editor.scss index 61629478a..5548a570e 100644 --- a/app/assets/stylesheets/_editor.scss +++ b/app/assets/stylesheets/_editor.scss @@ -34,7 +34,7 @@ $heading-height: 75px; padding-bottom: 10px; padding-right: 14px; - border-bottom: none; + border-bottom: 1px solid var(--sn-stylekit-border-color); z-index: $z-index-editor-title-bar; height: auto; @@ -66,8 +66,8 @@ $heading-height: 75px; #save-status-container { position: relative; - min-width: 15ch; - max-width: 15ch; + min-width: 16ch; + max-width: 16ch; overflow: visible; margin-right: 20px; } @@ -118,7 +118,6 @@ $heading-height: 75px; border: none; outline: none; padding: 15px; - padding-top: 11px; font-size: var(--sn-stylekit-font-size-editor); resize: none; } diff --git a/app/assets/stylesheets/_sn.scss b/app/assets/stylesheets/_sn.scss index 10b7171b4..4c2fc3caa 100644 --- a/app/assets/stylesheets/_sn.scss +++ b/app/assets/stylesheets/_sn.scss @@ -32,22 +32,6 @@ text-decoration: underline; } -.sn-icon { - @extend .h-5; - @extend .w-5; - @extend .fill-current; - - &.sn-icon--small { - @extend .h-3\.5; - @extend .w-3\.5; - } - - &.sn-icon--mid { - @extend .w-4; - @extend .h-4; - } -} - .sn-dropdown { @extend .bg-default; @extend .rounded; @@ -257,9 +241,6 @@ .ml-3 { margin-left: 0.75rem; } -.ml-4 { - margin-left: 1rem; -} .mr-2\.5 { margin-right: 0.625rem; @@ -296,6 +277,10 @@ margin-top: 0; } +.mt-0\.5 { + margin-top: 0.125rem; +} + .mt-2\.5 { margin-top: 0.625rem; } @@ -435,6 +420,10 @@ min-height: 1.5rem; } +.min-h-16 { + min-height: 4rem; +} + .max-h-5 { max-height: 1.25rem; } @@ -575,10 +564,6 @@ padding-bottom: 2.25rem; } -.select-none { - user-select: none; -} - .placeholder-dark-red::placeholder { @extend .color-dark-red; } @@ -711,11 +696,6 @@ background: var(--sn-stylekit-grey-4); } -.sn-component .spinner-info { - border-color: var(--sn-stylekit-info-color); - border-right-color: transparent; -} - @keyframes slide-up { 0% { opacity: 1; @@ -899,10 +879,6 @@ } } -.flex-shrink-0 { - flex-shrink: 0; -} - .leading-140\% { line-height: 140%; } @@ -913,10 +889,6 @@ pointer-events: none; } -.flex-shrink-0 { - flex-shrink: 0; -} - .last\:hidden:last-child { display: none; } diff --git a/app/assets/stylesheets/_ui.scss b/app/assets/stylesheets/_ui.scss index c2e8fab59..155cc39fb 100644 --- a/app/assets/stylesheets/_ui.scss +++ b/app/assets/stylesheets/_ui.scss @@ -210,10 +210,6 @@ $screen-md-max: ($screen-lg-min - 1) !default; pointer-events: none; } -.fill-current { - fill: currentColor; -} - .font-editor { font-family: var(--sn-stylekit-editor-font-family); } diff --git a/app/views/application/app.html.erb b/app/views/application/app.html.erb index 9045c0643..582011651 100644 --- a/app/views/application/app.html.erb +++ b/app/views/application/app.html.erb @@ -31,13 +31,14 @@ <% if Rails.env.development? %> diff --git a/index.html b/index.html index dc8ed5e44..f2028cfeb 100644 --- a/index.html +++ b/index.html @@ -29,10 +29,11 @@ diff --git a/package.json b/package.json index 1c4e0eb67..74e55fbfe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "standard-notes-web", - "version": "3.11.2", + "version": "3.12.0", "license": "AGPL-3.0-or-later", "repository": { "type": "git", @@ -27,12 +27,15 @@ "@babel/preset-typescript": "^7.16.7", "@reach/disclosure": "^0.16.2", "@reach/visually-hidden": "^0.16.0", + "@standardnotes/responses": "^1.1.5", + "@standardnotes/services": "^1.4.0", + "@standardnotes/stylekit": "5.14.0", "@svgr/webpack": "^6.2.1", - "@types/jest": "^27.4.0", - "@types/lodash": "^4.14.178", + "@types/jest": "^27.4.1", + "@types/lodash": "^4.14.179", "@types/react": "^17.0.39", - "@typescript-eslint/eslint-plugin": "^5.12.1", - "@typescript-eslint/parser": "^5.12.1", + "@typescript-eslint/eslint-plugin": "^5.13.0", + "@typescript-eslint/parser": "^5.13.0", "apply-loader": "^2.0.0", "babel-eslint": "^10.1.0", "babel-loader": "^8.2.3", @@ -40,9 +43,9 @@ "copy-webpack-plugin": "^10.2.4", "css-loader": "^6.6.0", "dotenv": "^16.0.0", - "eslint": "^8.9.0", - "eslint-config-prettier": "^8.4.0", - "eslint-plugin-react": "^7.28.0", + "eslint": "^8.10.0", + "eslint-config-prettier": "^8.5.0", + "eslint-plugin-react": "^7.29.2", "eslint-plugin-react-hooks": "^4.3.0", "file-loader": "^6.2.0", "html-webpack-plugin": "^5.5.0", @@ -57,13 +60,12 @@ "pretty-quick": "^3.1.3", "sass-loader": "^12.6.0", "serve-static": "^1.14.2", - "@standardnotes/stylekit": "5.9.0", "svg-jest": "^1.0.1", "ts-jest": "^27.1.3", - "ts-loader": "^9.2.6", - "typescript": "4.5.5", + "ts-loader": "^9.2.7", + "typescript": "4.6.2", "typescript-eslint": "0.0.1-alpha.0", - "webpack": "^5.69.1", + "webpack": "^5.70.0", "webpack-cli": "^4.9.2", "webpack-dev-server": "^4.7.4", "webpack-merge": "^5.8.0" @@ -76,12 +78,12 @@ "@reach/dialog": "^0.16.2", "@reach/listbox": "^0.16.2", "@reach/tooltip": "^0.16.2", - "@standardnotes/components": "1.7.5", - "@standardnotes/features": "1.32.11", - "@standardnotes/snjs": "2.63.1", - "@standardnotes/settings": "^1.11.3", - "@standardnotes/sncrypto-web": "1.7.0", - "mobx": "^6.4.1", + "@standardnotes/components": "1.7.8", + "@standardnotes/features": "1.34.0", + "@standardnotes/settings": "^1.11.5", + "@standardnotes/sncrypto-web": "1.7.3", + "@standardnotes/snjs": "2.72.0", + "mobx": "^6.4.2", "mobx-react-lite": "^3.3.0", "preact": "^10.6.6", "qrcode.react": "^1.0.1", diff --git a/yarn.lock b/yarn.lock index aab7acb6f..11674449d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1804,10 +1804,10 @@ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.5.tgz#9283c9ce5b289a3c4f61c12757469e59377f81f3" integrity sha512-6nFkfkmSeV/rqSaS4oWHgmpnYw194f6hmWF5is6b0J1naJZoiD0NTc9AiUwPHvWsowkjuHErCZT1wa0jg+BLIA== -"@eslint/eslintrc@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.1.0.tgz#583d12dbec5d4f22f333f9669f7d0b7c7815b4d3" - integrity sha512-C1DfL7XX4nPqGd6jcP01W9pVM1HYCuUkFk1432D7F0v3JSlUIeOYn9oCoi3eoLZ+iwBSb29BMFxxny0YrrEZqg== +"@eslint/eslintrc@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.0.tgz#7ce1547a5c46dfe56e1e45c3c9ed18038c721c6a" + integrity sha512-igm9SjJHNEJRiUnecP/1R5T3wKLEJ7pL6e2P+GUSfCd0dGjPYYZve08uzw8L2J8foVHFz+NGu12JxRcU2gGo6w== dependencies: ajv "^6.12.4" debug "^4.3.2" @@ -2052,6 +2052,11 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@nanostores/preact@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@nanostores/preact/-/preact-0.1.3.tgz#aeac0a1d8de1e067bc0b156c1fdd62a6b7bf6069" + integrity sha512-uiX1ned0LrzASot+sPUjyJzr8Js3pX075omazgsSdLf0zPp4ss8xwTiuNh5FSKigTSQEVqZFiS+W8CnHIrX62A== + "@nodelib/fs.scandir@2.1.4": version "2.1.4" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69" @@ -2111,14 +2116,6 @@ prop-types "^15.7.2" tslib "^2.3.0" -"@reach/auto-id@0.15.2": - version "0.15.2" - resolved "https://registry.yarnpkg.com/@reach/auto-id/-/auto-id-0.15.2.tgz#289640b47545a32f3621469ba497ba5c040b349c" - integrity sha512-K7d5qhYBlBHIjy+IpSEAyMeB5VTZ9m0tZdr7xyNd5Fr6oeefHEvJiJGuQpubP5bDoe7ShC3y0VQGFmT0g7KcZg== - dependencies: - "@reach/utils" "0.15.2" - tslib "^2.3.0" - "@reach/auto-id@0.16.0": version "0.16.0" resolved "https://registry.yarnpkg.com/@reach/auto-id/-/auto-id-0.16.0.tgz#dfabc3227844e8c04f8e6e45203a8e14a8edbaed" @@ -2139,14 +2136,6 @@ tiny-warning "^1.0.3" tslib "^2.3.0" -"@reach/descendants@0.15.2": - version "0.15.2" - resolved "https://registry.yarnpkg.com/@reach/descendants/-/descendants-0.15.2.tgz#b0641f0bc864d91271364678dea51cf86b2e5c66" - integrity sha512-GdQXWVpscss89MOhWh+sL4TnIn0qX1y+Te3wE72aKQrz/QCR69JFEW4wftovmF7rFm4/kDZcp14lMy512U6VlA== - dependencies: - "@reach/utils" "0.15.2" - tslib "^2.3.0" - "@reach/descendants@0.16.1": version "0.16.1" resolved "https://registry.yarnpkg.com/@reach/descendants/-/descendants-0.16.1.tgz#fa3d89c0503565369707f32985d87eef61985d9f" @@ -2178,17 +2167,16 @@ tiny-warning "^1.0.3" tslib "^2.3.0" -"@reach/listbox@^0.15.0": - version "0.15.2" - resolved "https://registry.yarnpkg.com/@reach/listbox/-/listbox-0.15.2.tgz#21aacc5340deb1b819d522f7f7fd4caac093c8a4" - integrity sha512-bXXelcm+PvAWAmhHQEaEVU6IQvTieIdoYcIrs5JsKzH98M+pp940Gdm0d2uDcmFatx/I9OMTAsOTJ129RPECrA== +"@reach/dropdown@0.16.2": + version "0.16.2" + resolved "https://registry.yarnpkg.com/@reach/dropdown/-/dropdown-0.16.2.tgz#4aa7df0f716cb448d01bc020d54df595303d5fa6" + integrity sha512-l4nNiX6iUpMdHQNbZMhgW5APtw0AUwJuRnkqE93vkjvdtrYl/sNJy1Jr6cGG7TrZIABLSOsfwbXU3C+qwJ3ftQ== dependencies: - "@reach/auto-id" "0.15.2" - "@reach/descendants" "0.15.2" - "@reach/machine" "0.15.2" - "@reach/popover" "0.15.2" - "@reach/utils" "0.15.2" - prop-types "^15.7.2" + "@reach/auto-id" "0.16.0" + "@reach/descendants" "0.16.1" + "@reach/popover" "0.16.2" + "@reach/utils" "0.16.0" + tslib "^2.3.0" "@reach/listbox@^0.16.2": version "0.16.2" @@ -2202,15 +2190,6 @@ "@reach/utils" "0.16.0" prop-types "^15.7.2" -"@reach/machine@0.15.2": - version "0.15.2" - resolved "https://registry.yarnpkg.com/@reach/machine/-/machine-0.15.2.tgz#f1558e63a6b304e6cc12feefb0d0dd315b32c962" - integrity sha512-op8Duhp6rNCReZgdVScbIzoXMPFYP4nje6dvg4g2GKo8hUkyQpebsUFnUNNNv6NWdbmhIRiKHFlTgSl2gIlh5Q== - dependencies: - "@reach/utils" "0.15.2" - "@xstate/fsm" "1.4.0" - tslib "^2.3.0" - "@reach/machine@0.16.0": version "0.16.0" resolved "https://registry.yarnpkg.com/@reach/machine/-/machine-0.16.0.tgz#0504ba47ac09ed495bd341bf5fdd6625bcade0e3" @@ -2220,15 +2199,14 @@ "@xstate/fsm" "1.4.0" tslib "^2.3.0" -"@reach/menu-button@^0.15.1": - version "0.15.2" - resolved "https://registry.yarnpkg.com/@reach/menu-button/-/menu-button-0.15.2.tgz#00f91402be3ff23d3b4cfe377529f4f9e82a78fe" - integrity sha512-slEji1AnfnH134YDZSTwst4nZHYNrfyg9GF+A8p1+kGc8N3JsPysHc7uIUZ/IsK+PdaOCB+r9kuL1QWBgNO+jw== +"@reach/menu-button@^0.16.2": + version "0.16.2" + resolved "https://registry.yarnpkg.com/@reach/menu-button/-/menu-button-0.16.2.tgz#664e33e70de431f88abf1f8537c48b1b6ce87e88" + integrity sha512-p4n6tFVaJZHJZEznHWy0YH2Xr3I+W7tsQWAT72PqKGT+uryGRdtgEQqi76f/8cRaw/00ueazBk5lwLG7UKGFaA== dependencies: - "@reach/auto-id" "0.15.2" - "@reach/descendants" "0.15.2" - "@reach/popover" "0.15.2" - "@reach/utils" "0.15.2" + "@reach/dropdown" "0.16.2" + "@reach/popover" "0.16.2" + "@reach/utils" "0.16.0" prop-types "^15.7.2" tiny-warning "^1.0.3" tslib "^2.3.0" @@ -2238,17 +2216,6 @@ resolved "https://registry.yarnpkg.com/@reach/observe-rect/-/observe-rect-1.2.0.tgz#d7a6013b8aafcc64c778a0ccb83355a11204d3b2" integrity sha512-Ba7HmkFgfQxZqqaeIWWkNK0rEhpxVQHIoVyW1YDSkGsGIXzcaW4deC8B0pZrNSSyLTdIk7y+5olKt5+g0GmFIQ== -"@reach/popover@0.15.2": - version "0.15.2" - resolved "https://registry.yarnpkg.com/@reach/popover/-/popover-0.15.2.tgz#e310e2afe82afa35929354f1fd1a747cdebb7654" - integrity sha512-92Ov7VPXjn4ciOVupeekki03lSMz9NAmw2BjWYE9mVvYWKyDx5jx2srtbkIqUaSCkAVV3KEsFUia8aMm60FDZg== - dependencies: - "@reach/portal" "0.15.2" - "@reach/rect" "0.15.2" - "@reach/utils" "0.15.2" - tabbable "^4.0.0" - tslib "^2.3.0" - "@reach/popover@0.16.2": version "0.16.2" resolved "https://registry.yarnpkg.com/@reach/popover/-/popover-0.16.2.tgz#71d7af3002ca49d791476b22dee1840dd1719c19" @@ -2260,14 +2227,6 @@ tabbable "^4.0.0" tslib "^2.3.0" -"@reach/portal@0.15.2": - version "0.15.2" - resolved "https://registry.yarnpkg.com/@reach/portal/-/portal-0.15.2.tgz#fe7aa3d9a475ec07686c39bab3a0d85093fa91fb" - integrity sha512-5x+dchGr4btRnLazwmyCYbSPVJAIrw0eXwhz7Vj9uT/EIp43WzOtTcODdLOoH6Ol2QLjX1Yt/fBjdK9+UAKxSA== - dependencies: - "@reach/utils" "0.15.2" - tslib "^2.3.0" - "@reach/portal@0.16.2": version "0.16.2" resolved "https://registry.yarnpkg.com/@reach/portal/-/portal-0.16.2.tgz#ca83696215ee03acc2bb25a5ae5d8793eaaf2f64" @@ -2277,17 +2236,6 @@ tiny-warning "^1.0.3" tslib "^2.3.0" -"@reach/rect@0.15.2": - version "0.15.2" - resolved "https://registry.yarnpkg.com/@reach/rect/-/rect-0.15.2.tgz#734e3f17a499d6e22bd2ea95856c801c41ed66fd" - integrity sha512-S2lzvvfclUHdvgcfW/eoz0i729HJvG5f6ayVaXcKz+X6LKF9i9Jdhfwsz7b3UmnSCihKNs0cX5tyWfWr1E1JFw== - dependencies: - "@reach/observe-rect" "1.2.0" - "@reach/utils" "0.15.2" - prop-types "^15.7.2" - tiny-warning "^1.0.3" - tslib "^2.3.0" - "@reach/rect@0.16.0": version "0.16.0" resolved "https://registry.yarnpkg.com/@reach/rect/-/rect-0.16.0.tgz#78cf6acefe2e83d3957fa84f938f6e1fc5700f16" @@ -2313,14 +2261,6 @@ tiny-warning "^1.0.3" tslib "^2.3.0" -"@reach/utils@0.15.2": - version "0.15.2" - resolved "https://registry.yarnpkg.com/@reach/utils/-/utils-0.15.2.tgz#a63a761eb36266bf33d65cb91520dd85a04ae116" - integrity sha512-Lr1SJ5X4hEjD/M0TAonURM8wytM/JuPSuIP7t+e5cil34pThyLsBvTGeNfmpSgaLJ5vlsv0x9u6g4SRAEr84Og== - dependencies: - tiny-warning "^1.0.3" - tslib "^2.3.0" - "@reach/utils@0.16.0": version "0.16.0" resolved "https://registry.yarnpkg.com/@reach/utils/-/utils-0.16.0.tgz#5b0777cf16a7cab1ddd4728d5d02762df0ba84ce" @@ -2366,99 +2306,133 @@ dependencies: "@sinonjs/commons" "^1.7.0" -"@standardnotes/auth@^3.16.4": - version "3.16.4" - resolved "https://registry.yarnpkg.com/@standardnotes/auth/-/auth-3.16.4.tgz#6293bd67cdc4055229f1d520b6f44b39c6053a7a" - integrity sha512-2tHsDnwQgGD3pOzKuSjo4yj8hLjATb70jzFnEWoEpyCdHTuGys9qSBElfi672hU4vg+/nXaHpdVUuD5DPzLaXg== +"@standardnotes/applications@^1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@standardnotes/applications/-/applications-1.1.3.tgz#7f19ab3e1a5d7754e18be9b6b37ed66cbacdbd05" + integrity sha512-B5kJ9S9F7ikGl+KHWgokbBYGwB15XWQSlwpxCw0IAseZuf/b2J8PAS1oeNhRNK73nvXercrQE15X42ORbjSb1Q== dependencies: - "@standardnotes/common" "^1.14.0" + "@standardnotes/common" "^1.15.3" + +"@standardnotes/auth@^3.17.3": + version "3.17.3" + resolved "https://registry.yarnpkg.com/@standardnotes/auth/-/auth-3.17.3.tgz#a00f10faa0fb2a7dd76509d3b678f85818aad63c" + integrity sha512-tb5ylXuDBPhgeZZynNsMk83N74NMMV9z6M9hyrwuK5HbKWM5r5L9U8lwFawG8flqTKpYzPeWxmaRFZT/5qR22Q== + dependencies: + "@standardnotes/common" "^1.15.3" jsonwebtoken "^8.5.1" -"@standardnotes/common@^1.14.0": - version "1.14.0" - resolved "https://registry.yarnpkg.com/@standardnotes/common/-/common-1.14.0.tgz#c3b8e06fb8120524da8d135f2dc594998e5a5c3a" - integrity sha512-QA8JhWty7y/N62jdLyWuXzsVvDDeFwcQAH/DB/g5Mmaqlz9VlKcsbRmVl4wHLG3ur6n5Qj68aOhzCQd0p7f/WA== +"@standardnotes/common@^1.15.3": + version "1.15.3" + resolved "https://registry.yarnpkg.com/@standardnotes/common/-/common-1.15.3.tgz#0b8ce48b81b260abe2d405431fb04aacb44b5a01" + integrity sha512-9oh/W3sFQYyA5Vabcbu6BUkLVkFq/25Q5EK9KCd4aT9QnDJ9JQlTtzDmTk1jYuM6rnccsJ6SW2pcWjbi9FVniw== -"@standardnotes/components@1.7.5": - version "1.7.5" - resolved "https://registry.yarnpkg.com/@standardnotes/components/-/components-1.7.5.tgz#2f199350779a8f99e9e536223d318b822bdf369f" - integrity sha512-7nyrrcgPAkCf6pjbAIO8qOM+22KQU0jMCIDX3b4GAS1jXM7DJDy5Frnk3oMHd9NeFhnbf0TQH4Nz4uEeid6/HA== +"@standardnotes/components@1.7.8": + version "1.7.8" + resolved "https://registry.yarnpkg.com/@standardnotes/components/-/components-1.7.8.tgz#2717f54afe013b8b8ca66a8f5197a753d0570d6e" + integrity sha512-6xaUFMvzpisTASmEFKt88QtXIisWxNuZYpOZ2niE4KWTfiknjdMR3m5MSNG6FVI5jbKwaJENkeXVRuKCoIpeIA== -"@standardnotes/domain-events@^2.23.14": - version "2.23.14" - resolved "https://registry.yarnpkg.com/@standardnotes/domain-events/-/domain-events-2.23.14.tgz#733e340c6d42935c90858380d7721150d1804574" - integrity sha512-DRPD0lGdVn/tbVyl97QGyyAcdUZd4qsETICCO882mG33HBN8Yc7st176U+izu3T5W3dlnTqE+MJUASj3UxVCvw== +"@standardnotes/domain-events@^2.23.20": + version "2.23.20" + resolved "https://registry.yarnpkg.com/@standardnotes/domain-events/-/domain-events-2.23.20.tgz#8ba0fe7a4f13d91ecf37af6478b5c782e09d2b2c" + integrity sha512-ZIQ/+mZ+II/T8rjgliBhKAuZ4Z2IpAkNIj7GZtcs830tgc5wg9cC92P7aYnLEDzH2J1KCm+UTndEi8fE+fOWyg== dependencies: - "@standardnotes/auth" "^3.16.4" - "@standardnotes/features" "^1.32.11" + "@standardnotes/auth" "^3.17.3" + "@standardnotes/features" "^1.34.0" -"@standardnotes/features@1.32.11", "@standardnotes/features@^1.32.11": - version "1.32.11" - resolved "https://registry.yarnpkg.com/@standardnotes/features/-/features-1.32.11.tgz#43417e541bdf0ce8a10dfd68e8073fc1338f1888" - integrity sha512-ZheQibMz4t2A6LKWcTDDGc5760AnPLFnHFwsSp0O8YydI3yz+qjm3pFF8XNeAEwgSvOX1W1nlX3E/X5tCp5LgQ== +"@standardnotes/features@1.34.0", "@standardnotes/features@^1.34.0": + version "1.34.0" + resolved "https://registry.yarnpkg.com/@standardnotes/features/-/features-1.34.0.tgz#88a48a4b70d2894b459dadc3f01db912afc7ffdb" + integrity sha512-ipmrCNGsy3zyJRgfTfiN9U1RN1vnzsHXftbhhRECXvYuq+QXyeytJrxCw6SSpZpW/DNOjV6jeIaX8WmaIQfvdA== dependencies: - "@standardnotes/auth" "^3.16.4" - "@standardnotes/common" "^1.14.0" + "@standardnotes/auth" "^3.17.3" + "@standardnotes/common" "^1.15.3" -"@standardnotes/services@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@standardnotes/services/-/services-1.1.0.tgz#42f743f58fb4ab85627368ae6bcdf513079ef708" - integrity sha512-r4lqUO30iHmjWodUTv+2D8xeCgpYFvJrNzR/pBIlZsAKMSjskxPyIUvBdQvHWs0o4vjf7ZedhpEwi68XwUqO3w== +"@standardnotes/payloads@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@standardnotes/payloads/-/payloads-1.3.0.tgz#0db372b21069ae5168cfcd1d6dc55bcb3247fb6b" + integrity sha512-2NUP22oevR2sBQ6blukLZCOkBt/3PoGh+x7nuCt6hdc2OfngcxtKmZ0XEscT1Pq5sAdXxLL4LrQzd0VLH1M0ZQ== dependencies: - "@standardnotes/common" "^1.14.0" - "@standardnotes/utils" "^1.1.1" + "@standardnotes/applications" "^1.1.3" + "@standardnotes/common" "^1.15.3" + "@standardnotes/features" "^1.34.0" + "@standardnotes/utils" "^1.2.3" -"@standardnotes/settings@^1.11.3": - version "1.11.3" - resolved "https://registry.yarnpkg.com/@standardnotes/settings/-/settings-1.11.3.tgz#f7735da40807dab6eaf81cc82d8d30f5461d26d5" - integrity sha512-95nqPYIZt57HMrymf4FTMDHOibM13AmV/8JEj7mPbIqcNKvVD486BURsaqpoBgkqB4Q43LbT8dfTrBPDgmIdxg== - -"@standardnotes/sncrypto-common@^1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@standardnotes/sncrypto-common/-/sncrypto-common-1.7.0.tgz#6ad96afeaa031c26e45cbaf527bb511b803f998d" - integrity sha512-Dke13reJMLQFXa7y9EqZYEeZG5Ouy+32qWEsQISLjLRPrTuNwyNXee2mdPh6c9uNZxOQwrdHxVGfqzJ2iy3RpQ== - -"@standardnotes/sncrypto-web@1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@standardnotes/sncrypto-web/-/sncrypto-web-1.7.0.tgz#e3a6e69019210f375ccf8b9abb789c7dd7147cf6" - integrity sha512-7NM1QJjtdvmUlBeQLjZukg5LovKKhoM8oX/FLOnBgl04TqDSGtvx+HDncm+laCnHZkAJ6VCSmUUxgfs1sQzyPw== +"@standardnotes/responses@^1.1.5": + version "1.1.5" + resolved "https://registry.yarnpkg.com/@standardnotes/responses/-/responses-1.1.5.tgz#565f8ae7cae95fab539904df8e56fd80dcf961d9" + integrity sha512-bk55ByUL07s92L38v4POfLKKBfCdxw/3dzHBRzF3FqDTH2bMOk4+qduqsTmdGDB4N9SuqZkv5/aMuZOw8PF6eA== dependencies: - "@standardnotes/sncrypto-common" "^1.7.0" + "@standardnotes/auth" "^3.17.3" + "@standardnotes/common" "^1.15.3" + "@standardnotes/features" "^1.34.0" + "@standardnotes/payloads" "^1.3.0" + +"@standardnotes/services@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@standardnotes/services/-/services-1.4.0.tgz#776ee5d022e4512844af1a284a2e90f599217218" + integrity sha512-wO0LQ+qMG0bfH0HNPulsO8nZ2Z1Y84NLP0fZdMdtqiuaCi1GrM/PUlcL/fpXCJKNeTKoYa8Dh4PfF8DOjalKXg== + dependencies: + "@standardnotes/applications" "^1.1.3" + "@standardnotes/common" "^1.15.3" + "@standardnotes/utils" "^1.2.3" + +"@standardnotes/settings@^1.11.5": + version "1.11.5" + resolved "https://registry.yarnpkg.com/@standardnotes/settings/-/settings-1.11.5.tgz#792bf3e0505065486f521b2f19c2bf1081b8fa5e" + integrity sha512-n6StAS3nBgs7Lia5mOt3+H4Xd6hatCcHFx83paFq9kdI1cKbqn7oFF4g/rUbWPy4nsx+96zBehB6EhsJ2MGzyQ== + +"@standardnotes/sncrypto-common@^1.7.3": + version "1.7.3" + resolved "https://registry.yarnpkg.com/@standardnotes/sncrypto-common/-/sncrypto-common-1.7.3.tgz#1e62a14800393be44cdb376d1d72fbc064334fc1" + integrity sha512-twwYeBL+COkNF9IUM5bWrLZ4gXjg41tRxBMR3r3JcbrkyYjcNqVHf9L+YdBcndjSV3/9xwWl2pYWK1RB3UR2Xg== + +"@standardnotes/sncrypto-web@1.7.3": + version "1.7.3" + resolved "https://registry.yarnpkg.com/@standardnotes/sncrypto-web/-/sncrypto-web-1.7.3.tgz#4fadaa8d41f301a5077db7a539c770db1cca9413" + integrity sha512-eudCOPQvuhEXUreBz8I+zN8NKNDkLZ1goxbi5nDC7THz+iGPxLFpYhhe9RzacA1oPjOQrBnkrWlByQD13XkvrA== + dependencies: + "@standardnotes/sncrypto-common" "^1.7.3" buffer "^6.0.3" libsodium-wrappers "^0.7.9" -"@standardnotes/snjs@2.63.1": - version "2.63.1" - resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.63.1.tgz#0759be39e77304fcca11ea902aa9be7bb737e756" - integrity sha512-d32CE7/yS+qEGlOfHTDc0NPzCFXPaK2zxlCi/j68R9lT/3LuV/uc1o9eNK9a5Fgcbtbk55vbW0rUYjQQVwUF8A== +"@standardnotes/snjs@2.72.0": + version "2.72.0" + resolved "https://registry.yarnpkg.com/@standardnotes/snjs/-/snjs-2.72.0.tgz#bf807b94a326e0d33acc15fe418f727f49737935" + integrity sha512-MIpfeZgJ/AHeHfNDGsG1te9SjmMAugOK1HFp8pY/LyEUw4uQJSKbPpwM6q81ExUPROFy3KbE4mn9IN2Kk/5c0A== dependencies: - "@standardnotes/auth" "^3.16.4" - "@standardnotes/common" "^1.14.0" - "@standardnotes/domain-events" "^2.23.14" - "@standardnotes/features" "^1.32.11" - "@standardnotes/services" "^1.1.0" - "@standardnotes/settings" "^1.11.3" - "@standardnotes/sncrypto-common" "^1.7.0" - "@standardnotes/utils" "^1.1.1" + "@standardnotes/applications" "^1.1.3" + "@standardnotes/auth" "^3.17.3" + "@standardnotes/common" "^1.15.3" + "@standardnotes/domain-events" "^2.23.20" + "@standardnotes/features" "^1.34.0" + "@standardnotes/payloads" "^1.3.0" + "@standardnotes/responses" "^1.1.5" + "@standardnotes/services" "^1.4.0" + "@standardnotes/settings" "^1.11.5" + "@standardnotes/sncrypto-common" "^1.7.3" + "@standardnotes/utils" "^1.2.3" -"@standardnotes/stylekit@5.9.0": - version "5.9.0" - resolved "https://registry.yarnpkg.com/@standardnotes/stylekit/-/stylekit-5.9.0.tgz#16d62623335091062238c850a930dedaa5ad6f1d" - integrity sha512-lIlEKwxKkQT+AttSmN40zvzWzfqpfI4VPTscZvRnWRqMQjYDEnSbcA1h0UDcT5tvnrna4RtsOiUL9o0KDx56sg== +"@standardnotes/stylekit@5.14.0": + version "5.14.0" + resolved "https://registry.yarnpkg.com/@standardnotes/stylekit/-/stylekit-5.14.0.tgz#806b7d896fb94de8be72e762dd205beefff05fd7" + integrity sha512-zCB8QFPUTe+063RsLNCudkP6FY6ujKC3iE2pD6ak4htpXtW6DndwYbhEffuiWIjbRzDGAy0YyQ7y8V19Jw7ElQ== dependencies: - "@reach/listbox" "^0.15.0" - "@reach/menu-button" "^0.15.1" + "@nanostores/preact" "^0.1.3" + "@reach/listbox" "^0.16.2" + "@reach/menu-button" "^0.16.2" "@svgr/webpack" "^6.2.1" - prop-types "^15.7.2" + nanoid "^3.3.1" + nanostores "^0.5.10" + prop-types "^15.8.1" -"@standardnotes/utils@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@standardnotes/utils/-/utils-1.1.1.tgz#a936edd328b4e10b43b11ffc8b1626a499fa6659" - integrity sha512-LaB1Y4arvwuABT0fybJ9At6pPEAwsDooaldYPuvqyfQAWdeqRCBMHxRDCX6yunrrwBwk7UoTie9MRw6DF1igwg== +"@standardnotes/utils@^1.2.3": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@standardnotes/utils/-/utils-1.2.3.tgz#2ff61f3214645c84dd6603858feb964db31cb19f" + integrity sha512-0/pSx+kJKRBdQ56oPPFRcMXBvTm/U4/zEE4Kqyx2vlm3EL0tXv4UKNuPSDbsbI5yUn8KpVSZ6LS4LZhhMU4IUA== dependencies: - "@standardnotes/common" "^1.14.0" - dompurify "^2.3.4" - lodash "^4.17.19" + "@standardnotes/common" "^1.15.3" + dompurify "^2.3.6" + lodash "^4.17.21" "@svgr/babel-plugin-add-jsx-attribute@^6.0.0": version "6.0.0" @@ -2720,12 +2694,12 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@^27.4.0": - version "27.4.0" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.4.0.tgz#037ab8b872067cae842a320841693080f9cb84ed" - integrity sha512-gHl8XuC1RZ8H2j5sHv/JqsaxXkDDM9iDOgu0Wp8sjs4u/snb2PVehyWXJPr+ORA0RPpgw231mnutWI1+0hgjIQ== +"@types/jest@^27.4.1": + version "27.4.1" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.4.1.tgz#185cbe2926eaaf9662d340cc02e548ce9e11ab6d" + integrity sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw== dependencies: - jest-diff "^27.0.0" + jest-matcher-utils "^27.0.0" pretty-format "^27.0.0" "@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": @@ -2738,10 +2712,10 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== -"@types/lodash@^4.14.178": - version "4.14.178" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.178.tgz#341f6d2247db528d4a13ddbb374bcdc80406f4f8" - integrity sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw== +"@types/lodash@^4.14.179": + version "4.14.179" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.179.tgz#490ec3288088c91295780237d2497a3aa9dfb5c5" + integrity sha512-uwc1x90yCKqGcIOAT6DwOSuxnrAbpkdPsUOZtwrXb4D/6wZs+6qG7QnIawDuZWg0sWpxl+ltIKCaLoMlna678w== "@types/mime@^1": version "1.3.2" @@ -2858,14 +2832,14 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@^5.12.1": - version "5.12.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.12.1.tgz#b2cd3e288f250ce8332d5035a2ff65aba3374ac4" - integrity sha512-M499lqa8rnNK7mUv74lSFFttuUsubIRdAbHcVaP93oFcKkEmHmLqy2n7jM9C8DVmFMYK61ExrZU6dLYhQZmUpw== +"@typescript-eslint/eslint-plugin@^5.13.0": + version "5.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.13.0.tgz#2809052b85911ced9c54a60dac10e515e9114497" + integrity sha512-vLktb2Uec81fxm/cfz2Hd6QaWOs8qdmVAZXLdOBX6JFJDhf6oDZpMzZ4/LZ6SFM/5DgDcxIMIvy3F+O9yZBuiQ== dependencies: - "@typescript-eslint/scope-manager" "5.12.1" - "@typescript-eslint/type-utils" "5.12.1" - "@typescript-eslint/utils" "5.12.1" + "@typescript-eslint/scope-manager" "5.13.0" + "@typescript-eslint/type-utils" "5.13.0" + "@typescript-eslint/utils" "5.13.0" debug "^4.3.2" functional-red-black-tree "^1.0.1" ignore "^5.1.8" @@ -2873,69 +2847,69 @@ semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/parser@^5.12.1": - version "5.12.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.12.1.tgz#b090289b553b8aa0899740d799d0f96e6f49771b" - integrity sha512-6LuVUbe7oSdHxUWoX/m40Ni8gsZMKCi31rlawBHt7VtW15iHzjbpj2WLiToG2758KjtCCiLRKZqfrOdl3cNKuw== +"@typescript-eslint/parser@^5.13.0": + version "5.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.13.0.tgz#0394ed8f2f849273c0bf4b811994d177112ced5c" + integrity sha512-GdrU4GvBE29tm2RqWOM0P5QfCtgCyN4hXICj/X9ibKED16136l9ZpoJvCL5pSKtmJzA+NRDzQ312wWMejCVVfg== dependencies: - "@typescript-eslint/scope-manager" "5.12.1" - "@typescript-eslint/types" "5.12.1" - "@typescript-eslint/typescript-estree" "5.12.1" + "@typescript-eslint/scope-manager" "5.13.0" + "@typescript-eslint/types" "5.13.0" + "@typescript-eslint/typescript-estree" "5.13.0" debug "^4.3.2" -"@typescript-eslint/scope-manager@5.12.1": - version "5.12.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.12.1.tgz#58734fd45d2d1dec49641aacc075fba5f0968817" - integrity sha512-J0Wrh5xS6XNkd4TkOosxdpObzlYfXjAFIm9QxYLCPOcHVv1FyyFCPom66uIh8uBr0sZCrtS+n19tzufhwab8ZQ== +"@typescript-eslint/scope-manager@5.13.0": + version "5.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.13.0.tgz#cf6aff61ca497cb19f0397eea8444a58f46156b6" + integrity sha512-T4N8UvKYDSfVYdmJq7g2IPJYCRzwtp74KyDZytkR4OL3NRupvswvmJQJ4CX5tDSurW2cvCc1Ia1qM7d0jpa7IA== dependencies: - "@typescript-eslint/types" "5.12.1" - "@typescript-eslint/visitor-keys" "5.12.1" + "@typescript-eslint/types" "5.13.0" + "@typescript-eslint/visitor-keys" "5.13.0" -"@typescript-eslint/type-utils@5.12.1": - version "5.12.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.12.1.tgz#8d58c6a0bb176b5e9a91581cda1a7f91a114d3f0" - integrity sha512-Gh8feEhsNLeCz6aYqynh61Vsdy+tiNNkQtc+bN3IvQvRqHkXGUhYkUi+ePKzP0Mb42se7FDb+y2SypTbpbR/Sg== +"@typescript-eslint/type-utils@5.13.0": + version "5.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.13.0.tgz#b0efd45c85b7bab1125c97b752cab3a86c7b615d" + integrity sha512-/nz7qFizaBM1SuqAKb7GLkcNn2buRdDgZraXlkhz+vUGiN1NZ9LzkA595tHHeduAiS2MsHqMNhE2zNzGdw43Yg== dependencies: - "@typescript-eslint/utils" "5.12.1" + "@typescript-eslint/utils" "5.13.0" debug "^4.3.2" tsutils "^3.21.0" -"@typescript-eslint/types@5.12.1": - version "5.12.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.12.1.tgz#46a36a28ff4d946821b58fe5a73c81dc2e12aa89" - integrity sha512-hfcbq4qVOHV1YRdhkDldhV9NpmmAu2vp6wuFODL71Y0Ixak+FLeEU4rnPxgmZMnGreGEghlEucs9UZn5KOfHJA== +"@typescript-eslint/types@5.13.0": + version "5.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.13.0.tgz#da1de4ae905b1b9ff682cab0bed6b2e3be9c04e5" + integrity sha512-LmE/KO6DUy0nFY/OoQU0XelnmDt+V8lPQhh8MOVa7Y5k2gGRd6U9Kp3wAjhB4OHg57tUO0nOnwYQhRRyEAyOyg== -"@typescript-eslint/typescript-estree@5.12.1": - version "5.12.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.12.1.tgz#6a9425b9c305bcbc38e2d1d9a24c08e15e02b722" - integrity sha512-ahOdkIY9Mgbza7L9sIi205Pe1inCkZWAHE1TV1bpxlU4RZNPtXaDZfiiFWcL9jdxvW1hDYZJXrFm+vlMkXRbBw== +"@typescript-eslint/typescript-estree@5.13.0": + version "5.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.13.0.tgz#b37c07b748ff030a3e93d87c842714e020b78141" + integrity sha512-Q9cQow0DeLjnp5DuEDjLZ6JIkwGx3oYZe+BfcNuw/POhtpcxMTy18Icl6BJqTSd+3ftsrfuVb7mNHRZf7xiaNA== dependencies: - "@typescript-eslint/types" "5.12.1" - "@typescript-eslint/visitor-keys" "5.12.1" + "@typescript-eslint/types" "5.13.0" + "@typescript-eslint/visitor-keys" "5.13.0" debug "^4.3.2" globby "^11.0.4" is-glob "^4.0.3" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/utils@5.12.1": - version "5.12.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.12.1.tgz#447c24a05d9c33f9c6c64cb48f251f2371eef920" - integrity sha512-Qq9FIuU0EVEsi8fS6pG+uurbhNTtoYr4fq8tKjBupsK5Bgbk2I32UGm0Sh+WOyjOPgo/5URbxxSNV6HYsxV4MQ== +"@typescript-eslint/utils@5.13.0": + version "5.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.13.0.tgz#2328feca700eb02837298339a2e49c46b41bd0af" + integrity sha512-+9oHlPWYNl6AwwoEt5TQryEHwiKRVjz7Vk6kaBeD3/kwHE5YqTGHtm/JZY8Bo9ITOeKutFaXnBlMgSATMJALUQ== dependencies: "@types/json-schema" "^7.0.9" - "@typescript-eslint/scope-manager" "5.12.1" - "@typescript-eslint/types" "5.12.1" - "@typescript-eslint/typescript-estree" "5.12.1" + "@typescript-eslint/scope-manager" "5.13.0" + "@typescript-eslint/types" "5.13.0" + "@typescript-eslint/typescript-estree" "5.13.0" eslint-scope "^5.1.1" eslint-utils "^3.0.0" -"@typescript-eslint/visitor-keys@5.12.1": - version "5.12.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.12.1.tgz#f722da106c8f9695ae5640574225e45af3e52ec3" - integrity sha512-l1KSLfupuwrXx6wc0AuOmC7Ko5g14ZOQ86wJJqRbdLbXLK02pK/DPiDDqCc7BqqiiA04/eAA6ayL0bgOrAkH7A== +"@typescript-eslint/visitor-keys@5.13.0": + version "5.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.13.0.tgz#f45ff55bcce16403b221ac9240fbeeae4764f0fd" + integrity sha512-HLKEAS/qA1V7d9EzcpLFykTePmOQqOFim8oCvhY3pZgQ8Hi38hYpHd9e5GN6nQBFQNecNhws5wkS9Y5XIO0s/g== dependencies: - "@typescript-eslint/types" "5.12.1" + "@typescript-eslint/types" "5.13.0" eslint-visitor-keys "^3.0.0" "@webassemblyjs/ast@1.11.1": @@ -4395,11 +4369,6 @@ detect-node@^2.0.4: resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== -diff-sequences@^27.4.0: - version "27.4.0" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.4.0.tgz#d783920ad8d06ec718a060d00196dfef25b132a5" - integrity sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww== - diff-sequences@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" @@ -4495,7 +4464,7 @@ domhandler@^4.0.0, domhandler@^4.2.0: dependencies: domelementtype "^2.2.0" -dompurify@^2.3.4: +dompurify@^2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.6.tgz#2e019d7d7617aacac07cbbe3d88ae3ad354cf875" integrity sha512-OFP2u/3T1R5CEgWCEONuJ1a5+MFKnOYpkywpUSxv/dj1LeBT1erK+JwM7zK0ROy2BRhqVCf0LRw/kHqKuMkVGg== @@ -4601,7 +4570,7 @@ end-of-stream@^1.1.0: dependencies: once "^1.4.0" -enhanced-resolve@^5.0.0, enhanced-resolve@^5.8.3: +enhanced-resolve@^5.0.0: version "5.8.3" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz#6d552d465cce0423f5b3d718511ea53826a7b2f0" integrity sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA== @@ -4609,6 +4578,14 @@ enhanced-resolve@^5.0.0, enhanced-resolve@^5.8.3: graceful-fs "^4.2.4" tapable "^2.2.0" +enhanced-resolve@^5.9.2: + version "5.9.2" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.9.2.tgz#0224dcd6a43389ebfb2d55efee517e5466772dd9" + integrity sha512-GIm3fQfwLJ8YZx2smuHpBKkXC1yOk+OBEmKckVyL0i/ea8mqDEykK3ld5dgH1QYPNyT/lIllxV2LULnxCHaHkA== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + entities@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5" @@ -4760,32 +4737,32 @@ escodegen@^2.0.0: optionalDependencies: source-map "~0.6.1" -eslint-config-prettier@^8.4.0: - version "8.4.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.4.0.tgz#8e6d17c7436649e98c4c2189868562921ef563de" - integrity sha512-CFotdUcMY18nGRo5KGsnNxpznzhkopOcOo0InID+sgQssPrzjvsyKZPvOgymTFeHrFuC3Tzdf2YndhXtULK9Iw== +eslint-config-prettier@^8.5.0: + version "8.5.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1" + integrity sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q== eslint-plugin-react-hooks@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.3.0.tgz#318dbf312e06fab1c835a4abef00121751ac1172" integrity sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA== -eslint-plugin-react@^7.28.0: - version "7.28.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.28.0.tgz#8f3ff450677571a659ce76efc6d80b6a525adbdf" - integrity sha512-IOlFIRHzWfEQQKcAD4iyYDndHwTQiCMcJVJjxempf203jnNLUnW34AXLrV33+nEXoifJE2ZEGmcjKPL8957eSw== +eslint-plugin-react@^7.29.2: + version "7.29.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.29.2.tgz#2d4da69d30d0a736efd30890dc6826f3e91f3f7c" + integrity sha512-ypEBTKOy5liFQXZWMchJ3LN0JX1uPI6n7MN7OPHKacqXAxq5gYC30TdO7wqGYQyxD1OrzpobdHC3hDmlRWDg9w== dependencies: array-includes "^3.1.4" array.prototype.flatmap "^1.2.5" doctrine "^2.1.0" estraverse "^5.3.0" jsx-ast-utils "^2.4.1 || ^3.0.0" - minimatch "^3.0.4" + minimatch "^3.1.2" object.entries "^1.1.5" object.fromentries "^2.0.5" object.hasown "^1.1.0" object.values "^1.1.5" - prop-types "^15.7.2" + prop-types "^15.8.1" resolve "^2.0.0-next.3" semver "^6.3.0" string.prototype.matchall "^4.0.6" @@ -4833,12 +4810,12 @@ eslint-visitor-keys@^3.3.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== -eslint@^8.9.0: - version "8.9.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.9.0.tgz#a2a8227a99599adc4342fd9b854cb8d8d6412fdb" - integrity sha512-PB09IGwv4F4b0/atrbcMFboF/giawbBLVC7fyDamk5Wtey4Jh2K+rYaBhCAbUyEI4QzB1ly09Uglc9iCtFaG2Q== +eslint@^8.10.0: + version "8.10.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.10.0.tgz#931be395eb60f900c01658b278e05b6dae47199d" + integrity sha512-tcI1D9lfVec+R4LE1mNDnzoJ/f71Kl/9Cv4nG47jOueCMBrCCKYXr4AUVS7go6mWYGFD4+EoN6+eXSrEbRzXVw== dependencies: - "@eslint/eslintrc" "^1.1.0" + "@eslint/eslintrc" "^1.2.0" "@humanwhocodes/config-array" "^0.9.2" ajv "^6.10.0" chalk "^4.0.0" @@ -6279,16 +6256,6 @@ jest-config@^27.5.1: slash "^3.0.0" strip-json-comments "^3.1.1" -jest-diff@^27.0.0: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.4.2.tgz#786b2a5211d854f848e2dcc1e324448e9481f36f" - integrity sha512-ujc9ToyUZDh9KcqvQDkk/gkbf6zSaeEg9AiBxtttXW59H/AcqEYp1ciXAtJp+jXWva5nAf/ePtSsgWwE5mqp4Q== - dependencies: - chalk "^4.0.0" - diff-sequences "^27.4.0" - jest-get-type "^27.4.0" - pretty-format "^27.4.2" - jest-diff@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.5.1.tgz#a07f5011ac9e6643cf8a95a462b7b1ecf6680def" @@ -6342,11 +6309,6 @@ jest-environment-node@^27.5.1: jest-mock "^27.5.1" jest-util "^27.5.1" -jest-get-type@^27.4.0: - version "27.4.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.4.0.tgz#7503d2663fffa431638337b3998d39c5e928e9b5" - integrity sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ== - jest-get-type@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1" @@ -6403,7 +6365,7 @@ jest-leak-detector@^27.5.1: jest-get-type "^27.5.1" pretty-format "^27.5.1" -jest-matcher-utils@^27.5.1: +jest-matcher-utils@^27.0.0, jest-matcher-utils@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz#9c0cdbda8245bc22d2331729d1091308b40cf8ab" integrity sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw== @@ -7215,6 +7177,13 @@ minimatch@^3.0.4, minimatch@~3.0.2: dependencies: brace-expansion "^1.1.7" +minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + minimist-options@4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619" @@ -7307,10 +7276,10 @@ mobx-react-lite@^3.3.0: resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-3.3.0.tgz#7174e807201943beff6f9d3701492314c9fc0db3" integrity sha512-U/kMSFtV/bNVgY01FuiGWpRkaQVHozBq5CEBZltFvPt4FcV111hEWkgwqVg9GPPZSEuEdV438PEz8mk8mKpYlA== -mobx@^6.4.1: - version "6.4.1" - resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.4.1.tgz#c1d0eeb37ceb31bb2020a85f6bf856782d47fe60" - integrity sha512-NFXx0uMbGBgsa0uxhH099L8cMuoRQWh01q6Sf0ZX/3hFU7svJ7yfTD+1LnLMa5wzY/b7gImAeMsR1p0wordDnA== +mobx@^6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.4.2.tgz#d25cd358a46b7a8fe2d8299259bc71008a2aa5b3" + integrity sha512-b4xQJYiH8sb0sEbfq/Ws3N77DEJtSihUFD1moeiz2jNoJ5B+mqJutt54ouO9iEfkp7Wk4jQDsVUOh7DPEW3wEw== mri@^1.1.5: version "1.2.0" @@ -7366,11 +7335,16 @@ nan@^2.13.2: resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== -nanoid@^3.2.0: +nanoid@^3.2.0, nanoid@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== +nanostores@^0.5.10: + version "0.5.10" + resolved "https://registry.yarnpkg.com/nanostores/-/nanostores-0.5.10.tgz#16488776f01fa288b09c026400ff535da55c3583" + integrity sha512-8Y7C8sF8PsHGpLVJochWT+ytEY34XrNRDA30hDqgvLcl5Ih4d/IFb7gUSFIwmgFAaht1pLwKZHTeFoJrNz88RQ== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -7922,7 +7896,7 @@ pretty-error@^4.0.0: lodash "^4.17.20" renderkid "^3.0.0" -pretty-format@^27.0.0, pretty-format@^27.4.2: +pretty-format@^27.0.0: version "27.4.2" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.4.2.tgz#e4ce92ad66c3888423d332b40477c87d1dac1fb8" integrity sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw== @@ -7988,6 +7962,15 @@ prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2: object-assign "^4.1.1" react-is "^16.8.1" +prop-types@^15.8.1: + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + proxy-addr@~2.0.5: version "2.0.6" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" @@ -8110,7 +8093,7 @@ react-focus-lock@^2.5.2: use-callback-ref "^1.2.5" use-sidecar "^1.0.5" -react-is@^16.7.0, react-is@^16.8.1: +react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.1: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -9273,10 +9256,10 @@ ts-jest@^27.1.3: semver "7.x" yargs-parser "20.x" -ts-loader@^9.2.6: - version "9.2.6" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.2.6.tgz#9937c4dd0a1e3dbbb5e433f8102a6601c6615d74" - integrity sha512-QMTC4UFzHmu9wU2VHZEmWWE9cUajjfcdcws+Gh7FhiO+Dy0RnR1bNz0YCHqhI0yRowCE9arVnNxYHqELOy9Hjw== +ts-loader@^9.2.7: + version "9.2.7" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.2.7.tgz#948654099ca96992b62ec47bd9cee5632006e101" + integrity sha512-Fxh44mKli9QezgbdCXkEJWxnedQ0ead7DXTH+lfXEPedu+Y9EtMJ2aQ9G3Dj1j7Q612E8931rww8NDZha4Tibg== dependencies: chalk "^4.1.0" enhanced-resolve "^5.0.0" @@ -9386,10 +9369,10 @@ typescript-eslint@0.0.1-alpha.0: resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-0.0.1-alpha.0.tgz#285d68a4e96588295cd436278801bcb6a6b916c1" integrity sha512-1hNKM37dAWML/2ltRXupOq2uqcdRQyDFphl+341NTPXFLLLiDhErXx8VtaSLh3xP7SyHZdcCgpt9boYYVb3fQg== -typescript@4.5.5: - version "4.5.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.5.tgz#d8c953832d28924a9e3d37c73d729c846c5896f3" - integrity sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA== +typescript@4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.2.tgz#fe12d2727b708f4eef40f51598b3398baa9611d4" + integrity sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg== unbox-primitive@^1.0.1: version "1.0.1" @@ -9674,10 +9657,10 @@ webpack-sources@^3.2.3: resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack@^5.69.1: - version "5.69.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.69.1.tgz#8cfd92c192c6a52c99ab00529b5a0d33aa848dc5" - integrity sha512-+VyvOSJXZMT2V5vLzOnDuMz5GxEqLk7hKWQ56YxPW/PQRUuKimPqmEIJOx8jHYeyo65pKbapbW464mvsKbaj4A== +webpack@^5.70.0: + version "5.70.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.70.0.tgz#3461e6287a72b5e6e2f4872700bc8de0d7500e6d" + integrity sha512-ZMWWy8CeuTTjCxbeaQI21xSswseF2oNOwc70QSKNePvmxE7XW36i7vpBMYZFAUHPwQiEbNGCEYIOOlyRbdGmxw== dependencies: "@types/eslint-scope" "^3.7.3" "@types/estree" "^0.0.51" @@ -9688,7 +9671,7 @@ webpack@^5.69.1: acorn-import-assertions "^1.7.6" browserslist "^4.14.5" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.8.3" + enhanced-resolve "^5.9.2" es-module-lexer "^0.9.0" eslint-scope "5.1.1" events "^3.2.0"