@planningcenter/chat-react-native 3.2.0-rc.4 → 3.2.0-rc.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/build/components/conversation/message_form.d.ts +2 -2
  2. package/build/components/conversation/message_form.d.ts.map +1 -1
  3. package/build/components/conversation/message_form.js +95 -41
  4. package/build/components/conversation/message_form.js.map +1 -1
  5. package/build/contexts/chat_context.d.ts +1 -0
  6. package/build/contexts/chat_context.d.ts.map +1 -1
  7. package/build/contexts/chat_context.js +3 -1
  8. package/build/contexts/chat_context.js.map +1 -1
  9. package/build/hooks/use_giphy.d.ts +9 -0
  10. package/build/hooks/use_giphy.d.ts.map +1 -0
  11. package/build/hooks/use_giphy.js +63 -0
  12. package/build/hooks/use_giphy.js.map +1 -0
  13. package/build/hooks/use_message_create.d.ts +11 -0
  14. package/build/hooks/use_message_create.d.ts.map +1 -0
  15. package/build/hooks/use_message_create.js +35 -0
  16. package/build/hooks/use_message_create.js.map +1 -0
  17. package/build/navigation/index.d.ts +5 -0
  18. package/build/navigation/index.d.ts.map +1 -1
  19. package/build/navigation/index.js +5 -0
  20. package/build/navigation/index.js.map +1 -1
  21. package/build/screens/conversation_screen.d.ts +1 -0
  22. package/build/screens/conversation_screen.d.ts.map +1 -1
  23. package/build/screens/conversation_screen.js +1 -1
  24. package/build/screens/conversation_screen.js.map +1 -1
  25. package/build/screens/message_actions_screen.d.ts +2 -2
  26. package/build/screens/message_actions_screen.d.ts.map +1 -1
  27. package/build/screens/message_actions_screen.js.map +1 -1
  28. package/build/screens/send_giphy_screen.d.ts +10 -0
  29. package/build/screens/send_giphy_screen.d.ts.map +1 -0
  30. package/build/screens/send_giphy_screen.js +98 -0
  31. package/build/screens/send_giphy_screen.js.map +1 -0
  32. package/package.json +2 -2
  33. package/src/components/conversation/message_form.tsx +127 -58
  34. package/src/contexts/chat_context.tsx +4 -1
  35. package/src/hooks/use_giphy.ts +97 -0
  36. package/src/hooks/use_message_create.ts +55 -0
  37. package/src/navigation/index.tsx +5 -0
  38. package/src/screens/conversation_screen.tsx +2 -1
  39. package/src/screens/message_actions_screen.tsx +2 -2
  40. package/src/screens/send_giphy_screen.tsx +155 -0
@@ -1 +1 @@
1
- {"version":3,"file":"conversation_screen.js","sourceRoot":"","sources":["../../src/screens/conversation_screen.tsx"],"names":[],"mappings":"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","sourcesContent":["import { HeaderTitle, HeaderTitleProps, PlatformPressable } from '@react-navigation/elements'\nimport {\n StaticScreenProps,\n useNavigation,\n useTheme as useNavigationTheme,\n useRoute,\n} from '@react-navigation/native'\nimport React, { useCallback, useEffect } from 'react'\nimport { FlatList, Platform, StyleSheet, View } from 'react-native'\nimport { useSafeAreaInsets } from 'react-native-safe-area-context'\nimport { Badge, Icon } from '../components'\nimport { Message } from '../components/conversation/message'\nimport { MessageForm } from '../components/conversation/message_form'\nimport { KeyboardView } from '../components/display/keyboard_view'\nimport { useConversation } from '../hooks/use_conversation'\nimport { useConversationMessages } from '../hooks/use_conversation_messages'\n\ntype ConversationRouteProps = {\n conversation_id: number\n chat_group_graph_id?: string\n}\n\nexport type ConversationScreenProps = StaticScreenProps<ConversationRouteProps>\n\nexport function ConversationScreen({ route }: ConversationScreenProps) {\n const styles = useStyles()\n const navigation = useNavigation()\n\n const { conversation_id } = route.params\n const { data: conversation } = useConversation(route.params)\n const { messages, refetch, isRefetching, fetchNextPage } = useConversationMessages({\n conversation_id,\n })\n\n // Seems to be necessary to define this way so we get the route picked up\n const headerTitle = useCallback(\n (props: HeaderTitleProps) => <PressableHeaderTitle {...props} />,\n []\n )\n\n useEffect(() => {\n navigation.setOptions({ headerTitle, title: conversation?.title })\n }, [conversation, conversation_id, navigation, headerTitle, conversation?.title])\n\n return (\n <View style={styles.container}>\n <KeyboardView style={styles.keyboardView}>\n <FlatList\n inverted\n contentContainerStyle={styles.listContainer}\n refreshing={isRefetching}\n onRefresh={refetch}\n data={messages}\n keyExtractor={item => item.id}\n renderItem={({ item }) => <Message {...item} conversation_id={conversation_id} />}\n onEndReached={() => fetchNextPage()}\n />\n <MessageForm.Root conversation={conversation}>\n {/* <MessageForm.AttachmentPicker /> */}\n {/* <MessageForm.Commands /> */}\n <MessageForm.TextInput />\n <MessageForm.SubmitButton />\n </MessageForm.Root>\n </KeyboardView>\n </View>\n )\n}\n\nconst PressableHeaderTitle = ({ style, children }: HeaderTitleProps) => {\n const styles = usePressableHeaderStyle()\n const navigation = useNavigation()\n\n const route = useRoute() as ConversationScreenProps['route']\n\n const { data: conversation } = useConversation(route.params)\n const badge = conversation.badges?.[0]\n const resourceType = badge?.pcoResourceType || ''\n const productName = badge?.appName\n const name = badge?.text || undefined\n\n return (\n <PlatformPressable\n style={styles.container}\n onPress={() =>\n navigation.navigate('ConversationDetails', { conversation_id: conversation?.id })\n }\n >\n <View style={styles.titleWrapper}>\n <HeaderTitle style={[styles.title, style]}>{children}</HeaderTitle>\n <Icon name=\"general.downChevron\" size={12} />\n </View>\n <Badge\n variant=\"metaSubtle\"\n productLogoName={productName}\n label={resourceType}\n metaLabel={name}\n style={styles.badge}\n />\n </PlatformPressable>\n )\n}\n\nconst usePressableHeaderStyle = () => {\n return StyleSheet.create({\n container: {\n alignItems: Platform.select({ android: 'flex-start', default: 'center' }),\n },\n titleWrapper: {\n alignItems: 'center',\n columnGap: 4,\n flexDirection: 'row',\n },\n title: {\n padding: 0,\n margin: 0,\n },\n badge: {\n alignSelf: Platform.select({ android: 'flex-start', default: 'center' }),\n marginTop: 2,\n },\n })\n}\n\nconst useStyles = () => {\n const navigationTheme = useNavigationTheme()\n const { bottom } = useSafeAreaInsets()\n\n return StyleSheet.create({\n container: {\n flex: 1,\n justifyContent: 'center',\n backgroundColor: navigationTheme.colors.card,\n paddingBottom: bottom,\n },\n keyboardView: {\n flex: 1,\n },\n listContainer: {\n gap: 12,\n paddingHorizontal: 16,\n paddingVertical: 12,\n },\n })\n}\n"]}
1
+ {"version":3,"file":"conversation_screen.js","sourceRoot":"","sources":["../../src/screens/conversation_screen.tsx"],"names":[],"mappings":"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","sourcesContent":["import { HeaderTitle, HeaderTitleProps, PlatformPressable } from '@react-navigation/elements'\nimport {\n StaticScreenProps,\n useNavigation,\n useTheme as useNavigationTheme,\n useRoute,\n} from '@react-navigation/native'\nimport React, { useCallback, useEffect } from 'react'\nimport { FlatList, Platform, StyleSheet, View } from 'react-native'\nimport { useSafeAreaInsets } from 'react-native-safe-area-context'\nimport { Badge, Icon } from '../components'\nimport { Message } from '../components/conversation/message'\nimport { MessageForm } from '../components/conversation/message_form'\nimport { KeyboardView } from '../components/display/keyboard_view'\nimport { useConversation } from '../hooks/use_conversation'\nimport { useConversationMessages } from '../hooks/use_conversation_messages'\n\ntype ConversationRouteProps = {\n conversation_id: number\n chat_group_graph_id?: string\n clear_input?: boolean\n}\n\nexport type ConversationScreenProps = StaticScreenProps<ConversationRouteProps>\n\nexport function ConversationScreen({ route }: ConversationScreenProps) {\n const styles = useStyles()\n const navigation = useNavigation()\n\n const { conversation_id } = route.params\n const { data: conversation } = useConversation(route.params)\n const { messages, refetch, isRefetching, fetchNextPage } = useConversationMessages({\n conversation_id,\n })\n\n // Seems to be necessary to define this way so we get the route picked up\n const headerTitle = useCallback(\n (props: HeaderTitleProps) => <PressableHeaderTitle {...props} />,\n []\n )\n\n useEffect(() => {\n navigation.setOptions({ headerTitle, title: conversation?.title })\n }, [conversation, conversation_id, navigation, headerTitle, conversation?.title])\n\n return (\n <View style={styles.container}>\n <KeyboardView style={styles.keyboardView}>\n <FlatList\n inverted\n contentContainerStyle={styles.listContainer}\n refreshing={isRefetching}\n onRefresh={refetch}\n data={messages}\n keyExtractor={item => item.id}\n renderItem={({ item }) => <Message {...item} conversation_id={conversation_id} />}\n onEndReached={() => fetchNextPage()}\n />\n <MessageForm.Root conversation={conversation}>\n {/* <MessageForm.AttachmentPicker /> */}\n <MessageForm.Commands />\n <MessageForm.TextInput />\n <MessageForm.SubmitButton />\n </MessageForm.Root>\n </KeyboardView>\n </View>\n )\n}\n\nconst PressableHeaderTitle = ({ style, children }: HeaderTitleProps) => {\n const styles = usePressableHeaderStyle()\n const navigation = useNavigation()\n\n const route = useRoute() as ConversationScreenProps['route']\n\n const { data: conversation } = useConversation(route.params)\n const badge = conversation.badges?.[0]\n const resourceType = badge?.pcoResourceType || ''\n const productName = badge?.appName\n const name = badge?.text || undefined\n\n return (\n <PlatformPressable\n style={styles.container}\n onPress={() =>\n navigation.navigate('ConversationDetails', { conversation_id: conversation?.id })\n }\n >\n <View style={styles.titleWrapper}>\n <HeaderTitle style={[styles.title, style]}>{children}</HeaderTitle>\n <Icon name=\"general.downChevron\" size={12} />\n </View>\n <Badge\n variant=\"metaSubtle\"\n productLogoName={productName}\n label={resourceType}\n metaLabel={name}\n style={styles.badge}\n />\n </PlatformPressable>\n )\n}\n\nconst usePressableHeaderStyle = () => {\n return StyleSheet.create({\n container: {\n alignItems: Platform.select({ android: 'flex-start', default: 'center' }),\n },\n titleWrapper: {\n alignItems: 'center',\n columnGap: 4,\n flexDirection: 'row',\n },\n title: {\n padding: 0,\n margin: 0,\n },\n badge: {\n alignSelf: Platform.select({ android: 'flex-start', default: 'center' }),\n marginTop: 2,\n },\n })\n}\n\nconst useStyles = () => {\n const navigationTheme = useNavigationTheme()\n const { bottom } = useSafeAreaInsets()\n\n return StyleSheet.create({\n container: {\n flex: 1,\n justifyContent: 'center',\n backgroundColor: navigationTheme.colors.card,\n paddingBottom: bottom,\n },\n keyboardView: {\n flex: 1,\n },\n listContainer: {\n gap: 12,\n paddingHorizontal: 16,\n paddingVertical: 12,\n },\n })\n}\n"]}
@@ -2,9 +2,9 @@ import { StaticScreenProps } from '@react-navigation/native';
2
2
  import { NativeStackNavigationOptions } from '@react-navigation/native-stack';
3
3
  import React from 'react';
4
4
  export declare const MessageActionsScreenOptions: NativeStackNavigationOptions;
5
- export type ReactionScreenProps = StaticScreenProps<{
5
+ export type MessageActionsScreenProps = StaticScreenProps<{
6
6
  message_id: string;
7
7
  conversation_id: number;
8
8
  }>;
9
- export declare function MessageActionsScreen({ route }: ReactionScreenProps): React.JSX.Element;
9
+ export declare function MessageActionsScreen({ route }: MessageActionsScreenProps): React.JSX.Element;
10
10
  //# sourceMappingURL=message_actions_screen.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"message_actions_screen.d.ts","sourceRoot":"","sources":["../../src/screens/message_actions_screen.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAiB,MAAM,0BAA0B,CAAA;AAC3E,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAA;AAE7E,OAAO,KAAsB,MAAM,OAAO,CAAA;AAa1C,eAAO,MAAM,2BAA2B,EAAE,4BAKzC,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG,iBAAiB,CAAC;IAClD,UAAU,EAAE,MAAM,CAAA;IAClB,eAAe,EAAE,MAAM,CAAA;CACxB,CAAC,CAAA;AAEF,wBAAgB,oBAAoB,CAAC,EAAE,KAAK,EAAE,EAAE,mBAAmB,qBAiHlE"}
1
+ {"version":3,"file":"message_actions_screen.d.ts","sourceRoot":"","sources":["../../src/screens/message_actions_screen.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAiB,MAAM,0BAA0B,CAAA;AAC3E,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAA;AAE7E,OAAO,KAAsB,MAAM,OAAO,CAAA;AAa1C,eAAO,MAAM,2BAA2B,EAAE,4BAKzC,CAAA;AAED,MAAM,MAAM,yBAAyB,GAAG,iBAAiB,CAAC;IACxD,UAAU,EAAE,MAAM,CAAA;IAClB,eAAe,EAAE,MAAM,CAAA;CACxB,CAAC,CAAA;AAEF,wBAAgB,oBAAoB,CAAC,EAAE,KAAK,EAAE,EAAE,yBAAyB,qBAiHxE"}
@@ -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 } 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: number\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<ApiResource<MessageResource>>({\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 => {\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 MessageActionsScreenProps = StaticScreenProps<{\n message_id: string\n conversation_id: number\n}>\n\nexport function MessageActionsScreen({ route }: MessageActionsScreenProps) {\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<ApiResource<MessageResource>>({\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 => {\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"]}
@@ -0,0 +1,10 @@
1
+ import { StaticScreenProps } from '@react-navigation/native';
2
+ import { NativeStackNavigationOptions } from '@react-navigation/native-stack';
3
+ import React from 'react';
4
+ export declare const SendGiphyScreenOptions: NativeStackNavigationOptions;
5
+ export type SendGiphyScreenProps = StaticScreenProps<{
6
+ conversation_id: number;
7
+ search_term: string;
8
+ }>;
9
+ export declare function SendGiphyScreen({ route }: SendGiphyScreenProps): React.JSX.Element | null;
10
+ //# sourceMappingURL=send_giphy_screen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send_giphy_screen.d.ts","sourceRoot":"","sources":["../../src/screens/send_giphy_screen.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgB,iBAAiB,EAAiB,MAAM,0BAA0B,CAAA;AACzF,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAA;AAC7E,OAAO,KAAK,MAAM,OAAO,CAAA;AAUzB,eAAO,MAAM,sBAAsB,EAAE,4BAKpC,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG,iBAAiB,CAAC;IACnD,eAAe,EAAE,MAAM,CAAA;IACvB,WAAW,EAAE,MAAM,CAAA;CACpB,CAAC,CAAA;AAEF,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,EAAE,oBAAoB,4BA+F9D"}
@@ -0,0 +1,98 @@
1
+ import { StackActions, useNavigation } from '@react-navigation/native';
2
+ import React from 'react';
3
+ import { Image as NativeImage, StyleSheet, useWindowDimensions, View } from 'react-native';
4
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
5
+ import { useTheme } from '../hooks';
6
+ import { useGiphy } from '../hooks/use_giphy';
7
+ import { useMessageCreate } from '../hooks/use_message_create';
8
+ import { Button, IconButton } from '../components';
9
+ import { MAX_FONT_SIZE_MULTIPLIER } from '../utils';
10
+ import { DefaultLoading } from '../components/page/loading';
11
+ export const SendGiphyScreenOptions = {
12
+ presentation: 'formSheet',
13
+ headerShown: false,
14
+ sheetAllowedDetents: [0.75],
15
+ sheetGrabberVisible: true,
16
+ };
17
+ export function SendGiphyScreen({ route }) {
18
+ const { conversation_id, search_term } = route.params;
19
+ const styles = useStyles();
20
+ const navigation = useNavigation();
21
+ const { isPending, mutate } = useMessageCreate({ conversationId: conversation_id });
22
+ const { isSearching, result, nextResult, prevResult } = useGiphy(search_term);
23
+ const disabled = isPending || isSearching;
24
+ const { width } = useWindowDimensions();
25
+ const size = width - 24;
26
+ if (!result)
27
+ return null;
28
+ const gif = result.giphy.fixed_width;
29
+ const { url } = gif;
30
+ function goBack({ clearInput = false }) {
31
+ if (clearInput) {
32
+ const routes = navigation.getState()?.routes || [];
33
+ const conversationParams = routes.find(r => r.name === 'Conversation')?.params || {};
34
+ navigation.dispatch(StackActions.popTo('Conversation', {
35
+ ...conversationParams,
36
+ conversation_id,
37
+ clear_input: true,
38
+ }));
39
+ }
40
+ else {
41
+ navigation.goBack();
42
+ }
43
+ }
44
+ function sendGiphy() {
45
+ if (disabled)
46
+ return;
47
+ mutate({ text: '', attachments: [result] });
48
+ goBack({ clearInput: true });
49
+ }
50
+ return (<View style={styles.container}>
51
+ <NativeImage alt="Powered by Giphy" style={styles.powered_by_giphy} source={require('../../assets/images/powered_by_giphy.png')}/>
52
+ <View style={styles.control_stack}>
53
+ <View style={styles.button_group}>
54
+ <IconButton name="general.leftArrow" accessibilityLabel={'Previous GIF'} size="md" appearance="neutral" onPress={prevResult} disabled={disabled}/>
55
+ <IconButton name="general.rightArrow" accessibilityLabel={'Next GIF'} size="md" appearance="neutral" onPress={nextResult} disabled={disabled}/>
56
+ </View>
57
+ <View style={styles.button_group}>
58
+ <Button onPress={() => goBack({ clearInput: false })} title="Cancel" variant="outline" size="sm" maxFontSizeMultiplier={MAX_FONT_SIZE_MULTIPLIER}/>
59
+ <Button onPress={sendGiphy} title="Send" size="sm" disabled={disabled} maxFontSizeMultiplier={MAX_FONT_SIZE_MULTIPLIER}/>
60
+ </View>
61
+ </View>
62
+ {isSearching ? (<DefaultLoading />) : (<NativeImage source={{ uri: url }} alt={result.title} style={[styles.image, { width: size, height: size }]}/>)}
63
+ </View>);
64
+ }
65
+ const useStyles = () => {
66
+ const theme = useTheme();
67
+ const { height } = useWindowDimensions();
68
+ const { bottom } = useSafeAreaInsets();
69
+ return StyleSheet.create({
70
+ container: {
71
+ justifyContent: 'flex-start',
72
+ paddingTop: 24,
73
+ paddingHorizontal: 12,
74
+ paddingBottom: bottom,
75
+ width: '100%',
76
+ backgroundColor: theme.colors.fillColorNeutral100Inverted,
77
+ height,
78
+ gap: 12,
79
+ },
80
+ powered_by_giphy: {
81
+ width: 200,
82
+ height: 22,
83
+ },
84
+ control_stack: {
85
+ flexDirection: 'row',
86
+ justifyContent: 'space-between',
87
+ alignItems: 'center',
88
+ },
89
+ button_group: {
90
+ flexDirection: 'row',
91
+ gap: 12,
92
+ },
93
+ image: {
94
+ borderRadius: 8,
95
+ },
96
+ });
97
+ };
98
+ //# sourceMappingURL=send_giphy_screen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send_giphy_screen.js","sourceRoot":"","sources":["../../src/screens/send_giphy_screen.tsx"],"names":[],"mappings":"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","sourcesContent":["import { StackActions, StaticScreenProps, useNavigation } from '@react-navigation/native'\nimport { NativeStackNavigationOptions } from '@react-navigation/native-stack'\nimport React from 'react'\nimport { Image as NativeImage, StyleSheet, useWindowDimensions, View } from 'react-native'\nimport { useSafeAreaInsets } from 'react-native-safe-area-context'\nimport { useTheme } from '../hooks'\nimport { useGiphy } from '../hooks/use_giphy'\nimport { useMessageCreate } from '../hooks/use_message_create'\nimport { Button, IconButton } from '../components'\nimport { MAX_FONT_SIZE_MULTIPLIER } from '../utils'\nimport { DefaultLoading } from '../components/page/loading'\n\nexport const SendGiphyScreenOptions: NativeStackNavigationOptions = {\n presentation: 'formSheet',\n headerShown: false,\n sheetAllowedDetents: [0.75],\n sheetGrabberVisible: true,\n}\n\nexport type SendGiphyScreenProps = StaticScreenProps<{\n conversation_id: number\n search_term: string\n}>\n\nexport function SendGiphyScreen({ route }: SendGiphyScreenProps) {\n const { conversation_id, search_term } = route.params\n const styles = useStyles()\n const navigation = useNavigation()\n\n const { isPending, mutate } = useMessageCreate({ conversationId: conversation_id })\n const { isSearching, result, nextResult, prevResult } = useGiphy(search_term)\n const disabled = isPending || isSearching\n\n const { width } = useWindowDimensions()\n const size = width - 24\n\n if (!result) return null\n\n const gif = result.giphy.fixed_width\n const { url } = gif\n\n function goBack({ clearInput = false }) {\n if (clearInput) {\n const routes = navigation.getState()?.routes || []\n const conversationParams = routes.find(r => r.name === 'Conversation')?.params || {}\n\n navigation.dispatch(\n StackActions.popTo('Conversation', {\n ...conversationParams,\n conversation_id,\n clear_input: true,\n })\n )\n } else {\n navigation.goBack()\n }\n }\n\n function sendGiphy() {\n if (disabled) return\n\n mutate({ text: '', attachments: [result] })\n goBack({ clearInput: true })\n }\n\n return (\n <View style={styles.container}>\n <NativeImage\n alt=\"Powered by Giphy\"\n style={styles.powered_by_giphy}\n source={require('../../assets/images/powered_by_giphy.png')}\n />\n <View style={styles.control_stack}>\n <View style={styles.button_group}>\n <IconButton\n name=\"general.leftArrow\"\n accessibilityLabel={'Previous GIF'}\n size=\"md\"\n appearance=\"neutral\"\n onPress={prevResult}\n disabled={disabled}\n />\n <IconButton\n name=\"general.rightArrow\"\n accessibilityLabel={'Next GIF'}\n size=\"md\"\n appearance=\"neutral\"\n onPress={nextResult}\n disabled={disabled}\n />\n </View>\n <View style={styles.button_group}>\n <Button\n onPress={() => goBack({ clearInput: false })}\n title=\"Cancel\"\n variant=\"outline\"\n size=\"sm\"\n maxFontSizeMultiplier={MAX_FONT_SIZE_MULTIPLIER}\n />\n <Button\n onPress={sendGiphy}\n title=\"Send\"\n size=\"sm\"\n disabled={disabled}\n maxFontSizeMultiplier={MAX_FONT_SIZE_MULTIPLIER}\n />\n </View>\n </View>\n {isSearching ? (\n <DefaultLoading />\n ) : (\n <NativeImage\n source={{ uri: url }}\n alt={result.title}\n style={[styles.image, { width: size, height: size }]}\n />\n )}\n </View>\n )\n}\n\nconst useStyles = () => {\n const theme = useTheme()\n const { height } = useWindowDimensions()\n const { bottom } = useSafeAreaInsets()\n\n return StyleSheet.create({\n container: {\n justifyContent: 'flex-start',\n paddingTop: 24,\n paddingHorizontal: 12,\n paddingBottom: bottom,\n width: '100%',\n backgroundColor: theme.colors.fillColorNeutral100Inverted,\n height,\n gap: 12,\n },\n powered_by_giphy: {\n width: 200,\n height: 22,\n },\n control_stack: {\n flexDirection: 'row',\n justifyContent: 'space-between',\n alignItems: 'center',\n },\n button_group: {\n flexDirection: 'row',\n gap: 12,\n },\n image: {\n borderRadius: 8,\n },\n })\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planningcenter/chat-react-native",
3
- "version": "3.2.0-rc.4",
3
+ "version": "3.2.0-rc.5",
4
4
  "description": "",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -54,5 +54,5 @@
54
54
  "prettier": "^3.4.2",
55
55
  "typescript": "<5.6.0"
56
56
  },
57
- "gitHead": "42cbdf97b47051e3f61aaaf79e000a01a2100612"
57
+ "gitHead": "cdfce65ff2c68dc79c0e40439ea2109a1105cb3f"
58
58
  }
@@ -1,13 +1,12 @@
1
- import { useTheme as useNavigationTheme } from '@react-navigation/native'
2
- import { InfiniteData, useMutation, useQueryClient } from '@tanstack/react-query'
3
- import React from 'react'
1
+ import { useNavigation, useTheme as useNavigationTheme, useRoute } from '@react-navigation/native'
2
+ import React, { useContext, useEffect, useState } from 'react'
4
3
  import { StyleSheet, TextInput, View, ViewProps } from 'react-native'
5
- import { IconButton } from '../../components'
4
+ import { IconButton, Text } from '../../components'
6
5
  import { useTheme } from '../../hooks'
7
- import { useApiClient } from '../../hooks/use_api_client'
8
- import { getMessagesQueryKey, getMessagesRequestArgs } from '../../hooks/use_conversation_messages'
9
- import { ApiCollection, ApiResource, ConversationResource, MessageResource } from '../../types'
10
- import { updateOrCreateRecordInPagesData } from '../../utils'
6
+ import { ConversationResource } from '../../types'
7
+ import { useMessageCreate } from '../../hooks/use_message_create'
8
+ import { ConversationScreenProps } from '../../screens/conversation_screen'
9
+ import { ChatContext } from '../../contexts/chat_context'
11
10
 
12
11
  export const MessageForm = {
13
12
  Root: MessageFormRoot,
@@ -26,51 +25,77 @@ const MessageFormContext = React.createContext({
26
25
  setText: (_text: string) => {},
27
26
  onSubmit: () => {},
28
27
  disabled: false,
28
+ canGiphy: false,
29
+ usingGiphy: false,
30
+ setUsingGiphy: (_usingGiphy: boolean) => {},
29
31
  })
30
32
 
31
33
  function MessageFormRoot({ conversation, children }: MessagesFormRootProps) {
34
+ const { giphyApiKey } = useContext(ChatContext)
35
+ const canGiphy = !!giphyApiKey
32
36
  const styles = useMessageFormStyles()
33
37
  const [text, setText] = React.useState('')
34
- const apiClient = useApiClient()
35
- const queryClient = useQueryClient()
36
-
37
- const { mutate, isPending } = useMutation({
38
- mutationFn: async () => {
39
- const requestParams = getMessagesRequestArgs({ conversation_id: conversation.id })
40
- const fieldsWithValueJoined = Object.fromEntries(
41
- Object.entries(requestParams.data.fields).map(([k, v]) => [k, v.join(',')])
42
- )
43
-
44
- return apiClient.chat.post<ApiResource<MessageResource>>({
45
- url: `/me/conversations/${conversation.id}/messages`,
46
- data: {
47
- ...requestParams.data,
48
- data: {
49
- type: 'Message',
50
- attributes: { text },
51
- },
52
- fields: fieldsWithValueJoined,
53
- },
54
- })
55
- },
56
- onSuccess: (result: ApiResource<MessageResource>) => {
57
- const updatedMessage = result.data
58
- type QueryData = InfiniteData<ApiCollection<MessageResource>>
59
- const queryKey = getMessagesQueryKey({ conversation_id: conversation.id })
60
-
38
+ const [usingGiphy, setUsingGiphy] = useState(false)
39
+ const navigation = useNavigation()
40
+ const route = useRoute() as ConversationScreenProps['route']
41
+ const { status, isPending, reset, mutate } = useMessageCreate({ conversationId: conversation.id })
42
+
43
+ useEffect(() => {
44
+ if (canGiphy && !usingGiphy && text.startsWith('/giphy ')) {
45
+ setUsingGiphy(true)
61
46
  setText('')
62
- queryClient.setQueryData<QueryData>(queryKey, data =>
63
- updateOrCreateRecordInPagesData({
64
- data,
65
- record: updatedMessage,
66
- })
67
- )
68
- },
69
- })
47
+ }
48
+ }, [canGiphy, text, usingGiphy])
49
+
50
+ useEffect(() => {
51
+ switch (status) {
52
+ case 'success':
53
+ setText('')
54
+ reset()
55
+ break
56
+ }
57
+ }, [reset, status])
58
+
59
+ useEffect(() => {
60
+ if (route.params.clear_input) {
61
+ setText('')
62
+ setUsingGiphy(false)
63
+ navigation.setParams({ ...route.params, clear_input: false })
64
+ }
65
+ }, [navigation, route.params])
66
+
67
+ const canSubmit = (() => {
68
+ if (isPending) return false
69
+ if (text.length > 0) return true
70
+ return false
71
+ })()
72
+ const disabled = !canSubmit
73
+
74
+ const handleSubmit = () => {
75
+ if (!canSubmit) return
76
+
77
+ if (canGiphy && usingGiphy) {
78
+ TextInput.State.blurTextInput(TextInput.State.currentlyFocusedInput())
79
+ navigation.navigate('SendGiphy', {
80
+ conversation_id: conversation.id,
81
+ search_term: text,
82
+ })
83
+ } else {
84
+ mutate({ text })
85
+ }
86
+ }
70
87
 
71
88
  return (
72
89
  <MessageFormContext.Provider
73
- value={{ text, setText, onSubmit: () => mutate(), disabled: isPending }}
90
+ value={{
91
+ text,
92
+ setText,
93
+ onSubmit: handleSubmit,
94
+ disabled,
95
+ canGiphy,
96
+ usingGiphy,
97
+ setUsingGiphy,
98
+ }}
74
99
  >
75
100
  <View style={styles.textInputContainer}>{children}</View>
76
101
  </MessageFormContext.Provider>
@@ -79,38 +104,51 @@ function MessageFormRoot({ conversation, children }: MessagesFormRootProps) {
79
104
 
80
105
  function MessageFormInput() {
81
106
  const styles = useMessageFormStyles()
82
- const { text, setText, onSubmit } = React.useContext(MessageFormContext)
107
+ const { text, setText, onSubmit, usingGiphy } = React.useContext(MessageFormContext)
83
108
 
84
109
  return (
85
- <TextInput
86
- aria-disabled={true}
87
- placeholder="Send a message"
88
- onChangeText={setText}
89
- value={text}
90
- style={styles.textInput}
91
- onSubmitEditing={onSubmit}
92
- />
110
+ <View style={styles.textInput}>
111
+ {usingGiphy ? (
112
+ <View style={styles.giphyBadge}>
113
+ <Text>/Giphy</Text>
114
+ </View>
115
+ ) : null}
116
+
117
+ <TextInput
118
+ aria-disabled={true}
119
+ placeholder="Send a message"
120
+ onChangeText={setText}
121
+ value={text}
122
+ onSubmitEditing={onSubmit}
123
+ />
124
+ </View>
93
125
  )
94
126
  }
95
127
 
96
128
  function MessageFormSubmitBtn() {
97
129
  const styles = useMessageFormStyles()
98
- const { onSubmit, disabled } = React.useContext(MessageFormContext)
130
+ const { onSubmit, disabled, usingGiphy } = React.useContext(MessageFormContext)
99
131
 
100
132
  return (
101
133
  <IconButton
102
134
  disabled={disabled}
103
- accessibilityLabel="Send message"
135
+ accessibilityLabel={usingGiphy ? 'Search Giphy' : 'Send message'}
104
136
  size="md"
105
137
  appearance="neutral"
106
138
  style={styles.textInputSend}
107
- name={'general.upArrow'}
139
+ name={usingGiphy ? 'general.search' : 'general.upArrow'}
108
140
  onPress={onSubmit}
109
141
  />
110
142
  )
111
143
  }
112
144
 
113
145
  function MessageFormAttachmentPicker() {
146
+ const { usingGiphy } = React.useContext(MessageFormContext)
147
+
148
+ if (usingGiphy) {
149
+ return null
150
+ }
151
+
114
152
  return (
115
153
  <IconButton
116
154
  accessibilityLabel="Shazam"
@@ -122,8 +160,32 @@ function MessageFormAttachmentPicker() {
122
160
  }
123
161
 
124
162
  function MessageFormCommands() {
163
+ const { canGiphy, usingGiphy, setUsingGiphy } = React.useContext(MessageFormContext)
164
+
165
+ if (!canGiphy) {
166
+ return null
167
+ }
168
+
169
+ if (usingGiphy) {
170
+ return (
171
+ <IconButton
172
+ accessibilityLabel="Exit Giphy Search"
173
+ size="md"
174
+ appearance="neutral"
175
+ name={'general.x'}
176
+ onPress={() => setUsingGiphy(false)}
177
+ />
178
+ )
179
+ }
180
+
125
181
  return (
126
- <IconButton accessibilityLabel="Shazam" size="md" appearance="neutral" name={'general.bolt'} />
182
+ <IconButton
183
+ accessibilityLabel="Search Giphy"
184
+ size="md"
185
+ appearance="neutral"
186
+ name={'general.bolt'}
187
+ onPress={() => setUsingGiphy(true)}
188
+ />
127
189
  )
128
190
  }
129
191
 
@@ -148,12 +210,19 @@ const useMessageFormStyles = () => {
148
210
  paddingHorizontal: 20,
149
211
  borderColor: theme.colors.fillColorNeutral050Base,
150
212
  flex: 1,
213
+ flexDirection: 'row',
214
+ gap: 12,
215
+ },
216
+ giphyBadge: {
217
+ backgroundColor: theme.colors.fillColorNeutral050Base,
218
+ borderRadius: 24,
219
+ padding: 8,
220
+ paddingHorizontal: 12,
151
221
  },
152
222
  textInputSend: {
153
223
  borderRadius: 24,
154
224
  height: 36,
155
225
  width: 36,
156
- backgroundColor: theme.colors.fillColorNeutral040,
157
226
  },
158
227
  })
159
228
  }
@@ -11,6 +11,7 @@ export type ChatContextValue = {
11
11
  theme: ChatTheme
12
12
  env?: ENV
13
13
  session: Session
14
+ giphyApiKey?: string
14
15
  }
15
16
 
16
17
  export interface ChatProviderProps extends Omit<ChatContextValue, 'client' | 'theme' | 'session'> {
@@ -23,10 +24,11 @@ export const ChatContext = createContext<ChatContextValue>({
23
24
  env: undefined,
24
25
  onUnauthorizedResponse: () => {},
25
26
  session: new Session(),
27
+ giphyApiKey: undefined,
26
28
  })
27
29
 
28
30
  export function ChatProvider({ children, value }: { children: any; value: ChatProviderProps }) {
29
- const { env, token, onUnauthorizedResponse } = value
31
+ const { env, token, onUnauthorizedResponse, giphyApiKey } = value
30
32
  const theme = useCreateChatTheme(value.theme || {})
31
33
  const session = useMemo(() => new Session({ token, env }), [env, token])
32
34
 
@@ -36,6 +38,7 @@ export function ChatProvider({ children, value }: { children: any; value: ChatPr
36
38
  onUnauthorizedResponse,
37
39
  session,
38
40
  theme,
41
+ giphyApiKey,
39
42
  }
40
43
 
41
44
  return <ChatContext.Provider value={contextValue}>{children}</ChatContext.Provider>