Skip to content

Commit f8d0af5

Browse files
committed
fix: attachment picker unread floating indicator issue
1 parent f2bc213 commit f8d0af5

File tree

20 files changed

+77
-82
lines changed

20 files changed

+77
-82
lines changed

examples/SampleApp/ios/Podfile.lock

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,27 +1481,6 @@ PODS:
14811481
- ReactCommon/turbomodule/bridging
14821482
- ReactCommon/turbomodule/core
14831483
- Yoga
1484-
- react-native-image-picker (7.1.2):
1485-
- DoubleConversion
1486-
- glog
1487-
- hermes-engine
1488-
- RCT-Folly (= 2024.01.01.00)
1489-
- RCTRequired
1490-
- RCTTypeSafety
1491-
- React-Core
1492-
- React-debug
1493-
- React-Fabric
1494-
- React-featureflags
1495-
- React-graphics
1496-
- React-ImageManager
1497-
- React-NativeModulesApple
1498-
- React-RCTFabric
1499-
- React-rendererdebug
1500-
- React-utils
1501-
- ReactCodegen
1502-
- ReactCommon/turbomodule/bridging
1503-
- ReactCommon/turbomodule/core
1504-
- Yoga
15051484
- react-native-netinfo (11.3.2):
15061485
- React-Core
15071486
- react-native-safe-area-context (4.14.0):
@@ -2187,7 +2166,7 @@ PODS:
21872166
- libwebp (~> 1.0)
21882167
- SDWebImage/Core (~> 5.10)
21892168
- SocketRocket (0.7.1)
2190-
- stream-chat-react-native (5.43.2):
2169+
- stream-chat-react-native (5.44.1):
21912170
- DoubleConversion
21922171
- glog
21932172
- hermes-engine
@@ -2256,7 +2235,6 @@ DEPENDENCIES:
22562235
- react-native-blob-util (from `../node_modules/react-native-blob-util`)
22572236
- "react-native-cameraroll (from `../node_modules/@react-native-camera-roll/camera-roll`)"
22582237
- react-native-document-picker (from `../node_modules/react-native-document-picker`)
2259-
- react-native-image-picker (from `../node_modules/react-native-image-picker`)
22602238
- "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)"
22612239
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
22622240
- react-native-video (from `../node_modules/react-native-video`)
@@ -2407,8 +2385,6 @@ EXTERNAL SOURCES:
24072385
:path: "../node_modules/@react-native-camera-roll/camera-roll"
24082386
react-native-document-picker:
24092387
:path: "../node_modules/react-native-document-picker"
2410-
react-native-image-picker:
2411-
:path: "../node_modules/react-native-image-picker"
24122388
react-native-netinfo:
24132389
:path: "../node_modules/@react-native-community/netinfo"
24142390
react-native-safe-area-context:
@@ -2557,7 +2533,6 @@ SPEC CHECKSUMS:
25572533
react-native-blob-util: 356047c561b3506396852bc0d7988243f74dd77d
25582534
react-native-cameraroll: 55de4896c31042eedcb0629a58ef5ff0d5a2c428
25592535
react-native-document-picker: 1e082836a633ca9e7c75758036ff42535baaf36b
2560-
react-native-image-picker: df6597d4b1878a443796be11eb2b7286ed10ece6
25612536
react-native-netinfo: 076df4f9b07f6670acf4ce9a75aac8d34c2e2ccc
25622537
react-native-safe-area-context: f826417dadd1c1042c59355fb050682a9839f990
25632538
react-native-video: e5e752b62458690667276df947aee93b394d3e20
@@ -2603,9 +2578,9 @@ SPEC CHECKSUMS:
26032578
SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d
26042579
SDWebImageWebPCoder: 908b83b6adda48effe7667cd2b7f78c897e5111d
26052580
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
2606-
stream-chat-react-native: 54bf193fb71d80dd8dd31b75bbaf6070525c72f2
2581+
stream-chat-react-native: ebdd490d850c18ea013e5e59fc7a0d4195ddfa36
26072582
Yoga: 83048fe4b4ce15018a5e9ccbf0b06bd76fc643d4
26082583

26092584
PODFILE CHECKSUM: 4f662370295f8f9cee909f1a4c59a614999a209d
26102585

2611-
COCOAPODS: 1.16.2
2586+
COCOAPODS: 1.14.3

examples/SampleApp/src/screens/ChannelListScreen.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ export const ChannelListScreen: React.FC = () => {
187187
filters={filters}
188188
HeaderNetworkDownIndicator={() => null}
189189
maxUnreadCount={99}
190-
onSelect={(channel) => {
190+
onSelect={async (channel) => {
191191
navigation.navigate('ChannelScreen', {
192192
channel,
193193
});

package/src/components/Channel/Channel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ const ChannelWithContext = <
517517
CreatePollContent,
518518
DateHeader = DateHeaderDefault,
519519
deletedMessagesVisibilityType = 'always',
520-
disableIfFrozenChannel = true,
520+
disableIfFrozenChannel = false,
521521
disableKeyboardCompatibleView = false,
522522
disableTypingIndicator,
523523
dismissKeyboardOnMessageTouch = true,

package/src/components/Channel/__tests__/useMessageListPagination.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -550,12 +550,12 @@ describe('useMessageListPagination', () => {
550550
`(
551551
'$scenario',
552552
async ({
553-
last_read,
554553
expectedJumpToMessageFinishedCalls,
555554
expectedQueryCalls,
556555
expectedSetChannelUnreadStateCalls,
557556
expectedSetTargetedMessageCalls,
558557
expectedTargetedMessageId,
558+
last_read,
559559
}) => {
560560
// Set up channel state
561561
channel.state = {
@@ -569,8 +569,8 @@ describe('useMessageListPagination', () => {
569569

570570
const channelUnreadState = {
571571
last_read,
572-
user,
573572
unread_messages: 2,
573+
user,
574574
};
575575

576576
// Mock query if needed

package/src/components/MessageList/MessageList.tsx

Lines changed: 40 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,11 @@ const MessageListWithContext = <
407407
return;
408408
}
409409

410+
if (selectedPicker === 'images') {
411+
setIsUnreadNotificationOpen(false);
412+
return;
413+
}
414+
410415
const lastItem = viewableItems[viewableItems.length - 1];
411416

412417
if (lastItem) {
@@ -578,6 +583,41 @@ const MessageListWithContext = <
578583
// eslint-disable-next-line react-hooks/exhaustive-deps
579584
}, [rawMessageList, threadList]);
580585

586+
/**
587+
* Check if a messageId needs to be scrolled to after list loads, and scroll to it
588+
* Note: This effect fires on every list change with a small debounce so that scrolling isnt abrupted by an immediate rerender
589+
*/
590+
useEffect(() => {
591+
scrollToDebounceTimeoutRef.current = setTimeout(async () => {
592+
const messageIdToScroll: string | undefined = targetedMessage;
593+
if (!messageIdToScroll) return;
594+
const indexOfParentInMessageList = processedMessageList.findIndex(
595+
(message) => message?.id === messageIdToScroll,
596+
);
597+
598+
// the message we want to scroll to has not been loaded in the state yet
599+
if (indexOfParentInMessageList === -1) {
600+
await loadChannelAroundMessage({ messageId: messageIdToScroll, setTargetedMessage });
601+
} else {
602+
if (!flatListRef.current) return;
603+
// By a fresh scroll we should clear the retries for the previous failed scroll
604+
clearTimeout(scrollToDebounceTimeoutRef.current);
605+
clearTimeout(failScrollTimeoutId.current);
606+
// reset the retry count
607+
scrollToIndexFailedRetryCountRef.current = 0;
608+
// now scroll to it
609+
flatListRef.current.scrollToIndex({
610+
animated: false,
611+
index: indexOfParentInMessageList,
612+
viewPosition: 0.5, // try to place message in the center of the screen
613+
});
614+
setTargetedMessage(undefined);
615+
}
616+
}, WAIT_FOR_SCROLL_TO_OFFSET_TIMEOUT);
617+
618+
// eslint-disable-next-line react-hooks/exhaustive-deps
619+
}, [targetedMessage]);
620+
581621
// TODO: do not apply on RN 0.73 and above
582622
const shouldApplyAndroidWorkaround = inverted && Platform.OS === 'android';
583623

@@ -883,41 +923,6 @@ const MessageListWithContext = <
883923
await loadChannelAroundMessage({ messageId });
884924
};
885925

886-
/**
887-
* Check if a messageId needs to be scrolled to after list loads, and scroll to it
888-
* Note: This effect fires on every list change with a small debounce so that scrolling isnt abrupted by an immediate rerender
889-
*/
890-
useEffect(() => {
891-
scrollToDebounceTimeoutRef.current = setTimeout(async () => {
892-
const messageIdToScroll: string | undefined = targetedMessage;
893-
if (!messageIdToScroll) return;
894-
const indexOfParentInMessageList = processedMessageList.findIndex(
895-
(message) => message?.id === messageIdToScroll,
896-
);
897-
898-
// the message we want to scroll to has not been loaded in the state yet
899-
if (indexOfParentInMessageList === -1) {
900-
await loadChannelAroundMessage({ messageId: messageIdToScroll, setTargetedMessage });
901-
} else {
902-
if (!flatListRef.current) return;
903-
// By a fresh scroll we should clear the retries for the previous failed scroll
904-
clearTimeout(scrollToDebounceTimeoutRef.current);
905-
clearTimeout(failScrollTimeoutId.current);
906-
// reset the retry count
907-
scrollToIndexFailedRetryCountRef.current = 0;
908-
// now scroll to it
909-
flatListRef.current.scrollToIndex({
910-
animated: false,
911-
index: indexOfParentInMessageList,
912-
viewPosition: 0.5, // try to place message in the center of the screen
913-
});
914-
setTargetedMessage(undefined);
915-
}
916-
}, WAIT_FOR_SCROLL_TO_OFFSET_TIMEOUT);
917-
918-
// eslint-disable-next-line react-hooks/exhaustive-deps
919-
}, [targetedMessage]);
920-
921926
const messagesWithImages =
922927
legacyImageViewerSwipeBehaviour &&
923928
processedMessageList.filter((message) => {

package/src/components/MessageList/UnreadMessagesNotification.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ export const UnreadMessagesNotification = (props: UnreadMessagesNotificationProp
2626
const {
2727
theme: {
2828
colors: { text_low_emphasis, white_snow },
29-
typingIndicator: { container },
29+
messageList: {
30+
unreadMessagesNotification: { container, closeButtonContainer, closeIcon, text },
31+
},
3032
},
3133
} = useTheme();
3234

@@ -41,16 +43,17 @@ export const UnreadMessagesNotification = (props: UnreadMessagesNotificationProp
4143
container,
4244
]}
4345
>
44-
<Text style={[styles.text, { color: white_snow }]}>{t<string>('Unread Messages')}</Text>
46+
<Text style={[styles.text, { color: white_snow }, text]}>{t<string>('Unread Messages')}</Text>
4547
<Pressable
4648
onPress={onCloseHandler}
4749
style={({ pressed }) => [
4850
{
4951
opacity: pressed ? 0.8 : 1,
5052
},
53+
closeButtonContainer,
5154
]}
5255
>
53-
<Close pathFill={white_snow} />
56+
<Close pathFill={white_snow} {...closeIcon} />
5457
</Pressable>
5558
</Pressable>
5659
);

package/src/contexts/themeContext/utils/theme.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,12 @@ export type Theme = {
427427
chevronColor?: ColorValue;
428428
};
429429
typingIndicatorContainer: ViewStyle;
430+
unreadMessagesNotification: {
431+
closeButtonContainer: ViewStyle;
432+
closeIcon: IconProps;
433+
container: ViewStyle;
434+
text: TextStyle;
435+
};
430436
};
431437
messageMenu: {
432438
actionList: {
@@ -1166,6 +1172,12 @@ export const defaultTheme: Theme = {
11661172
wrapper: {},
11671173
},
11681174
typingIndicatorContainer: {},
1175+
unreadMessagesNotification: {
1176+
closeButtonContainer: {},
1177+
closeIcon: {},
1178+
container: {},
1179+
text: {},
1180+
},
11691181
},
11701182
messageMenu: {
11711183
actionList: {

package/src/i18n/en.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
"Loading threads...": "Loading threads...",
5252
"Loading...": "Loading...",
5353
"Mark as Unread": "Mark as Unread",
54-
"Mark as unread action failed either due to a network issue or the message is already marked as unread": "",
5554
"Maximum number of files reached": "Maximum number of files reached",
5655
"Maximum votes per person": "Maximum votes per person",
5756
"Message Reactions": "Message Reactions",

package/src/i18n/es.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
"Loading threads...": "Cargando hilos...",
5252
"Loading...": "Cargando...",
5353
"Mark as Unread": "Marcar como no leído",
54-
"Mark as unread action failed either due to a network issue or the message is already marked as unread": "",
5554
"Maximum number of files reached": "Número máximo de archivos alcanzado",
5655
"Maximum votes per person": "Máximo de votos por persona",
5756
"Message Reactions": "Reacciones al mensaje",

package/src/i18n/fr.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
"Loading threads...": "Chargement des fils...",
5252
"Loading...": "Chargement...",
5353
"Mark as Unread": "Marquer comme non lu",
54-
"Mark as unread action failed either due to a network issue or the message is already marked as unread": "",
5554
"Maximum number of files reached": "Nombre maximal de fichiers atteint",
5655
"Maximum votes per person": "Maximum de votes par personne",
5756
"Message Reactions": "Réactions aux messages",

0 commit comments

Comments
 (0)