@planningcenter/chat-react-native 3.11.0-rc.6 → 3.11.0-rc.8
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.
- package/build/hooks/use_mark_latest_message_read.d.ts +1 -1
- package/build/hooks/use_mark_latest_message_read.d.ts.map +1 -1
- package/build/hooks/use_mark_latest_message_read.js +19 -15
- package/build/hooks/use_mark_latest_message_read.js.map +1 -1
- package/build/screens/conversations/components/list_header_component.d.ts.map +1 -1
- package/build/screens/conversations/components/list_header_component.js +2 -3
- package/build/screens/conversations/components/list_header_component.js.map +1 -1
- package/package.json +2 -2
- package/src/hooks/use_mark_latest_message_read.ts +29 -21
- package/src/screens/conversations/components/list_header_component.tsx +2 -4
|
@@ -3,6 +3,6 @@ interface Props {
|
|
|
3
3
|
conversation: ConversationResource;
|
|
4
4
|
messages: MessageResource[];
|
|
5
5
|
}
|
|
6
|
-
export declare function useMarkLatestMessageRead({ conversation
|
|
6
|
+
export declare function useMarkLatestMessageRead({ conversation }: Props): void;
|
|
7
7
|
export {};
|
|
8
8
|
//# sourceMappingURL=use_mark_latest_message_read.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use_mark_latest_message_read.d.ts","sourceRoot":"","sources":["../../src/hooks/use_mark_latest_message_read.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"use_mark_latest_message_read.d.ts","sourceRoot":"","sources":["../../src/hooks/use_mark_latest_message_read.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAIhE,UAAU,KAAK;IACb,YAAY,EAAE,oBAAoB,CAAA;IAClC,QAAQ,EAAE,eAAe,EAAE,CAAA;CAC5B;AAED,wBAAgB,wBAAwB,CAAC,EAAE,YAAY,EAAE,EAAE,KAAK,QAiB/D"}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useCurrentPerson } from './use_current_person';
|
|
1
|
+
import { useCallback, useEffect, useRef } from 'react';
|
|
3
2
|
import { useAppState } from './use_app_state';
|
|
4
3
|
import { useConversationsMarkRead } from './use_conversations_actions';
|
|
5
|
-
export function useMarkLatestMessageRead({ conversation
|
|
6
|
-
const currentPerson = useCurrentPerson();
|
|
4
|
+
export function useMarkLatestMessageRead({ conversation }) {
|
|
7
5
|
const { markRead } = useConversationsMarkRead({ conversation });
|
|
8
|
-
const
|
|
9
|
-
const
|
|
6
|
+
const debouncedMarkRead = useDebounce(markRead, 500);
|
|
7
|
+
const unreadCount = conversation.unreadCount;
|
|
10
8
|
const appState = useAppState();
|
|
11
9
|
const isActive = appState === 'active';
|
|
12
10
|
/**
|
|
@@ -15,15 +13,21 @@ export function useMarkLatestMessageRead({ conversation, messages }) {
|
|
|
15
13
|
* * The latest message from someone else is newer than the last read message
|
|
16
14
|
*/
|
|
17
15
|
useEffect(() => {
|
|
18
|
-
if (!isActive ||
|
|
16
|
+
if (!isActive || unreadCount < 1)
|
|
19
17
|
return;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
onSuccess: () => {
|
|
23
|
-
setLastReadMessageId(latestOtherPersonMessageId);
|
|
24
|
-
},
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
}, [isActive, latestOtherPersonMessageId, lastReadMessageId, markRead]);
|
|
18
|
+
debouncedMarkRead(true);
|
|
19
|
+
}, [debouncedMarkRead, isActive, unreadCount]);
|
|
28
20
|
}
|
|
21
|
+
const useDebounce = (fn, delay) => {
|
|
22
|
+
const lastBroadcastTime = useRef(0);
|
|
23
|
+
const action = useCallback((...args) => {
|
|
24
|
+
const now = Date.now();
|
|
25
|
+
if (now - lastBroadcastTime.current < delay) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
lastBroadcastTime.current = now;
|
|
29
|
+
fn(...args);
|
|
30
|
+
}, [delay, fn]);
|
|
31
|
+
return action;
|
|
32
|
+
};
|
|
29
33
|
//# sourceMappingURL=use_mark_latest_message_read.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use_mark_latest_message_read.js","sourceRoot":"","sources":["../../src/hooks/use_mark_latest_message_read.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"use_mark_latest_message_read.js","sourceRoot":"","sources":["../../src/hooks/use_mark_latest_message_read.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AAEtD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC7C,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAA;AAOtE,MAAM,UAAU,wBAAwB,CAAC,EAAE,YAAY,EAAS;IAC9D,MAAM,EAAE,QAAQ,EAAE,GAAG,wBAAwB,CAAC,EAAE,YAAY,EAAE,CAAC,CAAA;IAC/D,MAAM,iBAAiB,GAAG,WAAW,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;IACpD,MAAM,WAAW,GAAG,YAAY,CAAC,WAAW,CAAA;IAC5C,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;IAC9B,MAAM,QAAQ,GAAG,QAAQ,KAAK,QAAQ,CAAA;IAEtC;;;;OAIG;IACH,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,QAAQ,IAAI,WAAW,GAAG,CAAC;YAAE,OAAM;QAExC,iBAAiB,CAAC,IAAI,CAAC,CAAA;IACzB,CAAC,EAAE,CAAC,iBAAiB,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAA;AAChD,CAAC;AAED,MAAM,WAAW,GAAG,CAAC,EAA4B,EAAE,KAAa,EAAE,EAAE;IAClE,MAAM,iBAAiB,GAAG,MAAM,CAAS,CAAC,CAAC,CAAA;IAE3C,MAAM,MAAM,GAAG,WAAW,CACxB,CAAC,GAAG,IAAW,EAAE,EAAE;QACjB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAEtB,IAAI,GAAG,GAAG,iBAAiB,CAAC,OAAO,GAAG,KAAK,EAAE,CAAC;YAC5C,OAAM;QACR,CAAC;QAED,iBAAiB,CAAC,OAAO,GAAG,GAAG,CAAA;QAE/B,EAAE,CAAC,GAAG,IAAI,CAAC,CAAA;IACb,CAAC,EACD,CAAC,KAAK,EAAE,EAAE,CAAC,CACZ,CAAA;IAED,OAAO,MAAM,CAAA;AACf,CAAC,CAAA","sourcesContent":["import { useCallback, useEffect, useRef } from 'react'\nimport { ConversationResource, MessageResource } from '../types'\nimport { useAppState } from './use_app_state'\nimport { useConversationsMarkRead } from './use_conversations_actions'\n\ninterface Props {\n conversation: ConversationResource\n messages: MessageResource[]\n}\n\nexport function useMarkLatestMessageRead({ conversation }: Props) {\n const { markRead } = useConversationsMarkRead({ conversation })\n const debouncedMarkRead = useDebounce(markRead, 500)\n const unreadCount = conversation.unreadCount\n const appState = useAppState()\n const isActive = appState === 'active'\n\n /**\n * Handle marking the conversation as read.\n * * The app needs to be active\n * * The latest message from someone else is newer than the last read message\n */\n useEffect(() => {\n if (!isActive || unreadCount < 1) return\n\n debouncedMarkRead(true)\n }, [debouncedMarkRead, isActive, unreadCount])\n}\n\nconst useDebounce = (fn: (...args: any[]) => void, delay: number) => {\n const lastBroadcastTime = useRef<number>(0)\n\n const action = useCallback(\n (...args: any[]) => {\n const now = Date.now()\n\n if (now - lastBroadcastTime.current < delay) {\n return\n }\n\n lastBroadcastTime.current = now\n\n fn(...args)\n },\n [delay, fn]\n )\n\n return action\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list_header_component.d.ts","sourceRoot":"","sources":["../../../../src/screens/conversations/components/list_header_component.tsx"],"names":[],"mappings":"AACA,OAAO,KAA+B,MAAM,OAAO,CAAA;AAkBnD,eAAO,MAAM,mBAAmB,
|
|
1
|
+
{"version":3,"file":"list_header_component.d.ts","sourceRoot":"","sources":["../../../../src/screens/conversations/components/list_header_component.tsx"],"names":[],"mappings":"AACA,OAAO,KAA+B,MAAM,OAAO,CAAA;AAkBnD,eAAO,MAAM,mBAAmB,yBA4G/B,CAAA"}
|
|
@@ -2,7 +2,7 @@ import { useNavigation, useRoute } from '@react-navigation/native';
|
|
|
2
2
|
import React, { useCallback, useMemo } from 'react';
|
|
3
3
|
import { Alert, ScrollView, StyleSheet, View } from 'react-native';
|
|
4
4
|
import { Heading, TextButton, ToggleButton } from '../../../components';
|
|
5
|
-
import {
|
|
5
|
+
import { useCurrentPersonCache, useTheme } from '../../../hooks';
|
|
6
6
|
import { useMarkAllRead } from '../../../hooks/use_conversations_actions';
|
|
7
7
|
import { useCanDisplayGroups } from '../../../hooks/use_groups';
|
|
8
8
|
import { ChatGroupBadge } from './chat_group_badge';
|
|
@@ -21,7 +21,6 @@ export const ListHeaderComponent = () => {
|
|
|
21
21
|
const canFilterByGroups = useCanDisplayGroups({ source_app_name: 'Groups', source_type: 'Group' });
|
|
22
22
|
const route = useRoute();
|
|
23
23
|
const { chat_group_graph_id, group_source_app_name = '' } = route.params || {};
|
|
24
|
-
const { unreadCount } = useCurrentPerson();
|
|
25
24
|
const currentPersonCache = useCurrentPersonCache();
|
|
26
25
|
const { markAllRead, isPending } = useMarkAllRead();
|
|
27
26
|
const active = useMemo(() => {
|
|
@@ -54,7 +53,7 @@ export const ListHeaderComponent = () => {
|
|
|
54
53
|
<Heading numberOfLines={1} variant="h2">
|
|
55
54
|
Conversations
|
|
56
55
|
</Heading>
|
|
57
|
-
<TextButton onPress={alertMarkAllRead} disabled={isPending
|
|
56
|
+
<TextButton onPress={alertMarkAllRead} disabled={isPending}>
|
|
58
57
|
Mark all read
|
|
59
58
|
</TextButton>
|
|
60
59
|
</View>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list_header_component.js","sourceRoot":"","sources":["../../../../src/screens/conversations/components/list_header_component.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAa,aAAa,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAC7E,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AACnD,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAClE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AACvE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"list_header_component.js","sourceRoot":"","sources":["../../../../src/screens/conversations/components/list_header_component.tsx"],"names":[],"mappings":"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","sourcesContent":["import { RouteProp, useNavigation, useRoute } from '@react-navigation/native'\nimport React, { useCallback, useMemo } from 'react'\nimport { Alert, ScrollView, StyleSheet, View } from 'react-native'\nimport { Heading, TextButton, ToggleButton } from '../../../components'\nimport { useCurrentPersonCache, useTheme } from '../../../hooks'\nimport { useMarkAllRead } from '../../../hooks/use_conversations_actions'\nimport { useCanDisplayGroups } from '../../../hooks/use_groups'\nimport { ConversationScreenProps } from '../conversations_screen'\nimport { ChatGroupBadge } from './chat_group_badge'\n\nconst ROW_PADDING_HORIZONTAL = 16\n\nenum FilterTypes {\n All = 'All',\n Groups = 'Groups',\n Teams = 'Teams',\n More = 'More',\n}\n\nexport const 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 const currentPersonCache = useCurrentPersonCache()\n const { markAllRead, isPending } = useMarkAllRead()\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 handleMarkAllRead = useCallback(() => {\n currentPersonCache.update({ unreadCount: 0 })\n markAllRead()\n }, [currentPersonCache, markAllRead])\n\n const alertMarkAllRead = useCallback(() => {\n if (active === FilterTypes.All) return handleMarkAllRead()\n\n Alert.alert('Mark all read', 'This includes conversations not shown by the current filter.', [\n { text: 'Cancel' },\n { text: 'OK', onPress: () => handleMarkAllRead() },\n ])\n }, [active, handleMarkAllRead])\n\n const showAppFilters = 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 onPress={alertMarkAllRead} disabled={isPending}>\n Mark all read\n </TextButton>\n </View>\n <ScrollView\n horizontal\n showsHorizontalScrollIndicator={false}\n contentContainerStyle={styles.filterRow}\n accessibilityRole=\"toolbar\"\n >\n {showAppFilters && (\n <>\n <ToggleButton\n title={FilterTypes.All}\n active={active === FilterTypes.All}\n onPress={() =>\n navigation.setParams({\n chat_group_graph_id: undefined,\n group_source_app_name: undefined,\n })\n }\n accessibilityLabel=\"Show all conversations\"\n />\n <ToggleButton\n title={FilterTypes.Groups}\n active={active === FilterTypes.Groups}\n onPress={() =>\n navigation.setParams({\n chat_group_graph_id: undefined,\n group_source_app_name: 'Groups',\n })\n }\n accessibilityLabel=\"Filter to group conversations\"\n />\n\n <ToggleButton\n title={FilterTypes.Teams}\n active={active === FilterTypes.Teams}\n onPress={() =>\n navigation.setParams({\n chat_group_graph_id: undefined,\n group_source_app_name: 'Services',\n })\n }\n accessibilityLabel=\"Filter to team conversations\"\n />\n </>\n )}\n <ToggleButton\n title={showAppFilters ? FilterTypes.More : 'Filter'}\n onPress={() =>\n navigation.navigate('ConversationFilters', {\n chat_group_graph_id,\n group_source_app_name,\n })\n }\n active={active === FilterTypes.More}\n iconNameRight=\"general.threeReducingHorizontalBars\"\n accessibilityLabel={showAppFilters ? 'View all filters' : 'View more filters'}\n />\n </ScrollView>\n <ChatGroupBadge rowPaddingHorizontal={ROW_PADDING_HORIZONTAL} />\n </View>\n )\n}\n\nconst useStyles = () => {\n const theme = useTheme()\n return StyleSheet.create({\n listHeader: {\n borderBottomWidth: 1,\n borderBottomColor: theme.colors.fillColorNeutral050Base,\n paddingBottom: 16,\n gap: 12,\n },\n titleRow: {\n flexDirection: 'row',\n justifyContent: 'space-between',\n paddingTop: 8,\n paddingHorizontal: ROW_PADDING_HORIZONTAL,\n },\n filterRow: {\n flexDirection: 'row',\n justifyContent: 'flex-start',\n gap: 8,\n paddingHorizontal: ROW_PADDING_HORIZONTAL,\n },\n })\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@planningcenter/chat-react-native",
|
|
3
|
-
"version": "3.11.0-rc.
|
|
3
|
+
"version": "3.11.0-rc.8",
|
|
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": "
|
|
58
|
+
"gitHead": "93e08dbdc5b76a8fbbc6cf5d7ad95c750ab70ac6"
|
|
59
59
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useCallback, useEffect, useRef } from 'react'
|
|
2
2
|
import { ConversationResource, MessageResource } from '../types'
|
|
3
|
-
import { useCurrentPerson } from './use_current_person'
|
|
4
3
|
import { useAppState } from './use_app_state'
|
|
5
4
|
import { useConversationsMarkRead } from './use_conversations_actions'
|
|
6
5
|
|
|
@@ -9,17 +8,10 @@ interface Props {
|
|
|
9
8
|
messages: MessageResource[]
|
|
10
9
|
}
|
|
11
10
|
|
|
12
|
-
export function useMarkLatestMessageRead({ conversation
|
|
13
|
-
const currentPerson = useCurrentPerson()
|
|
11
|
+
export function useMarkLatestMessageRead({ conversation }: Props) {
|
|
14
12
|
const { markRead } = useConversationsMarkRead({ conversation })
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
() => messages.find(message => message.author.id !== currentPerson.id)?.id,
|
|
18
|
-
[currentPerson.id, messages]
|
|
19
|
-
)
|
|
20
|
-
const [lastReadMessageId, setLastReadMessageId] = useState(
|
|
21
|
-
conversation.conversationMembership?.lastReadMessageSortKey
|
|
22
|
-
)
|
|
13
|
+
const debouncedMarkRead = useDebounce(markRead, 500)
|
|
14
|
+
const unreadCount = conversation.unreadCount
|
|
23
15
|
const appState = useAppState()
|
|
24
16
|
const isActive = appState === 'active'
|
|
25
17
|
|
|
@@ -29,13 +21,29 @@ export function useMarkLatestMessageRead({ conversation, messages }: Props) {
|
|
|
29
21
|
* * The latest message from someone else is newer than the last read message
|
|
30
22
|
*/
|
|
31
23
|
useEffect(() => {
|
|
32
|
-
if (!isActive ||
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
24
|
+
if (!isActive || unreadCount < 1) return
|
|
25
|
+
|
|
26
|
+
debouncedMarkRead(true)
|
|
27
|
+
}, [debouncedMarkRead, isActive, unreadCount])
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const useDebounce = (fn: (...args: any[]) => void, delay: number) => {
|
|
31
|
+
const lastBroadcastTime = useRef<number>(0)
|
|
32
|
+
|
|
33
|
+
const action = useCallback(
|
|
34
|
+
(...args: any[]) => {
|
|
35
|
+
const now = Date.now()
|
|
36
|
+
|
|
37
|
+
if (now - lastBroadcastTime.current < delay) {
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
lastBroadcastTime.current = now
|
|
42
|
+
|
|
43
|
+
fn(...args)
|
|
44
|
+
},
|
|
45
|
+
[delay, fn]
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
return action
|
|
41
49
|
}
|
|
@@ -2,7 +2,7 @@ import { RouteProp, useNavigation, useRoute } from '@react-navigation/native'
|
|
|
2
2
|
import React, { useCallback, useMemo } from 'react'
|
|
3
3
|
import { Alert, ScrollView, StyleSheet, View } from 'react-native'
|
|
4
4
|
import { Heading, TextButton, ToggleButton } from '../../../components'
|
|
5
|
-
import {
|
|
5
|
+
import { useCurrentPersonCache, useTheme } from '../../../hooks'
|
|
6
6
|
import { useMarkAllRead } from '../../../hooks/use_conversations_actions'
|
|
7
7
|
import { useCanDisplayGroups } from '../../../hooks/use_groups'
|
|
8
8
|
import { ConversationScreenProps } from '../conversations_screen'
|
|
@@ -24,8 +24,6 @@ export const ListHeaderComponent = () => {
|
|
|
24
24
|
const canFilterByGroups = useCanDisplayGroups({ source_app_name: 'Groups', source_type: 'Group' })
|
|
25
25
|
const route = useRoute<RouteProp<ConversationScreenProps['route']>>()
|
|
26
26
|
const { chat_group_graph_id, group_source_app_name = '' } = route.params || {}
|
|
27
|
-
|
|
28
|
-
const { unreadCount } = useCurrentPerson()
|
|
29
27
|
const currentPersonCache = useCurrentPersonCache()
|
|
30
28
|
const { markAllRead, isPending } = useMarkAllRead()
|
|
31
29
|
|
|
@@ -63,7 +61,7 @@ export const ListHeaderComponent = () => {
|
|
|
63
61
|
<Heading numberOfLines={1} variant="h2">
|
|
64
62
|
Conversations
|
|
65
63
|
</Heading>
|
|
66
|
-
<TextButton onPress={alertMarkAllRead} disabled={isPending
|
|
64
|
+
<TextButton onPress={alertMarkAllRead} disabled={isPending}>
|
|
67
65
|
Mark all read
|
|
68
66
|
</TextButton>
|
|
69
67
|
</View>
|