@planningcenter/chat-react-native 4.4.1-qa-staging.16 → 4.4.1-qa-staging.18

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 (173) hide show
  1. package/build/components/conversations/archived_results_footer.d.ts +6 -0
  2. package/build/components/conversations/archived_results_footer.d.ts.map +1 -0
  3. package/build/components/conversations/archived_results_footer.js +51 -0
  4. package/build/components/conversations/archived_results_footer.js.map +1 -0
  5. package/build/components/conversations/conversation_actions.d.ts.map +1 -1
  6. package/build/components/conversations/conversation_actions.js +241 -206
  7. package/build/components/conversations/conversation_actions.js.map +1 -1
  8. package/build/components/conversations/conversation_preview.d.ts.map +1 -1
  9. package/build/components/conversations/conversation_preview.js +99 -93
  10. package/build/components/conversations/conversation_preview.js.map +1 -1
  11. package/build/components/conversations/conversations.d.ts.map +1 -1
  12. package/build/components/conversations/conversations.js +65 -40
  13. package/build/components/conversations/conversations.js.map +1 -1
  14. package/build/components/conversations/conversations_blank_state.d.ts.map +1 -1
  15. package/build/components/conversations/conversations_blank_state.js +55 -12
  16. package/build/components/conversations/conversations_blank_state.js.map +1 -1
  17. package/build/components/conversations/filtered_results_footer.d.ts +2 -0
  18. package/build/components/conversations/filtered_results_footer.d.ts.map +1 -0
  19. package/build/components/conversations/filtered_results_footer.js +77 -0
  20. package/build/components/conversations/filtered_results_footer.js.map +1 -0
  21. package/build/components/display/filter_dropdown.d.ts +2 -1
  22. package/build/components/display/filter_dropdown.d.ts.map +1 -1
  23. package/build/components/display/filter_dropdown.js +63 -58
  24. package/build/components/display/filter_dropdown.js.map +1 -1
  25. package/build/components/display/icon_tile.d.ts +12 -0
  26. package/build/components/display/icon_tile.d.ts.map +1 -0
  27. package/build/components/display/icon_tile.js +109 -0
  28. package/build/components/display/icon_tile.js.map +1 -0
  29. package/build/components/display/index.d.ts +1 -0
  30. package/build/components/display/index.d.ts.map +1 -1
  31. package/build/components/display/index.js +1 -0
  32. package/build/components/display/index.js.map +1 -1
  33. package/build/contexts/conversations_context.d.ts.map +1 -1
  34. package/build/contexts/conversations_context.js +21 -18
  35. package/build/contexts/conversations_context.js.map +1 -1
  36. package/build/hooks/index.d.ts +2 -0
  37. package/build/hooks/index.d.ts.map +1 -1
  38. package/build/hooks/index.js +2 -0
  39. package/build/hooks/index.js.map +1 -1
  40. package/build/hooks/use_can_browse_archived_conversations.d.ts +2 -0
  41. package/build/hooks/use_can_browse_archived_conversations.d.ts.map +1 -0
  42. package/build/hooks/use_can_browse_archived_conversations.js +29 -0
  43. package/build/hooks/use_can_browse_archived_conversations.js.map +1 -0
  44. package/build/hooks/use_clear_conversation_filters.d.ts +2 -0
  45. package/build/hooks/use_clear_conversation_filters.d.ts.map +1 -0
  46. package/build/hooks/use_clear_conversation_filters.js +25 -0
  47. package/build/hooks/use_clear_conversation_filters.js.map +1 -0
  48. package/build/hooks/use_conversation.d.ts.map +1 -1
  49. package/build/hooks/use_conversation.js +32 -24
  50. package/build/hooks/use_conversation.js.map +1 -1
  51. package/build/hooks/use_current_person.d.ts.map +1 -1
  52. package/build/hooks/use_current_person.js +1 -1
  53. package/build/hooks/use_current_person.js.map +1 -1
  54. package/build/hooks/use_jolt.d.ts.map +1 -1
  55. package/build/hooks/use_jolt.js +29 -8
  56. package/build/hooks/use_jolt.js.map +1 -1
  57. package/build/hooks/use_manual_archiving_enabled.d.ts +2 -0
  58. package/build/hooks/use_manual_archiving_enabled.d.ts.map +1 -0
  59. package/build/hooks/use_manual_archiving_enabled.js +18 -0
  60. package/build/hooks/use_manual_archiving_enabled.js.map +1 -0
  61. package/build/hooks/use_reduce_motion.d.ts.map +1 -1
  62. package/build/hooks/use_reduce_motion.js +2 -1
  63. package/build/hooks/use_reduce_motion.js.map +1 -1
  64. package/build/screens/conversation_details_screen.d.ts.map +1 -1
  65. package/build/screens/conversation_details_screen.js +2 -1
  66. package/build/screens/conversation_details_screen.js.map +1 -1
  67. package/build/screens/conversation_filters/components/conversation_filters.d.ts.map +1 -1
  68. package/build/screens/conversation_filters/components/conversation_filters.js +88 -18
  69. package/build/screens/conversation_filters/components/conversation_filters.js.map +1 -1
  70. package/build/screens/conversation_filters/components/rows.d.ts +9 -0
  71. package/build/screens/conversation_filters/components/rows.d.ts.map +1 -1
  72. package/build/screens/conversation_filters/components/rows.js +92 -1
  73. package/build/screens/conversation_filters/components/rows.js.map +1 -1
  74. package/build/screens/conversation_filters/context/conversation_filter_context.d.ts.map +1 -1
  75. package/build/screens/conversation_filters/context/conversation_filter_context.js +8 -4
  76. package/build/screens/conversation_filters/context/conversation_filter_context.js.map +1 -1
  77. package/build/screens/conversation_filters/filter_types.d.ts +1 -0
  78. package/build/screens/conversation_filters/filter_types.d.ts.map +1 -1
  79. package/build/screens/conversation_filters/filter_types.js +1 -0
  80. package/build/screens/conversation_filters/filter_types.js.map +1 -1
  81. package/build/screens/conversation_filters/screen_props.d.ts +1 -0
  82. package/build/screens/conversation_filters/screen_props.d.ts.map +1 -1
  83. package/build/screens/conversation_filters/screen_props.js.map +1 -1
  84. package/build/screens/conversation_filters_screen.d.ts +1 -0
  85. package/build/screens/conversation_filters_screen.d.ts.map +1 -1
  86. package/build/screens/conversation_filters_screen.js +79 -48
  87. package/build/screens/conversation_filters_screen.js.map +1 -1
  88. package/build/screens/conversations/components/filter_dropdown_list_header_component.d.ts +2 -0
  89. package/build/screens/conversations/components/filter_dropdown_list_header_component.d.ts.map +1 -0
  90. package/build/screens/conversations/components/filter_dropdown_list_header_component.js +587 -0
  91. package/build/screens/conversations/components/filter_dropdown_list_header_component.js.map +1 -0
  92. package/build/screens/conversations/components/list_header_component.d.ts.map +1 -1
  93. package/build/screens/conversations/components/list_header_component.js +95 -90
  94. package/build/screens/conversations/components/list_header_component.js.map +1 -1
  95. package/build/screens/conversations/components/search_list_header_component.d.ts.map +1 -1
  96. package/build/screens/conversations/components/search_list_header_component.js +100 -95
  97. package/build/screens/conversations/components/search_list_header_component.js.map +1 -1
  98. package/build/screens/conversations/conversations_screen.d.ts +1 -0
  99. package/build/screens/conversations/conversations_screen.d.ts.map +1 -1
  100. package/build/screens/conversations/conversations_screen.js +15 -2
  101. package/build/screens/conversations/conversations_screen.js.map +1 -1
  102. package/build/types/resources/person.d.ts +1 -0
  103. package/build/types/resources/person.d.ts.map +1 -1
  104. package/build/types/resources/person.js.map +1 -1
  105. package/build/utils/date.d.ts.map +1 -1
  106. package/build/utils/date.js +5 -10
  107. package/build/utils/date.js.map +1 -1
  108. package/build/utils/native_adapters/menu.d.ts +1 -0
  109. package/build/utils/native_adapters/menu.d.ts.map +1 -1
  110. package/build/utils/native_adapters/menu.js +1 -0
  111. package/build/utils/native_adapters/menu.js.map +1 -1
  112. package/build/utils/request/conversation.d.ts +2 -1
  113. package/build/utils/request/conversation.d.ts.map +1 -1
  114. package/build/utils/request/conversation.js +4 -1
  115. package/build/utils/request/conversation.js.map +1 -1
  116. package/build/vendor/font_awesome_pro_solid_icons.d.ts +1 -0
  117. package/build/vendor/font_awesome_pro_solid_icons.d.ts.map +1 -1
  118. package/build/vendor/font_awesome_pro_solid_icons.js +5 -0
  119. package/build/vendor/font_awesome_pro_solid_icons.js.map +1 -1
  120. package/package.json +3 -3
  121. package/src/__tests__/hooks/use_can_browse_archived_conversations.test.tsx +98 -0
  122. package/src/__tests__/screens/conversation_filters/components/conversation_filters.test.tsx +132 -0
  123. package/src/__tests__/screens/conversation_filters_screen.test.tsx +76 -0
  124. package/src/__tests__/screens/conversation_new/components/services_form.test.tsx +1 -0
  125. package/src/components/conversations/__tests__/conversation_actions.test.tsx +67 -0
  126. package/src/components/conversations/__tests__/conversation_preview.test.tsx +38 -3
  127. package/src/components/conversations/__tests__/conversations.test.tsx +82 -0
  128. package/src/components/conversations/__tests__/conversations_blank_state.test.tsx +73 -0
  129. package/src/components/conversations/archived_results_footer.tsx +36 -0
  130. package/src/components/conversations/conversation_actions.tsx +27 -19
  131. package/src/components/conversations/conversation_preview.tsx +30 -10
  132. package/src/components/conversations/conversations.tsx +25 -2
  133. package/src/components/conversations/conversations_blank_state.tsx +21 -0
  134. package/src/components/conversations/filtered_results_footer.tsx +38 -0
  135. package/src/components/display/__tests__/filter_dropdown.test.tsx +9 -1
  136. package/src/components/display/filter_dropdown.tsx +14 -13
  137. package/src/components/display/icon_tile.tsx +54 -0
  138. package/src/components/display/index.ts +1 -0
  139. package/src/contexts/conversations_context.tsx +2 -1
  140. package/src/hooks/__tests__/use_conversation_archive.test.tsx +22 -0
  141. package/src/hooks/__tests__/use_jolt.test.tsx +30 -8
  142. package/src/hooks/__tests__/use_reduce_motion.test.tsx +13 -1
  143. package/src/hooks/index.ts +2 -0
  144. package/src/hooks/use_can_browse_archived_conversations.ts +17 -0
  145. package/src/hooks/use_clear_conversation_filters.ts +16 -0
  146. package/src/hooks/use_conversation.ts +4 -1
  147. package/src/hooks/use_current_person.ts +1 -0
  148. package/src/hooks/use_jolt.ts +33 -8
  149. package/src/hooks/use_manual_archiving_enabled.ts +10 -0
  150. package/src/hooks/use_reduce_motion.ts +2 -1
  151. package/src/screens/conversation_details_screen.tsx +2 -3
  152. package/src/screens/conversation_filters/__tests__/conversation_filters.test.tsx +101 -0
  153. package/src/screens/conversation_filters/components/conversation_filters.tsx +40 -7
  154. package/src/screens/conversation_filters/components/rows.tsx +29 -1
  155. package/src/screens/conversation_filters/context/conversation_filter_context.tsx +4 -0
  156. package/src/screens/conversation_filters/filter_types.ts +1 -0
  157. package/src/screens/conversation_filters/screen_props.ts +1 -0
  158. package/src/screens/conversation_filters_screen.tsx +25 -5
  159. package/src/screens/conversations/__tests__/conversations_screen.test.tsx +52 -0
  160. package/src/screens/conversations/components/__tests__/filter_dropdown_list_header_component.test.tsx +248 -0
  161. package/src/screens/conversations/components/__tests__/list_header_component.test.tsx +21 -4
  162. package/src/screens/conversations/components/filter_dropdown_list_header_component.tsx +284 -0
  163. package/src/screens/conversations/components/list_header_component.tsx +17 -12
  164. package/src/screens/conversations/components/search_list_header_component.tsx +17 -12
  165. package/src/screens/conversations/conversations_screen.tsx +15 -2
  166. package/src/types/resources/person.ts +1 -0
  167. package/src/utils/__tests__/conversation.test.ts +1 -0
  168. package/src/utils/__tests__/date.test.ts +4 -0
  169. package/src/utils/date.ts +5 -4
  170. package/src/utils/native_adapters/__tests__/menu.test.tsx +6 -2
  171. package/src/utils/native_adapters/menu.tsx +2 -0
  172. package/src/utils/request/conversation.ts +4 -0
  173. package/src/vendor/font_awesome_pro_solid_icons.ts +12 -0
@@ -44,6 +44,7 @@ export const SearchListHeaderComponent = () => {
44
44
  chat_group_graph_id,
45
45
  group_source_app_name = '',
46
46
  show_direct_messages,
47
+ show_archived,
47
48
  } = route.params || {}
48
49
  const currentPersonCache = useCurrentPersonCache()
49
50
  const { markAllRead, isPending } = useMarkAllRead()
@@ -54,7 +55,7 @@ export const SearchListHeaderComponent = () => {
54
55
  )
55
56
 
56
57
  const active: FilterTypes = useMemo(() => {
57
- if (chat_group_graph_id) {
58
+ if (chat_group_graph_id || show_archived) {
58
59
  return FilterTypes.More
59
60
  } else if (/groups/i.test(group_source_app_name)) {
60
61
  return FilterTypes.Groups
@@ -65,7 +66,7 @@ export const SearchListHeaderComponent = () => {
65
66
  }
66
67
 
67
68
  return FilterTypes.All
68
- }, [chat_group_graph_id, group_source_app_name, show_direct_messages])
69
+ }, [chat_group_graph_id, group_source_app_name, show_direct_messages, show_archived])
69
70
 
70
71
  const handleNewConversationNavigation = useCallback(() => {
71
72
  if (newConversationFromFilter || entryMode === 'select_type') {
@@ -104,6 +105,7 @@ export const SearchListHeaderComponent = () => {
104
105
  chat_group_graph_id: undefined,
105
106
  group_source_app_name: undefined,
106
107
  show_direct_messages: undefined,
108
+ show_archived: undefined,
107
109
  ...params,
108
110
  })
109
111
  },
@@ -123,8 +125,9 @@ export const SearchListHeaderComponent = () => {
123
125
  chat_group_graph_id,
124
126
  group_source_app_name,
125
127
  show_direct_messages,
128
+ show_archived,
126
129
  })
127
- }, [navigation, chat_group_graph_id, group_source_app_name, show_direct_messages])
130
+ }, [navigation, chat_group_graph_id, group_source_app_name, show_direct_messages, show_archived])
128
131
 
129
132
  const handleMarkAllRead = useCallback(() => {
130
133
  currentPersonCache.update({ unreadCount: 0 })
@@ -165,15 +168,17 @@ export const SearchListHeaderComponent = () => {
165
168
  <Heading numberOfLines={1} variant="h2">
166
169
  Conversations
167
170
  </Heading>
168
- <TextButton
169
- onPress={alertMarkAllRead}
170
- disabled={isPending}
171
- maxFontSizeMultiplier={MAX_FONT_SIZE_MULTIPLIER_LANDMARK}
172
- accessibilityShowsLargeContentViewer
173
- accessibilityLargeContentTitle="Mark all read"
174
- >
175
- Mark all read
176
- </TextButton>
171
+ {!show_archived && (
172
+ <TextButton
173
+ onPress={alertMarkAllRead}
174
+ disabled={isPending}
175
+ maxFontSizeMultiplier={MAX_FONT_SIZE_MULTIPLIER_LANDMARK}
176
+ accessibilityShowsLargeContentViewer
177
+ accessibilityLargeContentTitle="Mark all read"
178
+ >
179
+ Mark all read
180
+ </TextButton>
181
+ )}
177
182
  </View>
178
183
  <View style={styles.actionsContainer}>
179
184
  <ListHeaderActionButton
@@ -3,10 +3,13 @@ import React from 'react'
3
3
  import { StyleSheet, View } from 'react-native'
4
4
  import { Conversations } from '../../components'
5
5
  import { ConversationsContextProvider } from '../../contexts/conversations_context'
6
+ import { useFilterDropdownEnabled } from '../../hooks/use_filter_dropdown_enabled'
6
7
  import { analyticsEvents, usePublishProductAnalyticsEvent } from '../../hooks/use_product_analytics'
7
8
  import { useSearchEnabled } from '../../hooks/use_search_enabled'
8
9
  import { AppName } from '../../types/resources/app_name'
9
10
  import { GraphId } from '../../types/resources/group_resource'
11
+ import { Menu } from '../../utils/native_adapters'
12
+ import { FilterDropdownListHeaderComponent } from './components/filter_dropdown_list_header_component'
10
13
  import { ListHeaderComponent } from './components/list_header_component'
11
14
  import { SearchListHeaderComponent } from './components/search_list_header_component'
12
15
 
@@ -15,12 +18,12 @@ export type ConversationsScreenProps = StaticScreenProps<{
15
18
  chat_group_graph_id?: GraphId
16
19
  group_source_app_name?: AppName
17
20
  show_direct_messages?: boolean
21
+ show_archived?: boolean
18
22
  }>
19
23
 
20
24
  export function ConversationsScreen({ route }: ConversationsScreenProps) {
21
25
  const styles = useStyles()
22
- const searchEnabled = useSearchEnabled()
23
- const Header = searchEnabled ? SearchListHeaderComponent : ListHeaderComponent
26
+ const Header = useListHeaderComponent()
24
27
 
25
28
  usePublishProductAnalyticsEvent(analyticsEvents.conversation_index_opened)
26
29
 
@@ -33,6 +36,16 @@ export function ConversationsScreen({ route }: ConversationsScreenProps) {
33
36
  )
34
37
  }
35
38
 
39
+ const useListHeaderComponent = () => {
40
+ const filterDropdownEnabled = useFilterDropdownEnabled()
41
+ const searchEnabled = useSearchEnabled()
42
+
43
+ if (filterDropdownEnabled && Menu.isConfigured) return FilterDropdownListHeaderComponent
44
+ if (searchEnabled) return SearchListHeaderComponent
45
+
46
+ return ListHeaderComponent
47
+ }
48
+
36
49
  const useStyles = () => {
37
50
  return StyleSheet.create({
38
51
  container: {
@@ -23,5 +23,6 @@ export interface CurrentPersonResource extends PersonResource {
23
23
  ageQualificationStatus?: AgeQualificationStatus
24
24
  directMessagesDisabled: boolean
25
25
  directMessagesEligible: boolean
26
+ canBrowseArchivedConversations?: boolean
26
27
  under_18: boolean
27
28
  }
@@ -12,6 +12,7 @@ describe('getConversationsRequestArgs', () => {
12
12
  ],
13
13
  ['chat_group_graph_id', { chat_group_graph_id: groupId }, 'mine_or_not_empty,group'],
14
14
  ['show_direct_messages', { show_direct_messages: true }, 'mine_or_not_empty,direct_message'],
15
+ ['show_archived', { show_archived: true }, 'mine_or_not_empty,archived'],
15
16
  ])('%s uses filter: %s', (_label, args, expectedFilter) => {
16
17
  expect(getConversationsRequestArgs(args).data.filter).toBe(expectedFilter)
17
18
  })
@@ -16,4 +16,8 @@ describe('formatEventDateTime', () => {
16
16
  it('includes the year for dates in other years', () => {
17
17
  expect(formatEventDateTime(new Date(2025, 1, 3, 14, 18))).toBe('Feb 3, 2025 at 2:18pm')
18
18
  })
19
+
20
+ it('drops the minutes on the hour', () => {
21
+ expect(formatEventDateTime(new Date(2026, 1, 3, 14, 0))).toBe('Feb 3 at 2pm')
22
+ })
19
23
  })
package/src/utils/date.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { date as formatDate, time as formatTime } from '@planningcenter/datetime-fmt'
1
+ import { date as formatDate } from '@planningcenter/datetime-fmt'
2
2
  import dayjs from './dayjs'
3
3
 
4
4
  export type DateProps = string | number | Date
@@ -64,7 +64,8 @@ export function relativeTime(date: DateProps): string {
64
64
 
65
65
  export function formatEventDateTime(date: DateProps) {
66
66
  const { isThisYear } = getRelativeDateStatus(date)
67
- const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone
68
- const day = formatDate(date, { style: 'abbreviated', year: !isThisYear, timeZone })
69
- return `${day} at ${formatTime(date, { timeZone })}`
67
+ const local = dayjs(date)
68
+ const day = local.format(isThisYear ? 'MMM D' : 'MMM D, YYYY')
69
+ const time = local.format(local.minute() === 0 ? 'ha' : 'h:mma')
70
+ return `${day} at ${time}`
70
71
  }
@@ -8,7 +8,9 @@ const actions = [{ id: 'all', title: 'All' }]
8
8
  describe('MenuAdapter', () => {
9
9
  it('renders the trigger and warns when the host configured no menu', () => {
10
10
  const warn = jest.spyOn(console, 'warn').mockImplementation(() => {})
11
- const { View } = new MenuAdapter()
11
+ const { View, isConfigured } = new MenuAdapter()
12
+
13
+ expect(isConfigured).toBe(false)
12
14
 
13
15
  render(
14
16
  <View actions={actions}>
@@ -28,7 +30,9 @@ describe('MenuAdapter', () => {
28
30
  <Text>{hostActions.map(action => action.title).join(',')}</Text>
29
31
  </>
30
32
  )
31
- const { View } = new MenuAdapter({ View: HostMenuView })
33
+ const { View, isConfigured } = new MenuAdapter({ View: HostMenuView })
34
+
35
+ expect(isConfigured).toBe(true)
32
36
 
33
37
  render(
34
38
  <View actions={actions}>
@@ -61,8 +61,10 @@ function UnconfiguredMenuView({ children, style, testID }: MenuViewProps) {
61
61
 
62
62
  export class MenuAdapter {
63
63
  View: MenuView
64
+ isConfigured: boolean
64
65
 
65
66
  constructor(methods?: { View: MenuView }) {
66
67
  this.View = methods?.View ?? UnconfiguredMenuView
68
+ this.isConfigured = !!methods?.View
67
69
  }
68
70
  }
@@ -6,6 +6,7 @@ export interface ConversationRequestArgs {
6
6
  chat_group_graph_id?: GraphId
7
7
  group_source_app_name?: string
8
8
  show_direct_messages?: boolean
9
+ show_archived?: boolean
9
10
  }
10
11
 
11
12
  export const getConversationsRequestArgs = ({
@@ -13,10 +14,13 @@ export const getConversationsRequestArgs = ({
13
14
  chat_group_graph_id,
14
15
  group_source_app_name,
15
16
  show_direct_messages,
17
+ show_archived,
16
18
  }: Partial<ConversationRequestArgs> = {}): GetRequest => {
17
19
  let filter: string
18
20
  if (chat_group_graph_id) {
19
21
  filter = 'mine_or_not_empty,group'
22
+ } else if (show_archived) {
23
+ filter = 'mine_or_not_empty,archived'
20
24
  } else if (show_direct_messages) {
21
25
  filter = 'mine_or_not_empty,direct_message'
22
26
  } else if (group_source_app_name) {
@@ -608,3 +608,15 @@ export const faTag: IconDefinition = {
608
608
  'M32.5 96l0 149.5c0 17 6.7 33.3 18.7 45.3l192 192c25 25 65.5 25 90.5 0L483.2 333.3c25-25 25-65.5 0-90.5l-192-192C279.2 38.7 263 32 246 32L96.5 32c-35.3 0-64 28.7-64 64zm112 16a32 32 0 1 1 0 64 32 32 0 1 1 0-64z',
609
609
  ],
610
610
  }
611
+
612
+ export const faBoxArchive: IconDefinition = {
613
+ prefix: 'fas',
614
+ iconName: 'box-archive',
615
+ icon: [
616
+ 512,
617
+ 512,
618
+ ['archive'],
619
+ 'f187',
620
+ 'M0 64C0 46.3 14.3 32 32 32l448 0c17.7 0 32 14.3 32 32l0 32c0 17.7-14.3 32-32 32L32 128C14.3 128 0 113.7 0 96L0 64zM32 176l448 0 0 240c0 35.3-28.7 64-64 64L96 480c-35.3 0-64-28.7-64-64l0-240zm152 64c-13.3 0-24 10.7-24 24s10.7 24 24 24l144 0c13.3 0 24-10.7 24-24s-10.7-24-24-24l-144 0z',
621
+ ],
622
+ }