stream-chat-react-native-core 5.1.0 → 5.2.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/ChannelList/ChannelListMessenger.js +32 -15
- package/lib/commonjs/components/ChannelList/ChannelListMessenger.js.map +1 -1
- package/lib/commonjs/components/Chat/Chat.js +17 -5
- package/lib/commonjs/components/Chat/Chat.js.map +1 -1
- package/lib/commonjs/components/ImageGallery/ImageGallery.js +106 -100
- package/lib/commonjs/components/ImageGallery/ImageGallery.js.map +1 -1
- package/lib/commonjs/components/ImageGallery/components/AnimatedGalleryVideo.js +14 -16
- package/lib/commonjs/components/ImageGallery/components/AnimatedGalleryVideo.js.map +1 -1
- package/lib/commonjs/components/ImageGallery/components/ImageGalleryFooter.js +13 -16
- package/lib/commonjs/components/ImageGallery/components/ImageGalleryFooter.js.map +1 -1
- package/lib/commonjs/components/ImageGallery/components/ImageGalleryVideoControl.js +6 -6
- package/lib/commonjs/components/ImageGallery/components/ImageGalleryVideoControl.js.map +1 -1
- package/lib/commonjs/components/MessageList/MessageList.js +39 -26
- package/lib/commonjs/components/MessageList/MessageList.js.map +1 -1
- package/lib/commonjs/components/MessageOverlay/OverlayReactions.js +19 -19
- package/lib/commonjs/components/MessageOverlay/OverlayReactions.js.map +1 -1
- package/lib/commonjs/components/ProgressControl/ProgressControl.js +6 -6
- package/lib/commonjs/components/ProgressControl/ProgressControl.js.map +1 -1
- package/lib/commonjs/contexts/debugContext/DebugContext.js +63 -0
- package/lib/commonjs/contexts/debugContext/DebugContext.js.map +1 -0
- package/lib/commonjs/contexts/index.js +13 -0
- package/lib/commonjs/contexts/index.js.map +1 -1
- package/lib/commonjs/native.js.map +1 -1
- package/lib/commonjs/version.json +1 -1
- package/lib/module/components/ChannelList/ChannelListMessenger.js +32 -15
- package/lib/module/components/ChannelList/ChannelListMessenger.js.map +1 -1
- package/lib/module/components/Chat/Chat.js +17 -5
- package/lib/module/components/Chat/Chat.js.map +1 -1
- package/lib/module/components/ImageGallery/ImageGallery.js +106 -100
- package/lib/module/components/ImageGallery/ImageGallery.js.map +1 -1
- package/lib/module/components/ImageGallery/components/AnimatedGalleryVideo.js +14 -16
- package/lib/module/components/ImageGallery/components/AnimatedGalleryVideo.js.map +1 -1
- package/lib/module/components/ImageGallery/components/ImageGalleryFooter.js +13 -16
- package/lib/module/components/ImageGallery/components/ImageGalleryFooter.js.map +1 -1
- package/lib/module/components/ImageGallery/components/ImageGalleryVideoControl.js +6 -6
- package/lib/module/components/ImageGallery/components/ImageGalleryVideoControl.js.map +1 -1
- package/lib/module/components/MessageList/MessageList.js +39 -26
- package/lib/module/components/MessageList/MessageList.js.map +1 -1
- package/lib/module/components/MessageOverlay/OverlayReactions.js +19 -19
- package/lib/module/components/MessageOverlay/OverlayReactions.js.map +1 -1
- package/lib/module/components/ProgressControl/ProgressControl.js +6 -6
- package/lib/module/components/ProgressControl/ProgressControl.js.map +1 -1
- package/lib/module/contexts/debugContext/DebugContext.js +63 -0
- package/lib/module/contexts/debugContext/DebugContext.js.map +1 -0
- package/lib/module/contexts/index.js +13 -0
- package/lib/module/contexts/index.js.map +1 -1
- package/lib/module/native.js.map +1 -1
- package/lib/module/version.json +1 -1
- package/lib/typescript/components/ImageGallery/ImageGallery.d.ts +3 -0
- package/lib/typescript/components/ImageGallery/components/AnimatedGalleryVideo.d.ts +5 -3
- package/lib/typescript/components/ImageGallery/components/ImageGalleryFooter.d.ts +1 -3
- package/lib/typescript/components/MessageOverlay/OverlayReactions.d.ts +1 -0
- package/lib/typescript/components/ProgressControl/ProgressControl.d.ts +1 -1
- package/lib/typescript/contexts/debugContext/DebugContext.d.ts +27 -0
- package/lib/typescript/contexts/index.d.ts +1 -0
- package/lib/typescript/native.d.ts +3 -2
- package/package.json +2 -2
- package/src/components/ChannelList/ChannelListMessenger.tsx +17 -0
- package/src/components/Chat/Chat.tsx +13 -0
- package/src/components/ImageGallery/ImageGallery.tsx +87 -65
- package/src/components/ImageGallery/__tests__/AnimatedVideoGallery.test.tsx +2 -2
- package/src/components/ImageGallery/__tests__/ImageGallery.test.tsx +40 -28
- package/src/components/ImageGallery/components/AnimatedGalleryVideo.tsx +16 -9
- package/src/components/ImageGallery/components/ImageGalleryFooter.tsx +1 -6
- package/src/components/ImageGallery/components/ImageGalleryVideoControl.tsx +5 -6
- package/src/components/MessageList/MessageList.tsx +15 -0
- package/src/components/MessageOverlay/OverlayReactions.tsx +1 -0
- package/src/components/ProgressControl/ProgressControl.tsx +8 -4
- package/src/contexts/debugContext/DebugContext.tsx +77 -0
- package/src/contexts/index.ts +1 -0
- package/src/native.ts +3 -2
- package/src/version.json +1 -1
|
@@ -55,12 +55,7 @@ import {
|
|
|
55
55
|
useOverlayContext,
|
|
56
56
|
} from '../../contexts/overlayContext/OverlayContext';
|
|
57
57
|
import { useTheme } from '../../contexts/themeContext/ThemeContext';
|
|
58
|
-
import {
|
|
59
|
-
isVideoPackageAvailable,
|
|
60
|
-
VideoPayloadData,
|
|
61
|
-
VideoProgressData,
|
|
62
|
-
VideoType,
|
|
63
|
-
} from '../../native';
|
|
58
|
+
import { isVideoPackageAvailable, VideoType } from '../../native';
|
|
64
59
|
import type { DefaultStreamChatGenerics } from '../../types/types';
|
|
65
60
|
import { getResizedImageUrl } from '../../utils/getResizedImageUrl';
|
|
66
61
|
import { getUrlOfImageAttachment } from '../../utils/getUrlOfImageAttachment';
|
|
@@ -151,9 +146,9 @@ export const ImageGallery = <
|
|
|
151
146
|
numberOfImageGalleryGridColumns,
|
|
152
147
|
overlayOpacity,
|
|
153
148
|
} = props;
|
|
154
|
-
const [
|
|
155
|
-
|
|
156
|
-
|
|
149
|
+
const [imageGalleryAttachments, setImageGalleryAttachments] = useState<
|
|
150
|
+
Photo<StreamChatGenerics>[]
|
|
151
|
+
>([]);
|
|
157
152
|
const {
|
|
158
153
|
theme: {
|
|
159
154
|
colors: { white_snow },
|
|
@@ -282,11 +277,14 @@ export const ImageGallery = <
|
|
|
282
277
|
return {
|
|
283
278
|
channelId: cur.cid,
|
|
284
279
|
created_at: cur.created_at,
|
|
280
|
+
duration: 0,
|
|
285
281
|
id: `photoId-${cur.id}-${imageUrl}`,
|
|
286
282
|
messageId: cur.id,
|
|
287
283
|
mime_type: a.type === 'giphy' ? getGiphyMimeType(giphyURL ?? '') : a.mime_type,
|
|
288
284
|
original_height: a.original_height,
|
|
289
285
|
original_width: a.original_width,
|
|
286
|
+
paused: true,
|
|
287
|
+
progress: 0,
|
|
290
288
|
type: a.type,
|
|
291
289
|
uri:
|
|
292
290
|
a.type === 'giphy'
|
|
@@ -312,6 +310,10 @@ export const ImageGallery = <
|
|
|
312
310
|
*/
|
|
313
311
|
const photoLength = photos.length;
|
|
314
312
|
|
|
313
|
+
useEffect(() => {
|
|
314
|
+
setImageGalleryAttachments(photos);
|
|
315
|
+
}, []);
|
|
316
|
+
|
|
315
317
|
/**
|
|
316
318
|
* The URL for the images may differ because of dimensions passed as
|
|
317
319
|
* part of the query.
|
|
@@ -338,10 +340,6 @@ export const ImageGallery = <
|
|
|
338
340
|
stripQueryFromUrl(photo.uri) === stripQueryFromUrl(selectedMessage?.url || ''),
|
|
339
341
|
);
|
|
340
342
|
|
|
341
|
-
if (photoLength > 1) {
|
|
342
|
-
setPaused(true);
|
|
343
|
-
}
|
|
344
|
-
|
|
345
343
|
runOnUI(updatePosition)(newIndex);
|
|
346
344
|
}, [selectedMessage, photoLength]);
|
|
347
345
|
|
|
@@ -351,10 +349,11 @@ export const ImageGallery = <
|
|
|
351
349
|
* to the proper scaled height based on the width being restricted to the
|
|
352
350
|
* screen width when the dimensions are received.
|
|
353
351
|
*/
|
|
354
|
-
const uriForCurrentImage =
|
|
352
|
+
const uriForCurrentImage = imageGalleryAttachments[selectedIndex]?.uri;
|
|
353
|
+
|
|
355
354
|
useEffect(() => {
|
|
356
355
|
setCurrentImageHeight(screenHeight);
|
|
357
|
-
const photo =
|
|
356
|
+
const photo = imageGalleryAttachments[index.value];
|
|
358
357
|
const height = photo?.original_height;
|
|
359
358
|
const width = photo?.original_width;
|
|
360
359
|
|
|
@@ -463,53 +462,69 @@ export const ImageGallery = <
|
|
|
463
462
|
const openGridView = () => {
|
|
464
463
|
if (bottomSheetModalRef.current?.present) {
|
|
465
464
|
bottomSheetModalRef.current.present();
|
|
466
|
-
setGridPhotos(
|
|
465
|
+
setGridPhotos(imageGalleryAttachments);
|
|
467
466
|
}
|
|
468
467
|
};
|
|
469
468
|
|
|
469
|
+
const handleEnd = () => {
|
|
470
|
+
handlePlayPause(imageGalleryAttachments[selectedIndex].id, true);
|
|
471
|
+
handleProgress(imageGalleryAttachments[selectedIndex].id, 1, true);
|
|
472
|
+
};
|
|
473
|
+
|
|
470
474
|
const videoRef = useRef<VideoType>(null);
|
|
471
475
|
|
|
472
|
-
const
|
|
473
|
-
|
|
474
|
-
|
|
476
|
+
const handleLoad = (index: string, duration: number) => {
|
|
477
|
+
setImageGalleryAttachments((prevImageGalleryAttachment) =>
|
|
478
|
+
prevImageGalleryAttachment.map((imageGalleryAttachment) => ({
|
|
479
|
+
...imageGalleryAttachment,
|
|
480
|
+
duration: imageGalleryAttachment.id === index ? duration : imageGalleryAttachment.duration,
|
|
481
|
+
})),
|
|
482
|
+
);
|
|
475
483
|
};
|
|
476
484
|
|
|
477
|
-
const
|
|
478
|
-
|
|
485
|
+
const handleProgress = (index: string, progress: number, hasEnd?: boolean) => {
|
|
486
|
+
setImageGalleryAttachments((prevImageGalleryAttachments) =>
|
|
487
|
+
prevImageGalleryAttachments.map((imageGalleryAttachment) => ({
|
|
488
|
+
...imageGalleryAttachment,
|
|
489
|
+
progress:
|
|
490
|
+
imageGalleryAttachment.id === index
|
|
491
|
+
? hasEnd
|
|
492
|
+
? 1
|
|
493
|
+
: progress
|
|
494
|
+
: imageGalleryAttachment.progress,
|
|
495
|
+
})),
|
|
496
|
+
);
|
|
479
497
|
};
|
|
480
498
|
|
|
481
|
-
const
|
|
482
|
-
if (
|
|
483
|
-
|
|
499
|
+
const handlePlayPause = (index: string, pausedStatus?: boolean) => {
|
|
500
|
+
if (pausedStatus === false) {
|
|
501
|
+
// If the status is false we set the audio with the index as playing and the others as paused.
|
|
502
|
+
setImageGalleryAttachments((prevImageGalleryAttachment) =>
|
|
503
|
+
prevImageGalleryAttachment.map((imageGalleryAttachment) => ({
|
|
504
|
+
...imageGalleryAttachment,
|
|
505
|
+
paused: imageGalleryAttachment.id === index ? false : true,
|
|
506
|
+
})),
|
|
507
|
+
);
|
|
508
|
+
} else {
|
|
509
|
+
// If the status is true we simply set all the audio's paused state as true.
|
|
510
|
+
setImageGalleryAttachments((prevImageGalleryAttachment) =>
|
|
511
|
+
prevImageGalleryAttachment.map((imageGalleryAttachment) => ({
|
|
512
|
+
...imageGalleryAttachment,
|
|
513
|
+
paused: true,
|
|
514
|
+
})),
|
|
515
|
+
);
|
|
484
516
|
}
|
|
485
517
|
};
|
|
486
518
|
|
|
487
|
-
const
|
|
519
|
+
const onPlayPause = (status?: boolean) => {
|
|
488
520
|
if (status === undefined) {
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
// Expo AV for Expo has replayAsync as an API to move to a starting of the video
|
|
494
|
-
if (progress === 1 && videoRef.current && videoRef.current.replayAsync) {
|
|
495
|
-
videoRef.current.replayAsync();
|
|
521
|
+
if (imageGalleryAttachments[selectedIndex].paused) {
|
|
522
|
+
handlePlayPause(imageGalleryAttachments[selectedIndex].id, false);
|
|
523
|
+
} else {
|
|
524
|
+
handlePlayPause(imageGalleryAttachments[selectedIndex].id, true);
|
|
496
525
|
}
|
|
497
|
-
|
|
498
|
-
setPaused((state) => !state);
|
|
499
526
|
} else {
|
|
500
|
-
|
|
501
|
-
}
|
|
502
|
-
};
|
|
503
|
-
|
|
504
|
-
const onProgressDrag = (progress: number) => {
|
|
505
|
-
// React Native Video for RN CLI has seek as an API to move to a particular location in the video
|
|
506
|
-
if (videoRef.current && videoRef.current.seek) {
|
|
507
|
-
videoRef.current.seek(progress);
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
// Expo AV for Expo has setPositionAsync as an API to move to a particular location of the video
|
|
511
|
-
if (videoRef.current && videoRef.current.setPositionAsync) {
|
|
512
|
-
videoRef.current.setPositionAsync(progress * 1000);
|
|
527
|
+
handlePlayPause(imageGalleryAttachments[selectedIndex].id, status);
|
|
513
528
|
}
|
|
514
529
|
};
|
|
515
530
|
|
|
@@ -568,17 +583,19 @@ export const ImageGallery = <
|
|
|
568
583
|
},
|
|
569
584
|
]}
|
|
570
585
|
>
|
|
571
|
-
{
|
|
586
|
+
{imageGalleryAttachments.map((photo, i) =>
|
|
572
587
|
photo.type === 'video' ? (
|
|
573
588
|
<AnimatedGalleryVideo
|
|
589
|
+
attachmentId={photo.id}
|
|
574
590
|
handleEnd={handleEnd}
|
|
575
591
|
handleLoad={handleLoad}
|
|
576
592
|
handleProgress={handleProgress}
|
|
577
593
|
index={i}
|
|
578
594
|
key={`${photo.uri}-${i}`}
|
|
579
595
|
offsetScale={offsetScale}
|
|
580
|
-
paused={paused}
|
|
596
|
+
paused={photo.paused || false}
|
|
581
597
|
previous={selectedIndex > i}
|
|
598
|
+
repeat={true}
|
|
582
599
|
scale={scale}
|
|
583
600
|
screenHeight={screenHeight}
|
|
584
601
|
selected={selectedIndex === i}
|
|
@@ -632,25 +649,27 @@ export const ImageGallery = <
|
|
|
632
649
|
</TapGestureHandler>
|
|
633
650
|
<ImageGalleryHeader<StreamChatGenerics>
|
|
634
651
|
opacity={headerFooterOpacity}
|
|
635
|
-
photo={
|
|
652
|
+
photo={imageGalleryAttachments[selectedIndex]}
|
|
636
653
|
visible={headerFooterVisible}
|
|
637
654
|
{...imageGalleryCustomComponents?.header}
|
|
638
655
|
/>
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
656
|
+
|
|
657
|
+
{imageGalleryAttachments.length > 0 && (
|
|
658
|
+
<ImageGalleryFooter<StreamChatGenerics>
|
|
659
|
+
accessibilityLabel={'Image Gallery Footer'}
|
|
660
|
+
duration={imageGalleryAttachments[selectedIndex].duration || 0}
|
|
661
|
+
onPlayPause={onPlayPause}
|
|
662
|
+
opacity={headerFooterOpacity}
|
|
663
|
+
openGridView={openGridView}
|
|
664
|
+
paused={imageGalleryAttachments[selectedIndex].paused || false}
|
|
665
|
+
photo={imageGalleryAttachments[selectedIndex]}
|
|
666
|
+
photoLength={imageGalleryAttachments.length}
|
|
667
|
+
progress={imageGalleryAttachments[selectedIndex].progress || 0}
|
|
668
|
+
selectedIndex={selectedIndex}
|
|
669
|
+
visible={headerFooterVisible}
|
|
670
|
+
{...imageGalleryCustomComponents?.footer}
|
|
671
|
+
/>
|
|
672
|
+
)}
|
|
654
673
|
|
|
655
674
|
<ImageGalleryOverlay
|
|
656
675
|
animatedBottomSheetIndex={animatedBottomSheetIndex}
|
|
@@ -708,10 +727,13 @@ export type Photo<
|
|
|
708
727
|
uri: string;
|
|
709
728
|
channelId?: string;
|
|
710
729
|
created_at?: string | Date;
|
|
730
|
+
duration?: number;
|
|
711
731
|
messageId?: string;
|
|
712
732
|
mime_type?: string;
|
|
713
733
|
original_height?: number;
|
|
714
734
|
original_width?: number;
|
|
735
|
+
paused?: boolean;
|
|
736
|
+
progress?: number;
|
|
715
737
|
type?: string;
|
|
716
738
|
user?: UserResponse<StreamChatGenerics> | null;
|
|
717
739
|
user_id?: string;
|
|
@@ -78,7 +78,7 @@ describe('ImageGallery', () => {
|
|
|
78
78
|
|
|
79
79
|
act(() => {
|
|
80
80
|
fireEvent(videoComponent, 'onEnd');
|
|
81
|
-
fireEvent(videoComponent, 'onProgress');
|
|
81
|
+
fireEvent(videoComponent, 'onProgress', { currentTime: 10, seekableDuration: 60 });
|
|
82
82
|
});
|
|
83
83
|
|
|
84
84
|
expect(handleEndMock).toHaveBeenCalled();
|
|
@@ -127,7 +127,7 @@ describe('ImageGallery', () => {
|
|
|
127
127
|
const spinnerComponent = queryByA11yLabel('Spinner');
|
|
128
128
|
|
|
129
129
|
act(() => {
|
|
130
|
-
fireEvent(videoComponent, 'onLoad');
|
|
130
|
+
fireEvent(videoComponent, 'onLoad', { duration: 10 });
|
|
131
131
|
});
|
|
132
132
|
|
|
133
133
|
expect(handleLoadMock).toHaveBeenCalled();
|
|
@@ -64,22 +64,25 @@ describe('ImageGallery', () => {
|
|
|
64
64
|
});
|
|
65
65
|
|
|
66
66
|
it('handle handleLoad function when video item present and payload duration is available', () => {
|
|
67
|
+
const attachment = generateVideoAttachment({ type: 'video' });
|
|
68
|
+
const message = generateMessage({
|
|
69
|
+
attachments: [attachment],
|
|
70
|
+
});
|
|
67
71
|
const { getByA11yLabel } = render(
|
|
68
72
|
getComponent({
|
|
69
|
-
messages: [
|
|
70
|
-
generateMessage({
|
|
71
|
-
attachments: [generateVideoAttachment({ type: 'video' })],
|
|
72
|
-
}),
|
|
73
|
-
] as unknown as MessageType<DefaultStreamChatGenerics>[],
|
|
73
|
+
messages: [message] as unknown as MessageType<DefaultStreamChatGenerics>[],
|
|
74
74
|
}),
|
|
75
75
|
);
|
|
76
76
|
|
|
77
77
|
const videoItemComponent = getByA11yLabel('Image Gallery Video');
|
|
78
78
|
|
|
79
79
|
act(() => {
|
|
80
|
-
fireEvent(
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
fireEvent(
|
|
81
|
+
videoItemComponent,
|
|
82
|
+
'handleLoad',
|
|
83
|
+
`photoId-${message.id}-${attachment.asset_url}`,
|
|
84
|
+
10,
|
|
85
|
+
);
|
|
83
86
|
});
|
|
84
87
|
|
|
85
88
|
const videoDurationComponent = getByA11yLabel('Video Duration');
|
|
@@ -110,26 +113,32 @@ describe('ImageGallery', () => {
|
|
|
110
113
|
});
|
|
111
114
|
|
|
112
115
|
it('handle handleProgress function when video item present and payload is well defined', () => {
|
|
116
|
+
const attachment = generateVideoAttachment({ type: 'video' });
|
|
117
|
+
const message = generateMessage({
|
|
118
|
+
attachments: [attachment],
|
|
119
|
+
});
|
|
120
|
+
|
|
113
121
|
const { getByA11yLabel } = render(
|
|
114
122
|
getComponent({
|
|
115
|
-
messages: [
|
|
116
|
-
generateMessage({
|
|
117
|
-
attachments: [generateVideoAttachment({ type: 'video' })],
|
|
118
|
-
}),
|
|
119
|
-
] as unknown as MessageType<DefaultStreamChatGenerics>[],
|
|
123
|
+
messages: [message] as unknown as MessageType<DefaultStreamChatGenerics>[],
|
|
120
124
|
}),
|
|
121
125
|
);
|
|
122
126
|
|
|
123
127
|
const videoItemComponent = getByA11yLabel('Image Gallery Video');
|
|
124
128
|
|
|
125
129
|
act(() => {
|
|
126
|
-
fireEvent(
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
130
|
+
fireEvent(
|
|
131
|
+
videoItemComponent,
|
|
132
|
+
'handleLoad',
|
|
133
|
+
`photoId-${message.id}-${attachment.asset_url}`,
|
|
134
|
+
10,
|
|
135
|
+
);
|
|
136
|
+
fireEvent(
|
|
137
|
+
videoItemComponent,
|
|
138
|
+
'handleProgress',
|
|
139
|
+
`photoId-${message.id}-${attachment.asset_url}`,
|
|
140
|
+
0.3,
|
|
141
|
+
);
|
|
133
142
|
});
|
|
134
143
|
|
|
135
144
|
const progressDurationComponent = getByA11yLabel('Progress Duration');
|
|
@@ -166,22 +175,25 @@ describe('ImageGallery', () => {
|
|
|
166
175
|
});
|
|
167
176
|
|
|
168
177
|
it('handle handleEnd function when video item present', () => {
|
|
178
|
+
const attachment = generateVideoAttachment({ type: 'video' });
|
|
179
|
+
const message = generateMessage({
|
|
180
|
+
attachments: [attachment],
|
|
181
|
+
});
|
|
169
182
|
const { getByA11yLabel } = render(
|
|
170
183
|
getComponent({
|
|
171
|
-
messages: [
|
|
172
|
-
generateMessage({
|
|
173
|
-
attachments: [generateVideoAttachment({ type: 'video' })],
|
|
174
|
-
}),
|
|
175
|
-
] as unknown as MessageType<DefaultStreamChatGenerics>[],
|
|
184
|
+
messages: [message] as unknown as MessageType<DefaultStreamChatGenerics>[],
|
|
176
185
|
}),
|
|
177
186
|
);
|
|
178
187
|
|
|
179
188
|
const videoItemComponent = getByA11yLabel('Image Gallery Video');
|
|
180
189
|
|
|
181
190
|
act(() => {
|
|
182
|
-
fireEvent(
|
|
183
|
-
|
|
184
|
-
|
|
191
|
+
fireEvent(
|
|
192
|
+
videoItemComponent,
|
|
193
|
+
'handleLoad',
|
|
194
|
+
`photoId-${message.id}-${attachment.asset_url}`,
|
|
195
|
+
10,
|
|
196
|
+
);
|
|
185
197
|
fireEvent(videoItemComponent, 'handleEnd');
|
|
186
198
|
});
|
|
187
199
|
|
|
@@ -20,9 +20,10 @@ const halfScreenWidth = vw(50);
|
|
|
20
20
|
const oneEighth = 1 / 8;
|
|
21
21
|
|
|
22
22
|
export type AnimatedGalleryVideoType = {
|
|
23
|
+
attachmentId: string;
|
|
23
24
|
handleEnd: () => void;
|
|
24
|
-
handleLoad: (
|
|
25
|
-
handleProgress: (
|
|
25
|
+
handleLoad: (index: string, duration: number) => void;
|
|
26
|
+
handleProgress: (index: string, progress: number, hasEnd?: boolean) => void;
|
|
26
27
|
index: number;
|
|
27
28
|
offsetScale: Animated.SharedValue<number>;
|
|
28
29
|
paused: boolean;
|
|
@@ -35,6 +36,7 @@ export type AnimatedGalleryVideoType = {
|
|
|
35
36
|
translateX: Animated.SharedValue<number>;
|
|
36
37
|
translateY: Animated.SharedValue<number>;
|
|
37
38
|
videoRef: React.RefObject<VideoType>;
|
|
39
|
+
repeat?: boolean;
|
|
38
40
|
style?: StyleProp<ViewStyle>;
|
|
39
41
|
};
|
|
40
42
|
|
|
@@ -51,7 +53,9 @@ const styles = StyleSheet.create({
|
|
|
51
53
|
export const AnimatedGalleryVideo: React.FC<AnimatedGalleryVideoType> = React.memo(
|
|
52
54
|
(props) => {
|
|
53
55
|
const [opacity, setOpacity] = useState<number>(1);
|
|
56
|
+
|
|
54
57
|
const {
|
|
58
|
+
attachmentId,
|
|
55
59
|
handleEnd,
|
|
56
60
|
handleLoad,
|
|
57
61
|
handleProgress,
|
|
@@ -59,6 +63,7 @@ export const AnimatedGalleryVideo: React.FC<AnimatedGalleryVideoType> = React.me
|
|
|
59
63
|
offsetScale,
|
|
60
64
|
paused,
|
|
61
65
|
previous,
|
|
66
|
+
repeat,
|
|
62
67
|
scale,
|
|
63
68
|
screenHeight,
|
|
64
69
|
selected,
|
|
@@ -76,7 +81,7 @@ export const AnimatedGalleryVideo: React.FC<AnimatedGalleryVideoType> = React.me
|
|
|
76
81
|
|
|
77
82
|
const onLoad = (payload: VideoPayloadData) => {
|
|
78
83
|
setOpacity(0);
|
|
79
|
-
handleLoad(payload);
|
|
84
|
+
handleLoad(attachmentId, payload.duration);
|
|
80
85
|
};
|
|
81
86
|
|
|
82
87
|
const onEnd = () => {
|
|
@@ -84,7 +89,7 @@ export const AnimatedGalleryVideo: React.FC<AnimatedGalleryVideoType> = React.me
|
|
|
84
89
|
};
|
|
85
90
|
|
|
86
91
|
const onProgress = (data: VideoProgressData) => {
|
|
87
|
-
handleProgress(data);
|
|
92
|
+
handleProgress(attachmentId, data.currentTime / data.seekableDuration);
|
|
88
93
|
};
|
|
89
94
|
|
|
90
95
|
const onBuffer = ({ isBuffering }: { isBuffering: boolean }) => {
|
|
@@ -102,13 +107,13 @@ export const AnimatedGalleryVideo: React.FC<AnimatedGalleryVideoType> = React.me
|
|
|
102
107
|
} else {
|
|
103
108
|
// Update your UI for the loaded state
|
|
104
109
|
setOpacity(0);
|
|
105
|
-
handleLoad(
|
|
110
|
+
handleLoad(attachmentId, playbackStatus.durationMillis / 1000);
|
|
106
111
|
if (playbackStatus.isPlaying) {
|
|
107
112
|
// Update your UI for the playing state
|
|
108
|
-
handleProgress(
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
113
|
+
handleProgress(
|
|
114
|
+
attachmentId,
|
|
115
|
+
playbackStatus.positionMillis / 1000 / (playbackStatus.durationMillis / 1000),
|
|
116
|
+
);
|
|
112
117
|
}
|
|
113
118
|
|
|
114
119
|
if (playbackStatus.isBuffering) {
|
|
@@ -189,6 +194,7 @@ export const AnimatedGalleryVideo: React.FC<AnimatedGalleryVideoType> = React.me
|
|
|
189
194
|
onPlaybackStatusUpdate={onPlayBackStatusUpdate}
|
|
190
195
|
onProgress={onProgress}
|
|
191
196
|
paused={paused}
|
|
197
|
+
repeat={repeat}
|
|
192
198
|
resizeMode='contain'
|
|
193
199
|
style={style}
|
|
194
200
|
testID='video-player'
|
|
@@ -219,6 +225,7 @@ export const AnimatedGalleryVideo: React.FC<AnimatedGalleryVideoType> = React.me
|
|
|
219
225
|
(prevProps, nextProps) => {
|
|
220
226
|
if (
|
|
221
227
|
prevProps.paused === nextProps.paused &&
|
|
228
|
+
prevProps.repeat === nextProps.repeat &&
|
|
222
229
|
prevProps.shouldRender === nextProps.shouldRender &&
|
|
223
230
|
prevProps.source.uri === nextProps.source.uri &&
|
|
224
231
|
prevProps.screenHeight === nextProps.screenHeight &&
|
|
@@ -65,7 +65,6 @@ export type ImageGalleryFooterCustomComponent<
|
|
|
65
65
|
export type ImageGalleryFooterVideoControlProps = {
|
|
66
66
|
duration: number;
|
|
67
67
|
onPlayPause: (status?: boolean) => void;
|
|
68
|
-
onProgressDrag: (progress: number) => void;
|
|
69
68
|
paused: boolean;
|
|
70
69
|
progress: number;
|
|
71
70
|
};
|
|
@@ -73,7 +72,6 @@ export type ImageGalleryFooterVideoControlProps = {
|
|
|
73
72
|
export type ImageGalleryFooterVideoControlComponent = ({
|
|
74
73
|
duration,
|
|
75
74
|
onPlayPause,
|
|
76
|
-
onProgressDrag,
|
|
77
75
|
paused,
|
|
78
76
|
progress,
|
|
79
77
|
}: ImageGalleryFooterVideoControlProps) => React.ReactElement | null;
|
|
@@ -95,7 +93,6 @@ type ImageGalleryFooterPropsWithContext<
|
|
|
95
93
|
accessibilityLabel: string;
|
|
96
94
|
duration: number;
|
|
97
95
|
onPlayPause: () => void;
|
|
98
|
-
onProgressDrag: (progress: number) => void;
|
|
99
96
|
opacity: Animated.SharedValue<number>;
|
|
100
97
|
openGridView: () => void;
|
|
101
98
|
paused: boolean;
|
|
@@ -118,7 +115,6 @@ export const ImageGalleryFooterWithContext = <
|
|
|
118
115
|
GridIcon,
|
|
119
116
|
leftElement,
|
|
120
117
|
onPlayPause,
|
|
121
|
-
onProgressDrag,
|
|
122
118
|
opacity,
|
|
123
119
|
openGridView,
|
|
124
120
|
paused,
|
|
@@ -192,12 +188,11 @@ export const ImageGalleryFooterWithContext = <
|
|
|
192
188
|
<ReanimatedSafeAreaView style={[container, footerStyle, { backgroundColor: white }]}>
|
|
193
189
|
{photo.type === 'video' ? (
|
|
194
190
|
videoControlElement ? (
|
|
195
|
-
videoControlElement({ duration, onPlayPause,
|
|
191
|
+
videoControlElement({ duration, onPlayPause, paused, progress })
|
|
196
192
|
) : (
|
|
197
193
|
<ImageGalleryVideoControl
|
|
198
194
|
duration={duration}
|
|
199
195
|
onPlayPause={onPlayPause}
|
|
200
|
-
onProgressDrag={onProgressDrag}
|
|
201
196
|
paused={paused}
|
|
202
197
|
progress={progress}
|
|
203
198
|
/>
|
|
@@ -35,7 +35,7 @@ const styles = StyleSheet.create({
|
|
|
35
35
|
|
|
36
36
|
export const ImageGalleryVideoControl: React.FC<ImageGalleryFooterVideoControlProps> = React.memo(
|
|
37
37
|
(props) => {
|
|
38
|
-
const { duration, onPlayPause,
|
|
38
|
+
const { duration, onPlayPause, paused, progress } = props;
|
|
39
39
|
|
|
40
40
|
const videoDuration = duration
|
|
41
41
|
? duration / 3600 >= 1
|
|
@@ -53,7 +53,7 @@ export const ImageGalleryVideoControl: React.FC<ImageGalleryFooterVideoControlPr
|
|
|
53
53
|
|
|
54
54
|
const {
|
|
55
55
|
theme: {
|
|
56
|
-
colors: { static_black, static_white },
|
|
56
|
+
colors: { accent_blue, black, static_black, static_white },
|
|
57
57
|
imageGallery: {
|
|
58
58
|
videoControl: { durationTextStyle, roundedView, videoContainer },
|
|
59
59
|
},
|
|
@@ -83,22 +83,21 @@ export const ImageGalleryVideoControl: React.FC<ImageGalleryFooterVideoControlPr
|
|
|
83
83
|
</TouchableOpacity>
|
|
84
84
|
<Text
|
|
85
85
|
accessibilityLabel='Progress Duration'
|
|
86
|
-
style={[styles.durationTextStyle, durationTextStyle, { color:
|
|
86
|
+
style={[styles.durationTextStyle, durationTextStyle, { color: black }]}
|
|
87
87
|
>
|
|
88
88
|
{progressDuration ? progressDuration : '00:00'}
|
|
89
89
|
</Text>
|
|
90
90
|
<ProgressControl
|
|
91
91
|
duration={duration}
|
|
92
|
-
filledColor={
|
|
92
|
+
filledColor={accent_blue}
|
|
93
93
|
onPlayPause={onPlayPause}
|
|
94
|
-
onProgressDrag={onProgressDrag}
|
|
95
94
|
progress={progress}
|
|
96
95
|
testID={'progress-control'}
|
|
97
96
|
width={180}
|
|
98
97
|
/>
|
|
99
98
|
<Text
|
|
100
99
|
accessibilityLabel='Video Duration'
|
|
101
|
-
style={[styles.durationTextStyle, durationTextStyle, { color:
|
|
100
|
+
style={[styles.durationTextStyle, durationTextStyle, { color: black }]}
|
|
102
101
|
>
|
|
103
102
|
{videoDuration ? videoDuration : '00:00'}
|
|
104
103
|
</Text>
|
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
useChannelContext,
|
|
31
31
|
} from '../../contexts/channelContext/ChannelContext';
|
|
32
32
|
import { ChatContextValue, useChatContext } from '../../contexts/chatContext/ChatContext';
|
|
33
|
+
import { useDebugContext } from '../../contexts/debugContext/DebugContext';
|
|
33
34
|
import {
|
|
34
35
|
ImageGalleryContextValue,
|
|
35
36
|
useImageGalleryContext,
|
|
@@ -936,6 +937,20 @@ const MessageListWithContext = <
|
|
|
936
937
|
setFlatListRef(ref);
|
|
937
938
|
}
|
|
938
939
|
};
|
|
940
|
+
|
|
941
|
+
const debugRef = useDebugContext();
|
|
942
|
+
|
|
943
|
+
const isDebugModeEnabled = __DEV__ && debugRef && debugRef.current;
|
|
944
|
+
|
|
945
|
+
if (isDebugModeEnabled) {
|
|
946
|
+
if (debugRef.current.setEventType) debugRef.current.setEventType('send');
|
|
947
|
+
if (debugRef.current.setSendEventParams)
|
|
948
|
+
debugRef.current.setSendEventParams({
|
|
949
|
+
action: thread ? 'ThreadList' : 'Messages',
|
|
950
|
+
data: messageList,
|
|
951
|
+
});
|
|
952
|
+
}
|
|
953
|
+
|
|
939
954
|
const renderListEmptyComponent = () => (
|
|
940
955
|
<View style={[styles.flex, styles.invert]} testID='empty-state'>
|
|
941
956
|
<EmptyStateIndicator listType='message' />
|
|
@@ -15,10 +15,10 @@ export type ProgressControlProps = {
|
|
|
15
15
|
duration: number;
|
|
16
16
|
filledColor: string;
|
|
17
17
|
onPlayPause: (status?: boolean) => void;
|
|
18
|
-
onProgressDrag: (progress: number) => void;
|
|
19
18
|
progress: number;
|
|
20
19
|
testID: string;
|
|
21
20
|
width: number;
|
|
21
|
+
onProgressDrag?: (progress: number) => void;
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
const height = 2;
|
|
@@ -94,7 +94,7 @@ export const ProgressControl: React.FC<ProgressControlProps> = React.memo(
|
|
|
94
94
|
onFinish: () => {
|
|
95
95
|
translateX.value = state.value;
|
|
96
96
|
const dragFinishLocationInSeconds = (state.value / width) * duration;
|
|
97
|
-
runOnJS(onProgressDrag)(dragFinishLocationInSeconds);
|
|
97
|
+
if (onProgressDrag) runOnJS(onProgressDrag)(dragFinishLocationInSeconds);
|
|
98
98
|
runOnJS(onPlayPause)(false);
|
|
99
99
|
},
|
|
100
100
|
onStart: () => {
|
|
@@ -109,9 +109,13 @@ export const ProgressControl: React.FC<ProgressControlProps> = React.memo(
|
|
|
109
109
|
<View style={[styles.containerStyle, { backgroundColor: grey_dark, width }]}>
|
|
110
110
|
<Animated.View style={[styles.innerStyle, animatedStyles]} />
|
|
111
111
|
|
|
112
|
-
<PanGestureHandler
|
|
112
|
+
<PanGestureHandler
|
|
113
|
+
maxPointers={1}
|
|
114
|
+
onGestureEvent={onProgressDrag ? onGestureEvent : undefined}
|
|
115
|
+
testID={testID}
|
|
116
|
+
>
|
|
113
117
|
<Animated.View style={[thumbStyles]}>
|
|
114
|
-
<ProgressControlThumb />
|
|
118
|
+
{onProgressDrag && <ProgressControlThumb />}
|
|
115
119
|
</Animated.View>
|
|
116
120
|
</PanGestureHandler>
|
|
117
121
|
</View>
|