@planningcenter/chat-react-native 3.1.0 → 3.2.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/build/components/display/index.d.ts +1 -0
  2. package/build/components/display/index.d.ts.map +1 -1
  3. package/build/components/display/index.js +1 -0
  4. package/build/components/display/index.js.map +1 -1
  5. package/build/components/display/toggle_button.d.ts +42 -0
  6. package/build/components/display/toggle_button.d.ts.map +1 -0
  7. package/build/components/display/toggle_button.js +67 -0
  8. package/build/components/display/toggle_button.js.map +1 -0
  9. package/build/navigation/index.d.ts +2 -9
  10. package/build/navigation/index.d.ts.map +1 -1
  11. package/build/navigation/index.js +1 -1
  12. package/build/navigation/index.js.map +1 -1
  13. package/build/screens/conversation_filters/components/conversation_filters.d.ts +3 -0
  14. package/build/screens/conversation_filters/components/conversation_filters.d.ts.map +1 -0
  15. package/build/screens/conversation_filters/components/conversation_filters.js +173 -0
  16. package/build/screens/conversation_filters/components/conversation_filters.js.map +1 -0
  17. package/build/screens/conversation_filters/components/rows.d.ts +31 -0
  18. package/build/screens/conversation_filters/components/rows.d.ts.map +1 -0
  19. package/build/screens/conversation_filters/components/rows.js +111 -0
  20. package/build/screens/conversation_filters/components/rows.js.map +1 -0
  21. package/build/screens/conversation_filters/context/conversation_filter_context.d.ts +23 -0
  22. package/build/screens/conversation_filters/context/conversation_filter_context.d.ts.map +1 -0
  23. package/build/screens/conversation_filters/context/conversation_filter_context.js +51 -0
  24. package/build/screens/conversation_filters/context/conversation_filter_context.js.map +1 -0
  25. package/build/screens/conversation_filters/filter_types.d.ts +7 -0
  26. package/build/screens/conversation_filters/filter_types.d.ts.map +1 -0
  27. package/build/screens/conversation_filters/filter_types.js +8 -0
  28. package/build/screens/conversation_filters/filter_types.js.map +1 -0
  29. package/build/screens/conversation_filters/group_filters.d.ts +6 -0
  30. package/build/screens/conversation_filters/group_filters.d.ts.map +1 -0
  31. package/build/screens/conversation_filters/group_filters.js +15 -0
  32. package/build/screens/conversation_filters/group_filters.js.map +1 -0
  33. package/build/screens/conversation_filters/hooks/filters.d.ts +415 -0
  34. package/build/screens/conversation_filters/hooks/filters.d.ts.map +1 -0
  35. package/build/screens/conversation_filters/hooks/filters.js +41 -0
  36. package/build/screens/conversation_filters/hooks/filters.js.map +1 -0
  37. package/build/screens/conversation_filters/screen_props.d.ts +13 -0
  38. package/build/screens/conversation_filters/screen_props.d.ts.map +1 -0
  39. package/build/screens/conversation_filters/screen_props.js +2 -0
  40. package/build/screens/conversation_filters/screen_props.js.map +1 -0
  41. package/build/screens/conversation_filters/team_filters.d.ts +6 -0
  42. package/build/screens/conversation_filters/team_filters.d.ts.map +1 -0
  43. package/build/screens/conversation_filters/team_filters.js +15 -0
  44. package/build/screens/conversation_filters/team_filters.js.map +1 -0
  45. package/build/screens/conversation_filters_screen.d.ts +2 -9
  46. package/build/screens/conversation_filters_screen.d.ts.map +1 -1
  47. package/build/screens/conversation_filters_screen.js +81 -302
  48. package/build/screens/conversation_filters_screen.js.map +1 -1
  49. package/build/screens/conversations/components/chat_group_badge.d.ts +3 -0
  50. package/build/screens/conversations/components/chat_group_badge.d.ts.map +1 -0
  51. package/build/screens/conversations/components/chat_group_badge.js +40 -0
  52. package/build/screens/conversations/components/chat_group_badge.js.map +1 -0
  53. package/build/screens/conversations/components/list_header_component.d.ts +3 -0
  54. package/build/screens/conversations/components/list_header_component.d.ts.map +1 -0
  55. package/build/screens/conversations/components/list_header_component.js +88 -0
  56. package/build/screens/conversations/components/list_header_component.js.map +1 -0
  57. package/build/screens/{conversations_screen.d.ts → conversations/conversations_screen.d.ts} +1 -1
  58. package/build/screens/conversations/conversations_screen.d.ts.map +1 -0
  59. package/build/screens/conversations/conversations_screen.js +35 -0
  60. package/build/screens/conversations/conversations_screen.js.map +1 -0
  61. package/build/screens/design_system_screen.d.ts.map +1 -1
  62. package/build/screens/design_system_screen.js +9 -1
  63. package/build/screens/design_system_screen.js.map +1 -1
  64. package/package.json +2 -2
  65. package/src/components/display/index.ts +1 -0
  66. package/src/components/display/toggle_button.tsx +157 -0
  67. package/src/navigation/index.tsx +1 -1
  68. package/src/screens/conversation_filters/components/conversation_filters.tsx +233 -0
  69. package/src/screens/conversation_filters/components/rows.tsx +164 -0
  70. package/src/screens/conversation_filters/context/conversation_filter_context.tsx +65 -0
  71. package/src/screens/conversation_filters/filter_types.ts +6 -0
  72. package/src/screens/conversation_filters/group_filters.tsx +31 -0
  73. package/src/screens/conversation_filters/hooks/filters.ts +68 -0
  74. package/src/screens/conversation_filters/screen_props.ts +15 -0
  75. package/src/screens/conversation_filters/team_filters.tsx +31 -0
  76. package/src/screens/conversation_filters_screen.tsx +93 -429
  77. package/src/screens/conversations/components/chat_group_badge.tsx +47 -0
  78. package/src/screens/conversations/components/list_header_component.tsx +125 -0
  79. package/src/screens/conversations/conversations_screen.tsx +56 -0
  80. package/src/screens/design_system_screen.tsx +28 -0
  81. package/build/screens/conversations_screen.d.ts.map +0 -1
  82. package/build/screens/conversations_screen.js +0 -144
  83. package/build/screens/conversations_screen.js.map +0 -1
  84. package/src/screens/conversations_screen.tsx +0 -222
@@ -0,0 +1,125 @@
1
+ import { RouteProp, useNavigation, useRoute } from '@react-navigation/native'
2
+ import React, { useMemo } from 'react'
3
+ import { StyleSheet, View } from 'react-native'
4
+ import { Heading, TextButton, ToggleButton } from '../../../components'
5
+ import { useTheme } from '../../../hooks'
6
+ import { useCanDisplayGroups } from '../../../hooks/use_groups'
7
+ import { ConversationScreenProps } from '../conversations_screen'
8
+ import { ChatGroupBadge } from './chat_group_badge'
9
+
10
+ enum FilterTypes {
11
+ All = 'All',
12
+ Groups = 'Groups',
13
+ Teams = 'Teams',
14
+ More = 'More',
15
+ }
16
+
17
+ export const ListHeaderComponent = () => {
18
+ const styles = useStyles()
19
+ const navigation = useNavigation()
20
+ const canFilterByTeams = useCanDisplayGroups({ source_app_name: 'Services', source_type: 'Team' })
21
+ const canFilterByGroups = useCanDisplayGroups({ source_app_name: 'Groups', source_type: 'Group' })
22
+ const route = useRoute<RouteProp<ConversationScreenProps['route']>>()
23
+ const { chat_group_graph_id, group_source_app_name = '' } = route.params
24
+
25
+ const active: FilterTypes = useMemo(() => {
26
+ if (chat_group_graph_id) {
27
+ return FilterTypes.More
28
+ } else if (/groups/i.test(group_source_app_name)) {
29
+ return FilterTypes.Groups
30
+ } else if (/services/i.test(group_source_app_name)) {
31
+ return FilterTypes.Teams
32
+ }
33
+
34
+ return FilterTypes.All
35
+ }, [chat_group_graph_id, group_source_app_name])
36
+
37
+ const showAppFilters = canFilterByGroups && canFilterByTeams
38
+
39
+ return (
40
+ <View style={styles.listHeader}>
41
+ <View style={styles.titleRow}>
42
+ <Heading numberOfLines={1} variant="h2">
43
+ Conversations
44
+ </Heading>
45
+ <TextButton>Mark all read</TextButton>
46
+ </View>
47
+ <View style={styles.filterRow}>
48
+ {showAppFilters && (
49
+ <>
50
+ <ToggleButton
51
+ title={FilterTypes.All}
52
+ active={active === FilterTypes.All}
53
+ onPress={() =>
54
+ navigation.setParams({
55
+ chat_group_graph_id: undefined,
56
+ group_source_app_name: undefined,
57
+ })
58
+ }
59
+ accessibilityLabel="Show all conversations"
60
+ />
61
+ <ToggleButton
62
+ title={FilterTypes.Groups}
63
+ active={active === FilterTypes.Groups}
64
+ onPress={() =>
65
+ navigation.setParams({
66
+ chat_group_graph_id: undefined,
67
+ group_source_app_name: 'Groups',
68
+ })
69
+ }
70
+ accessibilityLabel="Filter to group conversations"
71
+ />
72
+
73
+ <ToggleButton
74
+ title={FilterTypes.Teams}
75
+ active={active === FilterTypes.Teams}
76
+ onPress={() =>
77
+ navigation.setParams({
78
+ chat_group_graph_id: undefined,
79
+ group_source_app_name: 'Services',
80
+ })
81
+ }
82
+ accessibilityLabel="Filter to team conversations"
83
+ />
84
+ </>
85
+ )}
86
+ <ToggleButton
87
+ title={showAppFilters ? FilterTypes.More : 'Filter'}
88
+ onPress={() =>
89
+ navigation.navigate('ConversationFilters', {
90
+ chat_group_graph_id,
91
+ group_source_app_name,
92
+ })
93
+ }
94
+ active={active === FilterTypes.More}
95
+ iconNameRight="general.threeReducingHorizontalBars"
96
+ accessibilityLabel={showAppFilters ? 'View all filters' : 'View more filters'}
97
+ />
98
+ </View>
99
+ <ChatGroupBadge />
100
+ </View>
101
+ )
102
+ }
103
+
104
+ const useStyles = () => {
105
+ const theme = useTheme()
106
+ return StyleSheet.create({
107
+ listHeader: {
108
+ borderBottomWidth: 1,
109
+ borderBottomColor: theme.colors.fillColorNeutral050Base,
110
+ paddingHorizontal: 16,
111
+ paddingBottom: 16,
112
+ gap: 12,
113
+ },
114
+ titleRow: {
115
+ flexDirection: 'row',
116
+ justifyContent: 'space-between',
117
+ paddingTop: 8,
118
+ },
119
+ filterRow: {
120
+ flexDirection: 'row',
121
+ justifyContent: 'flex-start',
122
+ gap: 8,
123
+ },
124
+ })
125
+ }
@@ -0,0 +1,56 @@
1
+ import { StaticScreenProps, useNavigation } from '@react-navigation/native'
2
+ import React, { useMemo } from 'react'
3
+ import { StyleSheet, View } from 'react-native'
4
+ import { Conversations } from '../../components'
5
+ import { ActionButton } from '../../components/display/action_button'
6
+ import { useCanCreateConversations } from '../../hooks'
7
+ import { GraphId } from '../../types/resources/group_resource'
8
+ import { ListHeaderComponent } from './components/list_header_component'
9
+
10
+ export type ConversationScreenProps = StaticScreenProps<{
11
+ title?: string
12
+ chat_group_graph_id?: GraphId
13
+ group_source_app_name?: string
14
+ }>
15
+
16
+ export function ConversationsScreen({ route }: ConversationScreenProps) {
17
+ const navigation = useNavigation()
18
+ const canCreateConversations = useCanCreateConversations()
19
+ const styles = useStyles()
20
+ const { chat_group_graph_id, group_source_app_name } = route.params
21
+
22
+ const filter = useMemo(() => {
23
+ if (chat_group_graph_id) {
24
+ return 'group'
25
+ } else if (group_source_app_name) {
26
+ return 'group_source_app_name'
27
+ }
28
+
29
+ return 'mine_or_not_empty'
30
+ }, [chat_group_graph_id, group_source_app_name])
31
+
32
+ return (
33
+ <View style={styles.container}>
34
+ <Conversations
35
+ ListHeaderComponent={ListHeaderComponent}
36
+ group={chat_group_graph_id}
37
+ group_source_app_name={group_source_app_name}
38
+ filter={filter}
39
+ />
40
+ <ActionButton
41
+ visible={canCreateConversations}
42
+ title="New conversation"
43
+ onPress={() => navigation.navigate('Create')}
44
+ />
45
+ </View>
46
+ )
47
+ }
48
+
49
+ const useStyles = () => {
50
+ return StyleSheet.create({
51
+ container: {
52
+ flex: 1,
53
+ justifyContent: 'center',
54
+ },
55
+ })
56
+ }
@@ -9,6 +9,7 @@ import {
9
9
  Banner,
10
10
  BannerCollapsible,
11
11
  Button,
12
+ ToggleButton,
12
13
  Heading,
13
14
  Icon,
14
15
  IconButton,
@@ -253,6 +254,7 @@ function HeadingTextSection({ isLast }: SectionProps) {
253
254
 
254
255
  function PressablesSection({ isLast }: SectionProps) {
255
256
  const styles = useStyles()
257
+ const [filterSelected, setFilterSelected] = useState('Groups')
256
258
 
257
259
  return (
258
260
  <CollapsableSection title="Pressables" isLast={isLast}>
@@ -402,6 +404,32 @@ function PressablesSection({ isLast }: SectionProps) {
402
404
  />
403
405
  </Row>
404
406
  </Group>
407
+ <Group
408
+ title="ToggleButton"
409
+ description="Button with active and deactive states. Supports right & left icons, along with standard pressable props."
410
+ >
411
+ <Row>
412
+ <ToggleButton
413
+ onPress={() => setFilterSelected('Groups')}
414
+ title="Groups"
415
+ active={filterSelected === 'Groups'}
416
+ accessibilityLabel="Filter to group conversations"
417
+ />
418
+ <ToggleButton
419
+ onPress={() => setFilterSelected('Teams')}
420
+ title="Teams"
421
+ active={filterSelected === 'Teams'}
422
+ accessibilityLabel="Filter to team conversations"
423
+ />
424
+ <ToggleButton
425
+ onPress={() => setFilterSelected('More')}
426
+ title="More"
427
+ active={filterSelected === 'More'}
428
+ iconNameRight="general.threeReducingHorizontalBars"
429
+ accessibilityLabel="View more filters"
430
+ />
431
+ </Row>
432
+ </Group>
405
433
  <Group
406
434
  title="IconButton"
407
435
  description="Supports different appearances, sizes, along with loading & disabled states. Use `iconStyle` for custom colors and font sizes. Requires `accessibilityLabel` as icon's don't provide context to screen readers."
@@ -1 +0,0 @@
1
- {"version":3,"file":"conversations_screen.d.ts","sourceRoot":"","sources":["../../src/screens/conversations_screen.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAa,iBAAiB,EAA2B,MAAM,0BAA0B,CAAA;AAChG,OAAO,KAA+B,MAAM,OAAO,CAAA;AAMnD,OAAO,EAAE,OAAO,EAAiB,MAAM,mCAAmC,CAAA;AAG1E,MAAM,MAAM,uBAAuB,GAAG,iBAAiB,CAAC;IACtD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,qBAAqB,CAAC,EAAE,MAAM,CAAA;CAC/B,CAAC,CAAA;AAEF,wBAAgB,mBAAmB,CAAC,EAAE,KAAK,EAAE,EAAE,uBAAuB,qBA+BrE"}
@@ -1,144 +0,0 @@
1
- import { useNavigation, useRoute } from '@react-navigation/native';
2
- import React, { useCallback, useMemo } from 'react';
3
- import { StyleSheet, View } from 'react-native';
4
- import { Badge, Button, Conversations, Heading, TextButton } from '../components';
5
- import { ActionButton } from '../components/display/action_button';
6
- import { useCanCreateConversations, useTheme } from '../hooks';
7
- import { useApiGet } from '../hooks/use_api';
8
- import { useCanDisplayGroups } from '../hooks/use_groups';
9
- export function ConversationsScreen({ route }) {
10
- const navigation = useNavigation();
11
- const canCreateConversations = useCanCreateConversations();
12
- const styles = useStyles();
13
- const { chat_group_graph_id, group_source_app_name } = route.params;
14
- const filter = useMemo(() => {
15
- if (chat_group_graph_id) {
16
- return 'group';
17
- }
18
- else if (group_source_app_name) {
19
- return 'group_source_app_name';
20
- }
21
- return 'mine_or_not_empty';
22
- }, [chat_group_graph_id, group_source_app_name]);
23
- return (<View style={styles.container}>
24
- <Conversations ListHeaderComponent={ListHeaderComponent} group={chat_group_graph_id} group_source_app_name={group_source_app_name} filter={filter}/>
25
- <ActionButton visible={canCreateConversations} title="New conversation" onPress={() => navigation.navigate('Create')}/>
26
- </View>);
27
- }
28
- var FilterTypes;
29
- (function (FilterTypes) {
30
- FilterTypes["All"] = "All";
31
- FilterTypes["Groups"] = "Groups";
32
- FilterTypes["Teams"] = "Teams";
33
- FilterTypes["More"] = "More";
34
- })(FilterTypes || (FilterTypes = {}));
35
- const ListHeaderComponent = () => {
36
- const styles = useStyles();
37
- const navigation = useNavigation();
38
- const canFilterByTeams = useCanDisplayGroups({ source_app_name: 'Services', source_type: 'Team' });
39
- const canFilterByGroups = useCanDisplayGroups({ source_app_name: 'Groups', source_type: 'Group' });
40
- const route = useRoute();
41
- const { chat_group_graph_id, group_source_app_name = '' } = route.params;
42
- const active = useMemo(() => {
43
- if (chat_group_graph_id) {
44
- return FilterTypes.More;
45
- }
46
- else if (/groups/i.test(group_source_app_name)) {
47
- return FilterTypes.Groups;
48
- }
49
- else if (/services/i.test(group_source_app_name)) {
50
- return FilterTypes.Teams;
51
- }
52
- return FilterTypes.All;
53
- }, [chat_group_graph_id, group_source_app_name]);
54
- const hideAppFilters = !canFilterByGroups || !canFilterByTeams;
55
- return (<View style={styles.listHeader}>
56
- <View style={styles.titleRow}>
57
- <Heading numberOfLines={1} variant="h2">
58
- Conversations
59
- </Heading>
60
- <TextButton>Mark all read</TextButton>
61
- </View>
62
- <View style={styles.filterRow}>
63
- <FilterButton title={FilterTypes.All} activeTitle={active} hidden={!canFilterByGroups || !canFilterByTeams} onPress={() => navigation.setParams({
64
- chat_group_graph_id: undefined,
65
- group_source_app_name: undefined,
66
- })}/>
67
- <FilterButton title={FilterTypes.Groups} activeTitle={active} hidden={hideAppFilters} onPress={() => navigation.setParams({
68
- chat_group_graph_id: undefined,
69
- group_source_app_name: 'Groups',
70
- })}/>
71
- <FilterButton title={FilterTypes.Teams} activeTitle={active} hidden={hideAppFilters} onPress={() => navigation.setParams({
72
- chat_group_graph_id: undefined,
73
- group_source_app_name: 'Services',
74
- })}/>
75
- <Button title={hideAppFilters ? 'Filter' : FilterTypes.More} onPress={() => navigation.navigate('ConversationFilters', {
76
- chat_group_graph_id,
77
- group_source_app_name,
78
- })} variant={active === FilterTypes.More ? 'fill' : 'outline'} iconNameRight="general.threeReducingHorizontalBars"/>
79
- </View>
80
- <Badges />
81
- </View>);
82
- };
83
- const Badges = () => {
84
- const styles = useStyles();
85
- const navigation = useNavigation();
86
- const route = useRoute();
87
- const { chat_group_graph_id } = route.params;
88
- const { data: group } = useApiGet({
89
- url: `/me/groups/${chat_group_graph_id}`,
90
- data: {
91
- fields: {
92
- Group: [],
93
- },
94
- },
95
- enabled: !!chat_group_graph_id,
96
- app: 'chat',
97
- });
98
- const handleBadgePress = useCallback(() => {
99
- navigation.setParams({
100
- chat_group_graph_id: undefined,
101
- group_source_app_name: undefined,
102
- });
103
- }, [navigation]);
104
- if (!group)
105
- return null;
106
- return (<View style={styles.groupBadge}>
107
- <Badge iconNameRight="general.x" label={group?.name || ''} onPress={handleBadgePress}/>
108
- </View>);
109
- };
110
- function FilterButton({ title, activeTitle, onPress, hidden = false, ...restProps }) {
111
- if (hidden)
112
- return null;
113
- return (<Button title={title} variant={activeTitle === title ? 'fill' : 'outline'} onPress={onPress} {...restProps}/>);
114
- }
115
- const useStyles = () => {
116
- const theme = useTheme();
117
- return StyleSheet.create({
118
- container: {
119
- flex: 1,
120
- justifyContent: 'center',
121
- },
122
- listHeader: {
123
- borderBottomWidth: 1,
124
- borderBottomColor: theme.colors.fillColorNeutral050Base,
125
- paddingHorizontal: 16,
126
- paddingBottom: 16,
127
- gap: 12,
128
- },
129
- titleRow: {
130
- flexDirection: 'row',
131
- justifyContent: 'space-between',
132
- paddingTop: 8,
133
- },
134
- filterRow: {
135
- flexDirection: 'row',
136
- justifyContent: 'flex-start',
137
- gap: 8,
138
- },
139
- groupBadge: {
140
- flexDirection: 'row',
141
- },
142
- });
143
- };
144
- //# sourceMappingURL=conversations_screen.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"conversations_screen.js","sourceRoot":"","sources":["../../src/screens/conversations_screen.tsx"],"names":[],"mappings":"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","sourcesContent":["import { RouteProp, StaticScreenProps, useNavigation, useRoute } from '@react-navigation/native'\nimport React, { useCallback, useMemo } from 'react'\nimport { StyleSheet, View } from 'react-native'\nimport { Badge, Button, ButtonProps, Conversations, Heading, TextButton } from '../components'\nimport { ActionButton } from '../components/display/action_button'\nimport { useCanCreateConversations, useTheme } from '../hooks'\nimport { useApiGet } from '../hooks/use_api'\nimport { GraphId, GroupResource } from '../types/resources/group_resource'\nimport { useCanDisplayGroups } from '../hooks/use_groups'\n\nexport type ConversationScreenProps = StaticScreenProps<{\n title?: string\n chat_group_graph_id?: GraphId\n group_source_app_name?: string\n}>\n\nexport function ConversationsScreen({ route }: ConversationScreenProps) {\n const navigation = useNavigation()\n const canCreateConversations = useCanCreateConversations()\n const styles = useStyles()\n const { chat_group_graph_id, group_source_app_name } = route.params\n\n const filter = useMemo(() => {\n if (chat_group_graph_id) {\n return 'group'\n } else if (group_source_app_name) {\n return 'group_source_app_name'\n }\n\n return 'mine_or_not_empty'\n }, [chat_group_graph_id, group_source_app_name])\n\n return (\n <View style={styles.container}>\n <Conversations\n ListHeaderComponent={ListHeaderComponent}\n group={chat_group_graph_id}\n group_source_app_name={group_source_app_name}\n filter={filter}\n />\n <ActionButton\n visible={canCreateConversations}\n title=\"New conversation\"\n onPress={() => navigation.navigate('Create')}\n />\n </View>\n )\n}\n\nenum FilterTypes {\n All = 'All',\n Groups = 'Groups',\n Teams = 'Teams',\n More = 'More',\n}\n\nconst ListHeaderComponent = () => {\n const styles = useStyles()\n const navigation = useNavigation()\n const canFilterByTeams = useCanDisplayGroups({ source_app_name: 'Services', source_type: 'Team' })\n const canFilterByGroups = useCanDisplayGroups({ source_app_name: 'Groups', source_type: 'Group' })\n const route = useRoute<RouteProp<ConversationScreenProps['route']>>()\n const { chat_group_graph_id, group_source_app_name = '' } = route.params\n\n const active: FilterTypes = useMemo(() => {\n if (chat_group_graph_id) {\n return FilterTypes.More\n } else if (/groups/i.test(group_source_app_name)) {\n return FilterTypes.Groups\n } else if (/services/i.test(group_source_app_name)) {\n return FilterTypes.Teams\n }\n\n return FilterTypes.All\n }, [chat_group_graph_id, group_source_app_name])\n\n const hideAppFilters = !canFilterByGroups || !canFilterByTeams\n\n return (\n <View style={styles.listHeader}>\n <View style={styles.titleRow}>\n <Heading numberOfLines={1} variant=\"h2\">\n Conversations\n </Heading>\n <TextButton>Mark all read</TextButton>\n </View>\n <View style={styles.filterRow}>\n <FilterButton\n title={FilterTypes.All}\n activeTitle={active}\n hidden={!canFilterByGroups || !canFilterByTeams}\n onPress={() =>\n navigation.setParams({\n chat_group_graph_id: undefined,\n group_source_app_name: undefined,\n })\n }\n />\n <FilterButton\n title={FilterTypes.Groups}\n activeTitle={active}\n hidden={hideAppFilters}\n onPress={() =>\n navigation.setParams({\n chat_group_graph_id: undefined,\n group_source_app_name: 'Groups',\n })\n }\n />\n <FilterButton\n title={FilterTypes.Teams}\n activeTitle={active}\n hidden={hideAppFilters}\n onPress={() =>\n navigation.setParams({\n chat_group_graph_id: undefined,\n group_source_app_name: 'Services',\n })\n }\n />\n <Button\n title={hideAppFilters ? 'Filter' : FilterTypes.More}\n onPress={() =>\n navigation.navigate('ConversationFilters', {\n chat_group_graph_id,\n group_source_app_name,\n })\n }\n variant={active === FilterTypes.More ? 'fill' : 'outline'}\n iconNameRight=\"general.threeReducingHorizontalBars\"\n />\n </View>\n <Badges />\n </View>\n )\n}\n\nconst Badges = () => {\n const styles = useStyles()\n const navigation = useNavigation()\n const route = useRoute<RouteProp<ConversationScreenProps['route']>>()\n const { chat_group_graph_id } = route.params\n const { data: group } = useApiGet<GroupResource>({\n url: `/me/groups/${chat_group_graph_id}`,\n data: {\n fields: {\n Group: [],\n },\n },\n enabled: !!chat_group_graph_id,\n app: 'chat',\n })\n\n const handleBadgePress = useCallback(() => {\n navigation.setParams({\n chat_group_graph_id: undefined,\n group_source_app_name: undefined,\n })\n }, [navigation])\n\n if (!group) return null\n\n return (\n <View style={styles.groupBadge}>\n <Badge iconNameRight=\"general.x\" label={group?.name || ''} onPress={handleBadgePress} />\n </View>\n )\n}\n\nfunction FilterButton({\n title,\n activeTitle,\n onPress,\n hidden = false,\n ...restProps\n}: {\n title: string\n activeTitle: string\n onPress: () => void\n hidden?: boolean\n} & ButtonProps) {\n if (hidden) return null\n\n return (\n <Button\n title={title}\n variant={activeTitle === title ? 'fill' : 'outline'}\n onPress={onPress}\n {...restProps}\n />\n )\n}\n\nconst useStyles = () => {\n const theme = useTheme()\n return StyleSheet.create({\n container: {\n flex: 1,\n justifyContent: 'center',\n },\n listHeader: {\n borderBottomWidth: 1,\n borderBottomColor: theme.colors.fillColorNeutral050Base,\n paddingHorizontal: 16,\n paddingBottom: 16,\n gap: 12,\n },\n titleRow: {\n flexDirection: 'row',\n justifyContent: 'space-between',\n paddingTop: 8,\n },\n filterRow: {\n flexDirection: 'row',\n justifyContent: 'flex-start',\n gap: 8,\n },\n groupBadge: {\n flexDirection: 'row',\n },\n })\n}\n"]}
@@ -1,222 +0,0 @@
1
- import { RouteProp, StaticScreenProps, useNavigation, useRoute } from '@react-navigation/native'
2
- import React, { useCallback, useMemo } from 'react'
3
- import { StyleSheet, View } from 'react-native'
4
- import { Badge, Button, ButtonProps, Conversations, Heading, TextButton } from '../components'
5
- import { ActionButton } from '../components/display/action_button'
6
- import { useCanCreateConversations, useTheme } from '../hooks'
7
- import { useApiGet } from '../hooks/use_api'
8
- import { GraphId, GroupResource } from '../types/resources/group_resource'
9
- import { useCanDisplayGroups } from '../hooks/use_groups'
10
-
11
- export type ConversationScreenProps = StaticScreenProps<{
12
- title?: string
13
- chat_group_graph_id?: GraphId
14
- group_source_app_name?: string
15
- }>
16
-
17
- export function ConversationsScreen({ route }: ConversationScreenProps) {
18
- const navigation = useNavigation()
19
- const canCreateConversations = useCanCreateConversations()
20
- const styles = useStyles()
21
- const { chat_group_graph_id, group_source_app_name } = route.params
22
-
23
- const filter = useMemo(() => {
24
- if (chat_group_graph_id) {
25
- return 'group'
26
- } else if (group_source_app_name) {
27
- return 'group_source_app_name'
28
- }
29
-
30
- return 'mine_or_not_empty'
31
- }, [chat_group_graph_id, group_source_app_name])
32
-
33
- return (
34
- <View style={styles.container}>
35
- <Conversations
36
- ListHeaderComponent={ListHeaderComponent}
37
- group={chat_group_graph_id}
38
- group_source_app_name={group_source_app_name}
39
- filter={filter}
40
- />
41
- <ActionButton
42
- visible={canCreateConversations}
43
- title="New conversation"
44
- onPress={() => navigation.navigate('Create')}
45
- />
46
- </View>
47
- )
48
- }
49
-
50
- enum FilterTypes {
51
- All = 'All',
52
- Groups = 'Groups',
53
- Teams = 'Teams',
54
- More = 'More',
55
- }
56
-
57
- const ListHeaderComponent = () => {
58
- const styles = useStyles()
59
- const navigation = useNavigation()
60
- const canFilterByTeams = useCanDisplayGroups({ source_app_name: 'Services', source_type: 'Team' })
61
- const canFilterByGroups = useCanDisplayGroups({ source_app_name: 'Groups', source_type: 'Group' })
62
- const route = useRoute<RouteProp<ConversationScreenProps['route']>>()
63
- const { chat_group_graph_id, group_source_app_name = '' } = route.params
64
-
65
- const active: FilterTypes = useMemo(() => {
66
- if (chat_group_graph_id) {
67
- return FilterTypes.More
68
- } else if (/groups/i.test(group_source_app_name)) {
69
- return FilterTypes.Groups
70
- } else if (/services/i.test(group_source_app_name)) {
71
- return FilterTypes.Teams
72
- }
73
-
74
- return FilterTypes.All
75
- }, [chat_group_graph_id, group_source_app_name])
76
-
77
- const hideAppFilters = !canFilterByGroups || !canFilterByTeams
78
-
79
- return (
80
- <View style={styles.listHeader}>
81
- <View style={styles.titleRow}>
82
- <Heading numberOfLines={1} variant="h2">
83
- Conversations
84
- </Heading>
85
- <TextButton>Mark all read</TextButton>
86
- </View>
87
- <View style={styles.filterRow}>
88
- <FilterButton
89
- title={FilterTypes.All}
90
- activeTitle={active}
91
- hidden={!canFilterByGroups || !canFilterByTeams}
92
- onPress={() =>
93
- navigation.setParams({
94
- chat_group_graph_id: undefined,
95
- group_source_app_name: undefined,
96
- })
97
- }
98
- />
99
- <FilterButton
100
- title={FilterTypes.Groups}
101
- activeTitle={active}
102
- hidden={hideAppFilters}
103
- onPress={() =>
104
- navigation.setParams({
105
- chat_group_graph_id: undefined,
106
- group_source_app_name: 'Groups',
107
- })
108
- }
109
- />
110
- <FilterButton
111
- title={FilterTypes.Teams}
112
- activeTitle={active}
113
- hidden={hideAppFilters}
114
- onPress={() =>
115
- navigation.setParams({
116
- chat_group_graph_id: undefined,
117
- group_source_app_name: 'Services',
118
- })
119
- }
120
- />
121
- <Button
122
- title={hideAppFilters ? 'Filter' : FilterTypes.More}
123
- onPress={() =>
124
- navigation.navigate('ConversationFilters', {
125
- chat_group_graph_id,
126
- group_source_app_name,
127
- })
128
- }
129
- variant={active === FilterTypes.More ? 'fill' : 'outline'}
130
- iconNameRight="general.threeReducingHorizontalBars"
131
- />
132
- </View>
133
- <Badges />
134
- </View>
135
- )
136
- }
137
-
138
- const Badges = () => {
139
- const styles = useStyles()
140
- const navigation = useNavigation()
141
- const route = useRoute<RouteProp<ConversationScreenProps['route']>>()
142
- const { chat_group_graph_id } = route.params
143
- const { data: group } = useApiGet<GroupResource>({
144
- url: `/me/groups/${chat_group_graph_id}`,
145
- data: {
146
- fields: {
147
- Group: [],
148
- },
149
- },
150
- enabled: !!chat_group_graph_id,
151
- app: 'chat',
152
- })
153
-
154
- const handleBadgePress = useCallback(() => {
155
- navigation.setParams({
156
- chat_group_graph_id: undefined,
157
- group_source_app_name: undefined,
158
- })
159
- }, [navigation])
160
-
161
- if (!group) return null
162
-
163
- return (
164
- <View style={styles.groupBadge}>
165
- <Badge iconNameRight="general.x" label={group?.name || ''} onPress={handleBadgePress} />
166
- </View>
167
- )
168
- }
169
-
170
- function FilterButton({
171
- title,
172
- activeTitle,
173
- onPress,
174
- hidden = false,
175
- ...restProps
176
- }: {
177
- title: string
178
- activeTitle: string
179
- onPress: () => void
180
- hidden?: boolean
181
- } & ButtonProps) {
182
- if (hidden) return null
183
-
184
- return (
185
- <Button
186
- title={title}
187
- variant={activeTitle === title ? 'fill' : 'outline'}
188
- onPress={onPress}
189
- {...restProps}
190
- />
191
- )
192
- }
193
-
194
- const useStyles = () => {
195
- const theme = useTheme()
196
- return StyleSheet.create({
197
- container: {
198
- flex: 1,
199
- justifyContent: 'center',
200
- },
201
- listHeader: {
202
- borderBottomWidth: 1,
203
- borderBottomColor: theme.colors.fillColorNeutral050Base,
204
- paddingHorizontal: 16,
205
- paddingBottom: 16,
206
- gap: 12,
207
- },
208
- titleRow: {
209
- flexDirection: 'row',
210
- justifyContent: 'space-between',
211
- paddingTop: 8,
212
- },
213
- filterRow: {
214
- flexDirection: 'row',
215
- justifyContent: 'flex-start',
216
- gap: 8,
217
- },
218
- groupBadge: {
219
- flexDirection: 'row',
220
- },
221
- })
222
- }