@planningcenter/chat-react-native 2.1.1 → 2.2.0-rc.0
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/components/conversation/message_form.d.ts.map +1 -1
- package/build/components/conversation/message_form.js +4 -4
- package/build/components/conversation/message_form.js.map +1 -1
- package/build/contexts/api_provider.js +4 -3
- package/build/contexts/api_provider.js.map +1 -1
- package/build/contexts/chat_context.d.ts +2 -2
- package/build/contexts/chat_context.d.ts.map +1 -1
- package/build/contexts/chat_context.js +3 -15
- package/build/contexts/chat_context.js.map +1 -1
- package/build/hooks/use_api_client.d.ts +6 -0
- package/build/hooks/use_api_client.d.ts.map +1 -0
- package/build/hooks/use_api_client.js +18 -0
- package/build/hooks/use_api_client.js.map +1 -0
- package/build/hooks/use_conversation.d.ts +122 -0
- package/build/hooks/use_conversation.d.ts.map +1 -0
- package/build/hooks/use_conversation.js +103 -0
- package/build/hooks/use_conversation.js.map +1 -0
- package/build/hooks/use_conversation_jolt_events.d.ts.map +1 -1
- package/build/hooks/use_conversation_jolt_events.js +3 -4
- package/build/hooks/use_conversation_jolt_events.js.map +1 -1
- package/build/hooks/use_jolt.d.ts +1 -1
- package/build/hooks/use_jolt.d.ts.map +1 -1
- package/build/hooks/use_jolt.js +6 -6
- package/build/hooks/use_jolt.js.map +1 -1
- package/build/hooks/use_suspense_api.d.ts.map +1 -1
- package/build/hooks/use_suspense_api.js +3 -4
- package/build/hooks/use_suspense_api.js.map +1 -1
- package/build/navigation/header.d.ts +10 -0
- package/build/navigation/header.d.ts.map +1 -0
- package/build/navigation/header.js +16 -0
- package/build/navigation/header.js.map +1 -0
- package/build/navigation/index.d.ts +17 -4
- package/build/navigation/index.d.ts.map +1 -1
- package/build/navigation/index.js +18 -6
- package/build/navigation/index.js.map +1 -1
- package/build/screens/conversation_details_screen.d.ts +7 -0
- package/build/screens/conversation_details_screen.d.ts.map +1 -0
- package/build/screens/conversation_details_screen.js +155 -0
- package/build/screens/conversation_details_screen.js.map +1 -0
- package/build/screens/conversation_screen.d.ts +5 -3
- package/build/screens/conversation_screen.d.ts.map +1 -1
- package/build/screens/conversation_screen.js +43 -15
- package/build/screens/conversation_screen.js.map +1 -1
- package/build/screens/message_actions_screen.d.ts.map +1 -1
- package/build/screens/message_actions_screen.js +7 -7
- package/build/screens/message_actions_screen.js.map +1 -1
- package/build/utils/client/request_helpers.d.ts +2 -1
- package/build/utils/client/request_helpers.d.ts.map +1 -1
- package/build/utils/client/request_helpers.js +17 -0
- package/build/utils/client/request_helpers.js.map +1 -1
- package/package.json +2 -2
- package/src/components/conversation/message_form.tsx +4 -4
- package/src/contexts/api_provider.tsx +5 -5
- package/src/contexts/chat_context.tsx +4 -21
- package/src/hooks/use_api_client.ts +29 -0
- package/src/hooks/use_conversation.ts +113 -0
- package/src/hooks/use_conversation_jolt_events.ts +3 -4
- package/src/hooks/use_jolt.ts +9 -9
- package/src/hooks/use_suspense_api.ts +3 -4
- package/src/navigation/header.tsx +24 -0
- package/src/navigation/index.tsx +20 -6
- package/src/screens/conversation_details_screen.tsx +205 -0
- package/src/screens/conversation_screen.tsx +65 -20
- package/src/screens/message_actions_screen.tsx +7 -7
- package/src/utils/client/request_helpers.ts +21 -1
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { PlatformPressable } from '@react-navigation/elements';
|
|
2
2
|
import { useNavigation } from '@react-navigation/native';
|
|
3
3
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
4
|
-
import React, { useCallback
|
|
4
|
+
import React, { useCallback } from 'react';
|
|
5
5
|
import { Alert, Platform, StyleSheet, useWindowDimensions, View } from 'react-native';
|
|
6
6
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
7
7
|
import { Text, TextButton } from '../components';
|
|
8
8
|
import { REACTION_EMOJIS, useReactionStyles } from '../components/conversation/message_reaction';
|
|
9
|
-
import { ChatContext } from '../contexts';
|
|
10
9
|
import { useTheme } from '../hooks';
|
|
10
|
+
import { useApiClient } from '../hooks/use_api_client';
|
|
11
11
|
import { getMessagesRequestArgs, useConversationMessages } from '../hooks/use_conversation_messages';
|
|
12
12
|
import { updateRecordInPagesData } from '../utils';
|
|
13
13
|
import { Clipboard } from '../utils/native_adapters';
|
|
@@ -20,7 +20,7 @@ export const MessageActionsScreenOptions = {
|
|
|
20
20
|
export function MessageActionsScreen({ route }) {
|
|
21
21
|
const navigation = useNavigation();
|
|
22
22
|
const { conversation_id, message_id } = route.params;
|
|
23
|
-
const
|
|
23
|
+
const apiClient = useApiClient();
|
|
24
24
|
const queryClient = useQueryClient();
|
|
25
25
|
const styles = useStyles();
|
|
26
26
|
const { messages, queryKey, refetch } = useConversationMessages({ conversation_id }, { refetchOnMount: false });
|
|
@@ -45,7 +45,7 @@ export function MessageActionsScreen({ route }) {
|
|
|
45
45
|
const endpoint = !mine ? 'react' : 'unreact';
|
|
46
46
|
const url = `/me/conversations/${conversation_id}/messages/${message_id}/${endpoint}`;
|
|
47
47
|
const fieldsWithValueJoined = Object.fromEntries(Object.entries(requestParams.data.fields).map(([k, v]) => [k, v.join(',')]));
|
|
48
|
-
return
|
|
48
|
+
return apiClient.chat.post({
|
|
49
49
|
url,
|
|
50
50
|
data: {
|
|
51
51
|
...requestParams.data,
|
|
@@ -56,11 +56,11 @@ export function MessageActionsScreen({ route }) {
|
|
|
56
56
|
fields: fieldsWithValueJoined,
|
|
57
57
|
},
|
|
58
58
|
});
|
|
59
|
-
}, [
|
|
59
|
+
}, [apiClient, conversation_id, message_id]);
|
|
60
60
|
const deleteMessage = useCallback(() => {
|
|
61
61
|
const url = `/me/conversations/${conversation_id}/messages/${message_id}/`;
|
|
62
|
-
return
|
|
63
|
-
}, [
|
|
62
|
+
return apiClient.chat.delete({ url });
|
|
63
|
+
}, [apiClient, conversation_id, message_id]);
|
|
64
64
|
const { mutate: handleReaction, isPending } = useMutation({
|
|
65
65
|
mutationFn: handleReactionPress,
|
|
66
66
|
onSuccess: (result) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message_actions_screen.js","sourceRoot":"","sources":["../../src/screens/message_actions_screen.tsx"],"names":[],"mappings":"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","sourcesContent":["import { PlatformPressable } from '@react-navigation/elements'\nimport { StaticScreenProps, useNavigation } from '@react-navigation/native'\nimport { NativeStackNavigationOptions } from '@react-navigation/native-stack'\nimport { InfiniteData, useMutation, useQueryClient } from '@tanstack/react-query'\nimport React, { useCallback, useContext } from 'react'\nimport { Alert, Platform, StyleSheet, useWindowDimensions, View } from 'react-native'\nimport { useSafeAreaInsets } from 'react-native-safe-area-context'\nimport { Text, TextButton } from '../components'\nimport { REACTION_EMOJIS, useReactionStyles } from '../components/conversation/message_reaction'\nimport { ChatContext } from '../contexts'\nimport { useTheme } from '../hooks'\nimport { getMessagesRequestArgs, useConversationMessages } from '../hooks/use_conversation_messages'\nimport { ApiCollection, ApiResource, MessageResource } from '../types'\nimport { ReactionCountResource } from '../types/resources/reaction'\nimport { updateRecordInPagesData } from '../utils'\nimport { Clipboard } from '../utils/native_adapters'\n\nexport const MessageActionsScreenOptions: NativeStackNavigationOptions = {\n presentation: 'formSheet',\n headerShown: false,\n sheetAllowedDetents: [0.25],\n sheetGrabberVisible: true,\n}\n\nexport type ReactionScreenProps = StaticScreenProps<{\n message_id: string\n conversation_id: string\n}>\n\nexport function MessageActionsScreen({ route }: ReactionScreenProps) {\n const navigation = useNavigation()\n const { conversation_id, message_id } = route.params\n\n const { client } = useContext(ChatContext)\n const queryClient = useQueryClient()\n const styles = useStyles()\n\n const { messages, queryKey, refetch } = useConversationMessages(\n { conversation_id },\n { refetchOnMount: false }\n )\n const message = messages.find(m => m.id === message_id)\n const myReactions = message?.reactionCounts\n .filter(reaction => reaction.mine)\n .map(reaction => reaction.value)\n\n const availableReactions = Object.entries(REACTION_EMOJIS).map(([value, emoji]) => {\n return {\n value: value as ReactionCountResource['value'],\n emoji,\n mine: myReactions?.includes(value as ReactionCountResource['value']),\n }\n })\n\n const handleCopyPress = (text?: string) => {\n Clipboard.setStringAsync(text || '')\n navigation.goBack()\n }\n\n const handleReactionPress = useCallback(\n ({ value, mine }: { value: keyof typeof REACTION_EMOJIS; mine?: boolean }) => {\n const requestParams = getMessagesRequestArgs({ conversation_id })\n\n // Value has already been updated\n const endpoint = !mine ? 'react' : 'unreact'\n const url = `/me/conversations/${conversation_id}/messages/${message_id}/${endpoint}`\n const fieldsWithValueJoined = Object.fromEntries(\n Object.entries(requestParams.data.fields).map(([k, v]) => [k, v.join(',')])\n )\n\n return client.post({\n url,\n data: {\n ...requestParams.data,\n data: {\n type: 'Message',\n attributes: { value: value },\n },\n fields: fieldsWithValueJoined,\n },\n })\n },\n [client, conversation_id, message_id]\n )\n\n const deleteMessage = useCallback(() => {\n const url = `/me/conversations/${conversation_id}/messages/${message_id}/`\n\n return client.delete({ url })\n }, [client, conversation_id, message_id])\n\n const { mutate: handleReaction, isPending } = useMutation({\n mutationFn: handleReactionPress,\n onSuccess: (result: ApiResource<MessageResource>) => {\n const updatedMessage = result.data\n type QueryData = InfiniteData<ApiCollection<MessageResource>>\n\n queryClient.setQueryData<QueryData>(queryKey, data =>\n updateRecordInPagesData({\n data,\n record: updatedMessage,\n })\n )\n navigation.goBack()\n },\n onError: () => {\n Alert.alert('Oops', 'We were unable to react to this message. Please try again.')\n },\n })\n\n const { mutate: handleDeleteMessage } = useMutation({\n mutationFn: deleteMessage,\n onSuccess: () => {\n refetch()\n navigation.goBack()\n },\n onError: () => {\n Alert.alert('Oops', 'We were unable to delete this message. Please try again.')\n },\n })\n\n return (\n <View style={styles.container}>\n <View style={styles.reactionList}>\n {availableReactions.map((reaction, index) => (\n <Reaction key={index} reaction={reaction} onPress={() => handleReaction(reaction)} />\n ))}\n </View>\n <View style={styles.actions}>\n <View style={styles.actionButton}>\n <TextButton onPress={() => handleCopyPress(message?.text)}>Copy</TextButton>\n <TextButton\n appearance=\"danger\"\n onPress={() => handleDeleteMessage()}\n disabled={isPending}\n >\n Delete\n </TextButton>\n </View>\n </View>\n </View>\n )\n}\n\nconst Reaction = ({\n reaction,\n onPress,\n}: {\n reaction: { value: ReactionCountResource['value']; emoji: string; mine: boolean | undefined }\n onPress: () => void\n}) => {\n const styles = useStyles()\n const reactionStyles = useReactionStyles({ mine: reaction.mine ? 1 : 0 })\n\n return (\n <PlatformPressable\n key={reaction.value}\n style={[reactionStyles.reaction, styles.reaction]}\n onPress={onPress}\n >\n <Text style={reactionStyles.reactionEmoji}>{REACTION_EMOJIS[reaction.value]}</Text>\n </PlatformPressable>\n )\n}\n\nconst useStyles = () => {\n const theme = useTheme()\n const { height } = useWindowDimensions()\n const { bottom } = useSafeAreaInsets()\n const btnBorderWidth = 1\n const baseSize = 44\n const reactionBtnSize = Platform.select({\n ios: baseSize,\n android: baseSize + btnBorderWidth * 2,\n })\n\n return StyleSheet.create({\n container: {\n justifyContent: 'flex-start',\n paddingTop: 12,\n paddingBottom: bottom,\n width: '100%',\n backgroundColor: theme.colors.fillColorNeutral100Inverted,\n height,\n },\n reaction: {\n height: reactionBtnSize,\n width: reactionBtnSize,\n borderWidth: btnBorderWidth,\n borderRadius: 32,\n justifyContent: 'center',\n },\n reactionList: {\n justifyContent: 'center',\n gap: 24,\n paddingVertical: 12,\n flexDirection: 'row',\n borderBottomColor: theme.colors.fillColorNeutral040,\n borderBottomWidth: 1,\n },\n actions: { flex: 1 },\n actionButton: { padding: 12, paddingBottom: 100, gap: 12 },\n })\n}\n"]}
|
|
1
|
+
{"version":3,"file":"message_actions_screen.js","sourceRoot":"","sources":["../../src/screens/message_actions_screen.tsx"],"names":[],"mappings":"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","sourcesContent":["import { PlatformPressable } from '@react-navigation/elements'\nimport { StaticScreenProps, useNavigation } from '@react-navigation/native'\nimport { NativeStackNavigationOptions } from '@react-navigation/native-stack'\nimport { InfiniteData, useMutation, useQueryClient } from '@tanstack/react-query'\nimport React, { useCallback } from 'react'\nimport { Alert, Platform, StyleSheet, useWindowDimensions, View } from 'react-native'\nimport { useSafeAreaInsets } from 'react-native-safe-area-context'\nimport { Text, TextButton } from '../components'\nimport { REACTION_EMOJIS, useReactionStyles } from '../components/conversation/message_reaction'\nimport { useTheme } from '../hooks'\nimport { useApiClient } from '../hooks/use_api_client'\nimport { getMessagesRequestArgs, useConversationMessages } from '../hooks/use_conversation_messages'\nimport { ApiCollection, ApiResource, MessageResource } from '../types'\nimport { ReactionCountResource } from '../types/resources/reaction'\nimport { updateRecordInPagesData } from '../utils'\nimport { Clipboard } from '../utils/native_adapters'\n\nexport const MessageActionsScreenOptions: NativeStackNavigationOptions = {\n presentation: 'formSheet',\n headerShown: false,\n sheetAllowedDetents: [0.25],\n sheetGrabberVisible: true,\n}\n\nexport type ReactionScreenProps = StaticScreenProps<{\n message_id: string\n conversation_id: string\n}>\n\nexport function MessageActionsScreen({ route }: ReactionScreenProps) {\n const navigation = useNavigation()\n const { conversation_id, message_id } = route.params\n\n const apiClient = useApiClient()\n const queryClient = useQueryClient()\n const styles = useStyles()\n\n const { messages, queryKey, refetch } = useConversationMessages(\n { conversation_id },\n { refetchOnMount: false }\n )\n const message = messages.find(m => m.id === message_id)\n const myReactions = message?.reactionCounts\n .filter(reaction => reaction.mine)\n .map(reaction => reaction.value)\n\n const availableReactions = Object.entries(REACTION_EMOJIS).map(([value, emoji]) => {\n return {\n value: value as ReactionCountResource['value'],\n emoji,\n mine: myReactions?.includes(value as ReactionCountResource['value']),\n }\n })\n\n const handleCopyPress = (text?: string) => {\n Clipboard.setStringAsync(text || '')\n navigation.goBack()\n }\n\n const handleReactionPress = useCallback(\n ({ value, mine }: { value: keyof typeof REACTION_EMOJIS; mine?: boolean }) => {\n const requestParams = getMessagesRequestArgs({ conversation_id })\n\n // Value has already been updated\n const endpoint = !mine ? 'react' : 'unreact'\n const url = `/me/conversations/${conversation_id}/messages/${message_id}/${endpoint}`\n const fieldsWithValueJoined = Object.fromEntries(\n Object.entries(requestParams.data.fields).map(([k, v]) => [k, v.join(',')])\n )\n\n return apiClient.chat.post({\n url,\n data: {\n ...requestParams.data,\n data: {\n type: 'Message',\n attributes: { value: value },\n },\n fields: fieldsWithValueJoined,\n },\n })\n },\n [apiClient, conversation_id, message_id]\n )\n\n const deleteMessage = useCallback(() => {\n const url = `/me/conversations/${conversation_id}/messages/${message_id}/`\n\n return apiClient.chat.delete({ url })\n }, [apiClient, conversation_id, message_id])\n\n const { mutate: handleReaction, isPending } = useMutation({\n mutationFn: handleReactionPress,\n onSuccess: (result: ApiResource<MessageResource>) => {\n const updatedMessage = result.data\n type QueryData = InfiniteData<ApiCollection<MessageResource>>\n\n queryClient.setQueryData<QueryData>(queryKey, data =>\n updateRecordInPagesData({\n data,\n record: updatedMessage,\n })\n )\n navigation.goBack()\n },\n onError: () => {\n Alert.alert('Oops', 'We were unable to react to this message. Please try again.')\n },\n })\n\n const { mutate: handleDeleteMessage } = useMutation({\n mutationFn: deleteMessage,\n onSuccess: () => {\n refetch()\n navigation.goBack()\n },\n onError: () => {\n Alert.alert('Oops', 'We were unable to delete this message. Please try again.')\n },\n })\n\n return (\n <View style={styles.container}>\n <View style={styles.reactionList}>\n {availableReactions.map((reaction, index) => (\n <Reaction key={index} reaction={reaction} onPress={() => handleReaction(reaction)} />\n ))}\n </View>\n <View style={styles.actions}>\n <View style={styles.actionButton}>\n <TextButton onPress={() => handleCopyPress(message?.text)}>Copy</TextButton>\n <TextButton\n appearance=\"danger\"\n onPress={() => handleDeleteMessage()}\n disabled={isPending}\n >\n Delete\n </TextButton>\n </View>\n </View>\n </View>\n )\n}\n\nconst Reaction = ({\n reaction,\n onPress,\n}: {\n reaction: { value: ReactionCountResource['value']; emoji: string; mine: boolean | undefined }\n onPress: () => void\n}) => {\n const styles = useStyles()\n const reactionStyles = useReactionStyles({ mine: reaction.mine ? 1 : 0 })\n\n return (\n <PlatformPressable\n key={reaction.value}\n style={[reactionStyles.reaction, styles.reaction]}\n onPress={onPress}\n >\n <Text style={reactionStyles.reactionEmoji}>{REACTION_EMOJIS[reaction.value]}</Text>\n </PlatformPressable>\n )\n}\n\nconst useStyles = () => {\n const theme = useTheme()\n const { height } = useWindowDimensions()\n const { bottom } = useSafeAreaInsets()\n const btnBorderWidth = 1\n const baseSize = 44\n const reactionBtnSize = Platform.select({\n ios: baseSize,\n android: baseSize + btnBorderWidth * 2,\n })\n\n return StyleSheet.create({\n container: {\n justifyContent: 'flex-start',\n paddingTop: 12,\n paddingBottom: bottom,\n width: '100%',\n backgroundColor: theme.colors.fillColorNeutral100Inverted,\n height,\n },\n reaction: {\n height: reactionBtnSize,\n width: reactionBtnSize,\n borderWidth: btnBorderWidth,\n borderRadius: 32,\n justifyContent: 'center',\n },\n reactionList: {\n justifyContent: 'center',\n gap: 24,\n paddingVertical: 12,\n flexDirection: 'row',\n borderBottomColor: theme.colors.fillColorNeutral040,\n borderBottomWidth: 1,\n },\n actions: { flex: 1 },\n actionButton: { padding: 12, paddingBottom: 100, gap: 12 },\n })\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Accumulator, RequestData } from './types';
|
|
1
|
+
import { Accumulator, GetRequest, PostRequest, RequestData } from './types';
|
|
2
2
|
export type MakeRequestArgs = {
|
|
3
3
|
action: 'GET' | 'POST' | 'PATCH' | 'DELETE';
|
|
4
4
|
url: string;
|
|
@@ -17,4 +17,5 @@ export declare const noQueryParamsFriendlyErrors: (request: any, args: any) => P
|
|
|
17
17
|
export declare const ensureFieldsInDev: (walk: any, args: any) => Promise<any>;
|
|
18
18
|
export declare const ensureNoQueryParamsInDev: (request: any, args: any) => Promise<any>;
|
|
19
19
|
export declare const throwErrorIfQueryParams: (url: any) => Promise<void>;
|
|
20
|
+
export declare const transformGetToPost: (args: GetRequest) => PostRequest;
|
|
20
21
|
//# sourceMappingURL=request_helpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request_helpers.d.ts","sourceRoot":"","sources":["../../../src/utils/client/request_helpers.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"request_helpers.d.ts","sourceRoot":"","sources":["../../../src/utils/client/request_helpers.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAE3E,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAA;IAC3C,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAA;IAC3B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAChC,CAAA;AAED,eAAO,MAAM,WAAW,mCAAsD,eAAe,iBA+B5F,CAAA;AAcD,eAAO,MAAM,aAAa,YAAa,WAAW,eAAe,WAAW;;;;CAM1E,CAAA;AAEF,eAAO,MAAM,yBAAyB,wCAuBrC,CAAA;AAED,eAAO,MAAM,cAAc,wCAGC,CAAA;AAE5B,eAAO,MAAM,2BAA2B,2CAGZ,CAAA;AAI5B,eAAO,MAAM,iBAAiB,wCAAyC,CAAA;AAEvE,eAAO,MAAM,wBAAwB,2CAAsD,CAAA;AAE3F,eAAO,MAAM,uBAAuB,6BAMnC,CAAA;AAED,eAAO,MAAM,kBAAkB,SAAU,UAAU,KAAG,WAkBrD,CAAA"}
|
|
@@ -80,4 +80,21 @@ export const throwErrorIfQueryParams = url => {
|
|
|
80
80
|
}
|
|
81
81
|
return Promise.resolve();
|
|
82
82
|
};
|
|
83
|
+
export const transformGetToPost = (args) => {
|
|
84
|
+
const { data, ...rest } = args;
|
|
85
|
+
const { fields, include } = data;
|
|
86
|
+
const fieldsArray = Object.entries(fields).map(([key, value]) => {
|
|
87
|
+
if (Array.isArray(value)) {
|
|
88
|
+
return [key, value.join(',')];
|
|
89
|
+
}
|
|
90
|
+
return [key, value];
|
|
91
|
+
});
|
|
92
|
+
return {
|
|
93
|
+
...rest,
|
|
94
|
+
data: {
|
|
95
|
+
fields: Object.fromEntries(fieldsArray),
|
|
96
|
+
include,
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
};
|
|
83
100
|
//# sourceMappingURL=request_helpers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request_helpers.js","sourceRoot":"","sources":["../../../src/utils/client/request_helpers.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,QAAQ,CAAA;AACtB,OAAO,GAAG,MAAM,OAAO,CAAA;AACvB,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAA;AAC/D,OAAO,iBAAiB,MAAM,sBAAsB,CAAA;AAUpD,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,EAAE,MAAM,GAAG,KAAK,EAAE,GAAG,EAAE,IAAI,GAAG,EAAE,EAAE,OAAO,GAAG,EAAE,EAAmB,EAAE,EAAE;IAC/F,sEAAsE;IACtE,IAAI,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;IACtB,MAAM,KAAK,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAA;IACxC,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAEhC,kFAAkF;IAClF,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,GAAG,QAAQ,EAAE,CAAC;SAC5D,IAAI,EAAE;SACN,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QAC5B,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;QAChB,OAAO,GAAG,CAAA;IACZ,CAAC,EAAE,EAAE,CAAC,CAAA;IAER,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACrB,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA;IAChC,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAElF,OAAO,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,EAAE;QAC/C,MAAM,EAAE,MAAM;QACd,OAAO;QACP,IAAI;KACL,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;QACjB,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;YAChB,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QACnE,CAAC;aAAM,CAAC;YACN,OAAO,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QACjC,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,MAAM,wBAAwB,GAAG;IAC/B,aAAa;IACb,OAAO;IACP,MAAM;IACN,MAAM;IACN,cAAc;IACd,cAAc;IACd,aAAa;IACb,YAAY;IACZ,QAAQ;CACT,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,OAAoB,EAAE,WAAwB,EAAE,EAAE,CAAC,CAAC;IAChF,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC;IAC5C,QAAQ,EAAE,CAAC,GAAG,OAAO,CAAC,QAAQ,EAAE,GAAG,WAAW,CAAC,QAAQ,CAAC;IACxD,2DAA2D;IAC3D,kFAAkF;IAClF,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,wBAAwB,CAAC;CACzD,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,yBAAyB,GAAG,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;IAC5D,MAAM,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,CAAA;IAEjC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,iCAAiC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;IAC9D,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAEtC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAA;IAEjC,MAAM,SAAS,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,CAAA;IAClE,MAAM,aAAa,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;IACtD,MAAM,aAAa,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAA;IAC7D,MAAM,aAAa,GAAG,CAAC,CAAC,UAAU,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IAE5E,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CACb,kCAAkC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,gBAAgB,IAAI,CAAC,GAAG,EAAE,CAC1F,CAAA;IACH,CAAC;IAED,OAAO,iBAAiB,CAAC,QAAQ,CAAC,CAAA;AACpC,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAC3C,uBAAuB,CAAC,IAAI,CAAC,GAAG,CAAC;KAC9B,IAAI,CAAC,GAAG,EAAE,CAAC,yBAAyB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;KACjD,IAAI,CAAC,iBAAiB,CAAC,CAAA;AAE5B,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAC3D,uBAAuB,CAAC,IAAI,CAAC,GAAG,CAAC;KAC9B,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;KACzB,IAAI,CAAC,iBAAiB,CAAC,CAAA;AAE5B,MAAM,WAAW,GAAG,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AAE9F,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,WAAW,CAAA;AAEvE,MAAM,CAAC,MAAM,wBAAwB,GAAG,OAAO,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC,CAAC,WAAW,CAAA;AAE3F,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAC,EAAE;IAC3C,IAAI,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAA;IACvD,CAAC;IAED,OAAO,OAAO,CAAC,OAAO,EAAE,CAAA;AAC1B,CAAC,CAAA","sourcesContent":["import _ from 'lodash'\nimport URI from 'urijs'\nimport { transformRequestData } from './transform_request_data'\nimport transformResponse from './transform_response'\nimport { Accumulator, RequestData } from './types'\n\nexport type MakeRequestArgs = {\n action: 'GET' | 'POST' | 'PATCH' | 'DELETE'\n url: string\n data?: Partial<RequestData>\n headers: Record<string, string>\n}\n\nexport const makeRequest = ({ action = 'GET', url, data = {}, headers = {} }: MakeRequestArgs) => {\n // break apart url so we can reconstruct the url with the query params\n let uri = new URI(url)\n const query = transformRequestData(data)\n const urlQuery = uri.query(true)\n\n // This likely doesn't matter but will enforce consistent ordering of query params\n const combinedQuery = Object.entries({ ...query, ...urlQuery })\n .sort()\n .reduce((obj, [key, value]) => {\n obj[key] = value\n return obj\n }, {})\n\n if (action === 'GET') {\n uri = uri.query(combinedQuery)\n }\n\n const body = ['POST', 'PATCH'].includes(action) ? JSON.stringify(data) : undefined\n\n return fetch(decodeURIComponent(uri.toString()), {\n method: action,\n headers,\n body,\n }).then(response => {\n if (response.ok) {\n return response.text().then(t => (t === '' ? '' : JSON.parse(t)))\n } else {\n return Promise.reject(response)\n }\n })\n}\n\nconst STANDARD_META_ATTRIBUTES = [\n 'total_count',\n 'count',\n 'prev',\n 'next',\n 'can_order_by',\n 'can_query_by',\n 'can_include',\n 'can_filter',\n 'parent',\n]\n\nexport const concatRecords = (records: Accumulator, moreRecords: Accumulator) => ({\n data: [...records.data, ...moreRecords.data],\n included: [...records.included, ...moreRecords.included],\n // Because custom meta can be computed on a per-page bases,\n // it is safer to remove all custom meta when concatenating multiple pages of data\n meta: _.pick(moreRecords.meta, STANDARD_META_ATTRIBUTES),\n})\n\nexport const throwErrorIfFieldsMissing = async (walk, args) => {\n const fields = args?.data?.fields\n\n if (!fields) {\n throw new Error(`Must pass fields for request: ${args.url}`)\n }\n\n const fieldTypes = Object.keys(fields)\n\n const response = await walk(args)\n\n const dataTypes = _(response.data).castArray().map('type').value()\n const includedTypes = _.map(response.included, 'type')\n const responseTypes = _.uniq(dataTypes.concat(includedTypes))\n const missingFields = _.difference(responseTypes, fieldTypes).filter(t => t)\n\n if (missingFields.length > 0) {\n throw new Error(\n `Must include fields for types: ${JSON.stringify(missingFields)} for request ${args.url}`\n )\n }\n\n return transformResponse(response)\n}\n\nexport const friendlyErrors = (walk, args) =>\n throwErrorIfQueryParams(args.url)\n .then(() => throwErrorIfFieldsMissing(walk, args))\n .then(transformResponse)\n\nexport const noQueryParamsFriendlyErrors = (request, args) =>\n throwErrorIfQueryParams(args.url)\n .then(() => request(args))\n .then(transformResponse)\n\nconst passthrough = async (walk, args) => Promise.resolve(transformResponse(await walk(args)))\n\nexport const ensureFieldsInDev = __DEV__ ? friendlyErrors : passthrough\n\nexport const ensureNoQueryParamsInDev = __DEV__ ? noQueryParamsFriendlyErrors : passthrough\n\nexport const throwErrorIfQueryParams = url => {\n if (new URI(url).search().length) {\n throw new Error('Must pass query params as data arg')\n }\n\n return Promise.resolve()\n}\n"]}
|
|
1
|
+
{"version":3,"file":"request_helpers.js","sourceRoot":"","sources":["../../../src/utils/client/request_helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import _ from 'lodash'\nimport URI from 'urijs'\nimport { transformRequestData } from './transform_request_data'\nimport transformResponse from './transform_response'\nimport { Accumulator, GetRequest, PostRequest, RequestData } from './types'\n\nexport type MakeRequestArgs = {\n action: 'GET' | 'POST' | 'PATCH' | 'DELETE'\n url: string\n data?: Partial<RequestData>\n headers: Record<string, string>\n}\n\nexport const makeRequest = ({ action = 'GET', url, data = {}, headers = {} }: MakeRequestArgs) => {\n // break apart url so we can reconstruct the url with the query params\n let uri = new URI(url)\n const query = transformRequestData(data)\n const urlQuery = uri.query(true)\n\n // This likely doesn't matter but will enforce consistent ordering of query params\n const combinedQuery = Object.entries({ ...query, ...urlQuery })\n .sort()\n .reduce((obj, [key, value]) => {\n obj[key] = value\n return obj\n }, {})\n\n if (action === 'GET') {\n uri = uri.query(combinedQuery)\n }\n\n const body = ['POST', 'PATCH'].includes(action) ? JSON.stringify(data) : undefined\n\n return fetch(decodeURIComponent(uri.toString()), {\n method: action,\n headers,\n body,\n }).then(response => {\n if (response.ok) {\n return response.text().then(t => (t === '' ? '' : JSON.parse(t)))\n } else {\n return Promise.reject(response)\n }\n })\n}\n\nconst STANDARD_META_ATTRIBUTES = [\n 'total_count',\n 'count',\n 'prev',\n 'next',\n 'can_order_by',\n 'can_query_by',\n 'can_include',\n 'can_filter',\n 'parent',\n]\n\nexport const concatRecords = (records: Accumulator, moreRecords: Accumulator) => ({\n data: [...records.data, ...moreRecords.data],\n included: [...records.included, ...moreRecords.included],\n // Because custom meta can be computed on a per-page bases,\n // it is safer to remove all custom meta when concatenating multiple pages of data\n meta: _.pick(moreRecords.meta, STANDARD_META_ATTRIBUTES),\n})\n\nexport const throwErrorIfFieldsMissing = async (walk, args) => {\n const fields = args?.data?.fields\n\n if (!fields) {\n throw new Error(`Must pass fields for request: ${args.url}`)\n }\n\n const fieldTypes = Object.keys(fields)\n\n const response = await walk(args)\n\n const dataTypes = _(response.data).castArray().map('type').value()\n const includedTypes = _.map(response.included, 'type')\n const responseTypes = _.uniq(dataTypes.concat(includedTypes))\n const missingFields = _.difference(responseTypes, fieldTypes).filter(t => t)\n\n if (missingFields.length > 0) {\n throw new Error(\n `Must include fields for types: ${JSON.stringify(missingFields)} for request ${args.url}`\n )\n }\n\n return transformResponse(response)\n}\n\nexport const friendlyErrors = (walk, args) =>\n throwErrorIfQueryParams(args.url)\n .then(() => throwErrorIfFieldsMissing(walk, args))\n .then(transformResponse)\n\nexport const noQueryParamsFriendlyErrors = (request, args) =>\n throwErrorIfQueryParams(args.url)\n .then(() => request(args))\n .then(transformResponse)\n\nconst passthrough = async (walk, args) => Promise.resolve(transformResponse(await walk(args)))\n\nexport const ensureFieldsInDev = __DEV__ ? friendlyErrors : passthrough\n\nexport const ensureNoQueryParamsInDev = __DEV__ ? noQueryParamsFriendlyErrors : passthrough\n\nexport const throwErrorIfQueryParams = url => {\n if (new URI(url).search().length) {\n throw new Error('Must pass query params as data arg')\n }\n\n return Promise.resolve()\n}\n\nexport const transformGetToPost = (args: GetRequest): PostRequest => {\n const { data, ...rest } = args\n const { fields, include } = data\n const fieldsArray = Object.entries(fields).map(([key, value]) => {\n if (Array.isArray(value)) {\n return [key, value.join(',')]\n }\n\n return [key, value]\n })\n\n return {\n ...rest,\n data: {\n fields: Object.fromEntries(fieldsArray),\n include,\n },\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@planningcenter/chat-react-native",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0-rc.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -51,5 +51,5 @@
|
|
|
51
51
|
"prettier": "^3.4.2",
|
|
52
52
|
"typescript": "<5.6.0"
|
|
53
53
|
},
|
|
54
|
-
"gitHead": "
|
|
54
|
+
"gitHead": "89f37adcdf67bbdb15dddc82a4cf821ae9b922bb"
|
|
55
55
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { useTheme as useNavigationTheme } from '@react-navigation/native'
|
|
2
2
|
import { InfiniteData, useMutation, useQueryClient } from '@tanstack/react-query'
|
|
3
|
-
import React
|
|
3
|
+
import React from 'react'
|
|
4
4
|
import { StyleSheet, TextInput, View, ViewProps } from 'react-native'
|
|
5
5
|
import { IconButton } from '../../components'
|
|
6
|
-
import { ChatContext } from '../../contexts'
|
|
7
6
|
import { useTheme } from '../../hooks'
|
|
7
|
+
import { useApiClient } from '../../hooks/use_api_client'
|
|
8
8
|
import { getMessagesQueryKey, getMessagesRequestArgs } from '../../hooks/use_conversation_messages'
|
|
9
9
|
import { ApiCollection, ApiResource, ConversationResource, MessageResource } from '../../types'
|
|
10
10
|
import { updateRecordInPagesData } from '../../utils'
|
|
@@ -31,7 +31,7 @@ const MessageFormContext = React.createContext({
|
|
|
31
31
|
function MessageFormRoot({ conversation, children }: MessagesFormRootProps) {
|
|
32
32
|
const styles = useMessageFormStyles()
|
|
33
33
|
const [text, setText] = React.useState('')
|
|
34
|
-
const
|
|
34
|
+
const apiClient = useApiClient()
|
|
35
35
|
const queryClient = useQueryClient()
|
|
36
36
|
|
|
37
37
|
const { mutate, isPending } = useMutation({
|
|
@@ -41,7 +41,7 @@ function MessageFormRoot({ conversation, children }: MessagesFormRootProps) {
|
|
|
41
41
|
Object.entries(requestParams.data.fields).map(([k, v]) => [k, v.join(',')])
|
|
42
42
|
)
|
|
43
43
|
|
|
44
|
-
return
|
|
44
|
+
return apiClient.chat.post({
|
|
45
45
|
url: `/me/conversations/${conversation.id}/messages`,
|
|
46
46
|
data: {
|
|
47
47
|
...requestParams.data,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { QueryClient, QueryClientProvider, QueryKey } from '@tanstack/react-query'
|
|
2
2
|
import React, { useContext, useEffect, useRef } from 'react'
|
|
3
3
|
import { ViewProps } from 'react-native'
|
|
4
|
-
import { Client } from '../utils'
|
|
5
4
|
import { ChatContext, ChatContextValue } from './chat_context'
|
|
6
5
|
import { RequestQueryKey } from '../hooks'
|
|
6
|
+
import { ApiClient, useApiClient } from '../hooks/use_api_client'
|
|
7
7
|
|
|
8
|
-
let apiClient:
|
|
8
|
+
let apiClient: ApiClient | undefined
|
|
9
9
|
|
|
10
10
|
const defaultQueryFn = ({ queryKey }: { queryKey: QueryKey }) => {
|
|
11
11
|
if (!apiClient) {
|
|
@@ -14,7 +14,7 @@ const defaultQueryFn = ({ queryKey }: { queryKey: QueryKey }) => {
|
|
|
14
14
|
|
|
15
15
|
const [url, data, headers] = queryKey as RequestQueryKey
|
|
16
16
|
|
|
17
|
-
return apiClient.get({ url, data, headers })
|
|
17
|
+
return apiClient.chat.get({ url, data, headers })
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export const queryClient = new QueryClient({
|
|
@@ -27,10 +27,10 @@ export const queryClient = new QueryClient({
|
|
|
27
27
|
})
|
|
28
28
|
|
|
29
29
|
export function ApiProvider({ children }: ViewProps) {
|
|
30
|
-
const { token, env
|
|
30
|
+
const { token, env } = useContext(ChatContext)
|
|
31
31
|
const sessionChanged = useSessionChanged({ token, env })
|
|
32
32
|
|
|
33
|
-
apiClient =
|
|
33
|
+
apiClient = useApiClient()
|
|
34
34
|
|
|
35
35
|
useEffect(() => {
|
|
36
36
|
if (!sessionChanged) return
|
|
@@ -2,7 +2,7 @@ import { merge } from 'lodash'
|
|
|
2
2
|
import React, { createContext, useMemo } from 'react'
|
|
3
3
|
import { ColorSchemeName, useColorScheme } from 'react-native'
|
|
4
4
|
import { DeepPartial, OAuthToken } from '../types'
|
|
5
|
-
import {
|
|
5
|
+
import { ENV, Session } from '../utils'
|
|
6
6
|
import { ChatTheme, defaultTheme, DefaultTheme } from '../utils/theme'
|
|
7
7
|
|
|
8
8
|
export type ChatContextValue = {
|
|
@@ -10,49 +10,32 @@ export type ChatContextValue = {
|
|
|
10
10
|
onTokenExpired: () => void
|
|
11
11
|
theme: ChatTheme
|
|
12
12
|
env?: ENV
|
|
13
|
-
|
|
13
|
+
session: Session
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
export interface ChatProviderProps extends Omit<ChatContextValue, 'client' | 'theme'> {
|
|
17
17
|
theme: CreateChatThemeProps
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
const defaultChatClient = new Client({
|
|
21
|
-
app: 'chat',
|
|
22
|
-
session: new Session(),
|
|
23
|
-
version: '2018-11-01',
|
|
24
|
-
onTokenExpired: () => null,
|
|
25
|
-
})
|
|
26
|
-
|
|
27
20
|
export const ChatContext = createContext<ChatContextValue>({
|
|
28
21
|
theme: defaultTheme('light'),
|
|
29
22
|
token: undefined,
|
|
30
23
|
env: undefined,
|
|
31
24
|
onTokenExpired: () => {},
|
|
32
|
-
|
|
25
|
+
session: new Session(),
|
|
33
26
|
})
|
|
34
27
|
|
|
35
28
|
export function ChatProvider({ children, value }: { children: any; value: ChatProviderProps }) {
|
|
36
29
|
const { env, token, onTokenExpired } = value
|
|
37
30
|
const theme = useCreateChatTheme(value.theme || {})
|
|
38
31
|
const session = useMemo(() => new Session({ token, env }), [env, token])
|
|
39
|
-
const client = useMemo(
|
|
40
|
-
() =>
|
|
41
|
-
new Client({
|
|
42
|
-
app: 'chat',
|
|
43
|
-
session,
|
|
44
|
-
version: '2018-11-01',
|
|
45
|
-
onTokenExpired,
|
|
46
|
-
}),
|
|
47
|
-
[onTokenExpired, session]
|
|
48
|
-
)
|
|
49
32
|
|
|
50
33
|
const contextValue: ChatContextValue = {
|
|
51
34
|
env,
|
|
52
35
|
token,
|
|
53
36
|
onTokenExpired,
|
|
37
|
+
session,
|
|
54
38
|
theme,
|
|
55
|
-
client,
|
|
56
39
|
}
|
|
57
40
|
|
|
58
41
|
return <ChatContext.Provider value={contextValue}>{children}</ChatContext.Provider>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useContext, useMemo } from 'react'
|
|
2
|
+
import { ChatContext } from '../contexts'
|
|
3
|
+
import { Client } from '../utils'
|
|
4
|
+
|
|
5
|
+
type App = 'chat' | 'groups'
|
|
6
|
+
const apps: App[] = ['chat', 'groups']
|
|
7
|
+
export type ApiClient = Record<App, Client>
|
|
8
|
+
|
|
9
|
+
export const useApiClient = () => {
|
|
10
|
+
const { session, onTokenExpired } = useContext(ChatContext)
|
|
11
|
+
const api = useMemo(
|
|
12
|
+
() =>
|
|
13
|
+
apps.reduce(
|
|
14
|
+
(acc, app) => {
|
|
15
|
+
acc[app] = new Client({
|
|
16
|
+
app,
|
|
17
|
+
session,
|
|
18
|
+
version: '2018-11-01',
|
|
19
|
+
onTokenExpired,
|
|
20
|
+
})
|
|
21
|
+
return acc
|
|
22
|
+
},
|
|
23
|
+
{} as Record<App, Client>
|
|
24
|
+
),
|
|
25
|
+
[session, onTokenExpired]
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
return api
|
|
29
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { useMutation } from '@tanstack/react-query'
|
|
2
|
+
import { ApiResource, ConversationResource } from '../types'
|
|
3
|
+
import { getRequestQueryKey, useSuspenseGet } from './use_suspense_api'
|
|
4
|
+
import { queryClient } from '../contexts'
|
|
5
|
+
import { useApiClient } from './use_api_client'
|
|
6
|
+
import { transformGetToPost } from '../utils/client/request_helpers'
|
|
7
|
+
import { useState } from 'react'
|
|
8
|
+
|
|
9
|
+
export const getConversationRequestArgs = ({ conversation_id }: { conversation_id: string }) => ({
|
|
10
|
+
url: `/me/conversations/${conversation_id}`,
|
|
11
|
+
data: {
|
|
12
|
+
fields: {
|
|
13
|
+
Conversation: [
|
|
14
|
+
'created_at',
|
|
15
|
+
'badges',
|
|
16
|
+
'groups',
|
|
17
|
+
'last_message_author_id',
|
|
18
|
+
'last_message_author_name',
|
|
19
|
+
'last_message_created_at',
|
|
20
|
+
'last_message_text_preview',
|
|
21
|
+
'preview_avatar_urls',
|
|
22
|
+
'member_ability',
|
|
23
|
+
'muted',
|
|
24
|
+
'replies_disabled',
|
|
25
|
+
'title',
|
|
26
|
+
'unread_count',
|
|
27
|
+
'updated_at',
|
|
28
|
+
],
|
|
29
|
+
MemberAbility: ['can_update', 'can_delete'],
|
|
30
|
+
ConversationBadge: ['app_name', 'pco_resource_type', 'text'],
|
|
31
|
+
},
|
|
32
|
+
include: ['badges', 'member_ability'],
|
|
33
|
+
},
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
export const useConversation = ({ conversation_id }) => {
|
|
37
|
+
return useSuspenseGet<ConversationResource>(getConversationRequestArgs({ conversation_id }))
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const useConversationMute = ({ conversation_id }: { conversation_id: string }) => {
|
|
41
|
+
const apiClient = useApiClient()
|
|
42
|
+
const requestArgs = getConversationRequestArgs({ conversation_id })
|
|
43
|
+
const queryKey = getRequestQueryKey(requestArgs)
|
|
44
|
+
const { data: conversation } = useConversation({ conversation_id })
|
|
45
|
+
const [value, setValue] = useState<boolean>(conversation.muted)
|
|
46
|
+
|
|
47
|
+
const { mutate: setMuted, ...mutation } = useMutation({
|
|
48
|
+
onMutate: async (muted: boolean) => {
|
|
49
|
+
return queryClient.setQueryData<ApiResource<ConversationResource>>(queryKey, prev => {
|
|
50
|
+
if (!prev?.data) return prev
|
|
51
|
+
setValue(muted)
|
|
52
|
+
prev.data.muted = muted
|
|
53
|
+
|
|
54
|
+
return prev
|
|
55
|
+
})
|
|
56
|
+
},
|
|
57
|
+
mutationKey: ['muteConversation'],
|
|
58
|
+
mutationFn: async (muted: boolean) => {
|
|
59
|
+
const action = muted ? 'mute' : 'unmute'
|
|
60
|
+
|
|
61
|
+
return apiClient.chat.post({
|
|
62
|
+
url: `/me/conversations/${conversation_id}/${action}`,
|
|
63
|
+
data: { data: { type: '', attributes: {} }, fields: { Conversation: 'muted' } },
|
|
64
|
+
})
|
|
65
|
+
},
|
|
66
|
+
onSuccess: (response: ApiResource<ConversationResource>) => {
|
|
67
|
+
queryClient.setQueryData<ApiResource<ConversationResource>>(queryKey, prev => {
|
|
68
|
+
if (!prev?.data) return prev
|
|
69
|
+
|
|
70
|
+
// Posting to the mute action endpoint can't return all the fields
|
|
71
|
+
// so we need to set only the fields we require
|
|
72
|
+
prev.data.muted = response.data.muted
|
|
73
|
+
setValue(response.data.muted)
|
|
74
|
+
|
|
75
|
+
return prev
|
|
76
|
+
})
|
|
77
|
+
},
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
return { muted: value, setMuted, ...mutation }
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export const useConversationUpdate = ({ conversation_id }: { conversation_id: string }) => {
|
|
84
|
+
const apiClient = useApiClient()
|
|
85
|
+
const requestArgs = getConversationRequestArgs({ conversation_id })
|
|
86
|
+
const queryKey = getRequestQueryKey(requestArgs)
|
|
87
|
+
|
|
88
|
+
return useMutation({
|
|
89
|
+
onMutate: async (update: Partial<ConversationResource>) => {
|
|
90
|
+
queryClient.setQueryData<ApiResource<ConversationResource>>(queryKey, prev => {
|
|
91
|
+
if (prev?.data) {
|
|
92
|
+
prev.data = {
|
|
93
|
+
...prev.data,
|
|
94
|
+
...update,
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return prev
|
|
99
|
+
})
|
|
100
|
+
},
|
|
101
|
+
mutationKey: ['mutateConversation'],
|
|
102
|
+
mutationFn: async (update: Partial<ConversationResource>) => {
|
|
103
|
+
const postArgs = transformGetToPost(requestArgs).data
|
|
104
|
+
return apiClient.chat.patch({
|
|
105
|
+
url: `/me/conversations/${conversation_id}/`,
|
|
106
|
+
data: { data: { type: '', attributes: update }, ...postArgs },
|
|
107
|
+
})
|
|
108
|
+
},
|
|
109
|
+
onSuccess: (response: ApiResource<ConversationResource>) => {
|
|
110
|
+
queryClient.setQueryData<ApiResource<ConversationResource>>(queryKey, () => response)
|
|
111
|
+
},
|
|
112
|
+
})
|
|
113
|
+
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { CustomMessage } from '@planningcenter/jolt-client/dist/types/JoltConnection'
|
|
2
2
|
import { InfiniteData, useQueryClient } from '@tanstack/react-query'
|
|
3
|
-
import { useContext } from 'react'
|
|
4
|
-
import { ChatContext } from '../contexts'
|
|
5
3
|
import { ApiCollection, ApiResource, ConversationResource } from '../types'
|
|
6
4
|
import { deleteRecordInPagesData, updateRecordInPagesData } from '../utils'
|
|
5
|
+
import { useApiClient } from './use_api_client'
|
|
7
6
|
import { getConversationsRequestArgs } from './use_conversations'
|
|
8
7
|
import { useCurrentPerson } from './use_current_person'
|
|
9
8
|
import { useJoltChannel, useJoltEvent } from './use_jolt'
|
|
@@ -17,7 +16,7 @@ interface JoltConversationsEvent extends CustomMessage {
|
|
|
17
16
|
}
|
|
18
17
|
|
|
19
18
|
export function useConversationsJoltEvents() {
|
|
20
|
-
const
|
|
19
|
+
const apiClient = useApiClient()
|
|
21
20
|
const queryClient = useQueryClient()
|
|
22
21
|
const currentPerson = useCurrentPerson()
|
|
23
22
|
const joltChannel = useJoltChannel(`chat.people.${currentPerson.id}`)
|
|
@@ -27,7 +26,7 @@ export function useConversationsJoltEvents() {
|
|
|
27
26
|
|
|
28
27
|
const fetchConversation = async ({ id }: ConversationResource) => {
|
|
29
28
|
const { data: argsData } = conversationsRequestArgs
|
|
30
|
-
const { data } = await
|
|
29
|
+
const { data } = await apiClient.chat.get<ApiResource<ConversationResource>>({
|
|
31
30
|
url: `/me/conversations/${id}`,
|
|
32
31
|
data: {
|
|
33
32
|
fields: argsData.fields,
|
package/src/hooks/use_jolt.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import JoltClient from '@planningcenter/jolt-client'
|
|
2
|
-
import {
|
|
3
|
-
import { useContext, useEffect, useState } from 'react'
|
|
4
|
-
import { ChatContext } from '../contexts'
|
|
5
|
-
import { ApiResource } from '../types'
|
|
2
|
+
import { CustomMessage } from '@planningcenter/jolt-client/dist/types/JoltConnection'
|
|
6
3
|
import {
|
|
7
4
|
FetchSubscribeToken,
|
|
8
5
|
JoltSubscription,
|
|
9
6
|
} from '@planningcenter/jolt-client/dist/types/JoltSubscription'
|
|
10
|
-
import {
|
|
7
|
+
import { useQuery, useSuspenseQuery } from '@tanstack/react-query'
|
|
8
|
+
import { useEffect, useState } from 'react'
|
|
9
|
+
import { ApiResource } from '../types'
|
|
10
|
+
import { useApiClient } from './use_api_client'
|
|
11
11
|
|
|
12
12
|
interface JoltResponse {
|
|
13
13
|
type: 'JoltToken'
|
|
@@ -16,12 +16,12 @@ interface JoltResponse {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export const useJoltClient = (): JoltClient | undefined => {
|
|
19
|
-
const
|
|
19
|
+
const apiClient = useApiClient()
|
|
20
20
|
const { data: joltToken } = useSuspenseQuery<ApiResource<JoltResponse>>({
|
|
21
21
|
refetchOnMount: false,
|
|
22
22
|
queryKey: ['jolt-token'],
|
|
23
23
|
queryFn: () => {
|
|
24
|
-
return
|
|
24
|
+
return apiClient.chat.post({
|
|
25
25
|
url: '/me/jolt_authorize',
|
|
26
26
|
data: {
|
|
27
27
|
data: {
|
|
@@ -38,7 +38,7 @@ export const useJoltClient = (): JoltClient | undefined => {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
const fetchSubscribeTokenFn: FetchSubscribeToken = (channel: string, connectionId: string) => {
|
|
41
|
-
return
|
|
41
|
+
return apiClient.chat
|
|
42
42
|
.post({
|
|
43
43
|
url: '/me/jolt_subscribe',
|
|
44
44
|
data: {
|
|
@@ -66,7 +66,7 @@ export const useJoltClient = (): JoltClient | undefined => {
|
|
|
66
66
|
fetchAuthTokenFn,
|
|
67
67
|
fetchSubscribeTokenFn,
|
|
68
68
|
},
|
|
69
|
-
{ logToConsole:
|
|
69
|
+
{ logToConsole: false }
|
|
70
70
|
)
|
|
71
71
|
},
|
|
72
72
|
})
|
|
@@ -4,10 +4,9 @@ import {
|
|
|
4
4
|
useSuspenseInfiniteQuery,
|
|
5
5
|
useSuspenseQuery,
|
|
6
6
|
} from '@tanstack/react-query'
|
|
7
|
-
import { useContext } from 'react'
|
|
8
|
-
import { ChatContext } from '../contexts'
|
|
9
7
|
import { ApiCollection, ApiResource, ResourceObject } from '../types'
|
|
10
8
|
import { GetRequest, RequestData } from '../utils/client/types'
|
|
9
|
+
import { useApiClient } from './use_api_client'
|
|
11
10
|
|
|
12
11
|
export const useSuspenseGet = <T extends ResourceObject | ResourceObject[]>(args: GetRequest) => {
|
|
13
12
|
type Resource = ApiResource<T>
|
|
@@ -33,7 +32,7 @@ export const useSuspensePaginator = <T extends ResourceObject>(
|
|
|
33
32
|
args: GetRequest,
|
|
34
33
|
opts?: SuspensePaginatorOptions
|
|
35
34
|
) => {
|
|
36
|
-
const
|
|
35
|
+
const apiClient = useApiClient()
|
|
37
36
|
const query = useSuspenseInfiniteQuery<
|
|
38
37
|
ApiCollection<T>,
|
|
39
38
|
Response,
|
|
@@ -50,7 +49,7 @@ export const useSuspensePaginator = <T extends ResourceObject>(
|
|
|
50
49
|
const offset = pageParam?.offset || args.data.offset
|
|
51
50
|
const data = { ...args.data, where, offset }
|
|
52
51
|
|
|
53
|
-
return
|
|
52
|
+
return apiClient.chat.get({
|
|
54
53
|
url: args.url,
|
|
55
54
|
data,
|
|
56
55
|
})
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { HeaderButton, HeaderButtonProps, Text } from '@react-navigation/elements'
|
|
3
|
+
import { StyleSheet, TextProps, TextStyle } from 'react-native'
|
|
4
|
+
|
|
5
|
+
type HeaderRightButtonProps = HeaderButtonProps & {
|
|
6
|
+
children: TextProps['children']
|
|
7
|
+
textStyle?: TextStyle
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const HeaderRightButton = (props: HeaderRightButtonProps) => {
|
|
11
|
+
const styles = StyleSheet.create({
|
|
12
|
+
text: {
|
|
13
|
+
fontSize: 16,
|
|
14
|
+
},
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<HeaderButton {...props} style={props.style}>
|
|
19
|
+
<Text style={[styles.text, props.textStyle]} numberOfLines={1}>
|
|
20
|
+
{props.children}
|
|
21
|
+
</Text>
|
|
22
|
+
</HeaderButton>
|
|
23
|
+
)
|
|
24
|
+
}
|