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