stream-chat-react-native-core 8.11.0-beta.1 → 8.11.0
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/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/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/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/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/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/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/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/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
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { StateStore } from 'stream-chat';
|
|
2
|
+
import { AudioPlayerPool } from './audio-player-pool';
|
|
3
|
+
import { SoundReturnType } from '../native';
|
|
4
|
+
export type AudioDescriptor = {
|
|
5
|
+
id: string;
|
|
6
|
+
uri: string;
|
|
7
|
+
duration: number;
|
|
8
|
+
mimeType: string;
|
|
9
|
+
type: 'voiceRecording' | 'audio';
|
|
10
|
+
};
|
|
11
|
+
export type AudioPlayerState = {
|
|
12
|
+
isPlaying: boolean;
|
|
13
|
+
duration: number;
|
|
14
|
+
position: number;
|
|
15
|
+
progress: number;
|
|
16
|
+
currentPlaybackRate: number;
|
|
17
|
+
playbackRates: number[];
|
|
18
|
+
};
|
|
19
|
+
export type AudioPlayerOptions = AudioDescriptor & {
|
|
20
|
+
playbackRates?: number[];
|
|
21
|
+
previewVoiceRecording?: boolean;
|
|
22
|
+
};
|
|
23
|
+
export declare class AudioPlayer {
|
|
24
|
+
state: StateStore<AudioPlayerState>;
|
|
25
|
+
playerRef: SoundReturnType | null;
|
|
26
|
+
private _id;
|
|
27
|
+
private type;
|
|
28
|
+
private isExpoCLI;
|
|
29
|
+
private _pool;
|
|
30
|
+
/**
|
|
31
|
+
* This is a temporary flag to manage audio player for voice recording in preview as the one in message list uses react-native-video.
|
|
32
|
+
* We can get rid of this when we migrate to the react-native-nitro-sound everywhere.
|
|
33
|
+
*/
|
|
34
|
+
private previewVoiceRecording?;
|
|
35
|
+
constructor(options: AudioPlayerOptions);
|
|
36
|
+
initPlayer: ({ uri, playerRef }: {
|
|
37
|
+
uri?: string;
|
|
38
|
+
playerRef?: SoundReturnType;
|
|
39
|
+
}) => Promise<void>;
|
|
40
|
+
private onVoiceRecordingPreviewPlaybackStatusUpdate;
|
|
41
|
+
private onPlaybackStatusUpdate;
|
|
42
|
+
get isPlaying(): boolean;
|
|
43
|
+
get duration(): number;
|
|
44
|
+
get position(): number;
|
|
45
|
+
get progress(): number;
|
|
46
|
+
get playbackRates(): number[];
|
|
47
|
+
get currentPlaybackRate(): number;
|
|
48
|
+
get id(): string;
|
|
49
|
+
set pool(pool: AudioPlayerPool);
|
|
50
|
+
set duration(duration: number);
|
|
51
|
+
set position(position: number);
|
|
52
|
+
set progress(progress: number);
|
|
53
|
+
set isPlaying(isPlaying: boolean);
|
|
54
|
+
changePlaybackRate(): Promise<void>;
|
|
55
|
+
play(): void;
|
|
56
|
+
pause(): void;
|
|
57
|
+
toggle(): void;
|
|
58
|
+
seek(positionInSeconds: number): Promise<void>;
|
|
59
|
+
stop(): Promise<void>;
|
|
60
|
+
onRemove(): void;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=audio-player.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audio-player.d.ts","sourceRoot":"","sources":["../../../src/state-store/audio-player.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAyD,eAAe,EAAE,MAAM,WAAW,CAAC;AAEnG,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB,CAAC;AAmBF,MAAM,MAAM,kBAAkB,GAAG,eAAe,GAAG;IACjD,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC,CAAC;AAEF,qBAAa,WAAW;IACtB,KAAK,EAAE,UAAU,CAAC,gBAAgB,CAAC,CAAC;IACpC,SAAS,EAAE,eAAe,GAAG,IAAI,CAAQ;IACzC,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,IAAI,CAA6B;IACzC,OAAO,CAAC,SAAS,CAAU;IAC3B,OAAO,CAAC,KAAK,CAAgC;IAE7C;;;OAGG;IACH,OAAO,CAAC,qBAAqB,CAAC,CAAU;gBAE5B,OAAO,EAAE,kBAAkB;IAiBvC,UAAU,GAAU,oBAAoB;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,eAAe,CAAA;KAAE,mBA4BnF;IAEF,OAAO,CAAC,2CAA2C,CAOjD;IAGF,OAAO,CAAC,sBAAsB,CA6B5B;IAGF,IAAI,SAAS,IAqDY,OAAO,CAnD/B;IAED,IAAI,QAAQ,IA6BW,MAAM,CA3B5B;IAED,IAAI,QAAQ,IA+BW,MAAM,CA7B5B;IAED,IAAI,QAAQ,IAkCW,MAAM,CAhC5B;IAED,IAAI,aAAa,aAEhB;IAED,IAAI,mBAAmB,WAEtB;IAED,IAAI,EAAE,WAEL;IAGD,IAAI,IAAI,CAAC,IAAI,EAAE,eAAe,EAE7B;IAED,IAAI,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAI5B;IAED,IAAI,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAK5B;IAED,IAAI,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAK5B;IAED,IAAI,SAAS,CAAC,SAAS,EAAE,OAAO,EAI/B;IAGK,kBAAkB;IAqBxB,IAAI;IAqCJ,KAAK;IAoCL,MAAM;IAQA,IAAI,CAAC,iBAAiB,EAAE,MAAM;IA8B9B,IAAI;IAMV,QAAQ;CAyBT"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-app-notifications-store.d.ts","sourceRoot":"","sources":["../../../src/state-store/in-app-notifications-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEvD,MAAM,MAAM,uBAAuB,GAAG;IACpC,aAAa,EAAE,YAAY,EAAE,CAAC;CAC/B,CAAC;AAMF,eAAO,MAAM,uBAAuB,qCAAyD,CAAC;AAE9F,eAAO,MAAM,qBAAqB,GAAI,cAAc,YAAY,SAgB/D,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,IAAI,MAAM,SAShD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/state-store/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,qBAAqB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stream-chat-react-native-core",
|
|
3
3
|
"description": "The official React Native and Expo components for Stream Chat, a service for building chat applications",
|
|
4
|
-
"version": "8.11.0
|
|
4
|
+
"version": "8.11.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"company": "Stream.io Inc",
|
|
7
7
|
"name": "Stream.io Inc"
|
|
8
8
|
},
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
11
|
-
"url": "https://github.com/GetStream/stream-chat-react-native.git"
|
|
11
|
+
"url": "https://github.com/GetStream/stream-chat-react-native.git",
|
|
12
|
+
"directory": "package"
|
|
12
13
|
},
|
|
13
14
|
"license": "SEE LICENSE IN LICENSE",
|
|
14
15
|
"main": "lib/commonjs/index.js",
|
|
@@ -24,7 +25,7 @@
|
|
|
24
25
|
"scripts": {
|
|
25
26
|
"install-all": "(yarn install --force && (cd native-package && yarn install --force) && (cd expo-package && yarn install --force))",
|
|
26
27
|
"build": "rimraf lib && yarn run --silent build-translations && bob build && yarn run --silent copy-translations",
|
|
27
|
-
"build-translations": "i18next",
|
|
28
|
+
"build-translations": "i18next-cli sync",
|
|
28
29
|
"copy-translations": "echo '\u001b[34mℹ\u001b[0m Copying translation files to \u001b[34mlib/typescript/i18n\u001b[0m' && cp -R -f ./src/i18n ./lib/typescript/i18n && echo '\u001b[32m✓\u001b[0m Done Copying Translations'",
|
|
29
30
|
"eslint": "eslint 'src/**/*.{js,md,ts,jsx,tsx}' --max-warnings 0",
|
|
30
31
|
"lint": "prettier --ignore-path ../.prettierignore --list-different 'src/**/*.{js,ts,tsx,md,json}' eslint.config.mjs ../.prettierrc babel.config.js && eslint 'src/**/*.{js,ts,tsx,md}' --max-warnings 0 && yarn run validate-translations",
|
|
@@ -112,11 +113,11 @@
|
|
|
112
113
|
"@babel/core": "^7.27.4",
|
|
113
114
|
"@babel/runtime": "^7.27.6",
|
|
114
115
|
"@op-engineering/op-sqlite": "^14.0.3",
|
|
115
|
-
"@shopify/flash-list": "^2.1.0",
|
|
116
116
|
"@react-native-community/eslint-config": "3.2.0",
|
|
117
117
|
"@react-native-community/eslint-plugin": "1.3.0",
|
|
118
118
|
"@react-native-community/netinfo": "^11.4.1",
|
|
119
119
|
"@react-native/babel-preset": "0.79.3",
|
|
120
|
+
"@shopify/flash-list": "^2.1.0",
|
|
120
121
|
"@testing-library/jest-native": "^5.4.3",
|
|
121
122
|
"@testing-library/react-native": "13.2.0",
|
|
122
123
|
"@types/better-sqlite3": "^7.6.13",
|
|
@@ -145,7 +146,7 @@
|
|
|
145
146
|
"eslint-plugin-react": "^7.37.5",
|
|
146
147
|
"eslint-plugin-react-hooks": "^5.2.0",
|
|
147
148
|
"eslint-plugin-react-native": "^5.0.0",
|
|
148
|
-
"i18next-
|
|
149
|
+
"i18next-cli": "^1.31.0",
|
|
149
150
|
"jest": "^30.0.0",
|
|
150
151
|
"moment-timezone": "^0.6.0",
|
|
151
152
|
"prettier": "^3.5.3",
|
|
@@ -1,254 +1,179 @@
|
|
|
1
|
-
import React, { RefObject, useEffect, useMemo
|
|
1
|
+
import React, { RefObject, useEffect, useMemo } from 'react';
|
|
2
2
|
import { I18nManager, Pressable, StyleSheet, Text, View } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import dayjs from 'dayjs';
|
|
5
5
|
import duration from 'dayjs/plugin/duration';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
isVoiceRecordingAttachment,
|
|
9
|
+
LocalMessage,
|
|
10
|
+
AudioAttachment as StreamAudioAttachment,
|
|
11
|
+
VoiceRecordingAttachment as StreamVoiceRecordingAttachment,
|
|
12
|
+
} from 'stream-chat';
|
|
8
13
|
|
|
9
14
|
import { useTheme } from '../../contexts';
|
|
10
|
-
import {
|
|
15
|
+
import { useStateStore } from '../../hooks';
|
|
16
|
+
import { useAudioPlayerControl } from '../../hooks/useAudioPlayerControl';
|
|
11
17
|
import { Audio, Pause, Play } from '../../icons';
|
|
12
18
|
import {
|
|
13
19
|
NativeHandlers,
|
|
14
|
-
PlaybackStatus,
|
|
15
20
|
SoundReturnType,
|
|
16
21
|
VideoPayloadData,
|
|
17
22
|
VideoProgressData,
|
|
18
23
|
VideoSeekResponse,
|
|
19
24
|
} from '../../native';
|
|
20
|
-
import {
|
|
25
|
+
import { AudioPlayerState } from '../../state-store/audio-player';
|
|
26
|
+
import { AudioConfig } from '../../types/types';
|
|
21
27
|
import { getTrimmedAttachmentTitle } from '../../utils/getTrimmedAttachmentTitle';
|
|
22
28
|
import { ProgressControl } from '../ProgressControl/ProgressControl';
|
|
23
29
|
import { WaveProgressBar } from '../ProgressControl/WaveProgressBar';
|
|
24
30
|
|
|
31
|
+
const ONE_HOUR_IN_MILLISECONDS = 3600 * 1000;
|
|
32
|
+
const ONE_SECOND_IN_MILLISECONDS = 1000;
|
|
33
|
+
|
|
25
34
|
dayjs.extend(duration);
|
|
26
35
|
|
|
27
36
|
export type AudioAttachmentType = AudioConfig &
|
|
28
|
-
Pick<
|
|
37
|
+
Pick<
|
|
38
|
+
StreamAudioAttachment | StreamVoiceRecordingAttachment,
|
|
39
|
+
'waveform_data' | 'asset_url' | 'title' | 'mime_type'
|
|
40
|
+
> & {
|
|
29
41
|
id: string;
|
|
30
42
|
type: 'audio' | 'voiceRecording';
|
|
31
43
|
};
|
|
32
44
|
|
|
33
45
|
export type AudioAttachmentProps = {
|
|
34
46
|
item: AudioAttachmentType;
|
|
35
|
-
|
|
36
|
-
onPlayPause: (index: string, pausedStatus?: boolean) => void;
|
|
37
|
-
onProgress: (index: string, progress: number) => void;
|
|
47
|
+
message?: LocalMessage;
|
|
38
48
|
titleMaxLength?: number;
|
|
39
49
|
hideProgressBar?: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* If true, the speed settings button will be shown.
|
|
52
|
+
*/
|
|
40
53
|
showSpeedSettings?: boolean;
|
|
41
54
|
testID?: string;
|
|
55
|
+
/**
|
|
56
|
+
* If true, the audio attachment is in preview mode in the message input.
|
|
57
|
+
*/
|
|
58
|
+
isPreview?: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Callback to be called when the audio is loaded
|
|
61
|
+
* @deprecated This is deprecated and will be removed in the future.
|
|
62
|
+
*/
|
|
63
|
+
onLoad?: (index: string, duration: number) => void;
|
|
64
|
+
/**
|
|
65
|
+
* Callback to be called when the audio is played or paused
|
|
66
|
+
* @deprecated This is deprecated and will be removed in the future.
|
|
67
|
+
*/
|
|
68
|
+
onPlayPause?: (index: string, pausedStatus?: boolean) => void;
|
|
69
|
+
/**
|
|
70
|
+
* Callback to be called when the audio progresses
|
|
71
|
+
* @deprecated This is deprecated and will be removed in the future.
|
|
72
|
+
*/
|
|
73
|
+
onProgress?: (index: string, progress: number) => void;
|
|
42
74
|
};
|
|
43
75
|
|
|
76
|
+
const audioPlayerSelector = (state: AudioPlayerState) => ({
|
|
77
|
+
currentPlaybackRate: state.currentPlaybackRate,
|
|
78
|
+
duration: state.duration,
|
|
79
|
+
isPlaying: state.isPlaying,
|
|
80
|
+
position: state.position,
|
|
81
|
+
progress: state.progress,
|
|
82
|
+
});
|
|
83
|
+
|
|
44
84
|
/**
|
|
45
85
|
* AudioAttachment
|
|
46
86
|
* UI Component to preview the audio files
|
|
47
87
|
*/
|
|
48
88
|
export const AudioAttachment = (props: AudioAttachmentProps) => {
|
|
49
|
-
const [currentSpeed, setCurrentSpeed] = useState<number>(1.0);
|
|
50
|
-
const [audioFinished, setAudioFinished] = useState(false);
|
|
51
89
|
const soundRef = React.useRef<SoundReturnType | null>(null);
|
|
90
|
+
|
|
52
91
|
const {
|
|
53
92
|
hideProgressBar = false,
|
|
54
93
|
item,
|
|
55
|
-
|
|
56
|
-
onPlayPause,
|
|
57
|
-
onProgress,
|
|
94
|
+
message,
|
|
58
95
|
showSpeedSettings = false,
|
|
59
96
|
testID,
|
|
60
97
|
titleMaxLength,
|
|
98
|
+
isPreview = false,
|
|
61
99
|
} = props;
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
const
|
|
100
|
+
const isVoiceRecording = isVoiceRecordingAttachment(item);
|
|
101
|
+
|
|
102
|
+
const audioPlayer = useAudioPlayerControl({
|
|
103
|
+
duration: item.duration ?? 0,
|
|
104
|
+
mimeType: item.mime_type ?? '',
|
|
105
|
+
requester: isPreview
|
|
106
|
+
? 'preview'
|
|
107
|
+
: message?.id && `${message?.parent_id ?? message?.id}${message?.id}`,
|
|
108
|
+
type: isVoiceRecording ? 'voiceRecording' : 'audio',
|
|
109
|
+
uri: item.asset_url ?? '',
|
|
110
|
+
});
|
|
111
|
+
const { duration, isPlaying, position, progress, currentPlaybackRate } = useStateStore(
|
|
112
|
+
audioPlayer.state,
|
|
113
|
+
audioPlayerSelector,
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
// Initialize the player for native cli apps
|
|
117
|
+
useEffect(() => {
|
|
118
|
+
if (soundRef.current) {
|
|
119
|
+
audioPlayer.initPlayer({ playerRef: soundRef.current });
|
|
120
|
+
}
|
|
121
|
+
}, [audioPlayer]);
|
|
122
|
+
|
|
123
|
+
// When a audio attachment in preview is removed, we need to remove the player from the pool
|
|
124
|
+
useEffect(
|
|
125
|
+
() => () => {
|
|
126
|
+
if (isPreview) {
|
|
127
|
+
audioPlayer.onRemove();
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
[audioPlayer, isPreview],
|
|
131
|
+
);
|
|
65
132
|
|
|
66
133
|
/** This is for Native CLI Apps */
|
|
67
134
|
const handleLoad = (payload: VideoPayloadData) => {
|
|
68
|
-
//
|
|
69
|
-
if (isVoiceRecording
|
|
70
|
-
|
|
71
|
-
} else {
|
|
72
|
-
onLoad(item.id, item.duration || payload.duration);
|
|
135
|
+
// If the attachment is a voice recording, we rely on the duration from the attachment as the one from the react-native-video is incorrect.
|
|
136
|
+
if (isVoiceRecording) {
|
|
137
|
+
return;
|
|
73
138
|
}
|
|
139
|
+
audioPlayer.duration = payload.duration * ONE_SECOND_IN_MILLISECONDS;
|
|
74
140
|
};
|
|
75
141
|
|
|
76
142
|
/** This is for Native CLI Apps */
|
|
77
143
|
const handleProgress = (data: VideoProgressData) => {
|
|
78
|
-
const { currentTime
|
|
79
|
-
|
|
80
|
-
if (isVoiceRecording && item.duration) {
|
|
81
|
-
if (currentTime < item.duration && !audioFinished) {
|
|
82
|
-
onProgress(item.id, currentTime / item.duration);
|
|
83
|
-
} else {
|
|
84
|
-
setAudioFinished(true);
|
|
85
|
-
}
|
|
86
|
-
} else {
|
|
87
|
-
if (currentTime < seekableDuration && !audioFinished) {
|
|
88
|
-
onProgress(item.id, currentTime / seekableDuration);
|
|
89
|
-
} else {
|
|
90
|
-
setAudioFinished(true);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
144
|
+
const { currentTime } = data;
|
|
145
|
+
audioPlayer.position = currentTime * ONE_SECOND_IN_MILLISECONDS;
|
|
93
146
|
};
|
|
94
147
|
|
|
95
148
|
/** This is for Native CLI Apps */
|
|
96
149
|
const onSeek = (seekResponse: VideoSeekResponse) => {
|
|
97
|
-
|
|
98
|
-
onProgress(item.id, seekResponse.currentTime / (item.duration as number));
|
|
150
|
+
audioPlayer.position = seekResponse.currentTime * ONE_SECOND_IN_MILLISECONDS;
|
|
99
151
|
};
|
|
100
152
|
|
|
101
|
-
const handlePlayPause =
|
|
102
|
-
|
|
103
|
-
if (isExpoCLI) {
|
|
104
|
-
await playAudio();
|
|
105
|
-
}
|
|
106
|
-
onPlayPause(item.id, false);
|
|
107
|
-
} else {
|
|
108
|
-
if (isExpoCLI) {
|
|
109
|
-
await pauseAudio();
|
|
110
|
-
}
|
|
111
|
-
onPlayPause(item.id, true);
|
|
112
|
-
}
|
|
153
|
+
const handlePlayPause = () => {
|
|
154
|
+
audioPlayer.toggle();
|
|
113
155
|
};
|
|
114
156
|
|
|
115
157
|
const handleEnd = async () => {
|
|
116
|
-
|
|
117
|
-
await pauseAudio();
|
|
118
|
-
onPlayPause(item.id, true);
|
|
119
|
-
await seekAudio(0);
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
const dragStart = async () => {
|
|
123
|
-
if (isExpoCLI) {
|
|
124
|
-
await pauseAudio();
|
|
125
|
-
}
|
|
126
|
-
onPlayPause(item.id, true);
|
|
158
|
+
await audioPlayer.stop();
|
|
127
159
|
};
|
|
128
160
|
|
|
129
|
-
const
|
|
130
|
-
|
|
161
|
+
const dragStart = () => {
|
|
162
|
+
audioPlayer.pause();
|
|
131
163
|
};
|
|
132
164
|
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
if (isExpoCLI) {
|
|
136
|
-
await playAudio();
|
|
137
|
-
}
|
|
138
|
-
onPlayPause(item.id, false);
|
|
165
|
+
const dragProgress = (currentProgress: number) => {
|
|
166
|
+
audioPlayer.progress = currentProgress;
|
|
139
167
|
};
|
|
140
168
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
if (playbackStatus.error) {
|
|
146
|
-
console.log(`Encountered a fatal error during playback: ${playbackStatus.error}`);
|
|
147
|
-
}
|
|
148
|
-
} else {
|
|
149
|
-
const { durationMillis, positionMillis } = playbackStatus;
|
|
150
|
-
// This is done for Expo CLI where we don't get file duration from file picker
|
|
151
|
-
if (item.duration === 0) {
|
|
152
|
-
onLoad(item.id, durationMillis / 1000);
|
|
153
|
-
} else {
|
|
154
|
-
// The duration given by the expo-av is not same as the one of the voice recording, so we take the actual duration for voice recording.
|
|
155
|
-
if (isVoiceRecording && item.duration) {
|
|
156
|
-
onLoad(item.id, item.duration);
|
|
157
|
-
} else {
|
|
158
|
-
onLoad(item.id, durationMillis / 1000);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
// Update your UI for the loaded state
|
|
162
|
-
if (playbackStatus.isPlaying) {
|
|
163
|
-
if (isVoiceRecording && item.duration) {
|
|
164
|
-
if (positionMillis <= item.duration * 1000) {
|
|
165
|
-
onProgress(item.id, positionMillis / (item.duration * 1000));
|
|
166
|
-
}
|
|
167
|
-
} else {
|
|
168
|
-
if (positionMillis <= durationMillis) {
|
|
169
|
-
onProgress(item.id, positionMillis / durationMillis);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
} else {
|
|
173
|
-
// Update your UI for the paused state
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
if (playbackStatus.isBuffering) {
|
|
177
|
-
// Update your UI for the buffering state
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
if (playbackStatus.didJustFinish && !playbackStatus.isLooping) {
|
|
181
|
-
onProgress(item.id, 1);
|
|
182
|
-
// The player has just finished playing and will stop. Maybe you want to play something else?
|
|
183
|
-
// status: opposite of pause,says i am playing
|
|
184
|
-
handleEnd();
|
|
185
|
-
}
|
|
186
|
-
}
|
|
169
|
+
const dragEnd = async (currentProgress: number) => {
|
|
170
|
+
const positionInSeconds = (currentProgress * duration) / ONE_SECOND_IN_MILLISECONDS;
|
|
171
|
+
await audioPlayer.seek(positionInSeconds);
|
|
172
|
+
audioPlayer.play();
|
|
187
173
|
};
|
|
188
174
|
|
|
189
|
-
// This is for Expo CLI, sound initialization is done here.
|
|
190
|
-
useEffect(() => {
|
|
191
|
-
if (isExpoCLI) {
|
|
192
|
-
const initiateSound = async () => {
|
|
193
|
-
if (item && item.asset_url && NativeHandlers.Sound?.initializeSound) {
|
|
194
|
-
soundRef.current = await NativeHandlers.Sound.initializeSound(
|
|
195
|
-
{ uri: item.asset_url },
|
|
196
|
-
{
|
|
197
|
-
pitchCorrectionQuality: 'high',
|
|
198
|
-
progressUpdateIntervalMillis: 100,
|
|
199
|
-
shouldCorrectPitch: true,
|
|
200
|
-
},
|
|
201
|
-
onPlaybackStatusUpdate,
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
};
|
|
205
|
-
initiateSound();
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
return () => {
|
|
209
|
-
if (soundRef.current?.stopAsync && soundRef.current.unloadAsync) {
|
|
210
|
-
soundRef.current.stopAsync();
|
|
211
|
-
soundRef.current.unloadAsync();
|
|
212
|
-
}
|
|
213
|
-
};
|
|
214
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
215
|
-
}, []);
|
|
216
|
-
|
|
217
|
-
// This is needed for expo applications where the rerender doesn't occur on time thefore you need to update the state of the sound.
|
|
218
|
-
useEffect(() => {
|
|
219
|
-
const initalPlayPause = async () => {
|
|
220
|
-
if (!isExpoCLI) {
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
try {
|
|
224
|
-
if (item.paused) {
|
|
225
|
-
await pauseAudio();
|
|
226
|
-
} else {
|
|
227
|
-
await playAudio();
|
|
228
|
-
}
|
|
229
|
-
} catch (e) {
|
|
230
|
-
console.log('An error has occurred while trying to interact with the audio. ', e);
|
|
231
|
-
}
|
|
232
|
-
};
|
|
233
|
-
// For expo CLI
|
|
234
|
-
if (!NativeHandlers.Sound?.Player) {
|
|
235
|
-
initalPlayPause();
|
|
236
|
-
}
|
|
237
|
-
}, [item.paused, isExpoCLI, pauseAudio, playAudio]);
|
|
238
|
-
|
|
239
175
|
const onSpeedChangeHandler = async () => {
|
|
240
|
-
|
|
241
|
-
setCurrentSpeed(1.0);
|
|
242
|
-
await changeAudioSpeed(1.0);
|
|
243
|
-
} else {
|
|
244
|
-
if (currentSpeed === 1.0) {
|
|
245
|
-
setCurrentSpeed(1.5);
|
|
246
|
-
await changeAudioSpeed(1.5);
|
|
247
|
-
} else if (currentSpeed === 1.5) {
|
|
248
|
-
setCurrentSpeed(2.0);
|
|
249
|
-
await changeAudioSpeed(2.0);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
176
|
+
await audioPlayer.changePlaybackRate();
|
|
252
177
|
};
|
|
253
178
|
|
|
254
179
|
const {
|
|
@@ -270,19 +195,14 @@ export const AudioAttachment = (props: AudioAttachmentProps) => {
|
|
|
270
195
|
},
|
|
271
196
|
} = useTheme();
|
|
272
197
|
|
|
273
|
-
const progressValueInSeconds = useMemo(
|
|
274
|
-
() => (item.duration as number) * (item.progress as number),
|
|
275
|
-
[item.duration, item.progress],
|
|
276
|
-
);
|
|
277
|
-
|
|
278
198
|
const progressDuration = useMemo(
|
|
279
199
|
() =>
|
|
280
|
-
|
|
281
|
-
?
|
|
282
|
-
? dayjs.duration(
|
|
283
|
-
: dayjs.duration(
|
|
284
|
-
: dayjs.duration(
|
|
285
|
-
[
|
|
200
|
+
position
|
|
201
|
+
? position / ONE_HOUR_IN_MILLISECONDS >= 1
|
|
202
|
+
? dayjs.duration(position, 'milliseconds').format('HH:mm:ss')
|
|
203
|
+
: dayjs.duration(position, 'milliseconds').format('mm:ss')
|
|
204
|
+
: dayjs.duration(duration, 'milliseconds').format('mm:ss'),
|
|
205
|
+
[duration, position],
|
|
286
206
|
);
|
|
287
207
|
|
|
288
208
|
return (
|
|
@@ -308,7 +228,7 @@ export const AudioAttachment = (props: AudioAttachmentProps) => {
|
|
|
308
228
|
playPauseButton,
|
|
309
229
|
]}
|
|
310
230
|
>
|
|
311
|
-
{
|
|
231
|
+
{!isPlaying ? (
|
|
312
232
|
<Play fill={static_black} height={32} width={32} />
|
|
313
233
|
) : (
|
|
314
234
|
<Pause fill={static_black} height={32} width={32} />
|
|
@@ -328,7 +248,7 @@ export const AudioAttachment = (props: AudioAttachmentProps) => {
|
|
|
328
248
|
filenameText,
|
|
329
249
|
]}
|
|
330
250
|
>
|
|
331
|
-
{item
|
|
251
|
+
{isVoiceRecordingAttachment(item)
|
|
332
252
|
? 'Recording'
|
|
333
253
|
: getTrimmedAttachmentTitle(item.title, titleMaxLength)}
|
|
334
254
|
</Text>
|
|
@@ -344,17 +264,17 @@ export const AudioAttachment = (props: AudioAttachmentProps) => {
|
|
|
344
264
|
onEndDrag={dragEnd}
|
|
345
265
|
onProgressDrag={dragProgress}
|
|
346
266
|
onStartDrag={dragStart}
|
|
347
|
-
progress={
|
|
267
|
+
progress={progress}
|
|
348
268
|
waveformData={item.waveform_data}
|
|
349
269
|
/>
|
|
350
270
|
) : (
|
|
351
271
|
<ProgressControl
|
|
352
|
-
duration={
|
|
272
|
+
duration={duration}
|
|
353
273
|
filledColor={accent_blue}
|
|
354
274
|
onEndDrag={dragEnd}
|
|
355
275
|
onProgressDrag={dragProgress}
|
|
356
276
|
onStartDrag={dragStart}
|
|
357
|
-
progress={
|
|
277
|
+
progress={progress}
|
|
358
278
|
testID='progress-control'
|
|
359
279
|
/>
|
|
360
280
|
)}
|
|
@@ -367,8 +287,8 @@ export const AudioAttachment = (props: AudioAttachmentProps) => {
|
|
|
367
287
|
onLoad={handleLoad}
|
|
368
288
|
onProgress={handleProgress}
|
|
369
289
|
onSeek={onSeek}
|
|
370
|
-
paused={
|
|
371
|
-
rate={
|
|
290
|
+
paused={!isPlaying}
|
|
291
|
+
rate={currentPlaybackRate}
|
|
372
292
|
soundRef={soundRef as RefObject<SoundReturnType>}
|
|
373
293
|
testID='sound-player'
|
|
374
294
|
uri={item.asset_url}
|
|
@@ -377,7 +297,7 @@ export const AudioAttachment = (props: AudioAttachmentProps) => {
|
|
|
377
297
|
</View>
|
|
378
298
|
{showSpeedSettings ? (
|
|
379
299
|
<View style={[styles.rightContainer, rightContainer]}>
|
|
380
|
-
{
|
|
300
|
+
{!isPlaying ? (
|
|
381
301
|
<Audio fill={'#ffffff'} />
|
|
382
302
|
) : (
|
|
383
303
|
<Pressable
|
|
@@ -390,7 +310,7 @@ export const AudioAttachment = (props: AudioAttachmentProps) => {
|
|
|
390
310
|
>
|
|
391
311
|
<Text
|
|
392
312
|
style={[styles.speedChangeButtonText, speedChangeButtonText]}
|
|
393
|
-
>{`x${
|
|
313
|
+
>{`x${currentPlaybackRate.toFixed(1)}`}</Text>
|
|
394
314
|
</Pressable>
|
|
395
315
|
)}
|
|
396
316
|
</View>
|