Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
233 commits
Select commit Hold shift + click to select a range
8f79396
Migrating to expo-audio
Rohit3523 Oct 11, 2025
0deffc8
chore: format code with Prettier [skip ci]
Rohit3523 Oct 11, 2025
ac0b630
Recoding with expo-audio
Rohit3523 Oct 12, 2025
2667db7
Merge branch 'expo-audio' of https://github.com/RocketChat/Rocket.Cha…
Rohit3523 Oct 12, 2025
2561d80
chore: format code with Prettier [skip ci]
Rohit3523 Oct 12, 2025
f58a536
reanimated v4 and worklets
Rohit3523 Oct 12, 2025
23ec327
some alignment
Rohit3523 Oct 12, 2025
abab68f
remove unused
Rohit3523 Oct 12, 2025
1514c7e
runOnJs is now scheduleOnRN
Rohit3523 Oct 12, 2025
5f28192
jest update
Rohit3523 Oct 12, 2025
c0a4d25
chore: format code with Prettier [skip ci]
Rohit3523 Oct 12, 2025
f27e9f5
let me trigger ci
Rohit3523 Oct 12, 2025
14ecf41
revert
Rohit3523 Oct 12, 2025
58b5141
Using gorhom bottomsheet
Rohit3523 Oct 12, 2025
a624049
jest and test changes
Rohit3523 Oct 12, 2025
00af6b8
remove patch
Rohit3523 Oct 12, 2025
d181c65
fix type
Rohit3523 Oct 12, 2025
d3f516b
fix import, idk why they did this
Rohit3523 Oct 12, 2025
b2c221d
Project upgrade
Rohit3523 Jan 3, 2026
5e48723
added worklet, more package upgrade and ios changes
Rohit3523 Jan 3, 2026
261b939
react native patch for installing pod
Rohit3523 Jan 3, 2026
b64c1eb
downgrade typescript
Rohit3523 Jan 4, 2026
e1eaf31
extend tsconfig for react native
Rohit3523 Jan 4, 2026
1998f31
patch changes
Rohit3523 Jan 4, 2026
7e7f3d0
chore: format code and fix lint issues [skip ci]
Rohit3523 Jan 4, 2026
64a72f6
Remove ts extends
Rohit3523 Jan 4, 2026
998504c
Merge branch 'react-native-81' of https://github.com/RocketChat/Rocke…
Rohit3523 Jan 4, 2026
691fb63
metro config fix
Rohit3523 Jan 4, 2026
caedf9e
Merge remote-tracking branch 'upstream/develop' into reanimated-v4
Rohit3523 Jan 17, 2026
cbfe560
lint fix
Rohit3523 Jan 17, 2026
8f89ea2
chore: format code and fix lint issues [skip ci]
Rohit3523 Jan 17, 2026
65be6cf
feat: basic setup react-native-true-sheet
OtavioStasiak Feb 6, 2026
08056fb
fix: scroll height
OtavioStasiak Feb 6, 2026
b4a596f
fix: inconsistentaction sheet openning
OtavioStasiak Feb 6, 2026
76cc834
feat: add min height
OtavioStasiak Feb 6, 2026
f03df70
Merge branch 'develop' into expo-audio
Rohit3523 Feb 18, 2026
e13c5a4
revert the bottom sheet changes
Rohit3523 Mar 6, 2026
4fe2c97
revert version
Rohit3523 Mar 6, 2026
64f4dd9
Merge branch 'develop' into reanimated-v4
Rohit3523 Mar 6, 2026
1dba726
lock fix
Rohit3523 Mar 6, 2026
caf9d5a
chore: format code and fix lint issues
Rohit3523 Mar 6, 2026
b0d5d9f
Merge branch 'develop' into test.poc-a11y-bottom-shet
OtavioStasiak Mar 6, 2026
e3ccc64
chore: use Touch instead of pressable
OtavioStasiak Mar 5, 2026
2f535e3
cleanup
OtavioStasiak Mar 6, 2026
3776737
fix: padding on list and custom actionSheet content
OtavioStasiak Mar 6, 2026
7f04181
fix: actionsheet + gesture handler compatibility
OtavioStasiak Mar 6, 2026
40d9fb9
rollback Pressable
OtavioStasiak Mar 6, 2026
f868d6d
fix: pressable emoji
OtavioStasiak Mar 6, 2026
504d378
chore: comment
OtavioStasiak Mar 6, 2026
54698cb
fix: action sheet custom content height
OtavioStasiak Mar 6, 2026
9ed2a82
fix: directory test
OtavioStasiak Mar 6, 2026
baca611
fix: emoji picker
OtavioStasiak Mar 6, 2026
fd97518
fix: close action sheet
OtavioStasiak Mar 9, 2026
deb038d
fix: bottom sheet emoji picker scroll and padding
OtavioStasiak Mar 9, 2026
6afa789
chore: format code and fix lint issues
OtavioStasiak Mar 9, 2026
3937eec
fix: bottomSheet iOS weird padding
OtavioStasiak Mar 9, 2026
acd8675
Merge branch 'develop' into test.poc-a11y-bottom-shet
OtavioStasiak Mar 9, 2026
854b508
fix: add sleep to pass tests
OtavioStasiak Mar 10, 2026
9feee82
fix: e2e tests
OtavioStasiak Mar 10, 2026
b5aaff9
Merge branch 'develop' into reanimated-v4
Rohit3523 Mar 10, 2026
6413650
conflict fix
Rohit3523 Mar 10, 2026
d0f3d39
Merge branch 'develop' into reanimated-v4
Rohit3523 Mar 10, 2026
a8cdebd
Move worklet plugin to last
Rohit3523 Mar 10, 2026
ebe4419
Merge branch 'reanimated-v4' of https://github.com/RocketChat/Rocket.…
Rohit3523 Mar 10, 2026
b054ed4
fix: roomView test
OtavioStasiak Mar 10, 2026
bcbc7fe
fix: e2e tests
OtavioStasiak Mar 10, 2026
8a0d12c
Merge branch 'develop' into test.poc-a11y-bottom-shet
OtavioStasiak Mar 10, 2026
02cd74f
fix: code improvements
OtavioStasiak Mar 11, 2026
e50f3ad
fix: update required height
OtavioStasiak Mar 11, 2026
af3098d
Update patches/@lodev09+react-native-true-sheet+3.7.3.patch
OtavioStasiak Mar 11, 2026
b7c2b2f
code improvements
OtavioStasiak Mar 11, 2026
22ff512
fix: style
OtavioStasiak Mar 11, 2026
cc271ef
chore: format code and fix lint issues
OtavioStasiak Mar 11, 2026
eb37e68
remove unused style
OtavioStasiak Mar 11, 2026
b5a87b7
clean patch package
OtavioStasiak Mar 12, 2026
a0a6854
fix: remove border rounded and fixing padding issues
OtavioStasiak Mar 12, 2026
ebd8f88
fix: list padding
OtavioStasiak Mar 12, 2026
f4defa6
adjust bottom padding
OtavioStasiak Mar 12, 2026
d66c812
fix: android Directory view Actionsheet click and Servers List render
OtavioStasiak Mar 12, 2026
7662c7f
fix: orientation and unit test
OtavioStasiak Mar 12, 2026
88e8b42
Merge branch 'develop' into test.poc-a11y-bottom-shet
OtavioStasiak Mar 12, 2026
c19cadf
chore: format code and fix lint issues
OtavioStasiak Mar 12, 2026
7946eb4
fix: remve highlight of handle
OtavioStasiak Mar 12, 2026
d6a3237
cleanup
OtavioStasiak Mar 13, 2026
6fc21de
more bottom sheet changes
Rohit3523 Mar 14, 2026
7d1f242
adjustment for android
Rohit3523 Mar 15, 2026
301b0c3
chore: format code and fix lint issues
Rohit3523 Mar 15, 2026
8daab95
rerun
Rohit3523 Mar 15, 2026
d23a7e0
revert
Rohit3523 Mar 15, 2026
7c02045
Merge branch 'test.poc-a11y-bottom-shet' of https://github.com/Rocket…
Rohit3523 Mar 15, 2026
38cd2c9
test update
Rohit3523 Mar 15, 2026
930c88a
some improvements
Rohit3523 Mar 16, 2026
d0d218b
fix test
Rohit3523 Mar 16, 2026
3bab462
test fix
Rohit3523 Mar 16, 2026
cd35041
Remove unused bottomSheet prop
Rohit3523 Mar 16, 2026
35b55df
memorise bottom sheet handle
Rohit3523 Mar 16, 2026
50e1ffc
remove unused import
Rohit3523 Mar 16, 2026
ec14b28
ios test fix
Rohit3523 Mar 16, 2026
28d9062
clear timeout
Rohit3523 Mar 16, 2026
fb40b8b
wait for animation to close
Rohit3523 Mar 16, 2026
ae5df9f
Merge branch 'develop' into test.poc-a11y-bottom-shet
Rohit3523 Mar 16, 2026
fdaf544
lint fix
Rohit3523 Mar 16, 2026
05c7b5a
chore: format code and fix lint issues
Rohit3523 Mar 16, 2026
5064359
add comment for extra style
Rohit3523 Mar 16, 2026
650104e
tap on point to hide sheet
Rohit3523 Mar 16, 2026
7144138
Merge branch 'test.poc-a11y-bottom-shet' of https://github.com/Rocket…
Rohit3523 Mar 16, 2026
8db5f90
suggested changes by copilot and copilot
Rohit3523 Mar 17, 2026
d3f23e7
chore: format code and fix lint issues
Rohit3523 Mar 17, 2026
c03938c
revert the test
Rohit3523 Mar 17, 2026
4e7cc2b
Merge branch 'test.poc-a11y-bottom-shet' of https://github.com/Rocket…
Rohit3523 Mar 17, 2026
0e45349
Change sheet min height
Rohit3523 Mar 17, 2026
dbffe97
disable content panning for android
Rohit3523 Mar 17, 2026
d33a796
chore: format code and fix lint issues
Rohit3523 Mar 17, 2026
719c192
rerun
Rohit3523 Mar 17, 2026
1e6da08
revert
Rohit3523 Mar 17, 2026
e8abcf1
test update
Rohit3523 Mar 17, 2026
8b410dc
correct cancel button height
Rohit3523 Mar 19, 2026
b81a3ae
Remove timeout to present sheet
Rohit3523 Mar 19, 2026
4a7a9fb
Merge branch 'develop' into react-native-81
Rohit3523 Mar 19, 2026
709d7d8
chore: format code and fix lint issues
Rohit3523 Mar 19, 2026
9e60c47
Remove space
Rohit3523 Mar 19, 2026
449360a
ios fix
Rohit3523 Mar 19, 2026
9b1713c
Merge branch 'react-native-81' of https://github.com/RocketChat/Rocke…
Rohit3523 Mar 19, 2026
3dc77ca
package align
Rohit3523 Mar 19, 2026
9c25b88
Added bottom sheet in dev because of storybook
Rohit3523 Mar 19, 2026
9ff7576
snap update
Rohit3523 Mar 19, 2026
28d8d4e
Test fix
Rohit3523 Mar 19, 2026
1ddf1c6
test fix
Rohit3523 Mar 5, 2026
54c2e9d
Merge branch 'develop' into reanimated-v4
Rohit3523 Mar 19, 2026
a367e02
chore: format code and fix lint issues
Rohit3523 Mar 19, 2026
2b3e51a
lock file fixed
Rohit3523 Mar 19, 2026
5756896
Merge branch 'develop' into test.poc-a11y-bottom-shet
Rohit3523 Mar 19, 2026
45d1292
increase reaction open time
Rohit3523 Mar 20, 2026
ac20a76
Merge branch 'test.poc-a11y-bottom-shet' of https://github.com/Rocket…
Rohit3523 Mar 20, 2026
cdda960
increase timeout
Rohit3523 Mar 20, 2026
cf08b03
Upgrade to RN 0.81.6
Rohit3523 Mar 20, 2026
cff02b6
Removed deprecated addWhitelistedNativeProps
Rohit3523 Mar 21, 2026
c48a040
Merge branch 'test.poc-a11y-bottom-shet' into reanimated-v4
Rohit3523 Mar 23, 2026
175bd53
Merge branch 'reanimated-v4' into react-native-81
Rohit3523 Mar 23, 2026
1d7d89d
revert to rn 0.81.5
Rohit3523 Mar 23, 2026
bf5c915
snap update
Rohit3523 Mar 23, 2026
5042da6
remove worklet from jest
Rohit3523 Mar 23, 2026
912278c
Replace thumb button with touch
Rohit3523 Mar 23, 2026
2f1ba4a
update expo-file-system import to legacy
Rohit3523 Mar 23, 2026
59cae3a
ts fix
Rohit3523 Mar 23, 2026
1529a23
patch for webview
Rohit3523 Mar 23, 2026
4ed67ee
remove rn web 13.15.0 patch
Rohit3523 Mar 23, 2026
0232059
use custom snapshot serializer
Rohit3523 Mar 23, 2026
01552c7
snapshot update
Rohit3523 Mar 23, 2026
a603042
chore: format code and fix lint issues
Rohit3523 Mar 23, 2026
e9590e3
prettier ;-;
Rohit3523 Mar 23, 2026
063ce88
Merge branch 'react-native-81' of https://github.com/RocketChat/Rocke…
Rohit3523 Mar 23, 2026
f80ab8e
pod update
Rohit3523 Mar 23, 2026
53d9751
fix for expo-file-system in android
Rohit3523 Mar 24, 2026
cdf85b0
Merge branch 'develop' into reanimated-v4
Rohit3523 Mar 24, 2026
4ff6637
pod update
Rohit3523 Mar 24, 2026
c2a6ca4
Merge branch 'develop' into react-native-81
Rohit3523 Mar 24, 2026
31d5e63
lock file fix
Rohit3523 Mar 24, 2026
be5e8e9
Merge branch 'develop' into expo-audio
Rohit3523 Mar 24, 2026
cfc5f2e
enable liquid glass ui
Rohit3523 Mar 24, 2026
2116a2d
list item are not accessible for e2e, so maestro can interact with sw…
Rohit3523 Mar 24, 2026
c8a5cce
chore: format code and fix lint issues
Rohit3523 Mar 24, 2026
291143b
Merge branch 'develop' into react-native-81
Rohit3523 Mar 24, 2026
bdf46e7
Merge branch 'develop' into react-native-81
Rohit3523 Mar 24, 2026
21f08c8
revert last change
Rohit3523 Mar 24, 2026
fd24f10
Merge branch 'react-native-81' of https://github.com/RocketChat/Rocke…
Rohit3523 Mar 24, 2026
8048a08
improve logic...
Rohit3523 Mar 24, 2026
fbe735c
A temp change
Rohit3523 Mar 24, 2026
05cacf5
use rect button
Rohit3523 Mar 25, 2026
be81a47
test update
Rohit3523 Mar 25, 2026
f3c0d50
use match like in accessibility test
Rohit3523 Mar 25, 2026
6929797
ios profile test fix
Rohit3523 Mar 25, 2026
d327896
test fix
Rohit3523 Mar 25, 2026
09d63d8
Added test id in directory
Rohit3523 Mar 25, 2026
951558d
chore: format code and fix lint issues
Rohit3523 Mar 25, 2026
b4cd9b5
path fix ;-;
Rohit3523 Mar 25, 2026
ee7133d
Merge branch 'react-native-81' of https://github.com/RocketChat/Rocke…
Rohit3523 Mar 25, 2026
7f5e04d
coderabbit suggestion
Rohit3523 Mar 25, 2026
88be3cd
coderabbit suggestion
Rohit3523 Mar 25, 2026
6bb597e
Merge branch 'develop' into reanimated-v4
Rohit3523 Mar 25, 2026
03e0ae0
seekbar improvement
Rohit3523 Mar 25, 2026
a130cd1
Replace more runOnJS to scheduleOnRN
Rohit3523 Mar 25, 2026
a541660
Merge branch 'reanimated-v4' of https://github.com/RocketChat/Rocket.…
Rohit3523 Mar 25, 2026
6e35a0b
update seekbar
Rohit3523 Mar 25, 2026
49eb0d8
Merge branch 'reanimated-v4' into react-native-81
Rohit3523 Mar 25, 2026
6d0ef3a
trying to use RectButton in handle
Rohit3523 Mar 25, 2026
4688922
chore: format code and fix lint issues
Rohit3523 Mar 25, 2026
857ea2c
using TouchableNativeFeedback from RNGH
Rohit3523 Mar 26, 2026
8f9b788
readded message parser patch ;-;
Rohit3523 Mar 26, 2026
5646bdf
Merge branch 'react-native-81' of https://github.com/RocketChat/Rocke…
Rohit3523 Mar 26, 2026
9ca79ca
Switch from TouchableNativeFeedback to TouchableHighlight ;-;
Rohit3523 Mar 26, 2026
d169c97
chore: format code and fix lint issues
Rohit3523 Mar 26, 2026
0125108
rerun ci
Rohit3523 Mar 26, 2026
75e2166
revert
Rohit3523 Mar 26, 2026
ee646a4
Merge branch 'react-native-81' into expo-audio
Rohit3523 Mar 30, 2026
062be8f
lint fix
Rohit3523 Mar 30, 2026
10fd51f
eslint fix and api align
Rohit3523 Mar 30, 2026
41aaa31
Added changes for expo-video
Rohit3523 Mar 30, 2026
c9ac652
Remove expo-av
Rohit3523 Mar 30, 2026
f281134
code format
Rohit3523 Mar 30, 2026
4db9e2f
fix react hook rule
Rohit3523 Mar 30, 2026
59278db
remove plugins because it is not needed
Rohit3523 Apr 5, 2026
b01fe2c
fix audio play and seek fix
Rohit3523 Apr 6, 2026
e1c28fd
Merge branch 'develop' into expo-audio
Rohit3523 Apr 23, 2026
78f1f18
Merge branch 'develop' into expo-audio
Rohit3523 Apr 23, 2026
81881b9
changes revert
Rohit3523 Apr 23, 2026
380197d
Merge branch 'expo-audio' of https://github.com/RocketChat/Rocket.Cha…
Rohit3523 Apr 23, 2026
dd072db
chore: format code and fix lint issues
Rohit3523 Apr 23, 2026
097117b
making code rabbit happy
Rohit3523 Apr 23, 2026
0725500
making eslint happy...
Rohit3523 Apr 23, 2026
60f1eba
mock fix
Rohit3523 Apr 23, 2026
f9cc233
more changes
Rohit3523 Apr 23, 2026
e38798f
chore: format code and fix lint issues
Rohit3523 Apr 23, 2026
13ca710
video player fix
Rohit3523 Apr 23, 2026
a819401
Merge branch 'expo-audio' of https://github.com/RocketChat/Rocket.Cha…
Rohit3523 Apr 23, 2026
27182e1
Merge branch 'develop' into expo-audio
Rohit3523 Apr 28, 2026
8682447
Merge branch 'develop' into expo-audio
Rohit3523 May 5, 2026
087c7e8
Merge branch 'develop' into expo-audio
Rohit3523 May 5, 2026
3b9a6a9
pod install
Rohit3523 May 5, 2026
50e459e
Merge branch 'develop' into expo-audio
Rohit3523 May 11, 2026
96d5b49
code update
Rohit3523 May 11, 2026
6ef935f
test update
Rohit3523 May 11, 2026
97f4d75
making code rabbit happy
Rohit3523 May 11, 2026
ed07693
chore: format code and fix lint issues
Rohit3523 May 11, 2026
d74c32a
test fix
Rohit3523 May 11, 2026
b7f988d
Merge branch 'expo-audio' of https://github.com/RocketChat/Rocket.Cha…
Rohit3523 May 11, 2026
f761897
Merge branch 'develop' into expo-audio
Rohit3523 May 11, 2026
1f3a18d
Merge branch 'develop' into expo-audio
Rohit3523 May 26, 2026
a354032
improvements
Rohit3523 May 26, 2026
0bea258
remove expo-av
Rohit3523 May 26, 2026
424f719
Merge branch 'develop' into expo-audio
Rohit3523 May 28, 2026
56be8c6
Merge branch 'develop' into expo-audio
Rohit3523 Jun 8, 2026
01d3838
Merge branch 'develop' into expo-audio
Rohit3523 Jun 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions app/containers/AudioPlayer/Seek.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ interface ISeek {
duration: SharedValue<number>;
currentTime: SharedValue<number>;
loaded: boolean;
onChangeTime: (time: number) => Promise<void>;
onChangeTime: (time: number) => void;
}

function clamp(value: number, min: number, max: number) {
Expand Down Expand Up @@ -49,6 +49,8 @@ const Seek = ({ currentTime, duration, loaded = false, onChangeTime }: ISeek) =>
const scale = useSharedValue(1);
const isPanning = useSharedValue(false);
const contextX = useSharedValue(0);
const savedTranslateX = useSharedValue(0);
const savedCurrentTime = useSharedValue(0);

const styleLine = useAnimatedStyle(() => ({
width: translateX.value
Expand All @@ -69,23 +71,24 @@ const Seek = ({ currentTime, duration, loaded = false, onChangeTime }: ISeek) =>
.onStart(() => {
isPanning.value = true;
contextX.value = translateX.value;
savedTranslateX.value = translateX.value;
savedCurrentTime.value = currentTime.value;
scale.value = withTiming(1.3, { duration: 150 });
})
.onUpdate(event => {
const newX = contextX.value + event.translationX;
translateX.value = clamp(newX, 0, maxWidth.value);
})
.onEnd(() => {
scheduleOnRN(onChangeTime, Math.round(currentTime.value * 1000));
scheduleOnRN(onChangeTime, currentTime.value);
})
Comment thread
coderabbitai[bot] marked this conversation as resolved.
.onFinalize((_, didSucceed) => {
if (isPanning.value && !didSucceed) {
translateX.value = contextX.value;
currentTime.value = (contextX.value * duration.value) / maxWidth.value || 0;
}

.onFinalize(didSucceed => {
isPanning.value = false;
scale.value = withTiming(1, { duration: 150 });
if (!didSucceed) {
translateX.value = savedTranslateX.value;
currentTime.value = savedCurrentTime.value;
}
});
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Comment on lines +85 to 92

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

In react-native-gesture-handler v2 Pan gesture, is onFinalize invoked when the gesture fails activation criteria (e.g., activeOffsetX not met) without onStart ever firing, and what value does didSucceed carry in that case?

💡 Result:

Yes—when using RNGH2’s Pan gesture, onFinalize is invoked even if the gesture never satisfies the activation criteria (e.g., activeOffsetX not met), because onFinalize runs when the gesture transitions to END/FAILED/CANCELLED as long as the gesture has begun (BEGAN), regardless of whether it became ACTIVE. In that failure-to-activate case, didSucceed is false (success argument is false when the gesture transitions to FAILED or CANCELLED rather than END).

Citations:


Guard the rollback against gestures that never activated.

onFinalize fires even when the pan fails activation criteria (e.g., doesn't cross ACTIVE_OFFSET_X). In that case, onStart never runs, leaving savedTranslateX/savedCurrentTime at their initial 0 values (or stale from a prior gesture). The !didSucceed branch then overwrites translateX and currentTime with these bogus snapshots, snapping the thumb to position 0 until the next playback status update reconciles it. Gate the rollback on whether the gesture actually started.

Proposed fix
 	.onEnd(() => {
 		scheduleOnRN(onChangeTime, currentTime.value);
 	})
 	.onFinalize(didSucceed => {
+		const wasPanning = isPanning.value;
 		isPanning.value = false;
 		scale.value = withTiming(1, { duration: 150 });
-		if (!didSucceed) {
+		if (!didSucceed && wasPanning) {
 			translateX.value = savedTranslateX.value;
 			currentTime.value = savedCurrentTime.value;
 		}
 	});
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.onFinalize(didSucceed => {
isPanning.value = false;
scale.value = withTiming(1, { duration: 150 });
if (!didSucceed) {
translateX.value = savedTranslateX.value;
currentTime.value = savedCurrentTime.value;
}
});
.onEnd(() => {
scheduleOnRN(onChangeTime, currentTime.value);
})
.onFinalize(didSucceed => {
const wasPanning = isPanning.value;
isPanning.value = false;
scale.value = withTiming(1, { duration: 150 });
if (!didSucceed && wasPanning) {
translateX.value = savedTranslateX.value;
currentTime.value = savedCurrentTime.value;
}
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/containers/AudioPlayer/Seek.tsx` around lines 86 - 93, The rollback in
the onFinalize handler can run even when the gesture never activated because
onStart didn't run, causing savedTranslateX/savedCurrentTime to be invalid; add
and use a started flag (e.g., started.value or hasStarted boolean) that you set
in the gesture onStart handler and clear onFinalize, and in the onFinalize
!didSucceed branch only restore translateX/currentTime from
savedTranslateX/savedCurrentTime if that started flag is true (then reset the
flag afterwards) so you don't overwrite state when the pan never actually began.


useDerivedValue(() => {
Expand Down
31 changes: 15 additions & 16 deletions app/containers/AudioPlayer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useEffect, useRef, useState } from 'react';
import { InteractionManager, View } from 'react-native';
import { type AVPlaybackStatus } from 'expo-av';
import { activateKeepAwake, deactivateKeepAwake } from 'expo-keep-awake';
import { useSharedValue } from 'react-native-reanimated';
import { useNavigation } from '@react-navigation/native';
import type { AudioStatus } from 'expo-audio';

import { useTheme } from '../../theme';
import styles from './styles';
Expand Down Expand Up @@ -47,35 +47,34 @@
const audioUri = useRef<string>('');
const navigation = useNavigation();

const onPlaybackStatusUpdate = (status: AVPlaybackStatus) => {
const onPlaybackStatusUpdate = (status: AudioStatus) => {
if (status) {
onPlaying(status);
handlePlaybackStatusUpdate(status);
onEnd(status);
}
};

const onPlaying = (data: AVPlaybackStatus) => {
if (data.isLoaded && data.isPlaying) {
const onPlaying = (data: AudioStatus) => {
if (data.isLoaded && data.playing) {
setPaused(false);
} else {
setPaused(true);
}
};

const handlePlaybackStatusUpdate = (data: AVPlaybackStatus) => {
if (data.isLoaded && data.durationMillis) {
const durationSeconds = data.durationMillis / 1000;
duration.value = durationSeconds > 0 ? durationSeconds : 0;
const currentSecond = data.positionMillis / 1000;
if (currentSecond <= durationSeconds) {
currentTime.value = currentSecond;
}
const handlePlaybackStatusUpdate = (data: AudioStatus) => {
if (!data.isLoaded) return;
const durationSeconds = data.duration ?? 0;
duration.value = durationSeconds > 0 ? durationSeconds : 0;
const currentSecond = data.currentTime ?? 0;
Comment on lines +68 to +70

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why ?? instead of ||?

if (currentSecond <= durationSeconds) {
currentTime.value = currentSecond;
}
};
Comment thread
coderabbitai[bot] marked this conversation as resolved.

const onEnd = (data: AVPlaybackStatus) => {
if (data.isLoaded && data.didJustFinish) {
const onEnd = (data: AudioStatus) => {
if (data.isLoaded && data.playbackState === 'ended') {
try {
setPaused(true);
currentTime.value = 0;
Expand All @@ -85,8 +84,8 @@
}
};

const setPosition = async (time: number) => {
await AudioManager.setPositionAsync(audioUri.current, time);
const setPosition = (time: number) => {
AudioManager.setPositionAsync(audioUri.current, time);
};

const togglePlayPause = async () => {
Expand Down Expand Up @@ -128,7 +127,7 @@
});
return () => task.cancel();
}
}, [fileUri, isDownloaded]);

Check warning on line 130 in app/containers/AudioPlayer/index.tsx

View workflow job for this annotation

GitHub Actions / format

React Hook useEffect has missing dependencies: 'msgId', 'onPlaybackStatusUpdate', 'playbackSpeed', and 'rid'. Either include them or remove the dependency array

Check warning on line 130 in app/containers/AudioPlayer/index.tsx

View workflow job for this annotation

GitHub Actions / ESLint and Test / run-eslint-and-test

React Hook useEffect has missing dependencies: 'msgId', 'onPlaybackStatusUpdate', 'playbackSpeed', and 'rid'. Either include them or remove the dependency array

useEffect(() => {
if (paused) {
Expand All @@ -151,7 +150,7 @@
unsubscribeFocus();
unsubscribeBlur();
};
}, [navigation]);

Check warning on line 153 in app/containers/AudioPlayer/index.tsx

View workflow job for this annotation

GitHub Actions / format

React Hook useEffect has a missing dependency: 'onPlaybackStatusUpdate'. Either include it or remove the dependency array

Check warning on line 153 in app/containers/AudioPlayer/index.tsx

View workflow job for this annotation

GitHub Actions / ESLint and Test / run-eslint-and-test

React Hook useEffect has a missing dependency: 'onPlaybackStatusUpdate'. Either include it or remove the dependency array

useEffect(() => {
const audioFocusedEventHandler = (audioFocused: string) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Audio } from 'expo-av';
import { requestRecordingPermissionsAsync, getRecordingPermissionsAsync } from 'expo-audio';
import { useContext, type ReactElement } from 'react';
import { Alert } from 'react-native';
import { PermissionStatus } from 'expo-camera';
Expand All @@ -25,12 +25,12 @@ export const MicOrSendButton = (): ReactElement | null => {
const { setRecordingAudio } = useMessageComposerApi();

const requestPermissionAndStartToRecordAudio = () =>
Audio.requestPermissionsAsync()
requestRecordingPermissionsAsync()
.then(({ granted }) => setRecordingAudio(granted))
.catch(() => {});

const startRecording = async () => {
const { status, granted, canAskAgain } = await Audio.getPermissionsAsync();
const { status, granted, canAskAgain } = await getRecordingPermissionsAsync();
if (granted) return setRecordingAudio(true);
if (status === PermissionStatus.UNDETERMINED) return requestPermissionAndStartToRecordAudio();
if (canAskAgain) return requestPermissionAndStartToRecordAudio();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { forwardRef, useImperativeHandle, useState } from 'react';
import { type FontVariant, Text } from 'react-native';
import { type Audio } from 'expo-av';
import type { RecorderState } from 'expo-audio';

import sharedStyles from '../../../../views/Styles';
import { useTheme } from '../../../../theme';
import { formatTime } from './utils';

export interface IDurationRef {
onRecordingStatusUpdate: (status: Audio.RecordingStatus) => void;
onRecordingStatusUpdate: (status: RecorderState) => void;
}

export const Duration = forwardRef<IDurationRef>((_, ref) => {
Expand All @@ -18,7 +18,7 @@ export const Duration = forwardRef<IDurationRef>((_, ref) => {
onRecordingStatusUpdate
}));

const onRecordingStatusUpdate = (status: Audio.RecordingStatus) => {
const onRecordingStatusUpdate = (status: RecorderState) => {
if (!status.isRecording) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { View, Text } from 'react-native';
import { useEffect, useRef, useState, type ReactElement } from 'react';
import { Audio } from 'expo-av';
import {
RecordingPresets,
requestRecordingPermissionsAsync,
setAudioModeAsync,
useAudioRecorder,
useAudioRecorderState
} from 'expo-audio';
import { getInfoAsync } from 'expo-file-system/legacy';
import { useKeepAwake } from 'expo-keep-awake';
import { shallowEqual } from 'react-redux';
Expand All @@ -12,7 +18,7 @@
import { ReviewButton } from './ReviewButton';
import { useMessageComposerApi } from '../../context';
import { sendFileMessage } from '../../../../lib/methods/sendFileMessage';
import { RECORDING_EXTENSION, RECORDING_MODE, RECORDING_SETTINGS } from '../../../../lib/constants/audio';
import { RECORDING_EXTENSION } from '../../../../lib/constants/audio';
import { useAppSelector } from '../../../../lib/hooks/useAppSelector';
import log from '../../../../lib/methods/helpers/log';
import { type IUpload } from '../../../../definitions';
Expand All @@ -25,9 +31,11 @@

export const RecordAudio = (): ReactElement | null => {
const [styles, colors] = useStyle();
const recordingRef = useRef<Audio.Recording | null>(null);
const audioRecorder = useAudioRecorder(RecordingPresets.HIGH_QUALITY);
const recorderState = useAudioRecorderState(audioRecorder);

const durationRef = useRef<IDurationRef>({} as IDurationRef);
const numberOfTriesRef = useRef(0);

Check failure on line 38 in app/containers/MessageComposer/components/RecordAudio/RecordAudio.tsx

View workflow job for this annotation

GitHub Actions / format

'numberOfTriesRef' is assigned a value but never used

Check failure on line 38 in app/containers/MessageComposer/components/RecordAudio/RecordAudio.tsx

View workflow job for this annotation

GitHub Actions / ESLint and Test / run-eslint-and-test

'numberOfTriesRef' is assigned a value but never used

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔴 Critical | ⚡ Quick win

Remove the unused retry ref to unblock ESLint.

numberOfTriesRef is never read, and static analysis flags this as @typescript-eslint/no-unused-vars.

Proposed fix
-	const numberOfTriesRef = useRef(0);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const numberOfTriesRef = useRef(0);
🧰 Tools
🪛 ESLint

[error] 38-38: 'numberOfTriesRef' is assigned a value but never used.

(@typescript-eslint/no-unused-vars)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/containers/MessageComposer/components/RecordAudio/RecordAudio.tsx` at
line 38, The RecordAudio component has an unused retry ref that triggers ESLint.
Remove numberOfTriesRef from RecordAudio.tsx and clean up any related dead code
or imports so the component only keeps refs and state that are actually read.

Source: Linters/SAST tools

const [status, setStatus] = useState<'recording' | 'reviewing'>('recording');
const { setRecordingAudio } = useMessageComposerApi();
const { rid, tmid } = useRoomContext();
Expand All @@ -36,45 +44,44 @@
const permissionToUpload = useCanUploadFile(rid);
useKeepAwake();

async function doRecording() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason to rename and move away from the effect?

const permissions = await requestRecordingPermissionsAsync();
if (!permissions.granted) {
setRecordingAudio(false);
return;
}

await setAudioModeAsync({
playsInSilentMode: true,
allowsRecording: true
});

await audioRecorder.prepareToRecordAsync();
await audioRecorder.record();
}

useEffect(() => {
const record = async () => {
try {
await Audio.setAudioModeAsync(RECORDING_MODE);
recordingRef.current = new Audio.Recording();
await recordingRef.current.prepareToRecordAsync(RECORDING_SETTINGS);
recordingRef.current.setOnRecordingStatusUpdate(durationRef.current.onRecordingStatusUpdate);
await recordingRef.current.startAsync();
} catch (error: any) {
// error only occurs on iOS devices
if (error?.code === 'E_AUDIO_RECORDERNOTCREATED') {
if (numberOfTriesRef.current <= 5) {
recordingRef.current = null;
numberOfTriesRef.current += 1;
setTimeout(() => {
record();
}, 100);
} else {
console.error(error);
}
} else {
console.error(error);
}
}
};
record();
doRecording().catch(error => {
log(error);
setRecordingAudio(false);
});
Comment thread
coderabbitai[bot] marked this conversation as resolved.

return () => {
try {
recordingRef.current?.stopAndUnloadAsync();
} catch {
audioRecorder.stop().catch(() => {
// Do nothing
}
});
};
}, []);
Comment thread
coderabbitai[bot] marked this conversation as resolved.

useEffect(() => {
if (!durationRef.current) return;

durationRef.current.onRecordingStatusUpdate?.(recorderState);
}, [recorderState]);
Comment thread
coderabbitai[bot] marked this conversation as resolved.

const cancelRecording = async () => {
try {
await recordingRef.current?.stopAndUnloadAsync();
await audioRecorder.stop();
} catch {
// Do nothing
} finally {
Expand All @@ -84,7 +91,7 @@

const goReview = async () => {
try {
await recordingRef.current?.stopAndUnloadAsync();
await audioRecorder.stop();
setStatus('reviewing');
} catch {
// Do nothing
Expand All @@ -95,14 +102,13 @@
try {
if (!rid) return;
setRecordingAudio(false);
const fileURI = recordingRef.current?.getURI();
const fileData = await getInfoAsync(fileURI as string);
const fileData = await getInfoAsync(audioRecorder.uri as string);
const fileInfo = {
name: `${Date.now()}${RECORDING_EXTENSION}`,
mime: 'audio/aac',
type: 'audio/aac',
store: 'Uploads',
path: fileURI,
path: audioRecorder.uri,
size: fileData.exists ? fileData.size : null
} as IUpload;

Expand All @@ -124,7 +130,7 @@
return (
<View style={styles.review}>
<View style={styles.audioPlayer}>
<AudioPlayer fileUri={recordingRef.current?.getURI() ?? ''} rid={rid} downloadState='downloaded' />
<AudioPlayer fileUri={recorderState.url ?? ''} rid={rid} downloadState='downloaded' />
</View>
<View style={styles.buttons}>
<CancelButton onPress={cancelRecording} />
Expand Down
35 changes: 15 additions & 20 deletions app/containers/Ringer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,27 @@
import { Audio } from 'expo-av';
import { useEffect, useRef, memo } from 'react';
import { useAudioPlayer } from 'expo-audio';
import { useEffect, memo } from 'react';

export enum ERingerSounds {
DIALTONE = 'dialtone',
RINGTONE = 'ringtone'
}

const RINGER_SOUND_FILES = {
[ERingerSounds.DIALTONE]: require('./dialtone.mp3'),
[ERingerSounds.RINGTONE]: require('./ringtone.mp3')
} as const;

const Ringer = memo(({ ringer }: { ringer: ERingerSounds }) => {
const sound = useRef(new Audio.Sound());
const player = useAudioPlayer(RINGER_SOUND_FILES[ringer]);

useEffect(() => {
const loadAndPlay = async () => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason to remove the conditional loading?

try {
const soundFile = ringer === ERingerSounds.DIALTONE ? require(`./dialtone.mp3`) : require(`./ringtone.mp3`);
await sound.current.loadAsync(soundFile);
await sound.current.playAsync();
await sound.current.setIsLoopingAsync(true);
} catch (error) {
console.error('Error loading sound:', error);
}
};

loadAndPlay();

return () => {
sound.current?.unloadAsync();
};
}, []);
try {
player.loop = true;
player.play();
} catch (error) {
console.error('Error loading sound:', error);
}
}, [player]);

return null;
});
Expand Down
Loading
Loading