stream-chat-react-native-core 8.10.1 → 8.11.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/components/Attachment/AudioAttachment.js +84 -209
- package/lib/commonjs/components/Attachment/AudioAttachment.js.map +1 -1
- package/lib/commonjs/components/Attachment/FileAttachmentGroup.js +8 -5
- package/lib/commonjs/components/Attachment/FileAttachmentGroup.js.map +1 -1
- package/lib/commonjs/components/AttachmentPicker/components/AttachmentPickerBottomSheetHandle.js +7 -3
- package/lib/commonjs/components/AttachmentPicker/components/AttachmentPickerBottomSheetHandle.js.map +1 -1
- package/lib/commonjs/components/Channel/Channel.js +20 -9
- package/lib/commonjs/components/Channel/Channel.js.map +1 -1
- package/lib/commonjs/components/Message/hooks/useMessageActionHandlers.js +4 -1
- package/lib/commonjs/components/Message/hooks/useMessageActionHandlers.js.map +1 -1
- package/lib/commonjs/components/MessageInput/MessageInput.js +2 -0
- package/lib/commonjs/components/MessageInput/MessageInput.js.map +1 -1
- package/lib/commonjs/components/MessageInput/components/AttachmentPreview/AudioAttachmentUploadPreview.js +9 -3
- package/lib/commonjs/components/MessageInput/components/AttachmentPreview/AudioAttachmentUploadPreview.js.map +1 -1
- package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecordingPreview.js +44 -8
- package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecordingPreview.js.map +1 -1
- package/lib/commonjs/components/MessageInput/hooks/useAudioController.js +5 -0
- package/lib/commonjs/components/MessageInput/hooks/useAudioController.js.map +1 -1
- package/lib/commonjs/components/MessageInput/hooks/useAudioPreviewManager.js.map +1 -1
- package/lib/commonjs/components/ProgressControl/ProgressControl.js +25 -33
- package/lib/commonjs/components/ProgressControl/ProgressControl.js.map +1 -1
- package/lib/commonjs/components/ProgressControl/WaveProgressBar.js +21 -29
- package/lib/commonjs/components/ProgressControl/WaveProgressBar.js.map +1 -1
- package/lib/commonjs/contexts/audioPlayerContext/AudioPlayerContext.js +56 -0
- package/lib/commonjs/contexts/audioPlayerContext/AudioPlayerContext.js.map +1 -0
- package/lib/commonjs/contexts/index.js +11 -0
- package/lib/commonjs/contexts/index.js.map +1 -1
- package/lib/commonjs/contexts/themeContext/utils/theme.js +4 -0
- package/lib/commonjs/contexts/themeContext/utils/theme.js.map +1 -1
- package/lib/commonjs/hooks/index.js +11 -0
- package/lib/commonjs/hooks/index.js.map +1 -1
- package/lib/commonjs/hooks/useAudioPlayer.js +18 -25
- package/lib/commonjs/hooks/useAudioPlayer.js.map +1 -1
- package/lib/commonjs/hooks/useAudioPlayerControl.js +43 -0
- package/lib/commonjs/hooks/useAudioPlayerControl.js.map +1 -0
- package/lib/commonjs/hooks/useInAppNotificationsState.js +1 -1
- package/lib/commonjs/i18n/es.json +1 -2
- package/lib/commonjs/i18n/he.json +5 -5
- package/lib/commonjs/i18n/ru.json +0 -5
- package/lib/commonjs/index.js +4 -4
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/native.js.map +1 -1
- package/lib/commonjs/state-store/audio-player-pool.js +99 -0
- package/lib/commonjs/state-store/audio-player-pool.js.map +1 -0
- package/lib/commonjs/state-store/audio-player.js +373 -0
- package/lib/commonjs/state-store/audio-player.js.map +1 -0
- package/lib/commonjs/state-store/in-app-notifications-store.js.map +1 -0
- package/lib/commonjs/state-store/index.js +37 -0
- package/lib/commonjs/state-store/index.js.map +1 -0
- package/lib/commonjs/version.json +1 -1
- package/lib/module/components/Attachment/AudioAttachment.js +84 -209
- package/lib/module/components/Attachment/AudioAttachment.js.map +1 -1
- package/lib/module/components/Attachment/FileAttachmentGroup.js +8 -5
- package/lib/module/components/Attachment/FileAttachmentGroup.js.map +1 -1
- package/lib/module/components/AttachmentPicker/components/AttachmentPickerBottomSheetHandle.js +7 -3
- package/lib/module/components/AttachmentPicker/components/AttachmentPickerBottomSheetHandle.js.map +1 -1
- package/lib/module/components/Channel/Channel.js +20 -9
- package/lib/module/components/Channel/Channel.js.map +1 -1
- package/lib/module/components/Message/hooks/useMessageActionHandlers.js +4 -1
- package/lib/module/components/Message/hooks/useMessageActionHandlers.js.map +1 -1
- package/lib/module/components/MessageInput/MessageInput.js +2 -0
- package/lib/module/components/MessageInput/MessageInput.js.map +1 -1
- package/lib/module/components/MessageInput/components/AttachmentPreview/AudioAttachmentUploadPreview.js +9 -3
- package/lib/module/components/MessageInput/components/AttachmentPreview/AudioAttachmentUploadPreview.js.map +1 -1
- package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecordingPreview.js +44 -8
- package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecordingPreview.js.map +1 -1
- package/lib/module/components/MessageInput/hooks/useAudioController.js +5 -0
- package/lib/module/components/MessageInput/hooks/useAudioController.js.map +1 -1
- package/lib/module/components/MessageInput/hooks/useAudioPreviewManager.js.map +1 -1
- package/lib/module/components/ProgressControl/ProgressControl.js +25 -33
- package/lib/module/components/ProgressControl/ProgressControl.js.map +1 -1
- package/lib/module/components/ProgressControl/WaveProgressBar.js +21 -29
- package/lib/module/components/ProgressControl/WaveProgressBar.js.map +1 -1
- package/lib/module/contexts/audioPlayerContext/AudioPlayerContext.js +56 -0
- package/lib/module/contexts/audioPlayerContext/AudioPlayerContext.js.map +1 -0
- package/lib/module/contexts/index.js +11 -0
- package/lib/module/contexts/index.js.map +1 -1
- package/lib/module/contexts/themeContext/utils/theme.js +4 -0
- package/lib/module/contexts/themeContext/utils/theme.js.map +1 -1
- package/lib/module/hooks/index.js +11 -0
- package/lib/module/hooks/index.js.map +1 -1
- package/lib/module/hooks/useAudioPlayer.js +18 -25
- package/lib/module/hooks/useAudioPlayer.js.map +1 -1
- package/lib/module/hooks/useAudioPlayerControl.js +43 -0
- package/lib/module/hooks/useAudioPlayerControl.js.map +1 -0
- package/lib/module/hooks/useInAppNotificationsState.js +1 -1
- package/lib/module/i18n/es.json +1 -2
- package/lib/module/i18n/he.json +5 -5
- package/lib/module/i18n/ru.json +0 -5
- package/lib/module/index.js +4 -4
- package/lib/module/index.js.map +1 -1
- package/lib/module/native.js.map +1 -1
- package/lib/module/state-store/audio-player-pool.js +99 -0
- package/lib/module/state-store/audio-player-pool.js.map +1 -0
- package/lib/module/state-store/audio-player.js +373 -0
- package/lib/module/state-store/audio-player.js.map +1 -0
- package/lib/module/state-store/in-app-notifications-store.js.map +1 -0
- package/lib/module/state-store/index.js +37 -0
- package/lib/module/state-store/index.js.map +1 -0
- package/lib/module/version.json +1 -1
- package/lib/typescript/components/Attachment/AudioAttachment.d.ts +25 -5
- package/lib/typescript/components/Attachment/AudioAttachment.d.ts.map +1 -1
- package/lib/typescript/components/Attachment/FileAttachmentGroup.d.ts +2 -1
- package/lib/typescript/components/Attachment/FileAttachmentGroup.d.ts.map +1 -1
- package/lib/typescript/components/AttachmentPicker/components/AttachmentPickerBottomSheetHandle.d.ts.map +1 -1
- package/lib/typescript/components/Channel/Channel.d.ts +5 -0
- package/lib/typescript/components/Channel/Channel.d.ts.map +1 -1
- package/lib/typescript/components/Message/hooks/useMessageActionHandlers.d.ts.map +1 -1
- package/lib/typescript/components/MessageInput/MessageInput.d.ts.map +1 -1
- package/lib/typescript/components/MessageInput/components/AttachmentPreview/AudioAttachmentUploadPreview.d.ts +17 -0
- package/lib/typescript/components/MessageInput/components/AttachmentPreview/AudioAttachmentUploadPreview.d.ts.map +1 -1
- package/lib/typescript/components/MessageInput/components/AudioRecorder/AudioRecordingPreview.d.ts +18 -4
- package/lib/typescript/components/MessageInput/components/AudioRecorder/AudioRecordingPreview.d.ts.map +1 -1
- package/lib/typescript/components/MessageInput/hooks/useAudioController.d.ts +2 -0
- package/lib/typescript/components/MessageInput/hooks/useAudioController.d.ts.map +1 -1
- package/lib/typescript/components/MessageInput/hooks/useAudioPreviewManager.d.ts +2 -0
- package/lib/typescript/components/MessageInput/hooks/useAudioPreviewManager.d.ts.map +1 -1
- package/lib/typescript/components/ProgressControl/ProgressControl.d.ts +2 -0
- package/lib/typescript/components/ProgressControl/ProgressControl.d.ts.map +1 -1
- package/lib/typescript/components/ProgressControl/WaveProgressBar.d.ts.map +1 -1
- package/lib/typescript/contexts/audioPlayerContext/AudioPlayerContext.d.ts +15 -0
- package/lib/typescript/contexts/audioPlayerContext/AudioPlayerContext.d.ts.map +1 -0
- package/lib/typescript/contexts/index.d.ts +1 -0
- package/lib/typescript/contexts/index.d.ts.map +1 -1
- package/lib/typescript/contexts/themeContext/utils/theme.d.ts +4 -0
- package/lib/typescript/contexts/themeContext/utils/theme.d.ts.map +1 -1
- package/lib/typescript/hooks/index.d.ts +1 -0
- package/lib/typescript/hooks/index.d.ts.map +1 -1
- package/lib/typescript/hooks/useAudioPlayer.d.ts +3 -1
- package/lib/typescript/hooks/useAudioPlayer.d.ts.map +1 -1
- package/lib/typescript/hooks/useAudioPlayerControl.d.ts +18 -0
- package/lib/typescript/hooks/useAudioPlayerControl.d.ts.map +1 -0
- package/lib/typescript/i18n/es.json +1 -2
- package/lib/typescript/i18n/he.json +5 -5
- package/lib/typescript/i18n/ru.json +0 -5
- package/lib/typescript/index.d.ts +1 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/native.d.ts +1 -0
- package/lib/typescript/native.d.ts.map +1 -1
- package/lib/typescript/state-store/audio-player-pool.d.ts +24 -0
- package/lib/typescript/state-store/audio-player-pool.d.ts.map +1 -0
- package/lib/typescript/state-store/audio-player.d.ts +62 -0
- package/lib/typescript/state-store/audio-player.d.ts.map +1 -0
- package/lib/typescript/state-store/in-app-notifications-store.d.ts.map +1 -0
- package/lib/typescript/state-store/index.d.ts +4 -0
- package/lib/typescript/state-store/index.d.ts.map +1 -0
- package/package.json +6 -5
- package/src/components/Attachment/AudioAttachment.tsx +118 -198
- package/src/components/Attachment/FileAttachmentGroup.tsx +35 -16
- package/src/components/AttachmentPicker/components/AttachmentPickerBottomSheetHandle.tsx +5 -2
- package/src/components/Channel/Channel.tsx +21 -4
- package/src/components/Message/hooks/useMessageActionHandlers.ts +3 -1
- package/src/components/MessageInput/MessageInput.tsx +6 -0
- package/src/components/MessageInput/components/AttachmentPreview/AudioAttachmentUploadPreview.tsx +29 -2
- package/src/components/MessageInput/components/AudioRecorder/AudioRecordingPreview.tsx +73 -9
- package/src/components/MessageInput/hooks/useAudioController.tsx +62 -1
- package/src/components/MessageInput/hooks/useAudioPreviewManager.tsx +28 -5
- package/src/components/ProgressControl/ProgressControl.tsx +45 -47
- package/src/components/ProgressControl/WaveProgressBar.tsx +37 -36
- package/src/contexts/audioPlayerContext/AudioPlayerContext.tsx +55 -0
- package/src/contexts/index.ts +1 -0
- package/src/contexts/themeContext/utils/theme.ts +8 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useAudioPlayer.ts +7 -8
- package/src/hooks/useAudioPlayerControl.ts +59 -0
- package/src/hooks/useInAppNotificationsState.ts +2 -2
- package/src/i18n/es.json +1 -2
- package/src/i18n/he.json +5 -5
- package/src/i18n/ru.json +0 -5
- package/src/index.ts +1 -1
- package/src/native.ts +1 -0
- package/src/state-store/audio-player-pool.ts +94 -0
- package/src/state-store/audio-player.ts +372 -0
- package/src/state-store/index.ts +3 -0
- package/src/version.json +1 -1
- package/lib/commonjs/store/in-app-notifications-store.js.map +0 -1
- package/lib/commonjs/store/index.js +0 -15
- package/lib/commonjs/store/index.js.map +0 -1
- package/lib/module/store/in-app-notifications-store.js.map +0 -1
- package/lib/module/store/index.js +0 -15
- package/lib/module/store/index.js.map +0 -1
- package/lib/typescript/store/in-app-notifications-store.d.ts.map +0 -1
- package/lib/typescript/store/index.d.ts +0 -2
- package/lib/typescript/store/index.d.ts.map +0 -1
- package/src/store/index.ts +0 -1
- /package/lib/commonjs/{store → state-store}/in-app-notifications-store.js +0 -0
- /package/lib/module/{store → state-store}/in-app-notifications-store.js +0 -0
- /package/lib/typescript/{store → state-store}/in-app-notifications-store.d.ts +0 -0
- /package/src/{store → state-store}/in-app-notifications-store.ts +0 -0
|
@@ -52,6 +52,10 @@ import {
|
|
|
52
52
|
AttachmentPickerProvider,
|
|
53
53
|
MessageContextValue,
|
|
54
54
|
} from '../../contexts';
|
|
55
|
+
import {
|
|
56
|
+
AudioPlayerContextProps,
|
|
57
|
+
AudioPlayerProvider,
|
|
58
|
+
} from '../../contexts/audioPlayerContext/AudioPlayerContext';
|
|
55
59
|
import { ChannelContextValue, ChannelProvider } from '../../contexts/channelContext/ChannelContext';
|
|
56
60
|
import type { UseChannelStateValue } from '../../contexts/channelsStateContext/useChannelState';
|
|
57
61
|
import { useChannelState } from '../../contexts/channelsStateContext/useChannelState';
|
|
@@ -500,6 +504,11 @@ export type ChannelPropsWithContext = Pick<ChannelContextValue, 'channel'> &
|
|
|
500
504
|
*/
|
|
501
505
|
newMessageStateUpdateThrottleInterval?: number;
|
|
502
506
|
overrideOwnCapabilities?: Partial<OwnCapabilitiesContextValue>;
|
|
507
|
+
/**
|
|
508
|
+
* If true, multiple audio players will be allowed to play simultaneously
|
|
509
|
+
* @default true
|
|
510
|
+
*/
|
|
511
|
+
allowConcurrentAudioPlayback?: boolean;
|
|
503
512
|
stateUpdateThrottleInterval?: number;
|
|
504
513
|
/**
|
|
505
514
|
* Tells if channel is rendering a thread list
|
|
@@ -533,6 +542,7 @@ const ChannelWithContext = (props: PropsWithChildren<ChannelPropsWithContext>) =
|
|
|
533
542
|
additionalKeyboardAvoidingViewProps,
|
|
534
543
|
additionalPressableProps,
|
|
535
544
|
additionalTextInputProps,
|
|
545
|
+
allowConcurrentAudioPlayback = false,
|
|
536
546
|
allowThreadMessagesInChannel = true,
|
|
537
547
|
asyncMessagesLockDistance = 50,
|
|
538
548
|
asyncMessagesMinimumPressDuration = 500,
|
|
@@ -2009,6 +2019,11 @@ const ChannelWithContext = (props: PropsWithChildren<ChannelPropsWithContext>) =
|
|
|
2009
2019
|
typing: channelState.typing ?? {},
|
|
2010
2020
|
});
|
|
2011
2021
|
|
|
2022
|
+
const audioPlayerContext = useMemo<AudioPlayerContextProps>(
|
|
2023
|
+
() => ({ allowConcurrentAudioPlayback }),
|
|
2024
|
+
[allowConcurrentAudioPlayback],
|
|
2025
|
+
);
|
|
2026
|
+
|
|
2012
2027
|
const messageComposerContext = useMemo(
|
|
2013
2028
|
() => ({ channel, thread, threadInstance }),
|
|
2014
2029
|
[channel, thread, threadInstance],
|
|
@@ -2047,10 +2062,12 @@ const ChannelWithContext = (props: PropsWithChildren<ChannelPropsWithContext>) =
|
|
|
2047
2062
|
<AttachmentPickerProvider value={attachmentPickerContext}>
|
|
2048
2063
|
<MessageComposerProvider value={messageComposerContext}>
|
|
2049
2064
|
<MessageInputProvider value={inputMessageInputContext}>
|
|
2050
|
-
<
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2065
|
+
<AudioPlayerProvider value={audioPlayerContext}>
|
|
2066
|
+
<View style={{ height: '100%' }}>{children}</View>
|
|
2067
|
+
{!disableAttachmentPicker && (
|
|
2068
|
+
<AttachmentPicker ref={bottomSheetRef} {...attachmentPickerProps} />
|
|
2069
|
+
)}
|
|
2070
|
+
</AudioPlayerProvider>
|
|
2054
2071
|
</MessageInputProvider>
|
|
2055
2072
|
</MessageComposerProvider>
|
|
2056
2073
|
</AttachmentPickerProvider>
|
|
@@ -7,6 +7,7 @@ import type { MessageContextValue } from '../../../contexts/messageContext/Messa
|
|
|
7
7
|
import type { MessagesContextValue } from '../../../contexts/messagesContext/MessagesContext';
|
|
8
8
|
|
|
9
9
|
import { useTranslationContext } from '../../../contexts/translationContext/TranslationContext';
|
|
10
|
+
import { useTranslatedMessage } from '../../../hooks/useTranslatedMessage';
|
|
10
11
|
import { NativeHandlers } from '../../../native';
|
|
11
12
|
|
|
12
13
|
export const useMessageActionHandlers = ({
|
|
@@ -29,6 +30,7 @@ export const useMessageActionHandlers = ({
|
|
|
29
30
|
Pick<MessageComposerAPIContextValue, 'setEditingState' | 'setQuotedMessage'>) => {
|
|
30
31
|
const { t } = useTranslationContext();
|
|
31
32
|
const handleResendMessage = () => retrySendMessage(message);
|
|
33
|
+
const translatedMessage = useTranslatedMessage(message);
|
|
32
34
|
|
|
33
35
|
const handleQuotedReplyMessage = () => {
|
|
34
36
|
setQuotedMessage(message);
|
|
@@ -42,7 +44,7 @@ export const useMessageActionHandlers = ({
|
|
|
42
44
|
if (!message.text) {
|
|
43
45
|
return;
|
|
44
46
|
}
|
|
45
|
-
NativeHandlers.setClipboardString(message.text);
|
|
47
|
+
NativeHandlers.setClipboardString(translatedMessage?.text ?? message.text);
|
|
46
48
|
};
|
|
47
49
|
|
|
48
50
|
const handleDeleteMessage = () => {
|
|
@@ -453,6 +453,12 @@ const MessageInputWithContext = (props: MessageInputPropsWithContext) => {
|
|
|
453
453
|
paused={paused}
|
|
454
454
|
position={position}
|
|
455
455
|
progress={progress}
|
|
456
|
+
recordingDuration={recordingDuration}
|
|
457
|
+
uri={
|
|
458
|
+
typeof recording !== 'string'
|
|
459
|
+
? (recording?.getURI() as string)
|
|
460
|
+
: (recording as string)
|
|
461
|
+
}
|
|
456
462
|
waveformData={waveformData}
|
|
457
463
|
/>
|
|
458
464
|
) : micLocked ? (
|
package/src/components/MessageInput/components/AttachmentPreview/AudioAttachmentUploadPreview.tsx
CHANGED
|
@@ -10,6 +10,7 @@ import { DismissAttachmentUpload } from './DismissAttachmentUpload';
|
|
|
10
10
|
|
|
11
11
|
import { AudioAttachment } from '../../../../components/Attachment/AudioAttachment';
|
|
12
12
|
import { useChatContext } from '../../../../contexts/chatContext/ChatContext';
|
|
13
|
+
import { useMessageComposer } from '../../../../contexts/messageInputContext/hooks/useMessageComposer';
|
|
13
14
|
import { AudioConfig, UploadAttachmentPreviewProps } from '../../../../types/types';
|
|
14
15
|
import { getIndicatorTypeForFileState, ProgressIndicatorTypes } from '../../../../utils/utils';
|
|
15
16
|
|
|
@@ -17,9 +18,26 @@ export type AudioAttachmentUploadPreviewProps<CustomLocalMetadata = Record<strin
|
|
|
17
18
|
UploadAttachmentPreviewProps<
|
|
18
19
|
LocalAudioAttachment<CustomLocalMetadata> | LocalVoiceRecordingAttachment<CustomLocalMetadata>
|
|
19
20
|
> & {
|
|
21
|
+
/**
|
|
22
|
+
* The audio attachment config
|
|
23
|
+
*
|
|
24
|
+
* @deprecated This is deprecated and will be removed in the future.
|
|
25
|
+
*/
|
|
20
26
|
audioAttachmentConfig: AudioConfig;
|
|
27
|
+
/**
|
|
28
|
+
* Callback to be called when the audio is loaded
|
|
29
|
+
* @deprecated This is deprecated and will be removed in the future.
|
|
30
|
+
*/
|
|
21
31
|
onLoad: (index: string, duration: number) => void;
|
|
32
|
+
/**
|
|
33
|
+
* Callback to be called when the audio is played or paused
|
|
34
|
+
* @deprecated This is deprecated and will be removed in the future.
|
|
35
|
+
*/
|
|
22
36
|
onPlayPause: (index: string, pausedStatus?: boolean) => void;
|
|
37
|
+
/**
|
|
38
|
+
* Callback to be called when the audio progresses
|
|
39
|
+
* @deprecated This is deprecated and will be removed in the future.
|
|
40
|
+
*/
|
|
23
41
|
onProgress: (index: string, progress: number) => void;
|
|
24
42
|
};
|
|
25
43
|
|
|
@@ -37,15 +55,23 @@ export const AudioAttachmentUploadPreview = ({
|
|
|
37
55
|
attachment.localMetadata.uploadState,
|
|
38
56
|
enableOfflineSupport,
|
|
39
57
|
);
|
|
58
|
+
const messageComposer = useMessageComposer();
|
|
59
|
+
const isDraft = messageComposer.draftId;
|
|
60
|
+
const isEditing = messageComposer.editedMessage;
|
|
61
|
+
const assetUrl =
|
|
62
|
+
(isDraft || isEditing
|
|
63
|
+
? attachment.asset_url
|
|
64
|
+
: (attachment.localMetadata.file as FileReference).uri) ??
|
|
65
|
+
(attachment.localMetadata.file as FileReference).uri;
|
|
40
66
|
|
|
41
67
|
const finalAttachment = useMemo(
|
|
42
68
|
() => ({
|
|
43
69
|
...attachment,
|
|
44
|
-
asset_url:
|
|
70
|
+
asset_url: assetUrl,
|
|
45
71
|
id: attachment.localMetadata.id,
|
|
46
72
|
...audioAttachmentConfig,
|
|
47
73
|
}),
|
|
48
|
-
[attachment, audioAttachmentConfig],
|
|
74
|
+
[attachment, assetUrl, audioAttachmentConfig],
|
|
49
75
|
);
|
|
50
76
|
|
|
51
77
|
const onRetryHandler = useCallback(() => {
|
|
@@ -65,6 +91,7 @@ export const AudioAttachmentUploadPreview = ({
|
|
|
65
91
|
>
|
|
66
92
|
<AudioAttachment
|
|
67
93
|
hideProgressBar={true}
|
|
94
|
+
isPreview={true}
|
|
68
95
|
item={finalAttachment}
|
|
69
96
|
onLoad={onLoad}
|
|
70
97
|
onPlayPause={onPlayPause}
|
|
@@ -1,41 +1,91 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useEffect, useMemo } from 'react';
|
|
2
2
|
import { Pressable, StyleSheet, Text, View } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import dayjs from 'dayjs';
|
|
5
5
|
|
|
6
6
|
import { useTheme } from '../../../../contexts/themeContext/ThemeContext';
|
|
7
|
+
import { useAudioPlayerControl } from '../../../../hooks/useAudioPlayerControl';
|
|
8
|
+
import { useStateStore } from '../../../../hooks/useStateStore';
|
|
7
9
|
import { Pause, Play } from '../../../../icons';
|
|
8
10
|
|
|
11
|
+
import { NativeHandlers } from '../../../../native';
|
|
12
|
+
import { AudioPlayerState } from '../../../../state-store/audio-player';
|
|
9
13
|
import { WaveProgressBar } from '../../../ProgressControl/WaveProgressBar';
|
|
10
14
|
|
|
15
|
+
const ONE_SECOND_IN_MILLISECONDS = 1000;
|
|
16
|
+
const ONE_HOUR_IN_MILLISECONDS = 3600 * 1000;
|
|
17
|
+
|
|
11
18
|
export type AudioRecordingPreviewProps = {
|
|
19
|
+
recordingDuration: number;
|
|
20
|
+
uri: string;
|
|
21
|
+
/**
|
|
22
|
+
* The waveform data to be presented to show the audio levels.
|
|
23
|
+
*/
|
|
24
|
+
waveformData: number[];
|
|
12
25
|
/**
|
|
13
26
|
* Boolean used to show the paused state of the player.
|
|
27
|
+
*
|
|
28
|
+
* @deprecated This is deprecated and will be removed in the future in favour of the global audio manager.
|
|
29
|
+
* FIXME: Remove this in the next major version.
|
|
14
30
|
*/
|
|
15
31
|
paused: boolean;
|
|
16
32
|
/**
|
|
17
33
|
* Number used to show the current position of the audio being played.
|
|
34
|
+
*
|
|
35
|
+
* @deprecated This is deprecated and will be removed in the future in favour of the global audio manager.
|
|
36
|
+
* FIXME: Remove this in the next major version.
|
|
18
37
|
*/
|
|
19
38
|
position: number;
|
|
20
39
|
/**
|
|
21
40
|
* Number used to show the percentage of progress of the audio being played. It should be in 0-1 range.
|
|
41
|
+
*
|
|
42
|
+
* @deprecated This is deprecated and will be removed in the future in favour of the global audio manager.
|
|
43
|
+
* FIXME: Remove this in the next major version.
|
|
22
44
|
*/
|
|
23
45
|
progress: number;
|
|
24
|
-
/**
|
|
25
|
-
* The waveform data to be presented to show the audio levels.
|
|
26
|
-
*/
|
|
27
|
-
waveformData: number[];
|
|
28
46
|
/**
|
|
29
47
|
* Function to play or pause the audio player.
|
|
48
|
+
*
|
|
49
|
+
* @deprecated This is deprecated and will be removed in the future in favour of the global audio manager.
|
|
50
|
+
* FIXME: Remove this in the next major version.
|
|
30
51
|
*/
|
|
31
52
|
onVoicePlayerPlayPause?: () => Promise<void>;
|
|
32
53
|
};
|
|
33
54
|
|
|
55
|
+
const audioPlayerSelector = (state: AudioPlayerState) => ({
|
|
56
|
+
duration: state.duration,
|
|
57
|
+
isPlaying: state.isPlaying,
|
|
58
|
+
position: state.position,
|
|
59
|
+
progress: state.progress,
|
|
60
|
+
});
|
|
61
|
+
|
|
34
62
|
/**
|
|
35
63
|
* Component displayed when the audio is recorded and can be previewed.
|
|
36
64
|
*/
|
|
37
65
|
export const AudioRecordingPreview = (props: AudioRecordingPreviewProps) => {
|
|
38
|
-
const {
|
|
66
|
+
const { recordingDuration, uri, waveformData } = props;
|
|
67
|
+
|
|
68
|
+
const audioPlayer = useAudioPlayerControl({
|
|
69
|
+
duration: recordingDuration / ONE_SECOND_IN_MILLISECONDS,
|
|
70
|
+
mimeType: 'audio/aac',
|
|
71
|
+
// This is a temporary flag to manage audio player for voice recording in preview as the one in message list uses react-native-video.
|
|
72
|
+
previewVoiceRecording: !(NativeHandlers.SDK === 'stream-chat-expo'),
|
|
73
|
+
type: 'voiceRecording',
|
|
74
|
+
uri,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const { duration, isPlaying, position, progress } = useStateStore(
|
|
78
|
+
audioPlayer.state,
|
|
79
|
+
audioPlayerSelector,
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
// When a audio attachment in preview is removed, we need to remove the player from the pool
|
|
83
|
+
useEffect(
|
|
84
|
+
() => () => {
|
|
85
|
+
audioPlayer.onRemove();
|
|
86
|
+
},
|
|
87
|
+
[audioPlayer],
|
|
88
|
+
);
|
|
39
89
|
|
|
40
90
|
const {
|
|
41
91
|
theme: {
|
|
@@ -53,11 +103,25 @@ export const AudioRecordingPreview = (props: AudioRecordingPreviewProps) => {
|
|
|
53
103
|
},
|
|
54
104
|
} = useTheme();
|
|
55
105
|
|
|
106
|
+
const handlePlayPause = () => {
|
|
107
|
+
audioPlayer.toggle();
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const progressDuration = useMemo(
|
|
111
|
+
() =>
|
|
112
|
+
position
|
|
113
|
+
? position / ONE_HOUR_IN_MILLISECONDS >= 1
|
|
114
|
+
? dayjs.duration(position, 'milliseconds').format('HH:mm:ss')
|
|
115
|
+
: dayjs.duration(position, 'milliseconds').format('mm:ss')
|
|
116
|
+
: dayjs.duration(duration, 'milliseconds').format('mm:ss'),
|
|
117
|
+
[duration, position],
|
|
118
|
+
);
|
|
119
|
+
|
|
56
120
|
return (
|
|
57
121
|
<View style={[styles.container, container]}>
|
|
58
122
|
<View style={[styles.infoContainer, infoContainer]}>
|
|
59
|
-
<Pressable onPress={
|
|
60
|
-
{
|
|
123
|
+
<Pressable onPress={handlePlayPause}>
|
|
124
|
+
{!isPlaying ? (
|
|
61
125
|
<Play fill={accent_blue} height={32} width={32} {...playIcon} />
|
|
62
126
|
) : (
|
|
63
127
|
<Pause fill={accent_blue} height={32} width={32} {...pauseIcon} />
|
|
@@ -65,7 +129,7 @@ export const AudioRecordingPreview = (props: AudioRecordingPreviewProps) => {
|
|
|
65
129
|
</Pressable>
|
|
66
130
|
{/* `durationMillis` is for Expo apps, `currentPosition` is for Native CLI apps. */}
|
|
67
131
|
<Text style={[styles.currentTime, { color: grey_dark }, currentTime]}>
|
|
68
|
-
{
|
|
132
|
+
{progressDuration}
|
|
69
133
|
</Text>
|
|
70
134
|
</View>
|
|
71
135
|
<View style={[styles.progressBar, progressBar]}>
|
|
@@ -4,6 +4,7 @@ import { Alert, Platform } from 'react-native';
|
|
|
4
4
|
|
|
5
5
|
import { LocalVoiceRecordingAttachment } from 'stream-chat';
|
|
6
6
|
|
|
7
|
+
import { useActiveAudioPlayer } from '../../../contexts/audioPlayerContext/AudioPlayerContext';
|
|
7
8
|
import { useMessageComposer } from '../../../contexts/messageInputContext/hooks/useMessageComposer';
|
|
8
9
|
|
|
9
10
|
import { useMessageInputContext } from '../../../contexts/messageInputContext/MessageInputContext';
|
|
@@ -24,12 +25,29 @@ export type RecordingStatusStates = 'idle' | 'recording' | 'stopped';
|
|
|
24
25
|
|
|
25
26
|
/**
|
|
26
27
|
* The hook that controls all the async audio core features including start/stop or recording, player, upload/delete of the recorded audio.
|
|
28
|
+
*
|
|
29
|
+
* FIXME: Change the name to `useAudioRecorder` in the next major version as the hook will only be used for audio recording.
|
|
27
30
|
*/
|
|
28
31
|
export const useAudioController = () => {
|
|
29
32
|
const [micLocked, setMicLocked] = useState(false);
|
|
30
33
|
const [permissionsGranted, setPermissionsGranted] = useState(true);
|
|
34
|
+
/**
|
|
35
|
+
* @deprecated This is deprecated and will be removed in the future in favour of the global audio manager.
|
|
36
|
+
* Check: https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/components/MessageInput/components/AudioRecorder/AudioRecordingPreview.tsx on how to use the global audio manager.
|
|
37
|
+
* FIXME: Remove this in the next major version.
|
|
38
|
+
*/
|
|
31
39
|
const [paused, setPaused] = useState<boolean>(true);
|
|
40
|
+
/**
|
|
41
|
+
* @deprecated This is deprecated and will be removed in the future in favour of the global audio manager.
|
|
42
|
+
* Check: https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/components/MessageInput/components/AudioRecorder/AudioRecordingPreview.tsx on how to use the global audio manager.
|
|
43
|
+
* FIXME: Remove this in the next major version.
|
|
44
|
+
*/
|
|
32
45
|
const [position, setPosition] = useState<number>(0);
|
|
46
|
+
/**
|
|
47
|
+
* @deprecated This is deprecated and will be removed in the future in favour of the global audio manager.
|
|
48
|
+
* Check: https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/components/MessageInput/components/AudioRecorder/AudioRecordingPreview.tsx on how to use the global audio manager.
|
|
49
|
+
* FIXME: Remove this in the next major version.
|
|
50
|
+
*/
|
|
33
51
|
const [progress, setProgress] = useState<number>(0);
|
|
34
52
|
const [waveformData, setWaveformData] = useState<number[]>([]);
|
|
35
53
|
const [isScheduledForSubmit, setIsScheduleForSubmit] = useState(false);
|
|
@@ -37,10 +55,18 @@ export const useAudioController = () => {
|
|
|
37
55
|
const [recordingDuration, setRecordingDuration] = useState<number>(0);
|
|
38
56
|
const [recordingStatus, setRecordingStatus] = useState<RecordingStatusStates>('idle');
|
|
39
57
|
const { attachmentManager } = useMessageComposer();
|
|
58
|
+
const activeAudioPlayer = useActiveAudioPlayer();
|
|
40
59
|
|
|
41
60
|
const { sendMessage } = useMessageInputContext();
|
|
42
61
|
|
|
43
|
-
|
|
62
|
+
/**
|
|
63
|
+
* Reference to the sound object for playback support in Expo CLI apps
|
|
64
|
+
*
|
|
65
|
+
* @deprecated This is deprecated and will be removed in the future in favour of the global audio manager.
|
|
66
|
+
* Check: https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/components/MessageInput/components/AudioRecorder/AudioRecordingPreview.tsx on how to use the global audio manager.
|
|
67
|
+
*
|
|
68
|
+
* FIXME: Remove this in the next major version.
|
|
69
|
+
*/
|
|
44
70
|
const soundRef = useRef<SoundReturnType | null>(null);
|
|
45
71
|
|
|
46
72
|
// This effect stop the player from playing and stops audio recording on
|
|
@@ -60,6 +86,12 @@ export const useAudioController = () => {
|
|
|
60
86
|
}
|
|
61
87
|
}, [isScheduledForSubmit, sendMessage]);
|
|
62
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Function to update the progress of the voice recording.
|
|
91
|
+
*
|
|
92
|
+
* @deprecated This is deprecated and will be removed in the future in favour of the global audio manager.
|
|
93
|
+
* FIXME: Remove this in the next major version.
|
|
94
|
+
*/
|
|
63
95
|
const onVoicePlayerProgressHandler = (currentPosition: number, playbackDuration: number) => {
|
|
64
96
|
const currentProgress = currentPosition / playbackDuration;
|
|
65
97
|
if (currentProgress === 1) {
|
|
@@ -70,6 +102,14 @@ export const useAudioController = () => {
|
|
|
70
102
|
}
|
|
71
103
|
};
|
|
72
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Function to update the playback status of the voice recording.
|
|
107
|
+
*
|
|
108
|
+
* @deprecated This is deprecated and will be removed in the future in favour of the global audio manager.
|
|
109
|
+
* Check: https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/components/MessageInput/components/AudioRecorder/AudioRecordingPreview.tsx on how to use the global audio manager.
|
|
110
|
+
*
|
|
111
|
+
* FIXME: Remove this in the next major version.
|
|
112
|
+
*/
|
|
73
113
|
const onVoicePlayerPlaybackStatusUpdate = (status: PlaybackStatus) => {
|
|
74
114
|
if (status.shouldPlay === undefined || status.shouldPlay === true) {
|
|
75
115
|
setPosition(status?.currentPosition || status?.positionMillis);
|
|
@@ -90,6 +130,14 @@ export const useAudioController = () => {
|
|
|
90
130
|
}
|
|
91
131
|
};
|
|
92
132
|
|
|
133
|
+
/**
|
|
134
|
+
* Function to play or pause voice recording.
|
|
135
|
+
*
|
|
136
|
+
* @deprecated This is deprecated and will be removed in the future in favour of the global audio manager.
|
|
137
|
+
* Check: https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/components/MessageInput/components/AudioRecorder/AudioRecordingPreview.tsx on how to use the global audio manager.
|
|
138
|
+
*
|
|
139
|
+
* FIXME: Remove this in the next major version.
|
|
140
|
+
*/
|
|
93
141
|
const onVoicePlayerPlayPause = async () => {
|
|
94
142
|
if (paused) {
|
|
95
143
|
if (progress === 0) {
|
|
@@ -119,6 +167,11 @@ export const useAudioController = () => {
|
|
|
119
167
|
|
|
120
168
|
/**
|
|
121
169
|
* Function to start playing voice recording to preview it after recording.
|
|
170
|
+
*
|
|
171
|
+
* @deprecated This is deprecated and will be removed in the future in favour of the global audio manager.
|
|
172
|
+
* Check: https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/components/MessageInput/components/AudioRecorder/AudioRecordingPreview.tsx on how to use the global audio manager.
|
|
173
|
+
*
|
|
174
|
+
* FIXME: Remove this in the next major version.
|
|
122
175
|
*/
|
|
123
176
|
const startVoicePlayer = async () => {
|
|
124
177
|
if (!recording) {
|
|
@@ -150,6 +203,11 @@ export const useAudioController = () => {
|
|
|
150
203
|
|
|
151
204
|
/**
|
|
152
205
|
* Function to stop playing voice recording.
|
|
206
|
+
*
|
|
207
|
+
* @deprecated This is deprecated and will be removed in the future in favour of the global audio manager.
|
|
208
|
+
* Check: https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/components/MessageInput/components/AudioRecorder/AudioRecordingPreview.tsx on how to use the global audio manager.
|
|
209
|
+
*
|
|
210
|
+
* FIXME: Remove this in the next major version.
|
|
153
211
|
*/
|
|
154
212
|
const stopVoicePlayer = async () => {
|
|
155
213
|
// For Native CLI
|
|
@@ -200,6 +258,9 @@ export const useAudioController = () => {
|
|
|
200
258
|
}
|
|
201
259
|
setRecording(recording);
|
|
202
260
|
setRecordingStatus('recording');
|
|
261
|
+
if (activeAudioPlayer?.isPlaying) {
|
|
262
|
+
await activeAudioPlayer?.pause();
|
|
263
|
+
}
|
|
203
264
|
await stopVoicePlayer();
|
|
204
265
|
} else {
|
|
205
266
|
setPermissionsGranted(false);
|
|
@@ -8,6 +8,8 @@ import { AudioConfig } from '../../../types/types';
|
|
|
8
8
|
* Manages the state of audio attachments for preview and playback.
|
|
9
9
|
* @param files The audio files to manage.
|
|
10
10
|
* @returns An object containing the state and handlers for audio attachments.
|
|
11
|
+
*
|
|
12
|
+
* @deprecated This is deprecated and will be removed in the future.
|
|
11
13
|
*/
|
|
12
14
|
export const useAudioPreviewManager = (files: LocalAttachment[]) => {
|
|
13
15
|
const [audioAttachmentsStateMap, setAudioAttachmentsStateMap] = useState<
|
|
@@ -34,8 +36,15 @@ export const useAudioPreviewManager = (files: LocalAttachment[]) => {
|
|
|
34
36
|
});
|
|
35
37
|
}, [files]);
|
|
36
38
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
/**
|
|
40
|
+
* Handler triggered when an audio is loaded in the message input. The initial state is defined for the audio here
|
|
41
|
+
* and the duration is set.
|
|
42
|
+
* @param index - The index of the audio
|
|
43
|
+
* @param duration - The duration of the audio
|
|
44
|
+
*
|
|
45
|
+
* @deprecated This is deprecated and will be removed in the future.
|
|
46
|
+
* FIXME: Remove this in the next major version.
|
|
47
|
+
*/
|
|
39
48
|
const onLoad = useCallback((index: string, duration: number) => {
|
|
40
49
|
setAudioAttachmentsStateMap((prevState) => ({
|
|
41
50
|
...prevState,
|
|
@@ -46,8 +55,15 @@ export const useAudioPreviewManager = (files: LocalAttachment[]) => {
|
|
|
46
55
|
}));
|
|
47
56
|
}, []);
|
|
48
57
|
|
|
49
|
-
|
|
50
|
-
|
|
58
|
+
/**
|
|
59
|
+
* Handler which is triggered when the audio progresses/ the thumb is dragged in the progress control. The
|
|
60
|
+
* progressed duration is set here.
|
|
61
|
+
* @param index - The index of the audio
|
|
62
|
+
* @param progress - The progress of the audio
|
|
63
|
+
*
|
|
64
|
+
* @deprecated This is deprecated and will be removed in the future.
|
|
65
|
+
* FIXME: Remove this in the next major version.
|
|
66
|
+
*/
|
|
51
67
|
const onProgress = useCallback((index: string, progress: number) => {
|
|
52
68
|
setAudioAttachmentsStateMap((prevState) => ({
|
|
53
69
|
...prevState,
|
|
@@ -58,7 +74,14 @@ export const useAudioPreviewManager = (files: LocalAttachment[]) => {
|
|
|
58
74
|
}));
|
|
59
75
|
}, []);
|
|
60
76
|
|
|
61
|
-
|
|
77
|
+
/**
|
|
78
|
+
* Handler which controls or sets the paused/played state of the audio.
|
|
79
|
+
* @param index - The index of the audio
|
|
80
|
+
* @param pausedStatus - The paused status of the audio
|
|
81
|
+
*
|
|
82
|
+
* @deprecated This is deprecated and will be removed in the future.
|
|
83
|
+
* FIXME: Remove this in the next major version.
|
|
84
|
+
*/
|
|
62
85
|
const onPlayPause = useCallback((index: string, pausedStatus?: boolean) => {
|
|
63
86
|
if (pausedStatus === false) {
|
|
64
87
|
// In this case, all others except the index are set to paused.
|
|
@@ -1,12 +1,18 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
1
|
+
import React, { useMemo, useState } from 'react';
|
|
2
2
|
import { StyleSheet, View } from 'react-native';
|
|
3
3
|
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
|
|
4
|
-
import Animated, {
|
|
4
|
+
import Animated, {
|
|
5
|
+
runOnJS,
|
|
6
|
+
useAnimatedReaction,
|
|
7
|
+
useAnimatedStyle,
|
|
8
|
+
useSharedValue,
|
|
9
|
+
} from 'react-native-reanimated';
|
|
5
10
|
|
|
6
11
|
import { useTheme } from '../../contexts/themeContext/ThemeContext';
|
|
7
12
|
|
|
8
13
|
export type ProgressControlProps = {
|
|
9
14
|
/**
|
|
15
|
+
* @deprecated unused prop.
|
|
10
16
|
* The duration of the audio in seconds
|
|
11
17
|
*/
|
|
12
18
|
duration: number;
|
|
@@ -33,6 +39,7 @@ export type ProgressControlProps = {
|
|
|
33
39
|
onPlayPause?: (status?: boolean) => void;
|
|
34
40
|
/**
|
|
35
41
|
* The function to be called when the user is dragging the progress bar
|
|
42
|
+
* @deprecated This is not used anymore and is handled locally
|
|
36
43
|
*/
|
|
37
44
|
onProgressDrag?: (progress: number) => void;
|
|
38
45
|
/**
|
|
@@ -67,17 +74,9 @@ const ProgressControlThumb = () => {
|
|
|
67
74
|
|
|
68
75
|
export const ProgressControl = (props: ProgressControlProps) => {
|
|
69
76
|
const [widthInNumbers, setWidthInNumbers] = useState(0);
|
|
70
|
-
const {
|
|
71
|
-
filledColor: filledColorFromProp,
|
|
72
|
-
onEndDrag,
|
|
73
|
-
onPlayPause,
|
|
74
|
-
onProgressDrag,
|
|
75
|
-
onStartDrag,
|
|
76
|
-
progress,
|
|
77
|
-
testID,
|
|
78
|
-
} = props;
|
|
77
|
+
const { filledColor: filledColorFromProp, onEndDrag, onStartDrag, progress, testID } = props;
|
|
79
78
|
|
|
80
|
-
const
|
|
79
|
+
const state = useSharedValue(progress);
|
|
81
80
|
const {
|
|
82
81
|
theme: {
|
|
83
82
|
colors: { grey_dark },
|
|
@@ -85,51 +84,50 @@ export const ProgressControl = (props: ProgressControlProps) => {
|
|
|
85
84
|
},
|
|
86
85
|
} = useTheme();
|
|
87
86
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
.withTestId(testID);
|
|
87
|
+
useAnimatedReaction(
|
|
88
|
+
() => progress,
|
|
89
|
+
(newProgress) => {
|
|
90
|
+
state.value = newProgress;
|
|
91
|
+
},
|
|
92
|
+
[progress],
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
const pan = useMemo(
|
|
96
|
+
() =>
|
|
97
|
+
Gesture.Pan()
|
|
98
|
+
.maxPointers(1)
|
|
99
|
+
.onStart(() => {
|
|
100
|
+
if (onStartDrag) {
|
|
101
|
+
runOnJS(onStartDrag)(state.value);
|
|
102
|
+
}
|
|
103
|
+
})
|
|
104
|
+
.onUpdate((event) => {
|
|
105
|
+
const newProgress = Math.max(0, Math.min(event.x / widthInNumbers, 1));
|
|
106
|
+
state.value = newProgress;
|
|
107
|
+
})
|
|
108
|
+
.onEnd(() => {
|
|
109
|
+
if (onEndDrag) {
|
|
110
|
+
runOnJS(onEndDrag)(state.value);
|
|
111
|
+
}
|
|
112
|
+
})
|
|
113
|
+
.withTestId(testID),
|
|
114
|
+
[onEndDrag, onStartDrag, state, testID, widthInNumbers],
|
|
115
|
+
);
|
|
118
116
|
|
|
119
117
|
const filledColor = filledColorFromProp || filledColorFromTheme;
|
|
120
118
|
|
|
121
119
|
const thumbStyles = useAnimatedStyle(
|
|
122
120
|
() => ({
|
|
123
|
-
transform: [{ translateX:
|
|
121
|
+
transform: [{ translateX: state.value * widthInNumbers - THUMB_WIDTH / 2 }],
|
|
124
122
|
}),
|
|
125
|
-
[
|
|
123
|
+
[widthInNumbers],
|
|
126
124
|
);
|
|
127
125
|
|
|
128
126
|
const animatedFilledStyles = useAnimatedStyle(
|
|
129
127
|
() => ({
|
|
130
|
-
width:
|
|
128
|
+
width: state.value * widthInNumbers,
|
|
131
129
|
}),
|
|
132
|
-
[
|
|
130
|
+
[widthInNumbers],
|
|
133
131
|
);
|
|
134
132
|
|
|
135
133
|
return (
|
|
@@ -151,7 +149,7 @@ export const ProgressControl = (props: ProgressControlProps) => {
|
|
|
151
149
|
]}
|
|
152
150
|
/>
|
|
153
151
|
<Animated.View style={[thumbStyles, thumb]}>
|
|
154
|
-
{onEndDrag
|
|
152
|
+
{onEndDrag ? <ProgressControlThumb /> : null}
|
|
155
153
|
</Animated.View>
|
|
156
154
|
</View>
|
|
157
155
|
</GestureDetector>
|