@robono/messaging-react-native 0.7.0 → 0.9.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.
Files changed (49) hide show
  1. package/CHANGELOG.md +9 -1
  2. package/README.md +40 -37
  3. package/SBOM.spdx.json +235 -163
  4. package/dist/account.js +5 -3
  5. package/dist/attachment-menu.js +3 -1
  6. package/dist/call-message.js +6 -4
  7. package/dist/calling.js +3 -1
  8. package/dist/conversation-details.js +9 -6
  9. package/dist/expo-connected-calling.d.ts +4 -2
  10. package/dist/expo-connected-calling.js +19 -4
  11. package/dist/expo-extras.js +4 -1
  12. package/dist/expo-media.js +27 -5
  13. package/dist/expo-messenger.d.ts +42 -4
  14. package/dist/expo-messenger.js +57 -7
  15. package/dist/expo-notifications.d.ts +2 -0
  16. package/dist/expo-notifications.js +8 -3
  17. package/dist/expo-outbox.js +22 -1
  18. package/dist/expo-screen.d.ts +1 -1
  19. package/dist/expo-screen.js +23 -14
  20. package/dist/expo-social.js +3 -1
  21. package/dist/expo.d.ts +1 -1
  22. package/dist/expo.js +1 -1
  23. package/dist/extras.js +9 -6
  24. package/dist/forward.js +6 -4
  25. package/dist/group-editor.js +7 -5
  26. package/dist/header-calls.js +7 -5
  27. package/dist/inbox-search.js +4 -2
  28. package/dist/inbox.js +9 -7
  29. package/dist/index.d.ts +6 -3
  30. package/dist/index.js +91 -61
  31. package/dist/localization.d.ts +24 -0
  32. package/dist/localization.js +12 -0
  33. package/dist/maps-connection.js +3 -1
  34. package/dist/media-ui.js +13 -7
  35. package/dist/message-menu.js +3 -1
  36. package/dist/native-outbox.d.ts +9 -1
  37. package/dist/native-outbox.js +7 -0
  38. package/dist/polls.js +18 -14
  39. package/dist/popup.js +6 -3
  40. package/dist/quick-send.js +4 -2
  41. package/dist/safety.js +9 -7
  42. package/dist/saved.js +5 -3
  43. package/dist/scheduled.js +17 -13
  44. package/dist/search.js +5 -3
  45. package/dist/social.js +7 -4
  46. package/dist/translation-settings.js +5 -3
  47. package/dist/voice-composer.js +9 -5
  48. package/package.json +9 -7
  49. package/setup.plugin.cjs +20 -0
package/dist/inbox.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useRobonoLocale } from './localization.js';
2
3
  import { MessageMenuRow } from './message-menu.js';
3
4
  import { InboxMessageSearch } from './inbox-search.js';
4
5
  import { MessageIcon } from './icons.js';
@@ -8,6 +9,7 @@ import { defaultMessagingSettings } from '@robono/messaging';
8
9
  import { MessagingPopup, MessagingMenuSurface, MessagingPopupHeaderBoundary, messagingPopupColors, messagingPopupBackdrop } from './popup.js';
9
10
  /** Compact Messenger chat rows: avatar, name, last message, time and unread badge. */
10
11
  export function MessagingInbox({ client, userId, contacts = {}, appearance, active = true, onSelect, onDeleted, companyName, headerActions, searchText }) {
12
+ const { text: uiText, locale: uiLocale, number: uiNumber, count: uiCount } = useRobonoLocale();
11
13
  const state = useSyncExternalStore(client.subscribe, client.getSnapshot, client.getSnapshot), design = appearance ?? state.appearance ?? defaultMessagingSettings().appearance, c = design.colors;
12
14
  useEffect(() => { const update = (value) => { if (active && (value === null || value === 'active'))
13
15
  client.start();
@@ -45,25 +47,25 @@ export function MessagingInbox({ client, userId, contacts = {}, appearance, acti
45
47
  setConfirm(false);
46
48
  }
47
49
  catch (e) {
48
- setError(e instanceof Error ? e.message : 'Chat options could not be saved.');
50
+ setError(e instanceof Error ? e.message : uiText("Chat options could not be saved."));
49
51
  }
50
52
  finally {
51
53
  setBusy(false);
52
54
  } }
53
55
  const preview = (row) => { const m = row.lastMessage; if (!m)
54
56
  return 'No messages yet'; const text = m.kind === 'text' ? m.text ?? '' : ({ voice: 'Voice message', image: 'Photo', video: 'Video', document: 'Document', poll: 'Poll' }[m.kind] ?? 'Message'); return (m.senderId === userId ? 'You: ' : '') + text; };
55
- return _jsxs(View, { style: { flex: 1, minHeight: 0, backgroundColor: c.background }, children: [_jsx(MessagingPopupHeaderBoundary, { children: _jsxs(View, { testID: "messaging-inbox-header", style: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', minHeight: 64, paddingHorizontal: 16, paddingVertical: 8, gap: 8 }, children: [_jsx(Text, { accessibilityRole: "header", numberOfLines: 1, style: { flex: 1, color: c.foreground, fontSize: 20, fontWeight: '700' }, children: companyName ?? design.name }), headerActions] }) }), _jsxs(View, { style: { margin: 12, marginTop: 8, flexDirection: 'row', alignItems: 'center', gap: 8, borderRadius: 10, paddingHorizontal: 10, backgroundColor: c.foreground + '0b' }, children: [_jsx(MessageIcon, { name: "search", size: 20, color: c.secondary }), _jsx(TextInput, { accessibilityLabel: "Search chats", placeholder: state.globalSearchAvailable ? "Search chats and messages" : "Search chats", placeholderTextColor: c.secondary, value: query, onChangeText: setQuery, maxLength: 200, autoCapitalize: "none", autoCorrect: false, style: { flex: 1, minHeight: 44, color: c.foreground, fontSize: 16 } }), !!query && _jsx(Pressable, { accessibilityRole: "button", accessibilityLabel: "Clear chat search", onPress: () => setQuery(''), style: { width: 44, height: 44, alignItems: 'center', justifyContent: 'center' }, children: _jsx(MessageIcon, { name: "close", size: 20, color: c.secondary }) })] }), state.error && _jsxs(View, { style: { padding: 12 }, children: [_jsx(Text, { accessibilityRole: "alert", style: { color: c.foreground }, children: state.error }), _jsx(Pressable, { accessibilityRole: "button", onPress: () => void client.refresh().catch(() => { }), children: _jsx(Text, { style: { color: c.accent, paddingVertical: 8 }, children: "Try again" }) })] }), query.trim() && state.globalSearchAvailable ? _jsx(InboxMessageSearch, { client: client, query: query.trim(), appearance: design, name: title, chats: state.conversations.filter(row => title(row).toLocaleLowerCase().includes(query.trim().toLocaleLowerCase())), onSelect: onSelect }, userId) : _jsx(FlatList, { data: state.conversations.filter(row => !query.trim() || [title(row), row.lastMessage?.text ?? '', searchText?.(row) ?? ''].join(' ').toLocaleLowerCase().includes(query.trim().toLocaleLowerCase())), keyExtractor: row => row.id, contentContainerStyle: { flexGrow: 1 }, ItemSeparatorComponent: () => _jsx(View, { style: { height: 1, backgroundColor: c.foreground + '12', marginLeft: 64 } }), ListEmptyComponent: _jsx(Text, { style: { padding: 20, textAlign: 'center', color: c.secondary }, children: state.loading ? 'Loading chats…' : state.error ? '' : query ? 'No matching chats.' : 'No chats yet' }), ListFooterComponent: state.hasMore ? _jsx(Pressable, { accessibilityRole: "button", disabled: state.loading, onPress: () => void client.loadMore().catch(() => { }), children: _jsx(Text, { style: { padding: 12, textAlign: 'center', color: c.accent }, children: state.loading ? 'Loading…' : 'More chats' }) }) : null, renderItem: ({ item }) => {
57
+ return _jsxs(View, { style: { flex: 1, minHeight: 0, backgroundColor: c.background }, children: [_jsx(MessagingPopupHeaderBoundary, { children: _jsxs(View, { testID: "messaging-inbox-header", style: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', minHeight: 64, paddingHorizontal: 16, paddingVertical: 8, gap: 8 }, children: [_jsx(Text, { accessibilityRole: "header", numberOfLines: 1, style: { flex: 1, color: c.foreground, fontSize: 20, fontWeight: '700' }, children: companyName ?? design.name }), headerActions] }) }), _jsxs(View, { style: { margin: 12, marginTop: 8, flexDirection: 'row', alignItems: 'center', gap: 8, borderRadius: 10, paddingHorizontal: 10, backgroundColor: c.foreground + '0b' }, children: [_jsx(MessageIcon, { name: "search", size: 20, color: c.secondary }), _jsx(TextInput, { accessibilityLabel: uiText("Search chats"), placeholder: state.globalSearchAvailable ? uiText("Search chats and messages") : uiText("Search chats"), placeholderTextColor: c.secondary, value: query, onChangeText: setQuery, maxLength: 200, autoCapitalize: "none", autoCorrect: false, style: { flex: 1, minHeight: 44, color: c.foreground, fontSize: 16 } }), !!query && _jsx(Pressable, { accessibilityRole: "button", accessibilityLabel: uiText("Clear chat search"), onPress: () => setQuery(''), style: { width: 44, height: 44, alignItems: 'center', justifyContent: 'center' }, children: _jsx(MessageIcon, { name: "close", size: 20, color: c.secondary }) })] }), state.error && _jsxs(View, { style: { padding: 12 }, children: [_jsx(Text, { accessibilityRole: "alert", style: { color: c.foreground }, children: state.error }), _jsx(Pressable, { accessibilityRole: "button", onPress: () => void client.refresh().catch(() => { }), children: _jsx(Text, { style: { color: c.accent, paddingVertical: 8 }, children: uiText("Try again") }) })] }), query.trim() && state.globalSearchAvailable ? _jsx(InboxMessageSearch, { client: client, query: query.trim(), appearance: design, name: title, chats: state.conversations.filter(row => title(row).toLocaleLowerCase().includes(query.trim().toLocaleLowerCase())), onSelect: onSelect }, userId) : _jsx(FlatList, { data: state.conversations.filter(row => !query.trim() || [title(row), row.lastMessage?.text ?? '', searchText?.(row) ?? ''].join(' ').toLocaleLowerCase().includes(query.trim().toLocaleLowerCase())), keyExtractor: row => row.id, contentContainerStyle: { flexGrow: 1 }, ItemSeparatorComponent: () => _jsx(View, { style: { height: 1, backgroundColor: c.foreground + '12', marginLeft: 64 } }), ListEmptyComponent: _jsx(Text, { style: { padding: 20, textAlign: 'center', color: c.secondary }, children: state.loading ? uiText("Loading chats…") : state.error ? '' : query ? uiText("No matching chats.") : uiText("No chats yet") }), ListFooterComponent: state.hasMore ? _jsx(Pressable, { accessibilityRole: "button", disabled: state.loading, onPress: () => void client.loadMore().catch(() => { }), children: _jsx(Text, { style: { padding: 12, textAlign: 'center', color: c.accent }, children: state.loading ? uiText("Loading…") : uiText("More chats") }) }) : null, renderItem: ({ item }) => {
56
58
  const person = item.contactId ? contacts[item.contactId] : undefined, title = item.kind === 'group' ? item.name ?? 'Group' : person?.name ?? item.contactId ?? 'Chat';
57
59
  const date = item.lastMessage ? new Date(item.lastMessage.createdAt) : null;
58
60
  return _jsxs(Pressable, { ref: node => { if (node)
59
61
  rows.current.set(item.id, node);
60
62
  else
61
- rows.current.delete(item.id); }, accessibilityRole: "button", accessibilityLabel: `${title}${item.unreadCount ? `, ${item.unreadCount} unread` : ''}`, onPress: () => onSelect(item), onLongPress: () => openOptions(item), accessibilityActions: state.inboxActionsAvailable ? [{ name: 'showOptions', label: 'Chat options' }] : [], onAccessibilityAction: e => { if (e.nativeEvent.actionName === 'showOptions')
62
- openOptions(item); }, ...(Platform.OS === 'web' ? { onContextMenu: (e) => { e.preventDefault(); openOptions(item); } } : {}), style: { flexDirection: 'row', alignItems: 'center', gap: 12, paddingHorizontal: 12, paddingVertical: 10, minHeight: 68 }, children: [person?.avatarUrl ? _jsx(Image, { source: { uri: person.avatarUrl }, style: { width: 40, height: 40, borderRadius: 20 } }) : _jsx(View, { style: { width: 40, height: 40, borderRadius: 20, backgroundColor: c.accent + '20', alignItems: 'center', justifyContent: 'center' }, children: _jsx(Text, { style: { color: c.accent, fontSize: 18, fontWeight: '700' }, children: title.slice(0, 1).toUpperCase() }) }), _jsxs(View, { style: { flex: 1, minWidth: 0 }, children: [_jsxs(Text, { numberOfLines: 1, style: { color: c.foreground, fontSize: 16, fontWeight: '700' }, children: [title, item.muted ? ' · Muted' : ''] }), _jsx(Text, { numberOfLines: 1, style: { color: c.secondary, marginTop: 3, fontSize: 14 }, children: preview(item) })] }), _jsxs(View, { style: { alignItems: 'flex-end', gap: 4 }, children: [_jsx(Text, { style: { color: item.unreadCount ? c.accent : c.secondary, fontSize: 12 }, children: date ? date.toDateString() === new Date().toDateString() ? date.toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit' }) : date.toLocaleDateString(undefined, { month: 'short', day: 'numeric' }) : '' }), item.unreadCount > 0 && _jsx(View, { style: { minWidth: 20, height: 20, borderRadius: 10, borderWidth: 1.5, borderColor: c.accent, alignItems: 'center', justifyContent: 'center', paddingHorizontal: 5 }, children: _jsx(Text, { style: { color: c.accent, fontSize: 10, fontWeight: '900' }, children: item.unreadCount > 99 ? '99+' : item.unreadCount }) })] })] });
63
+ rows.current.delete(item.id); }, accessibilityRole: "button", accessibilityLabel: `${title}${item.unreadCount ? `, ${item.unreadCount} unread` : ''}`, onPress: () => onSelect(item), onLongPress: () => openOptions(item), accessibilityActions: state.inboxActionsAvailable ? [{ name: 'showOptions', label: uiText("Chat options") }] : [], onAccessibilityAction: e => { if (e.nativeEvent.actionName === 'showOptions')
64
+ openOptions(item); }, ...(Platform.OS === 'web' ? { onContextMenu: (e) => { e.preventDefault(); openOptions(item); } } : {}), style: { flexDirection: 'row', alignItems: 'center', gap: 12, paddingHorizontal: 12, paddingVertical: 10, minHeight: 68 }, children: [person?.avatarUrl ? _jsx(Image, { source: { uri: person.avatarUrl }, style: { width: 40, height: 40, borderRadius: 20 } }) : _jsx(View, { style: { width: 40, height: 40, borderRadius: 20, backgroundColor: c.accent + '20', alignItems: 'center', justifyContent: 'center' }, children: _jsx(Text, { style: { color: c.accent, fontSize: 18, fontWeight: '700' }, children: title.slice(0, 1).toUpperCase() }) }), _jsxs(View, { style: { flex: 1, minWidth: 0 }, children: [_jsxs(Text, { numberOfLines: 1, style: { color: c.foreground, fontSize: 16, fontWeight: '700' }, children: [title, item.muted ? uiText(" · Muted") : ''] }), _jsx(Text, { numberOfLines: 1, style: { color: c.secondary, marginTop: 3, fontSize: 14 }, children: preview(item) })] }), _jsxs(View, { style: { alignItems: 'flex-end', gap: 4 }, children: [_jsx(Text, { style: { color: item.unreadCount ? c.accent : c.secondary, fontSize: 12 }, children: date ? date.toDateString() === new Date().toDateString() ? date.toLocaleTimeString(uiLocale, { hour: 'numeric', minute: '2-digit' }) : date.toLocaleDateString(uiLocale, { month: 'short', day: 'numeric' }) : '' }), item.unreadCount > 0 && _jsx(View, { style: { minWidth: 20, height: 20, borderRadius: 10, borderWidth: 1.5, borderColor: c.accent, alignItems: 'center', justifyContent: 'center', paddingHorizontal: 5 }, children: _jsx(Text, { style: { color: c.accent, fontSize: 10, fontWeight: '900' }, children: item.unreadCount > 99 ? '99+' : item.unreadCount }) })] })] });
63
65
  } }), selected && _jsxs(_Fragment, { children: [_jsx(MessagingMenuSurface, { visible: menuVisible, onDismiss: dismissed, onClose: () => { if (!busy)
64
66
  setSelected(null); }, children: rect => {
65
67
  const width = Math.min(218, rect.width - 24), top = Math.max(12, Math.min(anchor.y - rect.top, rect.height - 124));
66
- return _jsxs(View, { style: { flex: 1 }, children: [_jsx(Pressable, { accessibilityLabel: "Close chat options", onPress: () => { if (!busy)
67
- setSelected(null); }, style: { position: 'absolute', inset: 0, backgroundColor: messagingPopupBackdrop } }), _jsx(View, { testID: "messaging-inbox-dropdown", style: { position: 'absolute', left: Math.max(12, Math.min(anchor.x - rect.left, rect.width - width - 12)), top, width, maxHeight: Math.max(44, rect.height - top - 12), borderRadius: 16, borderWidth: .5, borderColor: '#ffffff22', backgroundColor: '#151515', paddingVertical: 4, overflow: 'hidden' }, children: _jsxs(ScrollView, { keyboardShouldPersistTaps: "handled", children: [_jsx(MessageMenuRow, { icon: selected.muted ? 'notifications-outline' : 'notifications-off-outline', label: selected.muted ? 'Unmute' : 'Mute', disabled: busy, onPress: () => void act(false) }), _jsx(MessageMenuRow, { icon: "trash-outline", label: "Delete chat", danger: true, divider: true, disabled: busy, onPress: showConfirmation }), !!error && _jsx(Text, { accessibilityRole: "alert", style: { color: '#ffffff', padding: 12 }, children: error })] }) })] });
68
- } }), confirm && _jsxs(MessagingPopup, { visible: confirmVisible, onDismiss: dismissed, compact: true, title: "Delete chat with " + title(selected) + "?", foreground: c.foreground, closeLabel: "Close delete chat", closeDisabled: busy, background: c.background, onClose: returnToMenu, children: [_jsx(Text, { style: { color: messagingPopupColors.secondary, marginTop: 8 }, children: "This removes the chat and its history from your view. Other people keep their copy. New messages can bring the chat back." }), !!error && _jsx(Text, { accessibilityRole: "alert", style: { color: messagingPopupColors.foreground, paddingVertical: 8 }, children: error }), _jsxs(View, { style: { flexDirection: 'row', gap: 8, marginTop: 12 }, children: [_jsx(Pressable, { accessibilityRole: "button", disabled: busy, onPress: returnToMenu, style: { flex: 1, minHeight: 44, borderRadius: 12, backgroundColor: messagingPopupColors.incoming, alignItems: 'center', justifyContent: 'center' }, children: _jsx(Text, { style: { color: messagingPopupColors.foreground, fontSize: 16, fontWeight: '600' }, children: "Cancel" }) }), _jsx(Pressable, { accessibilityRole: "button", accessibilityLabel: "Confirm delete chat", disabled: busy, onPress: () => void act(true), style: { flex: 1, minHeight: 44, borderRadius: 12, backgroundColor: '#b72d34', alignItems: 'center', justifyContent: 'center' }, children: _jsx(Text, { style: { color: '#ffffff', fontSize: 16, fontWeight: '600' }, children: "Delete" }) })] })] })] })] });
68
+ return _jsxs(View, { style: { flex: 1 }, children: [_jsx(Pressable, { accessibilityLabel: uiText("Close chat options"), onPress: () => { if (!busy)
69
+ setSelected(null); }, style: { position: 'absolute', inset: 0, backgroundColor: messagingPopupBackdrop } }), _jsx(View, { testID: "messaging-inbox-dropdown", style: { position: 'absolute', left: Math.max(12, Math.min(anchor.x - rect.left, rect.width - width - 12)), top, width, maxHeight: Math.max(44, rect.height - top - 12), borderRadius: 16, borderWidth: .5, borderColor: '#ffffff22', backgroundColor: '#151515', paddingVertical: 4, overflow: 'hidden' }, children: _jsxs(ScrollView, { keyboardShouldPersistTaps: "handled", children: [_jsx(MessageMenuRow, { icon: selected.muted ? 'notifications-outline' : 'notifications-off-outline', label: selected.muted ? uiText("Unmute") : uiText("Mute"), disabled: busy, onPress: () => void act(false) }), _jsx(MessageMenuRow, { icon: "trash-outline", label: uiText("Delete chat"), danger: true, divider: true, disabled: busy, onPress: showConfirmation }), !!error && _jsx(Text, { accessibilityRole: "alert", style: { color: '#ffffff', padding: 12 }, children: error })] }) })] });
70
+ } }), confirm && _jsxs(MessagingPopup, { visible: confirmVisible, onDismiss: dismissed, compact: true, title: uiText('Delete chat with {name}?', { name: title(selected) }), foreground: c.foreground, closeLabel: uiText("Close delete chat"), closeDisabled: busy, background: c.background, onClose: returnToMenu, children: [_jsx(Text, { style: { color: messagingPopupColors.secondary, marginTop: 8 }, children: uiText("This removes the chat and its history from your view. Other people keep their copy. New messages can bring the chat back.") }), !!error && _jsx(Text, { accessibilityRole: "alert", style: { color: messagingPopupColors.foreground, paddingVertical: 8 }, children: error }), _jsxs(View, { style: { flexDirection: 'row', gap: 8, marginTop: 12 }, children: [_jsx(Pressable, { accessibilityRole: "button", disabled: busy, onPress: returnToMenu, style: { flex: 1, minHeight: 44, borderRadius: 12, backgroundColor: messagingPopupColors.incoming, alignItems: 'center', justifyContent: 'center' }, children: _jsx(Text, { style: { color: messagingPopupColors.foreground, fontSize: 16, fontWeight: '600' }, children: uiText("Cancel") }) }), _jsx(Pressable, { accessibilityRole: "button", accessibilityLabel: uiText("Confirm delete chat"), disabled: busy, onPress: () => void act(true), style: { flex: 1, minHeight: 44, borderRadius: 12, backgroundColor: '#b72d34', alignItems: 'center', justifyContent: 'center' }, children: _jsx(Text, { style: { color: '#ffffff', fontSize: 16, fontWeight: '600' }, children: uiText("Delete") }) })] })] })] })] });
69
71
  }
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export { RobonoLocaleProvider, useRobonoLocale } from './localization.js';
1
2
  import { type MessagingAccount } from './account.js';
2
3
  import { type MessagingCallActions } from './header-calls.js';
3
4
  export type { MessagingAccount } from './account.js';
@@ -57,6 +58,8 @@ export interface AttachmentChoice {
57
58
  durationMs?: number;
58
59
  }
59
60
  export interface MessagingScreenProps {
61
+ /** Language of controls and accessibility labels; separate from translated message content. */
62
+ interfaceLocale?: import('@robono/messaging').RobonoLocale;
60
63
  /** Optional tactile feedback at the quote threshold; supplied by the native screen. */
61
64
  onQuoteReady?: () => void;
62
65
  companyName?: string;
@@ -149,8 +152,8 @@ interface MessagingContext extends MessagingScreenProps {
149
152
  setReply: (message: MessagingMessage | null) => void;
150
153
  }
151
154
  export declare function useMessagingUI(): MessagingContext;
152
- export declare function MessagingProvider({ children, ...props }: MessagingScreenProps & {
153
- children: ReactNode;
155
+ export declare function MessagingProvider(props: MessagingScreenProps & {
156
+ children: React.ReactNode;
154
157
  }): React.JSX.Element;
155
158
  export declare function messagingHeaderColors(design: MessagingAppearance, group: boolean): {
156
159
  background: string;
@@ -161,7 +164,7 @@ export declare function MessagingHeader({ children }?: {
161
164
  }): React.JSX.Element;
162
165
  export declare function MessagingBubble({ message, pendingStatus, previousMessage, nextMessage }: {
163
166
  message: MessagingMessage;
164
- pendingStatus?: 'sending' | 'failed';
167
+ pendingStatus?: 'sending' | 'queued' | 'failed';
165
168
  previousMessage?: MessagingMessage;
166
169
  nextMessage?: MessagingMessage;
167
170
  }): React.JSX.Element;