refactor: rename states to view controllers (#1060)
This commit is contained in:
12
.babelrc
12
.babelrc
@@ -1,12 +1,4 @@
|
||||
{
|
||||
"presets": [
|
||||
"@babel/preset-typescript",
|
||||
"@babel/preset-env"
|
||||
],
|
||||
"plugins": [
|
||||
["@babel/plugin-transform-react-jsx", {
|
||||
"pragma": "h",
|
||||
"pragmaFrag": "Fragment"
|
||||
}]
|
||||
]
|
||||
"presets": ["@babel/preset-typescript", "@babel/preset-env"],
|
||||
"plugins": [["@babel/plugin-transform-react-jsx"]]
|
||||
}
|
||||
|
||||
@@ -25,9 +25,9 @@ import { DesktopManagerInterface, SNLog } from '@standardnotes/snjs'
|
||||
import ApplicationGroupView from './Components/ApplicationGroupView/ApplicationGroupView'
|
||||
import { WebDevice } from './Device/WebDevice'
|
||||
import { StartApplication } from './Device/StartApplication'
|
||||
import { ApplicationGroup } from './UIModels/ApplicationGroup'
|
||||
import { ApplicationGroup } from './Application/ApplicationGroup'
|
||||
import { WebOrDesktopDevice } from './Device/WebOrDesktopDevice'
|
||||
import { WebApplication } from './UIModels/Application'
|
||||
import { WebApplication } from './Application/Application'
|
||||
import { createRoot, Root } from 'react-dom/client'
|
||||
|
||||
let keyCount = 0
|
||||
|
||||
@@ -5,7 +5,7 @@ import { AutolockService } from '@/Services/AutolockService'
|
||||
import { DesktopManager } from '@/Services/DesktopManager'
|
||||
import { IOService } from '@/Services/IOService'
|
||||
import { ThemeManager } from '@/Services/ThemeManager'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { WebOrDesktopDevice } from '@/Device/WebOrDesktopDevice'
|
||||
import {
|
||||
DeinitSource,
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
import { makeObservable, observable } from 'mobx'
|
||||
|
||||
type WebServices = {
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
desktopService?: DesktopManager
|
||||
autolockService: AutolockService
|
||||
archiveService: ArchiveManager
|
||||
@@ -116,8 +116,8 @@ export class WebApplication extends SNApplication {
|
||||
}
|
||||
}
|
||||
|
||||
public getAppState(): AppState {
|
||||
return this.webServices.appState
|
||||
public getViewControllerManager(): ViewControllerManager {
|
||||
return this.webServices.viewControllerManager
|
||||
}
|
||||
|
||||
public getDesktopService(): DesktopManager | undefined {
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
InternalEventBus,
|
||||
isDesktopDevice,
|
||||
} from '@standardnotes/snjs'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { getPlatform, isDesktopApplication } from '@/Utils'
|
||||
import { ArchiveManager } from '@/Services/ArchiveManager'
|
||||
import { DesktopManager } from '@/Services/DesktopManager'
|
||||
@@ -32,14 +32,14 @@ const createApplication = (
|
||||
webSocketUrl,
|
||||
)
|
||||
|
||||
const appState = new AppState(application, device)
|
||||
const viewControllerManager = new ViewControllerManager(application, device)
|
||||
const archiveService = new ArchiveManager(application)
|
||||
const io = new IOService(platform === Platform.MacWeb || platform === Platform.MacDesktop)
|
||||
const autolockService = new AutolockService(application, new InternalEventBus())
|
||||
const themeService = new ThemeManager(application)
|
||||
|
||||
application.setWebServices({
|
||||
appState,
|
||||
viewControllerManager,
|
||||
archiveService,
|
||||
desktopService: isDesktopDevice(device) ? new DesktopManager(application, device) : undefined,
|
||||
io,
|
||||
@@ -1,8 +1,9 @@
|
||||
import { ApplicationEvent } from '@standardnotes/snjs'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { AppState, AppStateEvent } from '@/UIModels/AppState'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ViewControllerManager, ViewControllerManagerEvent } from '@/Services/ViewControllerManager'
|
||||
import { autorun, IReactionDisposer, IReactionPublic } from 'mobx'
|
||||
import { Component } from 'react'
|
||||
|
||||
export type PureComponentState = 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() {
|
||||
this.addAppEventObserver()
|
||||
this.addAppStateObserver()
|
||||
this.addViewControllerManagerObserver()
|
||||
}
|
||||
|
||||
deinit(): void {
|
||||
@@ -38,21 +39,21 @@ export abstract class PureComponent<P = PureComponentProps, S = PureComponentSta
|
||||
this.deinit()
|
||||
}
|
||||
|
||||
public get appState(): AppState {
|
||||
return this.application.getAppState()
|
||||
public get viewControllerManager(): ViewControllerManager {
|
||||
return this.application.getViewControllerManager()
|
||||
}
|
||||
|
||||
autorun(view: (r: IReactionPublic) => void): void {
|
||||
this.reactionDisposers.push(autorun(view))
|
||||
}
|
||||
|
||||
addAppStateObserver() {
|
||||
this.unsubState = this.application.getAppState().addObserver(async (eventName, data) => {
|
||||
this.onAppStateEvent(eventName, data)
|
||||
addViewControllerManagerObserver() {
|
||||
this.unsubState = this.application.getViewControllerManager().addObserver(async (eventName, data) => {
|
||||
this.onViewControllerManagerEvent(eventName, data)
|
||||
})
|
||||
}
|
||||
|
||||
onAppStateEvent(_eventName: AppStateEvent, _data: unknown) {
|
||||
onViewControllerManagerEvent(_eventName: ViewControllerManagerEvent, _data: unknown) {
|
||||
/** Optional override */
|
||||
}
|
||||
|
||||
|
||||
@@ -1,31 +1,36 @@
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { useCloseOnClickOutside } from '@/Hooks/useCloseOnClickOutside'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { useCallback, useRef, FunctionComponent, KeyboardEventHandler } from 'react'
|
||||
import { ApplicationGroup } from '@/UIModels/ApplicationGroup'
|
||||
import { ApplicationGroup } from '@/Application/ApplicationGroup'
|
||||
import { AccountMenuPane } from './AccountMenuPane'
|
||||
import MenuPaneSelector from './MenuPaneSelector'
|
||||
|
||||
type Props = {
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
application: WebApplication
|
||||
onClickOutside: () => void
|
||||
mainApplicationGroup: ApplicationGroup
|
||||
}
|
||||
|
||||
const AccountMenu: FunctionComponent<Props> = ({ application, appState, onClickOutside, mainApplicationGroup }) => {
|
||||
const { currentPane, shouldAnimateCloseMenu } = appState.accountMenu
|
||||
const AccountMenu: FunctionComponent<Props> = ({
|
||||
application,
|
||||
viewControllerManager,
|
||||
onClickOutside,
|
||||
mainApplicationGroup,
|
||||
}) => {
|
||||
const { currentPane, shouldAnimateCloseMenu } = viewControllerManager.accountMenuController
|
||||
|
||||
const closeAccountMenu = useCallback(() => {
|
||||
appState.accountMenu.closeAccountMenu()
|
||||
}, [appState])
|
||||
viewControllerManager.accountMenuController.closeAccountMenu()
|
||||
}, [viewControllerManager])
|
||||
|
||||
const setCurrentPane = useCallback(
|
||||
(pane: AccountMenuPane) => {
|
||||
appState.accountMenu.setCurrentPane(pane)
|
||||
viewControllerManager.accountMenuController.setCurrentPane(pane)
|
||||
},
|
||||
[appState],
|
||||
[viewControllerManager],
|
||||
)
|
||||
|
||||
const ref = useRef<HTMLDivElement>(null)
|
||||
@@ -59,7 +64,7 @@ const AccountMenu: FunctionComponent<Props> = ({ application, appState, onClickO
|
||||
onKeyDown={handleKeyDown}
|
||||
>
|
||||
<MenuPaneSelector
|
||||
appState={appState}
|
||||
viewControllerManager={viewControllerManager}
|
||||
application={application}
|
||||
mainApplicationGroup={mainApplicationGroup}
|
||||
menuPane={currentPane}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { ChangeEventHandler, FunctionComponent, useCallback, useEffect, useState } from 'react'
|
||||
import Checkbox from '@/Components/Checkbox/Checkbox'
|
||||
@@ -8,21 +8,21 @@ import Icon from '@/Components/Icon/Icon'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
disabled?: boolean
|
||||
onPrivateWorkspaceChange?: (isPrivate: boolean, identifier?: string) => void
|
||||
onStrictSignInChange?: (isStrictSignIn: boolean) => void
|
||||
}
|
||||
|
||||
const AdvancedOptions: FunctionComponent<Props> = ({
|
||||
appState,
|
||||
viewControllerManager,
|
||||
application,
|
||||
disabled = false,
|
||||
onPrivateWorkspaceChange,
|
||||
onStrictSignInChange,
|
||||
children,
|
||||
}) => {
|
||||
const { server, setServer, enableServerOption, setEnableServerOption } = appState.accountMenu
|
||||
const { server, setServer, enableServerOption, setEnableServerOption } = viewControllerManager.accountMenuController
|
||||
const [showAdvanced, setShowAdvanced] = useState(false)
|
||||
|
||||
const [isPrivateWorkspace, setIsPrivateWorkspace] = useState(false)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { STRING_NON_MATCHING_PASSWORDS } from '@/Strings'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { FunctionComponent, KeyboardEventHandler, useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { AccountMenuPane } from './AccountMenuPane'
|
||||
@@ -11,15 +11,21 @@ import Icon from '@/Components/Icon/Icon'
|
||||
import IconButton from '@/Components/Button/IconButton'
|
||||
|
||||
type Props = {
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
application: WebApplication
|
||||
setMenuPane: (pane: AccountMenuPane) => void
|
||||
email: string
|
||||
password: string
|
||||
}
|
||||
|
||||
const ConfirmPassword: FunctionComponent<Props> = ({ application, appState, setMenuPane, email, password }) => {
|
||||
const { notesAndTagsCount } = appState.accountMenu
|
||||
const ConfirmPassword: FunctionComponent<Props> = ({
|
||||
application,
|
||||
viewControllerManager,
|
||||
setMenuPane,
|
||||
email,
|
||||
password,
|
||||
}) => {
|
||||
const { notesAndTagsCount } = viewControllerManager.accountMenuController
|
||||
const [confirmPassword, setConfirmPassword] = useState('')
|
||||
const [isRegistering, setIsRegistering] = useState(false)
|
||||
const [isEphemeral, setIsEphemeral] = useState(false)
|
||||
@@ -61,8 +67,8 @@ const ConfirmPassword: FunctionComponent<Props> = ({ application, appState, setM
|
||||
if (res.error) {
|
||||
throw new Error(res.error.message)
|
||||
}
|
||||
appState.accountMenu.closeAccountMenu()
|
||||
appState.accountMenu.setCurrentPane(AccountMenuPane.GeneralMenu)
|
||||
viewControllerManager.accountMenuController.closeAccountMenu()
|
||||
viewControllerManager.accountMenuController.setCurrentPane(AccountMenuPane.GeneralMenu)
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err)
|
||||
@@ -77,7 +83,7 @@ const ConfirmPassword: FunctionComponent<Props> = ({ application, appState, setM
|
||||
passwordInputRef.current?.focus()
|
||||
}
|
||||
},
|
||||
[appState, application, confirmPassword, email, isEphemeral, password, shouldMergeLocal],
|
||||
[viewControllerManager, application, confirmPassword, email, isEphemeral, password, shouldMergeLocal],
|
||||
)
|
||||
|
||||
const handleKeyDown: KeyboardEventHandler = useCallback(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { FunctionComponent, KeyboardEventHandler, useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { AccountMenuPane } from './AccountMenuPane'
|
||||
@@ -11,7 +11,7 @@ import IconButton from '@/Components/Button/IconButton'
|
||||
import AdvancedOptions from './AdvancedOptions'
|
||||
|
||||
type Props = {
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
application: WebApplication
|
||||
setMenuPane: (pane: AccountMenuPane) => void
|
||||
email: string
|
||||
@@ -21,7 +21,7 @@ type Props = {
|
||||
}
|
||||
|
||||
const CreateAccount: FunctionComponent<Props> = ({
|
||||
appState,
|
||||
viewControllerManager,
|
||||
application,
|
||||
setMenuPane,
|
||||
email,
|
||||
@@ -137,7 +137,7 @@ const CreateAccount: FunctionComponent<Props> = ({
|
||||
<div className="h-1px my-2 bg-border"></div>
|
||||
<AdvancedOptions
|
||||
application={application}
|
||||
appState={appState}
|
||||
viewControllerManager={viewControllerManager}
|
||||
onPrivateWorkspaceChange={onPrivateWorkspaceChange}
|
||||
/>
|
||||
</>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import Icon from '@/Components/Icon/Icon'
|
||||
import { SyncQueueStrategy } from '@standardnotes/snjs'
|
||||
@@ -11,11 +11,11 @@ import MenuItem from '@/Components/Menu/MenuItem'
|
||||
import MenuItemSeparator from '@/Components/Menu/MenuItemSeparator'
|
||||
import { MenuItemType } from '@/Components/Menu/MenuItemType'
|
||||
import WorkspaceSwitcherOption from './WorkspaceSwitcher/WorkspaceSwitcherOption'
|
||||
import { ApplicationGroup } from '@/UIModels/ApplicationGroup'
|
||||
import { ApplicationGroup } from '@/Application/ApplicationGroup'
|
||||
import { formatLastSyncDate } from '@/Utils/FormatLastSyncDate'
|
||||
|
||||
type Props = {
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
application: WebApplication
|
||||
mainApplicationGroup: ApplicationGroup
|
||||
setMenuPane: (pane: AccountMenuPane) => void
|
||||
@@ -26,7 +26,7 @@ const iconClassName = 'color-neutral mr-2'
|
||||
|
||||
const GeneralAccountMenu: FunctionComponent<Props> = ({
|
||||
application,
|
||||
appState,
|
||||
viewControllerManager,
|
||||
setMenuPane,
|
||||
closeMenu,
|
||||
mainApplicationGroup,
|
||||
@@ -60,20 +60,20 @@ const GeneralAccountMenu: FunctionComponent<Props> = ({
|
||||
const user = useMemo(() => application.getUser(), [application])
|
||||
|
||||
const openPreferences = useCallback(() => {
|
||||
appState.accountMenu.closeAccountMenu()
|
||||
appState.preferences.setCurrentPane('account')
|
||||
appState.preferences.openPreferences()
|
||||
}, [appState])
|
||||
viewControllerManager.accountMenuController.closeAccountMenu()
|
||||
viewControllerManager.preferencesController.setCurrentPane('account')
|
||||
viewControllerManager.preferencesController.openPreferences()
|
||||
}, [viewControllerManager])
|
||||
|
||||
const openHelp = useCallback(() => {
|
||||
appState.accountMenu.closeAccountMenu()
|
||||
appState.preferences.setCurrentPane('help-feedback')
|
||||
appState.preferences.openPreferences()
|
||||
}, [appState])
|
||||
viewControllerManager.accountMenuController.closeAccountMenu()
|
||||
viewControllerManager.preferencesController.setCurrentPane('help-feedback')
|
||||
viewControllerManager.preferencesController.openPreferences()
|
||||
}, [viewControllerManager])
|
||||
|
||||
const signOut = useCallback(() => {
|
||||
appState.accountMenu.setSigningOut(true)
|
||||
}, [appState])
|
||||
viewControllerManager.accountMenuController.setSigningOut(true)
|
||||
}, [viewControllerManager])
|
||||
|
||||
const activateRegisterPane = useCallback(() => {
|
||||
setMenuPane(AccountMenuPane.Register)
|
||||
@@ -136,13 +136,16 @@ const GeneralAccountMenu: FunctionComponent<Props> = ({
|
||||
</>
|
||||
)}
|
||||
<Menu
|
||||
isOpen={appState.accountMenu.show}
|
||||
isOpen={viewControllerManager.accountMenuController.show}
|
||||
a11yLabel="General account menu"
|
||||
closeMenu={closeMenu}
|
||||
initialFocus={!application.hasAccount() ? CREATE_ACCOUNT_INDEX : SWITCHER_INDEX}
|
||||
>
|
||||
<MenuItemSeparator />
|
||||
<WorkspaceSwitcherOption mainApplicationGroup={mainApplicationGroup} appState={appState} />
|
||||
<WorkspaceSwitcherOption
|
||||
mainApplicationGroup={mainApplicationGroup}
|
||||
viewControllerManager={viewControllerManager}
|
||||
/>
|
||||
<MenuItemSeparator />
|
||||
{user ? (
|
||||
<MenuItem type={MenuItemType.IconButton} onClick={openPreferences}>
|
||||
@@ -166,7 +169,7 @@ const GeneralAccountMenu: FunctionComponent<Props> = ({
|
||||
<Icon type="help" className={iconClassName} />
|
||||
Help & feedback
|
||||
</div>
|
||||
<span className="color-neutral">v{appState.version}</span>
|
||||
<span className="color-neutral">v{viewControllerManager.version}</span>
|
||||
</MenuItem>
|
||||
{user ? (
|
||||
<>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { ApplicationGroup } from '@/UIModels/ApplicationGroup'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ApplicationGroup } from '@/Application/ApplicationGroup'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { FunctionComponent, useState } from 'react'
|
||||
import { AccountMenuPane } from './AccountMenuPane'
|
||||
@@ -10,7 +10,7 @@ import GeneralAccountMenu from './GeneralAccountMenu'
|
||||
import SignInPane from './SignIn'
|
||||
|
||||
type Props = {
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
application: WebApplication
|
||||
mainApplicationGroup: ApplicationGroup
|
||||
menuPane: AccountMenuPane
|
||||
@@ -20,7 +20,7 @@ type Props = {
|
||||
|
||||
const MenuPaneSelector: FunctionComponent<Props> = ({
|
||||
application,
|
||||
appState,
|
||||
viewControllerManager,
|
||||
menuPane,
|
||||
setMenuPane,
|
||||
closeMenu,
|
||||
@@ -33,7 +33,7 @@ const MenuPaneSelector: FunctionComponent<Props> = ({
|
||||
case AccountMenuPane.GeneralMenu:
|
||||
return (
|
||||
<GeneralAccountMenu
|
||||
appState={appState}
|
||||
viewControllerManager={viewControllerManager}
|
||||
application={application}
|
||||
mainApplicationGroup={mainApplicationGroup}
|
||||
setMenuPane={setMenuPane}
|
||||
@@ -41,11 +41,13 @@ const MenuPaneSelector: FunctionComponent<Props> = ({
|
||||
/>
|
||||
)
|
||||
case AccountMenuPane.SignIn:
|
||||
return <SignInPane appState={appState} application={application} setMenuPane={setMenuPane} />
|
||||
return (
|
||||
<SignInPane viewControllerManager={viewControllerManager} application={application} setMenuPane={setMenuPane} />
|
||||
)
|
||||
case AccountMenuPane.Register:
|
||||
return (
|
||||
<CreateAccount
|
||||
appState={appState}
|
||||
viewControllerManager={viewControllerManager}
|
||||
application={application}
|
||||
setMenuPane={setMenuPane}
|
||||
email={email}
|
||||
@@ -57,7 +59,7 @@ const MenuPaneSelector: FunctionComponent<Props> = ({
|
||||
case AccountMenuPane.ConfirmPassword:
|
||||
return (
|
||||
<ConfirmPassword
|
||||
appState={appState}
|
||||
viewControllerManager={viewControllerManager}
|
||||
application={application}
|
||||
setMenuPane={setMenuPane}
|
||||
email={email}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { isDev } from '@/Utils'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import React, { FunctionComponent, KeyboardEventHandler, useCallback, useEffect, useRef, useState } from 'react'
|
||||
@@ -13,13 +13,13 @@ import IconButton from '@/Components/Button/IconButton'
|
||||
import AdvancedOptions from './AdvancedOptions'
|
||||
|
||||
type Props = {
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
application: WebApplication
|
||||
setMenuPane: (pane: AccountMenuPane) => void
|
||||
}
|
||||
|
||||
const SignInPane: FunctionComponent<Props> = ({ application, appState, setMenuPane }) => {
|
||||
const { notesAndTagsCount } = appState.accountMenu
|
||||
const SignInPane: FunctionComponent<Props> = ({ application, viewControllerManager, setMenuPane }) => {
|
||||
const { notesAndTagsCount } = viewControllerManager.accountMenuController
|
||||
const [email, setEmail] = useState('')
|
||||
const [password, setPassword] = useState('')
|
||||
const [error, setError] = useState('')
|
||||
@@ -86,7 +86,7 @@ const SignInPane: FunctionComponent<Props> = ({ application, appState, setMenuPa
|
||||
if (res.error) {
|
||||
throw new Error(res.error.message)
|
||||
}
|
||||
appState.accountMenu.closeAccountMenu()
|
||||
viewControllerManager.accountMenuController.closeAccountMenu()
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err)
|
||||
@@ -97,7 +97,7 @@ const SignInPane: FunctionComponent<Props> = ({ application, appState, setMenuPa
|
||||
.finally(() => {
|
||||
setIsSigningIn(false)
|
||||
})
|
||||
}, [appState, application, email, isEphemeral, isStrictSignin, password, shouldMergeLocal])
|
||||
}, [viewControllerManager, application, email, isEphemeral, isStrictSignin, password, shouldMergeLocal])
|
||||
|
||||
const onPrivateWorkspaceChange = useCallback(
|
||||
(newIsPrivateWorkspace: boolean, privateWorkspaceIdentifier?: string) => {
|
||||
@@ -201,7 +201,7 @@ const SignInPane: FunctionComponent<Props> = ({ application, appState, setMenuPa
|
||||
</div>
|
||||
<div className="h-1px my-2 bg-border"></div>
|
||||
<AdvancedOptions
|
||||
appState={appState}
|
||||
viewControllerManager={viewControllerManager}
|
||||
application={application}
|
||||
disabled={isSigningIn}
|
||||
onPrivateWorkspaceChange={onPrivateWorkspaceChange}
|
||||
|
||||
@@ -1,24 +1,25 @@
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { User as UserType } from '@standardnotes/snjs'
|
||||
|
||||
type Props = {
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
application: WebApplication
|
||||
}
|
||||
|
||||
const User = ({ appState, application }: Props) => {
|
||||
const { server } = appState.accountMenu
|
||||
const User = ({ viewControllerManager, application }: Props) => {
|
||||
const { server } = viewControllerManager.accountMenuController
|
||||
const user = application.getUser() as UserType
|
||||
|
||||
return (
|
||||
<div className="sk-panel-section">
|
||||
{appState.sync.errorMessage && (
|
||||
{viewControllerManager.syncStatusController.errorMessage && (
|
||||
<div className="sk-notification danger">
|
||||
<div className="sk-notification-title">Sync Unreachable</div>
|
||||
<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>
|
||||
<a
|
||||
className="sk-a info-contrast sk-bold sk-panel-row"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ApplicationGroup } from '@/UIModels/ApplicationGroup'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { ApplicationGroup } from '@/Application/ApplicationGroup'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { ApplicationDescriptor, ApplicationGroupEvent, ButtonType } from '@standardnotes/snjs'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { FunctionComponent, useCallback, useEffect, useState } from 'react'
|
||||
@@ -12,14 +12,14 @@ import WorkspaceMenuItem from './WorkspaceMenuItem'
|
||||
|
||||
type Props = {
|
||||
mainApplicationGroup: ApplicationGroup
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
isOpen: boolean
|
||||
hideWorkspaceOptions?: boolean
|
||||
}
|
||||
|
||||
const WorkspaceSwitcherMenu: FunctionComponent<Props> = ({
|
||||
mainApplicationGroup,
|
||||
appState,
|
||||
viewControllerManager,
|
||||
isOpen,
|
||||
hideWorkspaceOptions = false,
|
||||
}: Props) => {
|
||||
@@ -42,7 +42,7 @@ const WorkspaceSwitcherMenu: FunctionComponent<Props> = ({
|
||||
}, [mainApplicationGroup])
|
||||
|
||||
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?',
|
||||
undefined,
|
||||
'Sign out all',
|
||||
@@ -52,11 +52,11 @@ const WorkspaceSwitcherMenu: FunctionComponent<Props> = ({
|
||||
return
|
||||
}
|
||||
mainApplicationGroup.signOutAllWorkspaces().catch(console.error)
|
||||
}, [mainApplicationGroup, appState])
|
||||
}, [mainApplicationGroup, viewControllerManager])
|
||||
|
||||
const destroyWorkspace = useCallback(() => {
|
||||
appState.accountMenu.setSigningOut(true)
|
||||
}, [appState])
|
||||
viewControllerManager.accountMenuController.setSigningOut(true)
|
||||
}, [viewControllerManager])
|
||||
|
||||
return (
|
||||
<Menu a11yLabel="Workspace switcher menu" className="px-0 focus:shadow-none" isOpen={isOpen}>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { FOCUSABLE_BUT_NOT_TABBABLE } from '@/Constants'
|
||||
import { ApplicationGroup } from '@/UIModels/ApplicationGroup'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { ApplicationGroup } from '@/Application/ApplicationGroup'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { calculateSubmenuStyle, SubmenuStyle } from '@/Utils/CalculateSubmenuStyle'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { FunctionComponent, useCallback, useEffect, useRef, useState } from 'react'
|
||||
@@ -9,10 +9,10 @@ import WorkspaceSwitcherMenu from './WorkspaceSwitcherMenu'
|
||||
|
||||
type Props = {
|
||||
mainApplicationGroup: ApplicationGroup
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
}
|
||||
|
||||
const WorkspaceSwitcherOption: FunctionComponent<Props> = ({ mainApplicationGroup, appState }) => {
|
||||
const WorkspaceSwitcherOption: FunctionComponent<Props> = ({ mainApplicationGroup, viewControllerManager }) => {
|
||||
const buttonRef = useRef<HTMLButtonElement>(null)
|
||||
const menuRef = useRef<HTMLDivElement>(null)
|
||||
const [isOpen, setIsOpen] = useState(false)
|
||||
@@ -58,7 +58,11 @@ const WorkspaceSwitcherOption: FunctionComponent<Props> = ({ mainApplicationGrou
|
||||
</button>
|
||||
{isOpen && (
|
||||
<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>
|
||||
)}
|
||||
</>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ApplicationGroup } from '@/UIModels/ApplicationGroup'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { ApplicationGroup } from '@/Application/ApplicationGroup'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { Component } from 'react'
|
||||
import ApplicationView from '@/Components/ApplicationView/ApplicationView'
|
||||
import { WebOrDesktopDevice } from '@/Device/WebOrDesktopDevice'
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { ApplicationGroup } from '@/UIModels/ApplicationGroup'
|
||||
import { ApplicationGroup } from '@/Application/ApplicationGroup'
|
||||
import { getPlatformString, getWindowUrlParams } from '@/Utils'
|
||||
import { AppStateEvent, PanelResizedData } from '@/UIModels/AppState'
|
||||
import { ViewControllerManagerEvent } from '@/Services/ViewControllerManager'
|
||||
import { ApplicationEvent, Challenge, removeFromArray } from '@standardnotes/snjs'
|
||||
import { PANEL_NAME_NOTES, PANEL_NAME_NAVIGATION } from '@/Constants'
|
||||
import { alertDialog } from '@/Services/AlertService'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import Navigation from '@/Components/Navigation/Navigation'
|
||||
import NoteGroupView from '@/Components/NoteGroupView/NoteGroupView'
|
||||
import Footer from '@/Components/Footer/Footer'
|
||||
@@ -23,6 +23,7 @@ import FilePreviewModalWrapper from '@/Components/Files/FilePreviewModal'
|
||||
import ContentListView from '@/Components/ContentListView/ContentListView'
|
||||
import FileContextMenuWrapper from '@/Components/FileContextMenu/FileContextMenu'
|
||||
import PermissionsModalWrapper from '@/Components/PermissionsModal/PermissionsModalWrapper'
|
||||
import { PanelResizedData } from '@/Typings/PanelResizedData'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
@@ -36,7 +37,7 @@ const ApplicationView: FunctionComponent<Props> = ({ application, mainApplicatio
|
||||
const [needsUnlock, setNeedsUnlock] = useState(true)
|
||||
const [challenges, setChallenges] = useState<Challenge[]>([])
|
||||
|
||||
const appState = application.getAppState()
|
||||
const viewControllerManager = application.getViewControllerManager()
|
||||
|
||||
useEffect(() => {
|
||||
const desktopService = application.getDesktopService()
|
||||
@@ -119,8 +120,8 @@ const ApplicationView: FunctionComponent<Props> = ({ application, mainApplicatio
|
||||
}, [application, onAppLaunch, onAppStart])
|
||||
|
||||
useEffect(() => {
|
||||
const removeObserver = application.getAppState().addObserver(async (eventName, data) => {
|
||||
if (eventName === AppStateEvent.PanelResized) {
|
||||
const removeObserver = application.getViewControllerManager().addObserver(async (eventName, data) => {
|
||||
if (eventName === ViewControllerManagerEvent.PanelResized) {
|
||||
const { panel, collapsed } = data as PanelResizedData
|
||||
let appClass = ''
|
||||
if (panel === PANEL_NAME_NOTES && collapsed) {
|
||||
@@ -130,7 +131,7 @@ const ApplicationView: FunctionComponent<Props> = ({ application, mainApplicatio
|
||||
appClass += ' collapsed-navigation'
|
||||
}
|
||||
setAppClass(appClass)
|
||||
} else if (eventName === AppStateEvent.WindowDidFocus) {
|
||||
} else if (eventName === ViewControllerManagerEvent.WindowDidFocus) {
|
||||
if (!(await application.isLocked())) {
|
||||
application.sync.sync().catch(console.error)
|
||||
}
|
||||
@@ -155,7 +156,7 @@ const ApplicationView: FunctionComponent<Props> = ({ application, mainApplicatio
|
||||
<ChallengeModal
|
||||
key={`${challenge.id}${application.ephemeralIdentifier}`}
|
||||
application={application}
|
||||
appState={appState}
|
||||
viewControllerManager={viewControllerManager}
|
||||
mainApplicationGroup={mainApplicationGroup}
|
||||
challenge={challenge}
|
||||
onDismiss={removeChallenge}
|
||||
@@ -165,42 +166,42 @@ const ApplicationView: FunctionComponent<Props> = ({ application, mainApplicatio
|
||||
})}
|
||||
</>
|
||||
)
|
||||
}, [appState, challenges, mainApplicationGroup, removeChallenge, application])
|
||||
}, [viewControllerManager, challenges, mainApplicationGroup, removeChallenge, application])
|
||||
|
||||
if (!renderAppContents) {
|
||||
return renderChallenges()
|
||||
}
|
||||
|
||||
return (
|
||||
<PremiumModalProvider application={application} appState={appState}>
|
||||
<PremiumModalProvider application={application} viewControllerManager={viewControllerManager}>
|
||||
<div className={platformString + ' main-ui-view sn-component'}>
|
||||
<div id="app" className={appClass + ' app app-column-container'}>
|
||||
<Navigation application={application} />
|
||||
<ContentListView application={application} appState={appState} />
|
||||
<ContentListView application={application} viewControllerManager={viewControllerManager} />
|
||||
<NoteGroupView application={application} />
|
||||
</div>
|
||||
|
||||
<>
|
||||
<Footer application={application} applicationGroup={mainApplicationGroup} />
|
||||
<SessionsModal application={application} appState={appState} />
|
||||
<PreferencesViewWrapper appState={appState} application={application} />
|
||||
<RevisionHistoryModalWrapper application={application} appState={appState} />
|
||||
<SessionsModal application={application} viewControllerManager={viewControllerManager} />
|
||||
<PreferencesViewWrapper viewControllerManager={viewControllerManager} application={application} />
|
||||
<RevisionHistoryModalWrapper application={application} viewControllerManager={viewControllerManager} />
|
||||
</>
|
||||
|
||||
{renderChallenges()}
|
||||
|
||||
<>
|
||||
<NotesContextMenu application={application} appState={appState} />
|
||||
<TagsContextMenuWrapper appState={appState} />
|
||||
<FileContextMenuWrapper appState={appState} />
|
||||
<PurchaseFlowWrapper application={application} appState={appState} />
|
||||
<NotesContextMenu application={application} viewControllerManager={viewControllerManager} />
|
||||
<TagsContextMenuWrapper viewControllerManager={viewControllerManager} />
|
||||
<FileContextMenuWrapper viewControllerManager={viewControllerManager} />
|
||||
<PurchaseFlowWrapper application={application} viewControllerManager={viewControllerManager} />
|
||||
<ConfirmSignoutContainer
|
||||
applicationGroup={mainApplicationGroup}
|
||||
appState={appState}
|
||||
viewControllerManager={viewControllerManager}
|
||||
application={application}
|
||||
/>
|
||||
<ToastContainer />
|
||||
<FilePreviewModalWrapper application={application} appState={appState} />
|
||||
<FilePreviewModalWrapper application={application} viewControllerManager={viewControllerManager} />
|
||||
<PermissionsModalWrapper application={application} />
|
||||
</>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { MENU_MARGIN_FROM_APP_BORDER } from '@/Constants'
|
||||
import { Disclosure, DisclosureButton, DisclosurePanel } from '@reach/disclosure'
|
||||
import VisuallyHidden from '@reach/visually-hidden'
|
||||
@@ -19,13 +19,17 @@ import { isHandlingFileDrag } from '@/Utils/DragTypeCheck'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
onClickPreprocessing?: () => Promise<void>
|
||||
}
|
||||
|
||||
const AttachedFilesButton: FunctionComponent<Props> = ({ application, appState, onClickPreprocessing }: Props) => {
|
||||
const AttachedFilesButton: FunctionComponent<Props> = ({
|
||||
application,
|
||||
viewControllerManager,
|
||||
onClickPreprocessing,
|
||||
}: Props) => {
|
||||
const premiumModal = usePremiumModal()
|
||||
const note: SNNote | undefined = appState.notes.firstSelectedNote
|
||||
const note: SNNote | undefined = viewControllerManager.notesController.firstSelectedNote
|
||||
|
||||
const [open, setOpen] = useState(false)
|
||||
const [position, setPosition] = useState({
|
||||
@@ -39,12 +43,12 @@ const AttachedFilesButton: FunctionComponent<Props> = ({ application, appState,
|
||||
const [closeOnBlur, keepMenuOpen] = useCloseOnBlur(containerRef, setOpen)
|
||||
|
||||
useEffect(() => {
|
||||
if (appState.filePreviewModal.isOpen) {
|
||||
if (viewControllerManager.filePreviewModalController.isOpen) {
|
||||
keepMenuOpen(true)
|
||||
} else {
|
||||
keepMenuOpen(false)
|
||||
}
|
||||
}, [appState.filePreviewModal.isOpen, keepMenuOpen])
|
||||
}, [viewControllerManager.filePreviewModalController.isOpen, keepMenuOpen])
|
||||
|
||||
const [currentTab, setCurrentTab] = useState(PopoverTabs.AttachedFiles)
|
||||
const [allFiles, setAllFiles] = useState<FileItem[]>([])
|
||||
@@ -90,10 +94,10 @@ const AttachedFilesButton: FunctionComponent<Props> = ({ application, appState,
|
||||
}, [onClickPreprocessing, open])
|
||||
|
||||
const prospectivelyShowFilesPremiumModal = useCallback(() => {
|
||||
if (!appState.features.hasFiles) {
|
||||
if (!viewControllerManager.featuresController.hasFiles) {
|
||||
premiumModal.activate('Files')
|
||||
}
|
||||
}, [appState.features.hasFiles, premiumModal])
|
||||
}, [viewControllerManager.featuresController.hasFiles, premiumModal])
|
||||
|
||||
const toggleAttachedFilesMenuWithEntitlementCheck = useCallback(async () => {
|
||||
prospectivelyShowFilesPremiumModal()
|
||||
@@ -121,7 +125,7 @@ const AttachedFilesButton: FunctionComponent<Props> = ({ application, appState,
|
||||
}
|
||||
|
||||
const downloadFile = async (file: FileItem) => {
|
||||
appState.files.downloadFile(file).catch(console.error)
|
||||
viewControllerManager.filesController.downloadFile(file).catch(console.error)
|
||||
}
|
||||
|
||||
const attachFileToNote = useCallback(
|
||||
@@ -213,7 +217,7 @@ const AttachedFilesButton: FunctionComponent<Props> = ({ application, appState,
|
||||
case PopoverFileItemActionType.PreviewFile: {
|
||||
keepMenuOpen(true)
|
||||
const otherFiles = currentTab === PopoverTabs.AllFiles ? allFiles : attachedFiles
|
||||
appState.filePreviewModal.activate(
|
||||
viewControllerManager.filePreviewModalController.activate(
|
||||
file,
|
||||
otherFiles.filter((file) => !file.protected),
|
||||
)
|
||||
@@ -305,7 +309,7 @@ const AttachedFilesButton: FunctionComponent<Props> = ({ application, appState,
|
||||
|
||||
setIsDraggingFiles(false)
|
||||
|
||||
if (!appState.features.hasFiles) {
|
||||
if (!viewControllerManager.featuresController.hasFiles) {
|
||||
prospectivelyShowFilesPremiumModal()
|
||||
return
|
||||
}
|
||||
@@ -320,7 +324,7 @@ const AttachedFilesButton: FunctionComponent<Props> = ({ application, appState,
|
||||
return
|
||||
}
|
||||
|
||||
const uploadedFiles = await appState.files.uploadNewFile(fileOrHandle)
|
||||
const uploadedFiles = await viewControllerManager.filesController.uploadNewFile(fileOrHandle)
|
||||
|
||||
if (!uploadedFiles) {
|
||||
return
|
||||
@@ -338,8 +342,8 @@ const AttachedFilesButton: FunctionComponent<Props> = ({ application, appState,
|
||||
}
|
||||
},
|
||||
[
|
||||
appState.files,
|
||||
appState.features.hasFiles,
|
||||
viewControllerManager.filesController,
|
||||
viewControllerManager.featuresController.hasFiles,
|
||||
attachFileToNote,
|
||||
currentTab,
|
||||
application,
|
||||
@@ -396,7 +400,7 @@ const AttachedFilesButton: FunctionComponent<Props> = ({ application, appState,
|
||||
{open && (
|
||||
<AttachedFilesPopover
|
||||
application={application}
|
||||
appState={appState}
|
||||
viewControllerManager={viewControllerManager}
|
||||
attachedFiles={attachedFiles}
|
||||
allFiles={allFiles}
|
||||
closeOnBlur={closeOnBlur}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { FOCUSABLE_BUT_NOT_TABBABLE } from '@/Constants'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { FileItem } from '@standardnotes/snjs'
|
||||
import { FilesIllustration } from '@standardnotes/icons'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
@@ -13,7 +13,7 @@ import { PopoverTabs } from './PopoverTabs'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
allFiles: FileItem[]
|
||||
attachedFiles: FileItem[]
|
||||
closeOnBlur: (event: { relatedTarget: EventTarget | null }) => void
|
||||
@@ -25,7 +25,7 @@ type Props = {
|
||||
|
||||
const AttachedFilesPopover: FunctionComponent<Props> = ({
|
||||
application,
|
||||
appState,
|
||||
viewControllerManager,
|
||||
allFiles,
|
||||
attachedFiles,
|
||||
closeOnBlur,
|
||||
@@ -45,7 +45,7 @@ const AttachedFilesPopover: FunctionComponent<Props> = ({
|
||||
: filesList
|
||||
|
||||
const handleAttachFilesClick = async () => {
|
||||
const uploadedFiles = await appState.files.uploadNewFile()
|
||||
const uploadedFiles = await viewControllerManager.filesController.uploadNewFile()
|
||||
if (!uploadedFiles) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { DialogContent, DialogOverlay } from '@reach/dialog'
|
||||
import {
|
||||
ButtonType,
|
||||
@@ -14,13 +14,13 @@ import Button from '@/Components/Button/Button'
|
||||
import Icon from '@/Components/Icon/Icon'
|
||||
import ChallengeModalPrompt from './ChallengePrompt'
|
||||
import LockscreenWorkspaceSwitcher from './LockscreenWorkspaceSwitcher'
|
||||
import { ApplicationGroup } from '@/UIModels/ApplicationGroup'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { ApplicationGroup } from '@/Application/ApplicationGroup'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { ChallengeModalValues } from './ChallengeModalValues'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
mainApplicationGroup: ApplicationGroup
|
||||
challenge: Challenge
|
||||
onDismiss?: (challenge: Challenge) => void
|
||||
@@ -44,7 +44,7 @@ const validateValues = (values: ChallengeModalValues, prompts: ChallengePrompt[]
|
||||
|
||||
const ChallengeModal: FunctionComponent<Props> = ({
|
||||
application,
|
||||
appState,
|
||||
viewControllerManager,
|
||||
mainApplicationGroup,
|
||||
challenge,
|
||||
onDismiss,
|
||||
@@ -255,7 +255,10 @@ const ChallengeModal: FunctionComponent<Props> = ({
|
||||
</Button>
|
||||
)}
|
||||
{shouldShowWorkspaceSwitcher && (
|
||||
<LockscreenWorkspaceSwitcher mainApplicationGroup={mainApplicationGroup} appState={appState} />
|
||||
<LockscreenWorkspaceSwitcher
|
||||
mainApplicationGroup={mainApplicationGroup}
|
||||
viewControllerManager={viewControllerManager}
|
||||
/>
|
||||
)}
|
||||
</DialogContent>
|
||||
</DialogOverlay>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ApplicationGroup } from '@/UIModels/ApplicationGroup'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { ApplicationGroup } from '@/Application/ApplicationGroup'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { calculateSubmenuStyle, SubmenuStyle } from '@/Utils/CalculateSubmenuStyle'
|
||||
import { FunctionComponent, useCallback, useEffect, useRef, useState } from 'react'
|
||||
import WorkspaceSwitcherMenu from '@/Components/AccountMenu/WorkspaceSwitcher/WorkspaceSwitcherMenu'
|
||||
@@ -9,10 +9,10 @@ import { useCloseOnClickOutside } from '@/Hooks/useCloseOnClickOutside'
|
||||
|
||||
type Props = {
|
||||
mainApplicationGroup: ApplicationGroup
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
}
|
||||
|
||||
const LockscreenWorkspaceSwitcher: FunctionComponent<Props> = ({ mainApplicationGroup, appState }) => {
|
||||
const LockscreenWorkspaceSwitcher: FunctionComponent<Props> = ({ mainApplicationGroup, viewControllerManager }) => {
|
||||
const buttonRef = useRef<HTMLButtonElement>(null)
|
||||
const menuRef = 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}>
|
||||
<WorkspaceSwitcherMenu
|
||||
mainApplicationGroup={mainApplicationGroup}
|
||||
appState={appState}
|
||||
viewControllerManager={viewControllerManager}
|
||||
isOpen={isOpen}
|
||||
hideWorkspaceOptions={true}
|
||||
/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { MENU_MARGIN_FROM_APP_BORDER } from '@/Constants'
|
||||
import { Disclosure, DisclosureButton, DisclosurePanel } from '@reach/disclosure'
|
||||
import VisuallyHidden from '@reach/visually-hidden'
|
||||
@@ -11,12 +11,16 @@ import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
onClickPreprocessing?: () => Promise<void>
|
||||
}
|
||||
|
||||
const ChangeEditorButton: FunctionComponent<Props> = ({ application, appState, onClickPreprocessing }: Props) => {
|
||||
const note = appState.notes.firstSelectedNote
|
||||
const ChangeEditorButton: FunctionComponent<Props> = ({
|
||||
application,
|
||||
viewControllerManager,
|
||||
onClickPreprocessing,
|
||||
}: Props) => {
|
||||
const note = viewControllerManager.notesController.firstSelectedNote
|
||||
const [isOpen, setIsOpen] = useState(false)
|
||||
const [isVisible, setIsVisible] = useState(false)
|
||||
const [position, setPosition] = useState({
|
||||
|
||||
@@ -4,7 +4,7 @@ import MenuItem from '@/Components/Menu/MenuItem'
|
||||
import { MenuItemType } from '@/Components/Menu/MenuItemType'
|
||||
import { usePremiumModal } from '@/Hooks/usePremiumModal'
|
||||
import { STRING_EDIT_LOCKED_ATTEMPT } from '@/Strings'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import {
|
||||
ComponentArea,
|
||||
ItemMutator,
|
||||
@@ -90,7 +90,7 @@ const ChangeEditorMenu: FunctionComponent<ChangeEditorMenuProps> = ({
|
||||
|
||||
const transactions: TransactionalMutation[] = []
|
||||
|
||||
await application.getAppState().contentListView.insertCurrentIfTemplate()
|
||||
await application.getViewControllerManager().contentListController.insertCurrentIfTemplate()
|
||||
|
||||
if (note.locked) {
|
||||
application.alertService.alert(STRING_EDIT_LOCKED_ATTEMPT).catch(console.error)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import {
|
||||
ContentType,
|
||||
FeatureStatus,
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
ComponentViewerEvent,
|
||||
ComponentViewerError,
|
||||
} from '@standardnotes/snjs'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { FunctionComponent, useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import OfflineRestricted from '@/Components/ComponentView/OfflineRestricted'
|
||||
@@ -15,12 +15,12 @@ import UrlMissing from '@/Components/ComponentView/UrlMissing'
|
||||
import IsDeprecated from '@/Components/ComponentView/IsDeprecated'
|
||||
import IsExpired from '@/Components/ComponentView/IsExpired'
|
||||
import IssueOnLoading from '@/Components/ComponentView/IssueOnLoading'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { openSubscriptionDashboard } from '@/Utils/ManageSubscription'
|
||||
|
||||
interface IProps {
|
||||
application: WebApplication
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
componentViewer: ComponentViewer
|
||||
requestReload?: (viewer: ComponentViewer, force?: boolean) => void
|
||||
onLoad?: (component: SNComponent) => void
|
||||
@@ -151,7 +151,7 @@ const ComponentView: FunctionComponent<IProps> = ({ application, onLoad, compone
|
||||
application.io.handleComponentKeyUp(data.keyboardModifier)
|
||||
break
|
||||
case ComponentAction.Click:
|
||||
application.getAppState().notes.setContextMenuOpen(false)
|
||||
application.getViewControllerManager().notesController.setContextMenuOpen(false)
|
||||
break
|
||||
default:
|
||||
return
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
import { FunctionComponent, useEffect, useRef, useState } from 'react'
|
||||
import { AlertDialog, AlertDialogDescription, AlertDialogLabel } from '@reach/alert-dialog'
|
||||
import { STRING_SIGN_OUT_CONFIRMATION } from '@/Strings'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { ApplicationGroup } from '@/UIModels/ApplicationGroup'
|
||||
import { ApplicationGroup } from '@/Application/ApplicationGroup'
|
||||
import { isDesktopApplication } from '@/Utils'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
applicationGroup: ApplicationGroup
|
||||
}
|
||||
|
||||
const ConfirmSignoutModal: FunctionComponent<Props> = ({ application, appState, applicationGroup }) => {
|
||||
const ConfirmSignoutModal: FunctionComponent<Props> = ({ application, viewControllerManager, applicationGroup }) => {
|
||||
const [deleteLocalBackups, setDeleteLocalBackups] = useState(false)
|
||||
|
||||
const cancelRef = useRef<HTMLButtonElement>(null)
|
||||
function closeDialog() {
|
||||
appState.accountMenu.setSigningOut(false)
|
||||
viewControllerManager.accountMenuController.setSigningOut(false)
|
||||
}
|
||||
|
||||
const [localBackupsCount, setLocalBackupsCount] = useState(0)
|
||||
|
||||
useEffect(() => {
|
||||
application.desktopDevice?.localBackupsCount().then(setLocalBackupsCount).catch(console.error)
|
||||
}, [appState.accountMenu.signingOut, application.desktopDevice])
|
||||
}, [viewControllerManager.accountMenuController.signingOut, application.desktopDevice])
|
||||
|
||||
const workspaces = applicationGroup.getDescriptors()
|
||||
const showWorkspaceWarning = workspaces.length > 1 && isDesktopApplication()
|
||||
@@ -112,7 +112,7 @@ const ConfirmSignoutModal: FunctionComponent<Props> = ({ application, appState,
|
||||
ConfirmSignoutModal.displayName = 'ConfirmSignoutModal'
|
||||
|
||||
const ConfirmSignoutContainer = (props: Props) => {
|
||||
if (!props.appState.accountMenu.signingOut) {
|
||||
if (!props.viewControllerManager.accountMenuController.signingOut) {
|
||||
return null
|
||||
}
|
||||
return <ConfirmSignoutModal {...props} />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { KeyboardKey } from '@/Services/IOService'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { UuidString } from '@standardnotes/snjs'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { FunctionComponent, KeyboardEventHandler, UIEventHandler, useCallback } from 'react'
|
||||
@@ -10,16 +10,23 @@ import ContentListItem from './ContentListItem'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
items: ListableContentItem[]
|
||||
selectedItems: Record<UuidString, ListableContentItem>
|
||||
paginate: () => void
|
||||
}
|
||||
|
||||
const ContentList: FunctionComponent<Props> = ({ application, appState, items, selectedItems, paginate }) => {
|
||||
const { selectPreviousItem, selectNextItem } = appState.contentListView
|
||||
const { hideTags, hideDate, hideNotePreview, hideEditorIcon } = appState.contentListView.webDisplayOptions
|
||||
const { sortBy } = appState.contentListView.displayOptions
|
||||
const ContentList: FunctionComponent<Props> = ({
|
||||
application,
|
||||
viewControllerManager,
|
||||
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(
|
||||
(e) => {
|
||||
@@ -57,7 +64,7 @@ const ContentList: FunctionComponent<Props> = ({ application, appState, items, s
|
||||
<ContentListItem
|
||||
key={item.uuid}
|
||||
application={application}
|
||||
appState={appState}
|
||||
viewControllerManager={viewControllerManager}
|
||||
item={item}
|
||||
selected={!!selectedItems[item.uuid]}
|
||||
hideDate={hideDate}
|
||||
|
||||
@@ -10,12 +10,12 @@ const ContentListItem: FunctionComponent<AbstractListItemProps> = (props) => {
|
||||
return []
|
||||
}
|
||||
|
||||
const selectedTag = props.appState.tags.selected
|
||||
const selectedTag = props.viewControllerManager.navigationController.selected
|
||||
if (!selectedTag) {
|
||||
return []
|
||||
}
|
||||
|
||||
const tags = props.appState.getItemTags(props.item)
|
||||
const tags = props.viewControllerManager.getItemTags(props.item)
|
||||
|
||||
const isNavigatingOnlyTag = selectedTag instanceof SNTag && tags.length === 1
|
||||
if (isNavigatingOnlyTag) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { CollectionSort, CollectionSortProperty, PrefKey, SystemViewId } from '@standardnotes/snjs'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { FunctionComponent, useCallback, useState } from 'react'
|
||||
@@ -7,11 +7,11 @@ import Menu from '@/Components/Menu/Menu'
|
||||
import MenuItem from '@/Components/Menu/MenuItem'
|
||||
import MenuItemSeparator from '@/Components/Menu/MenuItemSeparator'
|
||||
import { MenuItemType } from '@/Components/Menu/MenuItemType'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
closeOnBlur: (event: { relatedTarget: EventTarget | null }) => void
|
||||
closeDisplayOptionsMenu: () => void
|
||||
isOpen: boolean
|
||||
@@ -21,7 +21,7 @@ const ContentListOptionsMenu: FunctionComponent<Props> = ({
|
||||
closeDisplayOptionsMenu,
|
||||
closeOnBlur,
|
||||
application,
|
||||
appState,
|
||||
viewControllerManager,
|
||||
isOpen,
|
||||
}) => {
|
||||
const [sortBy, setSortBy] = useState(() => application.getPreference(PrefKey.SortNotesBy, CollectionSort.CreatedAt))
|
||||
@@ -174,7 +174,7 @@ const ContentListOptionsMenu: FunctionComponent<Props> = ({
|
||||
</MenuItem>
|
||||
<MenuItemSeparator />
|
||||
<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
|
||||
type={MenuItemType.SwitchButton}
|
||||
className="py-1 hover:bg-contrast focus:bg-info-backdrop"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { KeyboardKey, KeyboardModifier } from '@/Services/IOService'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { PANEL_NAME_NOTES } from '@/Constants'
|
||||
import { PrefKey, SystemViewId } from '@standardnotes/snjs'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
@@ -24,10 +24,10 @@ import ContentListOptionsMenu from './ContentListOptionsMenu'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
}
|
||||
|
||||
const ContentListView: FunctionComponent<Props> = ({ application, appState }) => {
|
||||
const ContentListView: FunctionComponent<Props> = ({ application, viewControllerManager }) => {
|
||||
const itemsViewPanelRef = useRef<HTMLDivElement>(null)
|
||||
const displayOptionsMenuRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
@@ -46,9 +46,9 @@ const ContentListView: FunctionComponent<Props> = ({ application, appState }) =>
|
||||
paginate,
|
||||
panelWidth,
|
||||
createNewNote,
|
||||
} = appState.contentListView
|
||||
} = viewControllerManager.contentListController
|
||||
|
||||
const { selectedItems } = appState.selectedItems
|
||||
const { selectedItems } = viewControllerManager.selectionController
|
||||
|
||||
const [showDisplayOptionsMenu, setShowDisplayOptionsMenu] = useState(false)
|
||||
const [focusedSearch, setFocusedSearch] = useState(false)
|
||||
@@ -56,17 +56,17 @@ const ContentListView: FunctionComponent<Props> = ({ application, appState }) =>
|
||||
const [closeDisplayOptMenuOnBlur] = useCloseOnBlur(displayOptionsMenuRef, setShowDisplayOptionsMenu)
|
||||
|
||||
const isFilesSmartView = useMemo(
|
||||
() => appState.tags.selected?.uuid === SystemViewId.Files,
|
||||
[appState.tags.selected?.uuid],
|
||||
() => viewControllerManager.navigationController.selected?.uuid === SystemViewId.Files,
|
||||
[viewControllerManager.navigationController.selected?.uuid],
|
||||
)
|
||||
|
||||
const addNewItem = useCallback(() => {
|
||||
if (isFilesSmartView) {
|
||||
void appState.files.uploadNewFile()
|
||||
void viewControllerManager.filesController.uploadNewFile()
|
||||
} else {
|
||||
void createNewNote()
|
||||
}
|
||||
}, [appState.files, createNewNote, isFilesSmartView])
|
||||
}, [viewControllerManager.filesController, createNewNote, isFilesSmartView])
|
||||
|
||||
useEffect(() => {
|
||||
/**
|
||||
@@ -142,15 +142,15 @@ const ContentListView: FunctionComponent<Props> = ({ application, appState }) =>
|
||||
const panelResizeFinishCallback: ResizeFinishCallback = useCallback(
|
||||
(width, _lastLeft, _isMaxWidth, isCollapsed) => {
|
||||
application.setPreference(PrefKey.NotesPanelWidth, width).catch(console.error)
|
||||
appState.noteTags.reloadTagsContainerMaxWidth()
|
||||
appState.panelDidResize(PANEL_NAME_NOTES, isCollapsed)
|
||||
viewControllerManager.noteTagsController.reloadTagsContainerMaxWidth()
|
||||
viewControllerManager.panelDidResize(PANEL_NAME_NOTES, isCollapsed)
|
||||
},
|
||||
[appState, application],
|
||||
[viewControllerManager, application],
|
||||
)
|
||||
|
||||
const panelWidthEventCallback = useCallback(() => {
|
||||
appState.noteTags.reloadTagsContainerMaxWidth()
|
||||
}, [appState])
|
||||
viewControllerManager.noteTagsController.reloadTagsContainerMaxWidth()
|
||||
}, [viewControllerManager])
|
||||
|
||||
const toggleDisplayOptionsMenu = useCallback(() => {
|
||||
setShowDisplayOptionsMenu(!showDisplayOptionsMenu)
|
||||
@@ -208,11 +208,11 @@ const ContentListView: FunctionComponent<Props> = ({ application, appState }) =>
|
||||
|
||||
{(focusedSearch || noteFilterText) && (
|
||||
<div className="animate-fade-from-top">
|
||||
<SearchOptions application={application} appState={appState} />
|
||||
<SearchOptions application={application} viewControllerManager={viewControllerManager} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<NoAccountWarningWrapper appState={appState} />
|
||||
<NoAccountWarningWrapper viewControllerManager={viewControllerManager} />
|
||||
</div>
|
||||
<div id="items-menu-bar" className="sn-component" ref={displayOptionsMenuRef}>
|
||||
<div className="sk-app-bar no-edges">
|
||||
@@ -235,7 +235,7 @@ const ContentListView: FunctionComponent<Props> = ({ application, appState }) =>
|
||||
{showDisplayOptionsMenu && (
|
||||
<ContentListOptionsMenu
|
||||
application={application}
|
||||
appState={appState}
|
||||
viewControllerManager={viewControllerManager}
|
||||
closeDisplayOptionsMenu={toggleDisplayOptionsMenu}
|
||||
closeOnBlur={closeDisplayOptMenuOnBlur}
|
||||
isOpen={showDisplayOptionsMenu}
|
||||
@@ -254,7 +254,7 @@ const ContentListView: FunctionComponent<Props> = ({ application, appState }) =>
|
||||
items={renderedItems}
|
||||
selectedItems={selectedItems}
|
||||
application={application}
|
||||
appState={appState}
|
||||
viewControllerManager={viewControllerManager}
|
||||
paginate={paginate}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
@@ -10,7 +10,7 @@ import { DisplayableListItemProps } from './Types/DisplayableListItemProps'
|
||||
|
||||
const FileListItem: FunctionComponent<DisplayableListItemProps> = ({
|
||||
application,
|
||||
appState,
|
||||
viewControllerManager,
|
||||
hideDate,
|
||||
hideIcon,
|
||||
hideTags,
|
||||
@@ -21,32 +21,40 @@ const FileListItem: FunctionComponent<DisplayableListItemProps> = ({
|
||||
}) => {
|
||||
const openFileContextMenu = useCallback(
|
||||
(posX: number, posY: number) => {
|
||||
appState.files.setFileContextMenuLocation({
|
||||
viewControllerManager.filesController.setFileContextMenuLocation({
|
||||
x: posX,
|
||||
y: posY,
|
||||
})
|
||||
appState.files.setShowFileContextMenu(true)
|
||||
viewControllerManager.filesController.setShowFileContextMenu(true)
|
||||
},
|
||||
[appState.files],
|
||||
[viewControllerManager.filesController],
|
||||
)
|
||||
|
||||
const openContextMenu = useCallback(
|
||||
async (posX: number, posY: number) => {
|
||||
const { didSelect } = await appState.selectedItems.selectItem(item.uuid)
|
||||
const { didSelect } = await viewControllerManager.selectionController.selectItem(item.uuid)
|
||||
if (didSelect) {
|
||||
openFileContextMenu(posX, posY)
|
||||
}
|
||||
},
|
||||
[appState.selectedItems, item.uuid, openFileContextMenu],
|
||||
[viewControllerManager.selectionController, item.uuid, openFileContextMenu],
|
||||
)
|
||||
|
||||
const onClick = useCallback(() => {
|
||||
void appState.selectedItems.selectItem(item.uuid, true).then(({ didSelect }) => {
|
||||
if (didSelect && appState.selectedItems.selectedItemsCount < 2) {
|
||||
appState.filePreviewModal.activate(item as FileItem, appState.files.allFiles)
|
||||
void viewControllerManager.selectionController.selectItem(item.uuid, true).then(({ didSelect }) => {
|
||||
if (didSelect && viewControllerManager.selectionController.selectedItemsCount < 2) {
|
||||
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 = () =>
|
||||
getFileIconComponent(
|
||||
|
||||
@@ -11,7 +11,7 @@ import { DisplayableListItemProps } from './Types/DisplayableListItemProps'
|
||||
|
||||
const NoteListItem: FunctionComponent<DisplayableListItemProps> = ({
|
||||
application,
|
||||
appState,
|
||||
viewControllerManager,
|
||||
hideDate,
|
||||
hideIcon,
|
||||
hideTags,
|
||||
@@ -27,16 +27,16 @@ const NoteListItem: FunctionComponent<DisplayableListItemProps> = ({
|
||||
const hasFiles = application.items.getFilesForNote(item as SNNote).length > 0
|
||||
|
||||
const openNoteContextMenu = (posX: number, posY: number) => {
|
||||
appState.notes.setContextMenuClickLocation({
|
||||
viewControllerManager.notesController.setContextMenuClickLocation({
|
||||
x: posX,
|
||||
y: posY,
|
||||
})
|
||||
appState.notes.reloadContextMenuLayout()
|
||||
appState.notes.setContextMenuOpen(true)
|
||||
viewControllerManager.notesController.reloadContextMenuLayout()
|
||||
viewControllerManager.notesController.setContextMenuOpen(true)
|
||||
}
|
||||
|
||||
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) {
|
||||
openNoteContextMenu(posX, posY)
|
||||
}
|
||||
@@ -49,7 +49,7 @@ const NoteListItem: FunctionComponent<DisplayableListItemProps> = ({
|
||||
}`}
|
||||
id={item.uuid}
|
||||
onClick={() => {
|
||||
void appState.selectedItems.selectItem(item.uuid, true)
|
||||
void viewControllerManager.selectionController.selectItem(item.uuid, true)
|
||||
}}
|
||||
onContextMenu={(event) => {
|
||||
event.preventDefault()
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { SortableItem } from '@standardnotes/snjs'
|
||||
import { ListableContentItem } from './ListableContentItem'
|
||||
|
||||
export type AbstractListItemProps = {
|
||||
application: WebApplication
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
hideDate: boolean
|
||||
hideIcon: boolean
|
||||
hideTags: boolean
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { FunctionComponent } from 'react'
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { MAX_MENU_SIZE_MULTIPLIER, MENU_MARGIN_FROM_APP_BORDER } from '@/Constants'
|
||||
import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur'
|
||||
import { useCloseOnClickOutside } from '@/Hooks/useCloseOnClickOutside'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { FunctionComponent, useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { PopoverFileItemAction } from '../AttachedFilesPopover/PopoverFileItemAction'
|
||||
@@ -9,11 +9,12 @@ import { PopoverTabs } from '../AttachedFilesPopover/PopoverTabs'
|
||||
import FileMenuOptions from './FileMenuOptions'
|
||||
|
||||
type Props = {
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
}
|
||||
|
||||
const FileContextMenu: FunctionComponent<Props> = observer(({ appState }) => {
|
||||
const { selectedFiles, showFileContextMenu, setShowFileContextMenu, fileContextMenuLocation } = appState.files
|
||||
const FileContextMenu: FunctionComponent<Props> = observer(({ viewControllerManager }) => {
|
||||
const { selectedFiles, showFileContextMenu, setShowFileContextMenu, fileContextMenuLocation } =
|
||||
viewControllerManager.filesController
|
||||
|
||||
const [contextMenuStyle, setContextMenuStyle] = useState<React.CSSProperties>({
|
||||
top: 0,
|
||||
@@ -23,7 +24,7 @@ const FileContextMenu: FunctionComponent<Props> = observer(({ appState }) => {
|
||||
const [contextMenuMaxHeight, setContextMenuMaxHeight] = useState<number | 'auto'>('auto')
|
||||
const contextMenuRef = useRef<HTMLDivElement>(null)
|
||||
const [closeOnBlur] = useCloseOnBlur(contextMenuRef, (open: boolean) => setShowFileContextMenu(open))
|
||||
useCloseOnClickOutside(contextMenuRef, () => appState.files.setShowFileContextMenu(false))
|
||||
useCloseOnClickOutside(contextMenuRef, () => viewControllerManager.filesController.setShowFileContextMenu(false))
|
||||
|
||||
const selectedFile = selectedFiles[0]
|
||||
|
||||
@@ -87,10 +88,13 @@ const FileContextMenu: FunctionComponent<Props> = observer(({ appState }) => {
|
||||
|
||||
const handleFileAction = useCallback(
|
||||
async (action: PopoverFileItemAction) => {
|
||||
const { didHandleAction } = await appState.files.handleFileAction(action, PopoverTabs.AllFiles)
|
||||
const { didHandleAction } = await viewControllerManager.filesController.handleFileAction(
|
||||
action,
|
||||
PopoverTabs.AllFiles,
|
||||
)
|
||||
return didHandleAction
|
||||
},
|
||||
[appState.files],
|
||||
[viewControllerManager.filesController],
|
||||
)
|
||||
|
||||
return (
|
||||
@@ -116,8 +120,8 @@ const FileContextMenu: FunctionComponent<Props> = observer(({ appState }) => {
|
||||
|
||||
FileContextMenu.displayName = 'FileContextMenu'
|
||||
|
||||
const FileContextMenuWrapper: FunctionComponent<Props> = ({ appState }) => {
|
||||
const { selectedFiles, showFileContextMenu } = appState.files
|
||||
const FileContextMenuWrapper: FunctionComponent<Props> = ({ viewControllerManager }) => {
|
||||
const { selectedFiles, showFileContextMenu } = viewControllerManager.filesController
|
||||
|
||||
const selectedFile = selectedFiles[0]
|
||||
|
||||
@@ -125,7 +129,7 @@ const FileContextMenuWrapper: FunctionComponent<Props> = ({ appState }) => {
|
||||
return null
|
||||
}
|
||||
|
||||
return <FileContextMenu appState={appState} />
|
||||
return <FileContextMenu viewControllerManager={viewControllerManager} />
|
||||
}
|
||||
|
||||
export default observer(FileContextMenuWrapper)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { concatenateUint8Arrays } from '@/Utils/ConcatenateUint8Arrays'
|
||||
import { DialogContent, DialogOverlay } from '@reach/dialog'
|
||||
import { addToast, ToastType } from '@standardnotes/stylekit'
|
||||
@@ -12,16 +12,16 @@ import { isFileTypePreviewable } from './isFilePreviewable'
|
||||
import PreviewComponent from './PreviewComponent'
|
||||
import { FOCUSABLE_BUT_NOT_TABBABLE } from '@/Constants'
|
||||
import { KeyboardKey } from '@/Services/IOService'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
}
|
||||
|
||||
const FilePreviewModal: FunctionComponent<Props> = observer(({ application, appState }) => {
|
||||
const { currentFile, setCurrentFile, otherFiles, dismiss } = appState.filePreviewModal
|
||||
const FilePreviewModal: FunctionComponent<Props> = observer(({ application, viewControllerManager }) => {
|
||||
const { currentFile, setCurrentFile, otherFiles, dismiss } = viewControllerManager.filePreviewModalController
|
||||
|
||||
if (!currentFile) {
|
||||
return null
|
||||
@@ -221,7 +221,10 @@ const FilePreviewModal: FunctionComponent<Props> = observer(({ application, appS
|
||||
<Button
|
||||
variant="normal"
|
||||
onClick={() => {
|
||||
application.getAppState().files.downloadFile(currentFile).catch(console.error)
|
||||
application
|
||||
.getViewControllerManager()
|
||||
.filesController.downloadFile(currentFile)
|
||||
.catch(console.error)
|
||||
}}
|
||||
>
|
||||
Download
|
||||
@@ -236,7 +239,10 @@ const FilePreviewModal: FunctionComponent<Props> = observer(({ application, appS
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={() => {
|
||||
application.getAppState().files.downloadFile(currentFile).catch(console.error)
|
||||
application
|
||||
.getViewControllerManager()
|
||||
.filesController.downloadFile(currentFile)
|
||||
.catch(console.error)
|
||||
}}
|
||||
>
|
||||
Download
|
||||
@@ -255,8 +261,10 @@ const FilePreviewModal: FunctionComponent<Props> = observer(({ application, appS
|
||||
|
||||
FilePreviewModal.displayName = 'FilePreviewModal'
|
||||
|
||||
const FilePreviewModalWrapper: FunctionComponent<Props> = ({ application, appState }) => {
|
||||
return appState.filePreviewModal.isOpen ? <FilePreviewModal application={application} appState={appState} /> : null
|
||||
const FilePreviewModalWrapper: FunctionComponent<Props> = ({ application, viewControllerManager }) => {
|
||||
return viewControllerManager.filePreviewModalController.isOpen ? (
|
||||
<FilePreviewModal application={application} viewControllerManager={viewControllerManager} />
|
||||
) : null
|
||||
}
|
||||
|
||||
export default observer(FilePreviewModalWrapper)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { WebAppEvent, WebApplication } from '@/UIModels/Application'
|
||||
import { ApplicationGroup } from '@/UIModels/ApplicationGroup'
|
||||
import { WebAppEvent, WebApplication } from '@/Application/Application'
|
||||
import { ApplicationGroup } from '@/Application/ApplicationGroup'
|
||||
import { PureComponent } from '@/Components/Abstract/PureComponent'
|
||||
import { destroyAllObjectProperties, preventRefreshing } from '@/Utils'
|
||||
import { ApplicationEvent, ApplicationDescriptor } from '@standardnotes/snjs'
|
||||
@@ -12,12 +12,13 @@ import {
|
||||
} from '@/Strings'
|
||||
import { alertDialog, confirmDialog } from '@/Services/AlertService'
|
||||
import AccountMenu from '@/Components/AccountMenu/AccountMenu'
|
||||
import { AppStateEvent, EventSource } from '@/UIModels/AppState'
|
||||
import { ViewControllerManagerEvent } from '@/Services/ViewControllerManager'
|
||||
import Icon from '@/Components/Icon/Icon'
|
||||
import QuickSettingsMenu from '@/Components/QuickSettingsMenu/QuickSettingsMenu'
|
||||
import SyncResolutionMenu from '@/Components/SyncResolutionMenu/SyncResolutionMenu'
|
||||
import { Fragment } from 'react'
|
||||
import { AccountMenuPane } from '../AccountMenu/AccountMenuPane'
|
||||
import { EditorEventSource } from '@/Typings/EditorEventSource'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
@@ -92,11 +93,11 @@ class Footer extends PureComponent<Props, State> {
|
||||
})
|
||||
|
||||
this.autorun(() => {
|
||||
const showBetaWarning = this.appState.showBetaWarning
|
||||
const showBetaWarning = this.viewControllerManager.showBetaWarning
|
||||
this.setState({
|
||||
showBetaWarning: showBetaWarning,
|
||||
showAccountMenu: this.appState.accountMenu.show,
|
||||
showQuickSettingsMenu: this.appState.quickSettingsMenu.open,
|
||||
showAccountMenu: this.viewControllerManager.accountMenuController.show,
|
||||
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
|
||||
switch (eventName) {
|
||||
case AppStateEvent.EditorFocused:
|
||||
if (data.eventSource === EventSource.UserInteraction) {
|
||||
case ViewControllerManagerEvent.EditorFocused:
|
||||
if (data.eventSource === EditorEventSource.UserInteraction) {
|
||||
this.closeAccountMenu()
|
||||
}
|
||||
break
|
||||
case AppStateEvent.BeganBackupDownload:
|
||||
case ViewControllerManagerEvent.BeganBackupDownload:
|
||||
statusService.setMessage('Saving local backup…')
|
||||
break
|
||||
case AppStateEvent.EndedBackupDownload: {
|
||||
case ViewControllerManagerEvent.EndedBackupDownload: {
|
||||
const successMessage = 'Successfully saved backup.'
|
||||
const errorMessage = 'Unable to save local backup.'
|
||||
statusService.setMessage(data.success ? successMessage : errorMessage)
|
||||
@@ -187,7 +188,7 @@ class Footer extends PureComponent<Props, State> {
|
||||
if (!this.didCheckForOffline) {
|
||||
this.didCheckForOffline = true
|
||||
if (this.state.offline && this.application.items.getNoteCount() === 0) {
|
||||
this.appState.accountMenu.setShow(true)
|
||||
this.viewControllerManager.accountMenuController.setShow(true)
|
||||
}
|
||||
}
|
||||
this.findErrors()
|
||||
@@ -288,13 +289,13 @@ class Footer extends PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
accountMenuClickHandler = () => {
|
||||
this.appState.quickSettingsMenu.closeQuickSettingsMenu()
|
||||
this.appState.accountMenu.toggleShow()
|
||||
this.viewControllerManager.quickSettingsMenuController.closeQuickSettingsMenu()
|
||||
this.viewControllerManager.accountMenuController.toggleShow()
|
||||
}
|
||||
|
||||
quickSettingsClickHandler = () => {
|
||||
this.appState.accountMenu.closeAccountMenu()
|
||||
this.appState.quickSettingsMenu.toggle()
|
||||
this.viewControllerManager.accountMenuController.closeAccountMenu()
|
||||
this.viewControllerManager.quickSettingsMenuController.toggle()
|
||||
}
|
||||
|
||||
syncResolutionClickHandler = () => {
|
||||
@@ -304,8 +305,8 @@ class Footer extends PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
closeAccountMenu = () => {
|
||||
this.appState.accountMenu.setShow(false)
|
||||
this.appState.accountMenu.setCurrentPane(AccountMenuPane.GeneralMenu)
|
||||
this.viewControllerManager.accountMenuController.setShow(false)
|
||||
this.viewControllerManager.accountMenuController.setCurrentPane(AccountMenuPane.GeneralMenu)
|
||||
}
|
||||
|
||||
lockClickHandler = () => {
|
||||
@@ -333,11 +334,11 @@ class Footer extends PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
clickOutsideAccountMenu = () => {
|
||||
this.appState.accountMenu.closeAccountMenu()
|
||||
this.viewControllerManager.accountMenuController.closeAccountMenu()
|
||||
}
|
||||
|
||||
clickOutsideQuickSettingsMenu = () => {
|
||||
this.appState.quickSettingsMenu.closeQuickSettingsMenu()
|
||||
this.viewControllerManager.quickSettingsMenuController.closeQuickSettingsMenu()
|
||||
}
|
||||
|
||||
override render() {
|
||||
@@ -360,7 +361,7 @@ class Footer extends PureComponent<Props, State> {
|
||||
{this.state.showAccountMenu && (
|
||||
<AccountMenu
|
||||
onClickOutside={this.clickOutsideAccountMenu}
|
||||
appState={this.appState}
|
||||
viewControllerManager={this.viewControllerManager}
|
||||
application={this.application}
|
||||
mainApplicationGroup={this.props.applicationGroup}
|
||||
/>
|
||||
@@ -381,7 +382,7 @@ class Footer extends PureComponent<Props, State> {
|
||||
{this.state.showQuickSettingsMenu && (
|
||||
<QuickSettingsMenu
|
||||
onClickOutside={this.clickOutsideQuickSettingsMenu}
|
||||
appState={this.appState}
|
||||
viewControllerManager={this.viewControllerManager}
|
||||
application={this.application}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { IlNotesIcon } from '@standardnotes/icons'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import NotesOptionsPanel from '@/Components/NotesOptions/NotesOptionsPanel'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import PinNoteButton from '@/Components/PinNoteButton/PinNoteButton'
|
||||
import Button from '../Button/Button'
|
||||
import { useCallback } from 'react'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
}
|
||||
|
||||
const MultipleSelectedNotes = ({ application, appState }: Props) => {
|
||||
const count = appState.notes.selectedNotesCount
|
||||
const MultipleSelectedNotes = ({ application, viewControllerManager }: Props) => {
|
||||
const count = viewControllerManager.notesController.selectedNotesCount
|
||||
|
||||
const cancelMultipleSelection = useCallback(() => {
|
||||
appState.selectedItems.cancelMultipleSelection()
|
||||
}, [appState])
|
||||
viewControllerManager.selectionController.cancelMultipleSelection()
|
||||
}, [viewControllerManager])
|
||||
|
||||
return (
|
||||
<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>
|
||||
<div className="flex">
|
||||
<div className="mr-3">
|
||||
<PinNoteButton appState={appState} />
|
||||
<PinNoteButton viewControllerManager={viewControllerManager} />
|
||||
</div>
|
||||
<NotesOptionsPanel application={application} appState={appState} />
|
||||
<NotesOptionsPanel application={application} viewControllerManager={viewControllerManager} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-grow flex flex-col justify-center items-center w-full max-w-md">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import SmartViewsSection from '@/Components/Tags/SmartViewsSection'
|
||||
import TagsSection from '@/Components/Tags/TagsSection'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { PANEL_NAME_NAVIGATION } from '@/Constants'
|
||||
import { ApplicationEvent, PrefKey } from '@standardnotes/snjs'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
@@ -12,7 +12,7 @@ type Props = {
|
||||
}
|
||||
|
||||
const Navigation: FunctionComponent<Props> = ({ application }) => {
|
||||
const appState = useMemo(() => application.getAppState(), [application])
|
||||
const viewControllerManager = useMemo(() => application.getViewControllerManager(), [application])
|
||||
const [ref, setRef] = useState<HTMLDivElement | null>()
|
||||
const [panelWidth, setPanelWidth] = useState<number>(0)
|
||||
|
||||
@@ -32,15 +32,15 @@ const Navigation: FunctionComponent<Props> = ({ application }) => {
|
||||
const panelResizeFinishCallback: ResizeFinishCallback = useCallback(
|
||||
(width, _lastLeft, _isMaxWidth, isCollapsed) => {
|
||||
application.setPreference(PrefKey.TagsPanelWidth, width).catch(console.error)
|
||||
appState.noteTags.reloadTagsContainerMaxWidth()
|
||||
appState.panelDidResize(PANEL_NAME_NAVIGATION, isCollapsed)
|
||||
viewControllerManager.noteTagsController.reloadTagsContainerMaxWidth()
|
||||
viewControllerManager.panelDidResize(PANEL_NAME_NAVIGATION, isCollapsed)
|
||||
},
|
||||
[application, appState],
|
||||
[application, viewControllerManager],
|
||||
)
|
||||
|
||||
const panelWidthEventCallback = useCallback(() => {
|
||||
appState.noteTags.reloadTagsContainerMaxWidth()
|
||||
}, [appState])
|
||||
viewControllerManager.noteTagsController.reloadTagsContainerMaxWidth()
|
||||
}, [viewControllerManager])
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -58,8 +58,8 @@ const Navigation: FunctionComponent<Props> = ({ application }) => {
|
||||
</div>
|
||||
</div>
|
||||
<div className="scrollable">
|
||||
<SmartViewsSection appState={appState} />
|
||||
<TagsSection appState={appState} />
|
||||
<SmartViewsSection viewControllerManager={viewControllerManager} />
|
||||
<TagsSection viewControllerManager={viewControllerManager} />
|
||||
</div>
|
||||
</div>
|
||||
{ref && (
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
import Icon from '@/Components/Icon/Icon'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
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(
|
||||
(event) => {
|
||||
event.stopPropagation()
|
||||
appState.accountMenu.setShow(true)
|
||||
viewControllerManager.accountMenuController.setShow(true)
|
||||
},
|
||||
[appState],
|
||||
[viewControllerManager],
|
||||
)
|
||||
|
||||
const hideWarning = useCallback(() => {
|
||||
appState.noAccountWarning.hide()
|
||||
}, [appState])
|
||||
viewControllerManager.noAccountWarningController.hide()
|
||||
}, [viewControllerManager])
|
||||
|
||||
return (
|
||||
<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'
|
||||
|
||||
const NoAccountWarningWrapper = ({ appState }: Props) => {
|
||||
const canShow = appState.noAccountWarning.show
|
||||
const NoAccountWarningWrapper = ({ viewControllerManager }: Props) => {
|
||||
const canShow = viewControllerManager.noAccountWarningController.show
|
||||
|
||||
return canShow ? <NoAccountWarning appState={appState} /> : null
|
||||
return canShow ? <NoAccountWarning viewControllerManager={viewControllerManager} /> : null
|
||||
}
|
||||
|
||||
export default observer(NoAccountWarningWrapper)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { NoteViewController } from '@standardnotes/snjs'
|
||||
import { PureComponent } from '@/Components/Abstract/PureComponent'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import MultipleSelectedNotes from '@/Components/MultipleSelectedNotes/MultipleSelectedNotes'
|
||||
import NoteView from '@/Components/NoteView/NoteView'
|
||||
import { ElementIds } from '@/ElementIDs'
|
||||
@@ -37,9 +37,9 @@ class NoteGroupView extends PureComponent<Props, State> {
|
||||
})
|
||||
|
||||
this.autorun(() => {
|
||||
if (this.appState && this.appState.notes) {
|
||||
if (this.viewControllerManager && this.viewControllerManager.notesController) {
|
||||
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 (
|
||||
<div id={ElementIds.EditorColumn} className="h-full app-column app-column-third">
|
||||
{this.state.showMultipleSelectedNotes && (
|
||||
<MultipleSelectedNotes application={this.application} appState={this.appState} />
|
||||
<MultipleSelectedNotes application={this.application} viewControllerManager={this.viewControllerManager} />
|
||||
)}
|
||||
|
||||
{!this.state.showMultipleSelectedNotes && (
|
||||
|
||||
@@ -8,17 +8,17 @@ import {
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { SNTag } from '@standardnotes/snjs'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
|
||||
type Props = {
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
tag: SNTag
|
||||
}
|
||||
|
||||
const NoteTag = ({ appState, tag }: Props) => {
|
||||
const noteTags = appState.noteTags
|
||||
const NoteTag = ({ viewControllerManager, tag }: Props) => {
|
||||
const noteTags = viewControllerManager.noteTagsController
|
||||
|
||||
const { autocompleteInputFocused, focusedTagUuid, tags } = noteTags
|
||||
|
||||
@@ -33,9 +33,9 @@ const NoteTag = ({ appState, tag }: Props) => {
|
||||
const longTitle = noteTags.getLongTitle(tag)
|
||||
|
||||
const deleteTag = useCallback(() => {
|
||||
appState.noteTags.focusPreviousTag(tag)
|
||||
appState.noteTags.removeTagFromActiveNote(tag).catch(console.error)
|
||||
}, [appState, tag])
|
||||
viewControllerManager.noteTagsController.focusPreviousTag(tag)
|
||||
viewControllerManager.noteTagsController.removeTagFromActiveNote(tag).catch(console.error)
|
||||
}, [viewControllerManager, tag])
|
||||
|
||||
const onDeleteTagClick: MouseEventHandler = useCallback(
|
||||
(event) => {
|
||||
@@ -49,28 +49,28 @@ const NoteTag = ({ appState, tag }: Props) => {
|
||||
(event) => {
|
||||
if (tagClicked && event.target !== deleteTagRef.current) {
|
||||
setTagClicked(false)
|
||||
void appState.tags.setSelectedTag(tag)
|
||||
void viewControllerManager.navigationController.setSelectedTag(tag)
|
||||
} else {
|
||||
setTagClicked(true)
|
||||
}
|
||||
},
|
||||
[appState, tagClicked, tag],
|
||||
[viewControllerManager, tagClicked, tag],
|
||||
)
|
||||
|
||||
const onFocus = useCallback(() => {
|
||||
appState.noteTags.setFocusedTagUuid(tag.uuid)
|
||||
viewControllerManager.noteTagsController.setFocusedTagUuid(tag.uuid)
|
||||
setShowDeleteButton(true)
|
||||
}, [appState, tag])
|
||||
}, [viewControllerManager, tag])
|
||||
|
||||
const onBlur: FocusEventHandler = useCallback(
|
||||
(event) => {
|
||||
const relatedTarget = event.relatedTarget as Node
|
||||
if (relatedTarget !== deleteTagRef.current) {
|
||||
appState.noteTags.setFocusedTagUuid(undefined)
|
||||
viewControllerManager.noteTagsController.setFocusedTagUuid(undefined)
|
||||
setShowDeleteButton(false)
|
||||
}
|
||||
},
|
||||
[appState],
|
||||
[viewControllerManager],
|
||||
)
|
||||
|
||||
const getTabIndex = useCallback(() => {
|
||||
@@ -85,33 +85,33 @@ const NoteTag = ({ appState, tag }: Props) => {
|
||||
|
||||
const onKeyDown: KeyboardEventHandler = useCallback(
|
||||
(event) => {
|
||||
const tagIndex = appState.noteTags.getTagIndex(tag, tags)
|
||||
const tagIndex = viewControllerManager.noteTagsController.getTagIndex(tag, tags)
|
||||
switch (event.key) {
|
||||
case 'Backspace':
|
||||
deleteTag()
|
||||
break
|
||||
case 'ArrowLeft':
|
||||
appState.noteTags.focusPreviousTag(tag)
|
||||
viewControllerManager.noteTagsController.focusPreviousTag(tag)
|
||||
break
|
||||
case 'ArrowRight':
|
||||
if (tagIndex === tags.length - 1) {
|
||||
appState.noteTags.setAutocompleteInputFocused(true)
|
||||
viewControllerManager.noteTagsController.setAutocompleteInputFocused(true)
|
||||
} else {
|
||||
appState.noteTags.focusNextTag(tag)
|
||||
viewControllerManager.noteTagsController.focusNextTag(tag)
|
||||
}
|
||||
break
|
||||
default:
|
||||
return
|
||||
}
|
||||
},
|
||||
[appState, deleteTag, tag, tags],
|
||||
[viewControllerManager, deleteTag, tag, tags],
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (focusedTagUuid === tag.uuid) {
|
||||
tagRef.current?.focus()
|
||||
}
|
||||
}, [appState, focusedTagUuid, tag])
|
||||
}, [viewControllerManager, focusedTagUuid, tag])
|
||||
|
||||
return (
|
||||
<button
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import AutocompleteTagInput from '@/Components/TagAutocomplete/AutocompleteTagInput'
|
||||
import NoteTag from './NoteTag'
|
||||
import { useEffect } from 'react'
|
||||
|
||||
type Props = {
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
}
|
||||
|
||||
const NoteTagsContainer = ({ appState }: Props) => {
|
||||
const { tags, tagsContainerMaxWidth } = appState.noteTags
|
||||
const NoteTagsContainer = ({ viewControllerManager }: Props) => {
|
||||
const { tags, tagsContainerMaxWidth } = viewControllerManager.noteTagsController
|
||||
|
||||
useEffect(() => {
|
||||
appState.noteTags.reloadTagsContainerMaxWidth()
|
||||
}, [appState])
|
||||
viewControllerManager.noteTagsController.reloadTagsContainerMaxWidth()
|
||||
}, [viewControllerManager])
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -23,9 +23,9 @@ const NoteTagsContainer = ({ appState }: Props) => {
|
||||
}}
|
||||
>
|
||||
{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>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
* @jest-environment jsdom
|
||||
*/
|
||||
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { NotesState } from '@/UIModels/AppState/NotesState'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { NotesController } from '@/Controllers/NotesController'
|
||||
import {
|
||||
ApplicationEvent,
|
||||
ProposedSecondsToDeferUILevelSessionExpirationDuringActiveInteraction,
|
||||
@@ -17,8 +17,8 @@ import NoteView from './NoteView'
|
||||
describe('NoteView', () => {
|
||||
let noteViewController: NoteViewController
|
||||
let application: WebApplication
|
||||
let appState: AppState
|
||||
let notesState: NotesState
|
||||
let viewControllerManager: ViewControllerManager
|
||||
let notesState: NotesController
|
||||
|
||||
const createNoteView = () =>
|
||||
new NoteView({
|
||||
@@ -31,15 +31,15 @@ describe('NoteView', () => {
|
||||
|
||||
noteViewController = {} as jest.Mocked<NoteViewController>
|
||||
|
||||
notesState = {} as jest.Mocked<NotesState>
|
||||
notesState = {} as jest.Mocked<NotesController>
|
||||
notesState.setShowProtectedWarning = jest.fn()
|
||||
|
||||
appState = {
|
||||
notes: notesState,
|
||||
} as jest.Mocked<AppState>
|
||||
viewControllerManager = {
|
||||
notesController: notesState,
|
||||
} as jest.Mocked<ViewControllerManager>
|
||||
|
||||
application = {} as jest.Mocked<WebApplication>
|
||||
application.getAppState = jest.fn().mockReturnValue(appState)
|
||||
application.getViewControllerManager = jest.fn().mockReturnValue(viewControllerManager)
|
||||
application.hasProtectionSources = jest.fn().mockReturnValue(true)
|
||||
application.authorizeNoteAccess = jest.fn()
|
||||
})
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
PayloadEmitSource,
|
||||
} from '@standardnotes/snjs'
|
||||
import { debounce, isDesktopApplication } from '@/Utils'
|
||||
import { EventSource } from '../../UIModels/AppState/EventSource'
|
||||
import { EditorEventSource } from '../../Typings/EditorEventSource'
|
||||
import { KeyboardModifier, KeyboardKey } from '@/Services/IOService'
|
||||
import { STRING_DELETE_PLACEHOLDER_ATTEMPT, STRING_DELETE_LOCKED_ATTEMPT, StringDeleteNote } from '@/Strings'
|
||||
import { confirmDialog } from '@/Services/AlertService'
|
||||
@@ -82,7 +82,7 @@ class NoteView extends PureComponent<NoteViewProps, State> {
|
||||
readonly controller!: NoteViewController
|
||||
|
||||
private statusTimeout?: NodeJS.Timeout
|
||||
private lastEditorFocusEventSource?: EventSource
|
||||
private lastEditorFocusEventSource?: EditorEventSource
|
||||
onEditorComponentLoad?: () => void
|
||||
|
||||
private scrollPosition = 0
|
||||
@@ -193,7 +193,7 @@ class NoteView extends PureComponent<NoteViewProps, State> {
|
||||
|
||||
this.autorun(() => {
|
||||
this.setState({
|
||||
showProtectedWarning: this.appState.notes.showProtectedWarning,
|
||||
showProtectedWarning: this.viewControllerManager.notesController.showProtectedWarning,
|
||||
})
|
||||
})
|
||||
|
||||
@@ -577,7 +577,7 @@ class NoteView extends PureComponent<NoteViewProps, State> {
|
||||
focusEditor() {
|
||||
const element = document.getElementById(ElementIds.NoteTextEditor)
|
||||
if (element) {
|
||||
this.lastEditorFocusEventSource = EventSource.Script
|
||||
this.lastEditorFocusEventSource = EditorEventSource.Script
|
||||
element.focus()
|
||||
}
|
||||
}
|
||||
@@ -588,13 +588,13 @@ class NoteView extends PureComponent<NoteViewProps, State> {
|
||||
|
||||
onContentFocus = () => {
|
||||
if (this.lastEditorFocusEventSource) {
|
||||
this.application.getAppState().editorDidFocus(this.lastEditorFocusEventSource)
|
||||
this.application.getViewControllerManager().editorDidFocus(this.lastEditorFocusEventSource)
|
||||
}
|
||||
this.lastEditorFocusEventSource = undefined
|
||||
}
|
||||
|
||||
setShowProtectedOverlay(show: boolean) {
|
||||
this.appState.notes.setShowProtectedWarning(show)
|
||||
this.viewControllerManager.notesController.setShowProtectedWarning(show)
|
||||
}
|
||||
|
||||
async deleteNote(permanently: boolean) {
|
||||
@@ -653,7 +653,7 @@ class NoteView extends PureComponent<NoteViewProps, State> {
|
||||
}
|
||||
|
||||
async reloadSpellcheck() {
|
||||
const spellcheck = this.appState.notes.getSpellcheckStateForNote(this.note)
|
||||
const spellcheck = this.viewControllerManager.notesController.getSpellcheckStateForNote(this.note)
|
||||
|
||||
if (spellcheck !== this.state.spellcheck) {
|
||||
this.setState({ textareaUnloading: true })
|
||||
@@ -871,7 +871,7 @@ class NoteView extends PureComponent<NoteViewProps, State> {
|
||||
{this.state.showProtectedWarning && (
|
||||
<div className="h-full flex justify-center items-center">
|
||||
<ProtectedNoteOverlay
|
||||
appState={this.appState}
|
||||
viewControllerManager={this.viewControllerManager}
|
||||
hasProtectionSources={this.application.hasProtectionSources()}
|
||||
onViewNote={this.dismissProtectedWarning}
|
||||
/>
|
||||
@@ -898,7 +898,7 @@ class NoteView extends PureComponent<NoteViewProps, State> {
|
||||
showLockedIcon: false,
|
||||
})
|
||||
}}
|
||||
onClick={() => this.appState.notes.setLockSelectedNotes(!this.state.noteLocked)}
|
||||
onClick={() => this.viewControllerManager.notesController.setLockSelectedNotes(!this.state.noteLocked)}
|
||||
showLockedIcon={this.state.showLockedIcon}
|
||||
lockText={this.state.lockText}
|
||||
/>
|
||||
@@ -942,31 +942,31 @@ class NoteView extends PureComponent<NoteViewProps, State> {
|
||||
<div className="mr-3">
|
||||
<AttachedFilesButton
|
||||
application={this.application}
|
||||
appState={this.appState}
|
||||
viewControllerManager={this.viewControllerManager}
|
||||
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
|
||||
/>
|
||||
</div>
|
||||
<div className="mr-3">
|
||||
<ChangeEditorButton
|
||||
application={this.application}
|
||||
appState={this.appState}
|
||||
viewControllerManager={this.viewControllerManager}
|
||||
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
|
||||
/>
|
||||
</div>
|
||||
<div className="mr-3">
|
||||
<PinNoteButton
|
||||
appState={this.appState}
|
||||
viewControllerManager={this.viewControllerManager}
|
||||
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
|
||||
/>
|
||||
</div>
|
||||
<NotesOptionsPanel
|
||||
application={this.application}
|
||||
appState={this.appState}
|
||||
viewControllerManager={this.viewControllerManager}
|
||||
onClickPreprocessing={this.ensureNoteIsInsertedBeforeUIAction}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<NoteTagsContainer appState={this.appState} />
|
||||
<NoteTagsContainer viewControllerManager={this.viewControllerManager} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -993,7 +993,7 @@ class NoteView extends PureComponent<NoteViewProps, State> {
|
||||
onLoad={this.onEditorComponentLoad}
|
||||
requestReload={this.editorComponentViewerRequestsReload}
|
||||
application={this.application}
|
||||
appState={this.appState}
|
||||
viewControllerManager={this.viewControllerManager}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
@@ -1068,7 +1068,7 @@ class NoteView extends PureComponent<NoteViewProps, State> {
|
||||
key={viewer.identifier}
|
||||
componentViewer={viewer}
|
||||
application={this.application}
|
||||
appState={this.appState}
|
||||
viewControllerManager={this.viewControllerManager}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { NoteViewController } from '@standardnotes/snjs'
|
||||
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
|
||||
export interface NoteViewProps {
|
||||
application: WebApplication
|
||||
|
||||
@@ -1,27 +1,29 @@
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur'
|
||||
import { useCloseOnClickOutside } from '@/Hooks/useCloseOnClickOutside'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import NotesOptions from '@/Components/NotesOptions/NotesOptions'
|
||||
import { useCallback, useEffect, useRef } from 'react'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
}
|
||||
|
||||
const NotesContextMenu = ({ application, appState }: Props) => {
|
||||
const { contextMenuOpen, contextMenuPosition, contextMenuMaxHeight } = appState.notes
|
||||
const NotesContextMenu = ({ application, viewControllerManager }: Props) => {
|
||||
const { contextMenuOpen, contextMenuPosition, contextMenuMaxHeight } = viewControllerManager.notesController
|
||||
|
||||
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(() => {
|
||||
appState.notes.reloadContextMenuLayout()
|
||||
}, [appState])
|
||||
viewControllerManager.notesController.reloadContextMenuLayout()
|
||||
}, [viewControllerManager])
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener('resize', reloadContextMenuLayout)
|
||||
@@ -39,7 +41,7 @@ const NotesContextMenu = ({ application, appState }: Props) => {
|
||||
maxHeight: contextMenuMaxHeight,
|
||||
}}
|
||||
>
|
||||
<NotesOptions application={application} appState={appState} closeOnBlur={closeOnBlur} />
|
||||
<NotesOptions application={application} viewControllerManager={viewControllerManager} closeOnBlur={closeOnBlur} />
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { calculateSubmenuStyle, SubmenuStyle } from '@/Utils/CalculateSubmenuStyle'
|
||||
import { Disclosure, DisclosureButton, DisclosurePanel } from '@reach/disclosure'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
@@ -7,10 +7,10 @@ import Icon from '@/Components/Icon/Icon'
|
||||
import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur'
|
||||
|
||||
type Props = {
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
}
|
||||
|
||||
const AddTagOption: FunctionComponent<Props> = ({ appState }) => {
|
||||
const AddTagOption: FunctionComponent<Props> = ({ viewControllerManager }) => {
|
||||
const menuContainerRef = useRef<HTMLDivElement>(null)
|
||||
const menuRef = useRef<HTMLDivElement>(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"
|
||||
>
|
||||
{appState.tags.tags.map((tag) => (
|
||||
{viewControllerManager.navigationController.tags.map((tag) => (
|
||||
<button
|
||||
key={tag.uuid}
|
||||
className="sn-dropdown-item sn-dropdown-item--no-icon max-w-80"
|
||||
onBlur={closeOnBlur}
|
||||
onClick={() => {
|
||||
appState.notes.isTagInSelectedNotes(tag)
|
||||
? appState.notes.removeTagFromSelectedNotes(tag).catch(console.error)
|
||||
: appState.notes.addTagToSelectedNotes(tag).catch(console.error)
|
||||
viewControllerManager.notesController.isTagInSelectedNotes(tag)
|
||||
? viewControllerManager.notesController.removeTagFromSelectedNotes(tag).catch(console.error)
|
||||
: viewControllerManager.notesController.addTagToSelectedNotes(tag).catch(console.error)
|
||||
}}
|
||||
>
|
||||
<span
|
||||
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>
|
||||
</button>
|
||||
))}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { KeyboardKey } from '@/Services/IOService'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { Disclosure, DisclosureButton, DisclosurePanel } from '@reach/disclosure'
|
||||
import { SNNote } from '@standardnotes/snjs'
|
||||
import { FunctionComponent, useCallback, useEffect, useRef, useState } from 'react'
|
||||
@@ -10,7 +10,7 @@ import { calculateSubmenuStyle, SubmenuStyle } from '@/Utils/CalculateSubmenuSty
|
||||
import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur'
|
||||
|
||||
type ChangeEditorOptionProps = {
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
application: WebApplication
|
||||
note: SNNote
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { calculateSubmenuStyle, SubmenuStyle } from '@/Utils/CalculateSubmenuStyle'
|
||||
import { Disclosure, DisclosureButton, DisclosurePanel } from '@reach/disclosure'
|
||||
import { Action, ListedAccount, SNNote } from '@standardnotes/snjs'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import Icon from '@/Components/Icon/Icon'
|
||||
import Switch from '@/Components/Switch/Switch'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
@@ -121,15 +121,15 @@ const NoteAttributes: FunctionComponent<{
|
||||
}
|
||||
|
||||
const SpellcheckOptions: FunctionComponent<{
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
note: SNNote
|
||||
}> = ({ appState, note }) => {
|
||||
const editor = appState.application.componentManager.editorForNote(note)
|
||||
}> = ({ viewControllerManager, note }) => {
|
||||
const editor = viewControllerManager.application.componentManager.editorForNote(note)
|
||||
const spellcheckControllable = Boolean(!editor || editor.package_info.spellcheckControl)
|
||||
const noteSpellcheck = !spellcheckControllable
|
||||
? true
|
||||
: note
|
||||
? appState.notes.getSpellcheckStateForNote(note)
|
||||
? viewControllerManager.notesController.getSpellcheckStateForNote(note)
|
||||
: undefined
|
||||
|
||||
return (
|
||||
@@ -137,7 +137,7 @@ const SpellcheckOptions: FunctionComponent<{
|
||||
<button
|
||||
className="sn-dropdown-item justify-between px-3 py-1"
|
||||
onClick={() => {
|
||||
appState.notes.toggleGlobalSpellcheckForNote(note).catch(console.error)
|
||||
viewControllerManager.notesController.toggleGlobalSpellcheckForNote(note).catch(console.error)
|
||||
}}
|
||||
disabled={!spellcheckControllable}
|
||||
>
|
||||
@@ -169,7 +169,7 @@ const NoteSizeWarning: FunctionComponent<{
|
||||
) : null
|
||||
}
|
||||
|
||||
const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps) => {
|
||||
const NotesOptions = ({ application, viewControllerManager, closeOnBlur }: NotesOptionsProps) => {
|
||||
const [altKeyDown, setAltKeyDown] = useState(false)
|
||||
|
||||
const toggleOn = (condition: (note: SNNote) => boolean) => {
|
||||
@@ -178,7 +178,7 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
|
||||
return notesMatchingAttribute.length > notesNotMatchingAttribute.length
|
||||
}
|
||||
|
||||
const notes = appState.notes.selectedNotes
|
||||
const notes = viewControllerManager.notesController.selectedNotes
|
||||
const hidePreviews = toggleOn((note) => note.hidePreview)
|
||||
const locked = toggleOn((note) => note.locked)
|
||||
const protect = toggleOn((note) => note.protected)
|
||||
@@ -248,8 +248,8 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
|
||||
}, [application, notes])
|
||||
|
||||
const openRevisionHistoryModal = useCallback(() => {
|
||||
appState.notes.setShowRevisionHistoryModal(true)
|
||||
}, [appState])
|
||||
viewControllerManager.notesController.setShowRevisionHistoryModal(true)
|
||||
}, [viewControllerManager])
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -265,7 +265,7 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
|
||||
<button
|
||||
className="sn-dropdown-item justify-between"
|
||||
onClick={() => {
|
||||
appState.notes.setLockSelectedNotes(!locked)
|
||||
viewControllerManager.notesController.setLockSelectedNotes(!locked)
|
||||
}}
|
||||
onBlur={closeOnBlur}
|
||||
>
|
||||
@@ -278,7 +278,7 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
|
||||
<button
|
||||
className="sn-dropdown-item justify-between"
|
||||
onClick={() => {
|
||||
appState.notes.setHideSelectedNotePreviews(!hidePreviews)
|
||||
viewControllerManager.notesController.setHideSelectedNotePreviews(!hidePreviews)
|
||||
}}
|
||||
onBlur={closeOnBlur}
|
||||
>
|
||||
@@ -291,7 +291,7 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
|
||||
<button
|
||||
className="sn-dropdown-item justify-between"
|
||||
onClick={() => {
|
||||
appState.notes.setProtectSelectedNotes(!protect).catch(console.error)
|
||||
viewControllerManager.notesController.setProtectSelectedNotes(!protect).catch(console.error)
|
||||
}}
|
||||
onBlur={closeOnBlur}
|
||||
>
|
||||
@@ -304,17 +304,19 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
|
||||
{notes.length === 1 && (
|
||||
<>
|
||||
<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>
|
||||
{appState.tags.tagsCount > 0 && <AddTagOption appState={appState} />}
|
||||
{viewControllerManager.navigationController.tagsCount > 0 && (
|
||||
<AddTagOption viewControllerManager={viewControllerManager} />
|
||||
)}
|
||||
{unpinned && (
|
||||
<button
|
||||
onBlur={closeOnBlur}
|
||||
className="sn-dropdown-item"
|
||||
onClick={() => {
|
||||
appState.notes.setPinSelectedNotes(true)
|
||||
viewControllerManager.notesController.setPinSelectedNotes(true)
|
||||
}}
|
||||
>
|
||||
<Icon type="pin" className={iconClass} />
|
||||
@@ -326,7 +328,7 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
|
||||
onBlur={closeOnBlur}
|
||||
className="sn-dropdown-item"
|
||||
onClick={() => {
|
||||
appState.notes.setPinSelectedNotes(false)
|
||||
viewControllerManager.notesController.setPinSelectedNotes(false)
|
||||
}}
|
||||
>
|
||||
<Icon type="unpin" className={iconClass} />
|
||||
@@ -346,7 +348,7 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
|
||||
onBlur={closeOnBlur}
|
||||
className="sn-dropdown-item"
|
||||
onClick={() => {
|
||||
appState.notes.setArchiveSelectedNotes(true).catch(console.error)
|
||||
viewControllerManager.notesController.setArchiveSelectedNotes(true).catch(console.error)
|
||||
}}
|
||||
>
|
||||
<Icon type="archive" className={iconClassWarning} />
|
||||
@@ -358,7 +360,7 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
|
||||
onBlur={closeOnBlur}
|
||||
className="sn-dropdown-item"
|
||||
onClick={() => {
|
||||
appState.notes.setArchiveSelectedNotes(false).catch(console.error)
|
||||
viewControllerManager.notesController.setArchiveSelectedNotes(false).catch(console.error)
|
||||
}}
|
||||
>
|
||||
<Icon type="unarchive" className={iconClassWarning} />
|
||||
@@ -370,7 +372,7 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
|
||||
<DeletePermanentlyButton
|
||||
closeOnBlur={closeOnBlur}
|
||||
onClick={async () => {
|
||||
await appState.notes.deleteNotesPermanently()
|
||||
await viewControllerManager.notesController.deleteNotesPermanently()
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
@@ -378,7 +380,7 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
|
||||
onBlur={closeOnBlur}
|
||||
className="sn-dropdown-item"
|
||||
onClick={async () => {
|
||||
await appState.notes.setTrashSelectedNotes(true)
|
||||
await viewControllerManager.notesController.setTrashSelectedNotes(true)
|
||||
}}
|
||||
>
|
||||
<Icon type="trash" className={iconClassDanger} />
|
||||
@@ -391,7 +393,7 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
|
||||
onBlur={closeOnBlur}
|
||||
className="sn-dropdown-item"
|
||||
onClick={async () => {
|
||||
await appState.notes.setTrashSelectedNotes(false)
|
||||
await viewControllerManager.notesController.setTrashSelectedNotes(false)
|
||||
}}
|
||||
>
|
||||
<Icon type="restore" className={iconClassSuccess} />
|
||||
@@ -400,21 +402,21 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
|
||||
<DeletePermanentlyButton
|
||||
closeOnBlur={closeOnBlur}
|
||||
onClick={async () => {
|
||||
await appState.notes.deleteNotesPermanently()
|
||||
await viewControllerManager.notesController.deleteNotesPermanently()
|
||||
}}
|
||||
/>
|
||||
<button
|
||||
onBlur={closeOnBlur}
|
||||
className="sn-dropdown-item"
|
||||
onClick={async () => {
|
||||
await appState.notes.emptyTrash()
|
||||
await viewControllerManager.notesController.emptyTrash()
|
||||
}}
|
||||
>
|
||||
<div className="flex items-start">
|
||||
<Icon type="trash-sweep" className="color-danger mr-2" />
|
||||
<div className="flex-row">
|
||||
<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>
|
||||
</button>
|
||||
@@ -425,7 +427,7 @@ const NotesOptions = ({ application, appState, closeOnBlur }: NotesOptionsProps)
|
||||
<div className="min-h-1px my-2 bg-border"></div>
|
||||
<ListedActionsOption application={application} note={notes[0]} />
|
||||
<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>
|
||||
<NoteAttributes application={application} note={notes[0]} />
|
||||
<NoteSizeWarning note={notes[0]} />
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import Icon from '@/Components/Icon/Icon'
|
||||
import VisuallyHidden from '@reach/visually-hidden'
|
||||
import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur'
|
||||
@@ -6,16 +6,16 @@ import { Disclosure, DisclosureButton, DisclosurePanel } from '@reach/disclosure
|
||||
import { useRef, useState } from 'react'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import NotesOptions from './NotesOptions'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { FOCUSABLE_BUT_NOT_TABBABLE } from '@/Constants'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
onClickPreprocessing?: () => Promise<void>
|
||||
}
|
||||
|
||||
const NotesOptionsPanel = ({ application, appState, onClickPreprocessing }: Props) => {
|
||||
const NotesOptionsPanel = ({ application, viewControllerManager, onClickPreprocessing }: Props) => {
|
||||
const [open, setOpen] = useState(false)
|
||||
const [position, setPosition] = useState({
|
||||
top: 0,
|
||||
@@ -79,7 +79,13 @@ const NotesOptionsPanel = ({ application, appState, onClickPreprocessing }: Prop
|
||||
onBlur={closeOnBlur}
|
||||
tabIndex={FOCUSABLE_BUT_NOT_TABBABLE}
|
||||
>
|
||||
{open && <NotesOptions application={application} appState={appState} closeOnBlur={closeOnBlur} />}
|
||||
{open && (
|
||||
<NotesOptions
|
||||
application={application}
|
||||
viewControllerManager={viewControllerManager}
|
||||
closeOnBlur={closeOnBlur}
|
||||
/>
|
||||
)}
|
||||
</DisclosurePanel>
|
||||
</Disclosure>
|
||||
)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
|
||||
export type NotesOptionsProps = {
|
||||
application: WebApplication
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
closeOnBlur: (event: { relatedTarget: EventTarget | null }) => void
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import { useCallback, useRef } from 'react'
|
||||
import { AlertDialog, AlertDialogDescription, AlertDialogLabel } from '@reach/alert-dialog'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
}
|
||||
|
||||
const ConfirmOtherSessionsSignOut = observer(({ application, appState }: Props) => {
|
||||
const ConfirmOtherSessionsSignOut = observer(({ application, viewControllerManager }: Props) => {
|
||||
const cancelRef = useRef<HTMLButtonElement>(null)
|
||||
|
||||
const closeDialog = useCallback(() => {
|
||||
appState.accountMenu.setOtherSessionsSignOut(false)
|
||||
}, [appState])
|
||||
viewControllerManager.accountMenuController.setOtherSessionsSignOut(false)
|
||||
}, [viewControllerManager])
|
||||
|
||||
return (
|
||||
<AlertDialog onDismiss={closeDialog} leastDestructiveRef={cancelRef}>
|
||||
@@ -62,7 +62,7 @@ const ConfirmOtherSessionsSignOut = observer(({ application, appState }: Props)
|
||||
ConfirmOtherSessionsSignOut.displayName = 'ConfirmOtherSessionsSignOut'
|
||||
|
||||
const OtherSessionsSignOutContainer = (props: Props) => {
|
||||
if (!props.appState.accountMenu.otherSessionsSignOut) {
|
||||
if (!props.viewControllerManager.accountMenuController.otherSessionsSignOut) {
|
||||
return null
|
||||
}
|
||||
return <ConfirmOtherSessionsSignOut {...props} />
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ChangeEventHandler, createRef } from 'react'
|
||||
import { PureComponent } from '@/Components/Abstract/PureComponent'
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { SNComponent } from '@standardnotes/snjs'
|
||||
import { Component } from 'react'
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ApplicationEvent, PermissionDialog } from '@standardnotes/snjs'
|
||||
import { FunctionComponent, useCallback, useEffect, useState } from 'react'
|
||||
import PermissionsModal from './PermissionsModal'
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import VisuallyHidden from '@reach/visually-hidden'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { FunctionComponent, useCallback } from 'react'
|
||||
import Icon from '@/Components/Icon/Icon'
|
||||
|
||||
type Props = {
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
className?: string
|
||||
onClickPreprocessing?: () => Promise<void>
|
||||
}
|
||||
|
||||
const PinNoteButton: FunctionComponent<Props> = ({ appState, className = '', onClickPreprocessing }: Props) => {
|
||||
const notes = appState.notes.selectedNotes
|
||||
const PinNoteButton: FunctionComponent<Props> = ({
|
||||
viewControllerManager,
|
||||
className = '',
|
||||
onClickPreprocessing,
|
||||
}: Props) => {
|
||||
const notes = viewControllerManager.notesController.selectedNotes
|
||||
const pinned = notes.some((note) => note.pinned)
|
||||
|
||||
const togglePinned = useCallback(async () => {
|
||||
@@ -19,11 +23,11 @@ const PinNoteButton: FunctionComponent<Props> = ({ appState, className = '', onC
|
||||
await onClickPreprocessing()
|
||||
}
|
||||
if (!pinned) {
|
||||
appState.notes.setPinSelectedNotes(true)
|
||||
viewControllerManager.notesController.setPinSelectedNotes(true)
|
||||
} else {
|
||||
appState.notes.setPinSelectedNotes(false)
|
||||
viewControllerManager.notesController.setPinSelectedNotes(false)
|
||||
}
|
||||
}, [appState, onClickPreprocessing, pinned])
|
||||
}, [viewControllerManager, onClickPreprocessing, pinned])
|
||||
|
||||
return (
|
||||
<button className={`sn-icon-button border-contrast ${pinned ? 'toggled' : ''} ${className}`} onClick={togglePinned}>
|
||||
|
||||
@@ -12,7 +12,7 @@ import { PreferencesProps } from './PreferencesProps'
|
||||
|
||||
const PaneSelector: FunctionComponent<PreferencesProps & { menu: PreferencesMenu }> = ({
|
||||
menu,
|
||||
appState,
|
||||
viewControllerManager,
|
||||
application,
|
||||
mfaProvider,
|
||||
userProvider,
|
||||
@@ -21,21 +21,26 @@ const PaneSelector: FunctionComponent<PreferencesProps & { menu: PreferencesMenu
|
||||
case 'general':
|
||||
return (
|
||||
<General
|
||||
appState={appState}
|
||||
viewControllerManager={viewControllerManager}
|
||||
application={application}
|
||||
extensionsLatestVersions={menu.extensionsLatestVersions}
|
||||
/>
|
||||
)
|
||||
case 'account':
|
||||
return <AccountPreferences application={application} appState={appState} />
|
||||
return <AccountPreferences application={application} viewControllerManager={viewControllerManager} />
|
||||
case 'appearance':
|
||||
return <Appearance application={application} />
|
||||
case 'security':
|
||||
return (
|
||||
<Security mfaProvider={mfaProvider} userProvider={userProvider} appState={appState} application={application} />
|
||||
<Security
|
||||
mfaProvider={mfaProvider}
|
||||
userProvider={userProvider}
|
||||
viewControllerManager={viewControllerManager}
|
||||
application={application}
|
||||
/>
|
||||
)
|
||||
case 'backups':
|
||||
return <Backups application={application} appState={appState} />
|
||||
return <Backups application={application} viewControllerManager={viewControllerManager} />
|
||||
case 'listed':
|
||||
return <Listed application={application} />
|
||||
case 'shortcuts':
|
||||
@@ -49,7 +54,7 @@ const PaneSelector: FunctionComponent<PreferencesProps & { menu: PreferencesMenu
|
||||
default:
|
||||
return (
|
||||
<General
|
||||
appState={appState}
|
||||
viewControllerManager={viewControllerManager}
|
||||
application={application}
|
||||
extensionsLatestVersions={menu.extensionsLatestVersions}
|
||||
/>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import Authentication from './Authentication'
|
||||
import Credentials from './Credentials'
|
||||
import Sync from './Sync'
|
||||
@@ -11,22 +11,24 @@ import PreferencesPane from '../../PreferencesComponents/PreferencesPane'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
}
|
||||
|
||||
const AccountPreferences = ({ application, appState }: Props) => (
|
||||
const AccountPreferences = ({ application, viewControllerManager }: Props) => (
|
||||
<PreferencesPane>
|
||||
{!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} />
|
||||
</>
|
||||
)}
|
||||
<Subscription application={application} appState={appState} />
|
||||
{application.hasAccount() && appState.features.hasFiles && <FilesSection application={application} />}
|
||||
<SignOutWrapper application={application} appState={appState} />
|
||||
<Subscription application={application} viewControllerManager={viewControllerManager} />
|
||||
{application.hasAccount() && viewControllerManager.featuresController.hasFiles && (
|
||||
<FilesSection application={application} />
|
||||
)}
|
||||
<SignOutWrapper application={application} viewControllerManager={viewControllerManager} />
|
||||
</PreferencesPane>
|
||||
)
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { FunctionComponent } from 'react'
|
||||
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 { AppState } from '@/UIModels/AppState'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import Extensions from '@/Components/Preferences/Panes/Extensions/Extensions'
|
||||
import { ExtensionsLatestVersions } from '@/Components/Preferences/Panes/Extensions/ExtensionsLatestVersions'
|
||||
import AccordionItem from '@/Components/Shared/AccordionItem'
|
||||
@@ -11,18 +11,18 @@ import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
extensionsLatestVersions: ExtensionsLatestVersions
|
||||
}
|
||||
|
||||
const Advanced: FunctionComponent<Props> = ({ application, appState, extensionsLatestVersions }) => {
|
||||
const Advanced: FunctionComponent<Props> = ({ application, viewControllerManager, extensionsLatestVersions }) => {
|
||||
return (
|
||||
<PreferencesGroup>
|
||||
<PreferencesSegment>
|
||||
<AccordionItem title={'Advanced Settings'}>
|
||||
<div className="flex flex-row items-center">
|
||||
<div className="flex-grow flex flex-col">
|
||||
<OfflineSubscription application={application} appState={appState} />
|
||||
<OfflineSubscription application={application} viewControllerManager={viewControllerManager} />
|
||||
<Extensions
|
||||
className={'mt-3'}
|
||||
application={application}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Button from '@/Components/Button/Button'
|
||||
import { Text, Title } from '@/Components/Preferences/PreferencesComponents/Content'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { FunctionComponent } from 'react'
|
||||
import { AccountIllustration } from '@standardnotes/icons'
|
||||
@@ -11,20 +11,20 @@ import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
}
|
||||
|
||||
const Authentication: FunctionComponent<Props> = ({ appState }) => {
|
||||
const Authentication: FunctionComponent<Props> = ({ viewControllerManager }) => {
|
||||
const clickSignIn = () => {
|
||||
appState.preferences.closePreferences()
|
||||
appState.accountMenu.setCurrentPane(AccountMenuPane.SignIn)
|
||||
appState.accountMenu.setShow(true)
|
||||
viewControllerManager.preferencesController.closePreferences()
|
||||
viewControllerManager.accountMenuController.setCurrentPane(AccountMenuPane.SignIn)
|
||||
viewControllerManager.accountMenuController.setShow(true)
|
||||
}
|
||||
|
||||
const clickRegister = () => {
|
||||
appState.preferences.closePreferences()
|
||||
appState.accountMenu.setCurrentPane(AccountMenuPane.Register)
|
||||
appState.accountMenu.setShow(true)
|
||||
viewControllerManager.preferencesController.closePreferences()
|
||||
viewControllerManager.accountMenuController.setCurrentPane(AccountMenuPane.Register)
|
||||
viewControllerManager.accountMenuController.setShow(true)
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -4,7 +4,7 @@ import ModalDialogDescription from '@/Components/Shared/ModalDialogDescription'
|
||||
import ModalDialogLabel from '@/Components/Shared/ModalDialogLabel'
|
||||
import Button from '@/Components/Button/Button'
|
||||
import { FunctionComponent, useState } from 'react'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { useBeforeUnload } from '@/Hooks/useBeforeUnload'
|
||||
import ChangeEmailForm from './ChangeEmailForm'
|
||||
import ChangeEmailSuccess from './ChangeEmailSuccess'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import Button from '@/Components/Button/Button'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { FunctionComponent } from 'react'
|
||||
import { Title, Text } from '../../PreferencesComponents/Content'
|
||||
@@ -7,8 +7,8 @@ import PreferencesGroup from '../../PreferencesComponents/PreferencesGroup'
|
||||
import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment'
|
||||
|
||||
const ClearSessionDataView: FunctionComponent<{
|
||||
appState: AppState
|
||||
}> = ({ appState }) => {
|
||||
viewControllerManager: ViewControllerManager
|
||||
}> = ({ viewControllerManager }) => {
|
||||
return (
|
||||
<PreferencesGroup>
|
||||
<PreferencesSegment>
|
||||
@@ -19,7 +19,7 @@ const ClearSessionDataView: FunctionComponent<{
|
||||
dangerStyle={true}
|
||||
label="Clear workspace"
|
||||
onClick={() => {
|
||||
appState.accountMenu.setSigningOut(true)
|
||||
viewControllerManager.accountMenuController.setSigningOut(true)
|
||||
}}
|
||||
/>
|
||||
</PreferencesSegment>
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { Subtitle, Text, Title } from '@/Components/Preferences/PreferencesComponents/Content'
|
||||
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 HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
|
||||
import { dateToLocalizedString } from '@standardnotes/snjs'
|
||||
import { useCallback, useState, FunctionComponent } from 'react'
|
||||
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 PreferencesGroup from '../../PreferencesComponents/PreferencesGroup'
|
||||
import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
}
|
||||
|
||||
const Credentials: FunctionComponent<Props> = ({ application }: Props) => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { formatSizeToReadableString } from '@standardnotes/filepicker'
|
||||
import { SubscriptionSettingName } from '@standardnotes/snjs'
|
||||
import { FunctionComponent, useEffect, useState } from 'react'
|
||||
|
||||
@@ -2,8 +2,8 @@ import React, { FunctionComponent, useEffect, useState } from 'react'
|
||||
import { Subtitle } from '@/Components/Preferences/PreferencesComponents/Content'
|
||||
import DecoratedInput from '@/Components/Input/DecoratedInput'
|
||||
import Button from '@/Components/Button/Button'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { STRING_REMOVE_OFFLINE_KEY_CONFIRMATION } from '@/Strings'
|
||||
import { ButtonType, ClientDisplayableError } from '@standardnotes/snjs'
|
||||
@@ -11,7 +11,7 @@ import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
}
|
||||
|
||||
const OfflineSubscription: FunctionComponent<Props> = ({ application }) => {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import Button from '@/Components/Button/Button'
|
||||
import OtherSessionsSignOutContainer from '@/Components/OtherSessionsSignOut/OtherSessionsSignOut'
|
||||
import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { FunctionComponent } from 'react'
|
||||
import { Subtitle, Title, Text } from '../../PreferencesComponents/Content'
|
||||
@@ -12,10 +12,10 @@ import ClearSessionDataView from './ClearSessionDataView'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
}
|
||||
|
||||
const SignOutView: FunctionComponent<Props> = observer(({ application, appState }) => {
|
||||
const SignOutView: FunctionComponent<Props> = observer(({ application, viewControllerManager }) => {
|
||||
return (
|
||||
<>
|
||||
<PreferencesGroup>
|
||||
@@ -30,10 +30,14 @@ const SignOutView: FunctionComponent<Props> = observer(({ application, appState
|
||||
variant="normal"
|
||||
label="Sign out other sessions"
|
||||
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>
|
||||
</PreferencesSegment>
|
||||
<HorizontalSeparator classes="my-4" />
|
||||
@@ -45,23 +49,23 @@ const SignOutView: FunctionComponent<Props> = observer(({ application, appState
|
||||
dangerStyle={true}
|
||||
label="Sign out workspace"
|
||||
onClick={() => {
|
||||
appState.accountMenu.setSigningOut(true)
|
||||
viewControllerManager.accountMenuController.setSigningOut(true)
|
||||
}}
|
||||
/>
|
||||
</PreferencesSegment>
|
||||
</PreferencesGroup>
|
||||
<OtherSessionsSignOutContainer appState={appState} application={application} />
|
||||
<OtherSessionsSignOutContainer viewControllerManager={viewControllerManager} application={application} />
|
||||
</>
|
||||
)
|
||||
})
|
||||
|
||||
SignOutView.displayName = 'SignOutView'
|
||||
|
||||
const SignOutWrapper: FunctionComponent<Props> = ({ application, appState }) => {
|
||||
const SignOutWrapper: FunctionComponent<Props> = ({ application, viewControllerManager }) => {
|
||||
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)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { FunctionComponent, useState } from 'react'
|
||||
import { LinkButton, Text } from '@/Components/Preferences/PreferencesComponents/Content'
|
||||
import Button from '@/Components/Button/Button'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { loadPurchaseFlowUrl } from '@/Components/PurchaseFlow/PurchaseFlowFunctions'
|
||||
|
||||
type Props = {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { SubscriptionState } from '@/UIModels/AppState/SubscriptionState'
|
||||
import { SubscriptionController } from '@/Controllers/Subscription/SubscriptionController'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { Text } from '@/Components/Preferences/PreferencesComponents/Content'
|
||||
|
||||
type Props = { subscriptionState: SubscriptionState }
|
||||
type Props = { subscriptionState: SubscriptionController }
|
||||
|
||||
const StatusText = ({ subscriptionState }: Props) => {
|
||||
const {
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import { Title } from '@/Components/Preferences/PreferencesComponents/Content'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import SubscriptionInformation from './SubscriptionInformation'
|
||||
import NoSubscription from './NoSubscription'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { FunctionComponent } from 'react'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import PreferencesGroup from '@/Components/Preferences/PreferencesComponents/PreferencesGroup'
|
||||
import PreferencesSegment from '@/Components/Preferences/PreferencesComponents/PreferencesSegment'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
}
|
||||
|
||||
const Subscription: FunctionComponent<Props> = ({ application, appState }: Props) => {
|
||||
const subscriptionState = appState.subscription
|
||||
const Subscription: FunctionComponent<Props> = ({ application, viewControllerManager }: Props) => {
|
||||
const subscriptionState = viewControllerManager.subscriptionController
|
||||
const { userSubscription } = subscriptionState
|
||||
|
||||
const now = new Date().getTime()
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
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 { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { openSubscriptionDashboard } from '@/Utils/ManageSubscription'
|
||||
import StatusText from './StatusText'
|
||||
|
||||
type Props = {
|
||||
subscriptionState: SubscriptionState
|
||||
subscriptionState: SubscriptionController
|
||||
application: WebApplication
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import Button from '@/Components/Button/Button'
|
||||
import { SyncQueueStrategy } from '@standardnotes/snjs'
|
||||
import { STRING_GENERIC_SYNC_ERROR } from '@/Strings'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { FunctionComponent, useState } from 'react'
|
||||
import { formatLastSyncDate } from '@/Utils/FormatLastSyncDate'
|
||||
import PreferencesGroup from '../../PreferencesComponents/PreferencesGroup'
|
||||
|
||||
@@ -3,7 +3,7 @@ import { DropdownItem } from '@/Components/Dropdown/DropdownItem'
|
||||
import { usePremiumModal } from '@/Hooks/usePremiumModal'
|
||||
import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
|
||||
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 { observer } from 'mobx-react-lite'
|
||||
import { FunctionComponent, useEffect, useState } from 'react'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { FunctionComponent } from 'react'
|
||||
import PreferencesPane from '@/Components/Preferences/PreferencesComponents/PreferencesPane'
|
||||
import CloudLink from './CloudBackups/CloudBackups'
|
||||
@@ -9,14 +9,14 @@ import FileBackupsCrossPlatform from './Files/FileBackupsCrossPlatform'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
|
||||
type Props = {
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
application: WebApplication
|
||||
}
|
||||
|
||||
const Backups: FunctionComponent<Props> = ({ application, appState }) => {
|
||||
const Backups: FunctionComponent<Props> = ({ application, viewControllerManager }) => {
|
||||
return (
|
||||
<PreferencesPane>
|
||||
<DataBackups application={application} appState={appState} />
|
||||
<DataBackups application={application} viewControllerManager={viewControllerManager} />
|
||||
<FileBackupsCrossPlatform application={application} />
|
||||
<EmailBackups application={application} />
|
||||
<CloudLink application={application} />
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
GoogleDriveBackupFrequency,
|
||||
OneDriveBackupFrequency,
|
||||
} from '@standardnotes/snjs'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import Button from '@/Components/Button/Button'
|
||||
import { isDev, openInNewTab } from '@/Utils'
|
||||
import { Subtitle } from '@/Components/Preferences/PreferencesComponents/Content'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import CloudBackupProvider from './CloudBackupProvider'
|
||||
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 HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
|
||||
import {
|
||||
|
||||
@@ -12,8 +12,8 @@ import {
|
||||
} from '@/Strings'
|
||||
import { BackupFile } from '@standardnotes/snjs'
|
||||
import { ChangeEventHandler, MouseEventHandler, useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { Title, Text, Subtitle } from '@/Components/Preferences/PreferencesComponents/Content'
|
||||
import Button from '@/Components/Button/Button'
|
||||
@@ -23,10 +23,10 @@ import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
}
|
||||
|
||||
const DataBackups = ({ application, appState }: Props) => {
|
||||
const DataBackups = ({ application, viewControllerManager }: Props) => {
|
||||
const fileInputRef = useRef<HTMLInputElement>(null)
|
||||
const [isImportDataLoading, setIsImportDataLoading] = useState(false)
|
||||
const {
|
||||
@@ -35,7 +35,7 @@ const DataBackups = ({ application, appState }: Props) => {
|
||||
setIsBackupEncrypted,
|
||||
setIsEncryptionEnabled,
|
||||
setEncryptionStatusString,
|
||||
} = appState.accountMenu
|
||||
} = viewControllerManager.accountMenuController
|
||||
|
||||
const refreshEncryptionStatus = useCallback(() => {
|
||||
const hasUser = application.hasAccount()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { convertStringifiedBooleanToBoolean, isDesktopApplication } from '@/Utils'
|
||||
import { STRING_FAILED_TO_UPDATE_USER_SETTING } from '@/Strings'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { Subtitle, Text, Title } from '@/Components/Preferences/PreferencesComponents/Content'
|
||||
import Dropdown from '@/Components/Dropdown/Dropdown'
|
||||
|
||||
@@ -6,7 +6,7 @@ import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
|
||||
import Icon from '@/Components/Icon/Icon'
|
||||
import { StreamingFileApi } from '@standardnotes/filepicker'
|
||||
import { isHandlingBackupDrag } from '@/Utils/DragTypeCheck'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import EncryptionStatusItem from '../../Security/EncryptionStatusItem'
|
||||
import PreferencesSegment from '@/Components/Preferences/PreferencesComponents/PreferencesSegment'
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Subtitle, Title, Text } from '@/Components/Preferences/PreferencesComponents/Content'
|
||||
import PreferencesGroup from '@/Components/Preferences/PreferencesComponents/PreferencesGroup'
|
||||
import PreferencesSegment from '@/Components/Preferences/PreferencesComponents/PreferencesSegment'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { useMemo } from 'react'
|
||||
import BackupsDropZone from './BackupsDropZone'
|
||||
import FileBackupsDesktop from './FileBackupsDesktop'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { Title, Text, Subtitle } from '@/Components/Preferences/PreferencesComponents/Content'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { AnyExtension } from './AnyExtension'
|
||||
|
||||
export interface ExtensionItemProps {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ButtonType, ContentType, SNComponent } from '@standardnotes/snjs'
|
||||
import Button from '@/Components/Button/Button'
|
||||
import DecoratedInput from '@/Components/Input/DecoratedInput'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { FunctionComponent, useEffect, useRef, useState } from 'react'
|
||||
import { Title } from '@/Components/Preferences/PreferencesComponents/Content'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ClientDisplayableError, FeatureDescription } from '@standardnotes/snjs'
|
||||
import { makeAutoObservable, observable } from 'mobx'
|
||||
import { AnyExtension } from './AnyExtension'
|
||||
|
||||
@@ -2,7 +2,7 @@ import Dropdown from '@/Components/Dropdown/Dropdown'
|
||||
import { DropdownItem } from '@/Components/Dropdown/DropdownItem'
|
||||
import { FeatureIdentifier, PrefKey, ComponentArea, ComponentMutator, SNComponent } from '@standardnotes/snjs'
|
||||
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 HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
|
||||
import Switch from '@/Components/Switch/Switch'
|
||||
@@ -57,7 +57,7 @@ const Defaults: FunctionComponent<Props> = ({ application }) => {
|
||||
|
||||
const toggleSpellcheck = () => {
|
||||
setSpellcheck(!spellcheck)
|
||||
application.getAppState().toggleGlobalSpellcheck().catch(console.error)
|
||||
application.getViewControllerManager().toggleGlobalSpellcheck().catch(console.error)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { FunctionComponent } from 'react'
|
||||
import { ExtensionsLatestVersions } from '@/Components/Preferences/Panes/Extensions/ExtensionsLatestVersions'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
@@ -10,17 +10,21 @@ import Advanced from '@/Components/Preferences/Panes/Account/Advanced'
|
||||
import PreferencesPane from '../../PreferencesComponents/PreferencesPane'
|
||||
|
||||
type Props = {
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
application: WebApplication
|
||||
extensionsLatestVersions: ExtensionsLatestVersions
|
||||
}
|
||||
|
||||
const General: FunctionComponent<Props> = ({ appState, application, extensionsLatestVersions }) => (
|
||||
const General: FunctionComponent<Props> = ({ viewControllerManager, application, extensionsLatestVersions }) => (
|
||||
<PreferencesPane>
|
||||
<Tools application={application} />
|
||||
<Defaults application={application} />
|
||||
<LabsPane application={application} />
|
||||
<Advanced application={application} appState={appState} extensionsLatestVersions={extensionsLatestVersions} />
|
||||
<Advanced
|
||||
application={application}
|
||||
viewControllerManager={viewControllerManager}
|
||||
extensionsLatestVersions={extensionsLatestVersions}
|
||||
/>
|
||||
</PreferencesPane>
|
||||
)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Switch from '@/Components/Switch/Switch'
|
||||
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 { Fragment, FunctionComponent, useCallback, useEffect, useState } from 'react'
|
||||
import { usePremiumModal } from '@/Hooks/usePremiumModal'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
|
||||
import Switch from '@/Components/Switch/Switch'
|
||||
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 { observer } from 'mobx-react-lite'
|
||||
import { FunctionComponent, useState } from 'react'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Title, Subtitle, Text } from '@/Components/Preferences/PreferencesComponents/Content'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ButtonType, ListedAccount } from '@standardnotes/snjs'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import ListedAccountItem from './ListedAccountItem'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
|
||||
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 { FunctionComponent, useEffect, useState } from 'react'
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
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 { FunctionComponent } from 'react'
|
||||
import { Title, Text } from '../../PreferencesComponents/Content'
|
||||
@@ -7,10 +7,10 @@ import PreferencesGroup from '../../PreferencesComponents/PreferencesGroup'
|
||||
import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment'
|
||||
import EncryptionEnabled from './EncryptionEnabled'
|
||||
|
||||
type Props = { appState: AppState }
|
||||
type Props = { viewControllerManager: ViewControllerManager }
|
||||
|
||||
const Encryption: FunctionComponent<Props> = ({ appState }) => {
|
||||
const app = appState.application
|
||||
const Encryption: FunctionComponent<Props> = ({ viewControllerManager }) => {
|
||||
const app = viewControllerManager.application
|
||||
const hasUser = app.hasAccount()
|
||||
const hasPasscode = app.hasPasscode()
|
||||
const isEncryptionEnabled = app.isEncryptionAvailable()
|
||||
@@ -27,7 +27,7 @@ const Encryption: FunctionComponent<Props> = ({ appState }) => {
|
||||
<Title>Encryption</Title>
|
||||
<Text>{encryptionStatusString}</Text>
|
||||
|
||||
{isEncryptionEnabled && <EncryptionEnabled appState={appState} />}
|
||||
{isEncryptionEnabled && <EncryptionEnabled viewControllerManager={viewControllerManager} />}
|
||||
</PreferencesSegment>
|
||||
</PreferencesGroup>
|
||||
)
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import Icon from '@/Components/Icon/Icon'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { FunctionComponent } from 'react'
|
||||
import EncryptionStatusItem from './EncryptionStatusItem'
|
||||
import { formatCount } from './formatCount'
|
||||
|
||||
type Props = {
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
}
|
||||
|
||||
const EncryptionEnabled: FunctionComponent<Props> = ({ appState }) => {
|
||||
const count = appState.accountMenu.structuredNotesAndTagsCount
|
||||
const EncryptionEnabled: FunctionComponent<Props> = ({ viewControllerManager }) => {
|
||||
const count = viewControllerManager.accountMenuController.structuredNotesAndTagsCount
|
||||
const notes = formatCount(count.notes, 'notes')
|
||||
const tags = formatCount(count.tags, 'tags')
|
||||
const archived = formatCount(count.archived, 'archived notes')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { Fragment, FunctionComponent, useState } from 'react'
|
||||
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 PreferencesGroup from '../../PreferencesComponents/PreferencesGroup'
|
||||
|
||||
type Props = { appState: AppState }
|
||||
type Props = { viewControllerManager: ViewControllerManager }
|
||||
|
||||
const ErroredItems: FunctionComponent<Props> = ({ appState }: Props) => {
|
||||
const app = appState.application
|
||||
const ErroredItems: FunctionComponent<Props> = ({ viewControllerManager }: Props) => {
|
||||
const app = viewControllerManager.application
|
||||
|
||||
const [erroredItems, setErroredItems] = useState(app.items.invalidItems)
|
||||
|
||||
|
||||
@@ -8,13 +8,13 @@ import {
|
||||
StringUtils,
|
||||
Strings,
|
||||
} from '@/Strings'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { preventRefreshing } from '@/Utils'
|
||||
import { alertDialog } from '@/Services/AlertService'
|
||||
import { ChangeEventHandler, FormEvent, useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { ApplicationEvent } from '@standardnotes/snjs'
|
||||
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 Button from '@/Components/Button/Button'
|
||||
import PreferencesGroup from '../../PreferencesComponents/PreferencesGroup'
|
||||
@@ -22,14 +22,15 @@ import PreferencesSegment from '../../PreferencesComponents/PreferencesSegment'
|
||||
|
||||
type Props = {
|
||||
application: WebApplication
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
}
|
||||
|
||||
const PasscodeLock = ({ application, appState }: Props) => {
|
||||
const PasscodeLock = ({ application, viewControllerManager }: Props) => {
|
||||
const keyStorageInfo = StringUtils.keyStorageInfo(application)
|
||||
const passcodeAutoLockOptions = application.getAutolockService().getAutoLockIntervalOptions()
|
||||
|
||||
const { setIsEncryptionEnabled, setIsBackupEncrypted, setEncryptionStatusString } = appState.accountMenu
|
||||
const { setIsEncryptionEnabled, setIsBackupEncrypted, setEncryptionStatusString } =
|
||||
viewControllerManager.accountMenuController
|
||||
|
||||
const passcodeInputRef = useRef<HTMLInputElement>(null)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import HorizontalSeparator from '@/Components/Shared/HorizontalSeparator'
|
||||
import Switch from '@/Components/Switch/Switch'
|
||||
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 { observer } from 'mobx-react-lite'
|
||||
import { FunctionComponent, useCallback, useEffect, useState } from 'react'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { FunctionComponent, useCallback, useState, useEffect } from 'react'
|
||||
import { ApplicationEvent } from '@standardnotes/snjs'
|
||||
import { isSameDay } from '@/Utils'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { AppState } from '@/UIModels/AppState'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ViewControllerManager } from '@/Services/ViewControllerManager'
|
||||
import { FunctionComponent } from 'react'
|
||||
import TwoFactorAuthWrapper from '../TwoFactorAuth/TwoFactorAuthWrapper'
|
||||
import { MfaProps } from '../TwoFactorAuth/MfaProps'
|
||||
@@ -11,17 +11,19 @@ import ErroredItems from './ErroredItems'
|
||||
import PreferencesPane from '@/Components/Preferences/PreferencesComponents/PreferencesPane'
|
||||
|
||||
interface SecurityProps extends MfaProps {
|
||||
appState: AppState
|
||||
viewControllerManager: ViewControllerManager
|
||||
application: WebApplication
|
||||
}
|
||||
|
||||
const Security: FunctionComponent<SecurityProps> = (props) => (
|
||||
<PreferencesPane>
|
||||
<Encryption appState={props.appState} />
|
||||
{props.application.items.invalidItems.length > 0 && <ErroredItems appState={props.appState} />}
|
||||
<Encryption viewControllerManager={props.viewControllerManager} />
|
||||
{props.application.items.invalidItems.length > 0 && (
|
||||
<ErroredItems viewControllerManager={props.viewControllerManager} />
|
||||
)}
|
||||
<Protections application={props.application} />
|
||||
<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} />}
|
||||
</PreferencesPane>
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
|
||||
export const securityPrefsHasBubble = (application: WebApplication): boolean => {
|
||||
return application.items.invalidItems.length > 0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { action, makeAutoObservable, observable } from 'mobx'
|
||||
import { IconType } from '@standardnotes/snjs'
|
||||
import { WebApplication } from '@/UIModels/Application'
|
||||
import { WebApplication } from '@/Application/Application'
|
||||
import { ExtensionsLatestVersions } from './Panes/Extensions/ExtensionsLatestVersions'
|
||||
import { securityPrefsHasBubble } from './Panes/Security/securityPrefsHasBubble'
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user