Skip to content

Commit d2bc714

Browse files
authored
feat: show audio attachments in message list (#1582)
* feat: allow audio upload and improve UI of audio files in message input * feat: add audio upload in message input for expo apps * feat: audio upload implementation for native cli * fix: issues with audio attachment controls with native and expo cli * fix: playing multiple audio in sync with url tracked in the state above the component * feat: playing audio from message input one after the other * fix: issues with audio playing in expo * refactor: set state logic and made audio attachment upload preview component customizable * fix: styling between two audio files * feat: add support for audio attachments in message attachments inside messagelist * fix: props usage and making the AudioAttachment customizable, added docs for the component * fix: added isAudioPackageAvailable condition so that the audio Ui only renders if package available * refactor: change of status parameter to pausedStatus in onPlayPause
1 parent 41aa246 commit d2bc714

File tree

21 files changed

+289
-98
lines changed

21 files changed

+289
-98
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Component for rendering the Audio Attachment
2+
3+
Available Props:
4+
5+
- `index`
6+
7+
| Type | Default |
8+
| --------- | ------------------------------------------------------------------- |
9+
| Component | [`AudioAttachment`](../../../../ui-components/audio_attachment.mdx) |

docusaurus/docs/reactnative/contexts/message_input_context.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import SelectedPicker from '../common-content/contexts/attachment-picker-context
77

88
import AdditionalTextInputProps from '../common-content/core-components/channel/props/additional_text_input_props.mdx';
99
import AttachButton from '../common-content/core-components/channel/props/attach_button.mdx';
10+
import AudioAttachment from '../common-content/core-components/channel/props/audio_attachment.mdx';
1011
import AutoCompleteSuggestionsLimit from '../common-content/core-components/channel/props/auto_complete_suggestions_limit.mdx';
1112
import AutoCompleteTriggerSettings from '../common-content/core-components/channel/props/auto_complete_trigger_settings.mdx';
1213
import CommandsButton from '../common-content/core-components/channel/props/commands_button.mdx';
@@ -370,6 +371,10 @@ const { sendMessage, toggleAttachmentPicker } = useMessageInputContext();
370371

371372
<AttachButton />
372373

374+
### <div class="label description">_forwarded from [Channel](../core-components/channel.mdx#audioattachment)_ props</div> AudioAttachment {#audioattachment}
375+
376+
<AudioAttachment />
377+
373378
### <div class="label description">_forwarded from [Channel](../core-components/channel.mdx#commandsbutton)_ props</div> CommandsButton {#commandsbutton}
374379

375380
<CommandsButton />

docusaurus/docs/reactnative/core-components/channel.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import AdditionalTouchableProps from '../common-content/core-components/channel/
2626
import AttachButton from '../common-content/core-components/channel/props/attach_button.mdx';
2727
import Attachment from '../common-content/core-components/channel/props/attachment.mdx';
2828
import AttachmentActions from '../common-content/core-components/channel/props/attachment_actions.mdx';
29+
import AudioAttachment from '../common-content/core-components/channel/props/audio_attachment.mdx';
2930
import Card from '../common-content/core-components/channel/props/card.mdx';
3031
import CardCover from '../common-content/core-components/channel/props/card_cover.mdx';
3132
import CardFooter from '../common-content/core-components/channel/props/card_footer.mdx';
@@ -688,6 +689,10 @@ Callback function to set the [ref](https://reactjs.org/docs/refs-and-the-dom.htm
688689

689690
<AttachmentActions />
690691

692+
### AudioAttachment
693+
694+
<AudioAttachment />
695+
691696
### Card
692697

693698
<Card />
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
---
2+
id: 'audio-attachment'
3+
title: 'AudioAttachment'
4+
---
5+
6+
Component to render the Audio Attachment controls within the [MessageList](./message_list.mdx) and [MessageInput](./message_input.mdx).
7+
8+
This is the default component provided to the prop [`AudioAttachment`](../core-components/channel.mdx#audioattachment) on the `Channel` component.
9+
10+
## Props
11+
12+
### <div class="label required">required</div> **index**
13+
14+
| Type |
15+
| ------ |
16+
| number |
17+
18+
### <div class="label required">required</div> **item**
19+
20+
| Type |
21+
| -------------------------------------------- |
22+
| object(duration, progress, paused, id, file) |
23+
24+
### <div class="label required">required</div> **onLoad**
25+
26+
| Type |
27+
| ------------------------------------------- |
28+
| `(index: string, duration: number) => void` |
29+
30+
### <div class="label required">required</div> **onProgress**
31+
32+
| Type |
33+
| ----------------------------------------------------------------- |
34+
| `(index: string, currentTime?: number, hasEnd?: boolean) => void` |
35+
36+
### <div class="label required">required</div> **onPlayPause**
37+
38+
| Type |
39+
| ------------------------------------------------- |
40+
| `(index: string, pausedStatus?: boolean) => void` |
41+
42+
### testID
43+
44+
| Type |
45+
| ------ |
46+
| string |

examples/ExpoMessaging/ios/Podfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ SPEC CHECKSUMS:
536536
EXSharing: 328228a9f14503cfdec68892796478a7a15b8d4d
537537
EXSplashScreen: 21669e598804ee810547dbb6692c8deb5dd8dbf3
538538
FBLazyVector: c71c5917ec0ad2de41d5d06a5855f6d5eda06971
539-
FBReactNativeSpec: 244d2780a858c4f0972d17e1d6a0cad15e32fbbc
539+
FBReactNativeSpec: de8769e567b4274ba4a943fafbfe2f7e8fab89a8
540540
glog: 73c2498ac6884b13ede40eda8228cb1eee9d9d62
541541
RCT-Folly: ec7a233ccc97cc556cf7237f0db1ff65b986f27c
542542
RCTRequired: d34bf57e17cb6e3b2681f4809b13843c021feb6c

examples/ExpoMessaging/yarn.lock

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1864,6 +1864,27 @@
18641864
xcode "^3.0.1"
18651865
xml2js "0.4.23"
18661866

1867+
"@expo/config-plugins@^4.0.14":
1868+
version "4.1.5"
1869+
resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-4.1.5.tgz#9d357d2cda9c095e511b51583ede8a3b76174068"
1870+
integrity sha512-RVvU40RtZt12HavuDAe+LDIq9lHj7sheOfMEHdmpJ/uTA8pgvkbc56XF6JHQD+yRr6+uhhb+JnAasGq49dsQbw==
1871+
dependencies:
1872+
"@expo/config-types" "^45.0.0"
1873+
"@expo/json-file" "8.2.36"
1874+
"@expo/plist" "0.0.18"
1875+
"@expo/sdk-runtime-versions" "^1.0.0"
1876+
"@react-native/normalize-color" "^2.0.0"
1877+
chalk "^4.1.2"
1878+
debug "^4.3.1"
1879+
find-up "~5.0.0"
1880+
getenv "^1.0.0"
1881+
glob "7.1.6"
1882+
resolve-from "^5.0.0"
1883+
semver "^7.3.5"
1884+
slash "^3.0.0"
1885+
xcode "^3.0.1"
1886+
xml2js "0.4.23"
1887+
18671888
"@expo/config-types@^43.0.1":
18681889
version "43.0.1"
18691890
resolved "https://registry.yarnpkg.com/@expo/config-types/-/config-types-43.0.1.tgz#3e047dccb371741a540980eaff26fb0c95039c30"
@@ -1874,6 +1895,11 @@
18741895
resolved "https://registry.yarnpkg.com/@expo/config-types/-/config-types-44.0.0.tgz#d3480fe2c99f9e895dae4ebba58b74ed72d03e26"
18751896
integrity sha512-d+gpdKOAhqaD5RmcMzGgKzNtvE1w+GCqpFQNSXLliYlXjj+Tv0eL8EPeAdPtvke0vowpPFwd5McXLA90dgY6Jg==
18761897

1898+
"@expo/config-types@^45.0.0":
1899+
version "45.0.0"
1900+
resolved "https://registry.yarnpkg.com/@expo/config-types/-/config-types-45.0.0.tgz#963c2fdce8fbcbd003758b92ed8a25375f437ef6"
1901+
integrity sha512-/QGhhLWyaGautgEyU50UJr5YqKJix5t77ePTwreOVAhmZH+ff3nrrtYTTnccx+qF08ZNQmfAyYMCD3rQfzpiJA==
1902+
18771903
"@expo/[email protected]", "@expo/config@^6.0.6":
18781904
version "6.0.19"
18791905
resolved "https://registry.yarnpkg.com/@expo/config/-/config-6.0.19.tgz#26a7f7ffb6419cc6e6d4205b3c7764aa9ecb551a"
@@ -1957,6 +1983,15 @@
19571983
json5 "^1.0.1"
19581984
write-file-atomic "^2.3.0"
19591985

1986+
1987+
version "8.2.36"
1988+
resolved "https://registry.yarnpkg.com/@expo/json-file/-/json-file-8.2.36.tgz#62a505cb7f30a34d097386476794680a3f7385ff"
1989+
integrity sha512-tOZfTiIFA5KmMpdW9KF7bc6CFiGjb0xnbieJhTGlHrLL+ps2G0OkqmuZ3pFEXBOMnJYUVpnSy++52LFxvpa5ZQ==
1990+
dependencies:
1991+
"@babel/code-frame" "~7.10.4"
1992+
json5 "^1.0.1"
1993+
write-file-atomic "^2.3.0"
1994+
19601995
"@expo/metro-config@~0.2.6":
19611996
version "0.2.8"
19621997
resolved "https://registry.yarnpkg.com/@expo/metro-config/-/metro-config-0.2.8.tgz#c0fd56723e2fb9bb352e788e8f8fe0e218aaf663"
@@ -1986,6 +2021,15 @@
19862021
base64-js "^1.2.3"
19872022
xmlbuilder "^14.0.0"
19882023

2024+
2025+
version "0.0.18"
2026+
resolved "https://registry.yarnpkg.com/@expo/plist/-/plist-0.0.18.tgz#9abcde78df703a88f6d9fa1a557ee2f045d178b0"
2027+
integrity sha512-+48gRqUiz65R21CZ/IXa7RNBXgAI/uPSdvJqoN9x1hfL44DNbUoWHgHiEXTx7XelcATpDwNTz6sHLfy0iNqf+w==
2028+
dependencies:
2029+
"@xmldom/xmldom" "~0.7.0"
2030+
base64-js "^1.2.3"
2031+
xmlbuilder "^14.0.0"
2032+
19892033
"@expo/prebuild-config@^3.0.15":
19902034
version "3.1.0"
19912035
resolved "https://registry.yarnpkg.com/@expo/prebuild-config/-/prebuild-config-3.1.0.tgz#9fa10f12745ecaa6d3d4957ba97142edb8747a85"
@@ -3677,6 +3721,13 @@ expo-asset@~8.4.6:
36773721
path-browserify "^1.0.0"
36783722
url-parse "^1.4.4"
36793723

3724+
expo-av@^11.2.3:
3725+
version "11.2.3"
3726+
resolved "https://registry.yarnpkg.com/expo-av/-/expo-av-11.2.3.tgz#254242dae76e3cd60ef9d9c33618e4a12d37aa33"
3727+
integrity sha512-ptTe96s33Ct0eOsOmNTvtaWFx4B0SDkQmDfPbiuX/C2afqbLQf8geEopw7BRO8ZZl7Qe3qBMH6YLHXKTkZkTyQ==
3728+
dependencies:
3729+
"@expo/config-plugins" "^4.0.14"
3730+
36803731
expo-av@~10.2.0:
36813732
version "10.2.1"
36823733
resolved "https://registry.yarnpkg.com/expo-av/-/expo-av-10.2.1.tgz#c08bce464d673d0e90c68cac082bfb75a9437f25"

package/src/components/MessageInput/AudioAttachmentUploadPreview.tsx renamed to package/src/components/Attachment/AudioAttachment.tsx

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const styles = StyleSheet.create({
3434
paddingLeft: 8,
3535
paddingRight: 8,
3636
},
37-
fileContentContainer: { flexDirection: 'row' },
37+
fileContentContainer: { flexDirection: 'row', paddingRight: 40 },
3838
filenameText: {
3939
fontSize: 14,
4040
fontWeight: 'bold',
@@ -76,24 +76,24 @@ const styles = StyleSheet.create({
7676
},
7777
});
7878

79-
export type AudioAttachmentUploadPreviewPropsWithContext<
79+
export type AudioAttachmentPropsWithContext<
8080
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
8181
> = Pick<
8282
MessageInputContextValue<StreamChatGenerics>,
8383
'fileUploads' | 'removeFile' | 'uploadFile'
8484
> & {
8585
index: number;
86-
item: FileUpload;
86+
item: Omit<FileUpload, 'state'>;
8787
onLoad: (index: string, duration: number) => void;
88-
onPlayPause: (index: string, status?: boolean) => void;
88+
onPlayPause: (index: string, pausedStatus?: boolean) => void;
8989
onProgress: (index: string, currentTime?: number, hasEnd?: boolean) => void;
90-
testID: string;
90+
testID?: string;
9191
};
9292

93-
const AudioAttachmentUploadPreviewWithContext = <
93+
const AudioAttachmentWithContext = <
9494
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
9595
>(
96-
props: AudioAttachmentUploadPreviewPropsWithContext<StreamChatGenerics>,
96+
props: AudioAttachmentPropsWithContext<StreamChatGenerics>,
9797
) => {
9898
const soundRef = React.useRef<SoundReturnType | null>(null);
9999
const { fileUploads, index, item, onLoad, onPlayPause, onProgress } = props;
@@ -212,10 +212,10 @@ const AudioAttachmentUploadPreviewWithContext = <
212212

213213
const {
214214
theme: {
215-
colors: { accent_blue, black, grey_dark, grey_whisper, static_black, static_white },
215+
colors: { accent_blue, black, grey_dark, grey_whisper, static_black, static_white, white },
216216
messageInput: {
217217
fileUploadPreview: {
218-
audioAttachmentUploadPreview: { progressControlView, progressDurationText, roundedView },
218+
audioAttachment: { progressControlView, progressDurationText, roundedView },
219219
fileContainer,
220220
fileContentContainer,
221221
filenameText,
@@ -245,6 +245,7 @@ const AudioAttachmentUploadPreviewWithContext = <
245245
}
246246
: {},
247247
{
248+
backgroundColor: white,
248249
borderColor: grey_whisper,
249250
width: -16,
250251
},
@@ -318,7 +319,7 @@ const AudioAttachmentUploadPreviewWithContext = <
318319
onProgressDrag={handleProgressDrag}
319320
progress={item.progress as number}
320321
testID='progress-control'
321-
width={110}
322+
width={120}
322323
/>
323324
</View>
324325
</View>
@@ -328,35 +329,29 @@ const AudioAttachmentUploadPreviewWithContext = <
328329
);
329330
};
330331

331-
export type AudioAttachmentUploadPreviewProps<
332+
export type AudioAttachmentProps<
332333
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
333-
> = Partial<AudioAttachmentUploadPreviewPropsWithContext<StreamChatGenerics>> & {
334+
> = Partial<AudioAttachmentPropsWithContext<StreamChatGenerics>> & {
334335
index: number;
335-
item: FileUpload;
336+
item: Omit<FileUpload, 'state'>;
336337
onLoad: (index: string, duration: number) => void;
337-
onPlayPause: (index: string, status?: boolean) => void;
338+
onPlayPause: (index: string, pausedStatus?: boolean) => void;
338339
onProgress: (index: string, currentTime?: number, hasEnd?: boolean) => void;
339340
testID: string;
340341
};
341342

342343
/**
343-
* AudioAttachmentUploadPreview
344-
* UI Component to preview the audio files set for upload
344+
* AudioAttachment
345+
* UI Component to preview the audio files
345346
*/
346-
export const AudioAttachmentUploadPreview = <
347+
export const AudioAttachment = <
347348
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
348349
>(
349-
props: AudioAttachmentUploadPreviewProps<StreamChatGenerics>,
350+
props: AudioAttachmentProps<StreamChatGenerics>,
350351
) => {
351352
const { fileUploads, removeFile, uploadFile } = useMessageInputContext<StreamChatGenerics>();
352353

353-
return (
354-
<AudioAttachmentUploadPreviewWithContext
355-
{...{ fileUploads, removeFile, uploadFile }}
356-
{...props}
357-
/>
358-
);
354+
return <AudioAttachmentWithContext {...{ fileUploads, removeFile, uploadFile }} {...props} />;
359355
};
360356

361-
AudioAttachmentUploadPreview.displayName =
362-
'AudioAttachmentUploadPreview{messageInput{autoAttachmentUploadPreview}}';
357+
AudioAttachment.displayName = 'AudioAttachment{messageInput{autoAttachment}}';

0 commit comments

Comments
 (0)