chore: preferences view swipe gesture
This commit is contained in:
@@ -114,7 +114,7 @@ const Modal = ({
|
|||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'flex w-full flex-shrink-0 items-center justify-between rounded-t border-b border-solid border-border bg-default px-2 text-text md:px-4.5 md:py-3',
|
'flex w-full flex-shrink-0 select-none items-center justify-between rounded-t border-b border-solid border-border bg-default px-2 text-text md:px-4.5 md:py-3',
|
||||||
hasTopInset ? 'pt-safe-top pb-1.5' : 'py-1.5',
|
hasTopInset ? 'pt-safe-top pb-1.5' : 'py-1.5',
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { useLifecycleAnimation } from '@/Hooks/useLifecycleAnimation'
|
import { useLifecycleAnimation } from '@/Hooks/useLifecycleAnimation'
|
||||||
import { useMediaQuery, MutuallyExclusiveMediaQueryBreakpoints } from '@/Hooks/useMediaQuery'
|
import { useMediaQuery, MutuallyExclusiveMediaQueryBreakpoints } from '@/Hooks/useMediaQuery'
|
||||||
|
|
||||||
|
export const IosModalAnimationEasing = 'cubic-bezier(.36,.66,.04,1)'
|
||||||
|
|
||||||
export const useModalAnimation = (isOpen: boolean) => {
|
export const useModalAnimation = (isOpen: boolean) => {
|
||||||
const isMobileScreen = useMediaQuery(MutuallyExclusiveMediaQueryBreakpoints.sm)
|
const isMobileScreen = useMediaQuery(MutuallyExclusiveMediaQueryBreakpoints.sm)
|
||||||
|
|
||||||
@@ -17,7 +19,7 @@ export const useModalAnimation = (isOpen: boolean) => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
options: {
|
options: {
|
||||||
easing: 'cubic-bezier(.36,.66,.04,1)',
|
easing: IosModalAnimationEasing,
|
||||||
duration: 250,
|
duration: 250,
|
||||||
fill: 'forwards',
|
fill: 'forwards',
|
||||||
},
|
},
|
||||||
@@ -38,7 +40,7 @@ export const useModalAnimation = (isOpen: boolean) => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
options: {
|
options: {
|
||||||
easing: 'cubic-bezier(.36,.66,.04,1)',
|
easing: IosModalAnimationEasing,
|
||||||
duration: 250,
|
duration: 250,
|
||||||
fill: 'forwards',
|
fill: 'forwards',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ export async function animatePaneExitTransitionOffscreenToTheRight(elementId: st
|
|||||||
* a Daily Notebook tag from navigation whereby two pane animations are simulatensouly triggered (the items panel, then
|
* a Daily Notebook tag from navigation whereby two pane animations are simulatensouly triggered (the items panel, then
|
||||||
* the editor panel), causing Safari to get tripped up.
|
* the editor panel), causing Safari to get tripped up.
|
||||||
*/
|
*/
|
||||||
function performSafariAnimationFix(element: HTMLElement): void {
|
export function performSafariAnimationFix(element: HTMLElement): void {
|
||||||
const isSafari = /Safari/.test(navigator.userAgent) || /AppleWebKit/.test(navigator.userAgent)
|
const isSafari = /Safari/.test(navigator.userAgent) || /AppleWebKit/.test(navigator.userAgent)
|
||||||
if (!isSafari) {
|
if (!isSafari) {
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -4,13 +4,14 @@ import { observer } from 'mobx-react-lite'
|
|||||||
import { PreferencesMenu } from './PreferencesMenu'
|
import { PreferencesMenu } from './PreferencesMenu'
|
||||||
import PreferencesCanvas from './PreferencesCanvas'
|
import PreferencesCanvas from './PreferencesCanvas'
|
||||||
import { PreferencesProps } from './PreferencesProps'
|
import { PreferencesProps } from './PreferencesProps'
|
||||||
import { useDisableBodyScrollOnMobile } from '@/Hooks/useDisableBodyScrollOnMobile'
|
|
||||||
import { useAndroidBackHandler } from '@/NativeMobileWeb/useAndroidBackHandler'
|
import { useAndroidBackHandler } from '@/NativeMobileWeb/useAndroidBackHandler'
|
||||||
import Modal from '../Modal/Modal'
|
import Modal, { ModalAction } from '../Modal/Modal'
|
||||||
import { classNames } from '@standardnotes/snjs'
|
import { classNames } from '@standardnotes/snjs'
|
||||||
import { useCommandService } from '../CommandProvider'
|
import { useCommandService } from '../CommandProvider'
|
||||||
import { ESCAPE_COMMAND } from '@standardnotes/ui-services'
|
import { ESCAPE_COMMAND } from '@standardnotes/ui-services'
|
||||||
import { useAvailableSafeAreaPadding } from '@/Hooks/useSafeAreaPadding'
|
import { useAvailableSafeAreaPadding } from '@/Hooks/useSafeAreaPadding'
|
||||||
|
import { MutuallyExclusiveMediaQueryBreakpoints, useMediaQuery } from '@/Hooks/useMediaQuery'
|
||||||
|
import Icon from '../Icon/Icon'
|
||||||
|
|
||||||
const PreferencesView: FunctionComponent<PreferencesProps> = ({
|
const PreferencesView: FunctionComponent<PreferencesProps> = ({
|
||||||
application,
|
application,
|
||||||
@@ -30,7 +31,7 @@ const PreferencesView: FunctionComponent<PreferencesProps> = ({
|
|||||||
menu.selectPane(viewControllerManager.preferencesController.currentPane)
|
menu.selectPane(viewControllerManager.preferencesController.currentPane)
|
||||||
}, [menu, viewControllerManager.preferencesController.currentPane])
|
}, [menu, viewControllerManager.preferencesController.currentPane])
|
||||||
|
|
||||||
useDisableBodyScrollOnMobile()
|
const isMobileScreen = useMediaQuery(MutuallyExclusiveMediaQueryBreakpoints.sm)
|
||||||
|
|
||||||
const addAndroidBackHandler = useAndroidBackHandler()
|
const addAndroidBackHandler = useAndroidBackHandler()
|
||||||
|
|
||||||
@@ -58,6 +59,23 @@ const PreferencesView: FunctionComponent<PreferencesProps> = ({
|
|||||||
|
|
||||||
const { hasTopInset } = useAvailableSafeAreaPadding()
|
const { hasTopInset } = useAvailableSafeAreaPadding()
|
||||||
|
|
||||||
|
const modalActions = useMemo(
|
||||||
|
(): ModalAction[] => [
|
||||||
|
{
|
||||||
|
label: (
|
||||||
|
<span className="flex items-center">
|
||||||
|
<Icon type="chevron-left" size="large" />
|
||||||
|
Back
|
||||||
|
</span>
|
||||||
|
),
|
||||||
|
type: 'primary',
|
||||||
|
mobileSlot: 'left',
|
||||||
|
onClick: closePreferences,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[closePreferences],
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
close={closePreferences}
|
close={closePreferences}
|
||||||
@@ -84,6 +102,9 @@ const PreferencesView: FunctionComponent<PreferencesProps> = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
disableCustomHeader={isMobileScreen}
|
||||||
|
actions={modalActions}
|
||||||
|
customFooter={<></>}
|
||||||
>
|
>
|
||||||
<PreferencesCanvas
|
<PreferencesCanvas
|
||||||
menu={menu}
|
menu={menu}
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ import { PreferencesViewWrapperProps } from './PreferencesViewWrapperProps'
|
|||||||
import { useCommandService } from '../CommandProvider'
|
import { useCommandService } from '../CommandProvider'
|
||||||
import { OPEN_PREFERENCES_COMMAND } from '@standardnotes/ui-services'
|
import { OPEN_PREFERENCES_COMMAND } from '@standardnotes/ui-services'
|
||||||
import ModalOverlay from '../Modal/ModalOverlay'
|
import ModalOverlay from '../Modal/ModalOverlay'
|
||||||
|
import { usePaneSwipeGesture } from '../Panes/usePaneGesture'
|
||||||
|
import { performSafariAnimationFix } from '../Panes/PaneAnimator'
|
||||||
|
import { IosModalAnimationEasing } from '../Modal/useModalAnimation'
|
||||||
|
|
||||||
const PreferencesViewWrapper: FunctionComponent<PreferencesViewWrapperProps> = ({
|
const PreferencesViewWrapper: FunctionComponent<PreferencesViewWrapperProps> = ({
|
||||||
viewControllerManager,
|
viewControllerManager,
|
||||||
@@ -19,10 +22,34 @@ const PreferencesViewWrapper: FunctionComponent<PreferencesViewWrapperProps> = (
|
|||||||
})
|
})
|
||||||
}, [commandService, viewControllerManager])
|
}, [commandService, viewControllerManager])
|
||||||
|
|
||||||
|
const [setElement] = usePaneSwipeGesture('right', async (element) => {
|
||||||
|
const animation = element.animate(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
transform: 'translateX(100%)',
|
||||||
|
opacity: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
{
|
||||||
|
easing: IosModalAnimationEasing,
|
||||||
|
duration: 250,
|
||||||
|
fill: 'both',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
await animation.finished
|
||||||
|
|
||||||
|
performSafariAnimationFix(element)
|
||||||
|
|
||||||
|
animation.finish()
|
||||||
|
|
||||||
|
viewControllerManager.preferencesController.closePreferences()
|
||||||
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalOverlay isOpen={viewControllerManager.preferencesController.isOpen}>
|
<ModalOverlay isOpen={viewControllerManager.preferencesController.isOpen} ref={setElement}>
|
||||||
<PreferencesView
|
<PreferencesView
|
||||||
closePreferences={() => viewControllerManager.preferencesController.closePreferences()}
|
closePreferences={viewControllerManager.preferencesController.closePreferences}
|
||||||
application={application}
|
application={application}
|
||||||
viewControllerManager={viewControllerManager}
|
viewControllerManager={viewControllerManager}
|
||||||
mfaProvider={application}
|
mfaProvider={application}
|
||||||
|
|||||||
Reference in New Issue
Block a user