stream-chat-react-native-core 9.0.0-beta.15 → 9.0.0-beta.17

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 (227) hide show
  1. package/lib/commonjs/components/AITypingIndicatorView/AITypingIndicatorView.js +1 -1
  2. package/lib/commonjs/components/AITypingIndicatorView/AITypingIndicatorView.js.map +1 -1
  3. package/lib/commonjs/components/AttachmentPicker/components/AttachmentPickerContent.js +1 -1
  4. package/lib/commonjs/components/AttachmentPicker/components/AttachmentPickerContent.js.map +1 -1
  5. package/lib/commonjs/components/AttachmentPicker/components/AttachmentTypePickerButton.js +1 -1
  6. package/lib/commonjs/components/AttachmentPicker/components/AttachmentTypePickerButton.js.map +1 -1
  7. package/lib/commonjs/components/ChannelList/ChannelListHeaderErrorIndicator.js +1 -1
  8. package/lib/commonjs/components/ChannelList/ChannelListHeaderErrorIndicator.js.map +1 -1
  9. package/lib/commonjs/components/ChannelList/ChannelListHeaderNetworkDownIndicator.js +1 -1
  10. package/lib/commonjs/components/ChannelList/ChannelListHeaderNetworkDownIndicator.js.map +1 -1
  11. package/lib/commonjs/components/ChannelList/Skeleton.js +1 -1
  12. package/lib/commonjs/components/ChannelList/Skeleton.js.map +1 -1
  13. package/lib/commonjs/components/ChannelList/hooks/useChannelActionItems.js +1 -1
  14. package/lib/commonjs/components/ChannelList/hooks/useChannelActionItems.js.map +1 -1
  15. package/lib/commonjs/components/ChannelPreview/ChannelDetailsBottomSheet.js +17 -2
  16. package/lib/commonjs/components/ChannelPreview/ChannelDetailsBottomSheet.js.map +1 -1
  17. package/lib/commonjs/components/ChannelPreview/ChannelPreviewMessage.js +5 -4
  18. package/lib/commonjs/components/ChannelPreview/ChannelPreviewMessage.js.map +1 -1
  19. package/lib/commonjs/components/ChannelPreview/ChannelSwipableWrapper.js +28 -33
  20. package/lib/commonjs/components/ChannelPreview/ChannelSwipableWrapper.js.map +1 -1
  21. package/lib/commonjs/components/KeyboardCompatibleView/KeyboardCompatibleView.js +65 -36
  22. package/lib/commonjs/components/KeyboardCompatibleView/KeyboardCompatibleView.js.map +1 -1
  23. package/lib/commonjs/components/KeyboardCompatibleView/KeyboardControllerAvoidingView.js +1 -1
  24. package/lib/commonjs/components/KeyboardCompatibleView/KeyboardControllerAvoidingView.js.map +1 -1
  25. package/lib/commonjs/components/Message/utils/messageActions.js +1 -1
  26. package/lib/commonjs/components/Message/utils/messageActions.js.map +1 -1
  27. package/lib/commonjs/components/MessageInput/components/AttachmentPreview/VideoAttachmentUploadPreview.js +4 -4
  28. package/lib/commonjs/components/MessageInput/components/AttachmentPreview/VideoAttachmentUploadPreview.js.map +1 -1
  29. package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecordingLockIndicator.js +2 -2
  30. package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecordingLockIndicator.js.map +1 -1
  31. package/lib/commonjs/components/MessageList/NetworkDownIndicator.js +1 -1
  32. package/lib/commonjs/components/MessageList/NetworkDownIndicator.js.map +1 -1
  33. package/lib/commonjs/components/MessageMenu/MessageUserReactions.js +3 -1
  34. package/lib/commonjs/components/MessageMenu/MessageUserReactions.js.map +1 -1
  35. package/lib/commonjs/components/ThreadList/ThreadListItemSkeleton.js +1 -1
  36. package/lib/commonjs/components/ThreadList/ThreadListItemSkeleton.js.map +1 -1
  37. package/lib/commonjs/components/ThreadList/ThreadListUnreadBanner.js +2 -2
  38. package/lib/commonjs/components/ThreadList/ThreadListUnreadBanner.js.map +1 -1
  39. package/lib/commonjs/components/UIComponents/BottomSheetModal.js +4 -2
  40. package/lib/commonjs/components/UIComponents/BottomSheetModal.js.map +1 -1
  41. package/lib/commonjs/components/ui/Badge/ImgurBadge.js +1 -1
  42. package/lib/commonjs/components/ui/Badge/ImgurBadge.js.map +1 -1
  43. package/lib/commonjs/components/ui/GiphyChip.js +3 -3
  44. package/lib/commonjs/components/ui/GiphyChip.js.map +1 -1
  45. package/lib/commonjs/icons/{chevron-down.js → chevron-up.js} +4 -4
  46. package/lib/commonjs/icons/chevron-up.js.map +1 -0
  47. package/lib/commonjs/icons/command.js +1 -0
  48. package/lib/commonjs/icons/command.js.map +1 -1
  49. package/lib/commonjs/icons/file.js +1 -1
  50. package/lib/commonjs/icons/index.js +12 -0
  51. package/lib/commonjs/icons/index.js.map +1 -1
  52. package/lib/commonjs/icons/link.js +2 -1
  53. package/lib/commonjs/icons/link.js.map +1 -1
  54. package/lib/commonjs/icons/pause-fill.js +1 -1
  55. package/lib/commonjs/icons/pause-fill.js.map +1 -1
  56. package/lib/commonjs/icons/plus.js +5 -1
  57. package/lib/commonjs/icons/plus.js.map +1 -1
  58. package/lib/commonjs/icons/stop-fill.js +1 -1
  59. package/lib/commonjs/icons/stop-fill.js.map +1 -1
  60. package/lib/commonjs/icons/thread.js +1 -1
  61. package/lib/commonjs/icons/thread.js.map +1 -1
  62. package/lib/commonjs/icons/xmark.js +2 -2
  63. package/lib/commonjs/icons/xmark.js.map +1 -1
  64. package/lib/commonjs/theme/generated/dark/StreamTokens.android.js +34 -30
  65. package/lib/commonjs/theme/generated/dark/StreamTokens.android.js.map +1 -1
  66. package/lib/commonjs/theme/generated/dark/StreamTokens.ios.js +34 -30
  67. package/lib/commonjs/theme/generated/dark/StreamTokens.ios.js.map +1 -1
  68. package/lib/commonjs/theme/generated/dark/StreamTokens.web.js +34 -30
  69. package/lib/commonjs/theme/generated/dark/StreamTokens.web.js.map +1 -1
  70. package/lib/commonjs/theme/generated/light/StreamTokens.android.js +28 -24
  71. package/lib/commonjs/theme/generated/light/StreamTokens.android.js.map +1 -1
  72. package/lib/commonjs/theme/generated/light/StreamTokens.ios.js +28 -24
  73. package/lib/commonjs/theme/generated/light/StreamTokens.ios.js.map +1 -1
  74. package/lib/commonjs/theme/generated/light/StreamTokens.web.js +28 -24
  75. package/lib/commonjs/theme/generated/light/StreamTokens.web.js.map +1 -1
  76. package/lib/commonjs/version.json +1 -1
  77. package/lib/module/components/AITypingIndicatorView/AITypingIndicatorView.js +1 -1
  78. package/lib/module/components/AITypingIndicatorView/AITypingIndicatorView.js.map +1 -1
  79. package/lib/module/components/AttachmentPicker/components/AttachmentPickerContent.js +1 -1
  80. package/lib/module/components/AttachmentPicker/components/AttachmentPickerContent.js.map +1 -1
  81. package/lib/module/components/AttachmentPicker/components/AttachmentTypePickerButton.js +1 -1
  82. package/lib/module/components/AttachmentPicker/components/AttachmentTypePickerButton.js.map +1 -1
  83. package/lib/module/components/ChannelList/ChannelListHeaderErrorIndicator.js +1 -1
  84. package/lib/module/components/ChannelList/ChannelListHeaderErrorIndicator.js.map +1 -1
  85. package/lib/module/components/ChannelList/ChannelListHeaderNetworkDownIndicator.js +1 -1
  86. package/lib/module/components/ChannelList/ChannelListHeaderNetworkDownIndicator.js.map +1 -1
  87. package/lib/module/components/ChannelList/Skeleton.js +1 -1
  88. package/lib/module/components/ChannelList/Skeleton.js.map +1 -1
  89. package/lib/module/components/ChannelList/hooks/useChannelActionItems.js +1 -1
  90. package/lib/module/components/ChannelList/hooks/useChannelActionItems.js.map +1 -1
  91. package/lib/module/components/ChannelPreview/ChannelDetailsBottomSheet.js +17 -2
  92. package/lib/module/components/ChannelPreview/ChannelDetailsBottomSheet.js.map +1 -1
  93. package/lib/module/components/ChannelPreview/ChannelPreviewMessage.js +5 -4
  94. package/lib/module/components/ChannelPreview/ChannelPreviewMessage.js.map +1 -1
  95. package/lib/module/components/ChannelPreview/ChannelSwipableWrapper.js +28 -33
  96. package/lib/module/components/ChannelPreview/ChannelSwipableWrapper.js.map +1 -1
  97. package/lib/module/components/KeyboardCompatibleView/KeyboardCompatibleView.js +65 -36
  98. package/lib/module/components/KeyboardCompatibleView/KeyboardCompatibleView.js.map +1 -1
  99. package/lib/module/components/KeyboardCompatibleView/KeyboardControllerAvoidingView.js +1 -1
  100. package/lib/module/components/KeyboardCompatibleView/KeyboardControllerAvoidingView.js.map +1 -1
  101. package/lib/module/components/Message/utils/messageActions.js +1 -1
  102. package/lib/module/components/Message/utils/messageActions.js.map +1 -1
  103. package/lib/module/components/MessageInput/components/AttachmentPreview/VideoAttachmentUploadPreview.js +4 -4
  104. package/lib/module/components/MessageInput/components/AttachmentPreview/VideoAttachmentUploadPreview.js.map +1 -1
  105. package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecordingLockIndicator.js +2 -2
  106. package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecordingLockIndicator.js.map +1 -1
  107. package/lib/module/components/MessageList/NetworkDownIndicator.js +1 -1
  108. package/lib/module/components/MessageList/NetworkDownIndicator.js.map +1 -1
  109. package/lib/module/components/MessageMenu/MessageUserReactions.js +3 -1
  110. package/lib/module/components/MessageMenu/MessageUserReactions.js.map +1 -1
  111. package/lib/module/components/ThreadList/ThreadListItemSkeleton.js +1 -1
  112. package/lib/module/components/ThreadList/ThreadListItemSkeleton.js.map +1 -1
  113. package/lib/module/components/ThreadList/ThreadListUnreadBanner.js +2 -2
  114. package/lib/module/components/ThreadList/ThreadListUnreadBanner.js.map +1 -1
  115. package/lib/module/components/UIComponents/BottomSheetModal.js +4 -2
  116. package/lib/module/components/UIComponents/BottomSheetModal.js.map +1 -1
  117. package/lib/module/components/ui/Badge/ImgurBadge.js +1 -1
  118. package/lib/module/components/ui/Badge/ImgurBadge.js.map +1 -1
  119. package/lib/module/components/ui/GiphyChip.js +3 -3
  120. package/lib/module/components/ui/GiphyChip.js.map +1 -1
  121. package/lib/module/icons/{chevron-down.js → chevron-up.js} +4 -4
  122. package/lib/module/icons/chevron-up.js.map +1 -0
  123. package/lib/module/icons/command.js +1 -0
  124. package/lib/module/icons/command.js.map +1 -1
  125. package/lib/module/icons/file.js +1 -1
  126. package/lib/module/icons/index.js +12 -0
  127. package/lib/module/icons/index.js.map +1 -1
  128. package/lib/module/icons/link.js +2 -1
  129. package/lib/module/icons/link.js.map +1 -1
  130. package/lib/module/icons/pause-fill.js +1 -1
  131. package/lib/module/icons/pause-fill.js.map +1 -1
  132. package/lib/module/icons/plus.js +5 -1
  133. package/lib/module/icons/plus.js.map +1 -1
  134. package/lib/module/icons/stop-fill.js +1 -1
  135. package/lib/module/icons/stop-fill.js.map +1 -1
  136. package/lib/module/icons/thread.js +1 -1
  137. package/lib/module/icons/thread.js.map +1 -1
  138. package/lib/module/icons/xmark.js +2 -2
  139. package/lib/module/icons/xmark.js.map +1 -1
  140. package/lib/module/theme/generated/dark/StreamTokens.android.js +34 -30
  141. package/lib/module/theme/generated/dark/StreamTokens.android.js.map +1 -1
  142. package/lib/module/theme/generated/dark/StreamTokens.ios.js +34 -30
  143. package/lib/module/theme/generated/dark/StreamTokens.ios.js.map +1 -1
  144. package/lib/module/theme/generated/dark/StreamTokens.web.js +34 -30
  145. package/lib/module/theme/generated/dark/StreamTokens.web.js.map +1 -1
  146. package/lib/module/theme/generated/light/StreamTokens.android.js +28 -24
  147. package/lib/module/theme/generated/light/StreamTokens.android.js.map +1 -1
  148. package/lib/module/theme/generated/light/StreamTokens.ios.js +28 -24
  149. package/lib/module/theme/generated/light/StreamTokens.ios.js.map +1 -1
  150. package/lib/module/theme/generated/light/StreamTokens.web.js +28 -24
  151. package/lib/module/theme/generated/light/StreamTokens.web.js.map +1 -1
  152. package/lib/module/version.json +1 -1
  153. package/lib/typescript/components/ChannelPreview/ChannelDetailsBottomSheet.d.ts.map +1 -1
  154. package/lib/typescript/components/ChannelPreview/ChannelPreviewMessage.d.ts.map +1 -1
  155. package/lib/typescript/components/ChannelPreview/ChannelSwipableWrapper.d.ts.map +1 -1
  156. package/lib/typescript/components/KeyboardCompatibleView/KeyboardCompatibleView.d.ts +3 -2
  157. package/lib/typescript/components/KeyboardCompatibleView/KeyboardCompatibleView.d.ts.map +1 -1
  158. package/lib/typescript/components/KeyboardCompatibleView/KeyboardControllerAvoidingView.d.ts.map +1 -1
  159. package/lib/typescript/components/MessageMenu/MessageUserReactions.d.ts.map +1 -1
  160. package/lib/typescript/components/UIComponents/BottomSheetModal.d.ts.map +1 -1
  161. package/lib/typescript/icons/chevron-up.d.ts +4 -0
  162. package/lib/typescript/icons/chevron-up.d.ts.map +1 -0
  163. package/lib/typescript/icons/command.d.ts.map +1 -1
  164. package/lib/typescript/icons/index.d.ts +1 -0
  165. package/lib/typescript/icons/index.d.ts.map +1 -1
  166. package/lib/typescript/icons/link.d.ts.map +1 -1
  167. package/lib/typescript/icons/plus.d.ts.map +1 -1
  168. package/lib/typescript/icons/xmark.d.ts.map +1 -1
  169. package/lib/typescript/theme/generated/StreamTokens.types.d.ts +8 -4
  170. package/lib/typescript/theme/generated/StreamTokens.types.d.ts.map +1 -1
  171. package/lib/typescript/theme/generated/dark/StreamTokens.android.d.ts.map +1 -1
  172. package/lib/typescript/theme/generated/dark/StreamTokens.ios.d.ts.map +1 -1
  173. package/lib/typescript/theme/generated/dark/StreamTokens.web.d.ts.map +1 -1
  174. package/lib/typescript/theme/generated/light/StreamTokens.android.d.ts.map +1 -1
  175. package/lib/typescript/theme/generated/light/StreamTokens.ios.d.ts.map +1 -1
  176. package/lib/typescript/theme/generated/light/StreamTokens.web.d.ts.map +1 -1
  177. package/package.json +1 -1
  178. package/src/components/AITypingIndicatorView/AITypingIndicatorView.tsx +1 -1
  179. package/src/components/AttachmentPicker/components/AttachmentPickerContent.tsx +2 -2
  180. package/src/components/AttachmentPicker/components/AttachmentTypePickerButton.tsx +2 -2
  181. package/src/components/ChannelList/ChannelListHeaderErrorIndicator.tsx +1 -1
  182. package/src/components/ChannelList/ChannelListHeaderNetworkDownIndicator.tsx +1 -1
  183. package/src/components/ChannelList/Skeleton.tsx +1 -1
  184. package/src/components/ChannelList/hooks/__tests__/useChannelActionItems.test.tsx +2 -2
  185. package/src/components/ChannelList/hooks/useChannelActionItems.tsx +1 -1
  186. package/src/components/ChannelPreview/ChannelDetailsBottomSheet.tsx +15 -1
  187. package/src/components/ChannelPreview/ChannelPreviewMessage.tsx +7 -2
  188. package/src/components/ChannelPreview/ChannelSwipableWrapper.tsx +28 -31
  189. package/src/components/ChannelPreview/__tests__/ChannelSwipableWrapper.test.tsx +201 -0
  190. package/src/components/KeyboardCompatibleView/KeyboardCompatibleView.tsx +43 -25
  191. package/src/components/KeyboardCompatibleView/KeyboardControllerAvoidingView.tsx +1 -7
  192. package/src/components/Message/utils/messageActions.ts +1 -1
  193. package/src/components/MessageInput/__tests__/__snapshots__/AttachButton.test.js.snap +30 -21
  194. package/src/components/MessageInput/__tests__/__snapshots__/SendButton.test.js.snap +6 -2
  195. package/src/components/MessageInput/components/AttachmentPreview/VideoAttachmentUploadPreview.tsx +4 -4
  196. package/src/components/MessageInput/components/AudioRecorder/AudioRecordingLockIndicator.tsx +2 -2
  197. package/src/components/MessageList/NetworkDownIndicator.tsx +1 -1
  198. package/src/components/MessageMenu/MessageUserReactions.tsx +3 -1
  199. package/src/components/MessageMenu/__tests__/MessageUserReactions.test.tsx +9 -2
  200. package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap +10 -7
  201. package/src/components/ThreadList/ThreadListItemSkeleton.tsx +1 -1
  202. package/src/components/ThreadList/ThreadListUnreadBanner.tsx +2 -2
  203. package/src/components/UIComponents/BottomSheetModal.tsx +4 -2
  204. package/src/components/ui/Badge/ImgurBadge.tsx +1 -1
  205. package/src/components/ui/GiphyChip.tsx +3 -3
  206. package/src/icons/{chevron-down.tsx → chevron-up.tsx} +1 -1
  207. package/src/icons/command.tsx +1 -0
  208. package/src/icons/file.tsx +1 -1
  209. package/src/icons/index.ts +1 -0
  210. package/src/icons/link.tsx +2 -1
  211. package/src/icons/pause-fill.tsx +1 -1
  212. package/src/icons/plus.tsx +8 -2
  213. package/src/icons/stop-fill.tsx +1 -1
  214. package/src/icons/thread.tsx +1 -1
  215. package/src/icons/xmark.tsx +2 -8
  216. package/src/theme/generated/StreamTokens.types.ts +8 -4
  217. package/src/theme/generated/dark/StreamTokens.android.ts +34 -30
  218. package/src/theme/generated/dark/StreamTokens.ios.ts +34 -30
  219. package/src/theme/generated/dark/StreamTokens.web.ts +34 -30
  220. package/src/theme/generated/light/StreamTokens.android.ts +28 -24
  221. package/src/theme/generated/light/StreamTokens.ios.ts +28 -24
  222. package/src/theme/generated/light/StreamTokens.web.ts +28 -24
  223. package/src/version.json +1 -1
  224. package/lib/commonjs/icons/chevron-down.js.map +0 -1
  225. package/lib/module/icons/chevron-down.js.map +0 -1
  226. package/lib/typescript/icons/chevron-down.d.ts +0 -4
  227. package/lib/typescript/icons/chevron-down.d.ts.map +0 -1
@@ -0,0 +1,201 @@
1
+ import React from 'react';
2
+ import { Text } from 'react-native';
3
+
4
+ import { act, render } from '@testing-library/react-native';
5
+ import type { Channel } from 'stream-chat';
6
+
7
+ import type { ChannelActionItem } from '../../ChannelList/hooks/useChannelActionItems';
8
+ import * as ChannelActionItemsModule from '../../ChannelList/hooks/useChannelActionItems';
9
+ import * as ChannelActionsModule from '../../ChannelList/hooks/useChannelActions';
10
+ import { ChannelSwipableWrapper } from '../ChannelSwipableWrapper';
11
+ import * as UseIsChannelMutedModule from '../hooks/useIsChannelMuted';
12
+
13
+ const rightActionsProbe = {
14
+ items: [] as Array<{ action: () => void; id: string }>,
15
+ };
16
+
17
+ const mockSwipableWrapper = jest.fn(
18
+ ({
19
+ children,
20
+ swipableProps,
21
+ }: React.PropsWithChildren<{
22
+ swipableProps?: { renderRightActions?: (...args: never[]) => void };
23
+ }>) => {
24
+ const rightActions = swipableProps?.renderRightActions?.({} as never, {} as never);
25
+ return (
26
+ <>
27
+ {children}
28
+ {rightActions}
29
+ </>
30
+ );
31
+ },
32
+ );
33
+
34
+ jest.mock('../../../contexts', () => ({
35
+ useTheme: () => ({
36
+ theme: {
37
+ semantics: {
38
+ accentPrimary: '#00f',
39
+ backgroundCoreSurfaceDefault: '#fff',
40
+ textOnAccent: '#000',
41
+ textPrimary: '#111',
42
+ },
43
+ },
44
+ }),
45
+ }));
46
+
47
+ jest.mock('../../../contexts/swipeableContext/SwipeRegistryContext', () => ({
48
+ useSwipeRegistryContext: () => ({
49
+ closeAll: jest.fn(),
50
+ }),
51
+ }));
52
+
53
+ jest.mock('../../UIComponents', () => ({
54
+ BottomSheetModal: ({ children }: React.PropsWithChildren) => <>{children}</>,
55
+ RightActions: ({ items }: { items: Array<{ action: () => void; id: string }> }) => {
56
+ rightActionsProbe.items = items;
57
+ return null;
58
+ },
59
+ SwipableWrapper: (...args: unknown[]) => mockSwipableWrapper(...args),
60
+ }));
61
+
62
+ describe('ChannelSwipableWrapper', () => {
63
+ const channel = { cid: 'messaging:test-channel', id: 'test-channel' } as Channel;
64
+
65
+ beforeEach(() => {
66
+ jest.clearAllMocks();
67
+ rightActionsProbe.items = [];
68
+ });
69
+
70
+ it('uses channel mute for direct-channel swipe actions and keeps mute user in the sheet', () => {
71
+ const muteChannel = jest.fn();
72
+ const unmuteChannel = jest.fn();
73
+ const customBottomSheet = jest.fn(() => null);
74
+ const items: ChannelActionItem[] = [
75
+ {
76
+ Icon: () => null,
77
+ action: jest.fn(),
78
+ id: 'mute',
79
+ label: 'Mute User',
80
+ placement: 'sheet',
81
+ type: 'standard',
82
+ },
83
+ {
84
+ Icon: () => null,
85
+ action: jest.fn(),
86
+ id: 'archive',
87
+ label: 'Archive Chat',
88
+ placement: 'sheet',
89
+ type: 'standard',
90
+ },
91
+ ];
92
+
93
+ jest.spyOn(ChannelActionsModule, 'useChannelActions').mockReturnValue({
94
+ archive: jest.fn(),
95
+ blockUser: jest.fn(),
96
+ deleteChannel: jest.fn(),
97
+ leave: jest.fn(),
98
+ muteChannel,
99
+ muteUser: jest.fn(),
100
+ pin: jest.fn(),
101
+ unarchive: jest.fn(),
102
+ unblockUser: jest.fn(),
103
+ unmuteChannel,
104
+ unmuteUser: jest.fn(),
105
+ unpin: jest.fn(),
106
+ });
107
+ jest.spyOn(ChannelActionItemsModule, 'useChannelActionItems').mockReturnValue(items);
108
+ jest.spyOn(UseIsChannelMutedModule, 'useIsChannelMuted').mockReturnValue({
109
+ createdAt: null,
110
+ expiresAt: null,
111
+ muted: false,
112
+ });
113
+
114
+ render(
115
+ <ChannelSwipableWrapper channel={channel} ChannelDetailsBottomSheet={customBottomSheet}>
116
+ <Text>child</Text>
117
+ </ChannelSwipableWrapper>,
118
+ );
119
+
120
+ expect(customBottomSheet).toHaveBeenCalledWith(
121
+ expect.objectContaining({
122
+ channel,
123
+ items,
124
+ }),
125
+ undefined,
126
+ );
127
+ expect(rightActionsProbe.items.map((item) => item.id)).toEqual(['openSheet', 'mute']);
128
+
129
+ act(() => {
130
+ rightActionsProbe.items[1].action();
131
+ });
132
+
133
+ expect(muteChannel).toHaveBeenCalledTimes(1);
134
+ expect(unmuteChannel).not.toHaveBeenCalled();
135
+ });
136
+
137
+ it('removes mute group from the sheet while keeping mute as the quick swipe action', () => {
138
+ const muteChannel = jest.fn();
139
+ const customBottomSheet = jest.fn(() => null);
140
+ const muteItem = {
141
+ Icon: () => null,
142
+ action: jest.fn(),
143
+ id: 'mute',
144
+ label: 'Mute Group',
145
+ placement: 'swipe',
146
+ type: 'standard',
147
+ } as const satisfies ChannelActionItem;
148
+ const archiveItem = {
149
+ Icon: () => null,
150
+ action: jest.fn(),
151
+ id: 'archive',
152
+ label: 'Archive Group',
153
+ placement: 'both',
154
+ type: 'standard',
155
+ } as const satisfies ChannelActionItem;
156
+
157
+ jest.spyOn(ChannelActionsModule, 'useChannelActions').mockReturnValue({
158
+ archive: jest.fn(),
159
+ blockUser: jest.fn(),
160
+ deleteChannel: jest.fn(),
161
+ leave: jest.fn(),
162
+ muteChannel,
163
+ muteUser: jest.fn(),
164
+ pin: jest.fn(),
165
+ unarchive: jest.fn(),
166
+ unblockUser: jest.fn(),
167
+ unmuteChannel: jest.fn(),
168
+ unmuteUser: jest.fn(),
169
+ unpin: jest.fn(),
170
+ });
171
+ jest
172
+ .spyOn(ChannelActionItemsModule, 'useChannelActionItems')
173
+ .mockReturnValue([muteItem, archiveItem]);
174
+ jest.spyOn(UseIsChannelMutedModule, 'useIsChannelMuted').mockReturnValue({
175
+ createdAt: null,
176
+ expiresAt: null,
177
+ muted: false,
178
+ });
179
+
180
+ render(
181
+ <ChannelSwipableWrapper channel={channel} ChannelDetailsBottomSheet={customBottomSheet}>
182
+ <Text>child</Text>
183
+ </ChannelSwipableWrapper>,
184
+ );
185
+
186
+ expect(customBottomSheet).toHaveBeenCalledWith(
187
+ expect.objectContaining({
188
+ channel,
189
+ items: [archiveItem],
190
+ }),
191
+ undefined,
192
+ );
193
+ expect(rightActionsProbe.items.map((item) => item.id)).toEqual(['openSheet', 'mute']);
194
+
195
+ act(() => {
196
+ rightActionsProbe.items[1].action();
197
+ });
198
+
199
+ expect(muteChannel).toHaveBeenCalledTimes(1);
200
+ });
201
+ });
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import {
3
+ AccessibilityInfo,
3
4
  AppState,
4
5
  AppStateStatus,
5
6
  Dimensions,
@@ -39,7 +40,7 @@ export class KeyboardCompatibleView extends React.Component<
39
40
  KeyboardAvoidingViewProps,
40
41
  'behavior' | 'enabled' | 'keyboardVerticalOffset'
41
42
  > = {
42
- behavior: Platform.OS === 'ios' ? 'padding' : 'position',
43
+ behavior: 'padding',
43
44
  enabled: true,
44
45
  keyboardVerticalOffset: Platform.OS === 'ios' ? 86.5 : -300, // default MessageComposer height
45
46
  };
@@ -62,35 +63,40 @@ export class KeyboardCompatibleView extends React.Component<
62
63
  this.viewRef = React.createRef();
63
64
  }
64
65
 
65
- _relativeKeyboardHeight(keyboardFrame: KeyboardMetrics) {
66
+ async _relativeKeyboardHeight(keyboardFrame: KeyboardMetrics): Promise<number> {
66
67
  const frame = this._frame;
67
- /**
68
- * With iOS 14 & Reduce Motion > Prefer Cross-Fade Transitions enabled, the keyboard position
69
- * height is reported differently (0 instead of Y position value) which caused the view to take full height
70
- * of the screen.
71
- */
72
- if (!frame || !keyboardFrame || keyboardFrame.screenY === 0) {
68
+ if (!frame || !keyboardFrame) {
69
+ return 0;
70
+ }
71
+
72
+ if (
73
+ Platform.OS === 'ios' &&
74
+ keyboardFrame.screenY === 0 &&
75
+ (await AccessibilityInfo.prefersCrossFadeTransitions())
76
+ ) {
73
77
  return 0;
74
78
  }
75
79
 
76
80
  const keyboardY = keyboardFrame.screenY - (this.props.keyboardVerticalOffset ?? 0);
77
- const relativeHeight = frame.y + frame.height - keyboardY;
78
81
 
79
- /**
80
- * When the StatusBar is translucent there is an issue
81
- * where the relative keyboard height is returned incorrectly
82
- * instead of 0 when closed.
83
- */
82
+ if (this.props.behavior === 'height') {
83
+ return Math.max(this.state.bottom + frame.y + frame.height - keyboardY, 0);
84
+ }
85
+
86
+ // Calculate the displacement needed for the view such that it
87
+ // no longer overlaps with the keyboard
88
+ const relativeHeight = Math.max(frame.y + frame.height - keyboardY, 0);
89
+
84
90
  if (Platform.OS === 'android') {
85
91
  const barHeights = Dimensions.get('screen').height - Dimensions.get('window').height;
86
- if (relativeHeight <= Math.max(barHeights, StatusBar.currentHeight ?? 0)) {
92
+ const systemInsetFloor = Math.max(barHeights, StatusBar.currentHeight ?? 0);
93
+
94
+ if (relativeHeight <= systemInsetFloor) {
87
95
  return 0;
88
96
  }
89
97
  }
90
98
 
91
- // Calculate the displacement needed for the view such that it
92
- // no longer overlaps with the keyboard
93
- return Math.max(relativeHeight, 0);
99
+ return relativeHeight;
94
100
  }
95
101
 
96
102
  _onKeyboardChange: KeyboardEventListener = (event) => {
@@ -98,7 +104,12 @@ export class KeyboardCompatibleView extends React.Component<
98
104
  this._updateBottomIfNecessary();
99
105
  };
100
106
 
101
- _onLayout: (event: LayoutChangeEvent) => void = (event) => {
107
+ _onKeyboardHide: KeyboardEventListener = () => {
108
+ this._keyboardEvent = null;
109
+ this._updateBottomIfNecessary();
110
+ };
111
+
112
+ _onLayout: (event: LayoutChangeEvent) => void = async (event) => {
102
113
  event.persist();
103
114
 
104
115
  const oldFrame = this._frame;
@@ -110,7 +121,7 @@ export class KeyboardCompatibleView extends React.Component<
110
121
 
111
122
  // update bottom height for the first time or when the height is changed
112
123
  if (!oldFrame || oldFrame.height !== this._frame.height) {
113
- this._updateBottomIfNecessary();
124
+ await this._updateBottomIfNecessary();
114
125
  }
115
126
 
116
127
  if (this.props.onLayout) {
@@ -127,14 +138,14 @@ export class KeyboardCompatibleView extends React.Component<
127
138
  }
128
139
  };
129
140
 
130
- _updateBottomIfNecessary = () => {
141
+ _updateBottomIfNecessary = async () => {
131
142
  if (this._keyboardEvent == null) {
132
143
  this._setBottom(0);
133
144
  return;
134
145
  }
135
146
 
136
147
  const { duration, easing, endCoordinates } = this._keyboardEvent;
137
- const height = this._relativeKeyboardHeight(endCoordinates);
148
+ const height = await this._relativeKeyboardHeight(endCoordinates);
138
149
 
139
150
  if (this._bottom === height) {
140
151
  return;
@@ -142,7 +153,8 @@ export class KeyboardCompatibleView extends React.Component<
142
153
 
143
154
  this._setBottom(height);
144
155
 
145
- if (duration && easing) {
156
+ const enabled = this.props.enabled ?? true;
157
+ if (enabled && duration && easing) {
146
158
  LayoutAnimation.configureNext({
147
159
  // We have to pass the duration equal to minimal accepted duration defined here: RCTLayoutAnimation.m
148
160
  duration: duration > 10 ? duration : 10,
@@ -169,11 +181,12 @@ export class KeyboardCompatibleView extends React.Component<
169
181
  setKeyboardListeners = () => {
170
182
  if (Platform.OS === 'ios') {
171
183
  this._subscriptions = [
172
- Keyboard.addListener('keyboardWillChangeFrame', this._onKeyboardChange),
184
+ Keyboard.addListener('keyboardWillHide', this._onKeyboardHide),
185
+ Keyboard.addListener('keyboardWillShow', this._onKeyboardChange),
173
186
  ];
174
187
  } else {
175
188
  this._subscriptions = [
176
- Keyboard.addListener('keyboardDidHide', this._onKeyboardChange),
189
+ Keyboard.addListener('keyboardDidHide', this._onKeyboardHide),
177
190
  Keyboard.addListener('keyboardDidShow', this._onKeyboardChange),
178
191
  ];
179
192
  }
@@ -218,6 +231,11 @@ export class KeyboardCompatibleView extends React.Component<
218
231
  }
219
232
 
220
233
  componentDidMount() {
234
+ if (!Keyboard.isVisible()) {
235
+ this._keyboardEvent = null;
236
+ this._setBottom(0);
237
+ }
238
+
221
239
  this._appStateSubscription = AppState.addEventListener('change', this._handleAppStateChange);
222
240
  this.setKeyboardListeners();
223
241
  }
@@ -2,7 +2,6 @@ import React, { useEffect } from 'react';
2
2
 
3
3
  import {
4
4
  Keyboard,
5
- Platform,
6
5
  KeyboardAvoidingViewProps as ReactNativeKeyboardAvoidingViewProps,
7
6
  } from 'react-native';
8
7
 
@@ -51,12 +50,7 @@ export const KeyboardCompatibleView = (props: KeyboardCompatibleViewProps) => {
51
50
  </KeyboardProvider>
52
51
  );
53
52
  }
54
- const compatibleBehavior =
55
- behavior === 'translate-with-padding'
56
- ? Platform.OS === 'ios'
57
- ? 'padding'
58
- : 'position'
59
- : behavior;
53
+ const compatibleBehavior = behavior === 'translate-with-padding' ? 'padding' : behavior;
60
54
 
61
55
  return (
62
56
  <KeyboardCompatibleViewDefault behavior={compatibleBehavior} {...rest}>
@@ -90,7 +90,7 @@ export const messageActions = ({
90
90
  actions.push(copyMessage);
91
91
  }
92
92
 
93
- if (ownCapabilities.readEvents && !error && !isThreadMessage) {
93
+ if (ownCapabilities.readEvents && !error && !isThreadMessage && !isMyMessage) {
94
94
  actions.push(markUnread);
95
95
  }
96
96
 
@@ -87,6 +87,7 @@ exports[`AttachButton should call handleAttachButtonPress when the button is cli
87
87
  align="xMidYMid"
88
88
  bbHeight={20}
89
89
  bbWidth={20}
90
+ fill="none"
90
91
  focusable={false}
91
92
  height={20}
92
93
  meetOrSlice={0}
@@ -112,14 +113,10 @@ exports[`AttachButton should call handleAttachButtonPress when the button is cli
112
113
  width={20}
113
114
  >
114
115
  <RNSVGGroup
115
- fill={
116
- {
117
- "payload": 4278190080,
118
- "type": 0,
119
- }
120
- }
116
+ fill={null}
121
117
  propList={
122
118
  [
119
+ "fill",
123
120
  "stroke",
124
121
  "strokeWidth",
125
122
  ]
@@ -144,6 +141,8 @@ exports[`AttachButton should call handleAttachButtonPress when the button is cli
144
141
  [
145
142
  "stroke",
146
143
  "strokeWidth",
144
+ "strokeLinecap",
145
+ "strokeLinejoin",
147
146
  ]
148
147
  }
149
148
  stroke={
@@ -152,6 +151,8 @@ exports[`AttachButton should call handleAttachButtonPress when the button is cli
152
151
  "type": 0,
153
152
  }
154
153
  }
154
+ strokeLinecap={1}
155
+ strokeLinejoin={1}
155
156
  strokeWidth={1.5}
156
157
  />
157
158
  </RNSVGGroup>
@@ -613,7 +614,7 @@ exports[`AttachButton should call handleAttachButtonPress when the button is cli
613
614
  }
614
615
  strokeLinecap={1}
615
616
  strokeLinejoin={1}
616
- strokeWidth={1.2}
617
+ strokeWidth={1.5}
617
618
  />
618
619
  </RNSVGGroup>
619
620
  </RNSVGSvgView>
@@ -748,6 +749,7 @@ exports[`AttachButton should call handleAttachButtonPress when the button is cli
748
749
  [
749
750
  "stroke",
750
751
  "strokeWidth",
752
+ "strokeLinecap",
751
753
  "strokeLinejoin",
752
754
  ]
753
755
  }
@@ -757,6 +759,7 @@ exports[`AttachButton should call handleAttachButtonPress when the button is cli
757
759
  "type": 0,
758
760
  }
759
761
  }
762
+ strokeLinecap={1}
760
763
  strokeLinejoin={1}
761
764
  strokeWidth={1.5}
762
765
  />
@@ -982,6 +985,7 @@ exports[`AttachButton should render a enabled AttachButton 1`] = `
982
985
  align="xMidYMid"
983
986
  bbHeight={20}
984
987
  bbWidth={20}
988
+ fill="none"
985
989
  focusable={false}
986
990
  height={20}
987
991
  meetOrSlice={0}
@@ -1007,14 +1011,10 @@ exports[`AttachButton should render a enabled AttachButton 1`] = `
1007
1011
  width={20}
1008
1012
  >
1009
1013
  <RNSVGGroup
1010
- fill={
1011
- {
1012
- "payload": 4278190080,
1013
- "type": 0,
1014
- }
1015
- }
1014
+ fill={null}
1016
1015
  propList={
1017
1016
  [
1017
+ "fill",
1018
1018
  "stroke",
1019
1019
  "strokeWidth",
1020
1020
  ]
@@ -1039,6 +1039,8 @@ exports[`AttachButton should render a enabled AttachButton 1`] = `
1039
1039
  [
1040
1040
  "stroke",
1041
1041
  "strokeWidth",
1042
+ "strokeLinecap",
1043
+ "strokeLinejoin",
1042
1044
  ]
1043
1045
  }
1044
1046
  stroke={
@@ -1047,6 +1049,8 @@ exports[`AttachButton should render a enabled AttachButton 1`] = `
1047
1049
  "type": 0,
1048
1050
  }
1049
1051
  }
1052
+ strokeLinecap={1}
1053
+ strokeLinejoin={1}
1050
1054
  strokeWidth={1.5}
1051
1055
  />
1052
1056
  </RNSVGGroup>
@@ -1508,7 +1512,7 @@ exports[`AttachButton should render a enabled AttachButton 1`] = `
1508
1512
  }
1509
1513
  strokeLinecap={1}
1510
1514
  strokeLinejoin={1}
1511
- strokeWidth={1.2}
1515
+ strokeWidth={1.5}
1512
1516
  />
1513
1517
  </RNSVGGroup>
1514
1518
  </RNSVGSvgView>
@@ -1643,6 +1647,7 @@ exports[`AttachButton should render a enabled AttachButton 1`] = `
1643
1647
  [
1644
1648
  "stroke",
1645
1649
  "strokeWidth",
1650
+ "strokeLinecap",
1646
1651
  "strokeLinejoin",
1647
1652
  ]
1648
1653
  }
@@ -1652,6 +1657,7 @@ exports[`AttachButton should render a enabled AttachButton 1`] = `
1652
1657
  "type": 0,
1653
1658
  }
1654
1659
  }
1660
+ strokeLinecap={1}
1655
1661
  strokeLinejoin={1}
1656
1662
  strokeWidth={1.5}
1657
1663
  />
@@ -1877,6 +1883,7 @@ exports[`AttachButton should render an disabled AttachButton 1`] = `
1877
1883
  align="xMidYMid"
1878
1884
  bbHeight={20}
1879
1885
  bbWidth={20}
1886
+ fill="none"
1880
1887
  focusable={false}
1881
1888
  height={20}
1882
1889
  meetOrSlice={0}
@@ -1902,14 +1909,10 @@ exports[`AttachButton should render an disabled AttachButton 1`] = `
1902
1909
  width={20}
1903
1910
  >
1904
1911
  <RNSVGGroup
1905
- fill={
1906
- {
1907
- "payload": 4278190080,
1908
- "type": 0,
1909
- }
1910
- }
1912
+ fill={null}
1911
1913
  propList={
1912
1914
  [
1915
+ "fill",
1913
1916
  "stroke",
1914
1917
  "strokeWidth",
1915
1918
  ]
@@ -1934,6 +1937,8 @@ exports[`AttachButton should render an disabled AttachButton 1`] = `
1934
1937
  [
1935
1938
  "stroke",
1936
1939
  "strokeWidth",
1940
+ "strokeLinecap",
1941
+ "strokeLinejoin",
1937
1942
  ]
1938
1943
  }
1939
1944
  stroke={
@@ -1942,6 +1947,8 @@ exports[`AttachButton should render an disabled AttachButton 1`] = `
1942
1947
  "type": 0,
1943
1948
  }
1944
1949
  }
1950
+ strokeLinecap={1}
1951
+ strokeLinejoin={1}
1945
1952
  strokeWidth={1.5}
1946
1953
  />
1947
1954
  </RNSVGGroup>
@@ -2403,7 +2410,7 @@ exports[`AttachButton should render an disabled AttachButton 1`] = `
2403
2410
  }
2404
2411
  strokeLinecap={1}
2405
2412
  strokeLinejoin={1}
2406
- strokeWidth={1.2}
2413
+ strokeWidth={1.5}
2407
2414
  />
2408
2415
  </RNSVGGroup>
2409
2416
  </RNSVGSvgView>
@@ -2538,6 +2545,7 @@ exports[`AttachButton should render an disabled AttachButton 1`] = `
2538
2545
  [
2539
2546
  "stroke",
2540
2547
  "strokeWidth",
2548
+ "strokeLinecap",
2541
2549
  "strokeLinejoin",
2542
2550
  ]
2543
2551
  }
@@ -2547,6 +2555,7 @@ exports[`AttachButton should render an disabled AttachButton 1`] = `
2547
2555
  "type": 0,
2548
2556
  }
2549
2557
  }
2558
+ strokeLinecap={1}
2550
2559
  strokeLinejoin={1}
2551
2560
  strokeWidth={1.5}
2552
2561
  />
@@ -603,7 +603,7 @@ exports[`SendButton should render a SendButton 1`] = `
603
603
  }
604
604
  strokeLinecap={1}
605
605
  strokeLinejoin={1}
606
- strokeWidth={1.2}
606
+ strokeWidth={1.5}
607
607
  />
608
608
  </RNSVGGroup>
609
609
  </RNSVGSvgView>
@@ -738,6 +738,7 @@ exports[`SendButton should render a SendButton 1`] = `
738
738
  [
739
739
  "stroke",
740
740
  "strokeWidth",
741
+ "strokeLinecap",
741
742
  "strokeLinejoin",
742
743
  ]
743
744
  }
@@ -747,6 +748,7 @@ exports[`SendButton should render a SendButton 1`] = `
747
748
  "type": 0,
748
749
  }
749
750
  }
751
+ strokeLinecap={1}
750
752
  strokeLinejoin={1}
751
753
  strokeWidth={1.5}
752
754
  />
@@ -1488,7 +1490,7 @@ exports[`SendButton should render a disabled SendButton 1`] = `
1488
1490
  }
1489
1491
  strokeLinecap={1}
1490
1492
  strokeLinejoin={1}
1491
- strokeWidth={1.2}
1493
+ strokeWidth={1.5}
1492
1494
  />
1493
1495
  </RNSVGGroup>
1494
1496
  </RNSVGSvgView>
@@ -1623,6 +1625,7 @@ exports[`SendButton should render a disabled SendButton 1`] = `
1623
1625
  [
1624
1626
  "stroke",
1625
1627
  "strokeWidth",
1628
+ "strokeLinecap",
1626
1629
  "strokeLinejoin",
1627
1630
  ]
1628
1631
  }
@@ -1632,6 +1635,7 @@ exports[`SendButton should render a disabled SendButton 1`] = `
1632
1635
  "type": 0,
1633
1636
  }
1634
1637
  }
1638
+ strokeLinecap={1}
1635
1639
  strokeLinejoin={1}
1636
1640
  strokeWidth={1.5}
1637
1641
  />
@@ -75,7 +75,7 @@ export const VideoAttachmentMetadataPill = ({
75
75
 
76
76
  return durationLabel ? (
77
77
  <View style={styles.durationContainer}>
78
- <Recorder height={12} width={12} pathFill={semantics.textInverse} />
78
+ <Recorder height={12} width={12} pathFill={semantics.textOnInverse} />
79
79
  <Text style={styles.durationText}>{durationLabel}</Text>
80
80
  </View>
81
81
  ) : null;
@@ -91,7 +91,7 @@ const useStyles = () => {
91
91
  },
92
92
  } = useTheme();
93
93
 
94
- const { badgeBgInverse, textInverse } = semantics;
94
+ const { badgeBgInverse, textOnInverse } = semantics;
95
95
 
96
96
  return useMemo(
97
97
  () =>
@@ -111,11 +111,11 @@ const useStyles = () => {
111
111
  durationText: {
112
112
  fontSize: primitives.typographyFontSizeXxs,
113
113
  fontWeight: primitives.typographyFontWeightBold,
114
- color: textInverse,
114
+ color: textOnInverse,
115
115
  marginLeft: primitives.spacingXxs,
116
116
  ...durationText,
117
117
  },
118
118
  }),
119
- [badgeBgInverse, textInverse, durationContainer, durationText],
119
+ [badgeBgInverse, textOnInverse, durationContainer, durationText],
120
120
  );
121
121
  };
@@ -4,7 +4,7 @@ import { StyleProp, StyleSheet, ViewStyle } from 'react-native';
4
4
  import Animated, { LinearTransition } from 'react-native-reanimated';
5
5
 
6
6
  import { useTheme } from '../../../../contexts/themeContext/ThemeContext';
7
- import { ChevronTop } from '../../../../icons/chevron-down';
7
+ import { ChevronUp } from '../../../../icons/chevron-up';
8
8
  import { Lock } from '../../../../icons/lock';
9
9
  import { Unlock } from '../../../../icons/unlock';
10
10
  import { AudioRecorderManagerState } from '../../../../state-store/audio-recorder-manager';
@@ -69,7 +69,7 @@ export const AudioRecordingLockIndicator = ({
69
69
  <Unlock stroke={semantics.textPrimary} height={20} width={20} {...lockIcon} />
70
70
  )}
71
71
  {!micLocked && (
72
- <ChevronTop stroke={semantics.textPrimary} height={20} width={20} {...arrowUpIcon} />
72
+ <ChevronUp stroke={semantics.textPrimary} height={20} width={20} {...arrowUpIcon} />
73
73
  )}
74
74
  </Animated.View>
75
75
  );
@@ -52,7 +52,7 @@ const useStyles = () => {
52
52
  right: 0,
53
53
  top: 0,
54
54
  justifyContent: 'center',
55
- backgroundColor: semantics.backgroundCoreSurface,
55
+ backgroundColor: semantics.backgroundCoreSurfaceDefault,
56
56
  ...errorNotification,
57
57
  },
58
58
  errorText: {