stream-chat-react-native-core 5.38.1 → 5.39.0-beta.1
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/Channel/Channel.js +58 -25
- package/lib/commonjs/components/Channel/Channel.js.map +1 -1
- package/lib/commonjs/components/Channel/hooks/useCreateThreadContext.js +33 -21
- package/lib/commonjs/components/Channel/hooks/useCreateThreadContext.js.map +1 -1
- package/lib/commonjs/components/Chat/Chat.js +7 -0
- package/lib/commonjs/components/Chat/Chat.js.map +1 -1
- package/lib/commonjs/components/Indicators/EmptyStateIndicator.js +14 -0
- package/lib/commonjs/components/Indicators/EmptyStateIndicator.js.map +1 -1
- package/lib/commonjs/components/Indicators/LoadingIndicator.js +4 -0
- package/lib/commonjs/components/Indicators/LoadingIndicator.js.map +1 -1
- package/lib/commonjs/components/Message/hooks/useProcessReactions.js +13 -7
- package/lib/commonjs/components/Message/hooks/useProcessReactions.js.map +1 -1
- package/lib/commonjs/components/MessageList/InlineLoadingMoreRecentThreadIndicator.js +52 -0
- package/lib/commonjs/components/MessageList/InlineLoadingMoreRecentThreadIndicator.js.map +1 -0
- package/lib/commonjs/components/MessageList/MessageList.js +14 -6
- package/lib/commonjs/components/MessageList/MessageList.js.map +1 -1
- package/lib/commonjs/components/Thread/Thread.js +12 -5
- package/lib/commonjs/components/Thread/Thread.js.map +1 -1
- package/lib/commonjs/components/Thread/components/ThreadFooterComponent.js +41 -18
- package/lib/commonjs/components/Thread/components/ThreadFooterComponent.js.map +1 -1
- package/lib/commonjs/components/ThreadList/ThreadList.js +132 -0
- package/lib/commonjs/components/ThreadList/ThreadList.js.map +1 -0
- package/lib/commonjs/components/ThreadList/ThreadListItem.js +246 -0
- package/lib/commonjs/components/ThreadList/ThreadListItem.js.map +1 -0
- package/lib/commonjs/components/ThreadList/ThreadListUnreadBanner.js +66 -0
- package/lib/commonjs/components/ThreadList/ThreadListUnreadBanner.js.map +1 -0
- package/lib/commonjs/components/index.js +11 -11
- package/lib/commonjs/components/index.js.map +1 -1
- package/lib/commonjs/contexts/themeContext/utils/theme.js +19 -0
- package/lib/commonjs/contexts/themeContext/utils/theme.js.map +1 -1
- package/lib/commonjs/contexts/threadContext/ThreadContext.js.map +1 -1
- package/lib/commonjs/contexts/threadsContext/ThreadListItemContext.js +28 -0
- package/lib/commonjs/contexts/threadsContext/ThreadListItemContext.js.map +1 -0
- package/lib/commonjs/contexts/threadsContext/ThreadsContext.js +33 -0
- package/lib/commonjs/contexts/threadsContext/ThreadsContext.js.map +1 -0
- package/lib/commonjs/hooks/index.js +11 -0
- package/lib/commonjs/hooks/index.js.map +1 -1
- package/lib/commonjs/hooks/useStateStore.js +23 -0
- package/lib/commonjs/hooks/useStateStore.js.map +1 -0
- package/lib/commonjs/i18n/en.json +7 -0
- package/lib/commonjs/i18n/es.json +7 -0
- package/lib/commonjs/i18n/fr.json +7 -0
- package/lib/commonjs/i18n/he.json +7 -0
- package/lib/commonjs/i18n/hi.json +7 -0
- package/lib/commonjs/i18n/it.json +7 -0
- package/lib/commonjs/i18n/ja.json +7 -0
- package/lib/commonjs/i18n/ko.json +7 -0
- package/lib/commonjs/i18n/nl.json +7 -0
- package/lib/commonjs/i18n/pt-br.json +7 -0
- package/lib/commonjs/i18n/ru.json +7 -0
- package/lib/commonjs/i18n/tr.json +7 -0
- package/lib/commonjs/icons/MessageBubble.js +19 -0
- package/lib/commonjs/icons/MessageBubble.js.map +1 -0
- package/lib/commonjs/icons/MessageBubbleEmpty.js +19 -0
- package/lib/commonjs/icons/MessageBubbleEmpty.js.map +1 -0
- package/lib/commonjs/icons/Reload.js +19 -0
- package/lib/commonjs/icons/Reload.js.map +1 -0
- package/lib/commonjs/icons/index.js +33 -0
- package/lib/commonjs/icons/index.js.map +1 -1
- package/lib/commonjs/store/mappers/mapDateTimeToStorable.js.map +1 -1
- package/lib/commonjs/version.json +1 -1
- package/lib/module/components/Channel/Channel.js +58 -25
- package/lib/module/components/Channel/Channel.js.map +1 -1
- package/lib/module/components/Channel/hooks/useCreateThreadContext.js +33 -21
- package/lib/module/components/Channel/hooks/useCreateThreadContext.js.map +1 -1
- package/lib/module/components/Chat/Chat.js +7 -0
- package/lib/module/components/Chat/Chat.js.map +1 -1
- package/lib/module/components/Indicators/EmptyStateIndicator.js +14 -0
- package/lib/module/components/Indicators/EmptyStateIndicator.js.map +1 -1
- package/lib/module/components/Indicators/LoadingIndicator.js +4 -0
- package/lib/module/components/Indicators/LoadingIndicator.js.map +1 -1
- package/lib/module/components/Message/hooks/useProcessReactions.js +13 -7
- package/lib/module/components/Message/hooks/useProcessReactions.js.map +1 -1
- package/lib/module/components/MessageList/InlineLoadingMoreRecentThreadIndicator.js +52 -0
- package/lib/module/components/MessageList/InlineLoadingMoreRecentThreadIndicator.js.map +1 -0
- package/lib/module/components/MessageList/MessageList.js +14 -6
- package/lib/module/components/MessageList/MessageList.js.map +1 -1
- package/lib/module/components/Thread/Thread.js +12 -5
- package/lib/module/components/Thread/Thread.js.map +1 -1
- package/lib/module/components/Thread/components/ThreadFooterComponent.js +41 -18
- package/lib/module/components/Thread/components/ThreadFooterComponent.js.map +1 -1
- package/lib/module/components/ThreadList/ThreadList.js +132 -0
- package/lib/module/components/ThreadList/ThreadList.js.map +1 -0
- package/lib/module/components/ThreadList/ThreadListItem.js +246 -0
- package/lib/module/components/ThreadList/ThreadListItem.js.map +1 -0
- package/lib/module/components/ThreadList/ThreadListUnreadBanner.js +66 -0
- package/lib/module/components/ThreadList/ThreadListUnreadBanner.js.map +1 -0
- package/lib/module/components/index.js +11 -11
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/contexts/themeContext/utils/theme.js +19 -0
- package/lib/module/contexts/themeContext/utils/theme.js.map +1 -1
- package/lib/module/contexts/threadContext/ThreadContext.js.map +1 -1
- package/lib/module/contexts/threadsContext/ThreadListItemContext.js +28 -0
- package/lib/module/contexts/threadsContext/ThreadListItemContext.js.map +1 -0
- package/lib/module/contexts/threadsContext/ThreadsContext.js +33 -0
- package/lib/module/contexts/threadsContext/ThreadsContext.js.map +1 -0
- package/lib/module/hooks/index.js +11 -0
- package/lib/module/hooks/index.js.map +1 -1
- package/lib/module/hooks/useStateStore.js +23 -0
- package/lib/module/hooks/useStateStore.js.map +1 -0
- package/lib/module/i18n/en.json +7 -0
- package/lib/module/i18n/es.json +7 -0
- package/lib/module/i18n/fr.json +7 -0
- package/lib/module/i18n/he.json +7 -0
- package/lib/module/i18n/hi.json +7 -0
- package/lib/module/i18n/it.json +7 -0
- package/lib/module/i18n/ja.json +7 -0
- package/lib/module/i18n/ko.json +7 -0
- package/lib/module/i18n/nl.json +7 -0
- package/lib/module/i18n/pt-br.json +7 -0
- package/lib/module/i18n/ru.json +7 -0
- package/lib/module/i18n/tr.json +7 -0
- package/lib/module/icons/MessageBubble.js +19 -0
- package/lib/module/icons/MessageBubble.js.map +1 -0
- package/lib/module/icons/MessageBubbleEmpty.js +19 -0
- package/lib/module/icons/MessageBubbleEmpty.js.map +1 -0
- package/lib/module/icons/Reload.js +19 -0
- package/lib/module/icons/Reload.js.map +1 -0
- package/lib/module/icons/index.js +33 -0
- package/lib/module/icons/index.js.map +1 -1
- package/lib/module/store/mappers/mapDateTimeToStorable.js.map +1 -1
- package/lib/module/version.json +1 -1
- package/lib/typescript/components/AttachmentPicker/AttachmentPicker.d.ts +1 -1
- package/lib/typescript/components/Channel/Channel.d.ts +3 -2
- package/lib/typescript/components/Channel/Channel.d.ts.map +1 -1
- package/lib/typescript/components/Channel/hooks/useCreateThreadContext.d.ts +34 -1
- package/lib/typescript/components/Channel/hooks/useCreateThreadContext.d.ts.map +1 -1
- package/lib/typescript/components/Chat/Chat.d.ts.map +1 -1
- package/lib/typescript/components/Indicators/EmptyStateIndicator.d.ts +1 -1
- package/lib/typescript/components/Indicators/EmptyStateIndicator.d.ts.map +1 -1
- package/lib/typescript/components/Indicators/LoadingIndicator.d.ts +1 -1
- package/lib/typescript/components/Indicators/LoadingIndicator.d.ts.map +1 -1
- package/lib/typescript/components/Message/hooks/useProcessReactions.d.ts.map +1 -1
- package/lib/typescript/components/MessageList/InlineLoadingMoreRecentThreadIndicator.d.ts +8 -0
- package/lib/typescript/components/MessageList/InlineLoadingMoreRecentThreadIndicator.d.ts.map +1 -0
- package/lib/typescript/components/MessageList/MessageList.d.ts +1 -1
- package/lib/typescript/components/MessageList/MessageList.d.ts.map +1 -1
- package/lib/typescript/components/Thread/Thread.d.ts +1 -1
- package/lib/typescript/components/Thread/Thread.d.ts.map +1 -1
- package/lib/typescript/components/Thread/components/ThreadFooterComponent.d.ts +1 -0
- package/lib/typescript/components/Thread/components/ThreadFooterComponent.d.ts.map +1 -1
- package/lib/typescript/components/ThreadList/ThreadList.d.ts +11 -0
- package/lib/typescript/components/ThreadList/ThreadList.d.ts.map +1 -0
- package/lib/typescript/components/ThreadList/ThreadListItem.d.ts +16 -0
- package/lib/typescript/components/ThreadList/ThreadListItem.d.ts.map +1 -0
- package/lib/typescript/components/ThreadList/ThreadListUnreadBanner.d.ts +3 -0
- package/lib/typescript/components/ThreadList/ThreadListUnreadBanner.d.ts.map +1 -0
- package/lib/typescript/components/index.d.ts +1 -1
- package/lib/typescript/components/index.d.ts.map +1 -1
- package/lib/typescript/contexts/attachmentPickerContext/AttachmentPickerContext.d.ts +1 -1
- package/lib/typescript/contexts/messageContext/MessageContext.d.ts +1 -1
- package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts +1 -1
- package/lib/typescript/contexts/themeContext/utils/theme.d.ts +19 -0
- package/lib/typescript/contexts/themeContext/utils/theme.d.ts.map +1 -1
- package/lib/typescript/contexts/threadContext/ThreadContext.d.ts +11 -2
- package/lib/typescript/contexts/threadContext/ThreadContext.d.ts.map +1 -1
- package/lib/typescript/contexts/threadsContext/ThreadListItemContext.d.ts +19 -0
- package/lib/typescript/contexts/threadsContext/ThreadListItemContext.d.ts.map +1 -0
- package/lib/typescript/contexts/threadsContext/ThreadsContext.d.ts +25 -0
- package/lib/typescript/contexts/threadsContext/ThreadsContext.d.ts.map +1 -0
- package/lib/typescript/hooks/index.d.ts +1 -0
- package/lib/typescript/hooks/index.d.ts.map +1 -1
- package/lib/typescript/hooks/useStateStore.d.ts +4 -0
- package/lib/typescript/hooks/useStateStore.d.ts.map +1 -0
- package/lib/typescript/i18n/en.json +7 -0
- package/lib/typescript/i18n/es.json +7 -0
- package/lib/typescript/i18n/fr.json +7 -0
- package/lib/typescript/i18n/he.json +7 -0
- package/lib/typescript/i18n/hi.json +7 -0
- package/lib/typescript/i18n/it.json +7 -0
- package/lib/typescript/i18n/ja.json +7 -0
- package/lib/typescript/i18n/ko.json +7 -0
- package/lib/typescript/i18n/nl.json +7 -0
- package/lib/typescript/i18n/pt-br.json +7 -0
- package/lib/typescript/i18n/ru.json +7 -0
- package/lib/typescript/i18n/tr.json +7 -0
- package/lib/typescript/icons/MessageBubble.d.ts +4 -0
- package/lib/typescript/icons/MessageBubble.d.ts.map +1 -0
- package/lib/typescript/icons/MessageBubbleEmpty.d.ts +4 -0
- package/lib/typescript/icons/MessageBubbleEmpty.d.ts.map +1 -0
- package/lib/typescript/icons/Reload.d.ts +4 -0
- package/lib/typescript/icons/Reload.d.ts.map +1 -0
- package/lib/typescript/icons/index.d.ts +3 -0
- package/lib/typescript/icons/index.d.ts.map +1 -1
- package/lib/typescript/store/mappers/mapDateTimeToStorable.d.ts +1 -1
- package/lib/typescript/store/mappers/mapDateTimeToStorable.d.ts.map +1 -1
- package/lib/typescript/utils/i18n/Streami18n.d.ts +7 -0
- package/lib/typescript/utils/i18n/Streami18n.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/components/Channel/Channel.tsx +54 -20
- package/src/components/Channel/hooks/useCreateThreadContext.ts +36 -31
- package/src/components/Chat/Chat.tsx +10 -0
- package/src/components/Indicators/EmptyStateIndicator.tsx +9 -2
- package/src/components/Indicators/LoadingIndicator.tsx +3 -1
- package/src/components/Message/hooks/useProcessReactions.ts +25 -4
- package/src/components/MessageList/InlineLoadingMoreRecentThreadIndicator.tsx +64 -0
- package/src/components/MessageList/MessageList.tsx +23 -9
- package/src/components/Thread/Thread.tsx +18 -9
- package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap +6 -0
- package/src/components/Thread/components/ThreadFooterComponent.tsx +28 -2
- package/src/components/ThreadList/ThreadList.tsx +118 -0
- package/src/components/ThreadList/ThreadListItem.tsx +268 -0
- package/src/components/ThreadList/ThreadListUnreadBanner.tsx +52 -0
- package/src/components/index.ts +1 -1
- package/src/contexts/themeContext/utils/theme.ts +36 -0
- package/src/contexts/threadContext/ThreadContext.tsx +9 -2
- package/src/contexts/threadsContext/ThreadListItemContext.tsx +41 -0
- package/src/contexts/threadsContext/ThreadsContext.tsx +62 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useStateStore.ts +31 -0
- package/src/i18n/en.json +7 -0
- package/src/i18n/es.json +7 -0
- package/src/i18n/fr.json +7 -0
- package/src/i18n/he.json +7 -0
- package/src/i18n/hi.json +7 -0
- package/src/i18n/it.json +7 -0
- package/src/i18n/ja.json +7 -0
- package/src/i18n/ko.json +7 -0
- package/src/i18n/nl.json +7 -0
- package/src/i18n/pt-br.json +7 -0
- package/src/i18n/ru.json +7 -0
- package/src/i18n/tr.json +7 -0
- package/src/icons/MessageBubble.tsx +12 -0
- package/src/icons/MessageBubbleEmpty.tsx +12 -0
- package/src/icons/Reload.tsx +12 -0
- package/src/icons/index.ts +3 -0
- package/src/store/mappers/mapDateTimeToStorable.ts +1 -1
- package/src/version.json +1 -1
- package/lib/commonjs/components/MessageList/InlineLoadingMoreThreadIndicator.js +0 -52
- package/lib/commonjs/components/MessageList/InlineLoadingMoreThreadIndicator.js.map +0 -1
- package/lib/module/components/MessageList/InlineLoadingMoreThreadIndicator.js +0 -52
- package/lib/module/components/MessageList/InlineLoadingMoreThreadIndicator.js.map +0 -1
- package/lib/typescript/components/MessageList/InlineLoadingMoreThreadIndicator.d.ts +0 -8
- package/lib/typescript/components/MessageList/InlineLoadingMoreThreadIndicator.d.ts.map +0 -1
- package/src/components/MessageList/InlineLoadingMoreThreadIndicator.tsx +0 -64
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import React, { useCallback, useMemo } from 'react';
|
|
2
|
+
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import { Thread, ThreadState } from 'stream-chat';
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
TranslationContextValue,
|
|
8
|
+
useChatContext,
|
|
9
|
+
useTheme,
|
|
10
|
+
useTranslationContext,
|
|
11
|
+
} from '../../contexts';
|
|
12
|
+
import {
|
|
13
|
+
ThreadListItemProvider,
|
|
14
|
+
useThreadListItemContext,
|
|
15
|
+
} from '../../contexts/threadsContext/ThreadListItemContext';
|
|
16
|
+
import { useThreadsContext } from '../../contexts/threadsContext/ThreadsContext';
|
|
17
|
+
import { useStateStore } from '../../hooks';
|
|
18
|
+
import { MessageBubble } from '../../icons';
|
|
19
|
+
import { getDateString } from '../../utils/i18n/getDateString';
|
|
20
|
+
import { Avatar } from '../Avatar/Avatar';
|
|
21
|
+
import { useChannelPreviewDisplayName } from '../ChannelPreview/hooks/useChannelPreviewDisplayName';
|
|
22
|
+
import { MessageType } from '../MessageList/hooks/useMessageList';
|
|
23
|
+
|
|
24
|
+
export type ThreadListItemProps = {
|
|
25
|
+
thread: Thread;
|
|
26
|
+
timestampTranslationKey?: string;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const styles = StyleSheet.create({
|
|
30
|
+
boldText: { fontSize: 14, fontWeight: '500' },
|
|
31
|
+
contentRow: {
|
|
32
|
+
flexDirection: 'row',
|
|
33
|
+
marginTop: 6,
|
|
34
|
+
},
|
|
35
|
+
contentTextWrapper: {
|
|
36
|
+
flex: 1,
|
|
37
|
+
marginLeft: 8,
|
|
38
|
+
},
|
|
39
|
+
dateText: { alignSelf: 'flex-end' },
|
|
40
|
+
headerRow: {
|
|
41
|
+
flexDirection: 'row',
|
|
42
|
+
},
|
|
43
|
+
infoRow: {
|
|
44
|
+
alignItems: 'center',
|
|
45
|
+
flexDirection: 'row',
|
|
46
|
+
},
|
|
47
|
+
lastReplyText: { flex: 1, fontSize: 14, marginTop: 4 },
|
|
48
|
+
parentMessageText: { flex: 1, fontSize: 12 },
|
|
49
|
+
touchableWrapper: {
|
|
50
|
+
flex: 1,
|
|
51
|
+
paddingHorizontal: 8,
|
|
52
|
+
paddingVertical: 14,
|
|
53
|
+
},
|
|
54
|
+
unreadBubbleWrapper: {
|
|
55
|
+
alignItems: 'center',
|
|
56
|
+
alignSelf: 'flex-end',
|
|
57
|
+
borderRadius: 50,
|
|
58
|
+
height: 22,
|
|
59
|
+
justifyContent: 'center',
|
|
60
|
+
width: 22,
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
export const attachmentTypeIconMap = {
|
|
65
|
+
audio: '🔈',
|
|
66
|
+
file: '📄',
|
|
67
|
+
image: '📷',
|
|
68
|
+
video: '🎥',
|
|
69
|
+
voiceRecording: '🎙️',
|
|
70
|
+
} as const;
|
|
71
|
+
|
|
72
|
+
const getTitleFromMessage = ({
|
|
73
|
+
currentUserId,
|
|
74
|
+
message,
|
|
75
|
+
t,
|
|
76
|
+
}: {
|
|
77
|
+
t: TranslationContextValue['t'];
|
|
78
|
+
currentUserId?: string;
|
|
79
|
+
message?: MessageType | undefined;
|
|
80
|
+
}) => {
|
|
81
|
+
const attachment = message?.attachments?.at(0);
|
|
82
|
+
|
|
83
|
+
const attachmentIcon = attachment
|
|
84
|
+
? `${
|
|
85
|
+
attachmentTypeIconMap[(attachment.type as keyof typeof attachmentTypeIconMap) ?? 'file'] ??
|
|
86
|
+
attachmentTypeIconMap.file
|
|
87
|
+
} `
|
|
88
|
+
: '';
|
|
89
|
+
|
|
90
|
+
const messageBelongsToCurrentUserPrefix =
|
|
91
|
+
message?.user?.id === currentUserId ? `${t('You')}: ` : '';
|
|
92
|
+
|
|
93
|
+
if (message?.deleted_at && message.parent_id)
|
|
94
|
+
return `${messageBelongsToCurrentUserPrefix}${t('This reply was deleted')}.`;
|
|
95
|
+
|
|
96
|
+
if (message?.deleted_at && !message.parent_id)
|
|
97
|
+
return `${messageBelongsToCurrentUserPrefix}${t('The source message was deleted')}.`;
|
|
98
|
+
|
|
99
|
+
if (attachment?.type === 'voiceRecording')
|
|
100
|
+
return `${attachmentIcon}${messageBelongsToCurrentUserPrefix}${t('Voice message')}.`;
|
|
101
|
+
|
|
102
|
+
return `${attachmentIcon}${messageBelongsToCurrentUserPrefix}${
|
|
103
|
+
message?.text || attachment?.fallback || 'N/A'
|
|
104
|
+
}`;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export const ThreadListItemComponent = () => {
|
|
108
|
+
const {
|
|
109
|
+
channel,
|
|
110
|
+
dateString,
|
|
111
|
+
deletedAtDateString,
|
|
112
|
+
lastReply,
|
|
113
|
+
ownUnreadMessageCount,
|
|
114
|
+
parentMessage,
|
|
115
|
+
thread,
|
|
116
|
+
} = useThreadListItemContext();
|
|
117
|
+
const displayName = useChannelPreviewDisplayName(channel);
|
|
118
|
+
const { onThreadSelect } = useThreadsContext();
|
|
119
|
+
const { client } = useChatContext();
|
|
120
|
+
const { t } = useTranslationContext();
|
|
121
|
+
const {
|
|
122
|
+
theme: {
|
|
123
|
+
colors: { accent_red, text_low_emphasis, white },
|
|
124
|
+
threadListItem,
|
|
125
|
+
},
|
|
126
|
+
} = useTheme();
|
|
127
|
+
|
|
128
|
+
return (
|
|
129
|
+
<TouchableOpacity
|
|
130
|
+
onPress={() => {
|
|
131
|
+
if (onThreadSelect) {
|
|
132
|
+
onThreadSelect({ thread: parentMessage as MessageType, threadInstance: thread }, channel);
|
|
133
|
+
}
|
|
134
|
+
}}
|
|
135
|
+
style={[styles.touchableWrapper, threadListItem.touchableWrapper]}
|
|
136
|
+
testID='thread-list-item'
|
|
137
|
+
>
|
|
138
|
+
<View style={[styles.headerRow, threadListItem.headerRow]}>
|
|
139
|
+
<MessageBubble />
|
|
140
|
+
<Text style={[styles.boldText, { color: text_low_emphasis }, threadListItem.boldText]}>
|
|
141
|
+
{displayName || 'N/A'}
|
|
142
|
+
</Text>
|
|
143
|
+
</View>
|
|
144
|
+
<View style={[styles.infoRow, threadListItem.infoRow]}>
|
|
145
|
+
<Text
|
|
146
|
+
numberOfLines={1}
|
|
147
|
+
style={[
|
|
148
|
+
styles.parentMessageText,
|
|
149
|
+
{ color: text_low_emphasis },
|
|
150
|
+
threadListItem.parentMessageText,
|
|
151
|
+
]}
|
|
152
|
+
>
|
|
153
|
+
{t<string>('replied to')}: {getTitleFromMessage({ message: parentMessage, t })}
|
|
154
|
+
</Text>
|
|
155
|
+
{ownUnreadMessageCount > 0 && !deletedAtDateString ? (
|
|
156
|
+
<View
|
|
157
|
+
style={[
|
|
158
|
+
styles.unreadBubbleWrapper,
|
|
159
|
+
{ backgroundColor: accent_red },
|
|
160
|
+
threadListItem.unreadBubbleWrapper,
|
|
161
|
+
]}
|
|
162
|
+
>
|
|
163
|
+
<Text style={[{ color: white }, threadListItem.unreadBubbleText]}>
|
|
164
|
+
{ownUnreadMessageCount}
|
|
165
|
+
</Text>
|
|
166
|
+
</View>
|
|
167
|
+
) : null}
|
|
168
|
+
</View>
|
|
169
|
+
<View style={[styles.contentRow, threadListItem.contentRow]}>
|
|
170
|
+
<Avatar
|
|
171
|
+
image={lastReply?.user?.image as string}
|
|
172
|
+
online={lastReply?.user?.online}
|
|
173
|
+
size={40}
|
|
174
|
+
/>
|
|
175
|
+
<View style={[styles.contentTextWrapper, threadListItem.contentTextWrapper]}>
|
|
176
|
+
<Text style={[styles.boldText, { color: text_low_emphasis }, threadListItem.boldText]}>
|
|
177
|
+
{lastReply?.user?.name}
|
|
178
|
+
</Text>
|
|
179
|
+
<View style={[styles.headerRow, threadListItem.headerRow]}>
|
|
180
|
+
<Text
|
|
181
|
+
numberOfLines={1}
|
|
182
|
+
style={[
|
|
183
|
+
styles.lastReplyText,
|
|
184
|
+
{ color: text_low_emphasis },
|
|
185
|
+
threadListItem.lastReplyText,
|
|
186
|
+
]}
|
|
187
|
+
>
|
|
188
|
+
{deletedAtDateString
|
|
189
|
+
? 'This thread was deleted.'
|
|
190
|
+
: getTitleFromMessage({
|
|
191
|
+
currentUserId: client.userID,
|
|
192
|
+
message: lastReply,
|
|
193
|
+
t,
|
|
194
|
+
})}
|
|
195
|
+
</Text>
|
|
196
|
+
<Text style={[styles.dateText, { color: text_low_emphasis }, threadListItem.dateText]}>
|
|
197
|
+
{deletedAtDateString ?? dateString}
|
|
198
|
+
</Text>
|
|
199
|
+
</View>
|
|
200
|
+
</View>
|
|
201
|
+
</View>
|
|
202
|
+
</TouchableOpacity>
|
|
203
|
+
);
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
export const ThreadListItem = (props: ThreadListItemProps) => {
|
|
207
|
+
const { client } = useChatContext();
|
|
208
|
+
const { t, tDateTimeParser } = useTranslationContext();
|
|
209
|
+
const { thread, timestampTranslationKey = 'timestamp/ThreadListItem' } = props;
|
|
210
|
+
const { ThreadListItem = ThreadListItemComponent } = useThreadsContext();
|
|
211
|
+
|
|
212
|
+
const selector = useCallback(
|
|
213
|
+
(nextValue: ThreadState) =>
|
|
214
|
+
[
|
|
215
|
+
nextValue.replies.at(-1),
|
|
216
|
+
(client.userID && nextValue.read[client.userID]?.unreadMessageCount) || 0,
|
|
217
|
+
nextValue.parentMessage,
|
|
218
|
+
nextValue.channel,
|
|
219
|
+
nextValue.deletedAt,
|
|
220
|
+
] as const,
|
|
221
|
+
[client],
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
const [lastReply, ownUnreadMessageCount, parentMessage, channel, deletedAt] = useStateStore(
|
|
225
|
+
thread.state,
|
|
226
|
+
selector,
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
const timestamp = lastReply?.created_at;
|
|
230
|
+
|
|
231
|
+
// TODO: Please rethink this, we have the same line of code in about 5 places in the SDK.
|
|
232
|
+
const dateString = useMemo(
|
|
233
|
+
() =>
|
|
234
|
+
getDateString({
|
|
235
|
+
date: timestamp,
|
|
236
|
+
t,
|
|
237
|
+
tDateTimeParser,
|
|
238
|
+
timestampTranslationKey,
|
|
239
|
+
}),
|
|
240
|
+
[timestamp, t, tDateTimeParser, timestampTranslationKey],
|
|
241
|
+
);
|
|
242
|
+
const deletedAtDateString = useMemo(
|
|
243
|
+
() =>
|
|
244
|
+
getDateString({
|
|
245
|
+
date: deletedAt as Date | undefined,
|
|
246
|
+
t,
|
|
247
|
+
tDateTimeParser,
|
|
248
|
+
timestampTranslationKey,
|
|
249
|
+
}),
|
|
250
|
+
[deletedAt, t, tDateTimeParser, timestampTranslationKey],
|
|
251
|
+
);
|
|
252
|
+
|
|
253
|
+
return (
|
|
254
|
+
<ThreadListItemProvider
|
|
255
|
+
value={{
|
|
256
|
+
channel,
|
|
257
|
+
dateString,
|
|
258
|
+
deletedAtDateString,
|
|
259
|
+
lastReply,
|
|
260
|
+
ownUnreadMessageCount,
|
|
261
|
+
parentMessage,
|
|
262
|
+
thread,
|
|
263
|
+
}}
|
|
264
|
+
>
|
|
265
|
+
<ThreadListItem />
|
|
266
|
+
</ThreadListItemProvider>
|
|
267
|
+
);
|
|
268
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { StyleSheet, Text, TouchableOpacity } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import { ThreadManagerState } from 'stream-chat';
|
|
5
|
+
|
|
6
|
+
import { useChatContext, useTheme } from '../../contexts';
|
|
7
|
+
import { useStateStore } from '../../hooks';
|
|
8
|
+
import { Reload } from '../../icons';
|
|
9
|
+
|
|
10
|
+
const styles = StyleSheet.create({
|
|
11
|
+
text: { alignSelf: 'flex-start', flex: 1, fontSize: 16 },
|
|
12
|
+
touchableWrapper: {
|
|
13
|
+
borderRadius: 16,
|
|
14
|
+
flexDirection: 'row',
|
|
15
|
+
marginHorizontal: 8,
|
|
16
|
+
marginVertical: 6,
|
|
17
|
+
paddingHorizontal: 16,
|
|
18
|
+
paddingVertical: 14,
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const selector = (nextValue: ThreadManagerState) => [nextValue.unseenThreadIds] as const;
|
|
23
|
+
|
|
24
|
+
export const ThreadListUnreadBanner = () => {
|
|
25
|
+
const { client } = useChatContext();
|
|
26
|
+
const {
|
|
27
|
+
theme: {
|
|
28
|
+
colors: { text_high_emphasis, white },
|
|
29
|
+
threadListUnreadBanner,
|
|
30
|
+
},
|
|
31
|
+
} = useTheme();
|
|
32
|
+
const [unseenThreadIds] = useStateStore(client.threads.state, selector);
|
|
33
|
+
if (!unseenThreadIds.length) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<TouchableOpacity
|
|
39
|
+
onPress={() => client.threads.reload()}
|
|
40
|
+
style={[
|
|
41
|
+
styles.touchableWrapper,
|
|
42
|
+
{ backgroundColor: text_high_emphasis },
|
|
43
|
+
threadListUnreadBanner.touchableWrapper,
|
|
44
|
+
]}
|
|
45
|
+
>
|
|
46
|
+
<Text style={[styles.text, { color: white }, threadListUnreadBanner.text]}>
|
|
47
|
+
{unseenThreadIds.length} unread threads
|
|
48
|
+
</Text>
|
|
49
|
+
<Reload pathFill={white} />
|
|
50
|
+
</TouchableOpacity>
|
|
51
|
+
);
|
|
52
|
+
};
|
package/src/components/index.ts
CHANGED
|
@@ -139,7 +139,6 @@ export * from './MessageList/hooks/useTypingString';
|
|
|
139
139
|
export * from './MessageList/InlineDateSeparator';
|
|
140
140
|
export * from './MessageList/InlineLoadingMoreIndicator';
|
|
141
141
|
export * from './MessageList/InlineLoadingMoreRecentIndicator';
|
|
142
|
-
export * from './MessageList/InlineLoadingMoreThreadIndicator';
|
|
143
142
|
export * from './MessageList/InlineUnreadIndicator';
|
|
144
143
|
export * from './MessageList/MessageList';
|
|
145
144
|
export * from './MessageList/MessageSystem';
|
|
@@ -169,3 +168,4 @@ export * from './Spinner/Spinner';
|
|
|
169
168
|
|
|
170
169
|
export * from './Thread/Thread';
|
|
171
170
|
export * from './Thread/components/ThreadFooterComponent';
|
|
171
|
+
export * from './ThreadList/ThreadList';
|
|
@@ -27,6 +27,8 @@ export const Colors = {
|
|
|
27
27
|
static_black: '#000000',
|
|
28
28
|
static_white: '#ffffff',
|
|
29
29
|
targetedMessageBackground: '#FBF4DD', // dark mode = #302D22
|
|
30
|
+
text_high_emphasis: '#080707',
|
|
31
|
+
text_low_emphasis: '#7E828B',
|
|
30
32
|
transparent: 'transparent',
|
|
31
33
|
white: '#FFFFFF',
|
|
32
34
|
white_smoke: '#F2F2F2',
|
|
@@ -637,6 +639,23 @@ export type Theme = {
|
|
|
637
639
|
threadHeight?: number;
|
|
638
640
|
};
|
|
639
641
|
};
|
|
642
|
+
threadListItem: {
|
|
643
|
+
boldText: TextStyle;
|
|
644
|
+
contentRow: ViewStyle;
|
|
645
|
+
contentTextWrapper: ViewStyle;
|
|
646
|
+
dateText: TextStyle;
|
|
647
|
+
headerRow: ViewStyle;
|
|
648
|
+
infoRow: ViewStyle;
|
|
649
|
+
lastReplyText: TextStyle;
|
|
650
|
+
parentMessageText: TextStyle;
|
|
651
|
+
touchableWrapper: ViewStyle;
|
|
652
|
+
unreadBubbleText: TextStyle;
|
|
653
|
+
unreadBubbleWrapper: ViewStyle;
|
|
654
|
+
};
|
|
655
|
+
threadListUnreadBanner: {
|
|
656
|
+
text: TextStyle;
|
|
657
|
+
touchableWrapper: ViewStyle;
|
|
658
|
+
};
|
|
640
659
|
typingIndicator: {
|
|
641
660
|
container: ViewStyle;
|
|
642
661
|
text: TextStyle & {
|
|
@@ -1241,6 +1260,23 @@ export const defaultTheme: Theme = {
|
|
|
1241
1260
|
text: {},
|
|
1242
1261
|
},
|
|
1243
1262
|
},
|
|
1263
|
+
threadListItem: {
|
|
1264
|
+
boldText: {},
|
|
1265
|
+
contentRow: {},
|
|
1266
|
+
contentTextWrapper: {},
|
|
1267
|
+
dateText: {},
|
|
1268
|
+
headerRow: {},
|
|
1269
|
+
infoRow: {},
|
|
1270
|
+
lastReplyText: {},
|
|
1271
|
+
parentMessageText: {},
|
|
1272
|
+
touchableWrapper: {},
|
|
1273
|
+
unreadBubbleText: {},
|
|
1274
|
+
unreadBubbleWrapper: {},
|
|
1275
|
+
},
|
|
1276
|
+
threadListUnreadBanner: {
|
|
1277
|
+
text: {},
|
|
1278
|
+
touchableWrapper: {},
|
|
1279
|
+
},
|
|
1244
1280
|
typingIndicator: {
|
|
1245
1281
|
container: {},
|
|
1246
1282
|
text: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { PropsWithChildren, useContext } from 'react';
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import { ChannelState, Thread } from 'stream-chat';
|
|
4
4
|
|
|
5
5
|
import type { MessageType } from '../../components/MessageList/hooks/useMessageList';
|
|
6
6
|
import type { DefaultStreamChatGenerics, UnknownType } from '../../types/types';
|
|
@@ -9,6 +9,10 @@ import { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue';
|
|
|
9
9
|
import { getDisplayName } from '../utils/getDisplayName';
|
|
10
10
|
import { isTestEnvironment } from '../utils/isTestEnvironment';
|
|
11
11
|
|
|
12
|
+
export type ThreadType<
|
|
13
|
+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
14
|
+
> = { thread: MessageType<StreamChatGenerics>; threadInstance: Thread };
|
|
15
|
+
|
|
12
16
|
export type ThreadContextValue<
|
|
13
17
|
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
14
18
|
> = {
|
|
@@ -20,12 +24,15 @@ export type ThreadContextValue<
|
|
|
20
24
|
setThreadLoadingMore: React.Dispatch<React.SetStateAction<boolean>>;
|
|
21
25
|
thread: MessageType<StreamChatGenerics> | null;
|
|
22
26
|
threadHasMore: boolean;
|
|
23
|
-
threadLoadingMore: boolean;
|
|
24
27
|
threadMessages: ChannelState<StreamChatGenerics>['threads'][string];
|
|
28
|
+
loadMoreRecentThread?: (opts: { limit?: number }) => Promise<void>;
|
|
25
29
|
/**
|
|
26
30
|
* Boolean to enable/disable parent message press
|
|
27
31
|
*/
|
|
28
32
|
parentMessagePreventPress?: boolean;
|
|
33
|
+
threadInstance?: Thread | null;
|
|
34
|
+
threadLoadingMore?: boolean;
|
|
35
|
+
threadLoadingMoreRecent?: boolean;
|
|
29
36
|
};
|
|
30
37
|
|
|
31
38
|
export const ThreadContext = React.createContext(DEFAULT_BASE_CONTEXT_VALUE as ThreadContextValue);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React, { PropsWithChildren, useContext } from 'react';
|
|
2
|
+
|
|
3
|
+
import { Channel, Thread } from 'stream-chat';
|
|
4
|
+
|
|
5
|
+
import { MessageType } from '../../components';
|
|
6
|
+
import type { DefaultStreamChatGenerics } from '../../types/types';
|
|
7
|
+
import { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue';
|
|
8
|
+
|
|
9
|
+
export type ThreadListItemContextValue<
|
|
10
|
+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
11
|
+
> = {
|
|
12
|
+
channel: Channel<StreamChatGenerics>;
|
|
13
|
+
dateString: string | number | undefined;
|
|
14
|
+
deletedAtDateString: string | number | undefined;
|
|
15
|
+
lastReply: MessageType<StreamChatGenerics> | undefined;
|
|
16
|
+
ownUnreadMessageCount: number;
|
|
17
|
+
parentMessage: MessageType<StreamChatGenerics> | undefined;
|
|
18
|
+
thread: Thread<StreamChatGenerics>;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const ThreadListItemContext = React.createContext(
|
|
22
|
+
DEFAULT_BASE_CONTEXT_VALUE as ThreadListItemContextValue,
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
export const ThreadListItemProvider = <
|
|
26
|
+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
27
|
+
>({
|
|
28
|
+
children,
|
|
29
|
+
value,
|
|
30
|
+
}: PropsWithChildren<{
|
|
31
|
+
value: ThreadListItemContextValue<StreamChatGenerics>;
|
|
32
|
+
}>) => (
|
|
33
|
+
<ThreadListItemContext.Provider value={value as unknown as ThreadListItemContextValue}>
|
|
34
|
+
{children}
|
|
35
|
+
</ThreadListItemContext.Provider>
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
export const useThreadListItemContext = <
|
|
39
|
+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
40
|
+
>() =>
|
|
41
|
+
useContext(ThreadListItemContext) as unknown as ThreadListItemContextValue<StreamChatGenerics>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import React, { PropsWithChildren, useContext } from 'react';
|
|
2
|
+
|
|
3
|
+
import { FlatListProps } from 'react-native';
|
|
4
|
+
|
|
5
|
+
import { Channel, Thread } from 'stream-chat';
|
|
6
|
+
|
|
7
|
+
import type { DefaultStreamChatGenerics } from '../../types/types';
|
|
8
|
+
import { ThreadType } from '../threadContext/ThreadContext';
|
|
9
|
+
import { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue';
|
|
10
|
+
|
|
11
|
+
import { isTestEnvironment } from '../utils/isTestEnvironment';
|
|
12
|
+
|
|
13
|
+
export type ThreadsContextValue<
|
|
14
|
+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
15
|
+
> = {
|
|
16
|
+
isFocused: boolean;
|
|
17
|
+
isLoading: boolean;
|
|
18
|
+
isLoadingNext: boolean;
|
|
19
|
+
threads: Thread<StreamChatGenerics>[];
|
|
20
|
+
additionalFlatListProps?: Partial<FlatListProps<Thread>>;
|
|
21
|
+
loadMore?: () => Promise<void>;
|
|
22
|
+
onThreadSelect?: (thread: ThreadType, channel: Channel) => void;
|
|
23
|
+
ThreadListEmptyPlaceholder?: React.ComponentType;
|
|
24
|
+
ThreadListItem?: React.ComponentType;
|
|
25
|
+
ThreadListLoadingIndicator?: React.ComponentType;
|
|
26
|
+
ThreadListLoadingMoreIndicator?: React.ComponentType;
|
|
27
|
+
ThreadListUnreadBanner?: React.ComponentType;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const ThreadsContext = React.createContext(
|
|
31
|
+
DEFAULT_BASE_CONTEXT_VALUE as ThreadsContextValue,
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
export const ThreadsProvider = <
|
|
35
|
+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
36
|
+
>({
|
|
37
|
+
children,
|
|
38
|
+
value,
|
|
39
|
+
}: PropsWithChildren<{
|
|
40
|
+
value: ThreadsContextValue<StreamChatGenerics>;
|
|
41
|
+
}>) => (
|
|
42
|
+
<ThreadsContext.Provider value={value as unknown as ThreadsContextValue}>
|
|
43
|
+
{children}
|
|
44
|
+
</ThreadsContext.Provider>
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
export const useThreadsContext = <
|
|
48
|
+
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
49
|
+
>() => {
|
|
50
|
+
const contextValue = useContext(
|
|
51
|
+
ThreadsContext,
|
|
52
|
+
) as unknown as ThreadsContextValue<StreamChatGenerics>;
|
|
53
|
+
|
|
54
|
+
if (contextValue === DEFAULT_BASE_CONTEXT_VALUE && !isTestEnvironment()) {
|
|
55
|
+
throw new Error(
|
|
56
|
+
// TODO: Set correct link to docs page, should be the new ThreadList instead of Channel
|
|
57
|
+
`The useThreadsContext hook was called outside of the ThreadsContext provider. Make sure you have configured the ThreadList component correctly - https://getstream.io/chat/docs/sdk/reactnative/basics/hello_stream_chat/#channel`,
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return contextValue;
|
|
62
|
+
};
|
package/src/hooks/index.ts
CHANGED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import type { StateStore } from 'stream-chat';
|
|
4
|
+
|
|
5
|
+
export function useStateStore<T extends Record<string, unknown>, O extends readonly unknown[]>(
|
|
6
|
+
store: StateStore<T>,
|
|
7
|
+
selector: (v: T) => O,
|
|
8
|
+
): O;
|
|
9
|
+
export function useStateStore<T extends Record<string, unknown>, O extends readonly unknown[]>(
|
|
10
|
+
store: StateStore<T> | undefined,
|
|
11
|
+
selector: (v: T) => O,
|
|
12
|
+
): O | undefined;
|
|
13
|
+
export function useStateStore<T extends Record<string, unknown>, O extends readonly unknown[]>(
|
|
14
|
+
store: StateStore<T> | undefined,
|
|
15
|
+
selector: (v: T) => O,
|
|
16
|
+
) {
|
|
17
|
+
const [state, setState] = useState<O | undefined>(() => {
|
|
18
|
+
if (!store) return undefined;
|
|
19
|
+
return selector(store.getLatestValue());
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
if (!store) return;
|
|
24
|
+
|
|
25
|
+
const unsubscribe = store.subscribeWithSelector(selector, setState);
|
|
26
|
+
|
|
27
|
+
return unsubscribe;
|
|
28
|
+
}, [store, selector]);
|
|
29
|
+
|
|
30
|
+
return state;
|
|
31
|
+
}
|
package/src/i18n/en.json
CHANGED
|
@@ -38,12 +38,14 @@
|
|
|
38
38
|
"Links are disabled": "Links are disabled",
|
|
39
39
|
"Loading channels...": "Loading channels...",
|
|
40
40
|
"Loading messages...": "Loading messages...",
|
|
41
|
+
"Loading threads...": "Loading threads...",
|
|
41
42
|
"Loading...": "Loading...",
|
|
42
43
|
"Message Reactions": "Message Reactions",
|
|
43
44
|
"Message deleted": "Message deleted",
|
|
44
45
|
"Message flagged": "Message flagged",
|
|
45
46
|
"Mute User": "Mute User",
|
|
46
47
|
"No chats here yet…": "No chats here yet…",
|
|
48
|
+
"No threads here yet": "No threads here yet",
|
|
47
49
|
"Not supported": "Not supported",
|
|
48
50
|
"Nothing yet...": "Nothing yet...",
|
|
49
51
|
"Ok": "Ok",
|
|
@@ -67,6 +69,8 @@
|
|
|
67
69
|
"Sending links is not allowed in this conversation": "Sending links is not allowed in this conversation",
|
|
68
70
|
"Slow mode ON": "Slow mode ON",
|
|
69
71
|
"The message has been reported to a moderator.": "The message has been reported to a moderator.",
|
|
72
|
+
"The source message was deleted": "The source message was deleted",
|
|
73
|
+
"This reply was deleted": "This reply was deleted",
|
|
70
74
|
"Thread Reply": "Thread Reply",
|
|
71
75
|
"Unban User": "Unban User",
|
|
72
76
|
"Unblock User": "Unblock User",
|
|
@@ -75,8 +79,10 @@
|
|
|
75
79
|
"Unpin from Conversation": "Unpin from Conversation",
|
|
76
80
|
"Unread Messages": "Unread Messages",
|
|
77
81
|
"Video": "Video",
|
|
82
|
+
"Voice message": "Voice message",
|
|
78
83
|
"You": "You",
|
|
79
84
|
"You can't send messages in this channel": "You can't send messages in this channel",
|
|
85
|
+
"replied to": "replied to",
|
|
80
86
|
"timestamp/ChannelPreviewStatus": "{{ timestamp | timestampFormatter(calendar: true; calendarFormats: {\"lastDay\":\"[Yesterday]\", \"lastWeek\":\"dddd\", \"nextDay\":\"[Tomorrow]\", \"nextWeek\":\"dddd [at] LT\", \"sameDay\":\"LT\", \"sameElse\":\"L\"}) }}",
|
|
81
87
|
"timestamp/ImageGalleryHeader": "{{ timestamp | timestampFormatter(calendar: true) }}",
|
|
82
88
|
"timestamp/InlineDateSeparator": "{{ timestamp | timestampFormatter(calendar: true) }}",
|
|
@@ -84,6 +90,7 @@
|
|
|
84
90
|
"timestamp/MessageSystem": "{{ timestamp | timestampFormatter(calendar: true) }}",
|
|
85
91
|
"timestamp/MessageTimestamp": "{{ timestamp | timestampFormatter(format: LT) }}",
|
|
86
92
|
"timestamp/StickyHeader": "{{ timestamp | timestampFormatter(calendar: true) }}",
|
|
93
|
+
"timestamp/ThreadListItem": "{{ timestamp | timestampFormatter(calendar: true; calendarFormats: {\"lastDay\":\"[Yesterday]\", \"lastWeek\":\"dddd\", \"nextDay\":\"[Tomorrow]\", \"nextWeek\":\"dddd [at] LT\", \"sameDay\":\"LT\", \"sameElse\":\"L\"}) }}",
|
|
87
94
|
"{{ firstUser }} and {{ nonSelfUserLength }} more are typing": "{{ firstUser }} and {{ nonSelfUserLength }} more are typing",
|
|
88
95
|
"{{ index }} of {{ photoLength }}": "{{ index }} of {{ photoLength }}",
|
|
89
96
|
"{{ replyCount }} Replies": "{{ replyCount }} Replies",
|
package/src/i18n/es.json
CHANGED
|
@@ -38,12 +38,14 @@
|
|
|
38
38
|
"Links are disabled": "Los enlaces están desactivados",
|
|
39
39
|
"Loading channels...": "Cargando canales...",
|
|
40
40
|
"Loading messages...": "Cargando mensajes...",
|
|
41
|
+
"Loading threads...": "Cargando hilos...",
|
|
41
42
|
"Loading...": "Cargando...",
|
|
42
43
|
"Message Reactions": "Reacciones al mensaje",
|
|
43
44
|
"Message deleted": "Mensaje eliminado",
|
|
44
45
|
"Message flagged": "Mensaje reportado",
|
|
45
46
|
"Mute User": "Silenciar usuario",
|
|
46
47
|
"No chats here yet…": "No hay chats aquí todavía...",
|
|
48
|
+
"No threads here yet": "Aún no hay hilos aquí",
|
|
47
49
|
"Not supported": "No admitido",
|
|
48
50
|
"Nothing yet...": "Aún no hay nada...",
|
|
49
51
|
"Ok": "Aceptar",
|
|
@@ -67,6 +69,8 @@
|
|
|
67
69
|
"Sending links is not allowed in this conversation": "No está permitido enviar enlaces en esta conversación",
|
|
68
70
|
"Slow mode ON": "Modo lento ACTIVADO",
|
|
69
71
|
"The message has been reported to a moderator.": "El mensaje ha sido reportado a un moderador.",
|
|
72
|
+
"The source message was deleted": "El mensaje original fue eliminado",
|
|
73
|
+
"This reply was deleted": "Esta respuesta fue eliminada",
|
|
70
74
|
"Thread Reply": "Respuesta de hilo",
|
|
71
75
|
"Unban User": "Desbloquear usuario",
|
|
72
76
|
"Unblock User": "Usuario desconocido",
|
|
@@ -75,8 +79,10 @@
|
|
|
75
79
|
"Unpin from Conversation": "Desmarcar de la conversación",
|
|
76
80
|
"Unread Messages": "Mensajes no leídos",
|
|
77
81
|
"Video": "Video",
|
|
82
|
+
"Voice message": "Mensaje de voz",
|
|
78
83
|
"You": "Tú",
|
|
79
84
|
"You can't send messages in this channel": "No puedes enviar mensajes en este canal",
|
|
85
|
+
"replied to": "respondió a",
|
|
80
86
|
"timestamp/ChannelPreviewStatus": "{{ timestamp | timestampFormatter(calendar: true; calendarFormats: {\"lastDay\":\"[Ayer]\", \"lastWeek\":\"dddd\", \"nextDay\":\"[Mañana]\", \"nextWeek\":\"dddd [a las] LT\", \"sameDay\":\"LT\", \"sameElse\":\"L\"}) }}",
|
|
81
87
|
"timestamp/ImageGalleryHeader": "{{ timestamp | timestampFormatter(calendar: true) }}",
|
|
82
88
|
"timestamp/InlineDateSeparator": "{{ timestamp | timestampFormatter(calendar: true) }}",
|
|
@@ -84,6 +90,7 @@
|
|
|
84
90
|
"timestamp/MessageSystem": "{{ timestamp | timestampFormatter(calendar: true) }}",
|
|
85
91
|
"timestamp/MessageTimestamp": "{{ timestamp | timestampFormatter(format: LT) }}",
|
|
86
92
|
"timestamp/StickyHeader": "{{ timestamp | timestampFormatter(calendar: true) }}",
|
|
93
|
+
"timestamp/ThreadListItem": "{{ timestamp | timestampFormatter(calendar: true; calendarFormats: {\"lastDay\":\"[Ayer]\", \"lastWeek\":\"dddd\", \"nextDay\":\"[Mañana]\", \"nextWeek\":\"dddd [a las] LT\", \"sameDay\":\"LT\", \"sameElse\":\"L\"}) }}",
|
|
87
94
|
"{{ firstUser }} and {{ nonSelfUserLength }} more are typing": "{{ firstUser }} y {{ nonSelfUserLength }} más están escribiendo",
|
|
88
95
|
"{{ index }} of {{ photoLength }}": "{{ index }} de {{ photoLength }}",
|
|
89
96
|
"{{ replyCount }} Replies": "{{ replyCount }} Respuestas",
|