fix: Fixes issue where lock screen would not use previously active theme (#2372)

This commit is contained in:
Mo
2023-07-26 15:50:08 -05:00
committed by GitHub
parent 86fc4c684d
commit d268c02ab3
88 changed files with 1118 additions and 716 deletions

View File

@@ -6,7 +6,7 @@ import { WebApplication } from '@/Application/WebApplication'
import {
UIFeature,
EditorFeatureDescription,
FeatureIdentifier,
NativeFeatureIdentifier,
IframeComponentFeatureDescription,
NoteMutator,
NoteType,
@@ -100,7 +100,7 @@ const ChangeEditorMenu: FunctionComponent<ChangeEditorMenuProps> = ({
setCurrentFeature(application.componentManager.editorForNote(note))
if (uiFeature.featureIdentifier === FeatureIdentifier.PlainEditor) {
if (uiFeature.featureIdentifier === NativeFeatureIdentifier.TYPES.PlainEditor) {
reloadFont(application.getPreference(PrefKey.EditorMonospaceEnabled))
}
},
@@ -211,7 +211,7 @@ const ChangeEditorMenu: FunctionComponent<ChangeEditorMenuProps> = ({
return (
<MenuRadioButtonItem
key={menuItem.uiFeature.uniqueIdentifier}
key={menuItem.uiFeature.uniqueIdentifier.value}
onClick={onClickEditorItem}
className={'flex-row-reversed py-2'}
checked={isSelected(menuItem)}

View File

@@ -141,7 +141,7 @@ const ChangeEditorMultipleMenu = ({ application, notes, setDisableClickOutside }
}
return (
<MenuItem
key={item.uiFeature.uniqueIdentifier}
key={item.uiFeature.uniqueIdentifier.value}
onClick={onClickEditorItem}
className={'flex-row-reversed py-2'}
>

View File

@@ -15,7 +15,7 @@ import {
ApplicationEvent,
ContentType,
DecryptedItem,
FeatureIdentifier,
NativeFeatureIdentifier,
FeatureStatus,
NoteContent,
NoteType,
@@ -61,7 +61,10 @@ const ClipperView = ({
const [user, setUser] = useState(() => application.getUser())
const [isEntitledToExtension, setIsEntitled] = useState(
() => application.features.getFeatureStatus(FeatureIdentifier.Extension) === FeatureStatus.Entitled,
() =>
application.features.getFeatureStatus(
NativeFeatureIdentifier.create(NativeFeatureIdentifier.TYPES.Clipper).getValue(),
) === FeatureStatus.Entitled,
)
const isEntitledRef = useStateRef(isEntitledToExtension)
const hasSubscription = application.hasValidFirstPartySubscription()
@@ -72,10 +75,18 @@ const ClipperView = ({
case ApplicationEvent.SignedOut:
case ApplicationEvent.UserRolesChanged:
setUser(application.getUser())
setIsEntitled(application.features.getFeatureStatus(FeatureIdentifier.Extension) === FeatureStatus.Entitled)
setIsEntitled(
application.features.getFeatureStatus(
NativeFeatureIdentifier.create(NativeFeatureIdentifier.TYPES.Clipper).getValue(),
) === FeatureStatus.Entitled,
)
break
case ApplicationEvent.FeaturesAvailabilityChanged:
setIsEntitled(application.features.getFeatureStatus(FeatureIdentifier.Extension) === FeatureStatus.Entitled)
setIsEntitled(
application.features.getFeatureStatus(
NativeFeatureIdentifier.create(NativeFeatureIdentifier.TYPES.Clipper).getValue(),
) === FeatureStatus.Entitled,
)
break
}
})
@@ -212,7 +223,7 @@ const ClipperView = ({
const note = application.items.createTemplateItem<NoteContent, SNNote>(ContentType.TYPES.Note, {
title: clipPayload.title,
text: editorStateJSON,
editorIdentifier: FeatureIdentifier.SuperEditor,
editorIdentifier: NativeFeatureIdentifier.TYPES.SuperEditor,
noteType: NoteType.Super,
references: [],
})

View File

@@ -168,7 +168,7 @@ const IframeFeatureView: FunctionComponent<Props> = ({ onLoad, componentViewer,
const unregisterDesktopObserver = application
.getDesktopService()
?.registerUpdateObserver((updatedComponent: ComponentInterface) => {
if (updatedComponent.uuid === uiFeature.uniqueIdentifier) {
if (updatedComponent.uuid === uiFeature.uniqueIdentifier.value) {
requestReload?.(componentViewer)
}
})

View File

@@ -1,14 +1,14 @@
import {
FeatureIdentifier,
NativeFeatureIdentifier,
NewNoteTitleFormat,
PrefKey,
EditorIdentifier,
TagPreferences,
isSmartView,
isSystemView,
SystemViewId,
PrefDefaults,
FeatureStatus,
Uuid,
} from '@standardnotes/snjs'
import { observer } from 'mobx-react-lite'
import { ChangeEventHandler, FunctionComponent, useCallback, useEffect, useRef, useState } from 'react'
@@ -17,6 +17,11 @@ import { DropdownItem } from '@/Components/Dropdown/DropdownItem'
import { WebApplication } from '@/Application/WebApplication'
import { AnyTag } from '@/Controllers/Navigation/AnyTagType'
import { PreferenceMode } from './PreferenceMode'
import { EditorOption, getDropdownItemsForAllEditors } from '@/Utils/DropdownItemsForEditors'
import { classNames } from '@standardnotes/utils'
import { NoteTitleFormatOptions } from './NoteTitleFormatOptions'
import { usePremiumModal } from '@/Hooks/usePremiumModal'
import dayjs from 'dayjs'
import dayjsAdvancedFormat from 'dayjs/plugin/advancedFormat'
import dayjsUTC from 'dayjs/plugin/utc'
@@ -24,11 +29,6 @@ import dayjsTimezone from 'dayjs/plugin/timezone'
dayjs.extend(dayjsAdvancedFormat)
dayjs.extend(dayjsUTC)
dayjs.extend(dayjsTimezone)
import { EditorOption, getDropdownItemsForAllEditors } from '@/Utils/DropdownItemsForEditors'
import { classNames } from '@standardnotes/utils'
import { NoteTitleFormatOptions } from './NoteTitleFormatOptions'
import { usePremiumModal } from '@/Hooks/usePremiumModal'
const PrefChangeDebounceTimeInMs = 25
@@ -57,8 +57,8 @@ const NewNotePreferences: FunctionComponent<Props> = ({
: selectedTag.preferences
const [editorItems, setEditorItems] = useState<DropdownItem[]>([])
const [defaultEditorIdentifier, setDefaultEditorIdentifier] = useState<EditorIdentifier>(
FeatureIdentifier.PlainEditor,
const [defaultEditorIdentifier, setDefaultEditorIdentifier] = useState<string>(
NativeFeatureIdentifier.TYPES.PlainEditor,
)
const [newNoteTitleFormat, setNewNoteTitleFormat] = useState<NewNoteTitleFormat>(
NewNoteTitleFormat.CurrentDateAndTime,
@@ -121,14 +121,19 @@ const NewNotePreferences: FunctionComponent<Props> = ({
const selectEditorForNewNoteDefault = useCallback(
(value: EditorOption['value']) => {
if (application.features.getFeatureStatus(value) !== FeatureStatus.Entitled) {
const uuid = Uuid.create(value)
const feature = NativeFeatureIdentifier.create(value)
if (
application.features.getFeatureStatus(!uuid.isFailed() ? uuid.getValue() : feature.getValue()) !==
FeatureStatus.Entitled
) {
const editorItem = editorItems.find((item) => item.value === value)
if (editorItem) {
premiumModal.activate(editorItem.label)
}
return
}
setDefaultEditorIdentifier(value as FeatureIdentifier)
setDefaultEditorIdentifier(value)
if (mode === 'global') {
void application.setPreference(PrefKey.DefaultEditorIdentifier, value)

View File

@@ -1,7 +1,6 @@
import { WebApplication } from '@/Application/WebApplication'
import { ContentType } from '@standardnotes/domain-core'
import {
MutatorService,
SNComponentManager,
SNComponent,
SNTag,
@@ -11,7 +10,7 @@ import {
ItemManagerInterface,
MutatorClientInterface,
} from '@standardnotes/snjs'
import { FeatureIdentifier, NoteType } from '@standardnotes/features'
import { NativeFeatureIdentifier, NoteType } from '@standardnotes/features'
import { NoteViewController } from './NoteViewController'
describe('note view controller', () => {
@@ -40,7 +39,9 @@ describe('note view controller', () => {
})
it('should create notes with plaintext note type', async () => {
application.componentManager.getDefaultEditorIdentifier = jest.fn().mockReturnValue(FeatureIdentifier.PlainEditor)
application.componentManager.getDefaultEditorIdentifier = jest
.fn()
.mockReturnValue(NativeFeatureIdentifier.TYPES.PlainEditor)
const controller = new NoteViewController(application)
await controller.initialize()
@@ -55,13 +56,13 @@ describe('note view controller', () => {
it('should create notes with markdown note type', async () => {
application.items.getDisplayableComponents = jest.fn().mockReturnValue([
{
identifier: FeatureIdentifier.MarkdownProEditor,
identifier: NativeFeatureIdentifier.TYPES.MarkdownProEditor,
} as SNComponent,
])
application.componentManager.getDefaultEditorIdentifier = jest
.fn()
.mockReturnValue(FeatureIdentifier.MarkdownProEditor)
.mockReturnValue(NativeFeatureIdentifier.TYPES.MarkdownProEditor)
const controller = new NoteViewController(application)
await controller.initialize()
@@ -74,7 +75,9 @@ describe('note view controller', () => {
})
it('should add tag to note if default tag is set', async () => {
application.componentManager.getDefaultEditorIdentifier = jest.fn().mockReturnValue(FeatureIdentifier.PlainEditor)
application.componentManager.getDefaultEditorIdentifier = jest
.fn()
.mockReturnValue(NativeFeatureIdentifier.TYPES.PlainEditor)
const tag = {
uuid: 'tag-uuid',

View File

@@ -8,7 +8,7 @@ import { ElementIds } from '@/Constants/ElementIDs'
import { StringDeleteNote, STRING_DELETE_LOCKED_ATTEMPT, STRING_DELETE_PLACEHOLDER_ATTEMPT } from '@/Constants/Strings'
import { log, LoggingDomain } from '@/Logging'
import { debounce, isDesktopApplication, isMobileScreen } from '@/Utils'
import { classNames, pluralize } from '@standardnotes/utils'
import { classNames, compareArrayReferences, pluralize } from '@standardnotes/utils'
import {
ApplicationEvent,
ComponentArea,
@@ -19,7 +19,6 @@ import {
EditorLineWidth,
IframeComponentFeatureDescription,
isUIFeatureAnIframeFeature,
isPayloadSourceInternalChange,
isPayloadSourceRetrieved,
NoteType,
PayloadEmitSource,
@@ -94,7 +93,6 @@ class NoteView extends AbstractComponent<NoteViewProps, State> {
onEditorComponentLoad?: () => void
private removeTrashKeyObserver?: () => void
private removeComponentStreamObserver?: () => void
private removeNoteStreamObserver?: () => void
private removeComponentManagerObserver?: () => void
private removeInnerNoteObserver?: () => void
@@ -144,9 +142,6 @@ class NoteView extends AbstractComponent<NoteViewProps, State> {
super.deinit()
;(this.controller as unknown) = undefined
this.removeComponentStreamObserver?.()
;(this.removeComponentStreamObserver as unknown) = undefined
this.removeNoteStreamObserver?.()
;(this.removeNoteStreamObserver as unknown) = undefined
@@ -187,14 +182,19 @@ class NoteView extends AbstractComponent<NoteViewProps, State> {
}
override shouldComponentUpdate(_nextProps: Readonly<NoteViewProps>, nextState: Readonly<State>): boolean {
const complexObjects: (keyof State)[] = ['availableStackComponents', 'stackComponentViewers']
for (const key of Object.keys(nextState) as (keyof State)[]) {
if (complexObjects.includes(key)) {
continue
}
const prevValue = this.state[key]
const nextValue = nextState[key]
if (Array.isArray(prevValue) && Array.isArray(nextValue)) {
const areEqual = compareArrayReferences<unknown>(prevValue, nextValue)
if (!areEqual) {
log(LoggingDomain.NoteView, 'Rendering due to array state change', key, prevValue, nextValue)
return true
}
continue
}
if (prevValue !== nextValue) {
log(LoggingDomain.NoteView, 'Rendering due to state change', key, prevValue, nextValue)
return true
@@ -340,7 +340,8 @@ class NoteView extends AbstractComponent<NoteViewProps, State> {
switch (eventName) {
case ApplicationEvent.PreferencesChanged:
this.reloadPreferences().catch(console.error)
void this.reloadPreferences()
void this.reloadStackComponents()
break
case ApplicationEvent.HighLatencySync:
this.setState({ syncTakingTooLong: true })
@@ -428,23 +429,6 @@ class NoteView extends AbstractComponent<NoteViewProps, State> {
}
streamItems() {
this.removeComponentStreamObserver = this.application.streamItems(
ContentType.TYPES.Component,
async ({ source }) => {
log(LoggingDomain.NoteView, 'On component stream observer', PayloadEmitSource[source])
if (isPayloadSourceInternalChange(source) || source === PayloadEmitSource.InitialObserverRegistrationPush) {
return
}
if (!this.note) {
return
}
await this.reloadStackComponents()
this.debounceReloadEditorComponent()
},
)
this.removeNoteStreamObserver = this.application.streamItems<SNNote>(ContentType.TYPES.Note, async () => {
if (!this.note) {
return
@@ -740,25 +724,22 @@ class NoteView extends AbstractComponent<NoteViewProps, State> {
async reloadStackComponents() {
log(LoggingDomain.NoteView, 'Reload stack components')
const stackComponents = sortAlphabetically(
const enabledComponents = sortAlphabetically(
this.application.componentManager
.thirdPartyComponentsForArea(ComponentArea.EditorStack)
.filter((component) => this.application.componentManager.isComponentActive(component)),
)
const enabledComponents = stackComponents.filter((component) => {
return component.isExplicitlyEnabledForItem(this.note.uuid)
})
const needsNewViewer = enabledComponents.filter((component) => {
const hasExistingViewer = this.state.stackComponentViewers.find(
(viewer) => viewer.componentUniqueIdentifier === component.uuid,
(viewer) => viewer.componentUniqueIdentifier.value === component.uuid,
)
return !hasExistingViewer
})
const needsDestroyViewer = this.state.stackComponentViewers.filter((viewer) => {
const viewerComponentExistsInEnabledComponents = enabledComponents.find((component) => {
return component.uuid === viewer.componentUniqueIdentifier
return component.uuid === viewer.componentUniqueIdentifier.value
})
return !viewerComponentExistsInEnabledComponents
})
@@ -779,13 +760,15 @@ class NoteView extends AbstractComponent<NoteViewProps, State> {
this.application.componentManager.destroyComponentViewer(viewer)
}
this.setState({
availableStackComponents: stackComponents,
availableStackComponents: enabledComponents,
stackComponentViewers: newViewers,
})
}
stackComponentExpanded = (component: ComponentInterface): boolean => {
return !!this.state.stackComponentViewers.find((viewer) => viewer.componentUniqueIdentifier === component.uuid)
return !!this.state.stackComponentViewers.find(
(viewer) => viewer.componentUniqueIdentifier.value === component.uuid,
)
}
toggleStackComponent = async (component: ComponentInterface) => {

View File

@@ -1,5 +1,5 @@
import {
FeatureIdentifier,
NativeFeatureIdentifier,
FeatureStatus,
MuteMarketingEmailsOption,
MuteSignInEmailsOption,
@@ -28,7 +28,9 @@ const Email: FunctionComponent<Props> = ({ application }: Props) => {
const [isLoading, setIsLoading] = useState(true)
const isMuteSignInEmailsFeatureAvailable =
application.features.getFeatureStatus(FeatureIdentifier.SignInAlerts) === FeatureStatus.Entitled
application.features.getFeatureStatus(
NativeFeatureIdentifier.create(NativeFeatureIdentifier.TYPES.SignInAlerts).getValue(),
) === FeatureStatus.Entitled
const updateSetting = async (settingName: SettingName, payload: string): Promise<boolean> => {
try {

View File

@@ -1,4 +1,4 @@
import { FeatureStatus, FeatureIdentifier } from '@standardnotes/snjs'
import { FeatureStatus, NativeFeatureIdentifier } from '@standardnotes/snjs'
import { observer } from 'mobx-react-lite'
import { FunctionComponent, useState } from 'react'
@@ -29,8 +29,9 @@ const SubscriptionSharing: FunctionComponent<Props> = ({ application, viewContro
const isReadOnlySession = application.sessions.isCurrentSessionReadOnly()
const isSubscriptionSharingFeatureAvailable =
application.features.getFeatureStatus(FeatureIdentifier.SubscriptionSharing) === FeatureStatus.Entitled &&
!isReadOnlySession
application.features.getFeatureStatus(
NativeFeatureIdentifier.create(NativeFeatureIdentifier.TYPES.SubscriptionSharing).getValue(),
) === FeatureStatus.Entitled && !isReadOnlySession
const closeInviteDialog = () => setIsInviteDialogOpen(false)

View File

@@ -4,7 +4,7 @@ import { usePremiumModal } from '@/Hooks/usePremiumModal'
import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
import Switch from '@/Components/Switch/Switch'
import { WebApplication } from '@/Application/WebApplication'
import { FeatureIdentifier, PrefKey, FeatureStatus, naturalSort, PrefDefaults } from '@standardnotes/snjs'
import { PrefKey, FeatureStatus, naturalSort, PrefDefaults } from '@standardnotes/snjs'
import { observer } from 'mobx-react-lite'
import { FunctionComponent, useEffect, useState } from 'react'
import { Subtitle, Title, Text } from '@/Components/Preferences/PreferencesComponents/Content'
@@ -50,7 +50,7 @@ const Appearance: FunctionComponent<Props> = ({ application }) => {
label: theme.displayName as string,
value: theme.featureIdentifier,
icon:
application.features.getFeatureStatus(theme.featureIdentifier) !== FeatureStatus.Entitled
application.features.getFeatureStatus(theme.uniqueIdentifier) !== FeatureStatus.Entitled
? PremiumFeatureIconName
: undefined,
}
@@ -72,14 +72,10 @@ const Appearance: FunctionComponent<Props> = ({ application }) => {
const toggleUseDeviceSettings = () => {
application.setPreference(PrefKey.UseSystemColorScheme, !useDeviceSettings).catch(console.error)
if (!application.getPreference(PrefKey.AutoLightThemeIdentifier)) {
application
.setPreference(PrefKey.AutoLightThemeIdentifier, autoLightTheme as FeatureIdentifier)
.catch(console.error)
application.setPreference(PrefKey.AutoLightThemeIdentifier, autoLightTheme).catch(console.error)
}
if (!application.getPreference(PrefKey.AutoDarkThemeIdentifier)) {
application
.setPreference(PrefKey.AutoDarkThemeIdentifier, autoDarkTheme as FeatureIdentifier)
.catch(console.error)
application.setPreference(PrefKey.AutoDarkThemeIdentifier, autoDarkTheme).catch(console.error)
}
setUseDeviceSettings(!useDeviceSettings)
}
@@ -90,7 +86,7 @@ const Appearance: FunctionComponent<Props> = ({ application }) => {
premiumModal.activate(`${item.label} theme`)
return
}
application.setPreference(PrefKey.AutoLightThemeIdentifier, value as FeatureIdentifier).catch(console.error)
application.setPreference(PrefKey.AutoLightThemeIdentifier, value).catch(console.error)
setAutoLightTheme(value)
}
@@ -100,7 +96,7 @@ const Appearance: FunctionComponent<Props> = ({ application }) => {
premiumModal.activate(`${item.label} theme`)
return
}
application.setPreference(PrefKey.AutoDarkThemeIdentifier, value as FeatureIdentifier).catch(console.error)
application.setPreference(PrefKey.AutoDarkThemeIdentifier, value).catch(console.error)
setAutoDarkTheme(value)
}

View File

@@ -2,7 +2,7 @@ import { Text, Title } from '@/Components/Preferences/PreferencesComponents/Cont
import { WebApplication } from '@/Application/WebApplication'
import {
ApplicationEvent,
FeatureIdentifier,
NativeFeatureIdentifier,
FeatureStatus,
FindNativeFeature,
PrefKey,
@@ -17,7 +17,7 @@ import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
import { MutuallyExclusiveMediaQueryBreakpoints, useMediaQuery } from '@/Hooks/useMediaQuery'
type ExperimentalFeatureItem = {
identifier: FeatureIdentifier
identifier: string
name: string
description: string
isEnabled: boolean
@@ -55,7 +55,9 @@ const LabsPane: FunctionComponent<Props> = ({ application }) => {
name: feature?.name ?? featureIdentifier,
description: feature?.description ?? '',
isEnabled: application.features.isExperimentalFeatureEnabled(featureIdentifier),
isEntitled: application.features.getFeatureStatus(featureIdentifier) === FeatureStatus.Entitled,
isEntitled:
application.features.getFeatureStatus(NativeFeatureIdentifier.create(featureIdentifier).getValue()) ===
FeatureStatus.Entitled,
}
})
setExperimentalFeatures(experimentalFeatures)

View File

@@ -1,4 +1,4 @@
import { FeatureIdentifier, FeatureStatus } from '@standardnotes/snjs'
import { NativeFeatureIdentifier, FeatureStatus } from '@standardnotes/snjs'
import { WebApplication } from '@/Application/WebApplication'
import { ViewControllerManager } from '@/Controllers/ViewControllerManager'
@@ -24,8 +24,9 @@ const Security: FunctionComponent<SecurityProps> = (props) => {
const isNativeMobileWeb = props.application.isNativeMobileWeb()
const isU2FFeatureAvailable =
props.application.features.getFeatureStatus(FeatureIdentifier.UniversalSecondFactor) === FeatureStatus.Entitled &&
props.userProvider.getUser() !== undefined
props.application.features.getFeatureStatus(
NativeFeatureIdentifier.create(NativeFeatureIdentifier.TYPES.UniversalSecondFactor).getValue(),
) === FeatureStatus.Entitled && props.userProvider.getUser() !== undefined
return (
<PreferencesPane>

View File

@@ -3,7 +3,7 @@ import {
ComponentInterface,
UIFeature,
ContentType,
FeatureIdentifier,
NativeFeatureIdentifier,
PreferencesServiceEvent,
ThemeFeatureDescription,
} from '@standardnotes/snjs'
@@ -54,7 +54,7 @@ const QuickSettingsMenu: FunctionComponent<MenuProps> = ({ quickSettingsMenuCont
(component) =>
!component.isTheme() &&
[ComponentArea.EditorStack].includes(component.area) &&
component.identifier !== FeatureIdentifier.DeprecatedFoldersComponent,
component.identifier !== NativeFeatureIdentifier.TYPES.DeprecatedFoldersComponent,
)
setEditorStackComponents(toggleableComponents)
@@ -100,7 +100,7 @@ const QuickSettingsMenu: FunctionComponent<MenuProps> = ({ quickSettingsMenuCont
const toggleEditorStackComponent = useCallback(
(component: ComponentInterface) => {
application.componentManager.toggleComponent(component).catch(console.error)
void application.componentManager.toggleComponent(component)
},
[application],
)
@@ -141,7 +141,7 @@ const QuickSettingsMenu: FunctionComponent<MenuProps> = ({ quickSettingsMenuCont
Default
</MenuRadioButtonItem>
{themes.map((theme) => (
<ThemesMenuButton uiFeature={theme} key={theme.uniqueIdentifier} />
<ThemesMenuButton uiFeature={theme} key={theme.uniqueIdentifier.value} />
))}
<HorizontalSeparator classes="my-2" />
<FocusModeSwitch

View File

@@ -1,4 +1,4 @@
import { UIFeature, FeatureIdentifier, FeatureStatus, ThemeFeatureDescription } from '@standardnotes/snjs'
import { UIFeature, NativeFeatureIdentifier, FeatureStatus, ThemeFeatureDescription } from '@standardnotes/snjs'
import { FunctionComponent, MouseEventHandler, useCallback, useMemo } from 'react'
import Icon from '@/Components/Icon/Icon'
import { usePremiumModal } from '@/Hooks/usePremiumModal'
@@ -26,8 +26,8 @@ const ThemesMenuButton: FunctionComponent<Props> = ({ uiFeature }) => {
[application, uiFeature.featureIdentifier],
)
const isEntitledToTheme = useMemo(
() => application.features.getFeatureStatus(uiFeature.featureIdentifier) === FeatureStatus.Entitled,
[application, uiFeature.featureIdentifier],
() => application.features.getFeatureStatus(uiFeature.uniqueIdentifier) === FeatureStatus.Entitled,
[application, uiFeature.uniqueIdentifier],
)
const canActivateTheme = useMemo(() => isEntitledToTheme || isThirdPartyTheme, [isEntitledToTheme, isThirdPartyTheme])
@@ -55,10 +55,10 @@ const ThemesMenuButton: FunctionComponent<Props> = ({ uiFeature }) => {
)
const isMobile = application.isNativeMobileWeb() || isMobileScreen()
const shouldHideButton = uiFeature.featureIdentifier === FeatureIdentifier.DynamicTheme && isMobile
const shouldHideButton = uiFeature.featureIdentifier === NativeFeatureIdentifier.TYPES.DynamicTheme && isMobile
const darkThemeShortcut = useMemo(() => {
if (uiFeature.featureIdentifier === FeatureIdentifier.DarkTheme) {
if (uiFeature.featureIdentifier === NativeFeatureIdentifier.TYPES.DarkTheme) {
return commandService.keyboardShortcutForCommand(TOGGLE_DARK_MODE_COMMAND)
}
}, [commandService, uiFeature.featureIdentifier])

View File

@@ -1,4 +1,4 @@
import { FeatureIdentifier } from '@standardnotes/features'
import { NativeFeatureIdentifier } from '@standardnotes/features'
import { NoteType, PredicateCompoundOperator, PredicateJsonForm } from '@standardnotes/snjs'
import { makeObservable, observable, action } from 'mobx'
import { PredicateKeypath, PredicateKeypathTypes } from './PredicateKeypaths'
@@ -59,7 +59,7 @@ export class CompoundPredicateBuilderController {
this.setPredicate(index, { value: Object.values(NoteType)[0] })
break
case 'editorIdentifier':
this.setPredicate(index, { value: FeatureIdentifier.PlainEditor })
this.setPredicate(index, { value: NativeFeatureIdentifier.TYPES.PlainEditor })
break
case 'date':
this.setPredicate(index, { value: '1.days.ago' })

View File

@@ -7,7 +7,7 @@ import {
isPayloadSourceRetrieved,
PrefKey,
PrefDefaults,
FeatureIdentifier,
NativeFeatureIdentifier,
FeatureStatus,
GetSuperNoteFeature,
} from '@standardnotes/snjs'
@@ -76,7 +76,12 @@ export const SuperEditor: FunctionComponent<Props> = ({
useEffect(() => {
setFeatureStatus(
application.features.getFeatureStatus(FeatureIdentifier.SuperEditor, { inContextOfItem: note.current }),
application.features.getFeatureStatus(
NativeFeatureIdentifier.create(NativeFeatureIdentifier.TYPES.SuperEditor).getValue(),
{
inContextOfItem: note.current,
},
),
)
}, [application.features])

View File

@@ -4,7 +4,7 @@ import { PremiumFeatureModalType } from '@/Components/PremiumFeaturesModal/Premi
import { destroyAllObjectProperties } from '@/Utils'
import {
ApplicationEvent,
FeatureIdentifier,
NativeFeatureIdentifier,
FeatureStatus,
InternalEventBusInterface,
InternalEventInterface,
@@ -100,19 +100,25 @@ export class FeaturesController extends AbstractViewController {
}
private isEntitledToFiles(): boolean {
const status = this.application.features.getFeatureStatus(FeatureIdentifier.Files)
const status = this.application.features.getFeatureStatus(
NativeFeatureIdentifier.create(NativeFeatureIdentifier.TYPES.Files).getValue(),
)
return status === FeatureStatus.Entitled
}
private isEntitledToFolders(): boolean {
const status = this.application.features.getFeatureStatus(FeatureIdentifier.TagNesting)
const status = this.application.features.getFeatureStatus(
NativeFeatureIdentifier.create(NativeFeatureIdentifier.TYPES.TagNesting).getValue(),
)
return status === FeatureStatus.Entitled
}
private isEntitledToSmartViews(): boolean {
const status = this.application.features.getFeatureStatus(FeatureIdentifier.SmartFilters)
const status = this.application.features.getFeatureStatus(
NativeFeatureIdentifier.create(NativeFeatureIdentifier.TYPES.SmartFilters).getValue(),
)
return status === FeatureStatus.Entitled
}

View File

@@ -1,11 +1,15 @@
import { FeatureIdentifier } from '@standardnotes/snjs'
import { ComponentArea, FindNativeFeature, GetIframeAndNativeEditors } from '@standardnotes/features'
import {
ComponentArea,
FindNativeFeature,
GetIframeAndNativeEditors,
NativeFeatureIdentifier,
} from '@standardnotes/features'
import { getIconAndTintForNoteType } from './Items/Icons/getIconAndTintForNoteType'
import { DropdownItem } from '@/Components/Dropdown/DropdownItem'
import { WebApplicationInterface } from '@standardnotes/ui-services'
export type EditorOption = DropdownItem & {
value: FeatureIdentifier
value: string
isLabs?: boolean
}
@@ -19,6 +23,7 @@ export function getDropdownItemsForAllEditors(application: WebApplicationInterfa
return {
label: editor.name,
value: editor.identifier,
id: NativeFeatureIdentifier.create(editor.identifier).getValue(),
...(iconType ? { icon: iconType } : null),
...(tint ? { iconClassName: `text-accessory-tint-${tint}` } : null),
}
@@ -30,12 +35,11 @@ export function getDropdownItemsForAllEditors(application: WebApplicationInterfa
.thirdPartyComponentsForArea(ComponentArea.Editor)
.filter((component) => FindNativeFeature(component.identifier) === undefined)
.map((editor): EditorOption => {
const identifier = editor.package_info.identifier
const [iconType, tint] = getIconAndTintForNoteType(editor.noteType)
return {
label: editor.displayName,
value: identifier,
value: editor.uuid,
...(iconType ? { icon: iconType } : null),
...(tint ? { iconClassName: `text-accessory-tint-${tint}` } : null),
}

View File

@@ -1,7 +1,7 @@
import { UIFeature, FeatureIdentifier, ThemeFeatureDescription } from '@standardnotes/snjs'
import { UIFeature, NativeFeatureIdentifier, ThemeFeatureDescription } from '@standardnotes/snjs'
const isDarkModeTheme = (theme: UIFeature<ThemeFeatureDescription>) =>
theme.featureIdentifier === FeatureIdentifier.DarkTheme
theme.featureIdentifier === NativeFeatureIdentifier.TYPES.DarkTheme
export const sortThemes = (a: UIFeature<ThemeFeatureDescription>, b: UIFeature<ThemeFeatureDescription>) => {
const aIsLayerable = a.layerable

View File

@@ -7,6 +7,8 @@ import {
GetSuperNoteFeature,
UIFeature,
IframeComponentFeatureDescription,
Uuid,
NativeFeatureIdentifier,
} from '@standardnotes/snjs'
import { EditorMenuGroup } from '@/Components/NotesOptions/EditorMenuGroup'
import { EditorMenuItem } from '@/Components/NotesOptions/EditorMenuItem'
@@ -29,7 +31,9 @@ const insertNativeEditorsInMap = (map: NoteTypeToEditorRowsMap, application: Web
const noteType = editorFeature.note_type
map[noteType].push({
isEntitled: application.features.getFeatureStatus(editorFeature.identifier) === FeatureStatus.Entitled,
isEntitled:
application.features.getFeatureStatus(NativeFeatureIdentifier.create(editorFeature.identifier).getValue()) ===
FeatureStatus.Entitled,
uiFeature: new UIFeature(editorFeature),
})
}
@@ -52,7 +56,7 @@ const insertInstalledComponentsInMap = (map: NoteTypeToEditorRowsMap, applicatio
const editorItem: EditorMenuItem = {
uiFeature: new UIFeature<IframeComponentFeatureDescription>(editor),
isEntitled: application.features.getFeatureStatus(editor.identifier) === FeatureStatus.Entitled,
isEntitled: application.features.getFeatureStatus(Uuid.create(editor.uuid).getValue()) === FeatureStatus.Entitled,
}
map[noteType].push(editorItem)