This commit is contained in:
Tomek Zawadzki
2026-07-29 19:57:21 +02:00
committed by Oleksii Bulenok
parent 3d39ca0c0c
commit 95ce988fb7
15 changed files with 279 additions and 313 deletions
+1 -1
View File
@@ -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';
+13 -42
View File
@@ -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)
+49 -54
View File
@@ -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>,
) {
+6 -5
View File
@@ -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 =
| {
+12 -11
View File
@@ -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,
+11 -10
View File
@@ -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
+2 -2
View File
@@ -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()
+53 -70
View File
@@ -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()}],
+13 -14
View File
@@ -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
+31 -41
View File
@@ -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 {
+2 -2
View File
@@ -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}) => {
+19 -20
View File
@@ -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}>