WIP
This commit is contained in:
committed by
Oleksii Bulenok
parent
3d39ca0c0c
commit
95ce988fb7
+1
-1
@@ -234,7 +234,7 @@
|
||||
"react-native-device-attest": "^0.1.6",
|
||||
"react-native-drawer-layout": "^4.2.3",
|
||||
"react-native-edge-to-edge": "^1.8.1",
|
||||
"react-native-gesture-handler": "~2.32.0",
|
||||
"react-native-gesture-handler": "~3.1.0",
|
||||
"react-native-keyboard-controller": "1.21.9",
|
||||
"react-native-mmkv": "^3.3.3",
|
||||
"react-native-pager-view": "6.8.0",
|
||||
|
||||
@@ -36,3 +36,12 @@ index 38470a658878a63919186257041098747ec55473..b9d25798c9be229efeb676166f89bfbc
|
||||
if (open) {
|
||||
runOnJS(onOpen)();
|
||||
} else {
|
||||
diff --git a/lib/typescript/src/types.d.ts b/lib/typescript/src/types.d.ts
|
||||
--- a/lib/typescript/src/types.d.ts
|
||||
+++ b/lib/typescript/src/types.d.ts
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as React from 'react';
|
||||
import type { StyleProp, View, ViewStyle } from 'react-native';
|
||||
-import type { PanGesture } from 'react-native-gesture-handler';
|
||||
+import type { LegacyPanGesture as PanGesture } from 'react-native-gesture-handler';
|
||||
import type { SharedValue } from 'react-native-reanimated';
|
||||
|
||||
Generated
+13
-42
@@ -228,7 +228,7 @@ patchedDependencies:
|
||||
expo@57.0.8: 1722861d12907a2d412d04230545b2fcbfa5547a79f99d763cb3e8de6f3a6f2a
|
||||
react-native-date-picker@5.0.13: 92943fb79d17d7342a29bbb12b0d8ee3cf6f7bca12ed322dc8d124a3e9fb75bd
|
||||
react-native-dotenv@3.4.11: 16b34eb974399935d3cf7c2526534f906991ccd876215176658347059cdd2021
|
||||
react-native-drawer-layout@4.2.3: 74f2c043cc22ab87054f219e7c7373a509b779b18bfa79d27e7d051d73355130
|
||||
react-native-drawer-layout@4.2.3: 2a67e397c87df9fb947b1931c9b00724b802a8dca5d3013617e6155f1ae3188e
|
||||
react-native-keyboard-controller@1.21.9: ac52bf7502ff3ad34a8594b5e1a916b96bf87a2523b6abc87c31f03607d52271
|
||||
react-native-pager-view@6.8.0: c8316acd33c9aef6531e8c272c2bfab7bd02af1255969eeaab2bad5ab48531cc
|
||||
react-native-screens@4.26.2: ba3295d44434a729f143a6b2c24e4a9b2f911ab200b2bc47e46cdfeaa1536f7c
|
||||
@@ -640,13 +640,13 @@ importers:
|
||||
version: 0.1.6(expo@57.0.8)(react-native@0.86.0(patch_hash=239208992c380d6785576d1fae2e3f60f60f509d7b09d56bf552be29d6c42a06)(@babel/core@7.29.0(supports-color@8.1.1))(@react-native/jest-preset@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(@react-native/metro-config@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
|
||||
react-native-drawer-layout:
|
||||
specifier: ^4.2.3
|
||||
version: 4.2.3(patch_hash=74f2c043cc22ab87054f219e7c7373a509b779b18bfa79d27e7d051d73355130)(react-native-gesture-handler@2.32.0(react-native@0.86.0(patch_hash=239208992c380d6785576d1fae2e3f60f60f509d7b09d56bf552be29d6c42a06)(@babel/core@7.29.0(supports-color@8.1.1))(@react-native/jest-preset@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(@react-native/metro-config@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3))(react-native-reanimated@4.6.0(92d1a74bc123f334ae9968fa1c80814f))(react-native@0.86.0(patch_hash=239208992c380d6785576d1fae2e3f60f60f509d7b09d56bf552be29d6c42a06)(@babel/core@7.29.0(supports-color@8.1.1))(@react-native/jest-preset@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(@react-native/metro-config@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
|
||||
version: 4.2.3(patch_hash=2a67e397c87df9fb947b1931c9b00724b802a8dca5d3013617e6155f1ae3188e)(react-native-gesture-handler@3.1.0(react-native@0.86.0(patch_hash=239208992c380d6785576d1fae2e3f60f60f509d7b09d56bf552be29d6c42a06)(@babel/core@7.29.0(supports-color@8.1.1))(@react-native/jest-preset@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(@react-native/metro-config@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3))(react-native-reanimated@4.6.0(92d1a74bc123f334ae9968fa1c80814f))(react-native@0.86.0(patch_hash=239208992c380d6785576d1fae2e3f60f60f509d7b09d56bf552be29d6c42a06)(@babel/core@7.29.0(supports-color@8.1.1))(@react-native/jest-preset@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(@react-native/metro-config@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
|
||||
react-native-edge-to-edge:
|
||||
specifier: ^1.8.1
|
||||
version: 1.8.1(react-native@0.86.0(patch_hash=239208992c380d6785576d1fae2e3f60f60f509d7b09d56bf552be29d6c42a06)(@babel/core@7.29.0(supports-color@8.1.1))(@react-native/jest-preset@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(@react-native/metro-config@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
|
||||
react-native-gesture-handler:
|
||||
specifier: ~2.32.0
|
||||
version: 2.32.0(react-native@0.86.0(patch_hash=239208992c380d6785576d1fae2e3f60f60f509d7b09d56bf552be29d6c42a06)(@babel/core@7.29.0(supports-color@8.1.1))(@react-native/jest-preset@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(@react-native/metro-config@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
|
||||
specifier: ~3.1.0
|
||||
version: 3.1.0(react-native@0.86.0(patch_hash=239208992c380d6785576d1fae2e3f60f60f509d7b09d56bf552be29d6c42a06)(@babel/core@7.29.0(supports-color@8.1.1))(@react-native/jest-preset@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(@react-native/metro-config@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
|
||||
react-native-keyboard-controller:
|
||||
specifier: 1.21.9
|
||||
version: 1.21.9(patch_hash=ac52bf7502ff3ad34a8594b5e1a916b96bf87a2523b6abc87c31f03607d52271)(react-native-reanimated@4.6.0(92d1a74bc123f334ae9968fa1c80814f))(react-native@0.86.0(patch_hash=239208992c380d6785576d1fae2e3f60f60f509d7b09d56bf552be29d6c42a06)(@babel/core@7.29.0(supports-color@8.1.1))(@react-native/jest-preset@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(@react-native/metro-config@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
|
||||
@@ -715,7 +715,7 @@ importers:
|
||||
version: 2.0.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
|
||||
sonner-native:
|
||||
specifier: 0.26.4
|
||||
version: 0.26.4(a1115538eb9b7f01f00730be61406201)
|
||||
version: 0.26.4(58a7fe7e7df4354448cb52f8cc2a8c5c)
|
||||
tippy.js:
|
||||
specifier: ^6.3.7
|
||||
version: 6.3.7
|
||||
@@ -1764,10 +1764,6 @@ packages:
|
||||
resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
|
||||
'@egjs/hammerjs@2.0.17':
|
||||
resolution: {integrity: sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==}
|
||||
engines: {node: '>=0.8.0'}
|
||||
|
||||
'@emnapi/runtime@1.11.3':
|
||||
resolution: {integrity: sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==}
|
||||
|
||||
@@ -3990,9 +3986,6 @@ packages:
|
||||
'@types/graceful-fs@4.1.9':
|
||||
resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==}
|
||||
|
||||
'@types/hammerjs@2.0.46':
|
||||
resolution: {integrity: sha512-ynRvcq6wvqexJ9brDMS4BnBLzmr0e14d6ZJTEShTBWKymQiHwlAyGu0ZPEFI2Fh1U53F7tN9ufClWM5KvqkKOw==}
|
||||
|
||||
'@types/html-minifier-terser@6.1.0':
|
||||
resolution: {integrity: sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==}
|
||||
|
||||
@@ -4080,9 +4073,6 @@ packages:
|
||||
'@types/react-test-renderer@19.1.0':
|
||||
resolution: {integrity: sha512-XD0WZrHqjNrxA/MaR9O22w/RNidWR9YZmBdRGI7wcnWGrv/3dA8wKCJ8m63Sn+tLJhcjmuhOi629N66W6kgWzQ==}
|
||||
|
||||
'@types/react@19.1.17':
|
||||
resolution: {integrity: sha512-Qec1E3mhALmaspIrhWt9jkQMNdw6bReVu64mjvhbhq2NFPftLPVr+l1SZgmw/66WwBNpDh7ao5AT6gF5v41PFA==}
|
||||
|
||||
'@types/react@19.2.18':
|
||||
resolution: {integrity: sha512-AnzbBERsrLKtk2XSfTbYRLjQPdy116Sty4q+T+Bp3IC4l6jNBvreVPAHmpq9qhXQM7CXZPjLVmGMw9sy+hxQ3w==}
|
||||
|
||||
@@ -6312,9 +6302,6 @@ packages:
|
||||
hls.js@1.6.16:
|
||||
resolution: {integrity: sha512-VSIRpLfRwlAAdGL4wiTucx2ScRipo0ed1FBatWkyt832jC4CReKstga6yIhYVwGu9LOBjuX9wzmRMeQdBJtzEA==}
|
||||
|
||||
hoist-non-react-statics@3.3.2:
|
||||
resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==}
|
||||
|
||||
hosted-git-info@7.0.2:
|
||||
resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==}
|
||||
engines: {node: ^16.14.0 || >=18.0.0}
|
||||
@@ -8369,8 +8356,8 @@ packages:
|
||||
react: '*'
|
||||
react-native: '*'
|
||||
|
||||
react-native-gesture-handler@2.32.0:
|
||||
resolution: {integrity: sha512-uYIMOKlKENORq2SABE+jIjbPU+h5I/sQKcq2v16zRq848nwEp1fWRVwML4QWqijc8UcXJC25o54S8GQd4Mf2OA==}
|
||||
react-native-gesture-handler@3.1.0:
|
||||
resolution: {integrity: sha512-+kWVyZ6vLdtyFa1/aOc/sZncLAVPUKxhji/ttbiLI7hOaSU44bLjhI7p+Ns+pMl2r3RqPXssl5qHReYet9G77g==}
|
||||
peerDependencies:
|
||||
react: '*'
|
||||
react-native: '*'
|
||||
@@ -10964,10 +10951,6 @@ snapshots:
|
||||
|
||||
'@discoveryjs/json-ext@0.5.7': {}
|
||||
|
||||
'@egjs/hammerjs@2.0.17':
|
||||
dependencies:
|
||||
'@types/hammerjs': 2.0.46
|
||||
|
||||
'@emnapi/runtime@1.11.3':
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
@@ -13580,8 +13563,6 @@ snapshots:
|
||||
dependencies:
|
||||
'@types/node': 24.12.4
|
||||
|
||||
'@types/hammerjs@2.0.46': {}
|
||||
|
||||
'@types/html-minifier-terser@6.1.0': {}
|
||||
|
||||
'@types/http-errors@2.0.5': {}
|
||||
@@ -13673,11 +13654,7 @@ snapshots:
|
||||
|
||||
'@types/react-test-renderer@19.1.0':
|
||||
dependencies:
|
||||
'@types/react': 19.1.17
|
||||
|
||||
'@types/react@19.1.17':
|
||||
dependencies:
|
||||
csstype: 3.2.3
|
||||
'@types/react': 19.2.18
|
||||
|
||||
'@types/react@19.2.18':
|
||||
dependencies:
|
||||
@@ -16164,10 +16141,6 @@ snapshots:
|
||||
|
||||
hls.js@1.6.16: {}
|
||||
|
||||
hoist-non-react-statics@3.3.2:
|
||||
dependencies:
|
||||
react-is: 16.13.1
|
||||
|
||||
hosted-git-info@7.0.2:
|
||||
dependencies:
|
||||
lru-cache: 10.4.3
|
||||
@@ -18481,12 +18454,12 @@ snapshots:
|
||||
'@babel/runtime': 7.29.2
|
||||
dotenv: 16.6.1
|
||||
|
||||
? react-native-drawer-layout@4.2.3(patch_hash=74f2c043cc22ab87054f219e7c7373a509b779b18bfa79d27e7d051d73355130)(react-native-gesture-handler@2.32.0(react-native@0.86.0(patch_hash=239208992c380d6785576d1fae2e3f60f60f509d7b09d56bf552be29d6c42a06)(@babel/core@7.29.0(supports-color@8.1.1))(@react-native/jest-preset@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(@react-native/metro-config@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3))(react-native-reanimated@4.6.0(92d1a74bc123f334ae9968fa1c80814f))(react-native@0.86.0(patch_hash=239208992c380d6785576d1fae2e3f60f60f509d7b09d56bf552be29d6c42a06)(@babel/core@7.29.0(supports-color@8.1.1))(@react-native/jest-preset@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(@react-native/metro-config@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
|
||||
? react-native-drawer-layout@4.2.3(patch_hash=2a67e397c87df9fb947b1931c9b00724b802a8dca5d3013617e6155f1ae3188e)(react-native-gesture-handler@3.1.0(react-native@0.86.0(patch_hash=239208992c380d6785576d1fae2e3f60f60f509d7b09d56bf552be29d6c42a06)(@babel/core@7.29.0(supports-color@8.1.1))(@react-native/jest-preset@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(@react-native/metro-config@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3))(react-native-reanimated@4.6.0(92d1a74bc123f334ae9968fa1c80814f))(react-native@0.86.0(patch_hash=239208992c380d6785576d1fae2e3f60f60f509d7b09d56bf552be29d6c42a06)(@babel/core@7.29.0(supports-color@8.1.1))(@react-native/jest-preset@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(@react-native/metro-config@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
|
||||
: dependencies:
|
||||
color: 4.2.3
|
||||
react: 19.2.3
|
||||
react-native: 0.86.0(patch_hash=239208992c380d6785576d1fae2e3f60f60f509d7b09d56bf552be29d6c42a06)(@babel/core@7.29.0(supports-color@8.1.1))(@react-native/jest-preset@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(@react-native/metro-config@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1)
|
||||
react-native-gesture-handler: 2.32.0(react-native@0.86.0(patch_hash=239208992c380d6785576d1fae2e3f60f60f509d7b09d56bf552be29d6c42a06)(@babel/core@7.29.0(supports-color@8.1.1))(@react-native/jest-preset@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(@react-native/metro-config@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
|
||||
react-native-gesture-handler: 3.1.0(react-native@0.86.0(patch_hash=239208992c380d6785576d1fae2e3f60f60f509d7b09d56bf552be29d6c42a06)(@babel/core@7.29.0(supports-color@8.1.1))(@react-native/jest-preset@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(@react-native/metro-config@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
|
||||
react-native-reanimated: 4.6.0(92d1a74bc123f334ae9968fa1c80814f)
|
||||
use-latest-callback: 0.2.6(react@19.2.3)
|
||||
|
||||
@@ -18495,11 +18468,9 @@ snapshots:
|
||||
react: 19.2.3
|
||||
react-native: 0.86.0(patch_hash=239208992c380d6785576d1fae2e3f60f60f509d7b09d56bf552be29d6c42a06)(@babel/core@7.29.0(supports-color@8.1.1))(@react-native/jest-preset@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(@react-native/metro-config@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1)
|
||||
|
||||
react-native-gesture-handler@2.32.0(react-native@0.86.0(patch_hash=239208992c380d6785576d1fae2e3f60f60f509d7b09d56bf552be29d6c42a06)(@babel/core@7.29.0(supports-color@8.1.1))(@react-native/jest-preset@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(@react-native/metro-config@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3):
|
||||
react-native-gesture-handler@3.1.0(react-native@0.86.0(patch_hash=239208992c380d6785576d1fae2e3f60f60f509d7b09d56bf552be29d6c42a06)(@babel/core@7.29.0(supports-color@8.1.1))(@react-native/jest-preset@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(@react-native/metro-config@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3):
|
||||
dependencies:
|
||||
'@egjs/hammerjs': 2.0.17
|
||||
'@types/react-test-renderer': 19.1.0
|
||||
hoist-non-react-statics: 3.3.2
|
||||
invariant: 2.2.4
|
||||
react: 19.2.3
|
||||
react-native: 0.86.0(patch_hash=239208992c380d6785576d1fae2e3f60f60f509d7b09d56bf552be29d6c42a06)(@babel/core@7.29.0(supports-color@8.1.1))(@react-native/jest-preset@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(@react-native/metro-config@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1)
|
||||
@@ -19164,11 +19135,11 @@ snapshots:
|
||||
dependencies:
|
||||
atomic-sleep: 1.0.0
|
||||
|
||||
sonner-native@0.26.4(a1115538eb9b7f01f00730be61406201):
|
||||
sonner-native@0.26.4(58a7fe7e7df4354448cb52f8cc2a8c5c):
|
||||
dependencies:
|
||||
react: 19.2.3
|
||||
react-native: 0.86.0(patch_hash=239208992c380d6785576d1fae2e3f60f60f509d7b09d56bf552be29d6c42a06)(@babel/core@7.29.0(supports-color@8.1.1))(@react-native/jest-preset@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(@react-native/metro-config@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1)
|
||||
react-native-gesture-handler: 2.32.0(react-native@0.86.0(patch_hash=239208992c380d6785576d1fae2e3f60f60f509d7b09d56bf552be29d6c42a06)(@babel/core@7.29.0(supports-color@8.1.1))(@react-native/jest-preset@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(@react-native/metro-config@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
|
||||
react-native-gesture-handler: 3.1.0(react-native@0.86.0(patch_hash=239208992c380d6785576d1fae2e3f60f60f509d7b09d56bf552be29d6c42a06)(@babel/core@7.29.0(supports-color@8.1.1))(@react-native/jest-preset@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(@react-native/metro-config@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
|
||||
react-native-reanimated: 4.6.0(92d1a74bc123f334ae9968fa1c80814f)
|
||||
react-native-safe-area-context: 5.7.0(react-native@0.86.0(patch_hash=239208992c380d6785576d1fae2e3f60f60f509d7b09d56bf552be29d6c42a06)(@babel/core@7.29.0(supports-color@8.1.1))(@react-native/jest-preset@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(@react-native/metro-config@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
|
||||
react-native-screens: 4.26.2(patch_hash=ba3295d44434a729f143a6b2c24e4a9b2f911ab200b2bc47e46cdfeaa1536f7c)(react-native@0.86.0(patch_hash=239208992c380d6785576d1fae2e3f60f60f509d7b09d56bf552be29d6c42a06)(@babel/core@7.29.0(supports-color@8.1.1))(@react-native/jest-preset@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(react@19.2.3)(supports-color@8.1.1))(@react-native/metro-config@0.86.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1))(@types/react@19.2.18)(react@19.2.3)(supports-color@8.1.1))(react@19.2.3)
|
||||
|
||||
@@ -20,11 +20,12 @@ import {
|
||||
type ViewStyle,
|
||||
} from 'react-native'
|
||||
import {
|
||||
Gesture,
|
||||
GestureDetector,
|
||||
type GestureStateChangeEvent,
|
||||
type GestureUpdateEvent,
|
||||
type PanGestureHandlerEventPayload,
|
||||
type PanGestureActiveEvent,
|
||||
useCompetingGestures,
|
||||
useExclusiveGestures,
|
||||
usePanGesture,
|
||||
useTapGesture,
|
||||
} from 'react-native-gesture-handler'
|
||||
import {KeyboardEvents} from 'react-native-keyboard-controller'
|
||||
import Animated, {
|
||||
@@ -299,24 +300,19 @@ export function Trigger({
|
||||
}
|
||||
}, [context, insets])
|
||||
|
||||
const tapGesture = useMemo(() => {
|
||||
const gesture = Gesture.Tap()
|
||||
.numberOfTaps(1)
|
||||
.cancelsTouchesInView(false)
|
||||
.runOnJS(true)
|
||||
if (onTap) {
|
||||
gesture.onEnd(() => void onTap())
|
||||
}
|
||||
return gesture
|
||||
}, [onTap])
|
||||
const tapGesture = useTapGesture({
|
||||
numberOfTaps: 1,
|
||||
cancelsTouchesInView: false,
|
||||
runOnJS: true,
|
||||
onDeactivate: onTap ? () => void onTap() : undefined,
|
||||
})
|
||||
|
||||
const doubleTapGesture = useMemo(() => {
|
||||
return Gesture.Tap()
|
||||
.numberOfTaps(2)
|
||||
.hitSlop(HITSLOP_10)
|
||||
.onEnd(() => void open('auxiliary-only'))
|
||||
.runOnJS(true)
|
||||
}, [open])
|
||||
const doubleTapGesture = useTapGesture({
|
||||
numberOfTaps: 2,
|
||||
hitSlop: HITSLOP_10,
|
||||
runOnJS: true,
|
||||
onDeactivate: () => void open('auxiliary-only'),
|
||||
})
|
||||
|
||||
const {
|
||||
hoverablesSV,
|
||||
@@ -336,34 +332,33 @@ export function Trigger({
|
||||
},
|
||||
)
|
||||
|
||||
const pressAndHoldGesture = useMemo(() => {
|
||||
return Gesture.Pan()
|
||||
.activateAfterLongPress(500)
|
||||
.cancelsTouchesInView(false)
|
||||
.averageTouches(true)
|
||||
.onStart(() => {
|
||||
'worklet'
|
||||
scheduleOnRN(open, 'full')
|
||||
})
|
||||
.onUpdate(evt => {
|
||||
'worklet'
|
||||
const item = getHoveredHoverable(evt, hoverablesSV, translationSV)
|
||||
hoveredItemSV.set(item)
|
||||
})
|
||||
.onEnd(() => {
|
||||
'worklet'
|
||||
// don't recalculate hovered item - if they haven't moved their finger from
|
||||
// the initial press, it's jarring to then select the item underneath
|
||||
// as the menu may have slid into place beneath their finger
|
||||
const item = hoveredItemSV.get()
|
||||
if (item) {
|
||||
scheduleOnRN(onTouchUpMenuItem, item)
|
||||
}
|
||||
})
|
||||
}, [open, hoverablesSV, onTouchUpMenuItem, hoveredItemSV, translationSV])
|
||||
const pressAndHoldGesture = usePanGesture({
|
||||
activateAfterLongPress: 500,
|
||||
cancelsTouchesInView: false,
|
||||
averageTouches: true,
|
||||
onActivate: () => {
|
||||
'worklet'
|
||||
scheduleOnRN(open, 'full')
|
||||
},
|
||||
onUpdate: evt => {
|
||||
'worklet'
|
||||
const item = getHoveredHoverable(evt, hoverablesSV, translationSV)
|
||||
hoveredItemSV.set(item)
|
||||
},
|
||||
onDeactivate: () => {
|
||||
'worklet'
|
||||
// don't recalculate hovered item - if they haven't moved their finger from
|
||||
// the initial press, it's jarring to then select the item underneath
|
||||
// as the menu may have slid into place beneath their finger
|
||||
const item = hoveredItemSV.get()
|
||||
if (item) {
|
||||
scheduleOnRN(onTouchUpMenuItem, item)
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
// Order matters here: doubleTapGesture must come before tapGesture.
|
||||
const tapAndHoldGestures = Gesture.Exclusive(
|
||||
const tapAndHoldGestures = useExclusiveGestures(
|
||||
doubleTapGesture,
|
||||
tapGesture,
|
||||
pressAndHoldGesture,
|
||||
@@ -371,11 +366,13 @@ export function Trigger({
|
||||
|
||||
// An optional swipe gesture (e.g. swipe-to-reply) races against the tap/hold
|
||||
// group: whichever activates first wins and cancels the rest, so they're
|
||||
// mutually exclusive. Race (not Exclusive) avoids a held-but-not-yet-moved
|
||||
// mutually exclusive. Competing (not Exclusive) avoids a held-but-not-yet-moved
|
||||
// swipe Pan blocking the long-press from firing.
|
||||
const composedGestures = swipeGesture
|
||||
? Gesture.Race(swipeGesture, tapAndHoldGestures)
|
||||
: tapAndHoldGestures
|
||||
const composedGestures = useCompetingGestures(
|
||||
...(swipeGesture
|
||||
? [swipeGesture, tapAndHoldGestures]
|
||||
: [tapAndHoldGestures]),
|
||||
)
|
||||
|
||||
const measurement = context.measurement || pendingMeasurement?.measurement
|
||||
|
||||
@@ -990,9 +987,7 @@ function measureView(
|
||||
}
|
||||
|
||||
function getHoveredHoverable(
|
||||
evt:
|
||||
| GestureStateChangeEvent<PanGestureHandlerEventPayload>
|
||||
| GestureUpdateEvent<PanGestureHandlerEventPayload>,
|
||||
evt: PanGestureActiveEvent,
|
||||
hoverables: SharedValue<Record<string, {id: string; rect: Measurement}>>,
|
||||
translation: SharedValue<number>,
|
||||
) {
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
type StyleProp,
|
||||
type ViewStyle,
|
||||
} from 'react-native'
|
||||
import {type GestureType} from 'react-native-gesture-handler'
|
||||
import {type PanGesture} from 'react-native-gesture-handler'
|
||||
import {type SharedValue} from 'react-native-reanimated'
|
||||
|
||||
import type * as Dialog from '#/components/Dialog'
|
||||
@@ -89,7 +89,7 @@ export type TriggerProps = {
|
||||
style?: StyleProp<ViewStyle>
|
||||
/**
|
||||
* Callback for single taps. Composed with the double-tap and
|
||||
* press-and-hold gestures via `Gesture.Exclusive`, so a double tap
|
||||
* press-and-hold gestures via `useExclusiveGestures`, so a double tap
|
||||
* does not also fire this handler.
|
||||
*
|
||||
* @platform ios, android
|
||||
@@ -97,12 +97,13 @@ export type TriggerProps = {
|
||||
onTap?: () => void
|
||||
/**
|
||||
* An optional gesture (e.g. swipe-to-reply) composed into the same
|
||||
* arbitration group as the tap and press-and-hold gestures via `Gesture.Race`,
|
||||
* making it mutually exclusive with them - only one can win a given touch.
|
||||
* arbitration group as the tap and press-and-hold gestures via
|
||||
* `useCompetingGestures`, making it mutually exclusive with them - only one
|
||||
* can win a given touch.
|
||||
*
|
||||
* @platform ios, android
|
||||
*/
|
||||
swipeGesture?: GestureType
|
||||
swipeGesture?: PanGesture
|
||||
}
|
||||
export type TriggerChildProps =
|
||||
| {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {useLayoutEffect, useRef} from 'react'
|
||||
import {Gesture, GestureDetector} from 'react-native-gesture-handler'
|
||||
import {GestureDetector, usePanGesture} from 'react-native-gesture-handler'
|
||||
import Animated, {
|
||||
type AnimatedRef,
|
||||
measure,
|
||||
@@ -253,8 +253,8 @@ function SortableItem<T>({
|
||||
|
||||
const lastHapticSlot = useSharedValue(-1)
|
||||
|
||||
const gesture = Gesture.Pan()
|
||||
.onStart(() => {
|
||||
const gesture = usePanGesture({
|
||||
onActivate: () => {
|
||||
'worklet'
|
||||
const s = state.get()
|
||||
const mySlot = s.slots[itemKey]
|
||||
@@ -268,8 +268,8 @@ function SortableItem<T>({
|
||||
scheduleOnRN(onDragStart)
|
||||
}
|
||||
scheduleOnRN(playHaptic)
|
||||
})
|
||||
.onChange(e => {
|
||||
},
|
||||
onUpdate: e => {
|
||||
'worklet'
|
||||
const startSlot = state.get().dragStartSlot
|
||||
const minY = -startSlot * itemHeight
|
||||
@@ -287,8 +287,8 @@ function SortableItem<T>({
|
||||
lastHapticSlot.set(clampedSlot)
|
||||
scheduleOnRN(playHaptic, 'Light')
|
||||
}
|
||||
})
|
||||
.onEnd(() => {
|
||||
},
|
||||
onDeactivate: () => {
|
||||
'worklet'
|
||||
// Stop auto-scroll BEFORE the snap animation.
|
||||
isGestureActive.set(false)
|
||||
@@ -338,9 +338,9 @@ function SortableItem<T>({
|
||||
}
|
||||
}),
|
||||
)
|
||||
})
|
||||
// Reset if the gesture is cancelled without onEnd firing.
|
||||
.onFinalize(() => {
|
||||
},
|
||||
// Reset if the gesture is cancelled without onDeactivate firing.
|
||||
onFinalize: () => {
|
||||
'worklet'
|
||||
isGestureActive.set(false)
|
||||
if (state.get().activeKey === itemKey && dragY.get() === 0) {
|
||||
@@ -350,7 +350,8 @@ function SortableItem<T>({
|
||||
scheduleOnRN(onDragEnd)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
// All vertical positioning is via translateY (no `top`). This avoids
|
||||
// discrete jumps when slots change — Reanimated smoothly animates from
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import {memo, useState} from 'react'
|
||||
import {ActivityIndicator, StyleSheet} from 'react-native'
|
||||
import {
|
||||
Gesture,
|
||||
GestureDetector,
|
||||
type PanGesture,
|
||||
useExclusiveGestures,
|
||||
useManualGesture,
|
||||
usePanGesture,
|
||||
usePinchGesture,
|
||||
useSimultaneousGestures,
|
||||
useTapGesture,
|
||||
} from 'react-native-gesture-handler'
|
||||
import Animated, {
|
||||
type AnimatableValue,
|
||||
@@ -137,16 +142,16 @@ const ImageItem = ({
|
||||
return [dx, dy]
|
||||
}
|
||||
|
||||
const pinch = Gesture.Pinch()
|
||||
.onStart(e => {
|
||||
const pinch = usePinchGesture({
|
||||
onActivate: e => {
|
||||
'worklet'
|
||||
const screenSize = measureSafeArea()
|
||||
pinchOrigin.set({
|
||||
x: e.focalX - screenSize.width / 2,
|
||||
y: e.focalY - screenSize.height / 2,
|
||||
})
|
||||
})
|
||||
.onChange(e => {
|
||||
},
|
||||
onUpdate: e => {
|
||||
'worklet'
|
||||
const screenSize = measureSafeArea()
|
||||
if (!imageDimensions) {
|
||||
@@ -181,8 +186,8 @@ const ImageItem = ({
|
||||
y: pt.y + dy,
|
||||
})
|
||||
}
|
||||
})
|
||||
.onEnd(() => {
|
||||
},
|
||||
onDeactivate: () => {
|
||||
'worklet'
|
||||
// Commit just the pinch.
|
||||
let t = createTransform()
|
||||
@@ -200,13 +205,14 @@ const ImageItem = ({
|
||||
pinchScale.set(1)
|
||||
pinchOrigin.set({x: 0, y: 0})
|
||||
pinchTranslation.set({x: 0, y: 0})
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
const pan = Gesture.Pan()
|
||||
.averageTouches(true)
|
||||
// Unlike .enabled(isScaled), this ensures that an initial pinch can turn into a pan midway:
|
||||
.minPointers(isScaled ? 1 : 2)
|
||||
.onChange(e => {
|
||||
const pan = usePanGesture({
|
||||
averageTouches: true,
|
||||
// Unlike enabled: isScaled, this ensures that an initial pinch can turn into a pan midway:
|
||||
minPointers: isScaled ? 1 : 2,
|
||||
onUpdate: e => {
|
||||
'worklet'
|
||||
const screenSize = measureSafeArea()
|
||||
if (!imageDimensions) {
|
||||
@@ -229,8 +235,8 @@ const ImageItem = ({
|
||||
nextPanTranslation.x += dx
|
||||
nextPanTranslation.y += dy
|
||||
panTranslation.set(nextPanTranslation)
|
||||
})
|
||||
.onEnd(() => {
|
||||
},
|
||||
onDeactivate: () => {
|
||||
'worklet'
|
||||
// Commit just the pan.
|
||||
let t = createTransform()
|
||||
@@ -241,16 +247,19 @@ const ImageItem = ({
|
||||
|
||||
// Reset just the pan.
|
||||
panTranslation.set({x: 0, y: 0})
|
||||
})
|
||||
|
||||
const singleTap = Gesture.Tap().onEnd(() => {
|
||||
'worklet'
|
||||
scheduleOnRN(onTap)
|
||||
},
|
||||
})
|
||||
|
||||
const doubleTap = Gesture.Tap()
|
||||
.numberOfTaps(2)
|
||||
.onEnd(e => {
|
||||
const singleTap = useTapGesture({
|
||||
onDeactivate: () => {
|
||||
'worklet'
|
||||
scheduleOnRN(onTap)
|
||||
},
|
||||
})
|
||||
|
||||
const doubleTap = useTapGesture({
|
||||
numberOfTaps: 2,
|
||||
onDeactivate: e => {
|
||||
'worklet'
|
||||
const screenSize = measureSafeArea()
|
||||
if (!imageDimensions || !imageAspect) {
|
||||
@@ -295,17 +304,21 @@ const ImageItem = ({
|
||||
const finalTransform = createTransform()
|
||||
prependPinch(finalTransform, scale, origin, {x: dx, y: dy})
|
||||
committedTransform.set(withClampedSpring(finalTransform))
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
// If the parent is not at rest, provide a no-op gesture.
|
||||
const noopGesture = useManualGesture()
|
||||
const pinchAndPan = useSimultaneousGestures(pinch, pan)
|
||||
const exclusiveGesture = useExclusiveGestures(
|
||||
dismissSwipePan,
|
||||
pinchAndPan,
|
||||
doubleTap,
|
||||
singleTap,
|
||||
)
|
||||
const composedGesture = isScrollViewBeingDragged
|
||||
? // If the parent is not at rest, provide a no-op gesture.
|
||||
Gesture.Manual()
|
||||
: Gesture.Exclusive(
|
||||
dismissSwipePan,
|
||||
Gesture.Simultaneous(pinch, pan),
|
||||
doubleTap,
|
||||
singleTap,
|
||||
)
|
||||
? noopGesture
|
||||
: exclusiveGesture
|
||||
|
||||
const containerStyle = useAnimatedStyle(() => {
|
||||
const {scaleAndMoveTransform, isHidden} = transforms.get()
|
||||
|
||||
@@ -9,9 +9,10 @@
|
||||
import {memo, useState} from 'react'
|
||||
import {ActivityIndicator, StyleSheet} from 'react-native'
|
||||
import {
|
||||
Gesture,
|
||||
GestureDetector,
|
||||
type PanGesture,
|
||||
useExclusiveGestures,
|
||||
useTapGesture,
|
||||
} from 'react-native-gesture-handler'
|
||||
import Animated, {
|
||||
type SharedValue,
|
||||
@@ -115,14 +116,16 @@ const ImageItem = ({
|
||||
})
|
||||
}
|
||||
|
||||
const singleTap = Gesture.Tap().onEnd(() => {
|
||||
'worklet'
|
||||
scheduleOnRN(onTap)
|
||||
const singleTap = useTapGesture({
|
||||
onDeactivate: () => {
|
||||
'worklet'
|
||||
scheduleOnRN(onTap)
|
||||
},
|
||||
})
|
||||
|
||||
const doubleTap = Gesture.Tap()
|
||||
.numberOfTaps(2)
|
||||
.onEnd(e => {
|
||||
const doubleTap = useTapGesture({
|
||||
numberOfTaps: 2,
|
||||
onDeactivate: e => {
|
||||
'worklet'
|
||||
const screenSize = measureSafeArea()
|
||||
const {absoluteX, absoluteY} = e
|
||||
@@ -142,9 +145,10 @@ const ImageItem = ({
|
||||
)
|
||||
}
|
||||
scheduleOnRN(zoomTo, nextZoomRect)
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
const composedGesture = Gesture.Exclusive(
|
||||
const composedGesture = useExclusiveGestures(
|
||||
dismissSwipePan,
|
||||
doubleTap,
|
||||
singleTap,
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
import {useCallback, useEffect, useMemo, useState} from 'react'
|
||||
import {PixelRatio, StyleSheet, useWindowDimensions, View} from 'react-native'
|
||||
import {SystemBars} from 'react-native-edge-to-edge'
|
||||
import {Gesture} from 'react-native-gesture-handler'
|
||||
import {usePanGesture} from 'react-native-gesture-handler'
|
||||
import PagerView, {
|
||||
type PagerViewOnPageSelectedEvent,
|
||||
type PageScrollStateChangedNativeEvent,
|
||||
@@ -566,19 +566,19 @@ function LightboxImage({
|
||||
}
|
||||
})
|
||||
|
||||
const dismissSwipePan = Gesture.Pan()
|
||||
.enabled(isActive && !isScaled)
|
||||
.activeOffsetY([-10, 10])
|
||||
.failOffsetX([-10, 10])
|
||||
.maxPointers(1)
|
||||
.onUpdate(e => {
|
||||
const dismissSwipePan = usePanGesture({
|
||||
enabled: isActive && !isScaled,
|
||||
activeOffsetY: [-10, 10],
|
||||
failOffsetX: [-10, 10],
|
||||
maxPointers: 1,
|
||||
onUpdate: e => {
|
||||
'worklet'
|
||||
if (openProgress.get() !== 1 || isFlyingAway.get()) {
|
||||
return
|
||||
}
|
||||
dismissSwipeTranslateY.set(e.translationY)
|
||||
})
|
||||
.onEnd(e => {
|
||||
},
|
||||
onDeactivate: e => {
|
||||
'worklet'
|
||||
if (openProgress.get() !== 1 || isFlyingAway.get()) {
|
||||
return
|
||||
@@ -608,7 +608,8 @@ function LightboxImage({
|
||||
}),
|
||||
)
|
||||
}
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
return (
|
||||
<ImageItem
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {memo, useCallback} from 'react'
|
||||
import {Platform} from 'react-native'
|
||||
import {type GestureType} from 'react-native-gesture-handler'
|
||||
import {type PanGesture} from 'react-native-gesture-handler'
|
||||
import * as Clipboard from 'expo-clipboard'
|
||||
import {type ModerationOpts} from '@bsky/sdk/moderation'
|
||||
import {RichText} from '@bsky/sdk/richtext'
|
||||
@@ -47,7 +47,7 @@ export let MessageContextMenu = ({
|
||||
* Native only. A swipe gesture (swipe-to-reply) composed into the trigger's
|
||||
* gesture group so it's mutually exclusive with the tap and long-press.
|
||||
*/
|
||||
swipeGesture?: GestureType
|
||||
swipeGesture?: PanGesture
|
||||
}): React.ReactNode => {
|
||||
const {t: l, i18n} = useLingui()
|
||||
const ax = useAnalytics()
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {useMemo} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {Gesture, type GestureType} from 'react-native-gesture-handler'
|
||||
import {type PanGesture, usePanGesture} from 'react-native-gesture-handler'
|
||||
import Animated, {
|
||||
clamp,
|
||||
interpolate,
|
||||
@@ -52,8 +51,9 @@ function applyResistance(value: number) {
|
||||
*
|
||||
* The pan gesture is built here but handed to `children` via a render prop so
|
||||
* the consumer can compose it into the message's context-menu gestures with
|
||||
* `Gesture.Exclusive`. Sharing one arbitration group is what makes the swipe
|
||||
* and the long-press mutually exclusive - only one can ever win the touch.
|
||||
* `useCompetingGestures`. Sharing one arbitration group is what makes the
|
||||
* swipe and the long-press mutually exclusive - only one can ever win the
|
||||
* touch.
|
||||
*/
|
||||
export function SwipeToReply({
|
||||
isFromSelf,
|
||||
@@ -64,7 +64,7 @@ export function SwipeToReply({
|
||||
isFromSelf: boolean
|
||||
onReply: () => void
|
||||
enabled?: boolean
|
||||
children: (swipeGesture: GestureType) => React.ReactNode
|
||||
children: (swipeGesture: PanGesture) => React.ReactNode
|
||||
}) {
|
||||
const t = useTheme()
|
||||
const playHaptic = useHaptics()
|
||||
@@ -74,73 +74,56 @@ export function SwipeToReply({
|
||||
const hit = useSharedValue(false)
|
||||
const iconScale = useSharedValue(1)
|
||||
|
||||
const swipeGesture = useMemo(() => {
|
||||
const runPop = () => {
|
||||
'worklet'
|
||||
if (isReducedMotion) return
|
||||
iconScale.set(
|
||||
withSequence(
|
||||
withTiming(1.2, {duration: 175}),
|
||||
withTiming(1, {duration: 100}),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
Gesture.Pan()
|
||||
.enabled(enabled)
|
||||
// Arm only on the inward axis; the outward direction is effectively
|
||||
// disabled so the bubble can't be dragged off its own edge.
|
||||
.activeOffsetX(
|
||||
isFromSelf
|
||||
? [-10, EFFECTIVELY_DISABLED_OFFSET]
|
||||
: [-EFFECTIVELY_DISABLED_OFFSET, 10],
|
||||
)
|
||||
.activeOffsetY([
|
||||
-EFFECTIVELY_DISABLED_OFFSET,
|
||||
EFFECTIVELY_DISABLED_OFFSET,
|
||||
])
|
||||
.onChange(e => {
|
||||
'worklet'
|
||||
const dir = isFromSelf
|
||||
? Math.min(e.translationX, 0)
|
||||
: Math.max(e.translationX, 0)
|
||||
transX.set(applyResistance(dir))
|
||||
|
||||
const pastThreshold = Math.abs(transX.get()) >= ACTIVATION_THRESHOLD
|
||||
if (pastThreshold && !hit.get()) {
|
||||
hit.set(true)
|
||||
runPop()
|
||||
scheduleOnRN(playHaptic, 'Medium')
|
||||
} else if (!pastThreshold && hit.get()) {
|
||||
hit.set(false)
|
||||
}
|
||||
})
|
||||
.onEnd(() => {
|
||||
'worklet'
|
||||
// Only a clean end (finger lifted past threshold) triggers the reply.
|
||||
if (hit.get()) {
|
||||
scheduleOnRN(onReply)
|
||||
}
|
||||
})
|
||||
.onFinalize(() => {
|
||||
'worklet'
|
||||
// Runs on both end and cancellation, so the bubble always animates
|
||||
// home even if the gesture is interrupted mid-swipe.
|
||||
transX.set(withTiming(0, {duration: 200}))
|
||||
hit.set(false)
|
||||
})
|
||||
const runPop = () => {
|
||||
'worklet'
|
||||
if (isReducedMotion) return
|
||||
iconScale.set(
|
||||
withSequence(
|
||||
withTiming(1.2, {duration: 175}),
|
||||
withTiming(1, {duration: 100}),
|
||||
),
|
||||
)
|
||||
}, [
|
||||
isFromSelf,
|
||||
}
|
||||
|
||||
const swipeGesture = usePanGesture({
|
||||
enabled,
|
||||
onReply,
|
||||
playHaptic,
|
||||
isReducedMotion,
|
||||
transX,
|
||||
hit,
|
||||
iconScale,
|
||||
])
|
||||
// Arm only on the inward axis; the outward direction is effectively
|
||||
// disabled so the bubble can't be dragged off its own edge.
|
||||
activeOffsetX: isFromSelf
|
||||
? [-10, EFFECTIVELY_DISABLED_OFFSET]
|
||||
: [-EFFECTIVELY_DISABLED_OFFSET, 10],
|
||||
activeOffsetY: [-EFFECTIVELY_DISABLED_OFFSET, EFFECTIVELY_DISABLED_OFFSET],
|
||||
onUpdate: e => {
|
||||
'worklet'
|
||||
const dir = isFromSelf
|
||||
? Math.min(e.translationX, 0)
|
||||
: Math.max(e.translationX, 0)
|
||||
transX.set(applyResistance(dir))
|
||||
|
||||
const pastThreshold = Math.abs(transX.get()) >= ACTIVATION_THRESHOLD
|
||||
if (pastThreshold && !hit.get()) {
|
||||
hit.set(true)
|
||||
runPop()
|
||||
scheduleOnRN(playHaptic, 'Medium')
|
||||
} else if (!pastThreshold && hit.get()) {
|
||||
hit.set(false)
|
||||
}
|
||||
},
|
||||
onDeactivate: () => {
|
||||
'worklet'
|
||||
// Only a clean end (finger lifted past threshold) triggers the reply.
|
||||
if (hit.get()) {
|
||||
scheduleOnRN(onReply)
|
||||
}
|
||||
},
|
||||
onFinalize: () => {
|
||||
'worklet'
|
||||
// Runs on both end and cancellation, so the bubble always animates
|
||||
// home even if the gesture is interrupted mid-swipe.
|
||||
transX.set(withTiming(0, {duration: 200}))
|
||||
hit.set(false)
|
||||
},
|
||||
})
|
||||
|
||||
const contentStyle = useAnimatedStyle(() => ({
|
||||
transform: [{translateX: transX.get()}],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {useMemo, useState} from 'react'
|
||||
import {type ColorValue, Dimensions, View} from 'react-native'
|
||||
import {Gesture, GestureDetector} from 'react-native-gesture-handler'
|
||||
import {GestureDetector, usePanGesture} from 'react-native-gesture-handler'
|
||||
import Animated, {
|
||||
clamp,
|
||||
interpolate,
|
||||
@@ -106,17 +106,17 @@ export function GestureActionView({
|
||||
// Absurdly high value so it doesn't interfere with the pan gestures above (i.e., scroll)
|
||||
// reanimated doesn't offer great support for disabling y/x axes :/
|
||||
const effectivelyDisabledOffset = 200
|
||||
const panGesture = Gesture.Pan()
|
||||
.activeOffsetX([
|
||||
const panGesture = usePanGesture({
|
||||
activeOffsetX: [
|
||||
actions.leftFirst ? -10 : -effectivelyDisabledOffset,
|
||||
actions.rightFirst ? 10 : effectivelyDisabledOffset,
|
||||
])
|
||||
.activeOffsetY([-effectivelyDisabledOffset, effectivelyDisabledOffset])
|
||||
.onStart(() => {
|
||||
],
|
||||
activeOffsetY: [-effectivelyDisabledOffset, effectivelyDisabledOffset],
|
||||
onActivate: () => {
|
||||
'worklet'
|
||||
isActive.set(true)
|
||||
})
|
||||
.onChange(e => {
|
||||
},
|
||||
onUpdate: e => {
|
||||
'worklet'
|
||||
transX.set(e.translationX)
|
||||
|
||||
@@ -189,8 +189,8 @@ export function GestureActionView({
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.onEnd(e => {
|
||||
},
|
||||
onDeactivate: e => {
|
||||
'worklet'
|
||||
if (e.translationX < 0) {
|
||||
if (hitSecond.get() && actions.leftSecond) {
|
||||
@@ -209,9 +209,8 @@ export function GestureActionView({
|
||||
hitFirst.set(false)
|
||||
hitSecond.set(false)
|
||||
isActive.set(false)
|
||||
})
|
||||
|
||||
const composedGesture = Gesture.Simultaneous(panGesture)
|
||||
},
|
||||
})
|
||||
|
||||
const animatedSliderStyle = useAnimatedStyle(() => {
|
||||
return {
|
||||
@@ -286,7 +285,7 @@ export function GestureActionView({
|
||||
})
|
||||
|
||||
return (
|
||||
<GestureDetector gesture={composedGesture}>
|
||||
<GestureDetector gesture={panGesture}>
|
||||
<View>
|
||||
<Animated.View style={[a.absolute, a.inset_0, animatedBackgroundStyle]}>
|
||||
<View
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import {useCallback, useMemo, useState} from 'react'
|
||||
import {useCallback, useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {
|
||||
Gesture,
|
||||
GestureDetector,
|
||||
type NativeGesture,
|
||||
usePanGesture,
|
||||
} from 'react-native-gesture-handler'
|
||||
import Animated, {
|
||||
clamp,
|
||||
@@ -85,48 +85,38 @@ export function Scrubber({
|
||||
[player, isSeekingSV, seekingAnimationSV],
|
||||
)
|
||||
|
||||
const scrubPanGesture = useMemo(() => {
|
||||
return Gesture.Pan()
|
||||
.blocksExternalGesture(scrollGesture)
|
||||
.activeOffsetX([-10, 10])
|
||||
.failOffsetY([-10, 10])
|
||||
.onStart(() => {
|
||||
'worklet'
|
||||
seekProgressSV.set(currentTimeSV.get())
|
||||
isSeekingSV.set(true)
|
||||
seekingAnimationSV.set(withTiming(1, {duration: 500}))
|
||||
})
|
||||
.onUpdate(evt => {
|
||||
'worklet'
|
||||
const progress = evt.x / screenWidth
|
||||
seekProgressSV.set(
|
||||
clamp(progress * durationSV.get(), 0, durationSV.get()),
|
||||
)
|
||||
})
|
||||
.onEnd(evt => {
|
||||
'worklet'
|
||||
isSeekingSV.get()
|
||||
const scrubPanGesture = usePanGesture({
|
||||
block: scrollGesture,
|
||||
activeOffsetX: [-10, 10],
|
||||
failOffsetY: [-10, 10],
|
||||
onActivate: () => {
|
||||
'worklet'
|
||||
seekProgressSV.set(currentTimeSV.get())
|
||||
isSeekingSV.set(true)
|
||||
seekingAnimationSV.set(withTiming(1, {duration: 500}))
|
||||
},
|
||||
onUpdate: evt => {
|
||||
'worklet'
|
||||
const progress = evt.x / screenWidth
|
||||
seekProgressSV.set(
|
||||
clamp(progress * durationSV.get(), 0, durationSV.get()),
|
||||
)
|
||||
},
|
||||
onDeactivate: evt => {
|
||||
'worklet'
|
||||
isSeekingSV.get()
|
||||
|
||||
const progress = evt.x / screenWidth
|
||||
const newTime = clamp(progress * durationSV.get(), 0, durationSV.get())
|
||||
const progress = evt.x / screenWidth
|
||||
const newTime = clamp(progress * durationSV.get(), 0, durationSV.get())
|
||||
|
||||
// optimisically set the progress bar
|
||||
seekProgressSV.set(newTime)
|
||||
// optimisically set the progress bar
|
||||
seekProgressSV.set(newTime)
|
||||
|
||||
// it's seek by, so offset by the current time
|
||||
// seekBy sets isSeekingSV back to false, so no need to do that here
|
||||
scheduleOnRN(seekBy, newTime - currentTimeSV.get())
|
||||
})
|
||||
}, [
|
||||
scrollGesture,
|
||||
seekingAnimationSV,
|
||||
seekBy,
|
||||
screenWidth,
|
||||
currentTimeSV,
|
||||
durationSV,
|
||||
isSeekingSV,
|
||||
seekProgressSV,
|
||||
])
|
||||
// it's seek by, so offset by the current time
|
||||
// seekBy sets isSeekingSV back to false, so no need to do that here
|
||||
scheduleOnRN(seekBy, newTime - currentTimeSV.get())
|
||||
},
|
||||
})
|
||||
|
||||
const timeStyle = useAnimatedStyle(() => {
|
||||
return {
|
||||
|
||||
@@ -7,9 +7,9 @@ import {
|
||||
View,
|
||||
} from 'react-native'
|
||||
import {
|
||||
Gesture,
|
||||
GestureDetector,
|
||||
type NativeGesture,
|
||||
useNativeGesture,
|
||||
} from 'react-native-gesture-handler'
|
||||
import Animated, {
|
||||
useAnimatedStyle,
|
||||
@@ -258,7 +258,7 @@ function Feed() {
|
||||
|
||||
const [currentIndex, setCurrentIndex] = useState(0)
|
||||
|
||||
const scrollGesture = useMemo(() => Gesture.Native(), [])
|
||||
const scrollGesture = useNativeGesture()
|
||||
|
||||
const renderItem: ListRenderItem<VideoItem> = useCallback(
|
||||
({item, index}) => {
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
import {createContext, useContext, useMemo, useRef, useState} from 'react'
|
||||
import {type StyleProp, View, type ViewStyle} from 'react-native'
|
||||
import {
|
||||
Gesture,
|
||||
GestureDetector,
|
||||
type GestureStateChangeEvent,
|
||||
type GestureUpdateEvent,
|
||||
type PanGestureHandlerEventPayload,
|
||||
type PanGestureActiveEvent,
|
||||
type PanGestureEvent,
|
||||
usePanGesture,
|
||||
} from 'react-native-gesture-handler'
|
||||
import {EventEmitter} from 'eventemitter3'
|
||||
|
||||
export type GlobalGestureEvents = {
|
||||
begin: GestureStateChangeEvent<PanGestureHandlerEventPayload>
|
||||
update: GestureUpdateEvent<PanGestureHandlerEventPayload>
|
||||
end: GestureStateChangeEvent<PanGestureHandlerEventPayload>
|
||||
finalize: GestureStateChangeEvent<PanGestureHandlerEventPayload>
|
||||
begin: PanGestureEvent
|
||||
update: PanGestureActiveEvent
|
||||
end: PanGestureActiveEvent & {canceled: boolean}
|
||||
finalize: PanGestureEvent & {canceled: boolean}
|
||||
}
|
||||
|
||||
const Context = createContext<{
|
||||
@@ -55,22 +54,22 @@ export function GlobalGestureEventsProvider({
|
||||
}),
|
||||
[events, setEnabled],
|
||||
)
|
||||
const gesture = Gesture.Pan()
|
||||
.runOnJS(true)
|
||||
.enabled(enabled)
|
||||
.simultaneousWithExternalGesture()
|
||||
.onBegin(e => {
|
||||
const gesture = usePanGesture({
|
||||
runOnJS: true,
|
||||
enabled,
|
||||
onBegin: e => {
|
||||
events.emit('begin', e)
|
||||
})
|
||||
.onUpdate(e => {
|
||||
},
|
||||
onUpdate: e => {
|
||||
events.emit('update', e)
|
||||
})
|
||||
.onEnd(e => {
|
||||
},
|
||||
onDeactivate: e => {
|
||||
events.emit('end', e)
|
||||
})
|
||||
.onFinalize(e => {
|
||||
},
|
||||
onFinalize: e => {
|
||||
events.emit('finalize', e)
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
return (
|
||||
<Context.Provider value={ctx}>
|
||||
|
||||
Reference in New Issue
Block a user