fix: Disabled pane gesture navigation by default and moved it to Labs since it is unstable
This commit is contained in:
@@ -637,7 +637,7 @@ EXTERNAL SOURCES:
|
|||||||
:path: "../node_modules/react-native/ReactCommon/yoga"
|
:path: "../node_modules/react-native/ReactCommon/yoga"
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
boost: a7c83b31436843459a1961bfd74b96033dc77234
|
boost: 57d2868c099736d80fcd648bf211b4431e51a558
|
||||||
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
|
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
|
||||||
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
|
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
|
||||||
FBLazyVector: 60195509584153283780abdac5569feffb8f08cc
|
FBLazyVector: 60195509584153283780abdac5569feffb8f08cc
|
||||||
@@ -658,7 +658,7 @@ SPEC CHECKSUMS:
|
|||||||
MMKV: 9c4663aa7ca255d478ff10f2f5cb7d17c1651ccd
|
MMKV: 9c4663aa7ca255d478ff10f2f5cb7d17c1651ccd
|
||||||
MMKVCore: 89f5c8a66bba2dcd551779dea4d412eeec8ff5bb
|
MMKVCore: 89f5c8a66bba2dcd551779dea4d412eeec8ff5bb
|
||||||
OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c
|
OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c
|
||||||
RCT-Folly: 0080d0a6ebf2577475bda044aa59e2ca1f909cda
|
RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1
|
||||||
RCTRequired: bec48f07daf7bcdc2655a0cde84e07d24d2a9e2a
|
RCTRequired: bec48f07daf7bcdc2655a0cde84e07d24d2a9e2a
|
||||||
RCTTypeSafety: 171394eebacf71e1cfad79dbfae7ee8fc16ca80a
|
RCTTypeSafety: 171394eebacf71e1cfad79dbfae7ee8fc16ca80a
|
||||||
React: d7433ccb6a8c36e4cbed59a73c0700fc83c3e98a
|
React: d7433ccb6a8c36e4cbed59a73c0700fc83c3e98a
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ export enum PrefKey {
|
|||||||
SystemViewPreferences = 'systemViewPreferences',
|
SystemViewPreferences = 'systemViewPreferences',
|
||||||
SuperNoteExportFormat = 'superNoteExportFormat',
|
SuperNoteExportFormat = 'superNoteExportFormat',
|
||||||
AuthenticatorNames = 'authenticatorNames',
|
AuthenticatorNames = 'authenticatorNames',
|
||||||
|
PaneGesturesEnabled = 'paneGesturesEnabled',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum NewNoteTitleFormat {
|
export enum NewNoteTitleFormat {
|
||||||
@@ -113,4 +114,5 @@ export type PrefValue = {
|
|||||||
[PrefKey.SystemViewPreferences]: Partial<Record<SystemViewId, TagPreferences>>
|
[PrefKey.SystemViewPreferences]: Partial<Record<SystemViewId, TagPreferences>>
|
||||||
[PrefKey.SuperNoteExportFormat]: 'json' | 'md' | 'html'
|
[PrefKey.SuperNoteExportFormat]: 'json' | 'md' | 'html'
|
||||||
[PrefKey.AuthenticatorNames]: string
|
[PrefKey.AuthenticatorNames]: string
|
||||||
|
[PrefKey.PaneGesturesEnabled]: boolean
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,18 +2,29 @@ import { useStateRef } from '@/Hooks/useStateRef'
|
|||||||
import { useEffect, useRef, useState } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
import { Direction, Pan, PointerListener, type GestureEventData } from 'contactjs'
|
import { Direction, Pan, PointerListener, type GestureEventData } from 'contactjs'
|
||||||
import { MutuallyExclusiveMediaQueryBreakpoints, useMediaQuery } from '@/Hooks/useMediaQuery'
|
import { MutuallyExclusiveMediaQueryBreakpoints, useMediaQuery } from '@/Hooks/useMediaQuery'
|
||||||
|
import { useApplication } from '../ApplicationProvider'
|
||||||
|
import { ApplicationEvent, PrefKey } from '@standardnotes/snjs'
|
||||||
|
|
||||||
export const usePaneSwipeGesture = (
|
export const usePaneSwipeGesture = (
|
||||||
direction: 'left' | 'right',
|
direction: 'left' | 'right',
|
||||||
onSwipeEnd: (element: HTMLElement) => void,
|
onSwipeEnd: (element: HTMLElement) => void,
|
||||||
gesture: 'pan' | 'swipe' = 'pan',
|
gesture: 'pan' | 'swipe' = 'pan',
|
||||||
) => {
|
) => {
|
||||||
|
const application = useApplication()
|
||||||
|
|
||||||
const overlayElementRef = useRef<HTMLElement | null>(null)
|
const overlayElementRef = useRef<HTMLElement | null>(null)
|
||||||
const [element, setElement] = useState<HTMLElement | null>(null)
|
const [element, setElement] = useState<HTMLElement | null>(null)
|
||||||
|
|
||||||
const onSwipeEndRef = useStateRef(onSwipeEnd)
|
const onSwipeEndRef = useStateRef(onSwipeEnd)
|
||||||
const isMobileScreen = useMediaQuery(MutuallyExclusiveMediaQueryBreakpoints.sm)
|
const isMobileScreen = useMediaQuery(MutuallyExclusiveMediaQueryBreakpoints.sm)
|
||||||
|
|
||||||
|
const [isEnabled, setIsEnabled] = useState(() => application.getPreference(PrefKey.PaneGesturesEnabled, false))
|
||||||
|
useEffect(() => {
|
||||||
|
return application.addSingleEventObserver(ApplicationEvent.PreferencesChanged, async () => {
|
||||||
|
setIsEnabled(application.getPreference(PrefKey.PaneGesturesEnabled, false))
|
||||||
|
})
|
||||||
|
}, [application])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!element) {
|
if (!element) {
|
||||||
return
|
return
|
||||||
@@ -23,6 +34,10 @@ export const usePaneSwipeGesture = (
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isEnabled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const panRecognizer = new Pan(element, {
|
const panRecognizer = new Pan(element, {
|
||||||
supportedDirections: direction === 'left' ? [Direction.Left] : [Direction.Right],
|
supportedDirections: direction === 'left' ? [Direction.Left] : [Direction.Right],
|
||||||
})
|
})
|
||||||
@@ -144,7 +159,7 @@ export const usePaneSwipeGesture = (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [direction, element, gesture, isMobileScreen, onSwipeEndRef])
|
}, [direction, element, gesture, isMobileScreen, onSwipeEndRef, isEnabled])
|
||||||
|
|
||||||
return [setElement]
|
return [setElement]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Text, Title } from '@/Components/Preferences/PreferencesComponents/Content'
|
import { Text, Title } from '@/Components/Preferences/PreferencesComponents/Content'
|
||||||
import { WebApplication } from '@/Application/Application'
|
import { WebApplication } from '@/Application/Application'
|
||||||
import { FeatureIdentifier, FeatureStatus, FindNativeFeature } from '@standardnotes/snjs'
|
import { ApplicationEvent, FeatureIdentifier, FeatureStatus, FindNativeFeature, PrefKey } 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'
|
||||||
import PreferencesGroup from '../../../PreferencesComponents/PreferencesGroup'
|
import PreferencesGroup from '../../../PreferencesComponents/PreferencesGroup'
|
||||||
@@ -18,15 +18,25 @@ type ExperimentalFeatureItem = {
|
|||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
application: {
|
application: {
|
||||||
setValue: WebApplication['setValue']
|
|
||||||
getValue: WebApplication['getValue']
|
|
||||||
features: WebApplication['features']
|
features: WebApplication['features']
|
||||||
|
getPreference: WebApplication['getPreference']
|
||||||
|
setPreference: WebApplication['setPreference']
|
||||||
|
addSingleEventObserver: WebApplication['addSingleEventObserver']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const LabsPane: FunctionComponent<Props> = ({ application }) => {
|
const LabsPane: FunctionComponent<Props> = ({ application }) => {
|
||||||
const [experimentalFeatures, setExperimentalFeatures] = useState<ExperimentalFeatureItem[]>([])
|
const [experimentalFeatures, setExperimentalFeatures] = useState<ExperimentalFeatureItem[]>([])
|
||||||
|
|
||||||
|
const [isPaneGesturesEnabled, setIsPaneGesturesEnabled] = useState(() =>
|
||||||
|
application.getPreference(PrefKey.PaneGesturesEnabled, false),
|
||||||
|
)
|
||||||
|
useEffect(() => {
|
||||||
|
return application.addSingleEventObserver(ApplicationEvent.PreferencesChanged, async () => {
|
||||||
|
setIsPaneGesturesEnabled(application.getPreference(PrefKey.PaneGesturesEnabled, false))
|
||||||
|
})
|
||||||
|
}, [application])
|
||||||
|
|
||||||
const reloadExperimentalFeatures = useCallback(() => {
|
const reloadExperimentalFeatures = useCallback(() => {
|
||||||
const experimentalFeatures = application.features.getExperimentalFeatures().map((featureIdentifier) => {
|
const experimentalFeatures = application.features.getExperimentalFeatures().map((featureIdentifier) => {
|
||||||
const feature = FindNativeFeature(featureIdentifier)
|
const feature = FindNativeFeature(featureIdentifier)
|
||||||
@@ -52,6 +62,14 @@ const LabsPane: FunctionComponent<Props> = ({ application }) => {
|
|||||||
<PreferencesSegment>
|
<PreferencesSegment>
|
||||||
<Title>Labs</Title>
|
<Title>Labs</Title>
|
||||||
<div>
|
<div>
|
||||||
|
<LabsFeature
|
||||||
|
name="Pane switch gestures"
|
||||||
|
description="Allows using gestures to navigate"
|
||||||
|
isEnabled={isPaneGesturesEnabled}
|
||||||
|
toggleFeature={() => {
|
||||||
|
void application.setPreference(PrefKey.PaneGesturesEnabled, !isPaneGesturesEnabled)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
{experimentalFeatures.map(({ identifier, name, description, isEnabled, isEntitled }, index) => {
|
{experimentalFeatures.map(({ identifier, name, description, isEnabled, isEntitled }, index) => {
|
||||||
const toggleFeature = () => {
|
const toggleFeature = () => {
|
||||||
if (!isEntitled) {
|
if (!isEntitled) {
|
||||||
@@ -77,7 +95,7 @@ const LabsPane: FunctionComponent<Props> = ({ application }) => {
|
|||||||
</Fragment>
|
</Fragment>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
{experimentalFeatures.length === 0 && (
|
{(experimentalFeatures.length === 0 || typeof isPaneGesturesEnabled === 'boolean') && (
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<Text>No experimental features available.</Text>
|
<Text>No experimental features available.</Text>
|
||||||
|
|||||||
Reference in New Issue
Block a user