Skip to content

Commit f10b73e

Browse files
committed
refactor: video gallery
1 parent 07f4d00 commit f10b73e

7 files changed

Lines changed: 130 additions & 63 deletions

File tree

package/src/components/Attachment/Attachment.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import {
2626
MessagesContextValue,
2727
useMessagesContext,
2828
} from '../../contexts/messagesContext/MessagesContext';
29-
import { usePendingAttachmentUpload } from '../../hooks/usePendingAttachmentUpload';
3029
import { isSoundPackageAvailable, isVideoPlayerAvailable } from '../../native';
3130

3231
import { primitives } from '../../theme';
@@ -189,14 +188,13 @@ const MessageAudioAttachment = ({
189188
message,
190189
}: MessageAudioAttachmentProps) => {
191190
const localId = (attachment as DefaultAttachmentData).localId;
192-
const { isUploading, uploadProgress } = usePendingAttachmentUpload(localId);
193-
194-
const indicator = isUploading ? (
191+
const indicator = (
195192
<AttachmentFileUploadProgressIndicator
193+
localId={localId}
194+
sourceUrl={attachment.asset_url ?? attachment.originalFile?.uri}
196195
totalBytes={attachment.file_size}
197-
uploadProgress={uploadProgress}
198196
/>
199-
) : undefined;
197+
);
200198

201199
const audioItemType = isVoiceRecordingAttachment(attachment) ? 'voiceRecording' : 'audio';
202200

package/src/components/Attachment/AttachmentFileUploadProgressIndicator.tsx

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
import React, { useMemo } from 'react';
22
import { StyleSheet, Text, View } from 'react-native';
3+
import type { StyleProp, ViewStyle } from 'react-native';
34

45
import { AttachmentUploadIndicator } from './AttachmentUploadIndicator';
56

67
import { useTheme } from '../../contexts/themeContext/ThemeContext';
8+
import { usePendingAttachmentUpload } from '../../hooks/usePendingAttachmentUpload';
79
import { primitives } from '../../theme';
10+
import { isLocalUrl } from '../../utils/utils';
811

912
export type AttachmentFileUploadProgressIndicatorProps = {
13+
containerStyle?: StyleProp<ViewStyle>;
14+
localId?: string;
15+
sourceUrl?: string;
1016
totalBytes?: number | string | null;
11-
uploadProgress: number | undefined;
1217
};
1318

1419
const parseTotalBytes = (value: number | string | null | undefined): number | null => {
@@ -35,13 +40,19 @@ const formatMegabytesOneDecimal = (bytes: number) => {
3540
/**
3641
* Circular progress plus `uploaded / total` for file and audio attachments during upload.
3742
*/
38-
export const AttachmentFileUploadProgressIndicator = ({
43+
export const AttachmentFileUploadProgressIndicatorUI = ({
44+
containerStyle,
45+
localId,
46+
sourceUrl,
3947
totalBytes,
40-
uploadProgress,
4148
}: AttachmentFileUploadProgressIndicatorProps) => {
4249
const {
4350
theme: { semantics },
4451
} = useTheme();
52+
const shouldTrackPendingUpload = !!localId && !!sourceUrl && isLocalUrl(sourceUrl);
53+
const pendingUpload = usePendingAttachmentUpload(shouldTrackPendingUpload ? localId : undefined);
54+
const uploadProgress = pendingUpload.uploadProgress;
55+
const shouldRender = pendingUpload.isUploading;
4556

4657
const progressLabel = useMemo(() => {
4758
const bytes = parseTotalBytes(totalBytes);
@@ -52,9 +63,13 @@ export const AttachmentFileUploadProgressIndicator = ({
5263
return `${formatMegabytesOneDecimal(uploaded)} / ${formatMegabytesOneDecimal(bytes)}`;
5364
}, [totalBytes, uploadProgress]);
5465

66+
if (!shouldRender) {
67+
return null;
68+
}
69+
5570
return (
56-
<View style={styles.row}>
57-
<AttachmentUploadIndicator uploadProgress={uploadProgress} />
71+
<View style={[styles.row, containerStyle]}>
72+
<AttachmentUploadIndicator localId={localId} sourceUrl={sourceUrl} />
5873
{progressLabel ? (
5974
<Text numberOfLines={1} style={[styles.label, { color: semantics.textSecondary }]}>
6075
{progressLabel}
@@ -64,6 +79,19 @@ export const AttachmentFileUploadProgressIndicator = ({
6479
);
6580
};
6681

82+
export const AttachmentFileUploadProgressIndicator = (
83+
props: AttachmentFileUploadProgressIndicatorProps,
84+
) => {
85+
const { localId, sourceUrl } = props;
86+
const shouldTrackPendingUpload = !!localId && !!sourceUrl && isLocalUrl(sourceUrl);
87+
88+
if (!shouldTrackPendingUpload) {
89+
return null;
90+
}
91+
92+
return <AttachmentFileUploadProgressIndicatorUI {...props} />;
93+
};
94+
6795
const styles = StyleSheet.create({
6896
label: {
6997
flex: 1,

package/src/components/Attachment/AttachmentUploadIndicator.tsx

Lines changed: 53 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,50 +5,82 @@ import type { StyleProp, ViewStyle } from 'react-native';
55
import { CircularProgressIndicator } from './CircularProgressIndicator';
66

77
import { useTheme } from '../../contexts/themeContext/ThemeContext';
8+
import { usePendingAttachmentUpload } from '../../hooks/usePendingAttachmentUpload';
9+
import { isLocalUrl } from '../../utils/utils';
810

911
export type AttachmentUploadIndicatorProps = {
12+
containerStyle?: StyleProp<ViewStyle>;
13+
localId?: string;
1014
size?: number;
15+
sourceUrl?: string;
1116
strokeWidth?: number;
1217
style?: StyleProp<ViewStyle>;
1318
testID?: string;
14-
/** When set, shows determinate `CircularProgressIndicator`; otherwise a generic spinner. */
15-
uploadProgress: number | undefined;
1619
};
1720

1821
/**
1922
* Upload state for attachment previews: determinate ring when progress is known, otherwise `ActivityIndicator`.
2023
*/
21-
export const AttachmentUploadIndicator = ({
24+
export const AttachmentUploadIndicatorUI = ({
25+
containerStyle,
26+
localId,
2227
size = 16,
2328
strokeWidth = 2,
2429
style,
2530
testID,
26-
uploadProgress,
2731
}: AttachmentUploadIndicatorProps) => {
2832
const {
2933
theme: { semantics },
3034
} = useTheme();
35+
const pendingUpload = usePendingAttachmentUpload(localId);
36+
const uploadProgress = pendingUpload.uploadProgress;
37+
const shouldRender = pendingUpload.isUploading;
38+
39+
if (!shouldRender) {
40+
return null;
41+
}
42+
43+
return (
44+
<View pointerEvents='none' style={containerStyle}>
45+
{uploadProgress === undefined ? (
46+
<View
47+
pointerEvents='none'
48+
style={[styles.indeterminateWrap, { height: size, width: size }, style]}
49+
testID={testID}
50+
>
51+
<ActivityIndicator color={semantics.accentPrimary} size='small' />
52+
</View>
53+
) : (
54+
<CircularProgressIndicator
55+
color={semantics.accentPrimary}
56+
progress={uploadProgress}
57+
size={size}
58+
strokeWidth={strokeWidth}
59+
style={style}
60+
testID={testID}
61+
/>
62+
)}
63+
</View>
64+
);
65+
};
66+
67+
export const AttachmentUploadIndicator = ({
68+
containerStyle,
69+
localId,
70+
sourceUrl,
71+
...props
72+
}: AttachmentUploadIndicatorProps) => {
73+
const shouldTrackPendingUpload = !!localId && !!sourceUrl && isLocalUrl(sourceUrl);
3174

32-
if (uploadProgress === undefined) {
33-
return (
34-
<View
35-
pointerEvents='none'
36-
style={[styles.indeterminateWrap, { height: size, width: size }, style]}
37-
testID={testID}
38-
>
39-
<ActivityIndicator color={semantics.accentPrimary} size='small' />
40-
</View>
41-
);
75+
if (!shouldTrackPendingUpload) {
76+
return null;
4277
}
4378

4479
return (
45-
<CircularProgressIndicator
46-
color={semantics.accentPrimary}
47-
progress={uploadProgress}
48-
size={size}
49-
strokeWidth={strokeWidth}
50-
style={style}
51-
testID={testID}
80+
<AttachmentUploadIndicatorUI
81+
{...props}
82+
containerStyle={containerStyle}
83+
localId={localId}
5284
/>
5385
);
5486
};

package/src/components/Attachment/FileAttachment.tsx

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import {
1818
useMessagesContext,
1919
} from '../../contexts/messagesContext/MessagesContext';
2020
import { useTheme } from '../../contexts/themeContext/ThemeContext';
21-
import { usePendingAttachmentUpload } from '../../hooks/usePendingAttachmentUpload';
2221
import type { DefaultAttachmentData } from '../../types/types';
2322

2423
export type FileAttachmentPropsWithContext = Pick<
@@ -54,7 +53,6 @@ const FileAttachmentWithContext = (props: FileAttachmentPropsWithContext) => {
5453
const { FilePreview } = useComponentsContext();
5554

5655
const localId = (attachment as DefaultAttachmentData).localId;
57-
const { isUploading, uploadProgress } = usePendingAttachmentUpload(localId);
5856

5957
const defaultOnPress = () => openUrlSafely(attachment.asset_url);
6058

@@ -98,12 +96,11 @@ const FileAttachmentWithContext = (props: FileAttachmentPropsWithContext) => {
9896
attachment={attachment}
9997
attachmentIconSize={attachmentIconSize}
10098
indicator={
101-
isUploading ? (
102-
<AttachmentFileUploadProgressIndicator
103-
totalBytes={attachment.file_size}
104-
uploadProgress={uploadProgress}
105-
/>
106-
) : undefined
99+
<AttachmentFileUploadProgressIndicator
100+
localId={localId}
101+
sourceUrl={attachment.asset_url ?? attachment.originalFile?.uri}
102+
totalBytes={attachment.file_size}
103+
/>
107104
}
108105
styles={stylesProp}
109106
/>

package/src/components/Attachment/Gallery.tsx

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ import {
3737
import { useTheme } from '../../contexts/themeContext/ThemeContext';
3838

3939
import { useLoadingImage } from '../../hooks/useLoadingImage';
40-
import { usePendingAttachmentUpload } from '../../hooks/usePendingAttachmentUpload';
4140
import { useStableCallback } from '../../hooks/useStableCallback';
4241
import { isVideoPlayerAvailable } from '../../native';
4342
import { primitives } from '../../theme';
@@ -347,7 +346,6 @@ const GalleryImageThumbnail = ({
347346
},
348347
} = useTheme();
349348
const styles = useStyles();
350-
const { isUploading, uploadProgress } = usePendingAttachmentUpload(thumbnail.localId);
351349

352350
const onLoadStart = useStableCallback(() => {
353351
setLoadingImageError(false);
@@ -379,11 +377,11 @@ const GalleryImageThumbnail = ({
379377
uri={thumbnail.url}
380378
/>
381379
{isLoadingImage ? <ImageLoadingIndicator /> : null}
382-
{isUploading ? (
383-
<View pointerEvents='none' style={styles.uploadProgressOnImage}>
384-
<AttachmentUploadIndicator uploadProgress={uploadProgress} />
385-
</View>
386-
) : null}
380+
<AttachmentUploadIndicator
381+
containerStyle={styles.uploadProgressOnImage}
382+
localId={thumbnail.localId}
383+
sourceUrl={thumbnail.url}
384+
/>
387385
</>
388386
)}
389387
</View>

package/src/components/Attachment/VideoThumbnail.tsx

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import React from 'react';
2-
import { ImageBackground, ImageStyle, StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
2+
import { ImageStyle, StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
33

44
import { AttachmentUploadIndicator } from './AttachmentUploadIndicator';
55

6+
import { useComponentsContext } from '../../contexts/componentsContext/ComponentsContext';
67
import { useTheme } from '../../contexts/themeContext/ThemeContext';
7-
import { usePendingAttachmentUpload } from '../../hooks/usePendingAttachmentUpload';
88
import { primitives } from '../../theme';
99
import { VideoPlayIndicator } from '../ui/VideoPlayIndicator';
1010

@@ -42,22 +42,22 @@ export const VideoThumbnail = (props: VideoThumbnailProps) => {
4242
},
4343
},
4444
} = useTheme();
45+
const { ImageComponent } = useComponentsContext();
4546
const { imageStyle, localId, style, thumb_url } = props;
46-
const { isUploading, uploadProgress } = usePendingAttachmentUpload(localId);
4747

4848
return (
49-
<ImageBackground
50-
accessibilityLabel='Video Thumbnail'
51-
imageStyle={imageStyle}
52-
source={{ uri: thumb_url }}
53-
style={[styles.container, container, style]}
54-
>
49+
<View style={[styles.container, container, style]}>
50+
<ImageComponent
51+
accessibilityLabel='Video Thumbnail'
52+
source={{ uri: thumb_url }}
53+
style={[StyleSheet.absoluteFill, imageStyle]}
54+
/>
5555
<VideoPlayIndicator size='md' />
56-
{isUploading ? (
57-
<View pointerEvents='none' style={styles.uploadProgressContainer}>
58-
<AttachmentUploadIndicator uploadProgress={uploadProgress} />
59-
</View>
60-
) : null}
61-
</ImageBackground>
56+
<AttachmentUploadIndicator
57+
containerStyle={styles.uploadProgressContainer}
58+
localId={localId}
59+
sourceUrl={thumb_url}
60+
/>
61+
</View>
6262
);
6363
};

package/src/components/Channel/Channel.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1082,7 +1082,21 @@ const ChannelWithContext = (props: PropsWithChildren<ChannelPropsWithContext>) =
10821082
fileForUpload = { ...originalFile, name: filename, uri: compressedUri };
10831083
}
10841084

1085-
const response = await client.uploadManager.upload({
1085+
const response = await (
1086+
client as typeof client & {
1087+
uploadManager: {
1088+
upload(args: {
1089+
channelCid: string;
1090+
file: {
1091+
name?: string;
1092+
type?: string;
1093+
uri: string;
1094+
};
1095+
id: string;
1096+
}): Promise<{ file: string; thumb_url?: string }>;
1097+
};
1098+
}
1099+
).uploadManager.upload({
10861100
channelCid: channel.cid,
10871101
file: fileForUpload,
10881102
id: localId,

0 commit comments

Comments
 (0)