fix(mobile): Fixed issue where pressing the back button on editor screen wouldn't switch back to the items list on Android
This commit is contained in:
@@ -17,4 +17,5 @@ export interface WebApplicationInterface extends ApplicationInterface {
|
|||||||
mobileDevice(): MobileDeviceInterface
|
mobileDevice(): MobileDeviceInterface
|
||||||
handleAndroidBackButtonPressed(): void
|
handleAndroidBackButtonPressed(): void
|
||||||
addAndroidBackHandlerEventListener(listener: () => boolean): (() => void) | undefined
|
addAndroidBackHandlerEventListener(listener: () => boolean): (() => void) | undefined
|
||||||
|
setAndroidBackHandlerFallbackListener(listener: () => boolean): void
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -369,6 +369,12 @@ export class WebApplication extends SNApplication implements WebApplicationInter
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setAndroidBackHandlerFallbackListener(listener: () => boolean) {
|
||||||
|
if (typeof this.androidBackHandler !== 'undefined') {
|
||||||
|
this.androidBackHandler.setFallbackListener(listener)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
isAuthorizedToRenderItem(item: DecryptedItem): boolean {
|
isAuthorizedToRenderItem(item: DecryptedItem): boolean {
|
||||||
if (item.protected && this.hasProtectionSources()) {
|
if (item.protected && this.hasProtectionSources()) {
|
||||||
return this.hasUnprotectedAccessSession()
|
return this.hasUnprotectedAccessSession()
|
||||||
|
|||||||
@@ -7,13 +7,13 @@ import ListItemTags from './ListItemTags'
|
|||||||
import ListItemMetadata from './ListItemMetadata'
|
import ListItemMetadata from './ListItemMetadata'
|
||||||
import { DisplayableListItemProps } from './Types/DisplayableListItemProps'
|
import { DisplayableListItemProps } from './Types/DisplayableListItemProps'
|
||||||
import { useResponsiveAppPane } from '../Panes/ResponsivePaneProvider'
|
import { useResponsiveAppPane } from '../Panes/ResponsivePaneProvider'
|
||||||
import { AppPaneId } from '../Panes/AppPaneMetadata'
|
|
||||||
import { useContextMenuEvent } from '@/Hooks/useContextMenuEvent'
|
import { useContextMenuEvent } from '@/Hooks/useContextMenuEvent'
|
||||||
import { classNames } from '@standardnotes/utils'
|
import { classNames } from '@standardnotes/utils'
|
||||||
import { formatSizeToReadableString } from '@standardnotes/filepicker'
|
import { formatSizeToReadableString } from '@standardnotes/filepicker'
|
||||||
import { getIconForFileType } from '@/Utils/Items/Icons/getIconForFileType'
|
import { getIconForFileType } from '@/Utils/Items/Icons/getIconForFileType'
|
||||||
import { useApplication } from '../ApplicationProvider'
|
import { useApplication } from '../ApplicationProvider'
|
||||||
import Icon from '../Icon/Icon'
|
import Icon from '../Icon/Icon'
|
||||||
|
import { PaneLayout } from '@/Controllers/PaneController/PaneLayout'
|
||||||
|
|
||||||
const FileListItem: FunctionComponent<DisplayableListItemProps<FileItem>> = ({
|
const FileListItem: FunctionComponent<DisplayableListItemProps<FileItem>> = ({
|
||||||
filesController,
|
filesController,
|
||||||
@@ -26,7 +26,7 @@ const FileListItem: FunctionComponent<DisplayableListItemProps<FileItem>> = ({
|
|||||||
sortBy,
|
sortBy,
|
||||||
tags,
|
tags,
|
||||||
}) => {
|
}) => {
|
||||||
const { toggleAppPane } = useResponsiveAppPane()
|
const { setPaneLayout } = useResponsiveAppPane()
|
||||||
const application = useApplication()
|
const application = useApplication()
|
||||||
|
|
||||||
const [backupInfo, setBackupInfo] = useState<FileBackupRecord | undefined>(undefined)
|
const [backupInfo, setBackupInfo] = useState<FileBackupRecord | undefined>(undefined)
|
||||||
@@ -70,9 +70,9 @@ const FileListItem: FunctionComponent<DisplayableListItemProps<FileItem>> = ({
|
|||||||
const onClick = useCallback(async () => {
|
const onClick = useCallback(async () => {
|
||||||
const { didSelect } = await onSelect(file, true)
|
const { didSelect } = await onSelect(file, true)
|
||||||
if (didSelect) {
|
if (didSelect) {
|
||||||
toggleAppPane(AppPaneId.Editor)
|
setPaneLayout(PaneLayout.Editing)
|
||||||
}
|
}
|
||||||
}, [file, onSelect, toggleAppPane])
|
}, [file, onSelect, setPaneLayout])
|
||||||
|
|
||||||
const IconComponent = () =>
|
const IconComponent = () =>
|
||||||
getFileIconComponent(getIconForFileType((file as FileItem).mimeType), 'w-10 h-10 flex-shrink-0')
|
getFileIconComponent(getIconForFileType((file as FileItem).mimeType), 'w-10 h-10 flex-shrink-0')
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
import { AppPaneId } from './AppPaneMetadata'
|
import { AppPaneId } from './AppPaneMetadata'
|
||||||
import { PaneController } from '../../Controllers/PaneController/PaneController'
|
import { PaneController } from '../../Controllers/PaneController/PaneController'
|
||||||
import { observer } from 'mobx-react-lite'
|
import { observer } from 'mobx-react-lite'
|
||||||
|
import { PaneLayout } from '@/Controllers/PaneController/PaneLayout'
|
||||||
|
|
||||||
type ResponsivePaneData = {
|
type ResponsivePaneData = {
|
||||||
selectedPane: AppPaneId
|
selectedPane: AppPaneId
|
||||||
@@ -84,7 +85,7 @@ const ResponsivePaneProvider = ({ paneController, children }: ProviderProps) =>
|
|||||||
currentSelectedPaneRef.current === AppPaneId.Editor ||
|
currentSelectedPaneRef.current === AppPaneId.Editor ||
|
||||||
currentSelectedPaneRef.current === AppPaneId.Navigation
|
currentSelectedPaneRef.current === AppPaneId.Navigation
|
||||||
) {
|
) {
|
||||||
toggleAppPane(AppPaneId.Items)
|
paneController.setPaneLayout(PaneLayout.ItemSelection)
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
@@ -95,7 +96,7 @@ const ResponsivePaneProvider = ({ paneController, children }: ProviderProps) =>
|
|||||||
removeListener()
|
removeListener()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [addAndroidBackHandler, currentSelectedPaneRef, toggleAppPane])
|
}, [addAndroidBackHandler, currentSelectedPaneRef, paneController])
|
||||||
|
|
||||||
const contextValue = useMemo(
|
const contextValue = useMemo(
|
||||||
(): ResponsivePaneData => ({
|
(): ResponsivePaneData => ({
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import { WebApplication } from '@/Application/Application'
|
|||||||
import { ApplicationEvent, PrefKey, WebAppEvent } from '@standardnotes/snjs'
|
import { ApplicationEvent, PrefKey, WebAppEvent } from '@standardnotes/snjs'
|
||||||
import { observer } from 'mobx-react-lite'
|
import { observer } from 'mobx-react-lite'
|
||||||
import { forwardRef, useEffect, useMemo, useState } from 'react'
|
import { forwardRef, useEffect, useMemo, useState } from 'react'
|
||||||
import { AppPaneId } from '@/Components/Panes/AppPaneMetadata'
|
|
||||||
import { classNames } from '@standardnotes/utils'
|
import { classNames } from '@standardnotes/utils'
|
||||||
import { useResponsiveAppPane } from '../Panes/ResponsivePaneProvider'
|
import { useResponsiveAppPane } from '../Panes/ResponsivePaneProvider'
|
||||||
import UpgradeNow from '../Footer/UpgradeNow'
|
import UpgradeNow from '../Footer/UpgradeNow'
|
||||||
@@ -12,6 +11,7 @@ import RoundIconButton from '../Button/RoundIconButton'
|
|||||||
import { isIOS } from '@/Utils'
|
import { isIOS } from '@/Utils'
|
||||||
import { PanelResizedData } from '@/Types/PanelResizedData'
|
import { PanelResizedData } from '@/Types/PanelResizedData'
|
||||||
import { PANEL_NAME_NAVIGATION } from '@/Constants/Constants'
|
import { PANEL_NAME_NAVIGATION } from '@/Constants/Constants'
|
||||||
|
import { PaneLayout } from '@/Controllers/PaneController/PaneLayout'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
application: WebApplication
|
application: WebApplication
|
||||||
@@ -22,7 +22,7 @@ type Props = {
|
|||||||
|
|
||||||
const Navigation = forwardRef<HTMLDivElement, Props>(({ application, className, children, id }, ref) => {
|
const Navigation = forwardRef<HTMLDivElement, Props>(({ application, className, children, id }, ref) => {
|
||||||
const viewControllerManager = useMemo(() => application.getViewControllerManager(), [application])
|
const viewControllerManager = useMemo(() => application.getViewControllerManager(), [application])
|
||||||
const { toggleAppPane } = useResponsiveAppPane()
|
const { setPaneLayout } = useResponsiveAppPane()
|
||||||
|
|
||||||
const [hasPasscode, setHasPasscode] = useState(() => application.hasPasscode())
|
const [hasPasscode, setHasPasscode] = useState(() => application.hasPasscode())
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -56,7 +56,7 @@ const Navigation = forwardRef<HTMLDivElement, Props>(({ application, className,
|
|||||||
<RoundIconButton
|
<RoundIconButton
|
||||||
className="mr-auto bg-default"
|
className="mr-auto bg-default"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
toggleAppPane(AppPaneId.Items)
|
setPaneLayout(PaneLayout.ItemSelection)
|
||||||
}}
|
}}
|
||||||
label="Go to items list"
|
label="Go to items list"
|
||||||
icon="chevron-left"
|
icon="chevron-left"
|
||||||
@@ -101,7 +101,7 @@ const Navigation = forwardRef<HTMLDivElement, Props>(({ application, className,
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}, [hasPasscode, application, viewControllerManager, toggleAppPane])
|
}, [application, viewControllerManager, hasPasscode, setPaneLayout])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -3,6 +3,11 @@ type RemoveListener = () => void
|
|||||||
|
|
||||||
export class AndroidBackHandler {
|
export class AndroidBackHandler {
|
||||||
private listeners = new Set<Listener>()
|
private listeners = new Set<Listener>()
|
||||||
|
private fallbackListener: Listener | undefined
|
||||||
|
|
||||||
|
setFallbackListener(listener: Listener) {
|
||||||
|
this.fallbackListener = listener
|
||||||
|
}
|
||||||
|
|
||||||
addEventListener(listener: Listener): RemoveListener {
|
addEventListener(listener: Listener): RemoveListener {
|
||||||
this.listeners.add(listener)
|
this.listeners.add(listener)
|
||||||
@@ -13,10 +18,17 @@ export class AndroidBackHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
notifyEvent() {
|
notifyEvent() {
|
||||||
|
let handled = false
|
||||||
for (const listener of Array.from(this.listeners).reverse()) {
|
for (const listener of Array.from(this.listeners).reverse()) {
|
||||||
if (listener()) {
|
if (listener()) {
|
||||||
|
handled = true
|
||||||
return
|
return
|
||||||
|
} else {
|
||||||
|
handled = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!handled && this.fallbackListener) {
|
||||||
|
this.fallbackListener()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,19 +34,14 @@ const AndroidBackHandlerProvider = ({ application, children }: ProviderProps) =>
|
|||||||
)
|
)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const removeListener = addAndroidBackHandler(() => {
|
application.setAndroidBackHandlerFallbackListener(() => {
|
||||||
const shouldConfirm = (application.getValue(AndroidConfirmBeforeExitKey) as boolean) ?? true
|
const shouldConfirm = (application.getValue(AndroidConfirmBeforeExitKey) as boolean) ?? true
|
||||||
|
|
||||||
application.mobileDevice().exitApp(shouldConfirm)
|
application.mobileDevice().exitApp(shouldConfirm)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
return () => {
|
}, [application])
|
||||||
if (removeListener) {
|
|
||||||
removeListener()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [addAndroidBackHandler, application])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BackHandlerContext.Provider value={addAndroidBackHandler}>
|
<BackHandlerContext.Provider value={addAndroidBackHandler}>
|
||||||
|
|||||||
Reference in New Issue
Block a user