@planningcenter/chat-react-native 3.6.0-rc.2 → 3.6.0-rc.4

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 (40) hide show
  1. package/build/components/conversations/conversation_preview.d.ts +1 -0
  2. package/build/components/conversations/conversation_preview.d.ts.map +1 -1
  3. package/build/components/conversations/conversation_preview.js +38 -0
  4. package/build/components/conversations/conversation_preview.js.map +1 -1
  5. package/build/components/conversations/conversations.d.ts.map +1 -1
  6. package/build/components/conversations/conversations.js +31 -10
  7. package/build/components/conversations/conversations.js.map +1 -1
  8. package/build/components/display/badge.d.ts +1 -1
  9. package/build/components/display/badge.d.ts.map +1 -1
  10. package/build/components/display/badge.js.map +1 -1
  11. package/build/contexts/conversations_context.d.ts.map +1 -1
  12. package/build/contexts/conversations_context.js +1 -2
  13. package/build/contexts/conversations_context.js.map +1 -1
  14. package/build/hooks/use_conversations.d.ts +3 -3
  15. package/build/hooks/use_conversations.d.ts.map +1 -1
  16. package/build/hooks/use_conversations.js +2 -2
  17. package/build/hooks/use_conversations.js.map +1 -1
  18. package/build/screens/conversation_filter_recipients/components/navigation_header.js +1 -1
  19. package/build/screens/conversation_filter_recipients/components/navigation_header.js.map +1 -1
  20. package/build/screens/conversation_new/components/services_form.d.ts.map +1 -1
  21. package/build/screens/conversation_new/components/services_form.js +22 -4
  22. package/build/screens/conversation_new/components/services_form.js.map +1 -1
  23. package/build/screens/conversations/components/conversations_jolt_events.d.ts +7 -0
  24. package/build/screens/conversations/components/conversations_jolt_events.d.ts.map +1 -0
  25. package/build/screens/conversations/components/conversations_jolt_events.js +14 -0
  26. package/build/screens/conversations/components/conversations_jolt_events.js.map +1 -0
  27. package/build/screens/conversations/conversations_screen.d.ts.map +1 -1
  28. package/build/screens/conversations/conversations_screen.js +2 -0
  29. package/build/screens/conversations/conversations_screen.js.map +1 -1
  30. package/package.json +2 -2
  31. package/src/__tests__/hooks/use_conversation_messages.ts +1 -5
  32. package/src/components/conversations/conversation_preview.tsx +54 -2
  33. package/src/components/conversations/conversations.tsx +53 -17
  34. package/src/components/display/badge.tsx +1 -1
  35. package/src/contexts/conversations_context.tsx +1 -3
  36. package/src/hooks/use_conversations.ts +5 -4
  37. package/src/screens/conversation_filter_recipients/components/navigation_header.tsx +1 -1
  38. package/src/screens/conversation_new/components/services_form.tsx +29 -4
  39. package/src/screens/conversations/components/conversations_jolt_events.tsx +23 -0
  40. package/src/screens/conversations/conversations_screen.tsx +2 -0
@@ -8,5 +8,6 @@ interface ConversationPreviewProps {
8
8
  style?: ViewStyle;
9
9
  }
10
10
  export declare const ConversationPreview: ({ conversation, onPress, showBadges, style, }: ConversationPreviewProps) => React.JSX.Element;
11
+ export declare const ConversationPreviewSkeleton: () => React.JSX.Element;
11
12
  export {};
12
13
  //# sourceMappingURL=conversation_preview.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"conversation_preview.d.ts","sourceRoot":"","sources":["../../../src/components/conversations/conversation_preview.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAoB,SAAS,EAAE,MAAM,cAAc,CAAA;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAQlD,UAAU,wBAAwB;IAChC,YAAY,EAAE,oBAAoB,CAAA;IAClC,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB;AAED,eAAO,MAAM,mBAAmB,kDAK7B,wBAAwB,sBAwD1B,CAAA"}
1
+ {"version":3,"file":"conversation_preview.d.ts","sourceRoot":"","sources":["../../../src/components/conversations/conversation_preview.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAoB,SAAS,EAAE,MAAM,cAAc,CAAA;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAQlD,UAAU,wBAAwB;IAChC,YAAY,EAAE,oBAAoB,CAAA;IAClC,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB;AAED,eAAO,MAAM,mBAAmB,kDAK7B,wBAAwB,sBAwD1B,CAAA;AAmCD,eAAO,MAAM,2BAA2B,yBAqBvC,CAAA"}
@@ -45,6 +45,26 @@ const ConversationBadges = ({ visible, badges }) => {
45
45
  {badges.map(badge => (<Badge key={badge.text} variant="meta" productLogoName={badge.appName} label={badge.pcoResourceType} metaLabel={badge.text || ''}/>))}
46
46
  </View>);
47
47
  };
48
+ const skeletonBadges = [
49
+ {
50
+ pcoResourceType: ' ',
51
+ text: ' ',
52
+ },
53
+ ];
54
+ export const ConversationPreviewSkeleton = () => {
55
+ const styles = useStyles();
56
+ return (<View style={styles.previewRow}>
57
+ <AvatarGroup size="lg" sourceUris={[]} showFallback={true} fallbackIconName={'general.person'}/>
58
+ <View style={styles.conversationBody}>
59
+ <View style={styles.titleLoading}/>
60
+ <View style={styles.subtitleLoading}/>
61
+ <ConversationBadges visible={true} badges={skeletonBadges}/>
62
+ </View>
63
+ <View style={styles.metaContainer}>
64
+ <View style={styles.dateLoading}/>
65
+ </View>
66
+ </View>);
67
+ };
48
68
  const useStyles = () => {
49
69
  const { colors } = useTheme();
50
70
  return StyleSheet.create({
@@ -61,6 +81,12 @@ const useStyles = () => {
61
81
  fontSize: 16,
62
82
  color: colors.textColorDefaultPrimary,
63
83
  },
84
+ titleLoading: {
85
+ width: 120,
86
+ height: 20,
87
+ backgroundColor: colors.fillColorNeutral080,
88
+ borderRadius: 4,
89
+ },
64
90
  conversationBody: {
65
91
  flex: 1,
66
92
  rowGap: 2,
@@ -68,10 +94,22 @@ const useStyles = () => {
68
94
  emptyConversationPreviewText: {
69
95
  color: colors.interaction,
70
96
  },
97
+ subtitleLoading: {
98
+ width: 80,
99
+ height: 16,
100
+ backgroundColor: colors.fillColorNeutral090,
101
+ borderRadius: 4,
102
+ },
71
103
  metaContainer: {
72
104
  rowGap: 4,
73
105
  alignItems: 'flex-end',
74
106
  },
107
+ dateLoading: {
108
+ width: 60,
109
+ height: 16,
110
+ backgroundColor: colors.fillColorNeutral090,
111
+ borderRadius: 4,
112
+ },
75
113
  badges: {
76
114
  marginTop: 4,
77
115
  alignItems: 'flex-start',
@@ -1 +1 @@
1
- {"version":3,"file":"conversation_preview.js","sourceRoot":"","sources":["../../../src/components/conversations/conversation_preview.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react'\nimport { StyleSheet, View, ViewStyle } from 'react-native'\nimport { ConversationResource } from '../../types'\nimport { AvatarGroup, Heading, Text, Badge } from '../display'\nimport { formatDatePreview } from '../../utils/date'\nimport { useTheme } from '../../hooks'\nimport { UnreadCountBadge } from './unread_count_badge'\nimport { ConversationActions } from './conversation_actions'\nimport { MuteIndicator } from './mute_indicator'\n\ninterface ConversationPreviewProps {\n conversation: ConversationResource\n onPress: () => void\n showBadges?: boolean\n style?: ViewStyle\n}\n\nexport const ConversationPreview = ({\n conversation,\n onPress,\n showBadges = true,\n style,\n}: ConversationPreviewProps) => {\n const styles = useStyles()\n const {\n lastMessageAuthorName,\n lastMessageCreatedAt,\n lastMessageTextPreview,\n previewAvatarUrls,\n title,\n unreadCount,\n badges,\n muted,\n } = conversation\n\n const emptyConversation = !lastMessageCreatedAt\n const hasAvatarUrls = previewAvatarUrls && previewAvatarUrls.length > 0\n const shouldShowFallback = emptyConversation || !hasAvatarUrls\n const fallbackIconName = emptyConversation ? 'people.noTextMessage' : 'general.person'\n\n const conversationPreviewText = lastMessageTextPreview\n ? `${lastMessageAuthorName}: ${lastMessageTextPreview}`\n : 'Send your first message'\n\n return (\n <ConversationActions\n conversation={conversation}\n style={[styles.previewRow, style]}\n onPress={onPress}\n >\n <AvatarGroup\n size=\"lg\"\n sourceUris={previewAvatarUrls || []}\n showFallback={shouldShowFallback}\n fallbackIconName={fallbackIconName}\n />\n <View style={styles.conversationBody}>\n <Heading numberOfLines={1} variant=\"h3\" style={styles.title}>\n {title}\n </Heading>\n <Text\n variant=\"tertiary\"\n numberOfLines={2}\n style={emptyConversation && styles.emptyConversationPreviewText}\n >\n {conversationPreviewText}\n </Text>\n <ConversationBadges visible={showBadges} badges={badges} />\n </View>\n <View style={styles.metaContainer}>\n <Text variant=\"tertiary\">{formatDatePreview(lastMessageCreatedAt)}</Text>\n <View style={styles.statusContainer}>\n <UnreadCountBadge count={unreadCount} showDot={muted} />\n <MuteIndicator muted={muted} />\n </View>\n </View>\n </ConversationActions>\n )\n}\n\nconst ConversationBadges = ({ visible, badges }: { visible: boolean; badges?: any[] }) => {\n const styles = useStyles()\n\n if (!visible || !badges || badges.length === 0) {\n return null\n }\n\n return (\n <View style={styles.badges}>\n {badges.map(badge => (\n <Badge\n key={badge.text}\n variant=\"meta\"\n productLogoName={badge.appName}\n label={badge.pcoResourceType}\n metaLabel={badge.text || ''}\n />\n ))}\n </View>\n )\n}\n\nconst useStyles = () => {\n const { colors } = useTheme()\n\n return StyleSheet.create({\n previewRow: {\n flexDirection: 'row',\n gap: 8,\n borderBottomWidth: 1,\n borderBottomColor: colors.borderColorDefaultDim,\n paddingTop: 12,\n paddingBottom: 12,\n paddingHorizontal: 16,\n },\n title: {\n fontSize: 16,\n color: colors.textColorDefaultPrimary,\n },\n conversationBody: {\n flex: 1,\n rowGap: 2,\n },\n emptyConversationPreviewText: {\n color: colors.interaction,\n },\n metaContainer: {\n rowGap: 4,\n alignItems: 'flex-end',\n },\n badges: {\n marginTop: 4,\n alignItems: 'flex-start',\n },\n statusContainer: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 4,\n },\n })\n}\n"]}
1
+ {"version":3,"file":"conversation_preview.js","sourceRoot":"","sources":["../../../src/components/conversations/conversation_preview.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react'\nimport { StyleSheet, View, ViewStyle } from 'react-native'\nimport { ConversationResource } from '../../types'\nimport { AvatarGroup, Heading, Text, Badge, type BadgeProps } from '../display'\nimport { formatDatePreview } from '../../utils/date'\nimport { useTheme } from '../../hooks'\nimport { UnreadCountBadge } from './unread_count_badge'\nimport { ConversationActions } from './conversation_actions'\nimport { MuteIndicator } from './mute_indicator'\n\ninterface ConversationPreviewProps {\n conversation: ConversationResource\n onPress: () => void\n showBadges?: boolean\n style?: ViewStyle\n}\n\nexport const ConversationPreview = ({\n conversation,\n onPress,\n showBadges = true,\n style,\n}: ConversationPreviewProps) => {\n const styles = useStyles()\n const {\n lastMessageAuthorName,\n lastMessageCreatedAt,\n lastMessageTextPreview,\n previewAvatarUrls,\n title,\n unreadCount,\n badges,\n muted,\n } = conversation\n\n const emptyConversation = !lastMessageCreatedAt\n const hasAvatarUrls = previewAvatarUrls && previewAvatarUrls.length > 0\n const shouldShowFallback = emptyConversation || !hasAvatarUrls\n const fallbackIconName = emptyConversation ? 'people.noTextMessage' : 'general.person'\n\n const conversationPreviewText = lastMessageTextPreview\n ? `${lastMessageAuthorName}: ${lastMessageTextPreview}`\n : 'Send your first message'\n\n return (\n <ConversationActions\n conversation={conversation}\n style={[styles.previewRow, style]}\n onPress={onPress}\n >\n <AvatarGroup\n size=\"lg\"\n sourceUris={previewAvatarUrls || []}\n showFallback={shouldShowFallback}\n fallbackIconName={fallbackIconName}\n />\n <View style={styles.conversationBody}>\n <Heading numberOfLines={1} variant=\"h3\" style={styles.title}>\n {title}\n </Heading>\n <Text\n variant=\"tertiary\"\n numberOfLines={2}\n style={emptyConversation && styles.emptyConversationPreviewText}\n >\n {conversationPreviewText}\n </Text>\n <ConversationBadges visible={showBadges} badges={badges} />\n </View>\n <View style={styles.metaContainer}>\n <Text variant=\"tertiary\">{formatDatePreview(lastMessageCreatedAt)}</Text>\n <View style={styles.statusContainer}>\n <UnreadCountBadge count={unreadCount} showDot={muted} />\n <MuteIndicator muted={muted} />\n </View>\n </View>\n </ConversationActions>\n )\n}\n\ninterface BadgeShape {\n appName?: BadgeProps['productLogoName']\n pcoResourceType: string\n text: string | null\n}\nconst ConversationBadges = ({ visible, badges }: { visible: boolean; badges?: BadgeShape[] }) => {\n const styles = useStyles()\n\n if (!visible || !badges || badges.length === 0) {\n return null\n }\n\n return (\n <View style={styles.badges}>\n {badges.map(badge => (\n <Badge\n key={badge.text}\n variant=\"meta\"\n productLogoName={badge.appName}\n label={badge.pcoResourceType}\n metaLabel={badge.text || ''}\n />\n ))}\n </View>\n )\n}\n\nconst skeletonBadges: BadgeShape[] = [\n {\n pcoResourceType: ' ',\n text: ' ',\n },\n]\nexport const ConversationPreviewSkeleton = () => {\n const styles = useStyles()\n\n return (\n <View style={styles.previewRow}>\n <AvatarGroup\n size=\"lg\"\n sourceUris={[]}\n showFallback={true}\n fallbackIconName={'general.person'}\n />\n <View style={styles.conversationBody}>\n <View style={styles.titleLoading} />\n <View style={styles.subtitleLoading} />\n <ConversationBadges visible={true} badges={skeletonBadges} />\n </View>\n <View style={styles.metaContainer}>\n <View style={styles.dateLoading} />\n </View>\n </View>\n )\n}\n\nconst useStyles = () => {\n const { colors } = useTheme()\n\n return StyleSheet.create({\n previewRow: {\n flexDirection: 'row',\n gap: 8,\n borderBottomWidth: 1,\n borderBottomColor: colors.borderColorDefaultDim,\n paddingTop: 12,\n paddingBottom: 12,\n paddingHorizontal: 16,\n },\n title: {\n fontSize: 16,\n color: colors.textColorDefaultPrimary,\n },\n titleLoading: {\n width: 120,\n height: 20,\n backgroundColor: colors.fillColorNeutral080,\n borderRadius: 4,\n },\n conversationBody: {\n flex: 1,\n rowGap: 2,\n },\n emptyConversationPreviewText: {\n color: colors.interaction,\n },\n subtitleLoading: {\n width: 80,\n height: 16,\n backgroundColor: colors.fillColorNeutral090,\n borderRadius: 4,\n },\n metaContainer: {\n rowGap: 4,\n alignItems: 'flex-end',\n },\n dateLoading: {\n width: 60,\n height: 16,\n backgroundColor: colors.fillColorNeutral090,\n borderRadius: 4,\n },\n badges: {\n marginTop: 4,\n alignItems: 'flex-start',\n },\n statusContainer: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 4,\n },\n })\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"conversations.d.ts","sourceRoot":"","sources":["../../../src/components/conversations/conversations.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAA;AAOzB,UAAU,kBAAkB;IAC1B,mBAAmB,CAAC,EAChB,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,GACxB,KAAK,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC,GAClE,IAAI,GACJ,SAAS,CAAA;CACd;AAED,eAAO,MAAM,aAAa,4BAA6B,kBAAkB,sBA+CxE,CAAA"}
1
+ {"version":3,"file":"conversations.d.ts","sourceRoot":"","sources":["../../../src/components/conversations/conversations.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAkB,MAAM,OAAO,CAAA;AAQtC,UAAU,kBAAkB;IAC1B,mBAAmB,CAAC,EAChB,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,GACxB,KAAK,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC,GAClE,IAAI,GACJ,SAAS,CAAA;CACd;AAED,eAAO,MAAM,aAAa,4BAA6B,kBAAkB,sBAkExE,CAAA"}
@@ -1,25 +1,42 @@
1
1
  import { useNavigation } from '@react-navigation/native';
2
2
  import { FlashList } from '@shopify/flash-list';
3
- import React from 'react';
3
+ import React, { useMemo } from 'react';
4
4
  import { StyleSheet, View } from 'react-native';
5
5
  import { useConversationsContext } from '../../contexts/conversations_context';
6
6
  import { useTheme } from '../../hooks';
7
7
  import { BlankState } from '../display';
8
- import { ConversationPreview } from './conversation_preview';
8
+ import { ConversationPreview, ConversationPreviewSkeleton } from './conversation_preview';
9
9
  export const Conversations = ({ ListHeaderComponent }) => {
10
10
  const styles = useStyles();
11
- const { conversations, fetchNextPage, refetch, isRefetching, isFetched, args: { chat_group_graph_id }, } = useConversationsContext();
11
+ const { conversations, isLoading, fetchNextPage, refetch, isRefetching, isFetched, args: { chat_group_graph_id }, } = useConversationsContext();
12
12
  const navigation = useNavigation();
13
13
  const showBadges = !chat_group_graph_id;
14
+ const data = useMemo(() => {
15
+ if (isLoading) {
16
+ return loadingPlaceholder;
17
+ }
18
+ return conversations.map(conversation => ({
19
+ type: 'conversation',
20
+ id: conversation.id,
21
+ resource: conversation,
22
+ }));
23
+ }, [conversations, isLoading]);
14
24
  return (<View style={styles.container}>
15
- <FlashList data={conversations} estimatedItemSize={97} contentContainerStyle={styles.contentContainer} onRefresh={refetch} refreshing={!isFetched && isRefetching} ListHeaderComponent={ListHeaderComponent} ListEmptyComponent={<View style={styles.listEmpty}>
25
+ <FlashList data={data} estimatedItemSize={97} keyExtractor={item => item.id.toString()} contentContainerStyle={styles.contentContainer} onRefresh={refetch} refreshing={!isFetched && isRefetching} ListHeaderComponent={ListHeaderComponent} ListEmptyComponent={<View style={styles.listEmpty}>
16
26
  <BlankState iconName="general.outlinedTextMessage" title="No conversations"/>
17
- </View>} renderItem={({ item }) => (<ConversationPreview conversation={item} onPress={() => navigation.navigate('Conversation', {
18
- conversation_id: item.id,
19
- title: item.title,
20
- badge: item.badges?.[0],
21
- deleted: item.deleted,
22
- })} showBadges={showBadges}/>)} onEndReached={() => fetchNextPage()}/>
27
+ </View>} renderItem={({ item }) => {
28
+ if (item.type === 'loading') {
29
+ return <ConversationPreviewSkeleton />;
30
+ }
31
+ else {
32
+ return (<ConversationPreview conversation={item.resource} onPress={() => navigation.navigate('Conversation', {
33
+ conversation_id: item.resource.id,
34
+ title: item.resource.title,
35
+ badge: item.resource.badges?.[0],
36
+ deleted: item.resource.deleted,
37
+ })} showBadges={showBadges}/>);
38
+ }
39
+ }} onEndReached={() => fetchNextPage()}/>
23
40
  </View>);
24
41
  };
25
42
  const useStyles = () => {
@@ -36,4 +53,8 @@ const useStyles = () => {
36
53
  },
37
54
  });
38
55
  };
56
+ const loadingPlaceholder = Array.from({ length: 5 }, (_, i) => ({
57
+ type: 'loading',
58
+ id: `loading${i}`,
59
+ }));
39
60
  //# sourceMappingURL=conversations.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"conversations.js","sourceRoot":"","sources":["../../../src/components/conversations/conversations.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC/C,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAA;AAC9E,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAU5D,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,EAAE,mBAAmB,EAAsB,EAAE,EAAE;IAC3E,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAE1B,MAAM,EACJ,aAAa,EACb,aAAa,EACb,OAAO,EACP,YAAY,EACZ,SAAS,EACT,IAAI,EAAE,EAAE,mBAAmB,EAAE,GAC9B,GAAG,uBAAuB,EAAE,CAAA;IAC7B,MAAM,UAAU,GAAG,aAAa,EAAE,CAAA;IAElC,MAAM,UAAU,GAAG,CAAC,mBAAmB,CAAA;IAEvC,OAAO,CACL,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAC5B;MAAA,CAAC,SAAS,CACR,IAAI,CAAC,CAAC,aAAa,CAAC,CACpB,iBAAiB,CAAC,CAAC,EAAE,CAAC,CACtB,qBAAqB,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAC/C,SAAS,CAAC,CAAC,OAAO,CAAC,CACnB,UAAU,CAAC,CAAC,CAAC,SAAS,IAAI,YAAY,CAAC,CACvC,mBAAmB,CAAC,CAAC,mBAAmB,CAAC,CACzC,kBAAkB,CAAC,CACjB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAC5B;YAAA,CAAC,UAAU,CAAC,QAAQ,CAAC,6BAA6B,CAAC,KAAK,CAAC,kBAAkB,EAC7E;UAAA,EAAE,IAAI,CACR,CAAC,CACD,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CACxB,CAAC,mBAAmB,CAClB,YAAY,CAAC,CAAC,IAAI,CAAC,CACnB,OAAO,CAAC,CAAC,GAAG,EAAE,CACZ,UAAU,CAAC,QAAQ,CAAC,cAAc,EAAE;gBAClC,eAAe,EAAE,IAAI,CAAC,EAAE;gBACxB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;gBACvB,OAAO,EAAE,IAAI,CAAC,OAAO;aACtB,CACH,CAAC,CACD,UAAU,CAAC,CAAC,UAAU,CAAC,EACvB,CACH,CAAC,CACF,YAAY,CAAC,CAAC,GAAG,EAAE,CAAC,aAAa,EAAE,CAAC,EAExC;IAAA,EAAE,IAAI,CAAC,CACR,CAAA;AACH,CAAC,CAAA;AAED,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAA;IAE7B,OAAO,UAAU,CAAC,MAAM,CAAC;QACvB,SAAS,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE;QACtB,gBAAgB,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE;QACzC,QAAQ,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,mBAAmB,EAAE;QAC/C,SAAS,EAAE;YACT,IAAI,EAAE,CAAC;YACP,cAAc,EAAE,QAAQ;YACxB,UAAU,EAAE,QAAQ;YACpB,eAAe,EAAE,EAAE;SACpB;KACF,CAAC,CAAA;AACJ,CAAC,CAAA","sourcesContent":["import { useNavigation } from '@react-navigation/native'\nimport { FlashList } from '@shopify/flash-list'\nimport React from 'react'\nimport { StyleSheet, View } from 'react-native'\nimport { useConversationsContext } from '../../contexts/conversations_context'\nimport { useTheme } from '../../hooks'\nimport { BlankState } from '../display'\nimport { ConversationPreview } from './conversation_preview'\n\ninterface ConversationsProps {\n ListHeaderComponent?:\n | React.ComponentType<any>\n | React.ReactElement<any, string | React.JSXElementConstructor<any>>\n | null\n | undefined\n}\n\nexport const Conversations = ({ ListHeaderComponent }: ConversationsProps) => {\n const styles = useStyles()\n\n const {\n conversations,\n fetchNextPage,\n refetch,\n isRefetching,\n isFetched,\n args: { chat_group_graph_id },\n } = useConversationsContext()\n const navigation = useNavigation()\n\n const showBadges = !chat_group_graph_id\n\n return (\n <View style={styles.container}>\n <FlashList\n data={conversations}\n estimatedItemSize={97}\n contentContainerStyle={styles.contentContainer}\n onRefresh={refetch}\n refreshing={!isFetched && isRefetching}\n ListHeaderComponent={ListHeaderComponent}\n ListEmptyComponent={\n <View style={styles.listEmpty}>\n <BlankState iconName=\"general.outlinedTextMessage\" title=\"No conversations\" />\n </View>\n }\n renderItem={({ item }) => (\n <ConversationPreview\n conversation={item}\n onPress={() =>\n navigation.navigate('Conversation', {\n conversation_id: item.id,\n title: item.title,\n badge: item.badges?.[0],\n deleted: item.deleted,\n })\n }\n showBadges={showBadges}\n />\n )}\n onEndReached={() => fetchNextPage()}\n />\n </View>\n )\n}\n\nconst useStyles = () => {\n const { colors } = useTheme()\n\n return StyleSheet.create({\n container: { flex: 1 },\n contentContainer: { paddingVertical: 16 },\n listItem: { color: colors.fillColorNeutral020 },\n listEmpty: {\n flex: 1,\n justifyContent: 'center',\n alignItems: 'center',\n paddingVertical: 32,\n },\n })\n}\n"]}
1
+ {"version":3,"file":"conversations.js","sourceRoot":"","sources":["../../../src/components/conversations/conversations.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useNavigation } from '@react-navigation/native'\nimport { FlashList } from '@shopify/flash-list'\nimport React, { useMemo } from 'react'\nimport { StyleSheet, View } from 'react-native'\nimport { useConversationsContext } from '../../contexts/conversations_context'\nimport { useTheme } from '../../hooks'\nimport { BlankState } from '../display'\nimport { ConversationPreview, ConversationPreviewSkeleton } from './conversation_preview'\nimport { ConversationResource } from '../../types'\n\ninterface ConversationsProps {\n ListHeaderComponent?:\n | React.ComponentType<any>\n | React.ReactElement<any, string | React.JSXElementConstructor<any>>\n | null\n | undefined\n}\n\nexport const Conversations = ({ ListHeaderComponent }: ConversationsProps) => {\n const styles = useStyles()\n\n const {\n conversations,\n isLoading,\n fetchNextPage,\n refetch,\n isRefetching,\n isFetched,\n args: { chat_group_graph_id },\n } = useConversationsContext()\n const navigation = useNavigation()\n\n const showBadges = !chat_group_graph_id\n\n const data: FlashListItem[] = useMemo(() => {\n if (isLoading) {\n return loadingPlaceholder\n }\n return conversations.map(conversation => ({\n type: 'conversation' as const,\n id: conversation.id,\n resource: conversation,\n }))\n }, [conversations, isLoading])\n\n return (\n <View style={styles.container}>\n <FlashList\n data={data}\n estimatedItemSize={97}\n keyExtractor={item => item.id.toString()}\n contentContainerStyle={styles.contentContainer}\n onRefresh={refetch}\n refreshing={!isFetched && isRefetching}\n ListHeaderComponent={ListHeaderComponent}\n ListEmptyComponent={\n <View style={styles.listEmpty}>\n <BlankState iconName=\"general.outlinedTextMessage\" title=\"No conversations\" />\n </View>\n }\n renderItem={({ item }) => {\n if (item.type === 'loading') {\n return <ConversationPreviewSkeleton />\n } else {\n return (\n <ConversationPreview\n conversation={item.resource}\n onPress={() =>\n navigation.navigate('Conversation', {\n conversation_id: item.resource.id,\n title: item.resource.title,\n badge: item.resource.badges?.[0],\n deleted: item.resource.deleted,\n })\n }\n showBadges={showBadges}\n />\n )\n }\n }}\n onEndReached={() => fetchNextPage()}\n />\n </View>\n )\n}\n\nconst useStyles = () => {\n const { colors } = useTheme()\n\n return StyleSheet.create({\n container: { flex: 1 },\n contentContainer: { paddingVertical: 16 },\n listItem: { color: colors.fillColorNeutral020 },\n listEmpty: {\n flex: 1,\n justifyContent: 'center',\n alignItems: 'center',\n paddingVertical: 32,\n },\n })\n}\n\ninterface FlashListLoadingItem {\n type: 'loading'\n id: string\n}\ninterface FlashListConversationItem {\n type: 'conversation'\n resource: ConversationResource\n id: number\n}\ntype FlashListItem = FlashListLoadingItem | FlashListConversationItem\n\nconst loadingPlaceholder: FlashListItem[] = Array.from({ length: 5 }, (_, i) => ({\n type: 'loading',\n id: `loading${i}`,\n}))\n"]}
@@ -9,7 +9,7 @@ declare const VARIANTS: {
9
9
  };
10
10
  type VariantUnion = (typeof VARIANTS)[keyof typeof VARIANTS];
11
11
  type ProductLogoName = 'Groups' | 'Services' | 'groups' | 'services';
12
- interface BadgeProps {
12
+ export interface BadgeProps {
13
13
  /**
14
14
  * Renders the main text.
15
15
  */
@@ -1 +1 @@
1
- {"version":3,"file":"badge.d.ts","sourceRoot":"","sources":["../../../src/components/display/badge.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAClC,OAAO,KAAK,EAAwB,SAAS,EAAE,MAAM,cAAc,CAAA;AAMnE,OAAO,EAAQ,UAAU,EAAE,MAAM,QAAQ,CAAA;AAEzC,OAAO,EAA+B,KAAK,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAM/F,QAAA,MAAM,QAAQ;;;;CAIJ,CAAA;AAEV,KAAK,YAAY,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,OAAO,QAAQ,CAAC,CAAA;AAiB5D,KAAK,eAAe,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,GAAG,UAAU,CAAA;AAcpE,UAAU,UAAU;IAClB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAA;IACb;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;OAEG;IACH,UAAU,CAAC,EAAE,qBAAqB,CAAA;IAClC;;OAEG;IACH,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB;;OAEG;IACH,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC;;OAEG;IACH,QAAQ,CAAC,EAAE,UAAU,CAAA;IACrB;;OAEG;IACH,aAAa,CAAC,EAAE,UAAU,CAAA;IAC1B;;OAEG;IACH,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB;;OAEG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB;AAED,wBAAgB,KAAK,CAAC,EACpB,UAAsB,EACtB,SAAS,EACT,KAAK,EACL,QAAQ,EACR,aAAa,EACb,KAAK,EACL,eAAe,EACf,OAAmB,EACnB,qBAAqB,EACrB,OAAO,GACR,EAAE,UAAU,eA4BZ"}
1
+ {"version":3,"file":"badge.d.ts","sourceRoot":"","sources":["../../../src/components/display/badge.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAClC,OAAO,KAAK,EAAwB,SAAS,EAAE,MAAM,cAAc,CAAA;AAMnE,OAAO,EAAQ,UAAU,EAAE,MAAM,QAAQ,CAAA;AAEzC,OAAO,EAA+B,KAAK,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAM/F,QAAA,MAAM,QAAQ;;;;CAIJ,CAAA;AAEV,KAAK,YAAY,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,OAAO,QAAQ,CAAC,CAAA;AAiB5D,KAAK,eAAe,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,GAAG,UAAU,CAAA;AAcpE,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAA;IACb;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;OAEG;IACH,UAAU,CAAC,EAAE,qBAAqB,CAAA;IAClC;;OAEG;IACH,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB;;OAEG;IACH,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC;;OAEG;IACH,QAAQ,CAAC,EAAE,UAAU,CAAA;IACrB;;OAEG;IACH,aAAa,CAAC,EAAE,UAAU,CAAA;IAC1B;;OAEG;IACH,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB;;OAEG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB;AAED,wBAAgB,KAAK,CAAC,EACpB,UAAsB,EACtB,SAAS,EACT,KAAK,EACL,QAAQ,EACR,aAAa,EACb,KAAK,EACL,eAAe,EACf,OAAmB,EACnB,qBAAqB,EACrB,OAAO,GACR,EAAE,UAAU,eA4BZ"}
@@ -1 +1 @@
1
- {"version":3,"file":"badge.js","sourceRoot":"","sources":["../../../src/components/display/badge.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { JSX } from 'react'\nimport type { TextStyle, ViewProps, ViewStyle } from 'react-native'\nimport { Pressable, StyleSheet, View } from 'react-native'\nimport Svg, { Defs, LinearGradient, Path, Stop } from 'react-native-svg'\nimport { useFontScale, useTheme } from '../../hooks'\nimport { platformFontWeightMedium, space } from '../../utils'\nimport { tokens } from '../../vendor/tapestry/tokens'\nimport { Icon, IconString } from './icon'\nimport { Text } from './text'\nimport { useStatusColorAppearanceMap, type StatusAppearanceUnion } from './utils/status_colors'\n\n// =================================\n// ====== Constants ================\n// =================================\n\nconst VARIANTS = {\n default: 'default',\n meta: 'meta',\n metaSubtle: 'metaSubtle',\n} as const\n\ntype VariantUnion = (typeof VARIANTS)[keyof typeof VARIANTS]\n\ntype VariantStyles = Record<\n VariantUnion,\n {\n backgroundColor: string\n paddingHorizontal: number\n paddingVertical: number\n borderWidth: number\n borderRadius: number\n textColor: string\n gap: number\n metaLabelPaddingLeft: number\n fontWeight: TextStyle['fontWeight']\n }\n>\n\ntype ProductLogoName = 'Groups' | 'Services' | 'groups' | 'services'\ntype ProductLogoComponent = ({ logoSize }: { logoSize: number }) => JSX.Element\n\nconst PRODUCT_LOGO_COMPONENT_MAP: Record<ProductLogoName, ProductLogoComponent> = {\n Groups: GroupsLogo,\n groups: GroupsLogo,\n services: ServicesIcon,\n Services: ServicesIcon,\n}\n\n// =================================\n// ====== Component ================\n// =================================\n\ninterface BadgeProps {\n /**\n * Renders the main text.\n */\n label: string\n /**\n * Renders secondary meta text to the right of the label.\n */\n metaLabel?: string\n /**\n * Changes the status color for the badge and icon.\n */\n appearance?: StatusAppearanceUnion\n /**\n * Changes form of the logo to support a meta label and badge\n */\n variant?: VariantUnion\n /**\n * Adds a product logo to the left of the text.\n */\n productLogoName?: ProductLogoName\n /**\n * Shows an icon of the user choice to the left of the text.\n */\n iconName?: IconString\n /**\n * Shows an icon of the user choice to the right of the text.\n */\n iconNameRight?: IconString\n /**\n * Styles badge wrapper.\n */\n style?: ViewStyle\n /**\n * Specifies the maximum size a font can reach when allowFontScaling is enabled.\n */\n maxFontSizeMultiplier?: number\n /**\n * Callback function when the badge is pressed.\n */\n onPress?: () => void\n}\n\nexport function Badge({\n appearance = 'neutral',\n metaLabel,\n style,\n iconName,\n iconNameRight,\n label,\n productLogoName,\n variant = 'default',\n maxFontSizeMultiplier,\n onPress,\n}: BadgeProps) {\n const styles = useStyles({ appearance, maxFontSizeMultiplier, variant })\n const { showBadgeProductLogo } = useTheme()\n\n const isMetaSubtle = variant === 'metaSubtle'\n const hasMetaLabel = Boolean(metaLabel)\n\n const showLogo = showBadgeProductLogo && productLogoName\n const ProductLogoSvg = showLogo && PRODUCT_LOGO_COMPONENT_MAP[productLogoName]\n const badgeLabel = isMetaSubtle && hasMetaLabel ? `${label}:` : label\n\n return (\n <BadgeWrapper style={[styles.badgeWrapper, style]} onPress={onPress} accessibilityRole=\"button\">\n <View style={styles.badge}>\n {showLogo && ProductLogoSvg && <ProductLogoSvg logoSize={styles.logo.fontSize} />}\n {iconName && <Icon name={iconName} style={styles.icon} />}\n <Text variant=\"footnote\" style={styles.label} numberOfLines={1}>\n {badgeLabel}\n </Text>\n {iconNameRight && <Icon name={iconNameRight} style={styles.iconRight} />}\n </View>\n {hasMetaLabel && (\n <Text variant=\"footnote\" style={styles.metaLabel} numberOfLines={1}>\n {metaLabel}\n </Text>\n )}\n </BadgeWrapper>\n )\n}\n\nconst BadgeWrapper = ({\n children,\n onPress,\n accessibilityRole,\n ...restProps\n}: ViewProps & Pick<BadgeProps, 'onPress'>) => {\n if (onPress) {\n return (\n <Pressable accessibilityRole={accessibilityRole} onPress={onPress} {...restProps}>\n {children}\n </Pressable>\n )\n }\n\n return <View {...restProps}>{children}</View>\n}\n\n// =================================\n// ====== Styles ===================\n// =================================\n\nconst useStyles = ({\n appearance = 'neutral',\n maxFontSizeMultiplier,\n variant = 'default',\n}: Partial<BadgeProps>) => {\n const { colors } = useTheme()\n const fontScale = useFontScale({ maxFontSizeMultiplier })\n\n const statusColorMap = useStatusColorAppearanceMap()\n\n const badgePaddingHorizontal = space(1) * fontScale\n const badgePaddingVertical = space(0.5) * fontScale\n const badgeGap = space(0.5) * fontScale\n const badgeFontSize = 12\n\n const variantStylesMap: VariantStyles = {\n default: {\n gap: badgeGap,\n backgroundColor: statusColorMap[appearance].background,\n metaLabelPaddingLeft: badgePaddingHorizontal,\n paddingHorizontal: badgePaddingHorizontal,\n paddingVertical: badgePaddingVertical,\n borderWidth: tokens.borderSizeDefault * fontScale,\n borderRadius: tokens.borderRadiusMd,\n textColor: statusColorMap[appearance].text,\n fontWeight: 'normal',\n },\n meta: {\n gap: badgeGap,\n backgroundColor: statusColorMap[appearance].background,\n metaLabelPaddingLeft: badgePaddingHorizontal,\n paddingHorizontal: badgePaddingHorizontal,\n paddingVertical: badgePaddingVertical,\n borderWidth: tokens.borderSizeDefault * fontScale,\n borderRadius: tokens.borderRadiusMd,\n textColor: statusColorMap[appearance].text,\n fontWeight: platformFontWeightMedium,\n },\n metaSubtle: {\n gap: badgeGap,\n backgroundColor: 'transparent',\n metaLabelPaddingLeft: badgeGap,\n paddingHorizontal: 0,\n paddingVertical: 0,\n borderWidth: 0,\n borderRadius: 0,\n textColor: colors.textColorDefaultSecondary,\n fontWeight: platformFontWeightMedium,\n },\n }\n\n return StyleSheet.create({\n badgeWrapper: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'center',\n alignSelf: 'flex-start',\n borderRadius: variantStylesMap[variant].borderRadius,\n borderWidth: variantStylesMap[variant].borderWidth,\n borderColor: statusColorMap[appearance].background,\n },\n badge: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: variantStylesMap[variant].gap,\n paddingVertical: variantStylesMap[variant].paddingVertical,\n paddingHorizontal: variantStylesMap[variant].paddingHorizontal,\n backgroundColor: variantStylesMap[variant].backgroundColor,\n borderRadius: variantStylesMap[variant].borderRadius - 2,\n },\n icon: {\n color: statusColorMap[appearance].icon,\n fontSize: badgeFontSize,\n },\n iconRight: {\n color: statusColorMap[appearance].icon,\n fontSize: badgeFontSize - 2,\n },\n logo: {\n fontSize: badgeFontSize * fontScale,\n },\n label: {\n color: variantStylesMap[variant].textColor,\n fontWeight: variantStylesMap[variant].fontWeight,\n fontSize: badgeFontSize,\n lineHeight: 15 * fontScale,\n flexShrink: 1,\n },\n metaLabel: {\n paddingHorizontal: variantStylesMap[variant].paddingHorizontal,\n fontSize: badgeFontSize,\n flexShrink: 1,\n paddingLeft: variantStylesMap[variant].metaLabelPaddingLeft,\n lineHeight: 15 * fontScale,\n },\n })\n}\n\n// =================================\n// ====== Product Logos ============\n// =================================\n\ninterface ProductLogoProps {\n logoSize: number\n}\n\nfunction GroupsLogo({ logoSize }: ProductLogoProps) {\n return (\n <Svg width={logoSize} height={logoSize} viewBox=\"0 0 16 16\" fill=\"none\">\n <Path\n d=\"M9.06 6.14H6.94c-.152.36-.438.646-.797.798v2.12c.359.152.645.438.797.797h2.117c.152-.359.437-.645.796-.797V6.94a1.502 1.502 0 01-.793-.8zM8 0C1.6 0 0 1.595 0 8s1.6 8 8 8 8-1.595 8-8-1.595-8-8-8zm3.939 10.44a1.5 1.5 0 01-2.882.585H6.94a1.5 1.5 0 11-1.963-1.963v-2.12A1.501 1.501 0 116.94 4.98h2.12a1.5 1.5 0 111.963 1.968v2.11a1.501 1.501 0 01.916 1.383z\"\n fill=\"url(#paint0_linear_2632_26363)\"\n />\n <Defs>\n <LinearGradient\n id=\"paint0_linear_2632_26363\"\n x1={-5.6338}\n y1={5.6338}\n x2={5.6338}\n y2={16.9014}\n gradientUnits=\"userSpaceOnUse\"\n >\n <Stop stopColor=\"#FF962D\" />\n <Stop offset={1} stopColor=\"#FC7638\" />\n </LinearGradient>\n </Defs>\n </Svg>\n )\n}\n\nfunction ServicesIcon({ logoSize }: ProductLogoProps) {\n return (\n <Svg width={logoSize} height={logoSize} viewBox=\"0 0 16 16\" fill=\"none\">\n <Path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M.116 8c0-6.4 1.6-8 8-8s8 1.6 8 8-1.6 8-8 8-8-1.6-8-8zm4.123 3.464a.848.848 0 10.943-1.41.848.848 0 00-.943 1.41zm.001-2.76a.848.848 0 10.948-1.408.848.848 0 00-.948 1.407zm0-2.759a.849.849 0 10.948-1.408.849.849 0 00-.948 1.408zm8.1 5.34a.388.388 0 00.03-.149v-.755a.39.39 0 00-.39-.39H6.87a.39.39 0 00-.39.39v.755a.39.39 0 00.39.39h5.11a.39.39 0 00.36-.24zm0-2.758a.388.388 0 00.03-.149v-.757a.387.387 0 00-.39-.388H6.87a.388.388 0 00-.39.388v.757a.388.388 0 00.39.388h5.11a.388.388 0 00.36-.24zm0-2.76a.388.388 0 00.03-.148v-.754a.39.39 0 00-.39-.389H6.87a.39.39 0 00-.39.387v.756a.39.39 0 00.39.39h5.11a.389.389 0 00.36-.241z\"\n fill=\"url(#paint0_linear_2632_56586)\"\n />\n <Defs>\n <LinearGradient\n id=\"paint0_linear_2632_56586\"\n x1={-5.51759}\n y1={5.6338}\n x2={5.75001}\n y2={16.9014}\n gradientUnits=\"userSpaceOnUse\"\n >\n <Stop stopColor=\"#6BB23D\" />\n <Stop offset={1} stopColor=\"#659630\" />\n </LinearGradient>\n </Defs>\n </Svg>\n )\n}\n"]}
1
+ {"version":3,"file":"badge.js","sourceRoot":"","sources":["../../../src/components/display/badge.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { JSX } from 'react'\nimport type { TextStyle, ViewProps, ViewStyle } from 'react-native'\nimport { Pressable, StyleSheet, View } from 'react-native'\nimport Svg, { Defs, LinearGradient, Path, Stop } from 'react-native-svg'\nimport { useFontScale, useTheme } from '../../hooks'\nimport { platformFontWeightMedium, space } from '../../utils'\nimport { tokens } from '../../vendor/tapestry/tokens'\nimport { Icon, IconString } from './icon'\nimport { Text } from './text'\nimport { useStatusColorAppearanceMap, type StatusAppearanceUnion } from './utils/status_colors'\n\n// =================================\n// ====== Constants ================\n// =================================\n\nconst VARIANTS = {\n default: 'default',\n meta: 'meta',\n metaSubtle: 'metaSubtle',\n} as const\n\ntype VariantUnion = (typeof VARIANTS)[keyof typeof VARIANTS]\n\ntype VariantStyles = Record<\n VariantUnion,\n {\n backgroundColor: string\n paddingHorizontal: number\n paddingVertical: number\n borderWidth: number\n borderRadius: number\n textColor: string\n gap: number\n metaLabelPaddingLeft: number\n fontWeight: TextStyle['fontWeight']\n }\n>\n\ntype ProductLogoName = 'Groups' | 'Services' | 'groups' | 'services'\ntype ProductLogoComponent = ({ logoSize }: { logoSize: number }) => JSX.Element\n\nconst PRODUCT_LOGO_COMPONENT_MAP: Record<ProductLogoName, ProductLogoComponent> = {\n Groups: GroupsLogo,\n groups: GroupsLogo,\n services: ServicesIcon,\n Services: ServicesIcon,\n}\n\n// =================================\n// ====== Component ================\n// =================================\n\nexport interface BadgeProps {\n /**\n * Renders the main text.\n */\n label: string\n /**\n * Renders secondary meta text to the right of the label.\n */\n metaLabel?: string\n /**\n * Changes the status color for the badge and icon.\n */\n appearance?: StatusAppearanceUnion\n /**\n * Changes form of the logo to support a meta label and badge\n */\n variant?: VariantUnion\n /**\n * Adds a product logo to the left of the text.\n */\n productLogoName?: ProductLogoName\n /**\n * Shows an icon of the user choice to the left of the text.\n */\n iconName?: IconString\n /**\n * Shows an icon of the user choice to the right of the text.\n */\n iconNameRight?: IconString\n /**\n * Styles badge wrapper.\n */\n style?: ViewStyle\n /**\n * Specifies the maximum size a font can reach when allowFontScaling is enabled.\n */\n maxFontSizeMultiplier?: number\n /**\n * Callback function when the badge is pressed.\n */\n onPress?: () => void\n}\n\nexport function Badge({\n appearance = 'neutral',\n metaLabel,\n style,\n iconName,\n iconNameRight,\n label,\n productLogoName,\n variant = 'default',\n maxFontSizeMultiplier,\n onPress,\n}: BadgeProps) {\n const styles = useStyles({ appearance, maxFontSizeMultiplier, variant })\n const { showBadgeProductLogo } = useTheme()\n\n const isMetaSubtle = variant === 'metaSubtle'\n const hasMetaLabel = Boolean(metaLabel)\n\n const showLogo = showBadgeProductLogo && productLogoName\n const ProductLogoSvg = showLogo && PRODUCT_LOGO_COMPONENT_MAP[productLogoName]\n const badgeLabel = isMetaSubtle && hasMetaLabel ? `${label}:` : label\n\n return (\n <BadgeWrapper style={[styles.badgeWrapper, style]} onPress={onPress} accessibilityRole=\"button\">\n <View style={styles.badge}>\n {showLogo && ProductLogoSvg && <ProductLogoSvg logoSize={styles.logo.fontSize} />}\n {iconName && <Icon name={iconName} style={styles.icon} />}\n <Text variant=\"footnote\" style={styles.label} numberOfLines={1}>\n {badgeLabel}\n </Text>\n {iconNameRight && <Icon name={iconNameRight} style={styles.iconRight} />}\n </View>\n {hasMetaLabel && (\n <Text variant=\"footnote\" style={styles.metaLabel} numberOfLines={1}>\n {metaLabel}\n </Text>\n )}\n </BadgeWrapper>\n )\n}\n\nconst BadgeWrapper = ({\n children,\n onPress,\n accessibilityRole,\n ...restProps\n}: ViewProps & Pick<BadgeProps, 'onPress'>) => {\n if (onPress) {\n return (\n <Pressable accessibilityRole={accessibilityRole} onPress={onPress} {...restProps}>\n {children}\n </Pressable>\n )\n }\n\n return <View {...restProps}>{children}</View>\n}\n\n// =================================\n// ====== Styles ===================\n// =================================\n\nconst useStyles = ({\n appearance = 'neutral',\n maxFontSizeMultiplier,\n variant = 'default',\n}: Partial<BadgeProps>) => {\n const { colors } = useTheme()\n const fontScale = useFontScale({ maxFontSizeMultiplier })\n\n const statusColorMap = useStatusColorAppearanceMap()\n\n const badgePaddingHorizontal = space(1) * fontScale\n const badgePaddingVertical = space(0.5) * fontScale\n const badgeGap = space(0.5) * fontScale\n const badgeFontSize = 12\n\n const variantStylesMap: VariantStyles = {\n default: {\n gap: badgeGap,\n backgroundColor: statusColorMap[appearance].background,\n metaLabelPaddingLeft: badgePaddingHorizontal,\n paddingHorizontal: badgePaddingHorizontal,\n paddingVertical: badgePaddingVertical,\n borderWidth: tokens.borderSizeDefault * fontScale,\n borderRadius: tokens.borderRadiusMd,\n textColor: statusColorMap[appearance].text,\n fontWeight: 'normal',\n },\n meta: {\n gap: badgeGap,\n backgroundColor: statusColorMap[appearance].background,\n metaLabelPaddingLeft: badgePaddingHorizontal,\n paddingHorizontal: badgePaddingHorizontal,\n paddingVertical: badgePaddingVertical,\n borderWidth: tokens.borderSizeDefault * fontScale,\n borderRadius: tokens.borderRadiusMd,\n textColor: statusColorMap[appearance].text,\n fontWeight: platformFontWeightMedium,\n },\n metaSubtle: {\n gap: badgeGap,\n backgroundColor: 'transparent',\n metaLabelPaddingLeft: badgeGap,\n paddingHorizontal: 0,\n paddingVertical: 0,\n borderWidth: 0,\n borderRadius: 0,\n textColor: colors.textColorDefaultSecondary,\n fontWeight: platformFontWeightMedium,\n },\n }\n\n return StyleSheet.create({\n badgeWrapper: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'center',\n alignSelf: 'flex-start',\n borderRadius: variantStylesMap[variant].borderRadius,\n borderWidth: variantStylesMap[variant].borderWidth,\n borderColor: statusColorMap[appearance].background,\n },\n badge: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: variantStylesMap[variant].gap,\n paddingVertical: variantStylesMap[variant].paddingVertical,\n paddingHorizontal: variantStylesMap[variant].paddingHorizontal,\n backgroundColor: variantStylesMap[variant].backgroundColor,\n borderRadius: variantStylesMap[variant].borderRadius - 2,\n },\n icon: {\n color: statusColorMap[appearance].icon,\n fontSize: badgeFontSize,\n },\n iconRight: {\n color: statusColorMap[appearance].icon,\n fontSize: badgeFontSize - 2,\n },\n logo: {\n fontSize: badgeFontSize * fontScale,\n },\n label: {\n color: variantStylesMap[variant].textColor,\n fontWeight: variantStylesMap[variant].fontWeight,\n fontSize: badgeFontSize,\n lineHeight: 15 * fontScale,\n flexShrink: 1,\n },\n metaLabel: {\n paddingHorizontal: variantStylesMap[variant].paddingHorizontal,\n fontSize: badgeFontSize,\n flexShrink: 1,\n paddingLeft: variantStylesMap[variant].metaLabelPaddingLeft,\n lineHeight: 15 * fontScale,\n },\n })\n}\n\n// =================================\n// ====== Product Logos ============\n// =================================\n\ninterface ProductLogoProps {\n logoSize: number\n}\n\nfunction GroupsLogo({ logoSize }: ProductLogoProps) {\n return (\n <Svg width={logoSize} height={logoSize} viewBox=\"0 0 16 16\" fill=\"none\">\n <Path\n d=\"M9.06 6.14H6.94c-.152.36-.438.646-.797.798v2.12c.359.152.645.438.797.797h2.117c.152-.359.437-.645.796-.797V6.94a1.502 1.502 0 01-.793-.8zM8 0C1.6 0 0 1.595 0 8s1.6 8 8 8 8-1.595 8-8-1.595-8-8-8zm3.939 10.44a1.5 1.5 0 01-2.882.585H6.94a1.5 1.5 0 11-1.963-1.963v-2.12A1.501 1.501 0 116.94 4.98h2.12a1.5 1.5 0 111.963 1.968v2.11a1.501 1.501 0 01.916 1.383z\"\n fill=\"url(#paint0_linear_2632_26363)\"\n />\n <Defs>\n <LinearGradient\n id=\"paint0_linear_2632_26363\"\n x1={-5.6338}\n y1={5.6338}\n x2={5.6338}\n y2={16.9014}\n gradientUnits=\"userSpaceOnUse\"\n >\n <Stop stopColor=\"#FF962D\" />\n <Stop offset={1} stopColor=\"#FC7638\" />\n </LinearGradient>\n </Defs>\n </Svg>\n )\n}\n\nfunction ServicesIcon({ logoSize }: ProductLogoProps) {\n return (\n <Svg width={logoSize} height={logoSize} viewBox=\"0 0 16 16\" fill=\"none\">\n <Path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M.116 8c0-6.4 1.6-8 8-8s8 1.6 8 8-1.6 8-8 8-8-1.6-8-8zm4.123 3.464a.848.848 0 10.943-1.41.848.848 0 00-.943 1.41zm.001-2.76a.848.848 0 10.948-1.408.848.848 0 00-.948 1.407zm0-2.759a.849.849 0 10.948-1.408.849.849 0 00-.948 1.408zm8.1 5.34a.388.388 0 00.03-.149v-.755a.39.39 0 00-.39-.39H6.87a.39.39 0 00-.39.39v.755a.39.39 0 00.39.39h5.11a.39.39 0 00.36-.24zm0-2.758a.388.388 0 00.03-.149v-.757a.387.387 0 00-.39-.388H6.87a.388.388 0 00-.39.388v.757a.388.388 0 00.39.388h5.11a.388.388 0 00.36-.24zm0-2.76a.388.388 0 00.03-.148v-.754a.39.39 0 00-.39-.389H6.87a.39.39 0 00-.39.387v.756a.39.39 0 00.39.39h5.11a.389.389 0 00.36-.241z\"\n fill=\"url(#paint0_linear_2632_56586)\"\n />\n <Defs>\n <LinearGradient\n id=\"paint0_linear_2632_56586\"\n x1={-5.51759}\n y1={5.6338}\n x2={5.75001}\n y2={16.9014}\n gradientUnits=\"userSpaceOnUse\"\n >\n <Stop stopColor=\"#6BB23D\" />\n <Stop offset={1} stopColor=\"#659630\" />\n </LinearGradient>\n </Defs>\n </Svg>\n )\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"conversations_context.d.ts","sourceRoot":"","sources":["../../src/contexts/conversations_context.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAiB,iBAAiB,EAAiC,MAAM,OAAO,CAAA;AAC9F,OAAO,EAAE,yBAAyB,EAAE,MAAM,8CAA8C,CAAA;AACxF,OAAO,EAAoB,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AASpF,UAAU,yBAA0B,SAAQ,qBAAqB;IAC/D,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,uBAAuB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9C,IAAI,EAAE,yBAAyB,CAAA;CAChC;AAqBD,eAAO,MAAM,4BAA4B,wBAGtC,iBAAiB,CAAC;IAAE,IAAI,EAAE,yBAAyB,CAAA;CAAE,CAAC,sBAmBxD,CAAA;AAUD,eAAO,MAAM,uBAAuB,iCAAyC,CAAA"}
1
+ {"version":3,"file":"conversations_context.d.ts","sourceRoot":"","sources":["../../src/contexts/conversations_context.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAiB,iBAAiB,EAAiC,MAAM,OAAO,CAAA;AAC9F,OAAO,EAAE,yBAAyB,EAAE,MAAM,8CAA8C,CAAA;AACxF,OAAO,EAAoB,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAQpF,UAAU,yBAA0B,SAAQ,qBAAqB;IAC/D,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,uBAAuB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9C,IAAI,EAAE,yBAAyB,CAAA;CAChC;AAsBD,eAAO,MAAM,4BAA4B,wBAGtC,iBAAiB,CAAC;IAAE,IAAI,EAAE,yBAAyB,CAAA;CAAE,CAAC,sBAiBxD,CAAA;AAUD,eAAO,MAAM,uBAAuB,iCAAyC,CAAA"}
@@ -1,11 +1,11 @@
1
1
  import React, { createContext, useContext, useMemo, useState } from 'react';
2
2
  import { useConversations } from '../hooks/use_conversations';
3
- import { useConversationsJoltEvents } from '../hooks/use_conversations_jolt_events';
4
3
  const defaultQueryValue = {
5
4
  conversations: [],
6
5
  refetch: () => Promise.resolve(null),
7
6
  error: null,
8
7
  isError: false,
8
+ isLoading: true,
9
9
  fetchNextPage,
10
10
  hasNextPage: false,
11
11
  isFetching: false,
@@ -28,7 +28,6 @@ export const ConversationsContextProvider = ({ children, args = {}, }) => {
28
28
  setActiveConversationId,
29
29
  ...query,
30
30
  }), [args, activeConversationId, query]);
31
- useConversationsJoltEvents(args);
32
31
  return <ConversationsContext.Provider value={value}>{children}</ConversationsContext.Provider>;
33
32
  };
34
33
  function fetchNextPage(_options) {
@@ -1 +1 @@
1
- {"version":3,"file":"conversations_context.js","sourceRoot":"","sources":["../../src/contexts/conversations_context.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,aAAa,EAAqB,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAE9F,OAAO,EAAE,gBAAgB,EAAyB,MAAM,4BAA4B,CAAA;AAOpF,OAAO,EAAE,0BAA0B,EAAE,MAAM,wCAAwC,CAAA;AAQnF,MAAM,iBAAiB,GAA0B;IAC/C,aAAa,EAAE,EAAE;IACjB,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;IACpC,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,KAAK;IACd,aAAa;IACb,WAAW,EAAE,KAAK;IAClB,UAAU,EAAE,KAAK;IACjB,SAAS,EAAE,KAAK;IAChB,YAAY,EAAE,KAAK;CACpB,CAAA;AAED,MAAM,oBAAoB,GAAG,aAAa,CAA4B;IACpE,IAAI,EAAE,EAAE;IACR,oBAAoB,EAAE,SAAS;IAC/B,uBAAuB,EAAE,GAAG,EAAE,GAAE,CAAC;IACjC,GAAG,iBAAiB;CACrB,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,EAC3C,QAAQ,EACR,IAAI,GAAG,EAAE,GAC8C,EAAE,EAAE;IAC3D,MAAM,CAAC,oBAAoB,EAAE,uBAAuB,CAAC,GAAG,QAAQ,EAAsB,CAAA;IACtF,MAAM,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,GAAG,IAAI,CAAA;IAE3D,MAAM,KAAK,GAAG,gBAAgB,CAAC,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,CAAC,CAAA;IAE9E,MAAM,KAAK,GAAG,OAAO,CACnB,GAAG,EAAE,CAAC,CAAC;QACL,IAAI;QACJ,oBAAoB;QACpB,uBAAuB;QACvB,GAAG,KAAK;KACT,CAAC,EACF,CAAC,IAAI,EAAE,oBAAoB,EAAE,KAAK,CAAC,CACpC,CAAA;IAED,0BAA0B,CAAC,IAAI,CAAC,CAAA;IAEhC,OAAO,CAAC,oBAAoB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,oBAAoB,CAAC,QAAQ,CAAC,CAAA;AAChG,CAAC,CAAA;AAED,SAAS,aAAa,CACpB,QAA+B;IAI/B,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAA;AAC9C,CAAC;AAED,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,EAAE,CAAC,UAAU,CAAC,oBAAoB,CAAC,CAAA","sourcesContent":["import React, { createContext, PropsWithChildren, useContext, useMemo, useState } from 'react'\nimport { ConversationFiltersParams } from '../screens/conversation_filters/screen_props'\nimport { useConversations, UseConversationsValue } from '../hooks/use_conversations'\nimport {\n FetchNextPageOptions,\n InfiniteQueryObserverResult,\n InfiniteData,\n} from '@tanstack/react-query'\nimport { ApiCollection, ConversationResource } from '../types'\nimport { useConversationsJoltEvents } from '../hooks/use_conversations_jolt_events'\n\ninterface ConversationsContextValue extends UseConversationsValue {\n activeConversationId?: number\n setActiveConversationId: (_id: number) => void\n args: ConversationFiltersParams\n}\n\nconst defaultQueryValue: UseConversationsValue = {\n conversations: [],\n refetch: () => Promise.resolve(null),\n error: null,\n isError: false,\n fetchNextPage,\n hasNextPage: false,\n isFetching: false,\n isFetched: false,\n isRefetching: false,\n}\n\nconst ConversationsContext = createContext<ConversationsContextValue>({\n args: {},\n activeConversationId: undefined,\n setActiveConversationId: () => {},\n ...defaultQueryValue,\n})\n\nexport const ConversationsContextProvider = ({\n children,\n args = {},\n}: PropsWithChildren<{ args: ConversationFiltersParams }>) => {\n const [activeConversationId, setActiveConversationId] = useState<number | undefined>()\n const { chat_group_graph_id, group_source_app_name } = args\n\n const query = useConversations({ chat_group_graph_id, group_source_app_name })\n\n const value = useMemo(\n () => ({\n args,\n activeConversationId,\n setActiveConversationId,\n ...query,\n }),\n [args, activeConversationId, query]\n )\n\n useConversationsJoltEvents(args)\n\n return <ConversationsContext.Provider value={value}>{children}</ConversationsContext.Provider>\n}\n\nfunction fetchNextPage(\n _options?: FetchNextPageOptions\n): Promise<\n InfiniteQueryObserverResult<InfiniteData<ApiCollection<ConversationResource>, unknown>, Response>\n> {\n throw new Error('Function not implemented.')\n}\n\nexport const useConversationsContext = () => useContext(ConversationsContext)\n"]}
1
+ {"version":3,"file":"conversations_context.js","sourceRoot":"","sources":["../../src/contexts/conversations_context.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,aAAa,EAAqB,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAE9F,OAAO,EAAE,gBAAgB,EAAyB,MAAM,4BAA4B,CAAA;AAcpF,MAAM,iBAAiB,GAA0B;IAC/C,aAAa,EAAE,EAAE;IACjB,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;IACpC,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,IAAI;IACf,aAAa;IACb,WAAW,EAAE,KAAK;IAClB,UAAU,EAAE,KAAK;IACjB,SAAS,EAAE,KAAK;IAChB,YAAY,EAAE,KAAK;CACpB,CAAA;AAED,MAAM,oBAAoB,GAAG,aAAa,CAA4B;IACpE,IAAI,EAAE,EAAE;IACR,oBAAoB,EAAE,SAAS;IAC/B,uBAAuB,EAAE,GAAG,EAAE,GAAE,CAAC;IACjC,GAAG,iBAAiB;CACrB,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,EAC3C,QAAQ,EACR,IAAI,GAAG,EAAE,GAC8C,EAAE,EAAE;IAC3D,MAAM,CAAC,oBAAoB,EAAE,uBAAuB,CAAC,GAAG,QAAQ,EAAsB,CAAA;IACtF,MAAM,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,GAAG,IAAI,CAAA;IAE3D,MAAM,KAAK,GAAG,gBAAgB,CAAC,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,CAAC,CAAA;IAE9E,MAAM,KAAK,GAAG,OAAO,CACnB,GAAG,EAAE,CAAC,CAAC;QACL,IAAI;QACJ,oBAAoB;QACpB,uBAAuB;QACvB,GAAG,KAAK;KACT,CAAC,EACF,CAAC,IAAI,EAAE,oBAAoB,EAAE,KAAK,CAAC,CACpC,CAAA;IAED,OAAO,CAAC,oBAAoB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,oBAAoB,CAAC,QAAQ,CAAC,CAAA;AAChG,CAAC,CAAA;AAED,SAAS,aAAa,CACpB,QAA+B;IAI/B,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAA;AAC9C,CAAC;AAED,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,EAAE,CAAC,UAAU,CAAC,oBAAoB,CAAC,CAAA","sourcesContent":["import React, { createContext, PropsWithChildren, useContext, useMemo, useState } from 'react'\nimport { ConversationFiltersParams } from '../screens/conversation_filters/screen_props'\nimport { useConversations, UseConversationsValue } from '../hooks/use_conversations'\nimport {\n FetchNextPageOptions,\n InfiniteQueryObserverResult,\n InfiniteData,\n} from '@tanstack/react-query'\nimport { ApiCollection, ConversationResource } from '../types'\n\ninterface ConversationsContextValue extends UseConversationsValue {\n activeConversationId?: number\n setActiveConversationId: (_id: number) => void\n args: ConversationFiltersParams\n}\n\nconst defaultQueryValue: UseConversationsValue = {\n conversations: [],\n refetch: () => Promise.resolve(null),\n error: null,\n isError: false,\n isLoading: true,\n fetchNextPage,\n hasNextPage: false,\n isFetching: false,\n isFetched: false,\n isRefetching: false,\n}\n\nconst ConversationsContext = createContext<ConversationsContextValue>({\n args: {},\n activeConversationId: undefined,\n setActiveConversationId: () => {},\n ...defaultQueryValue,\n})\n\nexport const ConversationsContextProvider = ({\n children,\n args = {},\n}: PropsWithChildren<{ args: ConversationFiltersParams }>) => {\n const [activeConversationId, setActiveConversationId] = useState<number | undefined>()\n const { chat_group_graph_id, group_source_app_name } = args\n\n const query = useConversations({ chat_group_graph_id, group_source_app_name })\n\n const value = useMemo(\n () => ({\n args,\n activeConversationId,\n setActiveConversationId,\n ...query,\n }),\n [args, activeConversationId, query]\n )\n\n return <ConversationsContext.Provider value={value}>{children}</ConversationsContext.Provider>\n}\n\nfunction fetchNextPage(\n _options?: FetchNextPageOptions\n): Promise<\n InfiniteQueryObserverResult<InfiniteData<ApiCollection<ConversationResource>, unknown>, Response>\n> {\n throw new Error('Function not implemented.')\n}\n\nexport const useConversationsContext = () => useContext(ConversationsContext)\n"]}
@@ -1,8 +1,8 @@
1
- import { InfiniteData, UseSuspenseInfiniteQueryResult } from '@tanstack/react-query';
1
+ import { InfiniteData, UseInfiniteQueryResult } from '@tanstack/react-query';
2
2
  import { ApiCollection, ConversationResource } from '../types';
3
3
  import { ConversationRequestArgs } from '../utils/request/conversation';
4
- export type ConversationPaginationResult = UseSuspenseInfiniteQueryResult<InfiniteData<ApiCollection<ConversationResource>, unknown>, Response>;
5
- export type UseConversationsValue = Pick<ConversationPaginationResult, 'isFetching' | 'isError' | 'error' | 'fetchNextPage' | 'hasNextPage' | 'isFetched' | 'isRefetching'> & {
4
+ export type ConversationPaginationResult = UseInfiniteQueryResult<InfiniteData<ApiCollection<ConversationResource>, unknown>, Response>;
5
+ export type UseConversationsValue = Pick<ConversationPaginationResult, 'isFetching' | 'isError' | 'isLoading' | 'error' | 'fetchNextPage' | 'hasNextPage' | 'isFetched' | 'isRefetching'> & {
6
6
  conversations: ConversationResource[];
7
7
  refetch: () => Promise<any>;
8
8
  };
@@ -1 +1 @@
1
- {"version":3,"file":"use_conversations.d.ts","sourceRoot":"","sources":["../../src/hooks/use_conversations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,8BAA8B,EAAE,MAAM,uBAAuB,CAAA;AAEpF,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAC9D,OAAO,EAAE,uBAAuB,EAA+B,MAAM,+BAA+B,CAAA;AAGpG,MAAM,MAAM,4BAA4B,GAAG,8BAA8B,CACvE,YAAY,CAAC,aAAa,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC,EAC1D,QAAQ,CACT,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG,IAAI,CACtC,4BAA4B,EAC1B,YAAY,GACZ,SAAS,GACT,OAAO,GACP,eAAe,GACf,aAAa,GACb,WAAW,GACX,cAAc,CACjB,GAAG;IACF,aAAa,EAAE,oBAAoB,EAAE,CAAA;IACrC,OAAO,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,CAAA;CAC5B,CAAA;AAED,wBAAgB,gBAAgB,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAAG,qBAAqB,CAO/F"}
1
+ {"version":3,"file":"use_conversations.d.ts","sourceRoot":"","sources":["../../src/hooks/use_conversations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAE5E,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAC9D,OAAO,EAAE,uBAAuB,EAA+B,MAAM,+BAA+B,CAAA;AAGpG,MAAM,MAAM,4BAA4B,GAAG,sBAAsB,CAC/D,YAAY,CAAC,aAAa,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC,EAC1D,QAAQ,CACT,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG,IAAI,CACtC,4BAA4B,EAC1B,YAAY,GACZ,SAAS,GACT,WAAW,GACX,OAAO,GACP,eAAe,GACf,aAAa,GACb,WAAW,GACX,cAAc,CACjB,GAAG;IACF,aAAa,EAAE,oBAAoB,EAAE,CAAA;IACrC,OAAO,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,CAAA;CAC5B,CAAA;AAED,wBAAgB,gBAAgB,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAAG,qBAAqB,CAO/F"}
@@ -1,9 +1,9 @@
1
1
  import { useMemo } from 'react';
2
2
  import { getConversationsRequestArgs } from '../utils/request/conversation';
3
- import { useSuspensePaginator } from './use_suspense_api';
3
+ import { useApiPaginator } from './use_api';
4
4
  export function useConversations(args) {
5
5
  const requestArgs = getConversationsRequestArgs(args);
6
- const { data, ...rest } = useSuspensePaginator(requestArgs);
6
+ const { data, ...rest } = useApiPaginator(requestArgs);
7
7
  const conversations = useMemo(() => data.sort(sortByLastMessage), [data]);
8
8
  return { conversations, ...rest };
9
9
  }
@@ -1 +1 @@
1
- {"version":3,"file":"use_conversations.js","sourceRoot":"","sources":["../../src/hooks/use_conversations.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAE/B,OAAO,EAA2B,2BAA2B,EAAE,MAAM,+BAA+B,CAAA;AACpG,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAqBzD,MAAM,UAAU,gBAAgB,CAAC,IAAuC;IACtE,MAAM,WAAW,GAAG,2BAA2B,CAAC,IAAI,CAAC,CAAA;IACrD,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,GAAG,oBAAoB,CAAuB,WAAW,CAAC,CAAA;IAEjF,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IAEzE,OAAO,EAAE,aAAa,EAAE,GAAG,IAAI,EAAE,CAAA;AACnC,CAAC;AAED,SAAS,iBAAiB,CAAC,CAAuB,EAAE,CAAuB;IACzE,MAAM,KAAK,GAAG,CAAC,CAAC,oBAAoB,IAAI,CAAC,CAAC,SAAS,CAAA;IACnD,MAAM,KAAK,GAAG,CAAC,CAAC,oBAAoB,IAAI,CAAC,CAAC,SAAS,CAAA;IACnD,IAAI,CAAC,CAAC,oBAAoB,IAAI,CAAC,CAAC,CAAC,oBAAoB;QAAE,OAAO,CAAC,CAAA;IAC/D,IAAI,CAAC,CAAC,CAAC,oBAAoB,IAAI,CAAC,CAAC,oBAAoB;QAAE,OAAO,CAAC,CAAC,CAAA;IAChE,IAAI,KAAK,GAAG,KAAK;QAAE,OAAO,CAAC,CAAA;IAC3B,IAAI,KAAK,GAAG,KAAK;QAAE,OAAO,CAAC,CAAC,CAAA;IAC5B,OAAO,CAAC,CAAA;AACV,CAAC","sourcesContent":["import { InfiniteData, UseSuspenseInfiniteQueryResult } from '@tanstack/react-query'\nimport { useMemo } from 'react'\nimport { ApiCollection, ConversationResource } from '../types'\nimport { ConversationRequestArgs, getConversationsRequestArgs } from '../utils/request/conversation'\nimport { useSuspensePaginator } from './use_suspense_api'\n\nexport type ConversationPaginationResult = UseSuspenseInfiniteQueryResult<\n InfiniteData<ApiCollection<ConversationResource>, unknown>,\n Response\n>\n\nexport type UseConversationsValue = Pick<\n ConversationPaginationResult,\n | 'isFetching'\n | 'isError'\n | 'error'\n | 'fetchNextPage'\n | 'hasNextPage'\n | 'isFetched'\n | 'isRefetching'\n> & {\n conversations: ConversationResource[]\n refetch: () => Promise<any>\n}\n\nexport function useConversations(args?: Partial<ConversationRequestArgs>): UseConversationsValue {\n const requestArgs = getConversationsRequestArgs(args)\n const { data, ...rest } = useSuspensePaginator<ConversationResource>(requestArgs)\n\n const conversations = useMemo(() => data.sort(sortByLastMessage), [data])\n\n return { conversations, ...rest }\n}\n\nfunction sortByLastMessage(a: ConversationResource, b: ConversationResource): number {\n const dateA = a.lastMessageCreatedAt || a.createdAt\n const dateB = b.lastMessageCreatedAt || b.createdAt\n if (a.lastMessageCreatedAt && !b.lastMessageCreatedAt) return 1\n if (!a.lastMessageCreatedAt && b.lastMessageCreatedAt) return -1\n if (dateB > dateA) return 1\n if (dateB < dateA) return -1\n return 0\n}\n"]}
1
+ {"version":3,"file":"use_conversations.js","sourceRoot":"","sources":["../../src/hooks/use_conversations.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAE/B,OAAO,EAA2B,2BAA2B,EAAE,MAAM,+BAA+B,CAAA;AACpG,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAsB3C,MAAM,UAAU,gBAAgB,CAAC,IAAuC;IACtE,MAAM,WAAW,GAAG,2BAA2B,CAAC,IAAI,CAAC,CAAA;IACrD,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,GAAG,eAAe,CAAuB,WAAW,CAAC,CAAA;IAE5E,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IAEzE,OAAO,EAAE,aAAa,EAAE,GAAG,IAAI,EAAE,CAAA;AACnC,CAAC;AAED,SAAS,iBAAiB,CAAC,CAAuB,EAAE,CAAuB;IACzE,MAAM,KAAK,GAAG,CAAC,CAAC,oBAAoB,IAAI,CAAC,CAAC,SAAS,CAAA;IACnD,MAAM,KAAK,GAAG,CAAC,CAAC,oBAAoB,IAAI,CAAC,CAAC,SAAS,CAAA;IACnD,IAAI,CAAC,CAAC,oBAAoB,IAAI,CAAC,CAAC,CAAC,oBAAoB;QAAE,OAAO,CAAC,CAAA;IAC/D,IAAI,CAAC,CAAC,CAAC,oBAAoB,IAAI,CAAC,CAAC,oBAAoB;QAAE,OAAO,CAAC,CAAC,CAAA;IAChE,IAAI,KAAK,GAAG,KAAK;QAAE,OAAO,CAAC,CAAA;IAC3B,IAAI,KAAK,GAAG,KAAK;QAAE,OAAO,CAAC,CAAC,CAAA;IAC5B,OAAO,CAAC,CAAA;AACV,CAAC","sourcesContent":["import { InfiniteData, UseInfiniteQueryResult } from '@tanstack/react-query'\nimport { useMemo } from 'react'\nimport { ApiCollection, ConversationResource } from '../types'\nimport { ConversationRequestArgs, getConversationsRequestArgs } from '../utils/request/conversation'\nimport { useApiPaginator } from './use_api'\n\nexport type ConversationPaginationResult = UseInfiniteQueryResult<\n InfiniteData<ApiCollection<ConversationResource>, unknown>,\n Response\n>\n\nexport type UseConversationsValue = Pick<\n ConversationPaginationResult,\n | 'isFetching'\n | 'isError'\n | 'isLoading'\n | 'error'\n | 'fetchNextPage'\n | 'hasNextPage'\n | 'isFetched'\n | 'isRefetching'\n> & {\n conversations: ConversationResource[]\n refetch: () => Promise<any>\n}\n\nexport function useConversations(args?: Partial<ConversationRequestArgs>): UseConversationsValue {\n const requestArgs = getConversationsRequestArgs(args)\n const { data, ...rest } = useApiPaginator<ConversationResource>(requestArgs)\n\n const conversations = useMemo(() => data.sort(sortByLastMessage), [data])\n\n return { conversations, ...rest }\n}\n\nfunction sortByLastMessage(a: ConversationResource, b: ConversationResource): number {\n const dateA = a.lastMessageCreatedAt || a.createdAt\n const dateB = b.lastMessageCreatedAt || b.createdAt\n if (a.lastMessageCreatedAt && !b.lastMessageCreatedAt) return 1\n if (!a.lastMessageCreatedAt && b.lastMessageCreatedAt) return -1\n if (dateB > dateA) return 1\n if (dateB < dateA) return -1\n return 0\n}\n"]}
@@ -20,7 +20,7 @@ const HeaderRight = () => {
20
20
  : 'Saves selected teams and navigates to the final step to create your conversation.';
21
21
  return (<View style={styles.headerRight}>
22
22
  <TextButton onPress={resetTeamFilters} accessibilityHint="Cancels any selected teams and closes this modal.">
23
- Reset
23
+ Cancel
24
24
  </TextButton>
25
25
  <Button title="Apply" accessibilityHint={applyButtonAccessibilityHint} onPress={() => applyTeamFilters(route.params)} disabled={noTeamsSelected}/>
26
26
  </View>);
@@ -1 +1 @@
1
- {"version":3,"file":"navigation_header.js","sourceRoot":"","sources":["../../../../src/screens/conversation_filter_recipients/components/navigation_header.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAoB,MAAM,4BAA4B,CAAA;AAC1E,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AACxD,OAAO,EAAa,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAA;AACxD,OAAO,EACL,wBAAwB,EACxB,0BAA0B,GAC3B,MAAM,mDAAmD,CAAA;AAG1D,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,EAAE,SAAS,EAAoB,EAAE,EAAE;IACnE,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAE1B,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,YAAY,EAAE,WAAW,CAAC,CAAA;AACnG,CAAC,CAAA;AAED,MAAM,WAAW,GAAG,GAAG,EAAE;IACvB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,KAAK,GAAG,QAAQ,EAA+D,CAAA;IACrF,MAAM,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,GAAG,0BAA0B,EAAE,CAAA;IAE3E,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC,MAAM,CAAA;IACjC,MAAM,eAAe,GAAG,QAAQ,EAAE,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAA;IAC3D,MAAM,4BAA4B,GAAG,eAAe;QAClD,CAAC,CAAC,uFAAuF;QACzF,CAAC,CAAC,mFAAmF,CAAA;IAEvF,OAAO,CACL,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAC9B;MAAA,CAAC,UAAU,CACT,OAAO,CAAC,CAAC,gBAAgB,CAAC,CAC1B,iBAAiB,CAAC,mDAAmD,CAErE;;MACF,EAAE,UAAU,CACZ;MAAA,CAAC,MAAM,CACL,KAAK,CAAC,OAAO,CACb,iBAAiB,CAAC,CAAC,4BAA4B,CAAC,CAChD,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAC9C,QAAQ,CAAC,CAAC,eAAe,CAAC,EAE9B;IAAA,EAAE,IAAI,CAAC,CACR,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,EAAE;IACzC,OAAO,CACL,CAAC,wBAAwB,CACvB;MAAA,CAAC,WAAW,CAAC,AAAD,EACd;IAAA,EAAE,wBAAwB,CAAC,CAC5B,CAAA;AACH,CAAC,CAAA;AAED,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,OAAO,UAAU,CAAC,MAAM,CAAC;QACvB,WAAW,EAAE;YACX,QAAQ,EAAE,MAAM,CAAC,UAAU;YAC3B,IAAI,EAAE,CAAC;SACR;QACD,WAAW,EAAE;YACX,aAAa,EAAE,KAAK;YACpB,GAAG,EAAE,EAAE;YACP,UAAU,EAAE,QAAQ;SACrB;KACF,CAAC,CAAA;AACJ,CAAC,CAAA","sourcesContent":["import { HeaderTitle, HeaderTitleProps } from '@react-navigation/elements'\nimport React from 'react'\nimport { StyleSheet, View } from 'react-native'\nimport { Button, TextButton } from '../../../components'\nimport { RouteProp, useRoute } from '@react-navigation/native'\nimport { tokens } from '../../../vendor/tapestry/tokens'\nimport {\n FilterRecipientsProvider,\n useFilterRecipientsContext,\n} from '../context/conversation_filter_recipients_context'\nimport { ConversationFilterRecipientsScreenProps } from '../types'\n\nexport const FilterHeaderTitle = ({ tintColor }: HeaderTitleProps) => {\n const styles = useStyles()\n\n return <HeaderTitle style={[styles.headerTitle, { color: tintColor }]}>Teams I lead</HeaderTitle>\n}\n\nconst HeaderRight = () => {\n const styles = useStyles()\n const route = useRoute<RouteProp<ConversationFilterRecipientsScreenProps['route']>>()\n const { resetTeamFilters, applyTeamFilters } = useFilterRecipientsContext()\n\n const { team_ids } = route.params\n const noTeamsSelected = team_ids?.length === 0 || !team_ids\n const applyButtonAccessibilityHint = noTeamsSelected\n ? 'Select at least one team to navigate to the final step in creating your conversation.'\n : 'Saves selected teams and navigates to the final step to create your conversation.'\n\n return (\n <View style={styles.headerRight}>\n <TextButton\n onPress={resetTeamFilters}\n accessibilityHint=\"Cancels any selected teams and closes this modal.\"\n >\n Reset\n </TextButton>\n <Button\n title=\"Apply\"\n accessibilityHint={applyButtonAccessibilityHint}\n onPress={() => applyTeamFilters(route.params)}\n disabled={noTeamsSelected}\n />\n </View>\n )\n}\n\nexport const HeaderRightWithContext = () => {\n return (\n <FilterRecipientsProvider>\n <HeaderRight />\n </FilterRecipientsProvider>\n )\n}\n\nconst useStyles = () => {\n return StyleSheet.create({\n headerTitle: {\n fontSize: tokens.fontSizeLg,\n flex: 1,\n },\n headerRight: {\n flexDirection: 'row',\n gap: 16,\n alignItems: 'center',\n },\n })\n}\n"]}
1
+ {"version":3,"file":"navigation_header.js","sourceRoot":"","sources":["../../../../src/screens/conversation_filter_recipients/components/navigation_header.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAoB,MAAM,4BAA4B,CAAA;AAC1E,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AACxD,OAAO,EAAa,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAA;AACxD,OAAO,EACL,wBAAwB,EACxB,0BAA0B,GAC3B,MAAM,mDAAmD,CAAA;AAG1D,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,EAAE,SAAS,EAAoB,EAAE,EAAE;IACnE,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAE1B,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,YAAY,EAAE,WAAW,CAAC,CAAA;AACnG,CAAC,CAAA;AAED,MAAM,WAAW,GAAG,GAAG,EAAE;IACvB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,KAAK,GAAG,QAAQ,EAA+D,CAAA;IACrF,MAAM,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,GAAG,0BAA0B,EAAE,CAAA;IAE3E,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC,MAAM,CAAA;IACjC,MAAM,eAAe,GAAG,QAAQ,EAAE,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAA;IAC3D,MAAM,4BAA4B,GAAG,eAAe;QAClD,CAAC,CAAC,uFAAuF;QACzF,CAAC,CAAC,mFAAmF,CAAA;IAEvF,OAAO,CACL,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAC9B;MAAA,CAAC,UAAU,CACT,OAAO,CAAC,CAAC,gBAAgB,CAAC,CAC1B,iBAAiB,CAAC,mDAAmD,CAErE;;MACF,EAAE,UAAU,CACZ;MAAA,CAAC,MAAM,CACL,KAAK,CAAC,OAAO,CACb,iBAAiB,CAAC,CAAC,4BAA4B,CAAC,CAChD,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAC9C,QAAQ,CAAC,CAAC,eAAe,CAAC,EAE9B;IAAA,EAAE,IAAI,CAAC,CACR,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,EAAE;IACzC,OAAO,CACL,CAAC,wBAAwB,CACvB;MAAA,CAAC,WAAW,CAAC,AAAD,EACd;IAAA,EAAE,wBAAwB,CAAC,CAC5B,CAAA;AACH,CAAC,CAAA;AAED,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,OAAO,UAAU,CAAC,MAAM,CAAC;QACvB,WAAW,EAAE;YACX,QAAQ,EAAE,MAAM,CAAC,UAAU;YAC3B,IAAI,EAAE,CAAC;SACR;QACD,WAAW,EAAE;YACX,aAAa,EAAE,KAAK;YACpB,GAAG,EAAE,EAAE;YACP,UAAU,EAAE,QAAQ;SACrB;KACF,CAAC,CAAA;AACJ,CAAC,CAAA","sourcesContent":["import { HeaderTitle, HeaderTitleProps } from '@react-navigation/elements'\nimport React from 'react'\nimport { StyleSheet, View } from 'react-native'\nimport { Button, TextButton } from '../../../components'\nimport { RouteProp, useRoute } from '@react-navigation/native'\nimport { tokens } from '../../../vendor/tapestry/tokens'\nimport {\n FilterRecipientsProvider,\n useFilterRecipientsContext,\n} from '../context/conversation_filter_recipients_context'\nimport { ConversationFilterRecipientsScreenProps } from '../types'\n\nexport const FilterHeaderTitle = ({ tintColor }: HeaderTitleProps) => {\n const styles = useStyles()\n\n return <HeaderTitle style={[styles.headerTitle, { color: tintColor }]}>Teams I lead</HeaderTitle>\n}\n\nconst HeaderRight = () => {\n const styles = useStyles()\n const route = useRoute<RouteProp<ConversationFilterRecipientsScreenProps['route']>>()\n const { resetTeamFilters, applyTeamFilters } = useFilterRecipientsContext()\n\n const { team_ids } = route.params\n const noTeamsSelected = team_ids?.length === 0 || !team_ids\n const applyButtonAccessibilityHint = noTeamsSelected\n ? 'Select at least one team to navigate to the final step in creating your conversation.'\n : 'Saves selected teams and navigates to the final step to create your conversation.'\n\n return (\n <View style={styles.headerRight}>\n <TextButton\n onPress={resetTeamFilters}\n accessibilityHint=\"Cancels any selected teams and closes this modal.\"\n >\n Cancel\n </TextButton>\n <Button\n title=\"Apply\"\n accessibilityHint={applyButtonAccessibilityHint}\n onPress={() => applyTeamFilters(route.params)}\n disabled={noTeamsSelected}\n />\n </View>\n )\n}\n\nexport const HeaderRightWithContext = () => {\n return (\n <FilterRecipientsProvider>\n <HeaderRight />\n </FilterRecipientsProvider>\n )\n}\n\nconst useStyles = () => {\n return StyleSheet.create({\n headerTitle: {\n fontSize: tokens.fontSizeLg,\n flex: 1,\n },\n headerRight: {\n flexDirection: 'row',\n gap: 16,\n alignItems: 'center',\n },\n })\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"services_form.d.ts","sourceRoot":"","sources":["../../../../src/screens/conversation_new/components/services_form.tsx"],"names":[],"mappings":"AACA,OAAO,KAAyC,MAAM,OAAO,CAAA;AAa7D,KAAK,iBAAiB,GAAG;IACvB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IACzB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,eAAO,MAAM,YAAY,sCAAuC,iBAAiB,sBA8DhF,CAAA"}
1
+ {"version":3,"file":"services_form.d.ts","sourceRoot":"","sources":["../../../../src/screens/conversation_new/components/services_form.tsx"],"names":[],"mappings":"AACA,OAAO,KAAoD,MAAM,OAAO,CAAA;AAcxE,KAAK,iBAAiB,GAAG;IACvB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IACzB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,eAAO,MAAM,YAAY,sCAAuC,iBAAiB,sBAoEhF,CAAA"}
@@ -1,7 +1,7 @@
1
1
  import { StackActions, useNavigation } from '@react-navigation/native';
2
- import React, { useCallback, useMemo, useState } from 'react';
2
+ import React, { useCallback, useEffect, useMemo, useState } from 'react';
3
3
  import { StyleSheet, View } from 'react-native';
4
- import { Badge, Banner, ChildNotice, Heading, Switch, Text } from '../../../components';
4
+ import { Badge, Banner, ChildNotice, Heading, Switch, TextButton } from '../../../components';
5
5
  import { ActionButton } from '../../../components/display/action_button';
6
6
  import { Divider, FormList } from './form_list';
7
7
  import { pluralize } from '../../../utils';
@@ -10,11 +10,17 @@ import { useTeamsILead } from '../../../hooks/services/use_teams_i_lead';
10
10
  import { FilterByPlanOptions } from './filter_by_plan_options';
11
11
  import { useTeamMembersForNewConversation } from '../../../hooks/services/use_team_members_for_new_conversation';
12
12
  import { useFindOrCreateServicesConversation } from '../../../hooks/services/use_find_or_create_services_conversation';
13
+ import { tokens } from '../../../vendor/tapestry/tokens';
13
14
  export const ServicesForm = ({ initialTeamIds, initialPlanId }) => {
14
15
  const styles = useStyles();
15
16
  const [selectedPlanId, setSelectedPlanId] = useState(initialPlanId);
16
- const initialState = uniq(initialTeamIds) || []; // Uniq here because services can send duplicates in the teams_i_lead response.
17
+ const initialState = useMemo(() => uniq(initialTeamIds) || [], [initialTeamIds]); // Uniq here because services can send duplicates in the teams_i_lead response.
17
18
  const [selectedTeamIds, setSelectedTeamIds] = useState(initialState);
19
+ // Sync with fresh props when they change (from navigation)
20
+ useEffect(() => {
21
+ setSelectedTeamIds(initialState);
22
+ setSelectedPlanId(initialPlanId);
23
+ }, [initialState, initialPlanId]);
18
24
  const removeSelection = useCallback((teamId) => {
19
25
  setSelectedTeamIds(selectedTeamIds.filter(id => id !== teamId));
20
26
  }, [selectedTeamIds]);
@@ -47,6 +53,7 @@ function FormContent({ selectedTeamIds, removeSelection, selectedPlanId, setSele
47
53
  const selectedTeamsILead = useMemo(() => {
48
54
  return teamsILead.filter(team => selectedTeamIds.includes(team.value.teamId));
49
55
  }, [selectedTeamIds, teamsILead]);
56
+ const navigation = useNavigation();
50
57
  const styles = useStyles();
51
58
  const teamCountHeader = pluralize(selectedTeamIds.length, 'team');
52
59
  const memberCount = members.length;
@@ -59,7 +66,15 @@ function FormContent({ selectedTeamIds, removeSelection, selectedPlanId, setSele
59
66
  <View style={styles.toSection}>
60
67
  <View style={styles.toSectionRow}>
61
68
  <Heading variant="h3">To:</Heading>
62
- <Text>{teamCountHeader}</Text>
69
+ <TextButton accessibilityLabel="Select teams" textStyle={styles.teamCountHeader} onPress={() => navigation.navigate('New', {
70
+ screen: 'ConversationFilterRecipients',
71
+ params: {
72
+ source_app_name: 'Services',
73
+ team_ids: selectedTeamIds,
74
+ },
75
+ })}>
76
+ {teamCountHeader}
77
+ </TextButton>
63
78
  </View>
64
79
  <View style={styles.toSectionRow}>
65
80
  {selectedTeamsILead.map(team => (<View key={team.value.teamId} style={styles.badgeRow}>
@@ -133,6 +148,9 @@ const useStyles = () => {
133
148
  banner: {
134
149
  marginTop: 16,
135
150
  },
151
+ teamCountHeader: {
152
+ fontSize: tokens.fontSizeLg,
153
+ },
136
154
  });
137
155
  };
138
156
  //# sourceMappingURL=services_form.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"services_form.js","sourceRoot":"","sources":["../../../../src/screens/conversation_new/components/services_form.tsx"],"names":[],"mappings":"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","sourcesContent":["import { StackActions, useNavigation } from '@react-navigation/native'\nimport React, { useCallback, useMemo, useState } from 'react'\nimport { StyleSheet, View } from 'react-native'\nimport { Badge, Banner, ChildNotice, Heading, Switch, Text } from '../../../components'\nimport { ActionButton } from '../../../components/display/action_button'\nimport { Divider, FormList } from './form_list'\nimport { pluralize } from '../../../utils'\nimport { uniq } from 'lodash'\nimport { useTeamsILead } from '../../../hooks/services/use_teams_i_lead'\nimport { FilterByPlanOptions } from './filter_by_plan_options'\nimport { useTeamMembersForNewConversation } from '../../../hooks/services/use_team_members_for_new_conversation'\nimport { useFindOrCreateServicesConversation } from '../../../hooks/services/use_find_or_create_services_conversation'\nimport { ConversationResource, MemberResource } from '../../../types'\n\ntype ServicesFormProps = {\n initialTeamIds?: number[]\n initialPlanId?: number\n}\n\nexport const ServicesForm = ({ initialTeamIds, initialPlanId }: ServicesFormProps) => {\n const styles = useStyles()\n const [selectedPlanId, setSelectedPlanId] = useState<number | undefined>(initialPlanId)\n const initialState = uniq(initialTeamIds) || [] // Uniq here because services can send duplicates in the teams_i_lead response.\n const [selectedTeamIds, setSelectedTeamIds] = useState<number[]>(initialState)\n\n const removeSelection = useCallback(\n (teamId: number) => {\n setSelectedTeamIds(selectedTeamIds.filter(id => id !== teamId))\n },\n [selectedTeamIds]\n )\n\n const [filerByPlan, setFilterByPlan] = useState(false)\n\n const { members, isError: isMemberError } = useTeamMembersForNewConversation({\n teamIds: selectedTeamIds,\n planId: selectedPlanId,\n })\n const adultMembers = useMemo(() => members.filter(member => !member.child), [members])\n\n const navigation = useNavigation()\n const { mutate: createConversation } = useFindOrCreateServicesConversation({\n teamIds: selectedTeamIds,\n planId: filerByPlan ? selectedPlanId : undefined,\n onSuccess: (conversation: ConversationResource) => {\n // exit from the create stack\n navigation.getParent()?.goBack()\n // navigate to the conversation screen\n navigation.dispatch(\n StackActions.push('Conversation', {\n conversation_id: conversation.id,\n })\n )\n },\n })\n\n return (\n <View style={styles.formContainer}>\n <FormList\n memberData={adultMembers}\n FormContent={\n <FormContent\n selectedTeamIds={selectedTeamIds}\n removeSelection={removeSelection}\n selectedPlanId={selectedPlanId}\n setSelectedPlanId={setSelectedPlanId}\n filterByPlan={filerByPlan}\n setFilterByPlan={setFilterByPlan}\n members={members}\n isMemberError={isMemberError}\n />\n }\n />\n <ActionButton\n disabled={!selectedTeamIds.length}\n title=\"Start Conversation\"\n onPress={createConversation}\n infoText=\"Conversation will be automatically updated if any members are added or removed from included teams.\"\n />\n </View>\n )\n}\n\ninterface FormContentProps {\n selectedTeamIds: number[]\n removeSelection: (teamId: number) => void\n selectedPlanId?: number\n setSelectedPlanId: (planId: number | undefined) => void\n filterByPlan: boolean\n setFilterByPlan: (value: boolean) => void\n members: MemberResource[]\n isMemberError: boolean\n}\n\nfunction FormContent({\n selectedTeamIds,\n removeSelection,\n selectedPlanId,\n setSelectedPlanId,\n filterByPlan,\n setFilterByPlan,\n members,\n isMemberError,\n}: FormContentProps) {\n const { teamsILead } = useTeamsILead()\n const selectedTeamsILead = useMemo(() => {\n return teamsILead.filter(team => selectedTeamIds.includes(team.value.teamId))\n }, [selectedTeamIds, teamsILead])\n\n const styles = useStyles()\n const teamCountHeader = pluralize(selectedTeamIds.length, 'team')\n const memberCount = members.length\n const childMembers = useMemo(() => members.filter(member => member.child), [members])\n const hasChildren = childMembers.length > 0\n const multipleServiceTypes =\n uniq(selectedTeamsILead.map(team => team.value.serviceTypeId)).length > 1\n const firstTeamId = selectedTeamIds[0]\n filterByPlan = filterByPlan && !!firstTeamId && !multipleServiceTypes\n\n return (\n <View style={styles.formContent}>\n <View style={styles.toSection}>\n <View style={styles.toSectionRow}>\n <Heading variant=\"h3\">To:</Heading>\n <Text>{teamCountHeader}</Text>\n </View>\n <View style={styles.toSectionRow}>\n {selectedTeamsILead.map(team => (\n <View key={team.value.teamId} style={styles.badgeRow}>\n <Badge\n iconNameRight=\"general.x\"\n label={team.name}\n onPress={() => removeSelection(team.value.teamId)}\n />\n </View>\n ))}\n </View>\n </View>\n <Divider />\n <View style={styles.filterByPlanSection}>\n <View style={styles.filterByPlanSectionLead}>\n <Heading variant=\"h3\">Filter by plan</Heading>\n <Switch\n value={filterByPlan}\n onValueChange={setFilterByPlan}\n disabled={multipleServiceTypes}\n />\n </View>\n {multipleServiceTypes ? (\n <Banner\n appearance=\"neutral\"\n description=\"Plan filtering is not possible using teams from multiple service types. Try choosing teams above with only one service type.\"\n />\n ) : filterByPlan ? (\n <FilterByPlanOptions\n teamIds={selectedTeamIds}\n planId={selectedPlanId}\n onChange={setSelectedPlanId}\n />\n ) : null}\n </View>\n <Divider />\n <View style={styles.memberSection}>\n <Heading variant=\"h3\">{pluralize(memberCount, 'member')} selected</Heading>\n {hasChildren && (\n <ChildNotice childMembers={childMembers} showMembers={true} style={styles.banner} />\n )}\n {isMemberError && (\n <Banner\n appearance=\"error\"\n description=\"There was an issue loading team members, please refresh and try again.\"\n style={styles.banner}\n />\n )}\n </View>\n </View>\n )\n}\n\nconst useStyles = () => {\n const sectionPadding = 16\n\n return StyleSheet.create({\n formContainer: {\n flex: 1,\n },\n formContent: {\n paddingVertical: sectionPadding,\n flex: 1,\n },\n toSection: {\n padding: sectionPadding,\n gap: 8,\n },\n toSectionRow: {\n flexDirection: 'row',\n gap: 8,\n alignItems: 'baseline',\n flexWrap: 'wrap',\n },\n badgeRow: {\n flexDirection: 'row',\n },\n groupName: {\n fontSize: 18,\n },\n filterByPlanSection: {\n padding: sectionPadding,\n gap: 8,\n },\n filterByPlanSectionLead: {\n flexDirection: 'row',\n gap: 8,\n justifyContent: 'space-between',\n alignItems: 'center',\n },\n filterByPlanSectionRow: {\n flexDirection: 'row',\n gap: 8,\n },\n titleInput: {\n fontSize: 18,\n },\n memberSection: {\n padding: sectionPadding,\n paddingBottom: 0,\n },\n banner: {\n marginTop: 16,\n },\n })\n}\n"]}
1
+ {"version":3,"file":"services_form.js","sourceRoot":"","sources":["../../../../src/screens/conversation_new/components/services_form.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACtE,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AACxE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAC7F,OAAO,EAAE,YAAY,EAAE,MAAM,2CAA2C,CAAA;AACxE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,0CAA0C,CAAA;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EAAE,gCAAgC,EAAE,MAAM,+DAA+D,CAAA;AAChH,OAAO,EAAE,mCAAmC,EAAE,MAAM,kEAAkE,CAAA;AAEtH,OAAO,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAA;AAOxD,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,EAAE,cAAc,EAAE,aAAa,EAAqB,EAAE,EAAE;IACnF,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAqB,aAAa,CAAC,CAAA;IACvF,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAA,CAAC,+EAA+E;IAChK,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CAAW,YAAY,CAAC,CAAA;IAE9E,2DAA2D;IAC3D,SAAS,CAAC,GAAG,EAAE;QACb,kBAAkB,CAAC,YAAY,CAAC,CAAA;QAChC,iBAAiB,CAAC,aAAa,CAAC,CAAA;IAClC,CAAC,EAAE,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC,CAAA;IAEjC,MAAM,eAAe,GAAG,WAAW,CACjC,CAAC,MAAc,EAAE,EAAE;QACjB,kBAAkB,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC,CAAA;IACjE,CAAC,EACD,CAAC,eAAe,CAAC,CAClB,CAAA;IAED,MAAM,CAAC,WAAW,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAEtD,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,gCAAgC,CAAC;QAC3E,OAAO,EAAE,eAAe;QACxB,MAAM,EAAE,cAAc;KACvB,CAAC,CAAA;IACF,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAA;IAEtF,MAAM,UAAU,GAAG,aAAa,EAAE,CAAA;IAClC,MAAM,EAAE,MAAM,EAAE,kBAAkB,EAAE,GAAG,mCAAmC,CAAC;QACzE,OAAO,EAAE,eAAe;QACxB,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS;QAChD,SAAS,EAAE,CAAC,YAAkC,EAAE,EAAE;YAChD,6BAA6B;YAC7B,UAAU,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,CAAA;YAChC,sCAAsC;YACtC,UAAU,CAAC,QAAQ,CACjB,YAAY,CAAC,IAAI,CAAC,cAAc,EAAE;gBAChC,eAAe,EAAE,YAAY,CAAC,EAAE;aACjC,CAAC,CACH,CAAA;QACH,CAAC;KACF,CAAC,CAAA;IAEF,OAAO,CACL,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAChC;MAAA,CAAC,QAAQ,CACP,UAAU,CAAC,CAAC,YAAY,CAAC,CACzB,WAAW,CAAC,CACV,CAAC,WAAW,CACV,eAAe,CAAC,CAAC,eAAe,CAAC,CACjC,eAAe,CAAC,CAAC,eAAe,CAAC,CACjC,cAAc,CAAC,CAAC,cAAc,CAAC,CAC/B,iBAAiB,CAAC,CAAC,iBAAiB,CAAC,CACrC,YAAY,CAAC,CAAC,WAAW,CAAC,CAC1B,eAAe,CAAC,CAAC,eAAe,CAAC,CACjC,OAAO,CAAC,CAAC,OAAO,CAAC,CACjB,aAAa,CAAC,CAAC,aAAa,CAAC,EAEjC,CAAC,EAEH;MAAA,CAAC,YAAY,CACX,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC,CAClC,KAAK,CAAC,oBAAoB,CAC1B,OAAO,CAAC,CAAC,kBAAkB,CAAC,CAC5B,QAAQ,CAAC,qGAAqG,EAElH;IAAA,EAAE,IAAI,CAAC,CACR,CAAA;AACH,CAAC,CAAA;AAaD,SAAS,WAAW,CAAC,EACnB,eAAe,EACf,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,eAAe,EACf,OAAO,EACP,aAAa,GACI;IACjB,MAAM,EAAE,UAAU,EAAE,GAAG,aAAa,EAAE,CAAA;IACtC,MAAM,kBAAkB,GAAG,OAAO,CAAC,GAAG,EAAE;QACtC,OAAO,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAA;IAC/E,CAAC,EAAE,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC,CAAA;IACjC,MAAM,UAAU,GAAG,aAAa,EAAE,CAAA;IAElC,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,eAAe,GAAG,SAAS,CAAC,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACjE,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAA;IAClC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAA;IACrF,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,CAAA;IAC3C,MAAM,oBAAoB,GACxB,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAA;IAC3E,MAAM,WAAW,GAAG,eAAe,CAAC,CAAC,CAAC,CAAA;IACtC,YAAY,GAAG,YAAY,IAAI,CAAC,CAAC,WAAW,IAAI,CAAC,oBAAoB,CAAA;IAErE,OAAO,CACL,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAC9B;MAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAC5B;QAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAC/B;UAAA,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAClC;UAAA,CAAC,UAAU,CACT,kBAAkB,CAAC,cAAc,CACjC,SAAS,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,CAClC,OAAO,CAAC,CAAC,GAAG,EAAE,CACZ,UAAU,CAAC,QAAQ,CAAC,KAAK,EAAE;YACzB,MAAM,EAAE,8BAA8B;YACtC,MAAM,EAAE;gBACN,eAAe,EAAE,UAAU;gBAC3B,QAAQ,EAAE,eAAe;aAC1B;SACF,CACH,CAAC,CAED;YAAA,CAAC,eAAe,CAClB;UAAA,EAAE,UAAU,CACd;QAAA,EAAE,IAAI,CACN;QAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAC/B;UAAA,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAC9B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CACnD;cAAA,CAAC,KAAK,CACJ,aAAa,CAAC,WAAW,CACzB,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACjB,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAEtD;YAAA,EAAE,IAAI,CAAC,CACR,CAAC,CACJ;QAAA,EAAE,IAAI,CACR;MAAA,EAAE,IAAI,CACN;MAAA,CAAC,OAAO,CAAC,AAAD,EACR;MAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,CACtC;QAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAC1C;UAAA,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,OAAO,CAC7C;UAAA,CAAC,MAAM,CACL,KAAK,CAAC,CAAC,YAAY,CAAC,CACpB,aAAa,CAAC,CAAC,eAAe,CAAC,CAC/B,QAAQ,CAAC,CAAC,oBAAoB,CAAC,EAEnC;QAAA,EAAE,IAAI,CACN;QAAA,CAAC,oBAAoB,CAAC,CAAC,CAAC,CACtB,CAAC,MAAM,CACL,UAAU,CAAC,SAAS,CACpB,WAAW,CAAC,8HAA8H,EAC1I,CACH,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CACjB,CAAC,mBAAmB,CAClB,OAAO,CAAC,CAAC,eAAe,CAAC,CACzB,MAAM,CAAC,CAAC,cAAc,CAAC,CACvB,QAAQ,CAAC,CAAC,iBAAiB,CAAC,EAC5B,CACH,CAAC,CAAC,CAAC,IAAI,CACV;MAAA,EAAE,IAAI,CACN;MAAA,CAAC,OAAO,CAAC,AAAD,EACR;MAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAChC;QAAA,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAE,SAAQ,EAAE,OAAO,CAC1E;QAAA,CAAC,WAAW,IAAI,CACd,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAG,CACrF,CACD;QAAA,CAAC,aAAa,IAAI,CAChB,CAAC,MAAM,CACL,UAAU,CAAC,OAAO,CAClB,WAAW,CAAC,wEAAwE,CACpF,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EACrB,CACH,CACH;MAAA,EAAE,IAAI,CACR;IAAA,EAAE,IAAI,CAAC,CACR,CAAA;AACH,CAAC;AAED,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,MAAM,cAAc,GAAG,EAAE,CAAA;IAEzB,OAAO,UAAU,CAAC,MAAM,CAAC;QACvB,aAAa,EAAE;YACb,IAAI,EAAE,CAAC;SACR;QACD,WAAW,EAAE;YACX,eAAe,EAAE,cAAc;YAC/B,IAAI,EAAE,CAAC;SACR;QACD,SAAS,EAAE;YACT,OAAO,EAAE,cAAc;YACvB,GAAG,EAAE,CAAC;SACP;QACD,YAAY,EAAE;YACZ,aAAa,EAAE,KAAK;YACpB,GAAG,EAAE,CAAC;YACN,UAAU,EAAE,UAAU;YACtB,QAAQ,EAAE,MAAM;SACjB;QACD,QAAQ,EAAE;YACR,aAAa,EAAE,KAAK;SACrB;QACD,SAAS,EAAE;YACT,QAAQ,EAAE,EAAE;SACb;QACD,mBAAmB,EAAE;YACnB,OAAO,EAAE,cAAc;YACvB,GAAG,EAAE,CAAC;SACP;QACD,uBAAuB,EAAE;YACvB,aAAa,EAAE,KAAK;YACpB,GAAG,EAAE,CAAC;YACN,cAAc,EAAE,eAAe;YAC/B,UAAU,EAAE,QAAQ;SACrB;QACD,sBAAsB,EAAE;YACtB,aAAa,EAAE,KAAK;YACpB,GAAG,EAAE,CAAC;SACP;QACD,UAAU,EAAE;YACV,QAAQ,EAAE,EAAE;SACb;QACD,aAAa,EAAE;YACb,OAAO,EAAE,cAAc;YACvB,aAAa,EAAE,CAAC;SACjB;QACD,MAAM,EAAE;YACN,SAAS,EAAE,EAAE;SACd;QACD,eAAe,EAAE;YACf,QAAQ,EAAE,MAAM,CAAC,UAAU;SAC5B;KACF,CAAC,CAAA;AACJ,CAAC,CAAA","sourcesContent":["import { StackActions, useNavigation } from '@react-navigation/native'\nimport React, { useCallback, useEffect, useMemo, useState } from 'react'\nimport { StyleSheet, View } from 'react-native'\nimport { Badge, Banner, ChildNotice, Heading, Switch, TextButton } from '../../../components'\nimport { ActionButton } from '../../../components/display/action_button'\nimport { Divider, FormList } from './form_list'\nimport { pluralize } from '../../../utils'\nimport { uniq } from 'lodash'\nimport { useTeamsILead } from '../../../hooks/services/use_teams_i_lead'\nimport { FilterByPlanOptions } from './filter_by_plan_options'\nimport { useTeamMembersForNewConversation } from '../../../hooks/services/use_team_members_for_new_conversation'\nimport { useFindOrCreateServicesConversation } from '../../../hooks/services/use_find_or_create_services_conversation'\nimport { ConversationResource, MemberResource } from '../../../types'\nimport { tokens } from '../../../vendor/tapestry/tokens'\n\ntype ServicesFormProps = {\n initialTeamIds?: number[]\n initialPlanId?: number\n}\n\nexport const ServicesForm = ({ initialTeamIds, initialPlanId }: ServicesFormProps) => {\n const styles = useStyles()\n const [selectedPlanId, setSelectedPlanId] = useState<number | undefined>(initialPlanId)\n const initialState = useMemo(() => uniq(initialTeamIds) || [], [initialTeamIds]) // Uniq here because services can send duplicates in the teams_i_lead response.\n const [selectedTeamIds, setSelectedTeamIds] = useState<number[]>(initialState)\n\n // Sync with fresh props when they change (from navigation)\n useEffect(() => {\n setSelectedTeamIds(initialState)\n setSelectedPlanId(initialPlanId)\n }, [initialState, initialPlanId])\n\n const removeSelection = useCallback(\n (teamId: number) => {\n setSelectedTeamIds(selectedTeamIds.filter(id => id !== teamId))\n },\n [selectedTeamIds]\n )\n\n const [filerByPlan, setFilterByPlan] = useState(false)\n\n const { members, isError: isMemberError } = useTeamMembersForNewConversation({\n teamIds: selectedTeamIds,\n planId: selectedPlanId,\n })\n const adultMembers = useMemo(() => members.filter(member => !member.child), [members])\n\n const navigation = useNavigation()\n const { mutate: createConversation } = useFindOrCreateServicesConversation({\n teamIds: selectedTeamIds,\n planId: filerByPlan ? selectedPlanId : undefined,\n onSuccess: (conversation: ConversationResource) => {\n // exit from the create stack\n navigation.getParent()?.goBack()\n // navigate to the conversation screen\n navigation.dispatch(\n StackActions.push('Conversation', {\n conversation_id: conversation.id,\n })\n )\n },\n })\n\n return (\n <View style={styles.formContainer}>\n <FormList\n memberData={adultMembers}\n FormContent={\n <FormContent\n selectedTeamIds={selectedTeamIds}\n removeSelection={removeSelection}\n selectedPlanId={selectedPlanId}\n setSelectedPlanId={setSelectedPlanId}\n filterByPlan={filerByPlan}\n setFilterByPlan={setFilterByPlan}\n members={members}\n isMemberError={isMemberError}\n />\n }\n />\n <ActionButton\n disabled={!selectedTeamIds.length}\n title=\"Start Conversation\"\n onPress={createConversation}\n infoText=\"Conversation will be automatically updated if any members are added or removed from included teams.\"\n />\n </View>\n )\n}\n\ninterface FormContentProps {\n selectedTeamIds: number[]\n removeSelection: (teamId: number) => void\n selectedPlanId?: number\n setSelectedPlanId: (planId: number | undefined) => void\n filterByPlan: boolean\n setFilterByPlan: (value: boolean) => void\n members: MemberResource[]\n isMemberError: boolean\n}\n\nfunction FormContent({\n selectedTeamIds,\n removeSelection,\n selectedPlanId,\n setSelectedPlanId,\n filterByPlan,\n setFilterByPlan,\n members,\n isMemberError,\n}: FormContentProps) {\n const { teamsILead } = useTeamsILead()\n const selectedTeamsILead = useMemo(() => {\n return teamsILead.filter(team => selectedTeamIds.includes(team.value.teamId))\n }, [selectedTeamIds, teamsILead])\n const navigation = useNavigation()\n\n const styles = useStyles()\n const teamCountHeader = pluralize(selectedTeamIds.length, 'team')\n const memberCount = members.length\n const childMembers = useMemo(() => members.filter(member => member.child), [members])\n const hasChildren = childMembers.length > 0\n const multipleServiceTypes =\n uniq(selectedTeamsILead.map(team => team.value.serviceTypeId)).length > 1\n const firstTeamId = selectedTeamIds[0]\n filterByPlan = filterByPlan && !!firstTeamId && !multipleServiceTypes\n\n return (\n <View style={styles.formContent}>\n <View style={styles.toSection}>\n <View style={styles.toSectionRow}>\n <Heading variant=\"h3\">To:</Heading>\n <TextButton\n accessibilityLabel=\"Select teams\"\n textStyle={styles.teamCountHeader}\n onPress={() =>\n navigation.navigate('New', {\n screen: 'ConversationFilterRecipients',\n params: {\n source_app_name: 'Services',\n team_ids: selectedTeamIds,\n },\n })\n }\n >\n {teamCountHeader}\n </TextButton>\n </View>\n <View style={styles.toSectionRow}>\n {selectedTeamsILead.map(team => (\n <View key={team.value.teamId} style={styles.badgeRow}>\n <Badge\n iconNameRight=\"general.x\"\n label={team.name}\n onPress={() => removeSelection(team.value.teamId)}\n />\n </View>\n ))}\n </View>\n </View>\n <Divider />\n <View style={styles.filterByPlanSection}>\n <View style={styles.filterByPlanSectionLead}>\n <Heading variant=\"h3\">Filter by plan</Heading>\n <Switch\n value={filterByPlan}\n onValueChange={setFilterByPlan}\n disabled={multipleServiceTypes}\n />\n </View>\n {multipleServiceTypes ? (\n <Banner\n appearance=\"neutral\"\n description=\"Plan filtering is not possible using teams from multiple service types. Try choosing teams above with only one service type.\"\n />\n ) : filterByPlan ? (\n <FilterByPlanOptions\n teamIds={selectedTeamIds}\n planId={selectedPlanId}\n onChange={setSelectedPlanId}\n />\n ) : null}\n </View>\n <Divider />\n <View style={styles.memberSection}>\n <Heading variant=\"h3\">{pluralize(memberCount, 'member')} selected</Heading>\n {hasChildren && (\n <ChildNotice childMembers={childMembers} showMembers={true} style={styles.banner} />\n )}\n {isMemberError && (\n <Banner\n appearance=\"error\"\n description=\"There was an issue loading team members, please refresh and try again.\"\n style={styles.banner}\n />\n )}\n </View>\n </View>\n )\n}\n\nconst useStyles = () => {\n const sectionPadding = 16\n\n return StyleSheet.create({\n formContainer: {\n flex: 1,\n },\n formContent: {\n paddingVertical: sectionPadding,\n flex: 1,\n },\n toSection: {\n padding: sectionPadding,\n gap: 8,\n },\n toSectionRow: {\n flexDirection: 'row',\n gap: 8,\n alignItems: 'baseline',\n flexWrap: 'wrap',\n },\n badgeRow: {\n flexDirection: 'row',\n },\n groupName: {\n fontSize: 18,\n },\n filterByPlanSection: {\n padding: sectionPadding,\n gap: 8,\n },\n filterByPlanSectionLead: {\n flexDirection: 'row',\n gap: 8,\n justifyContent: 'space-between',\n alignItems: 'center',\n },\n filterByPlanSectionRow: {\n flexDirection: 'row',\n gap: 8,\n },\n titleInput: {\n fontSize: 18,\n },\n memberSection: {\n padding: sectionPadding,\n paddingBottom: 0,\n },\n banner: {\n marginTop: 16,\n },\n teamCountHeader: {\n fontSize: tokens.fontSizeLg,\n },\n })\n}\n"]}
@@ -0,0 +1,7 @@
1
+ import { ConversationRequestArgs } from '../../../utils/request/conversation';
2
+ interface Props {
3
+ args?: Partial<ConversationRequestArgs>;
4
+ }
5
+ export declare function ConversationsJoltEvents({ args }: Props): import("react").JSX.Element;
6
+ export {};
7
+ //# sourceMappingURL=conversations_jolt_events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversations_jolt_events.d.ts","sourceRoot":"","sources":["../../../../src/screens/conversations/components/conversations_jolt_events.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAA;AAG7E,UAAU,KAAK;IACb,IAAI,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAA;CACxC;AAID,wBAAgB,uBAAuB,CAAC,EAAE,IAAI,EAAE,EAAE,KAAK,+BAMtD"}
@@ -0,0 +1,14 @@
1
+ import { Suspense } from 'react';
2
+ import { useConversationsJoltEvents } from '../../../hooks/use_conversations_jolt_events';
3
+ // This hook is extracted into a component so the Suspense boundary can be isolated.
4
+ // It doesn't need to block the entire Conversations screen from rendering.
5
+ export function ConversationsJoltEvents({ args }) {
6
+ return (<Suspense fallback={null}>
7
+ <PrivateSuspendedConversationsJoltEvents args={args}/>
8
+ </Suspense>);
9
+ }
10
+ function PrivateSuspendedConversationsJoltEvents({ args }) {
11
+ useConversationsJoltEvents(args);
12
+ return null;
13
+ }
14
+ //# sourceMappingURL=conversations_jolt_events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversations_jolt_events.js","sourceRoot":"","sources":["../../../../src/screens/conversations/components/conversations_jolt_events.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAEhC,OAAO,EAAE,0BAA0B,EAAE,MAAM,8CAA8C,CAAA;AAMzF,oFAAoF;AACpF,2EAA2E;AAC3E,MAAM,UAAU,uBAAuB,CAAC,EAAE,IAAI,EAAS;IACrD,OAAO,CACL,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CACvB;MAAA,CAAC,uCAAuC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EACtD;IAAA,EAAE,QAAQ,CAAC,CACZ,CAAA;AACH,CAAC;AAED,SAAS,uCAAuC,CAAC,EAAE,IAAI,EAAS;IAC9D,0BAA0B,CAAC,IAAI,CAAC,CAAA;IAEhC,OAAO,IAAI,CAAA;AACb,CAAC","sourcesContent":["import { Suspense } from 'react'\nimport { ConversationRequestArgs } from '../../../utils/request/conversation'\nimport { useConversationsJoltEvents } from '../../../hooks/use_conversations_jolt_events'\n\ninterface Props {\n args?: Partial<ConversationRequestArgs>\n}\n\n// This hook is extracted into a component so the Suspense boundary can be isolated.\n// It doesn't need to block the entire Conversations screen from rendering.\nexport function ConversationsJoltEvents({ args }: Props) {\n return (\n <Suspense fallback={null}>\n <PrivateSuspendedConversationsJoltEvents args={args} />\n </Suspense>\n )\n}\n\nfunction PrivateSuspendedConversationsJoltEvents({ args }: Props): null {\n useConversationsJoltEvents(args)\n\n return null\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"conversations_screen.d.ts","sourceRoot":"","sources":["../../../src/screens/conversations/conversations_screen.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAiB,MAAM,0BAA0B,CAAA;AAC3E,OAAO,KAAK,MAAM,OAAO,CAAA;AAMzB,OAAO,EAAE,OAAO,EAAE,MAAM,sCAAsC,CAAA;AAG9D,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAExD,MAAM,MAAM,uBAAuB,GAAG,iBAAiB,CAAC;IACtD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAChC,CAAC,CAAA;AAEF,wBAAgB,mBAAmB,CAAC,EAAE,KAAK,EAAE,EAAE,uBAAuB,qBA4DrE"}
1
+ {"version":3,"file":"conversations_screen.d.ts","sourceRoot":"","sources":["../../../src/screens/conversations/conversations_screen.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAiB,MAAM,0BAA0B,CAAA;AAC3E,OAAO,KAAK,MAAM,OAAO,CAAA;AAMzB,OAAO,EAAE,OAAO,EAAE,MAAM,sCAAsC,CAAA;AAG9D,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAGxD,MAAM,MAAM,uBAAuB,GAAG,iBAAiB,CAAC;IACtD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAChC,CAAC,CAAA;AAEF,wBAAgB,mBAAmB,CAAC,EAAE,KAAK,EAAE,EAAE,uBAAuB,qBA6DrE"}
@@ -7,6 +7,7 @@ import { ConversationsContextProvider } from '../../contexts/conversations_conte
7
7
  import { useCanCreateConversations } from '../../hooks';
8
8
  import { destructureChatGroupGraphId } from '../../utils';
9
9
  import { ListHeaderComponent } from './components/list_header_component';
10
+ import { ConversationsJoltEvents } from './components/conversations_jolt_events';
10
11
  export function ConversationsScreen({ route }) {
11
12
  const navigation = useNavigation();
12
13
  const canCreateConversations = useCanCreateConversations();
@@ -46,6 +47,7 @@ export function ConversationsScreen({ route }) {
46
47
  };
47
48
  return (<View style={styles.container}>
48
49
  <ConversationsContextProvider args={route.params}>
50
+ <ConversationsJoltEvents args={route.params}/>
49
51
  <Conversations ListHeaderComponent={ListHeaderComponent}/>
50
52
  </ConversationsContextProvider>
51
53
  <ActionButton visible={canCreateConversations} title="New conversation" onPress={handleNewConversationNavigation} buttonIconNameLeft="churchCenter.signups" secondaryButton={<TextButton variant="tertiary" onPress={reportABug}>
@@ -1 +1 @@
1
- {"version":3,"file":"conversations_screen.js","sourceRoot":"","sources":["../../../src/screens/conversations/conversations_screen.tsx"],"names":[],"mappings":"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","sourcesContent":["import { StaticScreenProps, useNavigation } from '@react-navigation/native'\nimport React from 'react'\nimport { StyleSheet, View } from 'react-native'\nimport { Conversations, TextButton } from '../../components'\nimport { ActionButton } from '../../components/display/action_button'\nimport { ConversationsContextProvider } from '../../contexts/conversations_context'\nimport { useCanCreateConversations } from '../../hooks'\nimport { GraphId } from '../../types/resources/group_resource'\nimport { destructureChatGroupGraphId } from '../../utils'\nimport { ListHeaderComponent } from './components/list_header_component'\nimport { AppName } from '../../types/resources/app_name'\n\nexport type ConversationScreenProps = StaticScreenProps<{\n title?: string\n chat_group_graph_id?: GraphId\n group_source_app_name?: AppName\n}>\n\nexport function ConversationsScreen({ route }: ConversationScreenProps) {\n const navigation = useNavigation()\n const canCreateConversations = useCanCreateConversations()\n const styles = useStyles()\n\n const { chat_group_graph_id } = route.params || {}\n const { sourceAppName, sourceId } = destructureChatGroupGraphId(chat_group_graph_id)\n\n const handleNewConversationNavigation = () => {\n if (sourceAppName === 'Services') {\n return navigation.navigate('New', {\n screen: 'ConversationNew',\n params: {\n team_ids: sourceId ? [sourceId] : [],\n source_app_name: sourceAppName,\n ...route.params,\n },\n })\n }\n if (sourceAppName === 'Groups') {\n return navigation.navigate('New', {\n screen: 'ConversationNew',\n params: {\n group_id: sourceId,\n source_app_name: sourceAppName,\n ...route.params,\n },\n })\n }\n\n return navigation.navigate('New', {\n screen: 'ConversationSelectRecipients',\n params: {\n ...route.params,\n },\n })\n }\n\n const reportABug = () => {\n return navigation.navigate('BugReport')\n }\n\n return (\n <View style={styles.container}>\n <ConversationsContextProvider args={route.params}>\n <Conversations ListHeaderComponent={ListHeaderComponent} />\n </ConversationsContextProvider>\n <ActionButton\n visible={canCreateConversations}\n title=\"New conversation\"\n onPress={handleNewConversationNavigation}\n buttonIconNameLeft=\"churchCenter.signups\"\n secondaryButton={\n <TextButton variant=\"tertiary\" onPress={reportABug}>\n Report a bug\n </TextButton>\n }\n />\n </View>\n )\n}\n\nconst useStyles = () => {\n return StyleSheet.create({\n container: {\n flex: 1,\n justifyContent: 'center',\n },\n })\n}\n"]}
1
+ {"version":3,"file":"conversations_screen.js","sourceRoot":"","sources":["../../../src/screens/conversations/conversations_screen.tsx"],"names":[],"mappings":"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","sourcesContent":["import { StaticScreenProps, useNavigation } from '@react-navigation/native'\nimport React from 'react'\nimport { StyleSheet, View } from 'react-native'\nimport { Conversations, TextButton } from '../../components'\nimport { ActionButton } from '../../components/display/action_button'\nimport { ConversationsContextProvider } from '../../contexts/conversations_context'\nimport { useCanCreateConversations } from '../../hooks'\nimport { GraphId } from '../../types/resources/group_resource'\nimport { destructureChatGroupGraphId } from '../../utils'\nimport { ListHeaderComponent } from './components/list_header_component'\nimport { AppName } from '../../types/resources/app_name'\nimport { ConversationsJoltEvents } from './components/conversations_jolt_events'\n\nexport type ConversationScreenProps = StaticScreenProps<{\n title?: string\n chat_group_graph_id?: GraphId\n group_source_app_name?: AppName\n}>\n\nexport function ConversationsScreen({ route }: ConversationScreenProps) {\n const navigation = useNavigation()\n const canCreateConversations = useCanCreateConversations()\n const styles = useStyles()\n\n const { chat_group_graph_id } = route.params || {}\n const { sourceAppName, sourceId } = destructureChatGroupGraphId(chat_group_graph_id)\n\n const handleNewConversationNavigation = () => {\n if (sourceAppName === 'Services') {\n return navigation.navigate('New', {\n screen: 'ConversationNew',\n params: {\n team_ids: sourceId ? [sourceId] : [],\n source_app_name: sourceAppName,\n ...route.params,\n },\n })\n }\n if (sourceAppName === 'Groups') {\n return navigation.navigate('New', {\n screen: 'ConversationNew',\n params: {\n group_id: sourceId,\n source_app_name: sourceAppName,\n ...route.params,\n },\n })\n }\n\n return navigation.navigate('New', {\n screen: 'ConversationSelectRecipients',\n params: {\n ...route.params,\n },\n })\n }\n\n const reportABug = () => {\n return navigation.navigate('BugReport')\n }\n\n return (\n <View style={styles.container}>\n <ConversationsContextProvider args={route.params}>\n <ConversationsJoltEvents args={route.params} />\n <Conversations ListHeaderComponent={ListHeaderComponent} />\n </ConversationsContextProvider>\n <ActionButton\n visible={canCreateConversations}\n title=\"New conversation\"\n onPress={handleNewConversationNavigation}\n buttonIconNameLeft=\"churchCenter.signups\"\n secondaryButton={\n <TextButton variant=\"tertiary\" onPress={reportABug}>\n Report a bug\n </TextButton>\n }\n />\n </View>\n )\n}\n\nconst useStyles = () => {\n return StyleSheet.create({\n container: {\n flex: 1,\n justifyContent: 'center',\n },\n })\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planningcenter/chat-react-native",
3
- "version": "3.6.0-rc.2",
3
+ "version": "3.6.0-rc.4",
4
4
  "description": "",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -55,5 +55,5 @@
55
55
  "prettier": "^3.4.2",
56
56
  "typescript": "<5.6.0"
57
57
  },
58
- "gitHead": "990ca75da4934ca6a43489726e4296d898e160e2"
58
+ "gitHead": "0ec2fdeab6ccd06f1a2695a8c0e538925b8ee2c0"
59
59
  }
@@ -1,10 +1,6 @@
1
1
  import { renderHook } from '@testing-library/react-hooks'
2
2
  import * as useSuspenseApi from '../../hooks/use_suspense_api'
3
- import {
4
- getMessagesQueryKey,
5
- getMessagesRequestArgs,
6
- useConversationMessages,
7
- } from '../../hooks/use_conversation_messages'
3
+ import { useConversationMessages } from '../../hooks/use_conversation_messages'
8
4
 
9
5
  const mockMessages = [
10
6
  {
@@ -1,7 +1,7 @@
1
1
  import React from 'react'
2
2
  import { StyleSheet, View, ViewStyle } from 'react-native'
3
3
  import { ConversationResource } from '../../types'
4
- import { AvatarGroup, Heading, Text, Badge } from '../display'
4
+ import { AvatarGroup, Heading, Text, Badge, type BadgeProps } from '../display'
5
5
  import { formatDatePreview } from '../../utils/date'
6
6
  import { useTheme } from '../../hooks'
7
7
  import { UnreadCountBadge } from './unread_count_badge'
@@ -78,7 +78,12 @@ export const ConversationPreview = ({
78
78
  )
79
79
  }
80
80
 
81
- const ConversationBadges = ({ visible, badges }: { visible: boolean; badges?: any[] }) => {
81
+ interface BadgeShape {
82
+ appName?: BadgeProps['productLogoName']
83
+ pcoResourceType: string
84
+ text: string | null
85
+ }
86
+ const ConversationBadges = ({ visible, badges }: { visible: boolean; badges?: BadgeShape[] }) => {
82
87
  const styles = useStyles()
83
88
 
84
89
  if (!visible || !badges || badges.length === 0) {
@@ -100,6 +105,35 @@ const ConversationBadges = ({ visible, badges }: { visible: boolean; badges?: an
100
105
  )
101
106
  }
102
107
 
108
+ const skeletonBadges: BadgeShape[] = [
109
+ {
110
+ pcoResourceType: ' ',
111
+ text: ' ',
112
+ },
113
+ ]
114
+ export const ConversationPreviewSkeleton = () => {
115
+ const styles = useStyles()
116
+
117
+ return (
118
+ <View style={styles.previewRow}>
119
+ <AvatarGroup
120
+ size="lg"
121
+ sourceUris={[]}
122
+ showFallback={true}
123
+ fallbackIconName={'general.person'}
124
+ />
125
+ <View style={styles.conversationBody}>
126
+ <View style={styles.titleLoading} />
127
+ <View style={styles.subtitleLoading} />
128
+ <ConversationBadges visible={true} badges={skeletonBadges} />
129
+ </View>
130
+ <View style={styles.metaContainer}>
131
+ <View style={styles.dateLoading} />
132
+ </View>
133
+ </View>
134
+ )
135
+ }
136
+
103
137
  const useStyles = () => {
104
138
  const { colors } = useTheme()
105
139
 
@@ -117,6 +151,12 @@ const useStyles = () => {
117
151
  fontSize: 16,
118
152
  color: colors.textColorDefaultPrimary,
119
153
  },
154
+ titleLoading: {
155
+ width: 120,
156
+ height: 20,
157
+ backgroundColor: colors.fillColorNeutral080,
158
+ borderRadius: 4,
159
+ },
120
160
  conversationBody: {
121
161
  flex: 1,
122
162
  rowGap: 2,
@@ -124,10 +164,22 @@ const useStyles = () => {
124
164
  emptyConversationPreviewText: {
125
165
  color: colors.interaction,
126
166
  },
167
+ subtitleLoading: {
168
+ width: 80,
169
+ height: 16,
170
+ backgroundColor: colors.fillColorNeutral090,
171
+ borderRadius: 4,
172
+ },
127
173
  metaContainer: {
128
174
  rowGap: 4,
129
175
  alignItems: 'flex-end',
130
176
  },
177
+ dateLoading: {
178
+ width: 60,
179
+ height: 16,
180
+ backgroundColor: colors.fillColorNeutral090,
181
+ borderRadius: 4,
182
+ },
131
183
  badges: {
132
184
  marginTop: 4,
133
185
  alignItems: 'flex-start',
@@ -1,11 +1,12 @@
1
1
  import { useNavigation } from '@react-navigation/native'
2
2
  import { FlashList } from '@shopify/flash-list'
3
- import React from 'react'
3
+ import React, { useMemo } from 'react'
4
4
  import { StyleSheet, View } from 'react-native'
5
5
  import { useConversationsContext } from '../../contexts/conversations_context'
6
6
  import { useTheme } from '../../hooks'
7
7
  import { BlankState } from '../display'
8
- import { ConversationPreview } from './conversation_preview'
8
+ import { ConversationPreview, ConversationPreviewSkeleton } from './conversation_preview'
9
+ import { ConversationResource } from '../../types'
9
10
 
10
11
  interface ConversationsProps {
11
12
  ListHeaderComponent?:
@@ -20,6 +21,7 @@ export const Conversations = ({ ListHeaderComponent }: ConversationsProps) => {
20
21
 
21
22
  const {
22
23
  conversations,
24
+ isLoading,
23
25
  fetchNextPage,
24
26
  refetch,
25
27
  isRefetching,
@@ -30,11 +32,23 @@ export const Conversations = ({ ListHeaderComponent }: ConversationsProps) => {
30
32
 
31
33
  const showBadges = !chat_group_graph_id
32
34
 
35
+ const data: FlashListItem[] = useMemo(() => {
36
+ if (isLoading) {
37
+ return loadingPlaceholder
38
+ }
39
+ return conversations.map(conversation => ({
40
+ type: 'conversation' as const,
41
+ id: conversation.id,
42
+ resource: conversation,
43
+ }))
44
+ }, [conversations, isLoading])
45
+
33
46
  return (
34
47
  <View style={styles.container}>
35
48
  <FlashList
36
- data={conversations}
49
+ data={data}
37
50
  estimatedItemSize={97}
51
+ keyExtractor={item => item.id.toString()}
38
52
  contentContainerStyle={styles.contentContainer}
39
53
  onRefresh={refetch}
40
54
  refreshing={!isFetched && isRefetching}
@@ -44,20 +58,26 @@ export const Conversations = ({ ListHeaderComponent }: ConversationsProps) => {
44
58
  <BlankState iconName="general.outlinedTextMessage" title="No conversations" />
45
59
  </View>
46
60
  }
47
- renderItem={({ item }) => (
48
- <ConversationPreview
49
- conversation={item}
50
- onPress={() =>
51
- navigation.navigate('Conversation', {
52
- conversation_id: item.id,
53
- title: item.title,
54
- badge: item.badges?.[0],
55
- deleted: item.deleted,
56
- })
57
- }
58
- showBadges={showBadges}
59
- />
60
- )}
61
+ renderItem={({ item }) => {
62
+ if (item.type === 'loading') {
63
+ return <ConversationPreviewSkeleton />
64
+ } else {
65
+ return (
66
+ <ConversationPreview
67
+ conversation={item.resource}
68
+ onPress={() =>
69
+ navigation.navigate('Conversation', {
70
+ conversation_id: item.resource.id,
71
+ title: item.resource.title,
72
+ badge: item.resource.badges?.[0],
73
+ deleted: item.resource.deleted,
74
+ })
75
+ }
76
+ showBadges={showBadges}
77
+ />
78
+ )
79
+ }
80
+ }}
61
81
  onEndReached={() => fetchNextPage()}
62
82
  />
63
83
  </View>
@@ -79,3 +99,19 @@ const useStyles = () => {
79
99
  },
80
100
  })
81
101
  }
102
+
103
+ interface FlashListLoadingItem {
104
+ type: 'loading'
105
+ id: string
106
+ }
107
+ interface FlashListConversationItem {
108
+ type: 'conversation'
109
+ resource: ConversationResource
110
+ id: number
111
+ }
112
+ type FlashListItem = FlashListLoadingItem | FlashListConversationItem
113
+
114
+ const loadingPlaceholder: FlashListItem[] = Array.from({ length: 5 }, (_, i) => ({
115
+ type: 'loading',
116
+ id: `loading${i}`,
117
+ }))
@@ -50,7 +50,7 @@ const PRODUCT_LOGO_COMPONENT_MAP: Record<ProductLogoName, ProductLogoComponent>
50
50
  // ====== Component ================
51
51
  // =================================
52
52
 
53
- interface BadgeProps {
53
+ export interface BadgeProps {
54
54
  /**
55
55
  * Renders the main text.
56
56
  */
@@ -7,7 +7,6 @@ import {
7
7
  InfiniteData,
8
8
  } from '@tanstack/react-query'
9
9
  import { ApiCollection, ConversationResource } from '../types'
10
- import { useConversationsJoltEvents } from '../hooks/use_conversations_jolt_events'
11
10
 
12
11
  interface ConversationsContextValue extends UseConversationsValue {
13
12
  activeConversationId?: number
@@ -20,6 +19,7 @@ const defaultQueryValue: UseConversationsValue = {
20
19
  refetch: () => Promise.resolve(null),
21
20
  error: null,
22
21
  isError: false,
22
+ isLoading: true,
23
23
  fetchNextPage,
24
24
  hasNextPage: false,
25
25
  isFetching: false,
@@ -53,8 +53,6 @@ export const ConversationsContextProvider = ({
53
53
  [args, activeConversationId, query]
54
54
  )
55
55
 
56
- useConversationsJoltEvents(args)
57
-
58
56
  return <ConversationsContext.Provider value={value}>{children}</ConversationsContext.Provider>
59
57
  }
60
58
 
@@ -1,10 +1,10 @@
1
- import { InfiniteData, UseSuspenseInfiniteQueryResult } from '@tanstack/react-query'
1
+ import { InfiniteData, UseInfiniteQueryResult } from '@tanstack/react-query'
2
2
  import { useMemo } from 'react'
3
3
  import { ApiCollection, ConversationResource } from '../types'
4
4
  import { ConversationRequestArgs, getConversationsRequestArgs } from '../utils/request/conversation'
5
- import { useSuspensePaginator } from './use_suspense_api'
5
+ import { useApiPaginator } from './use_api'
6
6
 
7
- export type ConversationPaginationResult = UseSuspenseInfiniteQueryResult<
7
+ export type ConversationPaginationResult = UseInfiniteQueryResult<
8
8
  InfiniteData<ApiCollection<ConversationResource>, unknown>,
9
9
  Response
10
10
  >
@@ -13,6 +13,7 @@ export type UseConversationsValue = Pick<
13
13
  ConversationPaginationResult,
14
14
  | 'isFetching'
15
15
  | 'isError'
16
+ | 'isLoading'
16
17
  | 'error'
17
18
  | 'fetchNextPage'
18
19
  | 'hasNextPage'
@@ -25,7 +26,7 @@ export type UseConversationsValue = Pick<
25
26
 
26
27
  export function useConversations(args?: Partial<ConversationRequestArgs>): UseConversationsValue {
27
28
  const requestArgs = getConversationsRequestArgs(args)
28
- const { data, ...rest } = useSuspensePaginator<ConversationResource>(requestArgs)
29
+ const { data, ...rest } = useApiPaginator<ConversationResource>(requestArgs)
29
30
 
30
31
  const conversations = useMemo(() => data.sort(sortByLastMessage), [data])
31
32
 
@@ -33,7 +33,7 @@ const HeaderRight = () => {
33
33
  onPress={resetTeamFilters}
34
34
  accessibilityHint="Cancels any selected teams and closes this modal."
35
35
  >
36
- Reset
36
+ Cancel
37
37
  </TextButton>
38
38
  <Button
39
39
  title="Apply"
@@ -1,7 +1,7 @@
1
1
  import { StackActions, useNavigation } from '@react-navigation/native'
2
- import React, { useCallback, useMemo, useState } from 'react'
2
+ import React, { useCallback, useEffect, useMemo, useState } from 'react'
3
3
  import { StyleSheet, View } from 'react-native'
4
- import { Badge, Banner, ChildNotice, Heading, Switch, Text } from '../../../components'
4
+ import { Badge, Banner, ChildNotice, Heading, Switch, TextButton } from '../../../components'
5
5
  import { ActionButton } from '../../../components/display/action_button'
6
6
  import { Divider, FormList } from './form_list'
7
7
  import { pluralize } from '../../../utils'
@@ -11,6 +11,7 @@ import { FilterByPlanOptions } from './filter_by_plan_options'
11
11
  import { useTeamMembersForNewConversation } from '../../../hooks/services/use_team_members_for_new_conversation'
12
12
  import { useFindOrCreateServicesConversation } from '../../../hooks/services/use_find_or_create_services_conversation'
13
13
  import { ConversationResource, MemberResource } from '../../../types'
14
+ import { tokens } from '../../../vendor/tapestry/tokens'
14
15
 
15
16
  type ServicesFormProps = {
16
17
  initialTeamIds?: number[]
@@ -20,9 +21,15 @@ type ServicesFormProps = {
20
21
  export const ServicesForm = ({ initialTeamIds, initialPlanId }: ServicesFormProps) => {
21
22
  const styles = useStyles()
22
23
  const [selectedPlanId, setSelectedPlanId] = useState<number | undefined>(initialPlanId)
23
- const initialState = uniq(initialTeamIds) || [] // Uniq here because services can send duplicates in the teams_i_lead response.
24
+ const initialState = useMemo(() => uniq(initialTeamIds) || [], [initialTeamIds]) // Uniq here because services can send duplicates in the teams_i_lead response.
24
25
  const [selectedTeamIds, setSelectedTeamIds] = useState<number[]>(initialState)
25
26
 
27
+ // Sync with fresh props when they change (from navigation)
28
+ useEffect(() => {
29
+ setSelectedTeamIds(initialState)
30
+ setSelectedPlanId(initialPlanId)
31
+ }, [initialState, initialPlanId])
32
+
26
33
  const removeSelection = useCallback(
27
34
  (teamId: number) => {
28
35
  setSelectedTeamIds(selectedTeamIds.filter(id => id !== teamId))
@@ -106,6 +113,7 @@ function FormContent({
106
113
  const selectedTeamsILead = useMemo(() => {
107
114
  return teamsILead.filter(team => selectedTeamIds.includes(team.value.teamId))
108
115
  }, [selectedTeamIds, teamsILead])
116
+ const navigation = useNavigation()
109
117
 
110
118
  const styles = useStyles()
111
119
  const teamCountHeader = pluralize(selectedTeamIds.length, 'team')
@@ -122,7 +130,21 @@ function FormContent({
122
130
  <View style={styles.toSection}>
123
131
  <View style={styles.toSectionRow}>
124
132
  <Heading variant="h3">To:</Heading>
125
- <Text>{teamCountHeader}</Text>
133
+ <TextButton
134
+ accessibilityLabel="Select teams"
135
+ textStyle={styles.teamCountHeader}
136
+ onPress={() =>
137
+ navigation.navigate('New', {
138
+ screen: 'ConversationFilterRecipients',
139
+ params: {
140
+ source_app_name: 'Services',
141
+ team_ids: selectedTeamIds,
142
+ },
143
+ })
144
+ }
145
+ >
146
+ {teamCountHeader}
147
+ </TextButton>
126
148
  </View>
127
149
  <View style={styles.toSectionRow}>
128
150
  {selectedTeamsILead.map(team => (
@@ -228,5 +250,8 @@ const useStyles = () => {
228
250
  banner: {
229
251
  marginTop: 16,
230
252
  },
253
+ teamCountHeader: {
254
+ fontSize: tokens.fontSizeLg,
255
+ },
231
256
  })
232
257
  }
@@ -0,0 +1,23 @@
1
+ import { Suspense } from 'react'
2
+ import { ConversationRequestArgs } from '../../../utils/request/conversation'
3
+ import { useConversationsJoltEvents } from '../../../hooks/use_conversations_jolt_events'
4
+
5
+ interface Props {
6
+ args?: Partial<ConversationRequestArgs>
7
+ }
8
+
9
+ // This hook is extracted into a component so the Suspense boundary can be isolated.
10
+ // It doesn't need to block the entire Conversations screen from rendering.
11
+ export function ConversationsJoltEvents({ args }: Props) {
12
+ return (
13
+ <Suspense fallback={null}>
14
+ <PrivateSuspendedConversationsJoltEvents args={args} />
15
+ </Suspense>
16
+ )
17
+ }
18
+
19
+ function PrivateSuspendedConversationsJoltEvents({ args }: Props): null {
20
+ useConversationsJoltEvents(args)
21
+
22
+ return null
23
+ }
@@ -9,6 +9,7 @@ import { GraphId } from '../../types/resources/group_resource'
9
9
  import { destructureChatGroupGraphId } from '../../utils'
10
10
  import { ListHeaderComponent } from './components/list_header_component'
11
11
  import { AppName } from '../../types/resources/app_name'
12
+ import { ConversationsJoltEvents } from './components/conversations_jolt_events'
12
13
 
13
14
  export type ConversationScreenProps = StaticScreenProps<{
14
15
  title?: string
@@ -61,6 +62,7 @@ export function ConversationsScreen({ route }: ConversationScreenProps) {
61
62
  return (
62
63
  <View style={styles.container}>
63
64
  <ConversationsContextProvider args={route.params}>
65
+ <ConversationsJoltEvents args={route.params} />
64
66
  <Conversations ListHeaderComponent={ListHeaderComponent} />
65
67
  </ConversationsContextProvider>
66
68
  <ActionButton