refactor: rename states to view controllers (#1060)

This commit is contained in:
Mo
2022-06-01 10:15:45 -05:00
committed by GitHub
parent 78f39ec85d
commit 54125cec21
177 changed files with 1518 additions and 1365 deletions

View File

@@ -1,12 +1,4 @@
{ {
"presets": [ "presets": ["@babel/preset-typescript", "@babel/preset-env"],
"@babel/preset-typescript", "plugins": [["@babel/plugin-transform-react-jsx"]]
"@babel/preset-env"
],
"plugins": [
["@babel/plugin-transform-react-jsx", {
"pragma": "h",
"pragmaFrag": "Fragment"
}]
]
} }

View File

@@ -25,9 +25,9 @@ import { DesktopManagerInterface, SNLog } from '@standardnotes/snjs'
import ApplicationGroupView from './Components/ApplicationGroupView/ApplicationGroupView' import ApplicationGroupView from './Components/ApplicationGroupView/ApplicationGroupView'
import { WebDevice } from './Device/WebDevice' import { WebDevice } from './Device/WebDevice'
import { StartApplication } from './Device/StartApplication' import { StartApplication } from './Device/StartApplication'
import { ApplicationGroup } from './UIModels/ApplicationGroup' import { ApplicationGroup } from './Application/ApplicationGroup'
import { WebOrDesktopDevice } from './Device/WebOrDesktopDevice' import { WebOrDesktopDevice } from './Device/WebOrDesktopDevice'
import { WebApplication } from './UIModels/Application' import { WebApplication } from './Application/Application'
import { createRoot, Root } from 'react-dom/client' import { createRoot, Root } from 'react-dom/client'
let keyCount = 0 let keyCount = 0

View File

@@ -5,7 +5,7 @@ import { AutolockService } from '@/Services/AutolockService'
import { DesktopManager } from '@/Services/DesktopManager' import { DesktopManager } from '@/Services/DesktopManager'
import { IOService } from '@/Services/IOService' import { IOService } from '@/Services/IOService'
import { ThemeManager } from '@/Services/ThemeManager' import { ThemeManager } from '@/Services/ThemeManager'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { WebOrDesktopDevice } from '@/Device/WebOrDesktopDevice' import { WebOrDesktopDevice } from '@/Device/WebOrDesktopDevice'
import { import {
DeinitSource, DeinitSource,
@@ -21,7 +21,7 @@ import {
import { makeObservable, observable } from 'mobx' import { makeObservable, observable } from 'mobx'
type WebServices = { type WebServices = {
appState: AppState viewControllerManager: ViewControllerManager
desktopService?: DesktopManager desktopService?: DesktopManager
autolockService: AutolockService autolockService: AutolockService
archiveService: ArchiveManager archiveService: ArchiveManager
@@ -116,8 +116,8 @@ export class WebApplication extends SNApplication {
} }
} }
public getAppState(): AppState { public getViewControllerManager(): ViewControllerManager {
return this.webServices.appState return this.webServices.viewControllerManager
} }
public getDesktopService(): DesktopManager | undefined { public getDesktopService(): DesktopManager | undefined {

View File

@@ -6,7 +6,7 @@ import {
InternalEventBus, InternalEventBus,
isDesktopDevice, isDesktopDevice,
} from '@standardnotes/snjs' } from '@standardnotes/snjs'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { getPlatform, isDesktopApplication } from '@/Utils' import { getPlatform, isDesktopApplication } from '@/Utils'
import { ArchiveManager } from '@/Services/ArchiveManager' import { ArchiveManager } from '@/Services/ArchiveManager'
import { DesktopManager } from '@/Services/DesktopManager' import { DesktopManager } from '@/Services/DesktopManager'
@@ -32,14 +32,14 @@ const createApplication = (
webSocketUrl, webSocketUrl,
) )
const appState = new AppState(application, device) const viewControllerManager = new ViewControllerManager(application, device)
const archiveService = new ArchiveManager(application) const archiveService = new ArchiveManager(application)
const io = new IOService(platform === Platform.MacWeb || platform === Platform.MacDesktop) const io = new IOService(platform === Platform.MacWeb || platform === Platform.MacDesktop)
const autolockService = new AutolockService(application, new InternalEventBus()) const autolockService = new AutolockService(application, new InternalEventBus())
const themeService = new ThemeManager(application) const themeService = new ThemeManager(application)
application.setWebServices({ application.setWebServices({
appState, viewControllerManager,
archiveService, archiveService,
desktopService: isDesktopDevice(device) ? new DesktopManager(application, device) : undefined, desktopService: isDesktopDevice(device) ? new DesktopManager(application, device) : undefined,
io, io,

View File

@@ -1,8 +1,9 @@
import { ApplicationEvent } from '@standardnotes/snjs' import { ApplicationEvent } from '@standardnotes/snjs'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { AppState, AppStateEvent } from '@/UIModels/AppState' import { ViewControllerManager, ViewControllerManagerEvent } from '@/Services/ViewControllerManager'
import { autorun, IReactionDisposer, IReactionPublic } from 'mobx' import { autorun, IReactionDisposer, IReactionPublic } from 'mobx'
import { Component } from 'react' import { Component } from 'react'
export type PureComponentState = Partial<Record<string, any>> export type PureComponentState = Partial<Record<string, any>>
export type PureComponentProps = Partial<Record<string, any>> export type PureComponentProps = Partial<Record<string, any>>
@@ -17,7 +18,7 @@ export abstract class PureComponent<P = PureComponentProps, S = PureComponentSta
override componentDidMount() { override componentDidMount() {
this.addAppEventObserver() this.addAppEventObserver()
this.addAppStateObserver() this.addViewControllerManagerObserver()
} }
deinit(): void { deinit(): void {
@@ -38,21 +39,21 @@ export abstract class PureComponent<P = PureComponentProps, S = PureComponentSta
this.deinit() this.deinit()
} }
public get appState(): AppState { public get viewControllerManager(): ViewControllerManager {
return this.application.getAppState() return this.application.getViewControllerManager()
} }
autorun(view: (r: IReactionPublic) => void): void { autorun(view: (r: IReactionPublic) => void): void {
this.reactionDisposers.push(autorun(view)) this.reactionDisposers.push(autorun(view))
} }
addAppStateObserver() { addViewControllerManagerObserver() {
this.unsubState = this.application.getAppState().addObserver(async (eventName, data) => { this.unsubState = this.application.getViewControllerManager().addObserver(async (eventName, data) => {
this.onAppStateEvent(eventName, data) this.onViewControllerManagerEvent(eventName, data)
}) })
} }
onAppStateEvent(_eventName: AppStateEvent, _data: unknown) { onViewControllerManagerEvent(_eventName: ViewControllerManagerEvent, _data: unknown) {
/** Optional override */ /** Optional override */
} }

View File

@@ -1,31 +1,36 @@
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { useCloseOnClickOutside } from '@/Hooks/useCloseOnClickOutside' import { useCloseOnClickOutside } from '@/Hooks/useCloseOnClickOutside'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { useCallback, useRef, FunctionComponent, KeyboardEventHandler } from 'react' import { useCallback, useRef, FunctionComponent, KeyboardEventHandler } from 'react'
import { ApplicationGroup } from '@/UIModels/ApplicationGroup' import { ApplicationGroup } from '@/Application/ApplicationGroup'
import { AccountMenuPane } from './AccountMenuPane' import { AccountMenuPane } from './AccountMenuPane'
import MenuPaneSelector from './MenuPaneSelector' import MenuPaneSelector from './MenuPaneSelector'
type Props = { type Props = {
appState: AppState viewControllerManager: ViewControllerManager
application: WebApplication application: WebApplication
onClickOutside: () => void onClickOutside: () => void
mainApplicationGroup: ApplicationGroup mainApplicationGroup: ApplicationGroup
} }
const AccountMenu: FunctionComponent<Props> = ({ application, appState, onClickOutside, mainApplicationGroup }) => { const AccountMenu: FunctionComponent<Props> = ({
const { currentPane, shouldAnimateCloseMenu } = appState.accountMenu application,
viewControllerManager,
onClickOutside,
mainApplicationGroup,
}) => {
const { currentPane, shouldAnimateCloseMenu } = viewControllerManager.accountMenuController
const closeAccountMenu = useCallback(() => { const closeAccountMenu = useCallback(() => {
appState.accountMenu.closeAccountMenu() viewControllerManager.accountMenuController.closeAccountMenu()
}, [appState]) }, [viewControllerManager])
const setCurrentPane = useCallback( const setCurrentPane = useCallback(
(pane: AccountMenuPane) => { (pane: AccountMenuPane) => {
appState.accountMenu.setCurrentPane(pane) viewControllerManager.accountMenuController.setCurrentPane(pane)
}, },
[appState], [viewControllerManager],
) )
const ref = useRef<HTMLDivElement>(null) const ref = useRef<HTMLDivElement>(null)
@@ -59,7 +64,7 @@ const AccountMenu: FunctionComponent<Props> = ({ application, appState, onClickO
onKeyDown={handleKeyDown} onKeyDown={handleKeyDown}
> >
<MenuPaneSelector <MenuPaneSelector
appState={appState} viewControllerManager={viewControllerManager}
application={application} application={application}
mainApplicationGroup={mainApplicationGroup} mainApplicationGroup={mainApplicationGroup}
menuPane={currentPane} menuPane={currentPane}

View File

@@ -1,5 +1,5 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { ChangeEventHandler, FunctionComponent, useCallback, useEffect, useState } from 'react' import { ChangeEventHandler, FunctionComponent, useCallback, useEffect, useState } from 'react'
import Checkbox from '@/Components/Checkbox/Checkbox' import Checkbox from '@/Components/Checkbox/Checkbox'
@@ -8,21 +8,21 @@ import Icon from '@/Components/Icon/Icon'
type Props = { type Props = {
application: WebApplication application: WebApplication
appState: AppState viewControllerManager: ViewControllerManager
disabled?: boolean disabled?: boolean
onPrivateWorkspaceChange?: (isPrivate: boolean, identifier?: string) => void onPrivateWorkspaceChange?: (isPrivate: boolean, identifier?: string) => void
onStrictSignInChange?: (isStrictSignIn: boolean) => void onStrictSignInChange?: (isStrictSignIn: boolean) => void
} }
const AdvancedOptions: FunctionComponent<Props> = ({ const AdvancedOptions: FunctionComponent<Props> = ({
appState, viewControllerManager,
application, application,
disabled = false, disabled = false,
onPrivateWorkspaceChange, onPrivateWorkspaceChange,
onStrictSignInChange, onStrictSignInChange,
children, children,
}) => { }) => {
const { server, setServer, enableServerOption, setEnableServerOption } = appState.accountMenu const { server, setServer, enableServerOption, setEnableServerOption } = viewControllerManager.accountMenuController
const [showAdvanced, setShowAdvanced] = useState(false) const [showAdvanced, setShowAdvanced] = useState(false)
const [isPrivateWorkspace, setIsPrivateWorkspace] = useState(false) const [isPrivateWorkspace, setIsPrivateWorkspace] = useState(false)

View File

@@ -1,6 +1,6 @@
import { STRING_NON_MATCHING_PASSWORDS } from '@/Strings' import { STRING_NON_MATCHING_PASSWORDS } from '@/Strings'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { FunctionComponent, KeyboardEventHandler, useCallback, useEffect, useRef, useState } from 'react' import { FunctionComponent, KeyboardEventHandler, useCallback, useEffect, useRef, useState } from 'react'
import { AccountMenuPane } from './AccountMenuPane' import { AccountMenuPane } from './AccountMenuPane'
@@ -11,15 +11,21 @@ import Icon from '@/Components/Icon/Icon'
import IconButton from '@/Components/Button/IconButton' import IconButton from '@/Components/Button/IconButton'
type Props = { type Props = {
appState: AppState viewControllerManager: ViewControllerManager
application: WebApplication application: WebApplication
setMenuPane: (pane: AccountMenuPane) => void setMenuPane: (pane: AccountMenuPane) => void
email: string email: string
password: string password: string
} }
const ConfirmPassword: FunctionComponent<Props> = ({ application, appState, setMenuPane, email, password }) => { const ConfirmPassword: FunctionComponent<Props> = ({
const { notesAndTagsCount } = appState.accountMenu application,
viewControllerManager,
setMenuPane,
email,
password,
}) => {
const { notesAndTagsCount } = viewControllerManager.accountMenuController
const [confirmPassword, setConfirmPassword] = useState('') const [confirmPassword, setConfirmPassword] = useState('')
const [isRegistering, setIsRegistering] = useState(false) const [isRegistering, setIsRegistering] = useState(false)
const [isEphemeral, setIsEphemeral] = useState(false) const [isEphemeral, setIsEphemeral] = useState(false)
@@ -61,8 +67,8 @@ const ConfirmPassword: FunctionComponent<Props> = ({ application, appState, setM
if (res.error) { if (res.error) {
throw new Error(res.error.message) throw new Error(res.error.message)
} }
appState.accountMenu.closeAccountMenu() viewControllerManager.accountMenuController.closeAccountMenu()
appState.accountMenu.setCurrentPane(AccountMenuPane.GeneralMenu) viewControllerManager.accountMenuController.setCurrentPane(AccountMenuPane.GeneralMenu)
}) })
.catch((err) => { .catch((err) => {
console.error(err) console.error(err)
@@ -77,7 +83,7 @@ const ConfirmPassword: FunctionComponent<Props> = ({ application, appState, setM
passwordInputRef.current?.focus() passwordInputRef.current?.focus()
} }
}, },
[appState, application, confirmPassword, email, isEphemeral, password, shouldMergeLocal], [viewControllerManager, application, confirmPassword, email, isEphemeral, password, shouldMergeLocal],
) )
const handleKeyDown: KeyboardEventHandler = useCallback( const handleKeyDown: KeyboardEventHandler = useCallback(

View File

@@ -1,5 +1,5 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { FunctionComponent, KeyboardEventHandler, useCallback, useEffect, useRef, useState } from 'react' import { FunctionComponent, KeyboardEventHandler, useCallback, useEffect, useRef, useState } from 'react'
import { AccountMenuPane } from './AccountMenuPane' import { AccountMenuPane } from './AccountMenuPane'
@@ -11,7 +11,7 @@ import IconButton from '@/Components/Button/IconButton'
import AdvancedOptions from './AdvancedOptions' import AdvancedOptions from './AdvancedOptions'
type Props = { type Props = {
appState: AppState viewControllerManager: ViewControllerManager
application: WebApplication application: WebApplication
setMenuPane: (pane: AccountMenuPane) => void setMenuPane: (pane: AccountMenuPane) => void
email: string email: string
@@ -21,7 +21,7 @@ type Props = {
} }
const CreateAccount: FunctionComponent<Props> = ({ const CreateAccount: FunctionComponent<Props> = ({
appState, viewControllerManager,
application, application,
setMenuPane, setMenuPane,
email, email,
@@ -137,7 +137,7 @@ const CreateAccount: FunctionComponent<Props> = ({
<div className="h-1px my-2 bg-border"></div> <div className="h-1px my-2 bg-border"></div>
<AdvancedOptions <AdvancedOptions
application={application} application={application}
appState={appState} viewControllerManager={viewControllerManager}
onPrivateWorkspaceChange={onPrivateWorkspaceChange} onPrivateWorkspaceChange={onPrivateWorkspaceChange}
/> />
</> </>

View File

@@ -1,5 +1,5 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import Icon from '@/Components/Icon/Icon' import Icon from '@/Components/Icon/Icon'
import { SyncQueueStrategy } from '@standardnotes/snjs' import { SyncQueueStrategy } from '@standardnotes/snjs'
@@ -11,11 +11,11 @@ import MenuItem from '@/Components/Menu/MenuItem'
import MenuItemSeparator from '@/Components/Menu/MenuItemSeparator' import MenuItemSeparator from '@/Components/Menu/MenuItemSeparator'
import { MenuItemType } from '@/Components/Menu/MenuItemType' import { MenuItemType } from '@/Components/Menu/MenuItemType'
import WorkspaceSwitcherOption from './WorkspaceSwitcher/WorkspaceSwitcherOption' import WorkspaceSwitcherOption from './WorkspaceSwitcher/WorkspaceSwitcherOption'
import { ApplicationGroup } from '@/UIModels/ApplicationGroup' import { ApplicationGroup } from '@/Application/ApplicationGroup'
import { formatLastSyncDate } from '@/Utils/FormatLastSyncDate' import { formatLastSyncDate } from '@/Utils/FormatLastSyncDate'
type Props = { type Props = {
appState: AppState viewControllerManager: ViewControllerManager
application: WebApplication application: WebApplication
mainApplicationGroup: ApplicationGroup mainApplicationGroup: ApplicationGroup
setMenuPane: (pane: AccountMenuPane) => void setMenuPane: (pane: AccountMenuPane) => void
@@ -26,7 +26,7 @@ const iconClassName = 'color-neutral mr-2'
const GeneralAccountMenu: FunctionComponent<Props> = ({ const GeneralAccountMenu: FunctionComponent<Props> = ({
application, application,
appState, viewControllerManager,
setMenuPane, setMenuPane,
closeMenu, closeMenu,
mainApplicationGroup, mainApplicationGroup,
@@ -60,20 +60,20 @@ const GeneralAccountMenu: FunctionComponent<Props> = ({
const user = useMemo(() => application.getUser(), [application]) const user = useMemo(() => application.getUser(), [application])
const openPreferences = useCallback(() => { const openPreferences = useCallback(() => {
appState.accountMenu.closeAccountMenu() viewControllerManager.accountMenuController.closeAccountMenu()
appState.preferences.setCurrentPane('account') viewControllerManager.preferencesController.setCurrentPane('account')
appState.preferences.openPreferences() viewControllerManager.preferencesController.openPreferences()
}, [appState]) }, [viewControllerManager])
const openHelp = useCallback(() => { const openHelp = useCallback(() => {
appState.accountMenu.closeAccountMenu() viewControllerManager.accountMenuController.closeAccountMenu()
appState.preferences.setCurrentPane('help-feedback') viewControllerManager.preferencesController.setCurrentPane('help-feedback')
appState.preferences.openPreferences() viewControllerManager.preferencesController.openPreferences()
}, [appState]) }, [viewControllerManager])
const signOut = useCallback(() => { const signOut = useCallback(() => {
appState.accountMenu.setSigningOut(true) viewControllerManager.accountMenuController.setSigningOut(true)
}, [appState]) }, [viewControllerManager])
const activateRegisterPane = useCallback(() => { const activateRegisterPane = useCallback(() => {
setMenuPane(AccountMenuPane.Register) setMenuPane(AccountMenuPane.Register)
@@ -136,13 +136,16 @@ const GeneralAccountMenu: FunctionComponent<Props> = ({
</> </>
)} )}
<Menu <Menu
isOpen={appState.accountMenu.show} isOpen={viewControllerManager.accountMenuController.show}
a11yLabel="General account menu" a11yLabel="General account menu"
closeMenu={closeMenu} closeMenu={closeMenu}
initialFocus={!application.hasAccount() ? CREATE_ACCOUNT_INDEX : SWITCHER_INDEX} initialFocus={!application.hasAccount() ? CREATE_ACCOUNT_INDEX : SWITCHER_INDEX}
> >
<MenuItemSeparator /> <MenuItemSeparator />
<WorkspaceSwitcherOption mainApplicationGroup={mainApplicationGroup} appState={appState} /> <WorkspaceSwitcherOption
mainApplicationGroup={mainApplicationGroup}
viewControllerManager={viewControllerManager}
/>
<MenuItemSeparator /> <MenuItemSeparator />
{user ? ( {user ? (
<MenuItem type={MenuItemType.IconButton} onClick={openPreferences}> <MenuItem type={MenuItemType.IconButton} onClick={openPreferences}>
@@ -166,7 +169,7 @@ const GeneralAccountMenu: FunctionComponent<Props> = ({
<Icon type="help" className={iconClassName} /> <Icon type="help" className={iconClassName} />
Help &amp; feedback Help &amp; feedback
</div> </div>
<span className="color-neutral">v{appState.version}</span> <span className="color-neutral">v{viewControllerManager.version}</span>
</MenuItem> </MenuItem>
{user ? ( {user ? (
<> <>

View File

@@ -1,6 +1,6 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { ApplicationGroup } from '@/UIModels/ApplicationGroup' import { ApplicationGroup } from '@/Application/ApplicationGroup'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { FunctionComponent, useState } from 'react' import { FunctionComponent, useState } from 'react'
import { AccountMenuPane } from './AccountMenuPane' import { AccountMenuPane } from './AccountMenuPane'
@@ -10,7 +10,7 @@ import GeneralAccountMenu from './GeneralAccountMenu'
import SignInPane from './SignIn' import SignInPane from './SignIn'
type Props = { type Props = {
appState: AppState viewControllerManager: ViewControllerManager
application: WebApplication application: WebApplication
mainApplicationGroup: ApplicationGroup mainApplicationGroup: ApplicationGroup
menuPane: AccountMenuPane menuPane: AccountMenuPane
@@ -20,7 +20,7 @@ type Props = {
const MenuPaneSelector: FunctionComponent<Props> = ({ const MenuPaneSelector: FunctionComponent<Props> = ({
application, application,
appState, viewControllerManager,
menuPane, menuPane,
setMenuPane, setMenuPane,
closeMenu, closeMenu,
@@ -33,7 +33,7 @@ const MenuPaneSelector: FunctionComponent<Props> = ({
case AccountMenuPane.GeneralMenu: case AccountMenuPane.GeneralMenu:
return ( return (
<GeneralAccountMenu <GeneralAccountMenu
appState={appState} viewControllerManager={viewControllerManager}
application={application} application={application}
mainApplicationGroup={mainApplicationGroup} mainApplicationGroup={mainApplicationGroup}
setMenuPane={setMenuPane} setMenuPane={setMenuPane}
@@ -41,11 +41,13 @@ const MenuPaneSelector: FunctionComponent<Props> = ({
/> />
) )
case AccountMenuPane.SignIn: case AccountMenuPane.SignIn:
return <SignInPane appState={appState} application={application} setMenuPane={setMenuPane} /> return (
<SignInPane viewControllerManager={viewControllerManager} application={application} setMenuPane={setMenuPane} />
)
case AccountMenuPane.Register: case AccountMenuPane.Register:
return ( return (
<CreateAccount <CreateAccount
appState={appState} viewControllerManager={viewControllerManager}
application={application} application={application}
setMenuPane={setMenuPane} setMenuPane={setMenuPane}
email={email} email={email}
@@ -57,7 +59,7 @@ const MenuPaneSelector: FunctionComponent<Props> = ({
case AccountMenuPane.ConfirmPassword: case AccountMenuPane.ConfirmPassword:
return ( return (
<ConfirmPassword <ConfirmPassword
appState={appState} viewControllerManager={viewControllerManager}
application={application} application={application}
setMenuPane={setMenuPane} setMenuPane={setMenuPane}
email={email} email={email}

View File

@@ -1,5 +1,5 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { isDev } from '@/Utils' import { isDev } from '@/Utils'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import React, { FunctionComponent, KeyboardEventHandler, useCallback, useEffect, useRef, useState } from 'react' import React, { FunctionComponent, KeyboardEventHandler, useCallback, useEffect, useRef, useState } from 'react'
@@ -13,13 +13,13 @@ import IconButton from '@/Components/Button/IconButton'
import AdvancedOptions from './AdvancedOptions' import AdvancedOptions from './AdvancedOptions'
type Props = { type Props = {
appState: AppState viewControllerManager: ViewControllerManager
application: WebApplication application: WebApplication
setMenuPane: (pane: AccountMenuPane) => void setMenuPane: (pane: AccountMenuPane) => void
} }
const SignInPane: FunctionComponent<Props> = ({ application, appState, setMenuPane }) => { const SignInPane: FunctionComponent<Props> = ({ application, viewControllerManager, setMenuPane }) => {
const { notesAndTagsCount } = appState.accountMenu const { notesAndTagsCount } = viewControllerManager.accountMenuController
const [email, setEmail] = useState('') const [email, setEmail] = useState('')
const [password, setPassword] = useState('') const [password, setPassword] = useState('')
const [error, setError] = useState('') const [error, setError] = useState('')
@@ -86,7 +86,7 @@ const SignInPane: FunctionComponent<Props> = ({ application, appState, setMenuPa
if (res.error) { if (res.error) {
throw new Error(res.error.message) throw new Error(res.error.message)
} }
appState.accountMenu.closeAccountMenu() viewControllerManager.accountMenuController.closeAccountMenu()
}) })
.catch((err) => { .catch((err) => {
console.error(err) console.error(err)
@@ -97,7 +97,7 @@ const SignInPane: FunctionComponent<Props> = ({ application, appState, setMenuPa
.finally(() => { .finally(() => {
setIsSigningIn(false) setIsSigningIn(false)
}) })
}, [appState, application, email, isEphemeral, isStrictSignin, password, shouldMergeLocal]) }, [viewControllerManager, application, email, isEphemeral, isStrictSignin, password, shouldMergeLocal])
const onPrivateWorkspaceChange = useCallback( const onPrivateWorkspaceChange = useCallback(
(newIsPrivateWorkspace: boolean, privateWorkspaceIdentifier?: string) => { (newIsPrivateWorkspace: boolean, privateWorkspaceIdentifier?: string) => {
@@ -201,7 +201,7 @@ const SignInPane: FunctionComponent<Props> = ({ application, appState, setMenuPa
</div> </div>
<div className="h-1px my-2 bg-border"></div> <div className="h-1px my-2 bg-border"></div>
<AdvancedOptions <AdvancedOptions
appState={appState} viewControllerManager={viewControllerManager}
application={application} application={application}
disabled={isSigningIn} disabled={isSigningIn}
onPrivateWorkspaceChange={onPrivateWorkspaceChange} onPrivateWorkspaceChange={onPrivateWorkspaceChange}

View File

@@ -1,24 +1,25 @@
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { User as UserType } from '@standardnotes/snjs' import { User as UserType } from '@standardnotes/snjs'
type Props = { type Props = {
appState: AppState viewControllerManager: ViewControllerManager
application: WebApplication application: WebApplication
} }
const User = ({ appState, application }: Props) => { const User = ({ viewControllerManager, application }: Props) => {
const { server } = appState.accountMenu const { server } = viewControllerManager.accountMenuController
const user = application.getUser() as UserType const user = application.getUser() as UserType
return ( return (
<div className="sk-panel-section"> <div className="sk-panel-section">
{appState.sync.errorMessage && ( {viewControllerManager.syncStatusController.errorMessage && (
<div className="sk-notification danger"> <div className="sk-notification danger">
<div className="sk-notification-title">Sync Unreachable</div> <div className="sk-notification-title">Sync Unreachable</div>
<div className="sk-notification-text"> <div className="sk-notification-text">
Hmm...we can't seem to sync your account. The reason: {appState.sync.errorMessage} Hmm...we can't seem to sync your account. The reason:{' '}
{viewControllerManager.syncStatusController.errorMessage}
</div> </div>
<a <a
className="sk-a info-contrast sk-bold sk-panel-row" className="sk-a info-contrast sk-bold sk-panel-row"

View File

@@ -1,5 +1,5 @@
import { ApplicationGroup } from '@/UIModels/ApplicationGroup' import { ApplicationGroup } from '@/Application/ApplicationGroup'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { ApplicationDescriptor, ApplicationGroupEvent, ButtonType } from '@standardnotes/snjs' import { ApplicationDescriptor, ApplicationGroupEvent, ButtonType } from '@standardnotes/snjs'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { FunctionComponent, useCallback, useEffect, useState } from 'react' import { FunctionComponent, useCallback, useEffect, useState } from 'react'
@@ -12,14 +12,14 @@ import WorkspaceMenuItem from './WorkspaceMenuItem'
type Props = { type Props = {
mainApplicationGroup: ApplicationGroup mainApplicationGroup: ApplicationGroup
appState: AppState viewControllerManager: ViewControllerManager
isOpen: boolean isOpen: boolean
hideWorkspaceOptions?: boolean hideWorkspaceOptions?: boolean
} }
const WorkspaceSwitcherMenu: FunctionComponent<Props> = ({ const WorkspaceSwitcherMenu: FunctionComponent<Props> = ({
mainApplicationGroup, mainApplicationGroup,
appState, viewControllerManager,
isOpen, isOpen,
hideWorkspaceOptions = false, hideWorkspaceOptions = false,
}: Props) => { }: Props) => {
@@ -42,7 +42,7 @@ const WorkspaceSwitcherMenu: FunctionComponent<Props> = ({
}, [mainApplicationGroup]) }, [mainApplicationGroup])
const signoutAll = useCallback(async () => { const signoutAll = useCallback(async () => {
const confirmed = await appState.application.alertService.confirm( const confirmed = await viewControllerManager.application.alertService.confirm(
'Are you sure you want to sign out of all workspaces on this device?', 'Are you sure you want to sign out of all workspaces on this device?',
undefined, undefined,
'Sign out all', 'Sign out all',
@@ -52,11 +52,11 @@ const WorkspaceSwitcherMenu: FunctionComponent<Props> = ({
return return
} }
mainApplicationGroup.signOutAllWorkspaces().catch(console.error) mainApplicationGroup.signOutAllWorkspaces().catch(console.error)
}, [mainApplicationGroup, appState]) }, [mainApplicationGroup, viewControllerManager])
const destroyWorkspace = useCallback(() => { const destroyWorkspace = useCallback(() => {
appState.accountMenu.setSigningOut(true) viewControllerManager.accountMenuController.setSigningOut(true)
}, [appState]) }, [viewControllerManager])
return ( return (
<Menu a11yLabel="Workspace switcher menu" className="px-0 focus:shadow-none" isOpen={isOpen}> <Menu a11yLabel="Workspace switcher menu" className="px-0 focus:shadow-none" isOpen={isOpen}>

View File

@@ -1,6 +1,6 @@
import { FOCUSABLE_BUT_NOT_TABBABLE } from '@/Constants' import { FOCUSABLE_BUT_NOT_TABBABLE } from '@/Constants'
import { ApplicationGroup } from '@/UIModels/ApplicationGroup' import { ApplicationGroup } from '@/Application/ApplicationGroup'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { calculateSubmenuStyle, SubmenuStyle } from '@/Utils/CalculateSubmenuStyle' import { calculateSubmenuStyle, SubmenuStyle } from '@/Utils/CalculateSubmenuStyle'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { FunctionComponent, useCallback, useEffect, useRef, useState } from 'react' import { FunctionComponent, useCallback, useEffect, useRef, useState } from 'react'
@@ -9,10 +9,10 @@ import WorkspaceSwitcherMenu from './WorkspaceSwitcherMenu'
type Props = { type Props = {
mainApplicationGroup: ApplicationGroup mainApplicationGroup: ApplicationGroup
appState: AppState viewControllerManager: ViewControllerManager
} }
const WorkspaceSwitcherOption: FunctionComponent<Props> = ({ mainApplicationGroup, appState }) => { const WorkspaceSwitcherOption: FunctionComponent<Props> = ({ mainApplicationGroup, viewControllerManager }) => {
const buttonRef = useRef<HTMLButtonElement>(null) const buttonRef = useRef<HTMLButtonElement>(null)
const menuRef = useRef<HTMLDivElement>(null) const menuRef = useRef<HTMLDivElement>(null)
const [isOpen, setIsOpen] = useState(false) const [isOpen, setIsOpen] = useState(false)
@@ -58,7 +58,11 @@ const WorkspaceSwitcherOption: FunctionComponent<Props> = ({ mainApplicationGrou
</button> </button>
{isOpen && ( {isOpen && (
<div ref={menuRef} className="sn-dropdown max-h-120 min-w-68 py-2 fixed overflow-y-auto" style={menuStyle}> <div ref={menuRef} className="sn-dropdown max-h-120 min-w-68 py-2 fixed overflow-y-auto" style={menuStyle}>
<WorkspaceSwitcherMenu mainApplicationGroup={mainApplicationGroup} appState={appState} isOpen={isOpen} /> <WorkspaceSwitcherMenu
mainApplicationGroup={mainApplicationGroup}
viewControllerManager={viewControllerManager}
isOpen={isOpen}
/>
</div> </div>
)} )}
</> </>

View File

@@ -1,5 +1,5 @@
import { ApplicationGroup } from '@/UIModels/ApplicationGroup' import { ApplicationGroup } from '@/Application/ApplicationGroup'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { Component } from 'react' import { Component } from 'react'
import ApplicationView from '@/Components/ApplicationView/ApplicationView' import ApplicationView from '@/Components/ApplicationView/ApplicationView'
import { WebOrDesktopDevice } from '@/Device/WebOrDesktopDevice' import { WebOrDesktopDevice } from '@/Device/WebOrDesktopDevice'

View File

@@ -1,10 +1,10 @@
import { ApplicationGroup } from '@/UIModels/ApplicationGroup' import { ApplicationGroup } from '@/Application/ApplicationGroup'
import { getPlatformString, getWindowUrlParams } from '@/Utils' import { getPlatformString, getWindowUrlParams } from '@/Utils'
import { AppStateEvent, PanelResizedData } from '@/UIModels/AppState' import { ViewControllerManagerEvent } from '@/Services/ViewControllerManager'
import { ApplicationEvent, Challenge, removeFromArray } from '@standardnotes/snjs' import { ApplicationEvent, Challenge, removeFromArray } from '@standardnotes/snjs'
import { PANEL_NAME_NOTES, PANEL_NAME_NAVIGATION } from '@/Constants' import { PANEL_NAME_NOTES, PANEL_NAME_NAVIGATION } from '@/Constants'
import { alertDialog } from '@/Services/AlertService' import { alertDialog } from '@/Services/AlertService'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import Navigation from '@/Components/Navigation/Navigation' import Navigation from '@/Components/Navigation/Navigation'
import NoteGroupView from '@/Components/NoteGroupView/NoteGroupView' import NoteGroupView from '@/Components/NoteGroupView/NoteGroupView'
import Footer from '@/Components/Footer/Footer' import Footer from '@/Components/Footer/Footer'
@@ -23,6 +23,7 @@ import FilePreviewModalWrapper from '@/Components/Files/FilePreviewModal'
import ContentListView from '@/Components/ContentListView/ContentListView' import ContentListView from '@/Components/ContentListView/ContentListView'
import FileContextMenuWrapper from '@/Components/FileContextMenu/FileContextMenu' import FileContextMenuWrapper from '@/Components/FileContextMenu/FileContextMenu'
import PermissionsModalWrapper from '@/Components/PermissionsModal/PermissionsModalWrapper' import PermissionsModalWrapper from '@/Components/PermissionsModal/PermissionsModalWrapper'
import { PanelResizedData } from '@/Typings/PanelResizedData'
type Props = { type Props = {
application: WebApplication application: WebApplication
@@ -36,7 +37,7 @@ const ApplicationView: FunctionComponent<Props> = ({ application, mainApplicatio
const [needsUnlock, setNeedsUnlock] = useState(true) const [needsUnlock, setNeedsUnlock] = useState(true)
const [challenges, setChallenges] = useState<Challenge[]>([]) const [challenges, setChallenges] = useState<Challenge[]>([])
const appState = application.getAppState() const viewControllerManager = application.getViewControllerManager()
useEffect(() => { useEffect(() => {
const desktopService = application.getDesktopService() const desktopService = application.getDesktopService()
@@ -119,8 +120,8 @@ const ApplicationView: FunctionComponent<Props> = ({ application, mainApplicatio
}, [application, onAppLaunch, onAppStart]) }, [application, onAppLaunch, onAppStart])
useEffect(() => { useEffect(() => {
const removeObserver = application.getAppState().addObserver(async (eventName, data) => { const removeObserver = application.getViewControllerManager().addObserver(async (eventName, data) => {
if (eventName === AppStateEvent.PanelResized) { if (eventName === ViewControllerManagerEvent.PanelResized) {
const { panel, collapsed } = data as PanelResizedData const { panel, collapsed } = data as PanelResizedData
let appClass = '' let appClass = ''
if (panel === PANEL_NAME_NOTES && collapsed) { if (panel === PANEL_NAME_NOTES && collapsed) {
@@ -130,7 +131,7 @@ const ApplicationView: FunctionComponent<Props> = ({ application, mainApplicatio
appClass += ' collapsed-navigation' appClass += ' collapsed-navigation'
} }
setAppClass(appClass) setAppClass(appClass)
} else if (eventName === AppStateEvent.WindowDidFocus) { } else if (eventName === ViewControllerManagerEvent.WindowDidFocus) {
if (!(await application.isLocked())) { if (!(await application.isLocked())) {
application.sync.sync().catch(console.error) application.sync.sync().catch(console.error)
} }
@@ -155,7 +156,7 @@ const ApplicationView: FunctionComponent<Props> = ({ application, mainApplicatio
<ChallengeModal <ChallengeModal
key={`${challenge.id}${application.ephemeralIdentifier}`} key={`${challenge.id}${application.ephemeralIdentifier}`}
application={application} application={application}
appState={appState} viewControllerManager={viewControllerManager}
mainApplicationGroup={mainApplicationGroup} mainApplicationGroup={mainApplicationGroup}
challenge={challenge} challenge={challenge}
onDismiss={removeChallenge} onDismiss={removeChallenge}
@@ -165,42 +166,42 @@ const ApplicationView: FunctionComponent<Props> = ({ application, mainApplicatio
})} })}
</> </>
) )
}, [appState, challenges, mainApplicationGroup, removeChallenge, application]) }, [viewControllerManager, challenges, mainApplicationGroup, removeChallenge, application])
if (!renderAppContents) { if (!renderAppContents) {
return renderChallenges() return renderChallenges()
} }
return ( return (
<PremiumModalProvider application={application} appState={appState}> <PremiumModalProvider application={application} viewControllerManager={viewControllerManager}>
<div className={platformString + ' main-ui-view sn-component'}> <div className={platformString + ' main-ui-view sn-component'}>
<div id="app" className={appClass + ' app app-column-container'}> <div id="app" className={appClass + ' app app-column-container'}>
<Navigation application={application} /> <Navigation application={application} />
<ContentListView application={application} appState={appState} /> <ContentListView application={application} viewControllerManager={viewControllerManager} />
<NoteGroupView application={application} /> <NoteGroupView application={application} />
</div> </div>
<> <>
<Footer application={application} applicationGroup={mainApplicationGroup} /> <Footer application={application} applicationGroup={mainApplicationGroup} />
<SessionsModal application={application} appState={appState} /> <SessionsModal application={application} viewControllerManager={viewControllerManager} />
<PreferencesViewWrapper appState={appState} application={application} /> <PreferencesViewWrapper viewControllerManager={viewControllerManager} application={application} />
<RevisionHistoryModalWrapper application={application} appState={appState} /> <RevisionHistoryModalWrapper application={application} viewControllerManager={viewControllerManager} />
</> </>
{renderChallenges()} {renderChallenges()}
<> <>
<NotesContextMenu application={application} appState={appState} /> <NotesContextMenu application={application} viewControllerManager={viewControllerManager} />
<TagsContextMenuWrapper appState={appState} /> <TagsContextMenuWrapper viewControllerManager={viewControllerManager} />
<FileContextMenuWrapper appState={appState} /> <FileContextMenuWrapper viewControllerManager={viewControllerManager} />
<PurchaseFlowWrapper application={application} appState={appState} /> <PurchaseFlowWrapper application={application} viewControllerManager={viewControllerManager} />
<ConfirmSignoutContainer <ConfirmSignoutContainer
applicationGroup={mainApplicationGroup} applicationGroup={mainApplicationGroup}
appState={appState} viewControllerManager={viewControllerManager}
application={application} application={application}
/> />
<ToastContainer /> <ToastContainer />
<FilePreviewModalWrapper application={application} appState={appState} /> <FilePreviewModalWrapper application={application} viewControllerManager={viewControllerManager} />
<PermissionsModalWrapper application={application} /> <PermissionsModalWrapper application={application} />
</> </>
</div> </div>

View File

@@ -1,5 +1,5 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { MENU_MARGIN_FROM_APP_BORDER } from '@/Constants' import { MENU_MARGIN_FROM_APP_BORDER } from '@/Constants'
import { Disclosure, DisclosureButton, DisclosurePanel } from '@reach/disclosure' import { Disclosure, DisclosureButton, DisclosurePanel } from '@reach/disclosure'
import VisuallyHidden from '@reach/visually-hidden' import VisuallyHidden from '@reach/visually-hidden'
@@ -19,13 +19,17 @@ import { isHandlingFileDrag } from '@/Utils/DragTypeCheck'
type Props = { type Props = {
application: WebApplication application: WebApplication
appState: AppState viewControllerManager: ViewControllerManager
onClickPreprocessing?: () => Promise<void> onClickPreprocessing?: () => Promise<void>
} }
const AttachedFilesButton: FunctionComponent<Props> = ({ application, appState, onClickPreprocessing }: Props) => { const AttachedFilesButton: FunctionComponent<Props> = ({
application,
viewControllerManager,
onClickPreprocessing,
}: Props) => {
const premiumModal = usePremiumModal() const premiumModal = usePremiumModal()
const note: SNNote | undefined = appState.notes.firstSelectedNote const note: SNNote | undefined = viewControllerManager.notesController.firstSelectedNote
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
const [position, setPosition] = useState({ const [position, setPosition] = useState({
@@ -39,12 +43,12 @@ const AttachedFilesButton: FunctionComponent<Props> = ({ application, appState,
const [closeOnBlur, keepMenuOpen] = useCloseOnBlur(containerRef, setOpen) const [closeOnBlur, keepMenuOpen] = useCloseOnBlur(containerRef, setOpen)
useEffect(() => { useEffect(() => {
if (appState.filePreviewModal.isOpen) { if (viewControllerManager.filePreviewModalController.isOpen) {
keepMenuOpen(true) keepMenuOpen(true)
} else { } else {
keepMenuOpen(false) keepMenuOpen(false)
} }
}, [appState.filePreviewModal.isOpen, keepMenuOpen]) }, [viewControllerManager.filePreviewModalController.isOpen, keepMenuOpen])
const [currentTab, setCurrentTab] = useState(PopoverTabs.AttachedFiles) const [currentTab, setCurrentTab] = useState(PopoverTabs.AttachedFiles)
const [allFiles, setAllFiles] = useState<FileItem[]>([]) const [allFiles, setAllFiles] = useState<FileItem[]>([])
@@ -90,10 +94,10 @@ const AttachedFilesButton: FunctionComponent<Props> = ({ application, appState,
}, [onClickPreprocessing, open]) }, [onClickPreprocessing, open])
const prospectivelyShowFilesPremiumModal = useCallback(() => { const prospectivelyShowFilesPremiumModal = useCallback(() => {
if (!appState.features.hasFiles) { if (!viewControllerManager.featuresController.hasFiles) {
premiumModal.activate('Files') premiumModal.activate('Files')
} }
}, [appState.features.hasFiles, premiumModal]) }, [viewControllerManager.featuresController.hasFiles, premiumModal])
const toggleAttachedFilesMenuWithEntitlementCheck = useCallback(async () => { const toggleAttachedFilesMenuWithEntitlementCheck = useCallback(async () => {
prospectivelyShowFilesPremiumModal() prospectivelyShowFilesPremiumModal()
@@ -121,7 +125,7 @@ const AttachedFilesButton: FunctionComponent<Props> = ({ application, appState,
} }
const downloadFile = async (file: FileItem) => { const downloadFile = async (file: FileItem) => {
appState.files.downloadFile(file).catch(console.error) viewControllerManager.filesController.downloadFile(file).catch(console.error)
} }
const attachFileToNote = useCallback( const attachFileToNote = useCallback(
@@ -213,7 +217,7 @@ const AttachedFilesButton: FunctionComponent<Props> = ({ application, appState,
case PopoverFileItemActionType.PreviewFile: { case PopoverFileItemActionType.PreviewFile: {
keepMenuOpen(true) keepMenuOpen(true)
const otherFiles = currentTab === PopoverTabs.AllFiles ? allFiles : attachedFiles const otherFiles = currentTab === PopoverTabs.AllFiles ? allFiles : attachedFiles
appState.filePreviewModal.activate( viewControllerManager.filePreviewModalController.activate(
file, file,
otherFiles.filter((file) => !file.protected), otherFiles.filter((file) => !file.protected),
) )
@@ -305,7 +309,7 @@ const AttachedFilesButton: FunctionComponent<Props> = ({ application, appState,
setIsDraggingFiles(false) setIsDraggingFiles(false)
if (!appState.features.hasFiles) { if (!viewControllerManager.featuresController.hasFiles) {
prospectivelyShowFilesPremiumModal() prospectivelyShowFilesPremiumModal()
return return
} }
@@ -320,7 +324,7 @@ const AttachedFilesButton: FunctionComponent<Props> = ({ application, appState,
return return
} }
const uploadedFiles = await appState.files.uploadNewFile(fileOrHandle) const uploadedFiles = await viewControllerManager.filesController.uploadNewFile(fileOrHandle)
if (!uploadedFiles) { if (!uploadedFiles) {
return return
@@ -338,8 +342,8 @@ const AttachedFilesButton: FunctionComponent<Props> = ({ application, appState,
} }
}, },
[ [
appState.files, viewControllerManager.filesController,
appState.features.hasFiles, viewControllerManager.featuresController.hasFiles,
attachFileToNote, attachFileToNote,
currentTab, currentTab,
application, application,
@@ -396,7 +400,7 @@ const AttachedFilesButton: FunctionComponent<Props> = ({ application, appState,
{open && ( {open && (
<AttachedFilesPopover <AttachedFilesPopover
application={application} application={application}
appState={appState} viewControllerManager={viewControllerManager}
attachedFiles={attachedFiles} attachedFiles={attachedFiles}
allFiles={allFiles} allFiles={allFiles}
closeOnBlur={closeOnBlur} closeOnBlur={closeOnBlur}

View File

@@ -1,6 +1,6 @@
import { FOCUSABLE_BUT_NOT_TABBABLE } from '@/Constants' import { FOCUSABLE_BUT_NOT_TABBABLE } from '@/Constants'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { FileItem } from '@standardnotes/snjs' import { FileItem } from '@standardnotes/snjs'
import { FilesIllustration } from '@standardnotes/icons' import { FilesIllustration } from '@standardnotes/icons'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
@@ -13,7 +13,7 @@ import { PopoverTabs } from './PopoverTabs'
type Props = { type Props = {
application: WebApplication application: WebApplication
appState: AppState viewControllerManager: ViewControllerManager
allFiles: FileItem[] allFiles: FileItem[]
attachedFiles: FileItem[] attachedFiles: FileItem[]
closeOnBlur: (event: { relatedTarget: EventTarget | null }) => void closeOnBlur: (event: { relatedTarget: EventTarget | null }) => void
@@ -25,7 +25,7 @@ type Props = {
const AttachedFilesPopover: FunctionComponent<Props> = ({ const AttachedFilesPopover: FunctionComponent<Props> = ({
application, application,
appState, viewControllerManager,
allFiles, allFiles,
attachedFiles, attachedFiles,
closeOnBlur, closeOnBlur,
@@ -45,7 +45,7 @@ const AttachedFilesPopover: FunctionComponent<Props> = ({
: filesList : filesList
const handleAttachFilesClick = async () => { const handleAttachFilesClick = async () => {
const uploadedFiles = await appState.files.uploadNewFile() const uploadedFiles = await viewControllerManager.filesController.uploadNewFile()
if (!uploadedFiles) { if (!uploadedFiles) {
return return
} }

View File

@@ -1,4 +1,4 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { DialogContent, DialogOverlay } from '@reach/dialog' import { DialogContent, DialogOverlay } from '@reach/dialog'
import { import {
ButtonType, ButtonType,
@@ -14,13 +14,13 @@ import Button from '@/Components/Button/Button'
import Icon from '@/Components/Icon/Icon' import Icon from '@/Components/Icon/Icon'
import ChallengeModalPrompt from './ChallengePrompt' import ChallengeModalPrompt from './ChallengePrompt'
import LockscreenWorkspaceSwitcher from './LockscreenWorkspaceSwitcher' import LockscreenWorkspaceSwitcher from './LockscreenWorkspaceSwitcher'
import { ApplicationGroup } from '@/UIModels/ApplicationGroup' import { ApplicationGroup } from '@/Application/ApplicationGroup'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { ChallengeModalValues } from './ChallengeModalValues' import { ChallengeModalValues } from './ChallengeModalValues'
type Props = { type Props = {
application: WebApplication application: WebApplication
appState: AppState viewControllerManager: ViewControllerManager
mainApplicationGroup: ApplicationGroup mainApplicationGroup: ApplicationGroup
challenge: Challenge challenge: Challenge
onDismiss?: (challenge: Challenge) => void onDismiss?: (challenge: Challenge) => void
@@ -44,7 +44,7 @@ const validateValues = (values: ChallengeModalValues, prompts: ChallengePrompt[]
const ChallengeModal: FunctionComponent<Props> = ({ const ChallengeModal: FunctionComponent<Props> = ({
application, application,
appState, viewControllerManager,
mainApplicationGroup, mainApplicationGroup,
challenge, challenge,
onDismiss, onDismiss,
@@ -255,7 +255,10 @@ const ChallengeModal: FunctionComponent<Props> = ({
</Button> </Button>
)} )}
{shouldShowWorkspaceSwitcher && ( {shouldShowWorkspaceSwitcher && (
<LockscreenWorkspaceSwitcher mainApplicationGroup={mainApplicationGroup} appState={appState} /> <LockscreenWorkspaceSwitcher
mainApplicationGroup={mainApplicationGroup}
viewControllerManager={viewControllerManager}
/>
)} )}
</DialogContent> </DialogContent>
</DialogOverlay> </DialogOverlay>

View File

@@ -1,5 +1,5 @@
import { ApplicationGroup } from '@/UIModels/ApplicationGroup' import { ApplicationGroup } from '@/Application/ApplicationGroup'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { calculateSubmenuStyle, SubmenuStyle } from '@/Utils/CalculateSubmenuStyle' import { calculateSubmenuStyle, SubmenuStyle } from '@/Utils/CalculateSubmenuStyle'
import { FunctionComponent, useCallback, useEffect, useRef, useState } from 'react' import { FunctionComponent, useCallback, useEffect, useRef, useState } from 'react'
import WorkspaceSwitcherMenu from '@/Components/AccountMenu/WorkspaceSwitcher/WorkspaceSwitcherMenu' import WorkspaceSwitcherMenu from '@/Components/AccountMenu/WorkspaceSwitcher/WorkspaceSwitcherMenu'
@@ -9,10 +9,10 @@ import { useCloseOnClickOutside } from '@/Hooks/useCloseOnClickOutside'
type Props = { type Props = {
mainApplicationGroup: ApplicationGroup mainApplicationGroup: ApplicationGroup
appState: AppState viewControllerManager: ViewControllerManager
} }
const LockscreenWorkspaceSwitcher: FunctionComponent<Props> = ({ mainApplicationGroup, appState }) => { const LockscreenWorkspaceSwitcher: FunctionComponent<Props> = ({ mainApplicationGroup, viewControllerManager }) => {
const buttonRef = useRef<HTMLButtonElement>(null) const buttonRef = useRef<HTMLButtonElement>(null)
const menuRef = useRef<HTMLDivElement>(null) const menuRef = useRef<HTMLDivElement>(null)
const containerRef = useRef<HTMLDivElement>(null) const containerRef = useRef<HTMLDivElement>(null)
@@ -55,7 +55,7 @@ const LockscreenWorkspaceSwitcher: FunctionComponent<Props> = ({ mainApplication
<div ref={menuRef} className="sn-dropdown max-h-120 min-w-68 py-2 fixed overflow-y-auto" style={menuStyle}> <div ref={menuRef} className="sn-dropdown max-h-120 min-w-68 py-2 fixed overflow-y-auto" style={menuStyle}>
<WorkspaceSwitcherMenu <WorkspaceSwitcherMenu
mainApplicationGroup={mainApplicationGroup} mainApplicationGroup={mainApplicationGroup}
appState={appState} viewControllerManager={viewControllerManager}
isOpen={isOpen} isOpen={isOpen}
hideWorkspaceOptions={true} hideWorkspaceOptions={true}
/> />

View File

@@ -1,5 +1,5 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { MENU_MARGIN_FROM_APP_BORDER } from '@/Constants' import { MENU_MARGIN_FROM_APP_BORDER } from '@/Constants'
import { Disclosure, DisclosureButton, DisclosurePanel } from '@reach/disclosure' import { Disclosure, DisclosureButton, DisclosurePanel } from '@reach/disclosure'
import VisuallyHidden from '@reach/visually-hidden' import VisuallyHidden from '@reach/visually-hidden'
@@ -11,12 +11,16 @@ import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur'
type Props = { type Props = {
application: WebApplication application: WebApplication
appState: AppState viewControllerManager: ViewControllerManager
onClickPreprocessing?: () => Promise<void> onClickPreprocessing?: () => Promise<void>
} }
const ChangeEditorButton: FunctionComponent<Props> = ({ application, appState, onClickPreprocessing }: Props) => { const ChangeEditorButton: FunctionComponent<Props> = ({
const note = appState.notes.firstSelectedNote application,
viewControllerManager,
onClickPreprocessing,
}: Props) => {
const note = viewControllerManager.notesController.firstSelectedNote
const [isOpen, setIsOpen] = useState(false) const [isOpen, setIsOpen] = useState(false)
const [isVisible, setIsVisible] = useState(false) const [isVisible, setIsVisible] = useState(false)
const [position, setPosition] = useState({ const [position, setPosition] = useState({

View File

@@ -4,7 +4,7 @@ import MenuItem from '@/Components/Menu/MenuItem'
import { MenuItemType } from '@/Components/Menu/MenuItemType' import { MenuItemType } from '@/Components/Menu/MenuItemType'
import { usePremiumModal } from '@/Hooks/usePremiumModal' import { usePremiumModal } from '@/Hooks/usePremiumModal'
import { STRING_EDIT_LOCKED_ATTEMPT } from '@/Strings' import { STRING_EDIT_LOCKED_ATTEMPT } from '@/Strings'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { import {
ComponentArea, ComponentArea,
ItemMutator, ItemMutator,
@@ -90,7 +90,7 @@ const ChangeEditorMenu: FunctionComponent<ChangeEditorMenuProps> = ({
const transactions: TransactionalMutation[] = [] const transactions: TransactionalMutation[] = []
await application.getAppState().contentListView.insertCurrentIfTemplate() await application.getViewControllerManager().contentListController.insertCurrentIfTemplate()
if (note.locked) { if (note.locked) {
application.alertService.alert(STRING_EDIT_LOCKED_ATTEMPT).catch(console.error) application.alertService.alert(STRING_EDIT_LOCKED_ATTEMPT).catch(console.error)

View File

@@ -1,4 +1,4 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { import {
ContentType, ContentType,
FeatureStatus, FeatureStatus,

View File

@@ -7,7 +7,7 @@ import {
ComponentViewerEvent, ComponentViewerEvent,
ComponentViewerError, ComponentViewerError,
} from '@standardnotes/snjs' } from '@standardnotes/snjs'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { FunctionComponent, useCallback, useEffect, useRef, useState } from 'react' import { FunctionComponent, useCallback, useEffect, useRef, useState } from 'react'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import OfflineRestricted from '@/Components/ComponentView/OfflineRestricted' import OfflineRestricted from '@/Components/ComponentView/OfflineRestricted'
@@ -15,12 +15,12 @@ import UrlMissing from '@/Components/ComponentView/UrlMissing'
import IsDeprecated from '@/Components/ComponentView/IsDeprecated' import IsDeprecated from '@/Components/ComponentView/IsDeprecated'
import IsExpired from '@/Components/ComponentView/IsExpired' import IsExpired from '@/Components/ComponentView/IsExpired'
import IssueOnLoading from '@/Components/ComponentView/IssueOnLoading' import IssueOnLoading from '@/Components/ComponentView/IssueOnLoading'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { openSubscriptionDashboard } from '@/Utils/ManageSubscription' import { openSubscriptionDashboard } from '@/Utils/ManageSubscription'
interface IProps { interface IProps {
application: WebApplication application: WebApplication
appState: AppState viewControllerManager: ViewControllerManager
componentViewer: ComponentViewer componentViewer: ComponentViewer
requestReload?: (viewer: ComponentViewer, force?: boolean) => void requestReload?: (viewer: ComponentViewer, force?: boolean) => void
onLoad?: (component: SNComponent) => void onLoad?: (component: SNComponent) => void
@@ -151,7 +151,7 @@ const ComponentView: FunctionComponent<IProps> = ({ application, onLoad, compone
application.io.handleComponentKeyUp(data.keyboardModifier) application.io.handleComponentKeyUp(data.keyboardModifier)
break break
case ComponentAction.Click: case ComponentAction.Click:
application.getAppState().notes.setContextMenuOpen(false) application.getViewControllerManager().notesController.setContextMenuOpen(false)
break break
default: default:
return return

View File

@@ -1,31 +1,31 @@
import { FunctionComponent, useEffect, useRef, useState } from 'react' import { FunctionComponent, useEffect, useRef, useState } from 'react'
import { AlertDialog, AlertDialogDescription, AlertDialogLabel } from '@reach/alert-dialog' import { AlertDialog, AlertDialogDescription, AlertDialogLabel } from '@reach/alert-dialog'
import { STRING_SIGN_OUT_CONFIRMATION } from '@/Strings' import { STRING_SIGN_OUT_CONFIRMATION } from '@/Strings'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { ApplicationGroup } from '@/UIModels/ApplicationGroup' import { ApplicationGroup } from '@/Application/ApplicationGroup'
import { isDesktopApplication } from '@/Utils' import { isDesktopApplication } from '@/Utils'
type Props = { type Props = {
application: WebApplication application: WebApplication
appState: AppState viewControllerManager: ViewControllerManager
applicationGroup: ApplicationGroup applicationGroup: ApplicationGroup
} }
const ConfirmSignoutModal: FunctionComponent<Props> = ({ application, appState, applicationGroup }) => { const ConfirmSignoutModal: FunctionComponent<Props> = ({ application, viewControllerManager, applicationGroup }) => {
const [deleteLocalBackups, setDeleteLocalBackups] = useState(false) const [deleteLocalBackups, setDeleteLocalBackups] = useState(false)
const cancelRef = useRef<HTMLButtonElement>(null) const cancelRef = useRef<HTMLButtonElement>(null)
function closeDialog() { function closeDialog() {
appState.accountMenu.setSigningOut(false) viewControllerManager.accountMenuController.setSigningOut(false)
} }
const [localBackupsCount, setLocalBackupsCount] = useState(0) const [localBackupsCount, setLocalBackupsCount] = useState(0)
useEffect(() => { useEffect(() => {
application.desktopDevice?.localBackupsCount().then(setLocalBackupsCount).catch(console.error) application.desktopDevice?.localBackupsCount().then(setLocalBackupsCount).catch(console.error)
}, [appState.accountMenu.signingOut, application.desktopDevice]) }, [viewControllerManager.accountMenuController.signingOut, application.desktopDevice])
const workspaces = applicationGroup.getDescriptors() const workspaces = applicationGroup.getDescriptors()
const showWorkspaceWarning = workspaces.length > 1 && isDesktopApplication() const showWorkspaceWarning = workspaces.length > 1 && isDesktopApplication()
@@ -112,7 +112,7 @@ const ConfirmSignoutModal: FunctionComponent<Props> = ({ application, appState,
ConfirmSignoutModal.displayName = 'ConfirmSignoutModal' ConfirmSignoutModal.displayName = 'ConfirmSignoutModal'
const ConfirmSignoutContainer = (props: Props) => { const ConfirmSignoutContainer = (props: Props) => {
if (!props.appState.accountMenu.signingOut) { if (!props.viewControllerManager.accountMenuController.signingOut) {
return null return null
} }
return <ConfirmSignoutModal {...props} /> return <ConfirmSignoutModal {...props} />

View File

@@ -1,6 +1,6 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { KeyboardKey } from '@/Services/IOService' import { KeyboardKey } from '@/Services/IOService'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { UuidString } from '@standardnotes/snjs' import { UuidString } from '@standardnotes/snjs'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { FunctionComponent, KeyboardEventHandler, UIEventHandler, useCallback } from 'react' import { FunctionComponent, KeyboardEventHandler, UIEventHandler, useCallback } from 'react'
@@ -10,16 +10,23 @@ import ContentListItem from './ContentListItem'
type Props = { type Props = {
application: WebApplication application: WebApplication
appState: AppState viewControllerManager: ViewControllerManager
items: ListableContentItem[] items: ListableContentItem[]
selectedItems: Record<UuidString, ListableContentItem> selectedItems: Record<UuidString, ListableContentItem>
paginate: () => void paginate: () => void
} }
const ContentList: FunctionComponent<Props> = ({ application, appState, items, selectedItems, paginate }) => { const ContentList: FunctionComponent<Props> = ({
const { selectPreviousItem, selectNextItem } = appState.contentListView application,
const { hideTags, hideDate, hideNotePreview, hideEditorIcon } = appState.contentListView.webDisplayOptions viewControllerManager,
const { sortBy } = appState.contentListView.displayOptions items,
selectedItems,
paginate,
}) => {
const { selectPreviousItem, selectNextItem } = viewControllerManager.contentListController
const { hideTags, hideDate, hideNotePreview, hideEditorIcon } =
viewControllerManager.contentListController.webDisplayOptions
const { sortBy } = viewControllerManager.contentListController.displayOptions
const onScroll: UIEventHandler = useCallback( const onScroll: UIEventHandler = useCallback(
(e) => { (e) => {
@@ -57,7 +64,7 @@ const ContentList: FunctionComponent<Props> = ({ application, appState, items, s
<ContentListItem <ContentListItem
key={item.uuid} key={item.uuid}
application={application} application={application}
appState={appState} viewControllerManager={viewControllerManager}
item={item} item={item}
selected={!!selectedItems[item.uuid]} selected={!!selectedItems[item.uuid]}
hideDate={hideDate} hideDate={hideDate}

View File

@@ -10,12 +10,12 @@ const ContentListItem: FunctionComponent<AbstractListItemProps> = (props) => {
return [] return []
} }
const selectedTag = props.appState.tags.selected const selectedTag = props.viewControllerManager.navigationController.selected
if (!selectedTag) { if (!selectedTag) {
return [] return []
} }
const tags = props.appState.getItemTags(props.item) const tags = props.viewControllerManager.getItemTags(props.item)
const isNavigatingOnlyTag = selectedTag instanceof SNTag && tags.length === 1 const isNavigatingOnlyTag = selectedTag instanceof SNTag && tags.length === 1
if (isNavigatingOnlyTag) { if (isNavigatingOnlyTag) {

View File

@@ -1,4 +1,4 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { CollectionSort, CollectionSortProperty, PrefKey, SystemViewId } from '@standardnotes/snjs' import { CollectionSort, CollectionSortProperty, PrefKey, SystemViewId } from '@standardnotes/snjs'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { FunctionComponent, useCallback, useState } from 'react' import { FunctionComponent, useCallback, useState } from 'react'
@@ -7,11 +7,11 @@ import Menu from '@/Components/Menu/Menu'
import MenuItem from '@/Components/Menu/MenuItem' import MenuItem from '@/Components/Menu/MenuItem'
import MenuItemSeparator from '@/Components/Menu/MenuItemSeparator' import MenuItemSeparator from '@/Components/Menu/MenuItemSeparator'
import { MenuItemType } from '@/Components/Menu/MenuItemType' import { MenuItemType } from '@/Components/Menu/MenuItemType'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
type Props = { type Props = {
application: WebApplication application: WebApplication
appState: AppState viewControllerManager: ViewControllerManager
closeOnBlur: (event: { relatedTarget: EventTarget | null }) => void closeOnBlur: (event: { relatedTarget: EventTarget | null }) => void
closeDisplayOptionsMenu: () => void closeDisplayOptionsMenu: () => void
isOpen: boolean isOpen: boolean
@@ -21,7 +21,7 @@ const ContentListOptionsMenu: FunctionComponent<Props> = ({
closeDisplayOptionsMenu, closeDisplayOptionsMenu,
closeOnBlur, closeOnBlur,
application, application,
appState, viewControllerManager,
isOpen, isOpen,
}) => { }) => {
const [sortBy, setSortBy] = useState(() => application.getPreference(PrefKey.SortNotesBy, CollectionSort.CreatedAt)) const [sortBy, setSortBy] = useState(() => application.getPreference(PrefKey.SortNotesBy, CollectionSort.CreatedAt))
@@ -174,7 +174,7 @@ const ContentListOptionsMenu: FunctionComponent<Props> = ({
</MenuItem> </MenuItem>
<MenuItemSeparator /> <MenuItemSeparator />
<div className="px-3 py-1 text-xs font-semibold color-text uppercase">View</div> <div className="px-3 py-1 text-xs font-semibold color-text uppercase">View</div>
{appState.tags.selectedUuid !== SystemViewId.Files && ( {viewControllerManager.navigationController.selectedUuid !== SystemViewId.Files && (
<MenuItem <MenuItem
type={MenuItemType.SwitchButton} type={MenuItemType.SwitchButton}
className="py-1 hover:bg-contrast focus:bg-info-backdrop" className="py-1 hover:bg-contrast focus:bg-info-backdrop"

View File

@@ -1,6 +1,6 @@
import { KeyboardKey, KeyboardModifier } from '@/Services/IOService' import { KeyboardKey, KeyboardModifier } from '@/Services/IOService'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { PANEL_NAME_NOTES } from '@/Constants' import { PANEL_NAME_NOTES } from '@/Constants'
import { PrefKey, SystemViewId } from '@standardnotes/snjs' import { PrefKey, SystemViewId } from '@standardnotes/snjs'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
@@ -24,10 +24,10 @@ import ContentListOptionsMenu from './ContentListOptionsMenu'
type Props = { type Props = {
application: WebApplication application: WebApplication
appState: AppState viewControllerManager: ViewControllerManager
} }
const ContentListView: FunctionComponent<Props> = ({ application, appState }) => { const ContentListView: FunctionComponent<Props> = ({ application, viewControllerManager }) => {
const itemsViewPanelRef = useRef<HTMLDivElement>(null) const itemsViewPanelRef = useRef<HTMLDivElement>(null)
const displayOptionsMenuRef = useRef<HTMLDivElement>(null) const displayOptionsMenuRef = useRef<HTMLDivElement>(null)
@@ -46,9 +46,9 @@ const ContentListView: FunctionComponent<Props> = ({ application, appState }) =>
paginate, paginate,
panelWidth, panelWidth,
createNewNote, createNewNote,
} = appState.contentListView } = viewControllerManager.contentListController
const { selectedItems } = appState.selectedItems const { selectedItems } = viewControllerManager.selectionController
const [showDisplayOptionsMenu, setShowDisplayOptionsMenu] = useState(false) const [showDisplayOptionsMenu, setShowDisplayOptionsMenu] = useState(false)
const [focusedSearch, setFocusedSearch] = useState(false) const [focusedSearch, setFocusedSearch] = useState(false)
@@ -56,17 +56,17 @@ const ContentListView: FunctionComponent<Props> = ({ application, appState }) =>
const [closeDisplayOptMenuOnBlur] = useCloseOnBlur(displayOptionsMenuRef, setShowDisplayOptionsMenu) const [closeDisplayOptMenuOnBlur] = useCloseOnBlur(displayOptionsMenuRef, setShowDisplayOptionsMenu)
const isFilesSmartView = useMemo( const isFilesSmartView = useMemo(
() => appState.tags.selected?.uuid === SystemViewId.Files, () => viewControllerManager.navigationController.selected?.uuid === SystemViewId.Files,
[appState.tags.selected?.uuid], [viewControllerManager.navigationController.selected?.uuid],
) )
const addNewItem = useCallback(() => { const addNewItem = useCallback(() => {
if (isFilesSmartView) { if (isFilesSmartView) {
void appState.files.uploadNewFile() void viewControllerManager.filesController.uploadNewFile()
} else { } else {
void createNewNote() void createNewNote()
} }
}, [appState.files, createNewNote, isFilesSmartView]) }, [viewControllerManager.filesController, createNewNote, isFilesSmartView])
useEffect(() => { useEffect(() => {
/** /**
@@ -142,15 +142,15 @@ const ContentListView: FunctionComponent<Props> = ({ application, appState }) =>
const panelResizeFinishCallback: ResizeFinishCallback = useCallback( const panelResizeFinishCallback: ResizeFinishCallback = useCallback(
(width, _lastLeft, _isMaxWidth, isCollapsed) => { (width, _lastLeft, _isMaxWidth, isCollapsed) => {
application.setPreference(PrefKey.NotesPanelWidth, width).catch(console.error) application.setPreference(PrefKey.NotesPanelWidth, width).catch(console.error)
appState.noteTags.reloadTagsContainerMaxWidth() viewControllerManager.noteTagsController.reloadTagsContainerMaxWidth()
appState.panelDidResize(PANEL_NAME_NOTES, isCollapsed) viewControllerManager.panelDidResize(PANEL_NAME_NOTES, isCollapsed)
}, },
[appState, application], [viewControllerManager, application],
) )
const panelWidthEventCallback = useCallback(() => { const panelWidthEventCallback = useCallback(() => {
appState.noteTags.reloadTagsContainerMaxWidth() viewControllerManager.noteTagsController.reloadTagsContainerMaxWidth()
}, [appState]) }, [viewControllerManager])
const toggleDisplayOptionsMenu = useCallback(() => { const toggleDisplayOptionsMenu = useCallback(() => {
setShowDisplayOptionsMenu(!showDisplayOptionsMenu) setShowDisplayOptionsMenu(!showDisplayOptionsMenu)
@@ -208,11 +208,11 @@ const ContentListView: FunctionComponent<Props> = ({ application, appState }) =>
{(focusedSearch || noteFilterText) && ( {(focusedSearch || noteFilterText) && (
<div className="animate-fade-from-top"> <div className="animate-fade-from-top">
<SearchOptions application={application} appState={appState} /> <SearchOptions application={application} viewControllerManager={viewControllerManager} />
</div> </div>
)} )}
</div> </div>
<NoAccountWarningWrapper appState={appState} /> <NoAccountWarningWrapper viewControllerManager={viewControllerManager} />
</div> </div>
<div id="items-menu-bar" className="sn-component" ref={displayOptionsMenuRef}> <div id="items-menu-bar" className="sn-component" ref={displayOptionsMenuRef}>
<div className="sk-app-bar no-edges"> <div className="sk-app-bar no-edges">
@@ -235,7 +235,7 @@ const ContentListView: FunctionComponent<Props> = ({ application, appState }) =>
{showDisplayOptionsMenu && ( {showDisplayOptionsMenu && (
<ContentListOptionsMenu <ContentListOptionsMenu
application={application} application={application}
appState={appState} viewControllerManager={viewControllerManager}
closeDisplayOptionsMenu={toggleDisplayOptionsMenu} closeDisplayOptionsMenu={toggleDisplayOptionsMenu}
closeOnBlur={closeDisplayOptMenuOnBlur} closeOnBlur={closeDisplayOptMenuOnBlur}
isOpen={showDisplayOptionsMenu} isOpen={showDisplayOptionsMenu}
@@ -254,7 +254,7 @@ const ContentListView: FunctionComponent<Props> = ({ application, appState }) =>
items={renderedItems} items={renderedItems}
selectedItems={selectedItems} selectedItems={selectedItems}
application={application} application={application}
appState={appState} viewControllerManager={viewControllerManager}
paginate={paginate} paginate={paginate}
/> />
) : null} ) : null}

View File

@@ -10,7 +10,7 @@ import { DisplayableListItemProps } from './Types/DisplayableListItemProps'
const FileListItem: FunctionComponent<DisplayableListItemProps> = ({ const FileListItem: FunctionComponent<DisplayableListItemProps> = ({
application, application,
appState, viewControllerManager,
hideDate, hideDate,
hideIcon, hideIcon,
hideTags, hideTags,
@@ -21,32 +21,40 @@ const FileListItem: FunctionComponent<DisplayableListItemProps> = ({
}) => { }) => {
const openFileContextMenu = useCallback( const openFileContextMenu = useCallback(
(posX: number, posY: number) => { (posX: number, posY: number) => {
appState.files.setFileContextMenuLocation({ viewControllerManager.filesController.setFileContextMenuLocation({
x: posX, x: posX,
y: posY, y: posY,
}) })
appState.files.setShowFileContextMenu(true) viewControllerManager.filesController.setShowFileContextMenu(true)
}, },
[appState.files], [viewControllerManager.filesController],
) )
const openContextMenu = useCallback( const openContextMenu = useCallback(
async (posX: number, posY: number) => { async (posX: number, posY: number) => {
const { didSelect } = await appState.selectedItems.selectItem(item.uuid) const { didSelect } = await viewControllerManager.selectionController.selectItem(item.uuid)
if (didSelect) { if (didSelect) {
openFileContextMenu(posX, posY) openFileContextMenu(posX, posY)
} }
}, },
[appState.selectedItems, item.uuid, openFileContextMenu], [viewControllerManager.selectionController, item.uuid, openFileContextMenu],
) )
const onClick = useCallback(() => { const onClick = useCallback(() => {
void appState.selectedItems.selectItem(item.uuid, true).then(({ didSelect }) => { void viewControllerManager.selectionController.selectItem(item.uuid, true).then(({ didSelect }) => {
if (didSelect && appState.selectedItems.selectedItemsCount < 2) { if (didSelect && viewControllerManager.selectionController.selectedItemsCount < 2) {
appState.filePreviewModal.activate(item as FileItem, appState.files.allFiles) viewControllerManager.filePreviewModalController.activate(
item as FileItem,
viewControllerManager.filesController.allFiles,
)
} }
}) })
}, [appState.filePreviewModal, appState.files.allFiles, appState.selectedItems, item]) }, [
viewControllerManager.filePreviewModalController,
viewControllerManager.filesController.allFiles,
viewControllerManager.selectionController,
item,
])
const IconComponent = () => const IconComponent = () =>
getFileIconComponent( getFileIconComponent(

View File

@@ -11,7 +11,7 @@ import { DisplayableListItemProps } from './Types/DisplayableListItemProps'
const NoteListItem: FunctionComponent<DisplayableListItemProps> = ({ const NoteListItem: FunctionComponent<DisplayableListItemProps> = ({
application, application,
appState, viewControllerManager,
hideDate, hideDate,
hideIcon, hideIcon,
hideTags, hideTags,
@@ -27,16 +27,16 @@ const NoteListItem: FunctionComponent<DisplayableListItemProps> = ({
const hasFiles = application.items.getFilesForNote(item as SNNote).length > 0 const hasFiles = application.items.getFilesForNote(item as SNNote).length > 0
const openNoteContextMenu = (posX: number, posY: number) => { const openNoteContextMenu = (posX: number, posY: number) => {
appState.notes.setContextMenuClickLocation({ viewControllerManager.notesController.setContextMenuClickLocation({
x: posX, x: posX,
y: posY, y: posY,
}) })
appState.notes.reloadContextMenuLayout() viewControllerManager.notesController.reloadContextMenuLayout()
appState.notes.setContextMenuOpen(true) viewControllerManager.notesController.setContextMenuOpen(true)
} }
const openContextMenu = async (posX: number, posY: number) => { const openContextMenu = async (posX: number, posY: number) => {
const { didSelect } = await appState.selectedItems.selectItem(item.uuid, true) const { didSelect } = await viewControllerManager.selectionController.selectItem(item.uuid, true)
if (didSelect) { if (didSelect) {
openNoteContextMenu(posX, posY) openNoteContextMenu(posX, posY)
} }
@@ -49,7 +49,7 @@ const NoteListItem: FunctionComponent<DisplayableListItemProps> = ({
}`} }`}
id={item.uuid} id={item.uuid}
onClick={() => { onClick={() => {
void appState.selectedItems.selectItem(item.uuid, true) void viewControllerManager.selectionController.selectItem(item.uuid, true)
}} }}
onContextMenu={(event) => { onContextMenu={(event) => {
event.preventDefault() event.preventDefault()

View File

@@ -1,11 +1,11 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { SortableItem } from '@standardnotes/snjs' import { SortableItem } from '@standardnotes/snjs'
import { ListableContentItem } from './ListableContentItem' import { ListableContentItem } from './ListableContentItem'
export type AbstractListItemProps = { export type AbstractListItemProps = {
application: WebApplication application: WebApplication
appState: AppState viewControllerManager: ViewControllerManager
hideDate: boolean hideDate: boolean
hideIcon: boolean hideIcon: boolean
hideTags: boolean hideTags: boolean

View File

@@ -1,4 +1,4 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { FunctionComponent } from 'react' import { FunctionComponent } from 'react'

View File

@@ -1,7 +1,7 @@
import { MAX_MENU_SIZE_MULTIPLIER, MENU_MARGIN_FROM_APP_BORDER } from '@/Constants' import { MAX_MENU_SIZE_MULTIPLIER, MENU_MARGIN_FROM_APP_BORDER } from '@/Constants'
import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur' import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur'
import { useCloseOnClickOutside } from '@/Hooks/useCloseOnClickOutside' import { useCloseOnClickOutside } from '@/Hooks/useCloseOnClickOutside'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { FunctionComponent, useCallback, useEffect, useRef, useState } from 'react' import { FunctionComponent, useCallback, useEffect, useRef, useState } from 'react'
import { PopoverFileItemAction } from '../AttachedFilesPopover/PopoverFileItemAction' import { PopoverFileItemAction } from '../AttachedFilesPopover/PopoverFileItemAction'
@@ -9,11 +9,12 @@ import { PopoverTabs } from '../AttachedFilesPopover/PopoverTabs'
import FileMenuOptions from './FileMenuOptions' import FileMenuOptions from './FileMenuOptions'
type Props = { type Props = {
appState: AppState viewControllerManager: ViewControllerManager
} }
const FileContextMenu: FunctionComponent<Props> = observer(({ appState }) => { const FileContextMenu: FunctionComponent<Props> = observer(({ viewControllerManager }) => {
const { selectedFiles, showFileContextMenu, setShowFileContextMenu, fileContextMenuLocation } = appState.files const { selectedFiles, showFileContextMenu, setShowFileContextMenu, fileContextMenuLocation } =
viewControllerManager.filesController
const [contextMenuStyle, setContextMenuStyle] = useState<React.CSSProperties>({ const [contextMenuStyle, setContextMenuStyle] = useState<React.CSSProperties>({
top: 0, top: 0,
@@ -23,7 +24,7 @@ const FileContextMenu: FunctionComponent<Props> = observer(({ appState }) => {
const [contextMenuMaxHeight, setContextMenuMaxHeight] = useState<number | 'auto'>('auto') const [contextMenuMaxHeight, setContextMenuMaxHeight] = useState<number | 'auto'>('auto')
const contextMenuRef = useRef<HTMLDivElement>(null) const contextMenuRef = useRef<HTMLDivElement>(null)
const [closeOnBlur] = useCloseOnBlur(contextMenuRef, (open: boolean) => setShowFileContextMenu(open)) const [closeOnBlur] = useCloseOnBlur(contextMenuRef, (open: boolean) => setShowFileContextMenu(open))
useCloseOnClickOutside(contextMenuRef, () => appState.files.setShowFileContextMenu(false)) useCloseOnClickOutside(contextMenuRef, () => viewControllerManager.filesController.setShowFileContextMenu(false))
const selectedFile = selectedFiles[0] const selectedFile = selectedFiles[0]
@@ -87,10 +88,13 @@ const FileContextMenu: FunctionComponent<Props> = observer(({ appState }) => {
const handleFileAction = useCallback( const handleFileAction = useCallback(
async (action: PopoverFileItemAction) => { async (action: PopoverFileItemAction) => {
const { didHandleAction } = await appState.files.handleFileAction(action, PopoverTabs.AllFiles) const { didHandleAction } = await viewControllerManager.filesController.handleFileAction(
action,
PopoverTabs.AllFiles,
)
return didHandleAction return didHandleAction
}, },
[appState.files], [viewControllerManager.filesController],
) )
return ( return (
@@ -116,8 +120,8 @@ const FileContextMenu: FunctionComponent<Props> = observer(({ appState }) => {
FileContextMenu.displayName = 'FileContextMenu' FileContextMenu.displayName = 'FileContextMenu'
const FileContextMenuWrapper: FunctionComponent<Props> = ({ appState }) => { const FileContextMenuWrapper: FunctionComponent<Props> = ({ viewControllerManager }) => {
const { selectedFiles, showFileContextMenu } = appState.files const { selectedFiles, showFileContextMenu } = viewControllerManager.filesController
const selectedFile = selectedFiles[0] const selectedFile = selectedFiles[0]
@@ -125,7 +129,7 @@ const FileContextMenuWrapper: FunctionComponent<Props> = ({ appState }) => {
return null return null
} }
return <FileContextMenu appState={appState} /> return <FileContextMenu viewControllerManager={viewControllerManager} />
} }
export default observer(FileContextMenuWrapper) export default observer(FileContextMenuWrapper)

View File

@@ -1,4 +1,4 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { concatenateUint8Arrays } from '@/Utils/ConcatenateUint8Arrays' import { concatenateUint8Arrays } from '@/Utils/ConcatenateUint8Arrays'
import { DialogContent, DialogOverlay } from '@reach/dialog' import { DialogContent, DialogOverlay } from '@reach/dialog'
import { addToast, ToastType } from '@standardnotes/stylekit' import { addToast, ToastType } from '@standardnotes/stylekit'
@@ -12,16 +12,16 @@ import { isFileTypePreviewable } from './isFilePreviewable'
import PreviewComponent from './PreviewComponent' import PreviewComponent from './PreviewComponent'
import { FOCUSABLE_BUT_NOT_TABBABLE } from '@/Constants' import { FOCUSABLE_BUT_NOT_TABBABLE } from '@/Constants'
import { KeyboardKey } from '@/Services/IOService' import { KeyboardKey } from '@/Services/IOService'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
type Props = { type Props = {
application: WebApplication application: WebApplication
appState: AppState viewControllerManager: ViewControllerManager
} }
const FilePreviewModal: FunctionComponent<Props> = observer(({ application, appState }) => { const FilePreviewModal: FunctionComponent<Props> = observer(({ application, viewControllerManager }) => {
const { currentFile, setCurrentFile, otherFiles, dismiss } = appState.filePreviewModal const { currentFile, setCurrentFile, otherFiles, dismiss } = viewControllerManager.filePreviewModalController
if (!currentFile) { if (!currentFile) {
return null return null
@@ -221,7 +221,10 @@ const FilePreviewModal: FunctionComponent<Props> = observer(({ application, appS
<Button <Button
variant="normal" variant="normal"
onClick={() => { onClick={() => {
application.getAppState().files.downloadFile(currentFile).catch(console.error) application
.getViewControllerManager()
.filesController.downloadFile(currentFile)
.catch(console.error)
}} }}
> >
Download Download
@@ -236,7 +239,10 @@ const FilePreviewModal: FunctionComponent<Props> = observer(({ application, appS
<Button <Button
variant="primary" variant="primary"
onClick={() => { onClick={() => {
application.getAppState().files.downloadFile(currentFile).catch(console.error) application
.getViewControllerManager()
.filesController.downloadFile(currentFile)
.catch(console.error)
}} }}
> >
Download Download
@@ -255,8 +261,10 @@ const FilePreviewModal: FunctionComponent<Props> = observer(({ application, appS
FilePreviewModal.displayName = 'FilePreviewModal' FilePreviewModal.displayName = 'FilePreviewModal'
const FilePreviewModalWrapper: FunctionComponent<Props> = ({ application, appState }) => { const FilePreviewModalWrapper: FunctionComponent<Props> = ({ application, viewControllerManager }) => {
return appState.filePreviewModal.isOpen ? <FilePreviewModal application={application} appState={appState} /> : null return viewControllerManager.filePreviewModalController.isOpen ? (
<FilePreviewModal application={application} viewControllerManager={viewControllerManager} />
) : null
} }
export default observer(FilePreviewModalWrapper) export default observer(FilePreviewModalWrapper)

View File

@@ -1,5 +1,5 @@
import { WebAppEvent, WebApplication } from '@/UIModels/Application' import { WebAppEvent, WebApplication } from '@/Application/Application'
import { ApplicationGroup } from '@/UIModels/ApplicationGroup' import { ApplicationGroup } from '@/Application/ApplicationGroup'
import { PureComponent } from '@/Components/Abstract/PureComponent' import { PureComponent } from '@/Components/Abstract/PureComponent'
import { destroyAllObjectProperties, preventRefreshing } from '@/Utils' import { destroyAllObjectProperties, preventRefreshing } from '@/Utils'
import { ApplicationEvent, ApplicationDescriptor } from '@standardnotes/snjs' import { ApplicationEvent, ApplicationDescriptor } from '@standardnotes/snjs'
@@ -12,12 +12,13 @@ import {
} from '@/Strings' } from '@/Strings'
import { alertDialog, confirmDialog } from '@/Services/AlertService' import { alertDialog, confirmDialog } from '@/Services/AlertService'
import AccountMenu from '@/Components/AccountMenu/AccountMenu' import AccountMenu from '@/Components/AccountMenu/AccountMenu'
import { AppStateEvent, EventSource } from '@/UIModels/AppState' import { ViewControllerManagerEvent } from '@/Services/ViewControllerManager'
import Icon from '@/Components/Icon/Icon' import Icon from '@/Components/Icon/Icon'
import QuickSettingsMenu from '@/Components/QuickSettingsMenu/QuickSettingsMenu' import QuickSettingsMenu from '@/Components/QuickSettingsMenu/QuickSettingsMenu'
import SyncResolutionMenu from '@/Components/SyncResolutionMenu/SyncResolutionMenu' import SyncResolutionMenu from '@/Components/SyncResolutionMenu/SyncResolutionMenu'
import { Fragment } from 'react' import { Fragment } from 'react'
import { AccountMenuPane } from '../AccountMenu/AccountMenuPane' import { AccountMenuPane } from '../AccountMenu/AccountMenuPane'
import { EditorEventSource } from '@/Typings/EditorEventSource'
type Props = { type Props = {
application: WebApplication application: WebApplication
@@ -92,11 +93,11 @@ class Footer extends PureComponent<Props, State> {
}) })
this.autorun(() => { this.autorun(() => {
const showBetaWarning = this.appState.showBetaWarning const showBetaWarning = this.viewControllerManager.showBetaWarning
this.setState({ this.setState({
showBetaWarning: showBetaWarning, showBetaWarning: showBetaWarning,
showAccountMenu: this.appState.accountMenu.show, showAccountMenu: this.viewControllerManager.accountMenuController.show,
showQuickSettingsMenu: this.appState.quickSettingsMenu.open, showQuickSettingsMenu: this.viewControllerManager.quickSettingsMenuController.open,
}) })
}) })
} }
@@ -132,18 +133,18 @@ class Footer extends PureComponent<Props, State> {
}) })
} }
override onAppStateEvent(eventName: AppStateEvent, data: any) { override onViewControllerManagerEvent(eventName: ViewControllerManagerEvent, data: any) {
const statusService = this.application.status const statusService = this.application.status
switch (eventName) { switch (eventName) {
case AppStateEvent.EditorFocused: case ViewControllerManagerEvent.EditorFocused:
if (data.eventSource === EventSource.UserInteraction) { if (data.eventSource === EditorEventSource.UserInteraction) {
this.closeAccountMenu() this.closeAccountMenu()
} }
break break
case AppStateEvent.BeganBackupDownload: case ViewControllerManagerEvent.BeganBackupDownload:
statusService.setMessage('Saving local backup…') statusService.setMessage('Saving local backup…')
break break
case AppStateEvent.EndedBackupDownload: { case ViewControllerManagerEvent.EndedBackupDownload: {
const successMessage = 'Successfully saved backup.' const successMessage = 'Successfully saved backup.'
const errorMessage = 'Unable to save local backup.' const errorMessage = 'Unable to save local backup.'
statusService.setMessage(data.success ? successMessage : errorMessage) statusService.setMessage(data.success ? successMessage : errorMessage)
@@ -187,7 +188,7 @@ class Footer extends PureComponent<Props, State> {
if (!this.didCheckForOffline) { if (!this.didCheckForOffline) {
this.didCheckForOffline = true this.didCheckForOffline = true
if (this.state.offline && this.application.items.getNoteCount() === 0) { if (this.state.offline && this.application.items.getNoteCount() === 0) {
this.appState.accountMenu.setShow(true) this.viewControllerManager.accountMenuController.setShow(true)
} }
} }
this.findErrors() this.findErrors()
@@ -288,13 +289,13 @@ class Footer extends PureComponent<Props, State> {
} }
accountMenuClickHandler = () => { accountMenuClickHandler = () => {
this.appState.quickSettingsMenu.closeQuickSettingsMenu() this.viewControllerManager.quickSettingsMenuController.closeQuickSettingsMenu()
this.appState.accountMenu.toggleShow() this.viewControllerManager.accountMenuController.toggleShow()
} }
quickSettingsClickHandler = () => { quickSettingsClickHandler = () => {
this.appState.accountMenu.closeAccountMenu() this.viewControllerManager.accountMenuController.closeAccountMenu()
this.appState.quickSettingsMenu.toggle() this.viewControllerManager.quickSettingsMenuController.toggle()
} }
syncResolutionClickHandler = () => { syncResolutionClickHandler = () => {
@@ -304,8 +305,8 @@ class Footer extends PureComponent<Props, State> {
} }
closeAccountMenu = () => { closeAccountMenu = () => {
this.appState.accountMenu.setShow(false) this.viewControllerManager.accountMenuController.setShow(false)
this.appState.accountMenu.setCurrentPane(AccountMenuPane.GeneralMenu) this.viewControllerManager.accountMenuController.setCurrentPane(AccountMenuPane.GeneralMenu)
} }
lockClickHandler = () => { lockClickHandler = () => {
@@ -333,11 +334,11 @@ class Footer extends PureComponent<Props, State> {
} }
clickOutsideAccountMenu = () => { clickOutsideAccountMenu = () => {
this.appState.accountMenu.closeAccountMenu() this.viewControllerManager.accountMenuController.closeAccountMenu()
} }
clickOutsideQuickSettingsMenu = () => { clickOutsideQuickSettingsMenu = () => {
this.appState.quickSettingsMenu.closeQuickSettingsMenu() this.viewControllerManager.quickSettingsMenuController.closeQuickSettingsMenu()
} }
override render() { override render() {
@@ -360,7 +361,7 @@ class Footer extends PureComponent<Props, State> {
{this.state.showAccountMenu && ( {this.state.showAccountMenu && (
<AccountMenu <AccountMenu
onClickOutside={this.clickOutsideAccountMenu} onClickOutside={this.clickOutsideAccountMenu}
appState={this.appState} viewControllerManager={this.viewControllerManager}
application={this.application} application={this.application}
mainApplicationGroup={this.props.applicationGroup} mainApplicationGroup={this.props.applicationGroup}
/> />
@@ -381,7 +382,7 @@ class Footer extends PureComponent<Props, State> {
{this.state.showQuickSettingsMenu && ( {this.state.showQuickSettingsMenu && (
<QuickSettingsMenu <QuickSettingsMenu
onClickOutside={this.clickOutsideQuickSettingsMenu} onClickOutside={this.clickOutsideQuickSettingsMenu}
appState={this.appState} viewControllerManager={this.viewControllerManager}
application={this.application} application={this.application}
/> />
)} )}

View File

@@ -1,23 +1,23 @@
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { IlNotesIcon } from '@standardnotes/icons' import { IlNotesIcon } from '@standardnotes/icons'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import NotesOptionsPanel from '@/Components/NotesOptions/NotesOptionsPanel' import NotesOptionsPanel from '@/Components/NotesOptions/NotesOptionsPanel'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import PinNoteButton from '@/Components/PinNoteButton/PinNoteButton' import PinNoteButton from '@/Components/PinNoteButton/PinNoteButton'
import Button from '../Button/Button' import Button from '../Button/Button'
import { useCallback } from 'react' import { useCallback } from 'react'
type Props = { type Props = {
application: WebApplication application: WebApplication
appState: AppState viewControllerManager: ViewControllerManager
} }
const MultipleSelectedNotes = ({ application, appState }: Props) => { const MultipleSelectedNotes = ({ application, viewControllerManager }: Props) => {
const count = appState.notes.selectedNotesCount const count = viewControllerManager.notesController.selectedNotesCount
const cancelMultipleSelection = useCallback(() => { const cancelMultipleSelection = useCallback(() => {
appState.selectedItems.cancelMultipleSelection() viewControllerManager.selectionController.cancelMultipleSelection()
}, [appState]) }, [viewControllerManager])
return ( return (
<div className="flex flex-col h-full items-center"> <div className="flex flex-col h-full items-center">
@@ -25,9 +25,9 @@ const MultipleSelectedNotes = ({ application, appState }: Props) => {
<h1 className="sk-h1 font-bold m-0">{count} selected notes</h1> <h1 className="sk-h1 font-bold m-0">{count} selected notes</h1>
<div className="flex"> <div className="flex">
<div className="mr-3"> <div className="mr-3">
<PinNoteButton appState={appState} /> <PinNoteButton viewControllerManager={viewControllerManager} />
</div> </div>
<NotesOptionsPanel application={application} appState={appState} /> <NotesOptionsPanel application={application} viewControllerManager={viewControllerManager} />
</div> </div>
</div> </div>
<div className="flex-grow flex flex-col justify-center items-center w-full max-w-md"> <div className="flex-grow flex flex-col justify-center items-center w-full max-w-md">

View File

@@ -1,6 +1,6 @@
import SmartViewsSection from '@/Components/Tags/SmartViewsSection' import SmartViewsSection from '@/Components/Tags/SmartViewsSection'
import TagsSection from '@/Components/Tags/TagsSection' import TagsSection from '@/Components/Tags/TagsSection'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { PANEL_NAME_NAVIGATION } from '@/Constants' import { PANEL_NAME_NAVIGATION } from '@/Constants'
import { ApplicationEvent, PrefKey } from '@standardnotes/snjs' import { ApplicationEvent, PrefKey } from '@standardnotes/snjs'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
@@ -12,7 +12,7 @@ type Props = {
} }
const Navigation: FunctionComponent<Props> = ({ application }) => { const Navigation: FunctionComponent<Props> = ({ application }) => {
const appState = useMemo(() => application.getAppState(), [application]) const viewControllerManager = useMemo(() => application.getViewControllerManager(), [application])
const [ref, setRef] = useState<HTMLDivElement | null>() const [ref, setRef] = useState<HTMLDivElement | null>()
const [panelWidth, setPanelWidth] = useState<number>(0) const [panelWidth, setPanelWidth] = useState<number>(0)
@@ -32,15 +32,15 @@ const Navigation: FunctionComponent<Props> = ({ application }) => {
const panelResizeFinishCallback: ResizeFinishCallback = useCallback( const panelResizeFinishCallback: ResizeFinishCallback = useCallback(
(width, _lastLeft, _isMaxWidth, isCollapsed) => { (width, _lastLeft, _isMaxWidth, isCollapsed) => {
application.setPreference(PrefKey.TagsPanelWidth, width).catch(console.error) application.setPreference(PrefKey.TagsPanelWidth, width).catch(console.error)
appState.noteTags.reloadTagsContainerMaxWidth() viewControllerManager.noteTagsController.reloadTagsContainerMaxWidth()
appState.panelDidResize(PANEL_NAME_NAVIGATION, isCollapsed) viewControllerManager.panelDidResize(PANEL_NAME_NAVIGATION, isCollapsed)
}, },
[application, appState], [application, viewControllerManager],
) )
const panelWidthEventCallback = useCallback(() => { const panelWidthEventCallback = useCallback(() => {
appState.noteTags.reloadTagsContainerMaxWidth() viewControllerManager.noteTagsController.reloadTagsContainerMaxWidth()
}, [appState]) }, [viewControllerManager])
return ( return (
<div <div
@@ -58,8 +58,8 @@ const Navigation: FunctionComponent<Props> = ({ application }) => {
</div> </div>
</div> </div>
<div className="scrollable"> <div className="scrollable">
<SmartViewsSection appState={appState} /> <SmartViewsSection viewControllerManager={viewControllerManager} />
<TagsSection appState={appState} /> <TagsSection viewControllerManager={viewControllerManager} />
</div> </div>
</div> </div>
{ref && ( {ref && (

View File

@@ -1,22 +1,22 @@
import Icon from '@/Components/Icon/Icon' import Icon from '@/Components/Icon/Icon'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { MouseEventHandler, useCallback } from 'react' import { MouseEventHandler, useCallback } from 'react'
type Props = { appState: AppState } type Props = { viewControllerManager: ViewControllerManager }
const NoAccountWarning = observer(({ appState }: Props) => { const NoAccountWarning = observer(({ viewControllerManager }: Props) => {
const showAccountMenu: MouseEventHandler = useCallback( const showAccountMenu: MouseEventHandler = useCallback(
(event) => { (event) => {
event.stopPropagation() event.stopPropagation()
appState.accountMenu.setShow(true) viewControllerManager.accountMenuController.setShow(true)
}, },
[appState], [viewControllerManager],
) )
const hideWarning = useCallback(() => { const hideWarning = useCallback(() => {
appState.noAccountWarning.hide() viewControllerManager.noAccountWarningController.hide()
}, [appState]) }, [viewControllerManager])
return ( return (
<div className="mt-4 p-4 rounded-md shadow-sm grid grid-template-cols-1fr"> <div className="mt-4 p-4 rounded-md shadow-sm grid grid-template-cols-1fr">
@@ -40,10 +40,10 @@ const NoAccountWarning = observer(({ appState }: Props) => {
NoAccountWarning.displayName = 'NoAccountWarning' NoAccountWarning.displayName = 'NoAccountWarning'
const NoAccountWarningWrapper = ({ appState }: Props) => { const NoAccountWarningWrapper = ({ viewControllerManager }: Props) => {
const canShow = appState.noAccountWarning.show const canShow = viewControllerManager.noAccountWarningController.show
return canShow ? <NoAccountWarning appState={appState} /> : null return canShow ? <NoAccountWarning viewControllerManager={viewControllerManager} /> : null
} }
export default observer(NoAccountWarningWrapper) export default observer(NoAccountWarningWrapper)

View File

@@ -1,6 +1,6 @@
import { NoteViewController } from '@standardnotes/snjs' import { NoteViewController } from '@standardnotes/snjs'
import { PureComponent } from '@/Components/Abstract/PureComponent' import { PureComponent } from '@/Components/Abstract/PureComponent'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import MultipleSelectedNotes from '@/Components/MultipleSelectedNotes/MultipleSelectedNotes' import MultipleSelectedNotes from '@/Components/MultipleSelectedNotes/MultipleSelectedNotes'
import NoteView from '@/Components/NoteView/NoteView' import NoteView from '@/Components/NoteView/NoteView'
import { ElementIds } from '@/ElementIDs' import { ElementIds } from '@/ElementIDs'
@@ -37,9 +37,9 @@ class NoteGroupView extends PureComponent<Props, State> {
}) })
this.autorun(() => { this.autorun(() => {
if (this.appState && this.appState.notes) { if (this.viewControllerManager && this.viewControllerManager.notesController) {
this.setState({ this.setState({
showMultipleSelectedNotes: this.appState.notes.selectedNotesCount > 1, showMultipleSelectedNotes: this.viewControllerManager.notesController.selectedNotesCount > 1,
}) })
} }
}) })
@@ -56,7 +56,7 @@ class NoteGroupView extends PureComponent<Props, State> {
return ( return (
<div id={ElementIds.EditorColumn} className="h-full app-column app-column-third"> <div id={ElementIds.EditorColumn} className="h-full app-column app-column-third">
{this.state.showMultipleSelectedNotes && ( {this.state.showMultipleSelectedNotes && (
<MultipleSelectedNotes application={this.application} appState={this.appState} /> <MultipleSelectedNotes application={this.application} viewControllerManager={this.viewControllerManager} />
)} )}
{!this.state.showMultipleSelectedNotes && ( {!this.state.showMultipleSelectedNotes && (

View File

@@ -8,17 +8,17 @@ import {
useRef, useRef,
useState, useState,
} from 'react' } from 'react'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { SNTag } from '@standardnotes/snjs' import { SNTag } from '@standardnotes/snjs'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
type Props = { type Props = {
appState: AppState viewControllerManager: ViewControllerManager
tag: SNTag tag: SNTag
} }
const NoteTag = ({ appState, tag }: Props) => { const NoteTag = ({ viewControllerManager, tag }: Props) => {
const noteTags = appState.noteTags const noteTags = viewControllerManager.noteTagsController
const { autocompleteInputFocused, focusedTagUuid, tags } = noteTags const { autocompleteInputFocused, focusedTagUuid, tags } = noteTags
@@ -33,9 +33,9 @@ const NoteTag = ({ appState, tag }: Props) => {
const longTitle = noteTags.getLongTitle(tag) const longTitle = noteTags.getLongTitle(tag)
const deleteTag = useCallback(() => { const deleteTag = useCallback(() => {
appState.noteTags.focusPreviousTag(tag) viewControllerManager.noteTagsController.focusPreviousTag(tag)
appState.noteTags.removeTagFromActiveNote(tag).catch(console.error) viewControllerManager.noteTagsController.removeTagFromActiveNote(tag).catch(console.error)
}, [appState, tag]) }, [viewControllerManager, tag])
const onDeleteTagClick: MouseEventHandler = useCallback( const onDeleteTagClick: MouseEventHandler = useCallback(
(event) => { (event) => {
@@ -49,28 +49,28 @@ const NoteTag = ({ appState, tag }: Props) => {
(event) => { (event) => {
if (tagClicked && event.target !== deleteTagRef.current) { if (tagClicked && event.target !== deleteTagRef.current) {
setTagClicked(false) setTagClicked(false)
void appState.tags.setSelectedTag(tag) void viewControllerManager.navigationController.setSelectedTag(tag)
} else { } else {
setTagClicked(true) setTagClicked(true)
} }
}, },
[appState, tagClicked, tag], [viewControllerManager, tagClicked, tag],
) )
const onFocus = useCallback(() => { const onFocus = useCallback(() => {
appState.noteTags.setFocusedTagUuid(tag.uuid) viewControllerManager.noteTagsController.setFocusedTagUuid(tag.uuid)
setShowDeleteButton(true) setShowDeleteButton(true)
}, [appState, tag]) }, [viewControllerManager, tag])
const onBlur: FocusEventHandler = useCallback( const onBlur: FocusEventHandler = useCallback(
(event) => { (event) => {
const relatedTarget = event.relatedTarget as Node const relatedTarget = event.relatedTarget as Node
if (relatedTarget !== deleteTagRef.current) { if (relatedTarget !== deleteTagRef.current) {
appState.noteTags.setFocusedTagUuid(undefined) viewControllerManager.noteTagsController.setFocusedTagUuid(undefined)
setShowDeleteButton(false) setShowDeleteButton(false)
} }
}, },
[appState], [viewControllerManager],
) )
const getTabIndex = useCallback(() => { const getTabIndex = useCallback(() => {
@@ -85,33 +85,33 @@ const NoteTag = ({ appState, tag }: Props) => {
const onKeyDown: KeyboardEventHandler = useCallback( const onKeyDown: KeyboardEventHandler = useCallback(
(event) => { (event) => {
const tagIndex = appState.noteTags.getTagIndex(tag, tags) const tagIndex = viewControllerManager.noteTagsController.getTagIndex(tag, tags)
switch (event.key) { switch (event.key) {
case 'Backspace': case 'Backspace':
deleteTag() deleteTag()
break break
case 'ArrowLeft': case 'ArrowLeft':
appState.noteTags.focusPreviousTag(tag) viewControllerManager.noteTagsController.focusPreviousTag(tag)
break break
case 'ArrowRight': case 'ArrowRight':
if (tagIndex === tags.length - 1) { if (tagIndex === tags.length - 1) {
appState.noteTags.setAutocompleteInputFocused(true) viewControllerManager.noteTagsController.setAutocompleteInputFocused(true)
} else { } else {
appState.noteTags.focusNextTag(tag) viewControllerManager.noteTagsController.focusNextTag(tag)
} }
break break
default: default:
return return
} }
}, },
[appState, deleteTag, tag, tags], [viewControllerManager, deleteTag, tag, tags],
) )
useEffect(() => { useEffect(() => {
if (focusedTagUuid === tag.uuid) { if (focusedTagUuid === tag.uuid) {
tagRef.current?.focus() tagRef.current?.focus()
} }
}, [appState, focusedTagUuid, tag]) }, [viewControllerManager, focusedTagUuid, tag])
return ( return (
<button <button

View File

@@ -1,19 +1,19 @@
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import AutocompleteTagInput from '@/Components/TagAutocomplete/AutocompleteTagInput' import AutocompleteTagInput from '@/Components/TagAutocomplete/AutocompleteTagInput'
import NoteTag from './NoteTag' import NoteTag from './NoteTag'
import { useEffect } from 'react' import { useEffect } from 'react'
type Props = { type Props = {
appState: AppState viewControllerManager: ViewControllerManager
} }
const NoteTagsContainer = ({ appState }: Props) => { const NoteTagsContainer = ({ viewControllerManager }: Props) => {
const { tags, tagsContainerMaxWidth } = appState.noteTags const { tags, tagsContainerMaxWidth } = viewControllerManager.noteTagsController
useEffect(() => { useEffect(() => {
appState.noteTags.reloadTagsContainerMaxWidth() viewControllerManager.noteTagsController.reloadTagsContainerMaxWidth()
}, [appState]) }, [viewControllerManager])
return ( return (
<div <div
@@ -23,9 +23,9 @@ const NoteTagsContainer = ({ appState }: Props) => {
}} }}
> >
{tags.map((tag) => ( {tags.map((tag) => (
<NoteTag key={tag.uuid} appState={appState} tag={tag} /> <NoteTag key={tag.uuid} viewControllerManager={viewControllerManager} tag={tag} />
))} ))}
<AutocompleteTagInput appState={appState} /> <AutocompleteTagInput viewControllerManager={viewControllerManager} />
</div> </div>
) )
} }

View File

@@ -2,9 +2,9 @@
* @jest-environment jsdom * @jest-environment jsdom
*/ */
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { NotesState } from '@/UIModels/AppState/NotesState' import { NotesController } from '@/Controllers/NotesController'
import { import {
ApplicationEvent, ApplicationEvent,
ProposedSecondsToDeferUILevelSessionExpirationDuringActiveInteraction, ProposedSecondsToDeferUILevelSessionExpirationDuringActiveInteraction,
@@ -17,8 +17,8 @@ import NoteView from './NoteView'
describe('NoteView', () => { describe('NoteView', () => {
let noteViewController: NoteViewController let noteViewController: NoteViewController
let application: WebApplication let application: WebApplication
let appState: AppState let viewControllerManager: ViewControllerManager
let notesState: NotesState let notesState: NotesController
const createNoteView = () => const createNoteView = () =>
new NoteView({ new NoteView({
@@ -31,15 +31,15 @@ describe('NoteView', () => {
noteViewController = {} as jest.Mocked<NoteViewController> noteViewController = {} as jest.Mocked<NoteViewController>
notesState = {} as jest.Mocked<NotesState> notesState = {} as jest.Mocked<NotesController>
notesState.setShowProtectedWarning = jest.fn() notesState.setShowProtectedWarning = jest.fn()
appState = { viewControllerManager = {
notes: notesState, notesController: notesState,
} as jest.Mocked<AppState> } as jest.Mocked<ViewControllerManager>
application = {} as jest.Mocked<WebApplication> application = {} as jest.Mocked<WebApplication>
application.getAppState = jest.fn().mockReturnValue(appState) application.getViewControllerManager = jest.fn().mockReturnValue(viewControllerManager)
application.hasProtectionSources = jest.fn().mockReturnValue(true) application.hasProtectionSources = jest.fn().mockReturnValue(true)
application.authorizeNoteAccess = jest.fn() application.authorizeNoteAccess = jest.fn()
}) })

View File

@@ -14,7 +14,7 @@ import {
PayloadEmitSource, PayloadEmitSource,
} from '@standardnotes/snjs' } from '@standardnotes/snjs'
import { debounce, isDesktopApplication } from '@/Utils' import { debounce, isDesktopApplication } from '@/Utils'
import { EventSource } from '../../UIModels/AppState/EventSource' import { EditorEventSource } from '../../Typings/EditorEventSource'
import { KeyboardModifier, KeyboardKey } from '@/Services/IOService' import { KeyboardModifier, KeyboardKey } from '@/Services/IOService'
import { STRING_DELETE_PLACEHOLDER_ATTEMPT, STRING_DELETE_LOCKED_ATTEMPT, StringDeleteNote } from '@/Strings' import { STRING_DELETE_PLACEHOLDER_ATTEMPT, STRING_DELETE_LOCKED_ATTEMPT, StringDeleteNote } from '@/Strings'
import { confirmDialog } from '@/Services/AlertService' import { confirmDialog } from '@/Services/AlertService'
@@ -82,7 +82,7 @@ class NoteView extends PureComponent<NoteViewProps, State> {
readonly controller!: NoteViewController readonly controller!: NoteViewController
private statusTimeout?: NodeJS.Timeout private statusTimeout?: NodeJS.Timeout
private lastEditorFocusEventSource?: EventSource private lastEditorFocusEventSource?: EditorEventSource
onEditorComponentLoad?: () => void onEditorComponentLoad?: () => void
private scrollPosition = 0 private scrollPosition = 0
@@ -193,7 +193,7 @@ class NoteView extends PureComponent<NoteViewProps, State> {
this.autorun(() => { this.autorun(() => {
this.setState({ this.setState({
showProtectedWarning: this.appState.notes.showProtectedWarning, showProtectedWarning: this.viewControllerManager.notesController.showProtectedWarning,
}) })
}) })
@@ -577,7 +577,7 @@ class NoteView extends PureComponent<NoteViewProps, State> {
focusEditor() { focusEditor() {
const element = document.getElementById(ElementIds.NoteTextEditor) const element = document.getElementById(ElementIds.NoteTextEditor)
if (element) { if (element) {
this.lastEditorFocusEventSource = EventSource.Script this.lastEditorFocusEventSource = EditorEventSource.Script
element.focus() element.focus()
} }
} }
@@ -588,13 +588,13 @@ class NoteView extends PureComponent<NoteViewProps, State> {
onContentFocus = () => { onContentFocus = () => {
if (this.lastEditorFocusEventSource) { if (this.lastEditorFocusEventSource) {
this.application.getAppState().editorDidFocus(this.lastEditorFocusEventSource) this.application.getViewControllerManager().editorDidFocus(this.lastEditorFocusEventSource)
} }
this.lastEditorFocusEventSource = undefined this.lastEditorFocusEventSource = undefined
} }
setShowProtectedOverlay(show: boolean) { setShowProtectedOverlay(show: boolean) {
this.appState.notes.setShowProtectedWarning(show) this.viewControllerManager.notesController.setShowProtectedWarning(show)
} }
async deleteNote(permanently: boolean) { async deleteNote(permanently: boolean) {
@@ -653,7 +653,7 @@ class NoteView extends PureComponent<NoteViewProps, State> {
} }
async reloadSpellcheck() { async reloadSpellcheck() {
const spellcheck = this.appState.notes.getSpellcheckStateForNote(this.note) const spellcheck = this.viewControllerManager.notesController.getSpellcheckStateForNote(this.note)
if (spellcheck !== this.state.spellcheck) { if (spellcheck !== this.state.spellcheck) {
this.setState({ textareaUnloading: true }) this.setState({ textareaUnloading: true })
@@ -871,7 +871,7 @@ class NoteView extends PureComponent<NoteViewProps, State> {
{this.state.showProtectedWarning && ( {this.state.showProtectedWarning && (
<div className="h-full flex justify-center items-center"> <div className="h-full flex justify-center items-center">
<ProtectedNoteOverlay <ProtectedNoteOverlay
appState={this.appState} viewControllerManager={this.viewControllerManager}
hasProtectionSources={this.application.hasProtectionSources()} hasProtectionSources={this.application.hasProtectionSources()}
onViewNote={this.dismissProtectedWarning} onViewNote={this.dismissProtectedWarning}
/> />
@@ -898,7 +898,7 @@ class NoteView extends PureComponent<NoteViewProps, State> {
showLockedIcon: false, showLockedIcon: false,
}) })
}} }}
onClick={() => this.appState.notes.setLockSelectedNotes(!this.state.noteLocked)} onClick={() => this.viewControllerManager.notesController.setLockSelectedNotes(!this.state.noteLocked)}
showLockedIcon={this.state.showLockedIcon} showLockedIcon={this.state.showLockedIcon}
lockText={this.state.lockText} lockText={this.state.lockText}
/> />
@@ -942,31 +942,31 @@ class NoteView extends PureComponent<NoteViewProps, State> {
<div className="mr-3"> <div className="mr-3">
<AttachedFilesButton <AttachedFilesButton
application={this.application} application={this.application}
appState={this.appState} viewControllerManager={this.viewControllerManager}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction} onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/> />
</div> </div>
<div className="mr-3"> <div className="mr-3">
<ChangeEditorButton <ChangeEditorButton
application={this.application} application={this.application}
appState={this.appState} viewControllerManager={this.viewControllerManager}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction} onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/> />
</div> </div>
<div className="mr-3"> <div className="mr-3">
<PinNoteButton <PinNoteButton
appState={this.appState} viewControllerManager={this.viewControllerManager}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction} onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/> />
</div> </div>
<NotesOptionsPanel <NotesOptionsPanel
application={this.application} application={this.application}
appState={this.appState} viewControllerManager={this.viewControllerManager}
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction} onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
/> />
</div> </div>
</div> </div>
<NoteTagsContainer appState={this.appState} /> <NoteTagsContainer viewControllerManager={this.viewControllerManager} />
</div> </div>
)} )}
@@ -993,7 +993,7 @@ class NoteView extends PureComponent<NoteViewProps, State> {
onLoad={this.onEditorComponentLoad} onLoad={this.onEditorComponentLoad}
requestReload={this.editorComponentViewerRequestsReload} requestReload={this.editorComponentViewerRequestsReload}
application={this.application} application={this.application}
appState={this.appState} viewControllerManager={this.viewControllerManager}
/> />
</div> </div>
)} )}
@@ -1068,7 +1068,7 @@ class NoteView extends PureComponent<NoteViewProps, State> {
key={viewer.identifier} key={viewer.identifier}
componentViewer={viewer} componentViewer={viewer}
application={this.application} application={this.application}
appState={this.appState} viewControllerManager={this.viewControllerManager}
/> />
</div> </div>
) )

View File

@@ -1,6 +1,6 @@
import { NoteViewController } from '@standardnotes/snjs' import { NoteViewController } from '@standardnotes/snjs'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
export interface NoteViewProps { export interface NoteViewProps {
application: WebApplication application: WebApplication

View File

@@ -1,27 +1,29 @@
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur' import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur'
import { useCloseOnClickOutside } from '@/Hooks/useCloseOnClickOutside' import { useCloseOnClickOutside } from '@/Hooks/useCloseOnClickOutside'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import NotesOptions from '@/Components/NotesOptions/NotesOptions' import NotesOptions from '@/Components/NotesOptions/NotesOptions'
import { useCallback, useEffect, useRef } from 'react' import { useCallback, useEffect, useRef } from 'react'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
type Props = { type Props = {
application: WebApplication application: WebApplication
appState: AppState viewControllerManager: ViewControllerManager
} }
const NotesContextMenu = ({ application, appState }: Props) => { const NotesContextMenu = ({ application, viewControllerManager }: Props) => {
const { contextMenuOpen, contextMenuPosition, contextMenuMaxHeight } = appState.notes const { contextMenuOpen, contextMenuPosition, contextMenuMaxHeight } = viewControllerManager.notesController
const contextMenuRef = useRef<HTMLDivElement>(null) const contextMenuRef = useRef<HTMLDivElement>(null)
const [closeOnBlur] = useCloseOnBlur(contextMenuRef, (open: boolean) => appState.notes.setContextMenuOpen(open)) const [closeOnBlur] = useCloseOnBlur(contextMenuRef, (open: boolean) =>
viewControllerManager.notesController.setContextMenuOpen(open),
)
useCloseOnClickOutside(contextMenuRef, () => appState.notes.setContextMenuOpen(false)) useCloseOnClickOutside(contextMenuRef, () => viewControllerManager.notesController.setContextMenuOpen(false))
const reloadContextMenuLayout = useCallback(() => { const reloadContextMenuLayout = useCallback(() => {
appState.notes.reloadContextMenuLayout() viewControllerManager.notesController.reloadContextMenuLayout()
}, [appState]) }, [viewControllerManager])
useEffect(() => { useEffect(() => {
window.addEventListener('resize', reloadContextMenuLayout) window.addEventListener('resize', reloadContextMenuLayout)
@@ -39,7 +41,7 @@ const NotesContextMenu = ({ application, appState }: Props) => {
maxHeight: contextMenuMaxHeight, maxHeight: contextMenuMaxHeight,
}} }}
> >
<NotesOptions application={application} appState={appState} closeOnBlur={closeOnBlur} /> <NotesOptions application={application} viewControllerManager={viewControllerManager} closeOnBlur={closeOnBlur} />
</div> </div>
) : null ) : null
} }

View File

@@ -1,4 +1,4 @@
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { calculateSubmenuStyle, SubmenuStyle } from '@/Utils/CalculateSubmenuStyle' import { calculateSubmenuStyle, SubmenuStyle } from '@/Utils/CalculateSubmenuStyle'
import { Disclosure, DisclosureButton, DisclosurePanel } from '@reach/disclosure' import { Disclosure, DisclosureButton, DisclosurePanel } from '@reach/disclosure'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
@@ -7,10 +7,10 @@ import Icon from '@/Components/Icon/Icon'
import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur' import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur'
type Props = { type Props = {
appState: AppState viewControllerManager: ViewControllerManager
} }
const AddTagOption: FunctionComponent<Props> = ({ appState }) => { const AddTagOption: FunctionComponent<Props> = ({ viewControllerManager }) => {
const menuContainerRef = useRef<HTMLDivElement>(null) const menuContainerRef = useRef<HTMLDivElement>(null)
const menuRef = useRef<HTMLDivElement>(null) const menuRef = useRef<HTMLDivElement>(null)
const menuButtonRef = useRef<HTMLButtonElement>(null) const menuButtonRef = useRef<HTMLButtonElement>(null)
@@ -84,22 +84,22 @@ const AddTagOption: FunctionComponent<Props> = ({ appState }) => {
}} }}
className="sn-dropdown min-w-80 flex flex-col py-2 max-h-120 max-w-xs fixed overflow-y-auto" className="sn-dropdown min-w-80 flex flex-col py-2 max-h-120 max-w-xs fixed overflow-y-auto"
> >
{appState.tags.tags.map((tag) => ( {viewControllerManager.navigationController.tags.map((tag) => (
<button <button
key={tag.uuid} key={tag.uuid}
className="sn-dropdown-item sn-dropdown-item--no-icon max-w-80" className="sn-dropdown-item sn-dropdown-item--no-icon max-w-80"
onBlur={closeOnBlur} onBlur={closeOnBlur}
onClick={() => { onClick={() => {
appState.notes.isTagInSelectedNotes(tag) viewControllerManager.notesController.isTagInSelectedNotes(tag)
? appState.notes.removeTagFromSelectedNotes(tag).catch(console.error) ? viewControllerManager.notesController.removeTagFromSelectedNotes(tag).catch(console.error)
: appState.notes.addTagToSelectedNotes(tag).catch(console.error) : viewControllerManager.notesController.addTagToSelectedNotes(tag).catch(console.error)
}} }}
> >
<span <span
className={`whitespace-nowrap overflow-hidden overflow-ellipsis className={`whitespace-nowrap overflow-hidden overflow-ellipsis
${appState.notes.isTagInSelectedNotes(tag) ? 'font-bold' : ''}`} ${viewControllerManager.notesController.isTagInSelectedNotes(tag) ? 'font-bold' : ''}`}
> >
{appState.noteTags.getLongTitle(tag)} {viewControllerManager.noteTagsController.getLongTitle(tag)}
</span> </span>
</button> </button>
))} ))}

View File

@@ -1,6 +1,6 @@
import { KeyboardKey } from '@/Services/IOService' import { KeyboardKey } from '@/Services/IOService'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { Disclosure, DisclosureButton, DisclosurePanel } from '@reach/disclosure' import { Disclosure, DisclosureButton, DisclosurePanel } from '@reach/disclosure'
import { SNNote } from '@standardnotes/snjs' import { SNNote } from '@standardnotes/snjs'
import { FunctionComponent, useCallback, useEffect, useRef, useState } from 'react' import { FunctionComponent, useCallback, useEffect, useRef, useState } from 'react'
@@ -10,7 +10,7 @@ import { calculateSubmenuStyle, SubmenuStyle } from '@/Utils/CalculateSubmenuSty
import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur' import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur'
type ChangeEditorOptionProps = { type ChangeEditorOptionProps = {
appState: AppState viewControllerManager: ViewControllerManager
application: WebApplication application: WebApplication
note: SNNote note: SNNote
} }

View File

@@ -1,4 +1,4 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { calculateSubmenuStyle, SubmenuStyle } from '@/Utils/CalculateSubmenuStyle' import { calculateSubmenuStyle, SubmenuStyle } from '@/Utils/CalculateSubmenuStyle'
import { Disclosure, DisclosureButton, DisclosurePanel } from '@reach/disclosure' import { Disclosure, DisclosureButton, DisclosurePanel } from '@reach/disclosure'
import { Action, ListedAccount, SNNote } from '@standardnotes/snjs' import { Action, ListedAccount, SNNote } from '@standardnotes/snjs'

View File

@@ -1,4 +1,4 @@
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import Icon from '@/Components/Icon/Icon' import Icon from '@/Components/Icon/Icon'
import Switch from '@/Components/Switch/Switch' import Switch from '@/Components/Switch/Switch'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
@@ -121,15 +121,15 @@ const NoteAttributes: FunctionComponent<{
} }
const SpellcheckOptions: FunctionComponent<{ const SpellcheckOptions: FunctionComponent<{
appState: AppState viewControllerManager: ViewControllerManager
note: SNNote note: SNNote
}> = ({ appState, note }) => { }> = ({ viewControllerManager, note }) => {
const editor = appState.application.componentManager.editorForNote(note) const editor = viewControllerManager.application.componentManager.editorForNote(note)
const spellcheckControllable = Boolean(!editor || editor.package_info.spellcheckControl) const spellcheckControllable = Boolean(!editor || editor.package_info.spellcheckControl)
const noteSpellcheck = !spellcheckControllable const noteSpellcheck = !spellcheckControllable
? true ? true
: note : note
? appState.notes.getSpellcheckStateForNote(note) ? viewControllerManager.notesController.getSpellcheckStateForNote(note)
: undefined : undefined
return ( return (
@@ -137,7 +137,7 @@ const SpellcheckOptions: FunctionComponent<{
<button <button
className="sn-dropdown-item justify-between px-3 py-1" className="sn-dropdown-item justify-between px-3 py-1"
onClick={() => { onClick={() => {
appState.notes.toggleGlobalSpellcheckForNote(note).catch(console.error) viewControllerManager.notesController.toggleGlobalSpellcheckForNote(note).catch(console.error)
}} }}
disabled={!spellcheckControllable} disabled={!spellcheckControllable}
> >
@@ -169,7 +169,7 @@ const NoteSizeWarning: FunctionComponent<{
) : null ) : null
} }
const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps) => { const NotesOptions = ({ application, viewControllerManager, closeOnBlur }: NotesOptionsProps) => {
const [altKeyDown, setAltKeyDown] = useState(false) const [altKeyDown, setAltKeyDown] = useState(false)
const toggleOn = (condition: (note: SNNote) => boolean) => { const toggleOn = (condition: (note: SNNote) => boolean) => {
@@ -178,7 +178,7 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
return notesMatchingAttribute.length > notesNotMatchingAttribute.length return notesMatchingAttribute.length > notesNotMatchingAttribute.length
} }
const notes = appState.notes.selectedNotes const notes = viewControllerManager.notesController.selectedNotes
const hidePreviews = toggleOn((note) => note.hidePreview) const hidePreviews = toggleOn((note) => note.hidePreview)
const locked = toggleOn((note) => note.locked) const locked = toggleOn((note) => note.locked)
const protect = toggleOn((note) => note.protected) const protect = toggleOn((note) => note.protected)
@@ -248,8 +248,8 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
}, [application, notes]) }, [application, notes])
const openRevisionHistoryModal = useCallback(() => { const openRevisionHistoryModal = useCallback(() => {
appState.notes.setShowRevisionHistoryModal(true) viewControllerManager.notesController.setShowRevisionHistoryModal(true)
}, [appState]) }, [viewControllerManager])
return ( return (
<> <>
@@ -265,7 +265,7 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
<button <button
className="sn-dropdown-item justify-between" className="sn-dropdown-item justify-between"
onClick={() => { onClick={() => {
appState.notes.setLockSelectedNotes(!locked) viewControllerManager.notesController.setLockSelectedNotes(!locked)
}} }}
onBlur={closeOnBlur} onBlur={closeOnBlur}
> >
@@ -278,7 +278,7 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
<button <button
className="sn-dropdown-item justify-between" className="sn-dropdown-item justify-between"
onClick={() => { onClick={() => {
appState.notes.setHideSelectedNotePreviews(!hidePreviews) viewControllerManager.notesController.setHideSelectedNotePreviews(!hidePreviews)
}} }}
onBlur={closeOnBlur} onBlur={closeOnBlur}
> >
@@ -291,7 +291,7 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
<button <button
className="sn-dropdown-item justify-between" className="sn-dropdown-item justify-between"
onClick={() => { onClick={() => {
appState.notes.setProtectSelectedNotes(!protect).catch(console.error) viewControllerManager.notesController.setProtectSelectedNotes(!protect).catch(console.error)
}} }}
onBlur={closeOnBlur} onBlur={closeOnBlur}
> >
@@ -304,17 +304,19 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
{notes.length === 1 && ( {notes.length === 1 && (
<> <>
<div className="min-h-1px my-2 bg-border"></div> <div className="min-h-1px my-2 bg-border"></div>
<ChangeEditorOption appState={appState} application={application} note={notes[0]} /> <ChangeEditorOption viewControllerManager={viewControllerManager} application={application} note={notes[0]} />
</> </>
)} )}
<div className="min-h-1px my-2 bg-border"></div> <div className="min-h-1px my-2 bg-border"></div>
{appState.tags.tagsCount > 0 && <AddTagOption appState={appState} />} {viewControllerManager.navigationController.tagsCount > 0 && (
<AddTagOption viewControllerManager={viewControllerManager} />
)}
{unpinned && ( {unpinned && (
<button <button
onBlur={closeOnBlur} onBlur={closeOnBlur}
className="sn-dropdown-item" className="sn-dropdown-item"
onClick={() => { onClick={() => {
appState.notes.setPinSelectedNotes(true) viewControllerManager.notesController.setPinSelectedNotes(true)
}} }}
> >
<Icon type="pin" className={iconClass} /> <Icon type="pin" className={iconClass} />
@@ -326,7 +328,7 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
onBlur={closeOnBlur} onBlur={closeOnBlur}
className="sn-dropdown-item" className="sn-dropdown-item"
onClick={() => { onClick={() => {
appState.notes.setPinSelectedNotes(false) viewControllerManager.notesController.setPinSelectedNotes(false)
}} }}
> >
<Icon type="unpin" className={iconClass} /> <Icon type="unpin" className={iconClass} />
@@ -346,7 +348,7 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
onBlur={closeOnBlur} onBlur={closeOnBlur}
className="sn-dropdown-item" className="sn-dropdown-item"
onClick={() => { onClick={() => {
appState.notes.setArchiveSelectedNotes(true).catch(console.error) viewControllerManager.notesController.setArchiveSelectedNotes(true).catch(console.error)
}} }}
> >
<Icon type="archive" className={iconClassWarning} /> <Icon type="archive" className={iconClassWarning} />
@@ -358,7 +360,7 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
onBlur={closeOnBlur} onBlur={closeOnBlur}
className="sn-dropdown-item" className="sn-dropdown-item"
onClick={() => { onClick={() => {
appState.notes.setArchiveSelectedNotes(false).catch(console.error) viewControllerManager.notesController.setArchiveSelectedNotes(false).catch(console.error)
}} }}
> >
<Icon type="unarchive" className={iconClassWarning} /> <Icon type="unarchive" className={iconClassWarning} />
@@ -370,7 +372,7 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
<DeletePermanentlyButton <DeletePermanentlyButton
closeOnBlur={closeOnBlur} closeOnBlur={closeOnBlur}
onClick={async () => { onClick={async () => {
await appState.notes.deleteNotesPermanently() await viewControllerManager.notesController.deleteNotesPermanently()
}} }}
/> />
) : ( ) : (
@@ -378,7 +380,7 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
onBlur={closeOnBlur} onBlur={closeOnBlur}
className="sn-dropdown-item" className="sn-dropdown-item"
onClick={async () => { onClick={async () => {
await appState.notes.setTrashSelectedNotes(true) await viewControllerManager.notesController.setTrashSelectedNotes(true)
}} }}
> >
<Icon type="trash" className={iconClassDanger} /> <Icon type="trash" className={iconClassDanger} />
@@ -391,7 +393,7 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
onBlur={closeOnBlur} onBlur={closeOnBlur}
className="sn-dropdown-item" className="sn-dropdown-item"
onClick={async () => { onClick={async () => {
await appState.notes.setTrashSelectedNotes(false) await viewControllerManager.notesController.setTrashSelectedNotes(false)
}} }}
> >
<Icon type="restore" className={iconClassSuccess} /> <Icon type="restore" className={iconClassSuccess} />
@@ -400,21 +402,21 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
<DeletePermanentlyButton <DeletePermanentlyButton
closeOnBlur={closeOnBlur} closeOnBlur={closeOnBlur}
onClick={async () => { onClick={async () => {
await appState.notes.deleteNotesPermanently() await viewControllerManager.notesController.deleteNotesPermanently()
}} }}
/> />
<button <button
onBlur={closeOnBlur} onBlur={closeOnBlur}
className="sn-dropdown-item" className="sn-dropdown-item"
onClick={async () => { onClick={async () => {
await appState.notes.emptyTrash() await viewControllerManager.notesController.emptyTrash()
}} }}
> >
<div className="flex items-start"> <div className="flex items-start">
<Icon type="trash-sweep" className="color-danger mr-2" /> <Icon type="trash-sweep" className="color-danger mr-2" />
<div className="flex-row"> <div className="flex-row">
<div className="color-danger">Empty Trash</div> <div className="color-danger">Empty Trash</div>
<div className="text-xs">{appState.notes.trashedNotesCount} notes in Trash</div> <div className="text-xs">{viewControllerManager.notesController.trashedNotesCount} notes in Trash</div>
</div> </div>
</div> </div>
</button> </button>
@@ -425,7 +427,7 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
<div className="min-h-1px my-2 bg-border"></div> <div className="min-h-1px my-2 bg-border"></div>
<ListedActionsOption application={application} note={notes[0]} /> <ListedActionsOption application={application} note={notes[0]} />
<div className="min-h-1px my-2 bg-border"></div> <div className="min-h-1px my-2 bg-border"></div>
<SpellcheckOptions appState={appState} note={notes[0]} /> <SpellcheckOptions viewControllerManager={viewControllerManager} note={notes[0]} />
<div className="min-h-1px my-2 bg-border"></div> <div className="min-h-1px my-2 bg-border"></div>
<NoteAttributes application={application} note={notes[0]} /> <NoteAttributes application={application} note={notes[0]} />
<NoteSizeWarning note={notes[0]} /> <NoteSizeWarning note={notes[0]} />

View File

@@ -1,4 +1,4 @@
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import Icon from '@/Components/Icon/Icon' import Icon from '@/Components/Icon/Icon'
import VisuallyHidden from '@reach/visually-hidden' import VisuallyHidden from '@reach/visually-hidden'
import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur' import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur'
@@ -6,16 +6,16 @@ import { Disclosure, DisclosureButton, DisclosurePanel } from '@reach/disclosure
import { useRef, useState } from 'react' import { useRef, useState } from 'react'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import NotesOptions from './NotesOptions' import NotesOptions from './NotesOptions'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { FOCUSABLE_BUT_NOT_TABBABLE } from '@/Constants' import { FOCUSABLE_BUT_NOT_TABBABLE } from '@/Constants'
type Props = { type Props = {
application: WebApplication application: WebApplication
appState: AppState viewControllerManager: ViewControllerManager
onClickPreprocessing?: () => Promise<void> onClickPreprocessing?: () => Promise<void>
} }
const NotesOptionsPanel = ({ application, appState, onClickPreprocessing }: Props) => { const NotesOptionsPanel = ({ application, viewControllerManager, onClickPreprocessing }: Props) => {
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
const [position, setPosition] = useState({ const [position, setPosition] = useState({
top: 0, top: 0,
@@ -79,7 +79,13 @@ const NotesOptionsPanel = ({ application, appState, onClickPreprocessing }: Prop
onBlur={closeOnBlur} onBlur={closeOnBlur}
tabIndex={FOCUSABLE_BUT_NOT_TABBABLE} tabIndex={FOCUSABLE_BUT_NOT_TABBABLE}
> >
{open && <NotesOptions application={application} appState={appState} closeOnBlur={closeOnBlur} />} {open && (
<NotesOptions
application={application}
viewControllerManager={viewControllerManager}
closeOnBlur={closeOnBlur}
/>
)}
</DisclosurePanel> </DisclosurePanel>
</Disclosure> </Disclosure>
) )

View File

@@ -1,8 +1,8 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
export type NotesOptionsProps = { export type NotesOptionsProps = {
application: WebApplication application: WebApplication
appState: AppState viewControllerManager: ViewControllerManager
closeOnBlur: (event: { relatedTarget: EventTarget | null }) => void closeOnBlur: (event: { relatedTarget: EventTarget | null }) => void
} }

View File

@@ -1,20 +1,20 @@
import { useCallback, useRef } from 'react' import { useCallback, useRef } from 'react'
import { AlertDialog, AlertDialogDescription, AlertDialogLabel } from '@reach/alert-dialog' import { AlertDialog, AlertDialogDescription, AlertDialogLabel } from '@reach/alert-dialog'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
type Props = { type Props = {
application: WebApplication application: WebApplication
appState: AppState viewControllerManager: ViewControllerManager
} }
const ConfirmOtherSessionsSignOut = observer(({ application, appState }: Props) => { const ConfirmOtherSessionsSignOut = observer(({ application, viewControllerManager }: Props) => {
const cancelRef = useRef<HTMLButtonElement>(null) const cancelRef = useRef<HTMLButtonElement>(null)
const closeDialog = useCallback(() => { const closeDialog = useCallback(() => {
appState.accountMenu.setOtherSessionsSignOut(false) viewControllerManager.accountMenuController.setOtherSessionsSignOut(false)
}, [appState]) }, [viewControllerManager])
return ( return (
<AlertDialog onDismiss={closeDialog} leastDestructiveRef={cancelRef}> <AlertDialog onDismiss={closeDialog} leastDestructiveRef={cancelRef}>
@@ -62,7 +62,7 @@ const ConfirmOtherSessionsSignOut = observer(({ application, appState }: Props)
ConfirmOtherSessionsSignOut.displayName = 'ConfirmOtherSessionsSignOut' ConfirmOtherSessionsSignOut.displayName = 'ConfirmOtherSessionsSignOut'
const OtherSessionsSignOutContainer = (props: Props) => { const OtherSessionsSignOutContainer = (props: Props) => {
if (!props.appState.accountMenu.otherSessionsSignOut) { if (!props.viewControllerManager.accountMenuController.otherSessionsSignOut) {
return null return null
} }
return <ConfirmOtherSessionsSignOut {...props} /> return <ConfirmOtherSessionsSignOut {...props} />

View File

@@ -1,4 +1,4 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { ChangeEventHandler, createRef } from 'react' import { ChangeEventHandler, createRef } from 'react'
import { PureComponent } from '@/Components/Abstract/PureComponent' import { PureComponent } from '@/Components/Abstract/PureComponent'

View File

@@ -1,4 +1,4 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { SNComponent } from '@standardnotes/snjs' import { SNComponent } from '@standardnotes/snjs'
import { Component } from 'react' import { Component } from 'react'

View File

@@ -1,4 +1,4 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { ApplicationEvent, PermissionDialog } from '@standardnotes/snjs' import { ApplicationEvent, PermissionDialog } from '@standardnotes/snjs'
import { FunctionComponent, useCallback, useEffect, useState } from 'react' import { FunctionComponent, useCallback, useEffect, useState } from 'react'
import PermissionsModal from './PermissionsModal' import PermissionsModal from './PermissionsModal'

View File

@@ -1,17 +1,21 @@
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import VisuallyHidden from '@reach/visually-hidden' import VisuallyHidden from '@reach/visually-hidden'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { FunctionComponent, useCallback } from 'react' import { FunctionComponent, useCallback } from 'react'
import Icon from '@/Components/Icon/Icon' import Icon from '@/Components/Icon/Icon'
type Props = { type Props = {
appState: AppState viewControllerManager: ViewControllerManager
className?: string className?: string
onClickPreprocessing?: () => Promise<void> onClickPreprocessing?: () => Promise<void>
} }
const PinNoteButton: FunctionComponent<Props> = ({ appState, className = '', onClickPreprocessing }: Props) => { const PinNoteButton: FunctionComponent<Props> = ({
const notes = appState.notes.selectedNotes viewControllerManager,
className = '',
onClickPreprocessing,
}: Props) => {
const notes = viewControllerManager.notesController.selectedNotes
const pinned = notes.some((note) => note.pinned) const pinned = notes.some((note) => note.pinned)
const togglePinned = useCallback(async () => { const togglePinned = useCallback(async () => {
@@ -19,11 +23,11 @@ const PinNoteButton: FunctionComponent<Props> = ({ appState, className = '', onC
await onClickPreprocessing() await onClickPreprocessing()
} }
if (!pinned) { if (!pinned) {
appState.notes.setPinSelectedNotes(true) viewControllerManager.notesController.setPinSelectedNotes(true)
} else { } else {
appState.notes.setPinSelectedNotes(false) viewControllerManager.notesController.setPinSelectedNotes(false)
} }
}, [appState, onClickPreprocessing, pinned]) }, [viewControllerManager, onClickPreprocessing, pinned])
return ( return (
<button className={`sn-icon-button border-contrast ${pinned ? 'toggled' : ''} ${className}`} onClick={togglePinned}> <button className={`sn-icon-button border-contrast ${pinned ? 'toggled' : ''} ${className}`} onClick={togglePinned}>

View File

@@ -12,7 +12,7 @@ import { PreferencesProps } from './PreferencesProps'
const PaneSelector: FunctionComponent<PreferencesProps & { menu: PreferencesMenu }> = ({ const PaneSelector: FunctionComponent<PreferencesProps & { menu: PreferencesMenu }> = ({
menu, menu,
appState, viewControllerManager,
application, application,
mfaProvider, mfaProvider,
userProvider, userProvider,
@@ -21,21 +21,26 @@ const PaneSelector: FunctionComponent<PreferencesProps & { menu: PreferencesMenu
case 'general': case 'general':
return ( return (
<General <General
appState={appState} viewControllerManager={viewControllerManager}
application={application} application={application}
extensionsLatestVersions={menu.extensionsLatestVersions} extensionsLatestVersions={menu.extensionsLatestVersions}
/> />
) )
case 'account': case 'account':
return <AccountPreferences application={application} appState={appState} /> return <AccountPreferences application={application} viewControllerManager={viewControllerManager} />
case 'appearance': case 'appearance':
return <Appearance application={application} /> return <Appearance application={application} />
case 'security': case 'security':
return ( return (
<Security mfaProvider={mfaProvider} userProvider={userProvider} appState={appState} application={application} /> <Security
mfaProvider={mfaProvider}
userProvider={userProvider}
viewControllerManager={viewControllerManager}
application={application}
/>
) )
case 'backups': case 'backups':
return <Backups application={application} appState={appState} /> return <Backups application={application} viewControllerManager={viewControllerManager} />
case 'listed': case 'listed':
return <Listed application={application} /> return <Listed application={application} />
case 'shortcuts': case 'shortcuts':
@@ -49,7 +54,7 @@ const PaneSelector: FunctionComponent<PreferencesProps & { menu: PreferencesMenu
default: default:
return ( return (
<General <General
appState={appState} viewControllerManager={viewControllerManager}
application={application} application={application}
extensionsLatestVersions={menu.extensionsLatestVersions} extensionsLatestVersions={menu.extensionsLatestVersions}
/> />

View File

@@ -1,6 +1,6 @@
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import Authentication from './Authentication' import Authentication from './Authentication'
import Credentials from './Credentials' import Credentials from './Credentials'
import Sync from './Sync' import Sync from './Sync'
@@ -11,22 +11,24 @@ import PreferencesPane from '../../PreferencesComponents/PreferencesPane'
type Props = { type Props = {
application: WebApplication application: WebApplication
appState: AppState viewControllerManager: ViewControllerManager
} }
const AccountPreferences = ({ application, appState }: Props) => ( const AccountPreferences = ({ application, viewControllerManager }: Props) => (
<PreferencesPane> <PreferencesPane>
{!application.hasAccount() ? ( {!application.hasAccount() ? (
<Authentication application={application} appState={appState} /> <Authentication application={application} viewControllerManager={viewControllerManager} />
) : ( ) : (
<> <>
<Credentials application={application} appState={appState} /> <Credentials application={application} viewControllerManager={viewControllerManager} />
<Sync application={application} /> <Sync application={application} />
</> </>
)} )}
<Subscription application={application} appState={appState} /> <Subscription application={application} viewControllerManager={viewControllerManager} />
{application.hasAccount() && appState.features.hasFiles && <FilesSection application={application} />} {application.hasAccount() && viewControllerManager.featuresController.hasFiles && (
<SignOutWrapper application={application} appState={appState} /> <FilesSection application={application} />
)}
<SignOutWrapper application={application} viewControllerManager={viewControllerManager} />
</PreferencesPane> </PreferencesPane>
) )

View File

@@ -1,8 +1,8 @@
import { FunctionComponent } from 'react' import { FunctionComponent } from 'react'
import OfflineSubscription from '@/Components/Preferences/Panes/Account/OfflineSubscription' import OfflineSubscription from '@/Components/Preferences/Panes/Account/OfflineSubscription'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import Extensions from '@/Components/Preferences/Panes/Extensions/Extensions' import Extensions from '@/Components/Preferences/Panes/Extensions/Extensions'
import { ExtensionsLatestVersions } from '@/Components/Preferences/Panes/Extensions/ExtensionsLatestVersions' import { ExtensionsLatestVersions } from '@/Components/Preferences/Panes/Extensions/ExtensionsLatestVersions'
import AccordionItem from '@/Components/Shared/AccordionItem' import AccordionItem from '@/Components/Shared/AccordionItem'
@@ -11,18 +11,18 @@ import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment'
type Props = { type Props = {
application: WebApplication application: WebApplication
appState: AppState viewControllerManager: ViewControllerManager
extensionsLatestVersions: ExtensionsLatestVersions extensionsLatestVersions: ExtensionsLatestVersions
} }
const Advanced: FunctionComponent<Props> = ({ application, appState, extensionsLatestVersions }) => { const Advanced: FunctionComponent<Props> = ({ application, viewControllerManager, extensionsLatestVersions }) => {
return ( return (
<PreferencesGroup> <PreferencesGroup>
<PreferencesSegment> <PreferencesSegment>
<AccordionItem title={'Advanced Settings'}> <AccordionItem title={'Advanced Settings'}>
<div className="flex flex-row items-center"> <div className="flex flex-row items-center">
<div className="flex-grow flex flex-col"> <div className="flex-grow flex flex-col">
<OfflineSubscription application={application} appState={appState} /> <OfflineSubscription application={application} viewControllerManager={viewControllerManager} />
<Extensions <Extensions
className={'mt-3'} className={'mt-3'}
application={application} application={application}

View File

@@ -1,7 +1,7 @@
import Button from '@/Components/Button/Button' import Button from '@/Components/Button/Button'
import { Text, Title } from '@/Components/Preferences/PreferencesComponents/Content' import { Text, Title } from '@/Components/Preferences/PreferencesComponents/Content'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { FunctionComponent } from 'react' import { FunctionComponent } from 'react'
import { AccountIllustration } from '@standardnotes/icons' import { AccountIllustration } from '@standardnotes/icons'
@@ -11,20 +11,20 @@ import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment'
type Props = { type Props = {
application: WebApplication application: WebApplication
appState: AppState viewControllerManager: ViewControllerManager
} }
const Authentication: FunctionComponent<Props> = ({ appState }) => { const Authentication: FunctionComponent<Props> = ({ viewControllerManager }) => {
const clickSignIn = () => { const clickSignIn = () => {
appState.preferences.closePreferences() viewControllerManager.preferencesController.closePreferences()
appState.accountMenu.setCurrentPane(AccountMenuPane.SignIn) viewControllerManager.accountMenuController.setCurrentPane(AccountMenuPane.SignIn)
appState.accountMenu.setShow(true) viewControllerManager.accountMenuController.setShow(true)
} }
const clickRegister = () => { const clickRegister = () => {
appState.preferences.closePreferences() viewControllerManager.preferencesController.closePreferences()
appState.accountMenu.setCurrentPane(AccountMenuPane.Register) viewControllerManager.accountMenuController.setCurrentPane(AccountMenuPane.Register)
appState.accountMenu.setShow(true) viewControllerManager.accountMenuController.setShow(true)
} }
return ( return (

View File

@@ -4,7 +4,7 @@ import ModalDialogDescription from '@/Components/Shared/ModalDialogDescription'
import ModalDialogLabel from '@/Components/Shared/ModalDialogLabel' import ModalDialogLabel from '@/Components/Shared/ModalDialogLabel'
import Button from '@/Components/Button/Button' import Button from '@/Components/Button/Button'
import { FunctionComponent, useState } from 'react' import { FunctionComponent, useState } from 'react'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { useBeforeUnload } from '@/Hooks/useBeforeUnload' import { useBeforeUnload } from '@/Hooks/useBeforeUnload'
import ChangeEmailForm from './ChangeEmailForm' import ChangeEmailForm from './ChangeEmailForm'
import ChangeEmailSuccess from './ChangeEmailSuccess' import ChangeEmailSuccess from './ChangeEmailSuccess'

View File

@@ -1,5 +1,5 @@
import Button from '@/Components/Button/Button' import Button from '@/Components/Button/Button'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { FunctionComponent } from 'react' import { FunctionComponent } from 'react'
import { Title, Text } from '../../PreferencesComponents/Content' import { Title, Text } from '../../PreferencesComponents/Content'
@@ -7,8 +7,8 @@ import PreferencesGroup from '../../PreferencesComponents/PreferencesGroup'
import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment' import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment'
const ClearSessionDataView: FunctionComponent<{ const ClearSessionDataView: FunctionComponent<{
appState: AppState viewControllerManager: ViewControllerManager
}> = ({ appState }) => { }> = ({ viewControllerManager }) => {
return ( return (
<PreferencesGroup> <PreferencesGroup>
<PreferencesSegment> <PreferencesSegment>
@@ -19,7 +19,7 @@ const ClearSessionDataView: FunctionComponent<{
dangerStyle={true} dangerStyle={true}
label="Clear workspace" label="Clear workspace"
onClick={() => { onClick={() => {
appState.accountMenu.setSigningOut(true) viewControllerManager.accountMenuController.setSigningOut(true)
}} }}
/> />
</PreferencesSegment> </PreferencesSegment>

View File

@@ -1,19 +1,19 @@
import { Subtitle, Text, Title } from '@/Components/Preferences/PreferencesComponents/Content' import { Subtitle, Text, Title } from '@/Components/Preferences/PreferencesComponents/Content'
import Button from '@/Components/Button/Button' import Button from '@/Components/Button/Button'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { observer } from '@node_modules/mobx-react-lite' import { observer } from '@node_modules/mobx-react-lite'
import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator' import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
import { dateToLocalizedString } from '@standardnotes/snjs' import { dateToLocalizedString } from '@standardnotes/snjs'
import { useCallback, useState, FunctionComponent } from 'react' import { useCallback, useState, FunctionComponent } from 'react'
import ChangeEmail from '@/Components/Preferences/Panes/Account/ChangeEmail/ChangeEmail' import ChangeEmail from '@/Components/Preferences/Panes/Account/ChangeEmail/ChangeEmail'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import PasswordWizard from '@/Components/PasswordWizard/PasswordWizard' import PasswordWizard from '@/Components/PasswordWizard/PasswordWizard'
import PreferencesGroup from '../../PreferencesComponents/PreferencesGroup' import PreferencesGroup from '../../PreferencesComponents/PreferencesGroup'
import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment' import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment'
type Props = { type Props = {
application: WebApplication application: WebApplication
appState: AppState viewControllerManager: ViewControllerManager
} }
const Credentials: FunctionComponent<Props> = ({ application }: Props) => { const Credentials: FunctionComponent<Props> = ({ application }: Props) => {

View File

@@ -1,4 +1,4 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { formatSizeToReadableString } from '@standardnotes/filepicker' import { formatSizeToReadableString } from '@standardnotes/filepicker'
import { SubscriptionSettingName } from '@standardnotes/snjs' import { SubscriptionSettingName } from '@standardnotes/snjs'
import { FunctionComponent, useEffect, useState } from 'react' import { FunctionComponent, useEffect, useState } from 'react'

View File

@@ -2,8 +2,8 @@ import React, { FunctionComponent, useEffect, useState } from 'react'
import { Subtitle } from '@/Components/Preferences/PreferencesComponents/Content' import { Subtitle } from '@/Components/Preferences/PreferencesComponents/Content'
import DecoratedInput from '@/Components/Input/DecoratedInput' import DecoratedInput from '@/Components/Input/DecoratedInput'
import Button from '@/Components/Button/Button' import Button from '@/Components/Button/Button'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { STRING_REMOVE_OFFLINE_KEY_CONFIRMATION } from '@/Strings' import { STRING_REMOVE_OFFLINE_KEY_CONFIRMATION } from '@/Strings'
import { ButtonType, ClientDisplayableError } from '@standardnotes/snjs' import { ButtonType, ClientDisplayableError } from '@standardnotes/snjs'
@@ -11,7 +11,7 @@ import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
type Props = { type Props = {
application: WebApplication application: WebApplication
appState: AppState viewControllerManager: ViewControllerManager
} }
const OfflineSubscription: FunctionComponent<Props> = ({ application }) => { const OfflineSubscription: FunctionComponent<Props> = ({ application }) => {

View File

@@ -1,8 +1,8 @@
import Button from '@/Components/Button/Button' import Button from '@/Components/Button/Button'
import OtherSessionsSignOutContainer from '@/Components/OtherSessionsSignOut/OtherSessionsSignOut' import OtherSessionsSignOutContainer from '@/Components/OtherSessionsSignOut/OtherSessionsSignOut'
import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator' import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { FunctionComponent } from 'react' import { FunctionComponent } from 'react'
import { Subtitle, Title, Text } from '../../PreferencesComponents/Content' import { Subtitle, Title, Text } from '../../PreferencesComponents/Content'
@@ -12,10 +12,10 @@ import ClearSessionDataView from './ClearSessionDataView'
type Props = { type Props = {
application: WebApplication application: WebApplication
appState: AppState viewControllerManager: ViewControllerManager
} }
const SignOutView: FunctionComponent<Props> = observer(({ application, appState }) => { const SignOutView: FunctionComponent<Props> = observer(({ application, viewControllerManager }) => {
return ( return (
<> <>
<PreferencesGroup> <PreferencesGroup>
@@ -30,10 +30,14 @@ const SignOutView: FunctionComponent<Props> = observer(({ application, appState
variant="normal" variant="normal"
label="Sign out other sessions" label="Sign out other sessions"
onClick={() => { onClick={() => {
appState.accountMenu.setOtherSessionsSignOut(true) viewControllerManager.accountMenuController.setOtherSessionsSignOut(true)
}} }}
/> />
<Button variant="normal" label="Manage sessions" onClick={() => appState.openSessionsModal()} /> <Button
variant="normal"
label="Manage sessions"
onClick={() => viewControllerManager.openSessionsModal()}
/>
</div> </div>
</PreferencesSegment> </PreferencesSegment>
<HorizontalSeparator classes="my-4" /> <HorizontalSeparator classes="my-4" />
@@ -45,23 +49,23 @@ const SignOutView: FunctionComponent<Props> = observer(({ application, appState
dangerStyle={true} dangerStyle={true}
label="Sign out workspace" label="Sign out workspace"
onClick={() => { onClick={() => {
appState.accountMenu.setSigningOut(true) viewControllerManager.accountMenuController.setSigningOut(true)
}} }}
/> />
</PreferencesSegment> </PreferencesSegment>
</PreferencesGroup> </PreferencesGroup>
<OtherSessionsSignOutContainer appState={appState} application={application} /> <OtherSessionsSignOutContainer viewControllerManager={viewControllerManager} application={application} />
</> </>
) )
}) })
SignOutView.displayName = 'SignOutView' SignOutView.displayName = 'SignOutView'
const SignOutWrapper: FunctionComponent<Props> = ({ application, appState }) => { const SignOutWrapper: FunctionComponent<Props> = ({ application, viewControllerManager }) => {
if (!application.hasAccount()) { if (!application.hasAccount()) {
return <ClearSessionDataView appState={appState} /> return <ClearSessionDataView viewControllerManager={viewControllerManager} />
} }
return <SignOutView appState={appState} application={application} /> return <SignOutView viewControllerManager={viewControllerManager} application={application} />
} }
export default observer(SignOutWrapper) export default observer(SignOutWrapper)

View File

@@ -1,7 +1,7 @@
import { FunctionComponent, useState } from 'react' import { FunctionComponent, useState } from 'react'
import { LinkButton, Text } from '@/Components/Preferences/PreferencesComponents/Content' import { LinkButton, Text } from '@/Components/Preferences/PreferencesComponents/Content'
import Button from '@/Components/Button/Button' import Button from '@/Components/Button/Button'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { loadPurchaseFlowUrl } from '@/Components/PurchaseFlow/PurchaseFlowFunctions' import { loadPurchaseFlowUrl } from '@/Components/PurchaseFlow/PurchaseFlowFunctions'
type Props = { type Props = {

View File

@@ -1,8 +1,8 @@
import { SubscriptionState } from '@/UIModels/AppState/SubscriptionState' import { SubscriptionController } from '@/Controllers/Subscription/SubscriptionController'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { Text } from '@/Components/Preferences/PreferencesComponents/Content' import { Text } from '@/Components/Preferences/PreferencesComponents/Content'
type Props = { subscriptionState: SubscriptionState } type Props = { subscriptionState: SubscriptionController }
const StatusText = ({ subscriptionState }: Props) => { const StatusText = ({ subscriptionState }: Props) => {
const { const {

View File

@@ -1,20 +1,20 @@
import { Title } from '@/Components/Preferences/PreferencesComponents/Content' import { Title } from '@/Components/Preferences/PreferencesComponents/Content'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import SubscriptionInformation from './SubscriptionInformation' import SubscriptionInformation from './SubscriptionInformation'
import NoSubscription from './NoSubscription' import NoSubscription from './NoSubscription'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { FunctionComponent } from 'react' import { FunctionComponent } from 'react'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import PreferencesGroup from '@/Components/Preferences/PreferencesComponents/PreferencesGroup' import PreferencesGroup from '@/Components/Preferences/PreferencesComponents/PreferencesGroup'
import PreferencesSegment from '@/Components/Preferences/PreferencesComponents/PreferencesSegment' import PreferencesSegment from '@/Components/Preferences/PreferencesComponents/PreferencesSegment'
type Props = { type Props = {
application: WebApplication application: WebApplication
appState: AppState viewControllerManager: ViewControllerManager
} }
const Subscription: FunctionComponent<Props> = ({ application, appState }: Props) => { const Subscription: FunctionComponent<Props> = ({ application, viewControllerManager }: Props) => {
const subscriptionState = appState.subscription const subscriptionState = viewControllerManager.subscriptionController
const { userSubscription } = subscriptionState const { userSubscription } = subscriptionState
const now = new Date().getTime() const now = new Date().getTime()

View File

@@ -1,12 +1,12 @@
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { SubscriptionState } from '@/UIModels/AppState/SubscriptionState' import { SubscriptionController } from '@/Controllers/Subscription/SubscriptionController'
import Button from '@/Components/Button/Button' import Button from '@/Components/Button/Button'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { openSubscriptionDashboard } from '@/Utils/ManageSubscription' import { openSubscriptionDashboard } from '@/Utils/ManageSubscription'
import StatusText from './StatusText' import StatusText from './StatusText'
type Props = { type Props = {
subscriptionState: SubscriptionState subscriptionState: SubscriptionController
application: WebApplication application: WebApplication
} }

View File

@@ -3,7 +3,7 @@ import Button from '@/Components/Button/Button'
import { SyncQueueStrategy } from '@standardnotes/snjs' import { SyncQueueStrategy } from '@standardnotes/snjs'
import { STRING_GENERIC_SYNC_ERROR } from '@/Strings' import { STRING_GENERIC_SYNC_ERROR } from '@/Strings'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { FunctionComponent, useState } from 'react' import { FunctionComponent, useState } from 'react'
import { formatLastSyncDate } from '@/Utils/FormatLastSyncDate' import { formatLastSyncDate } from '@/Utils/FormatLastSyncDate'
import PreferencesGroup from '../../PreferencesComponents/PreferencesGroup' import PreferencesGroup from '../../PreferencesComponents/PreferencesGroup'

View File

@@ -3,7 +3,7 @@ import { DropdownItem } from '@/Components/Dropdown/DropdownItem'
import { usePremiumModal } from '@/Hooks/usePremiumModal' import { usePremiumModal } from '@/Hooks/usePremiumModal'
import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator' import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
import Switch from '@/Components/Switch/Switch' import Switch from '@/Components/Switch/Switch'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { ContentType, FeatureIdentifier, FeatureStatus, PrefKey, GetFeatures, SNTheme } from '@standardnotes/snjs' import { ContentType, FeatureIdentifier, FeatureStatus, PrefKey, GetFeatures, SNTheme } from '@standardnotes/snjs'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { FunctionComponent, useEffect, useState } from 'react' import { FunctionComponent, useEffect, useState } from 'react'

View File

@@ -1,5 +1,5 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { FunctionComponent } from 'react' import { FunctionComponent } from 'react'
import PreferencesPane from '@/Components/Preferences/PreferencesComponents/PreferencesPane' import PreferencesPane from '@/Components/Preferences/PreferencesComponents/PreferencesPane'
import CloudLink from './CloudBackups/CloudBackups' import CloudLink from './CloudBackups/CloudBackups'
@@ -9,14 +9,14 @@ import FileBackupsCrossPlatform from './Files/FileBackupsCrossPlatform'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
type Props = { type Props = {
appState: AppState viewControllerManager: ViewControllerManager
application: WebApplication application: WebApplication
} }
const Backups: FunctionComponent<Props> = ({ application, appState }) => { const Backups: FunctionComponent<Props> = ({ application, viewControllerManager }) => {
return ( return (
<PreferencesPane> <PreferencesPane>
<DataBackups application={application} appState={appState} /> <DataBackups application={application} viewControllerManager={viewControllerManager} />
<FileBackupsCrossPlatform application={application} /> <FileBackupsCrossPlatform application={application} />
<EmailBackups application={application} /> <EmailBackups application={application} />
<CloudLink application={application} /> <CloudLink application={application} />

View File

@@ -15,7 +15,7 @@ import {
GoogleDriveBackupFrequency, GoogleDriveBackupFrequency,
OneDriveBackupFrequency, OneDriveBackupFrequency,
} from '@standardnotes/snjs' } from '@standardnotes/snjs'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import Button from '@/Components/Button/Button' import Button from '@/Components/Button/Button'
import { isDev, openInNewTab } from '@/Utils' import { isDev, openInNewTab } from '@/Utils'
import { Subtitle } from '@/Components/Preferences/PreferencesComponents/Content' import { Subtitle } from '@/Components/Preferences/PreferencesComponents/Content'

View File

@@ -1,6 +1,6 @@
import CloudBackupProvider from './CloudBackupProvider' import CloudBackupProvider from './CloudBackupProvider'
import { useCallback, useEffect, useState, FunctionComponent, Fragment } from 'react' import { useCallback, useEffect, useState, FunctionComponent, Fragment } from 'react'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { Subtitle, Text, Title } from '@/Components/Preferences/PreferencesComponents/Content' import { Subtitle, Text, Title } from '@/Components/Preferences/PreferencesComponents/Content'
import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator' import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
import { import {

View File

@@ -12,8 +12,8 @@ import {
} from '@/Strings' } from '@/Strings'
import { BackupFile } from '@standardnotes/snjs' import { BackupFile } from '@standardnotes/snjs'
import { ChangeEventHandler, MouseEventHandler, useCallback, useEffect, useRef, useState } from 'react' import { ChangeEventHandler, MouseEventHandler, useCallback, useEffect, useRef, useState } from 'react'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { Title, Text, Subtitle } from '@/Components/Preferences/PreferencesComponents/Content' import { Title, Text, Subtitle } from '@/Components/Preferences/PreferencesComponents/Content'
import Button from '@/Components/Button/Button' import Button from '@/Components/Button/Button'
@@ -23,10 +23,10 @@ import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
type Props = { type Props = {
application: WebApplication application: WebApplication
appState: AppState viewControllerManager: ViewControllerManager
} }
const DataBackups = ({ application, appState }: Props) => { const DataBackups = ({ application, viewControllerManager }: Props) => {
const fileInputRef = useRef<HTMLInputElement>(null) const fileInputRef = useRef<HTMLInputElement>(null)
const [isImportDataLoading, setIsImportDataLoading] = useState(false) const [isImportDataLoading, setIsImportDataLoading] = useState(false)
const { const {
@@ -35,7 +35,7 @@ const DataBackups = ({ application, appState }: Props) => {
setIsBackupEncrypted, setIsBackupEncrypted,
setIsEncryptionEnabled, setIsEncryptionEnabled,
setEncryptionStatusString, setEncryptionStatusString,
} = appState.accountMenu } = viewControllerManager.accountMenuController
const refreshEncryptionStatus = useCallback(() => { const refreshEncryptionStatus = useCallback(() => {
const hasUser = application.hasAccount() const hasUser = application.hasAccount()

View File

@@ -1,7 +1,7 @@
import { convertStringifiedBooleanToBoolean, isDesktopApplication } from '@/Utils' import { convertStringifiedBooleanToBoolean, isDesktopApplication } from '@/Utils'
import { STRING_FAILED_TO_UPDATE_USER_SETTING } from '@/Strings' import { STRING_FAILED_TO_UPDATE_USER_SETTING } from '@/Strings'
import { useCallback, useEffect, useState } from 'react' import { useCallback, useEffect, useState } from 'react'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { Subtitle, Text, Title } from '@/Components/Preferences/PreferencesComponents/Content' import { Subtitle, Text, Title } from '@/Components/Preferences/PreferencesComponents/Content'
import Dropdown from '@/Components/Dropdown/Dropdown' import Dropdown from '@/Components/Dropdown/Dropdown'

View File

@@ -6,7 +6,7 @@ import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
import Icon from '@/Components/Icon/Icon' import Icon from '@/Components/Icon/Icon'
import { StreamingFileApi } from '@standardnotes/filepicker' import { StreamingFileApi } from '@standardnotes/filepicker'
import { isHandlingBackupDrag } from '@/Utils/DragTypeCheck' import { isHandlingBackupDrag } from '@/Utils/DragTypeCheck'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import EncryptionStatusItem from '../../Security/EncryptionStatusItem' import EncryptionStatusItem from '../../Security/EncryptionStatusItem'
import PreferencesSegment from '@/Components/Preferences/PreferencesComponents/PreferencesSegment' import PreferencesSegment from '@/Components/Preferences/PreferencesComponents/PreferencesSegment'

View File

@@ -1,7 +1,7 @@
import { Subtitle, Title, Text } from '@/Components/Preferences/PreferencesComponents/Content' import { Subtitle, Title, Text } from '@/Components/Preferences/PreferencesComponents/Content'
import PreferencesGroup from '@/Components/Preferences/PreferencesComponents/PreferencesGroup' import PreferencesGroup from '@/Components/Preferences/PreferencesComponents/PreferencesGroup'
import PreferencesSegment from '@/Components/Preferences/PreferencesComponents/PreferencesSegment' import PreferencesSegment from '@/Components/Preferences/PreferencesComponents/PreferencesSegment'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { useMemo } from 'react' import { useMemo } from 'react'
import BackupsDropZone from './BackupsDropZone' import BackupsDropZone from './BackupsDropZone'
import FileBackupsDesktop from './FileBackupsDesktop' import FileBackupsDesktop from './FileBackupsDesktop'

View File

@@ -1,4 +1,4 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { Title, Text, Subtitle } from '@/Components/Preferences/PreferencesComponents/Content' import { Title, Text, Subtitle } from '@/Components/Preferences/PreferencesComponents/Content'
import { useCallback, useEffect, useState } from 'react' import { useCallback, useEffect, useState } from 'react'

View File

@@ -1,4 +1,4 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { AnyExtension } from './AnyExtension' import { AnyExtension } from './AnyExtension'
export interface ExtensionItemProps { export interface ExtensionItemProps {

View File

@@ -1,7 +1,7 @@
import { ButtonType, ContentType, SNComponent } from '@standardnotes/snjs' import { ButtonType, ContentType, SNComponent } from '@standardnotes/snjs'
import Button from '@/Components/Button/Button' import Button from '@/Components/Button/Button'
import DecoratedInput from '@/Components/Input/DecoratedInput' import DecoratedInput from '@/Components/Input/DecoratedInput'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { FunctionComponent, useEffect, useRef, useState } from 'react' import { FunctionComponent, useEffect, useRef, useState } from 'react'
import { Title } from '@/Components/Preferences/PreferencesComponents/Content' import { Title } from '@/Components/Preferences/PreferencesComponents/Content'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'

View File

@@ -1,4 +1,4 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { ClientDisplayableError, FeatureDescription } from '@standardnotes/snjs' import { ClientDisplayableError, FeatureDescription } from '@standardnotes/snjs'
import { makeAutoObservable, observable } from 'mobx' import { makeAutoObservable, observable } from 'mobx'
import { AnyExtension } from './AnyExtension' import { AnyExtension } from './AnyExtension'

View File

@@ -2,7 +2,7 @@ import Dropdown from '@/Components/Dropdown/Dropdown'
import { DropdownItem } from '@/Components/Dropdown/DropdownItem' import { DropdownItem } from '@/Components/Dropdown/DropdownItem'
import { FeatureIdentifier, PrefKey, ComponentArea, ComponentMutator, SNComponent } from '@standardnotes/snjs' import { FeatureIdentifier, PrefKey, ComponentArea, ComponentMutator, SNComponent } from '@standardnotes/snjs'
import { Subtitle, Text, Title } from '@/Components/Preferences/PreferencesComponents/Content' import { Subtitle, Text, Title } from '@/Components/Preferences/PreferencesComponents/Content'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { FunctionComponent, useEffect, useState } from 'react' import { FunctionComponent, useEffect, useState } from 'react'
import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator' import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
import Switch from '@/Components/Switch/Switch' import Switch from '@/Components/Switch/Switch'
@@ -57,7 +57,7 @@ const Defaults: FunctionComponent<Props> = ({ application }) => {
const toggleSpellcheck = () => { const toggleSpellcheck = () => {
setSpellcheck(!spellcheck) setSpellcheck(!spellcheck)
application.getAppState().toggleGlobalSpellcheck().catch(console.error) application.getViewControllerManager().toggleGlobalSpellcheck().catch(console.error)
} }
useEffect(() => { useEffect(() => {

View File

@@ -1,5 +1,5 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { FunctionComponent } from 'react' import { FunctionComponent } from 'react'
import { ExtensionsLatestVersions } from '@/Components/Preferences/Panes/Extensions/ExtensionsLatestVersions' import { ExtensionsLatestVersions } from '@/Components/Preferences/Panes/Extensions/ExtensionsLatestVersions'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
@@ -10,17 +10,21 @@ import Advanced from '@/Components/Preferences/Panes/Account/Advanced'
import PreferencesPane from '../../PreferencesComponents/PreferencesPane' import PreferencesPane from '../../PreferencesComponents/PreferencesPane'
type Props = { type Props = {
appState: AppState viewControllerManager: ViewControllerManager
application: WebApplication application: WebApplication
extensionsLatestVersions: ExtensionsLatestVersions extensionsLatestVersions: ExtensionsLatestVersions
} }
const General: FunctionComponent<Props> = ({ appState, application, extensionsLatestVersions }) => ( const General: FunctionComponent<Props> = ({ viewControllerManager, application, extensionsLatestVersions }) => (
<PreferencesPane> <PreferencesPane>
<Tools application={application} /> <Tools application={application} />
<Defaults application={application} /> <Defaults application={application} />
<LabsPane application={application} /> <LabsPane application={application} />
<Advanced application={application} appState={appState} extensionsLatestVersions={extensionsLatestVersions} /> <Advanced
application={application}
viewControllerManager={viewControllerManager}
extensionsLatestVersions={extensionsLatestVersions}
/>
</PreferencesPane> </PreferencesPane>
) )

View File

@@ -1,6 +1,6 @@
import Switch from '@/Components/Switch/Switch' import Switch from '@/Components/Switch/Switch'
import { Subtitle, Text, Title } from '@/Components/Preferences/PreferencesComponents/Content' import { Subtitle, Text, Title } from '@/Components/Preferences/PreferencesComponents/Content'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { FeatureIdentifier, FeatureStatus, FindNativeFeature } from '@standardnotes/snjs' import { FeatureIdentifier, FeatureStatus, FindNativeFeature } from '@standardnotes/snjs'
import { Fragment, FunctionComponent, useCallback, useEffect, useState } from 'react' import { Fragment, FunctionComponent, useCallback, useEffect, useState } from 'react'
import { usePremiumModal } from '@/Hooks/usePremiumModal' import { usePremiumModal } from '@/Hooks/usePremiumModal'

View File

@@ -1,7 +1,7 @@
import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator' import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
import Switch from '@/Components/Switch/Switch' import Switch from '@/Components/Switch/Switch'
import { Subtitle, Text, Title } from '@/Components/Preferences/PreferencesComponents/Content' import { Subtitle, Text, Title } from '@/Components/Preferences/PreferencesComponents/Content'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { PrefKey } from '@standardnotes/snjs' import { PrefKey } from '@standardnotes/snjs'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { FunctionComponent, useState } from 'react' import { FunctionComponent, useState } from 'react'

View File

@@ -1,6 +1,6 @@
import { Title, Subtitle, Text } from '@/Components/Preferences/PreferencesComponents/Content' import { Title, Subtitle, Text } from '@/Components/Preferences/PreferencesComponents/Content'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { ButtonType, ListedAccount } from '@standardnotes/snjs' import { ButtonType, ListedAccount } from '@standardnotes/snjs'
import { useCallback, useEffect, useState } from 'react' import { useCallback, useEffect, useState } from 'react'
import ListedAccountItem from './ListedAccountItem' import ListedAccountItem from './ListedAccountItem'

View File

@@ -1,6 +1,6 @@
import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator' import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
import { LinkButton, Subtitle } from '@/Components/Preferences/PreferencesComponents/Content' import { LinkButton, Subtitle } from '@/Components/Preferences/PreferencesComponents/Content'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { ListedAccount, ListedAccountInfo } from '@standardnotes/snjs' import { ListedAccount, ListedAccountInfo } from '@standardnotes/snjs'
import { FunctionComponent, useEffect, useState } from 'react' import { FunctionComponent, useEffect, useState } from 'react'

View File

@@ -1,5 +1,5 @@
import { STRING_E2E_ENABLED, STRING_ENC_NOT_ENABLED, STRING_LOCAL_ENC_ENABLED } from '@/Strings' import { STRING_E2E_ENABLED, STRING_ENC_NOT_ENABLED, STRING_LOCAL_ENC_ENABLED } from '@/Strings'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { FunctionComponent } from 'react' import { FunctionComponent } from 'react'
import { Title, Text } from '../../PreferencesComponents/Content' import { Title, Text } from '../../PreferencesComponents/Content'
@@ -7,10 +7,10 @@ import PreferencesGroup from '../../PreferencesComponents/PreferencesGroup'
import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment' import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment'
import EncryptionEnabled from './EncryptionEnabled' import EncryptionEnabled from './EncryptionEnabled'
type Props = { appState: AppState } type Props = { viewControllerManager: ViewControllerManager }
const Encryption: FunctionComponent<Props> = ({ appState }) => { const Encryption: FunctionComponent<Props> = ({ viewControllerManager }) => {
const app = appState.application const app = viewControllerManager.application
const hasUser = app.hasAccount() const hasUser = app.hasAccount()
const hasPasscode = app.hasPasscode() const hasPasscode = app.hasPasscode()
const isEncryptionEnabled = app.isEncryptionAvailable() const isEncryptionEnabled = app.isEncryptionAvailable()
@@ -27,7 +27,7 @@ const Encryption: FunctionComponent<Props> = ({ appState }) => {
<Title>Encryption</Title> <Title>Encryption</Title>
<Text>{encryptionStatusString}</Text> <Text>{encryptionStatusString}</Text>
{isEncryptionEnabled && <EncryptionEnabled appState={appState} />} {isEncryptionEnabled && <EncryptionEnabled viewControllerManager={viewControllerManager} />}
</PreferencesSegment> </PreferencesSegment>
</PreferencesGroup> </PreferencesGroup>
) )

View File

@@ -1,16 +1,16 @@
import Icon from '@/Components/Icon/Icon' import Icon from '@/Components/Icon/Icon'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { FunctionComponent } from 'react' import { FunctionComponent } from 'react'
import EncryptionStatusItem from './EncryptionStatusItem' import EncryptionStatusItem from './EncryptionStatusItem'
import { formatCount } from './formatCount' import { formatCount } from './formatCount'
type Props = { type Props = {
appState: AppState viewControllerManager: ViewControllerManager
} }
const EncryptionEnabled: FunctionComponent<Props> = ({ appState }) => { const EncryptionEnabled: FunctionComponent<Props> = ({ viewControllerManager }) => {
const count = appState.accountMenu.structuredNotesAndTagsCount const count = viewControllerManager.accountMenuController.structuredNotesAndTagsCount
const notes = formatCount(count.notes, 'notes') const notes = formatCount(count.notes, 'notes')
const tags = formatCount(count.tags, 'tags') const tags = formatCount(count.tags, 'tags')
const archived = formatCount(count.archived, 'archived notes') const archived = formatCount(count.archived, 'archived notes')

View File

@@ -1,4 +1,4 @@
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { Fragment, FunctionComponent, useState } from 'react' import { Fragment, FunctionComponent, useState } from 'react'
import { Text, Title, Subtitle } from '@/Components/Preferences/PreferencesComponents/Content' import { Text, Title, Subtitle } from '@/Components/Preferences/PreferencesComponents/Content'
@@ -13,10 +13,10 @@ import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment' import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment'
import PreferencesGroup from '../../PreferencesComponents/PreferencesGroup' import PreferencesGroup from '../../PreferencesComponents/PreferencesGroup'
type Props = { appState: AppState } type Props = { viewControllerManager: ViewControllerManager }
const ErroredItems: FunctionComponent<Props> = ({ appState }: Props) => { const ErroredItems: FunctionComponent<Props> = ({ viewControllerManager }: Props) => {
const app = appState.application const app = viewControllerManager.application
const [erroredItems, setErroredItems] = useState(app.items.invalidItems) const [erroredItems, setErroredItems] = useState(app.items.invalidItems)

View File

@@ -8,13 +8,13 @@ import {
StringUtils, StringUtils,
Strings, Strings,
} from '@/Strings' } from '@/Strings'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { preventRefreshing } from '@/Utils' import { preventRefreshing } from '@/Utils'
import { alertDialog } from '@/Services/AlertService' import { alertDialog } from '@/Services/AlertService'
import { ChangeEventHandler, FormEvent, useCallback, useEffect, useRef, useState } from 'react' import { ChangeEventHandler, FormEvent, useCallback, useEffect, useRef, useState } from 'react'
import { ApplicationEvent } from '@standardnotes/snjs' import { ApplicationEvent } from '@standardnotes/snjs'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { Title, Text } from '@/Components/Preferences/PreferencesComponents/Content' import { Title, Text } from '@/Components/Preferences/PreferencesComponents/Content'
import Button from '@/Components/Button/Button' import Button from '@/Components/Button/Button'
import PreferencesGroup from '../../PreferencesComponents/PreferencesGroup' import PreferencesGroup from '../../PreferencesComponents/PreferencesGroup'
@@ -22,14 +22,15 @@ import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment'
type Props = { type Props = {
application: WebApplication application: WebApplication
appState: AppState viewControllerManager: ViewControllerManager
} }
const PasscodeLock = ({ application, appState }: Props) => { const PasscodeLock = ({ application, viewControllerManager }: Props) => {
const keyStorageInfo = StringUtils.keyStorageInfo(application) const keyStorageInfo = StringUtils.keyStorageInfo(application)
const passcodeAutoLockOptions = application.getAutolockService().getAutoLockIntervalOptions() const passcodeAutoLockOptions = application.getAutolockService().getAutoLockIntervalOptions()
const { setIsEncryptionEnabled, setIsBackupEncrypted, setEncryptionStatusString } = appState.accountMenu const { setIsEncryptionEnabled, setIsBackupEncrypted, setEncryptionStatusString } =
viewControllerManager.accountMenuController
const passcodeInputRef = useRef<HTMLInputElement>(null) const passcodeInputRef = useRef<HTMLInputElement>(null)

View File

@@ -1,7 +1,7 @@
import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator' import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
import Switch from '@/Components/Switch/Switch' import Switch from '@/Components/Switch/Switch'
import { Subtitle, Text, Title } from '@/Components/Preferences/PreferencesComponents/Content' import { Subtitle, Text, Title } from '@/Components/Preferences/PreferencesComponents/Content'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { MuteSignInEmailsOption, LogSessionUserAgentOption, SettingName } from '@standardnotes/snjs' import { MuteSignInEmailsOption, LogSessionUserAgentOption, SettingName } from '@standardnotes/snjs'
import { observer } from 'mobx-react-lite' import { observer } from 'mobx-react-lite'
import { FunctionComponent, useCallback, useEffect, useState } from 'react' import { FunctionComponent, useCallback, useEffect, useState } from 'react'

View File

@@ -1,4 +1,4 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { FunctionComponent, useCallback, useState, useEffect } from 'react' import { FunctionComponent, useCallback, useState, useEffect } from 'react'
import { ApplicationEvent } from '@standardnotes/snjs' import { ApplicationEvent } from '@standardnotes/snjs'
import { isSameDay } from '@/Utils' import { isSameDay } from '@/Utils'

View File

@@ -1,5 +1,5 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { AppState } from '@/UIModels/AppState' import { ViewControllerManager } from '@/Services/ViewControllerManager'
import { FunctionComponent } from 'react' import { FunctionComponent } from 'react'
import TwoFactorAuthWrapper from '../TwoFactorAuth/TwoFactorAuthWrapper' import TwoFactorAuthWrapper from '../TwoFactorAuth/TwoFactorAuthWrapper'
import { MfaProps } from '../TwoFactorAuth/MfaProps' import { MfaProps } from '../TwoFactorAuth/MfaProps'
@@ -11,17 +11,19 @@ import ErroredItems from './ErroredItems'
import PreferencesPane from '@/Components/Preferences/PreferencesComponents/PreferencesPane' import PreferencesPane from '@/Components/Preferences/PreferencesComponents/PreferencesPane'
interface SecurityProps extends MfaProps { interface SecurityProps extends MfaProps {
appState: AppState viewControllerManager: ViewControllerManager
application: WebApplication application: WebApplication
} }
const Security: FunctionComponent<SecurityProps> = (props) => ( const Security: FunctionComponent<SecurityProps> = (props) => (
<PreferencesPane> <PreferencesPane>
<Encryption appState={props.appState} /> <Encryption viewControllerManager={props.viewControllerManager} />
{props.application.items.invalidItems.length > 0 && <ErroredItems appState={props.appState} />} {props.application.items.invalidItems.length > 0 && (
<ErroredItems viewControllerManager={props.viewControllerManager} />
)}
<Protections application={props.application} /> <Protections application={props.application} />
<TwoFactorAuthWrapper mfaProvider={props.mfaProvider} userProvider={props.userProvider} /> <TwoFactorAuthWrapper mfaProvider={props.mfaProvider} userProvider={props.userProvider} />
<PasscodeLock appState={props.appState} application={props.application} /> <PasscodeLock viewControllerManager={props.viewControllerManager} application={props.application} />
{props.application.getUser() && <Privacy application={props.application} />} {props.application.getUser() && <Privacy application={props.application} />}
</PreferencesPane> </PreferencesPane>
) )

View File

@@ -1,4 +1,4 @@
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
export const securityPrefsHasBubble = (application: WebApplication): boolean => { export const securityPrefsHasBubble = (application: WebApplication): boolean => {
return application.items.invalidItems.length > 0 return application.items.invalidItems.length > 0

View File

@@ -1,6 +1,6 @@
import { action, makeAutoObservable, observable } from 'mobx' import { action, makeAutoObservable, observable } from 'mobx'
import { IconType } from '@standardnotes/snjs' import { IconType } from '@standardnotes/snjs'
import { WebApplication } from '@/UIModels/Application' import { WebApplication } from '@/Application/Application'
import { ExtensionsLatestVersions } from './Panes/Extensions/ExtensionsLatestVersions' import { ExtensionsLatestVersions } from './Panes/Extensions/ExtensionsLatestVersions'
import { securityPrefsHasBubble } from './Panes/Security/securityPrefsHasBubble' import { securityPrefsHasBubble } from './Panes/Security/securityPrefsHasBubble'

Some files were not shown because too many files have changed in this diff Show More