@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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use_jolt.js","sourceRoot":"","sources":["../../src/hooks/use_jolt.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,6BAA6B,CAAA;
|
|
1
|
+
{"version":3,"file":"use_jolt.js","sourceRoot":"","sources":["../../src/hooks/use_jolt.ts"],"names":[],"mappings":"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","sourcesContent":["import JoltClient from '@planningcenter/jolt-client'\nimport { CustomMessage } from '@planningcenter/jolt-client/dist/types/JoltConnection'\nimport {\n FetchSubscribeToken,\n JoltSubscription,\n} from '@planningcenter/jolt-client/dist/types/JoltSubscription'\nimport { useQuery, useSuspenseQuery } from '@tanstack/react-query'\nimport { useEffect, useState } from 'react'\nimport { ApiResource } from '../types'\nimport { useApiClient } from './use_api_client'\n\ninterface JoltResponse {\n type: 'JoltToken'\n id: string\n wssUrl: string\n}\n\nexport const useJoltClient = (): JoltClient | undefined => {\n const apiClient = useApiClient()\n const { data: joltToken } = useSuspenseQuery<ApiResource<JoltResponse>>({\n refetchOnMount: false,\n queryKey: ['jolt-token'],\n queryFn: () => {\n return apiClient.chat.post({\n url: '/me/jolt_authorize',\n data: {\n data: {\n type: 'JoltToken',\n attributes: {},\n },\n },\n })\n },\n })\n\n const fetchAuthTokenFn = async () => {\n return joltToken.data.id || ''\n }\n\n const fetchSubscribeTokenFn: FetchSubscribeToken = (channel: string, connectionId: string) => {\n return apiClient.chat\n .post({\n url: '/me/jolt_subscribe',\n data: {\n data: {\n type: 'JoltSubscribeToken',\n attributes: { channel, cid: connectionId },\n },\n },\n })\n .then((res: ApiResource<JoltResponse>) => res.data.id)\n }\n\n const { data: joltClient } = useQuery({\n refetchOnMount: false,\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n enabled: Boolean(joltToken),\n queryKey: ['jolt-client'],\n queryFn: async () => {\n if (!joltToken) return undefined\n\n return new JoltClient(\n joltToken?.data.wssUrl,\n {\n fetchAuthTokenFn,\n fetchSubscribeTokenFn,\n },\n { logToConsole: false }\n )\n },\n })\n\n return joltClient\n}\n\nexport function useJoltChannel(channelName: string) {\n const [joltChannel, setJoltChannel] = useState<JoltSubscription>()\n const jolt = useJoltClient()\n\n useEffect(() => {\n setJoltChannel(jolt?.subscribe(channelName))\n return () => jolt?.unsubscribe(channelName)\n }, [channelName, jolt])\n\n return joltChannel\n}\n\ntype UserCallbackFn<T> = (_event: T) => void\n\nexport function useJoltEvent<T extends CustomMessage>(\n channel: JoltSubscription | undefined,\n eventName: string,\n callback: UserCallbackFn<T>\n) {\n useEffect(() => {\n if (!channel) return () => {}\n\n return channel.bind(eventName, e => callback(e as T))\n }, [channel, eventName, callback])\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use_suspense_api.d.ts","sourceRoot":"","sources":["../../src/hooks/use_suspense_api.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kCAAkC,EAClC,YAAY,EAGb,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"use_suspense_api.d.ts","sourceRoot":"","sources":["../../src/hooks/use_suspense_api.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kCAAkC,EAClC,YAAY,EAGb,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AACrE,OAAO,EAAE,UAAU,EAAe,MAAM,uBAAuB,CAAA;AAG/D,eAAO,MAAM,cAAc,GAAI,CAAC,SAAS,cAAc,GAAG,cAAc,EAAE,QAAQ,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;CAQ3F,CAAA;AAOD,MAAM,MAAM,wBAAwB,GAAG,IAAI,CACzC,kCAAkC,EAClC,kBAAkB,GAAG,kBAAkB,GAAG,SAAS,GAAG,UAAU,CACjE,CAAA;AAED,eAAO,MAAM,oBAAoB,GAAI,CAAC,SAAS,cAAc,QACrD,UAAU,SACT,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwChC,CAAA;AAED,MAAM,MAAM,eAAe,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC,CAAA;AAC5F,eAAO,MAAM,kBAAkB,SAAU,UAAU,KAAG,eAIrD,CAAA"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { useSuspenseInfiniteQuery, useSuspenseQuery, } from '@tanstack/react-query';
|
|
2
|
-
import {
|
|
3
|
-
import { ChatContext } from '../contexts';
|
|
2
|
+
import { useApiClient } from './use_api_client';
|
|
4
3
|
export const useSuspenseGet = (args) => {
|
|
5
4
|
const { data, ...query } = useSuspenseQuery({
|
|
6
5
|
queryKey: getRequestQueryKey(args),
|
|
@@ -8,7 +7,7 @@ export const useSuspenseGet = (args) => {
|
|
|
8
7
|
return { ...data, ...query };
|
|
9
8
|
};
|
|
10
9
|
export const useSuspensePaginator = (args, opts) => {
|
|
11
|
-
const
|
|
10
|
+
const apiClient = useApiClient();
|
|
12
11
|
const query = useSuspenseInfiniteQuery({
|
|
13
12
|
queryKey: getRequestQueryKey(args),
|
|
14
13
|
queryFn: ({ pageParam }) => {
|
|
@@ -17,7 +16,7 @@ export const useSuspensePaginator = (args, opts) => {
|
|
|
17
16
|
const where = { ...argsWhere, ...pageParmWhere };
|
|
18
17
|
const offset = pageParam?.offset || args.data.offset;
|
|
19
18
|
const data = { ...args.data, where, offset };
|
|
20
|
-
return
|
|
19
|
+
return apiClient.chat.get({
|
|
21
20
|
url: args.url,
|
|
22
21
|
data,
|
|
23
22
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use_suspense_api.js","sourceRoot":"","sources":["../../src/hooks/use_suspense_api.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,wBAAwB,EACxB,gBAAgB,GACjB,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"use_suspense_api.js","sourceRoot":"","sources":["../../src/hooks/use_suspense_api.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,wBAAwB,EACxB,gBAAgB,GACjB,MAAM,uBAAuB,CAAA;AAG9B,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAE/C,MAAM,CAAC,MAAM,cAAc,GAAG,CAA8C,IAAgB,EAAE,EAAE;IAG9F,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,EAAE,GAAG,gBAAgB,CAAqB;QAC9D,QAAQ,EAAE,kBAAkB,CAAC,IAAI,CAAC;KACnC,CAAC,CAAA;IAEF,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,EAAE,CAAA;AAC9B,CAAC,CAAA;AAYD,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,IAAgB,EAChB,IAA+B,EAC/B,EAAE;IACF,MAAM,SAAS,GAAG,YAAY,EAAE,CAAA;IAChC,MAAM,KAAK,GAAG,wBAAwB,CAMpC;QACA,QAAQ,EAAE,kBAAkB,CAAC,IAAI,CAAC;QAClC,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE;YACzB,MAAM,aAAa,GAAG,SAAS,EAAE,KAAK,IAAI,EAAE,CAAA;YAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAA;YACvC,MAAM,KAAK,GAAG,EAAE,GAAG,SAAS,EAAE,GAAG,aAAa,EAAE,CAAA;YAEhD,MAAM,MAAM,GAAG,SAAS,EAAE,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAA;YACpD,MAAM,IAAI,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA;YAE5C,OAAO,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;gBACxB,GAAG,EAAE,IAAI,CAAC,GAAG;gBACb,IAAI;aACL,CAAC,CAAA;QACJ,CAAC;QACD,gBAAgB,EAAE,EAA0B;QAC5C,gBAAgB,EAAE,QAAQ,CAAC,EAAE;YAC3B,MAAM,IAAI,GAAa,QAAQ,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAA;YAChD,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAA;YAE7B,IAAI,IAAI;gBAAE,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAA;YAC3C,IAAI,MAAM;gBAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAA;YAE7C,OAAO,SAAS,CAAA;QAClB,CAAC;QACD,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;KAChB,CAAC,CAAA;IAEF,MAAM,IAAI,GAAQ,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAA;IAEpE,OAAO,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,CAAA;AAC3B,CAAC,CAAA;AAGD,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,IAAgB,EAAmB,EAAE,CAAC;IACvE,IAAI,CAAC,GAAG;IACR,IAAI,CAAC,IAAI;IACT,IAAI,CAAC,OAAO;CACb,CAAA","sourcesContent":["import {\n AnyUseSuspenseInfiniteQueryOptions,\n InfiniteData,\n useSuspenseInfiniteQuery,\n useSuspenseQuery,\n} from '@tanstack/react-query'\nimport { ApiCollection, ApiResource, ResourceObject } from '../types'\nimport { GetRequest, RequestData } from '../utils/client/types'\nimport { useApiClient } from './use_api_client'\n\nexport const useSuspenseGet = <T extends ResourceObject | ResourceObject[]>(args: GetRequest) => {\n type Resource = ApiResource<T>\n\n const { data, ...query } = useSuspenseQuery<Resource, Response>({\n queryKey: getRequestQueryKey(args),\n })\n\n return { ...data, ...query }\n}\n\ntype NextMeta = Partial<{\n offset: string\n idLt: string\n}>\n\nexport type SuspensePaginatorOptions = Omit<\n AnyUseSuspenseInfiniteQueryOptions,\n 'getNextPageParam' | 'initialPageParam' | 'queryFn' | 'queryKey'\n>\n\nexport const useSuspensePaginator = <T extends ResourceObject>(\n args: GetRequest,\n opts?: SuspensePaginatorOptions\n) => {\n const apiClient = useApiClient()\n const query = useSuspenseInfiniteQuery<\n ApiCollection<T>,\n Response,\n InfiniteData<ApiCollection<T>>,\n any,\n Partial<RequestData> | undefined\n >({\n queryKey: getRequestQueryKey(args),\n queryFn: ({ pageParam }) => {\n const pageParmWhere = pageParam?.where || {}\n const argsWhere = args.data.where || {}\n const where = { ...argsWhere, ...pageParmWhere }\n\n const offset = pageParam?.offset || args.data.offset\n const data = { ...args.data, where, offset }\n\n return apiClient.chat.get({\n url: args.url,\n data,\n })\n },\n initialPageParam: {} as Partial<RequestData>,\n getNextPageParam: lastPage => {\n const next: NextMeta = lastPage.meta?.next || {}\n const { offset, idLt } = next\n\n if (idLt) return { where: { id_lt: idLt } }\n if (offset) return { offset: Number(offset) }\n\n return undefined\n },\n ...(opts || {}),\n })\n\n const data: T[] = query.data?.pages.flatMap(page => page.data) || []\n\n return { ...query, data }\n}\n\nexport type RequestQueryKey = [GetRequest['url'], GetRequest['data'], GetRequest['headers']]\nexport const getRequestQueryKey = (args: GetRequest): RequestQueryKey => [\n args.url,\n args.data,\n args.headers,\n]\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { HeaderButtonProps } from '@react-navigation/elements';
|
|
3
|
+
import { TextProps, TextStyle } from 'react-native';
|
|
4
|
+
type HeaderRightButtonProps = HeaderButtonProps & {
|
|
5
|
+
children: TextProps['children'];
|
|
6
|
+
textStyle?: TextStyle;
|
|
7
|
+
};
|
|
8
|
+
export declare const HeaderRightButton: (props: HeaderRightButtonProps) => React.JSX.Element;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=header.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"header.d.ts","sourceRoot":"","sources":["../../src/navigation/header.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAgB,iBAAiB,EAAQ,MAAM,4BAA4B,CAAA;AAClF,OAAO,EAAc,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAE/D,KAAK,sBAAsB,GAAG,iBAAiB,GAAG;IAChD,QAAQ,EAAE,SAAS,CAAC,UAAU,CAAC,CAAA;IAC/B,SAAS,CAAC,EAAE,SAAS,CAAA;CACtB,CAAA;AAED,eAAO,MAAM,iBAAiB,UAAW,sBAAsB,sBAc9D,CAAA"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { HeaderButton, Text } from '@react-navigation/elements';
|
|
3
|
+
import { StyleSheet } from 'react-native';
|
|
4
|
+
export const HeaderRightButton = (props) => {
|
|
5
|
+
const styles = StyleSheet.create({
|
|
6
|
+
text: {
|
|
7
|
+
fontSize: 16,
|
|
8
|
+
},
|
|
9
|
+
});
|
|
10
|
+
return (<HeaderButton {...props} style={props.style}>
|
|
11
|
+
<Text style={[styles.text, props.textStyle]} numberOfLines={1}>
|
|
12
|
+
{props.children}
|
|
13
|
+
</Text>
|
|
14
|
+
</HeaderButton>);
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=header.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"header.js","sourceRoot":"","sources":["../../src/navigation/header.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,YAAY,EAAqB,IAAI,EAAE,MAAM,4BAA4B,CAAA;AAClF,OAAO,EAAE,UAAU,EAAwB,MAAM,cAAc,CAAA;AAO/D,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAA6B,EAAE,EAAE;IACjE,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;QAC/B,IAAI,EAAE;YACJ,QAAQ,EAAE,EAAE;SACb;KACF,CAAC,CAAA;IAEF,OAAO,CACL,CAAC,YAAY,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAC1C;MAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAC5D;QAAA,CAAC,KAAK,CAAC,QAAQ,CACjB;MAAA,EAAE,IAAI,CACR;IAAA,EAAE,YAAY,CAAC,CAChB,CAAA;AACH,CAAC,CAAA","sourcesContent":["import React from 'react'\nimport { HeaderButton, HeaderButtonProps, Text } from '@react-navigation/elements'\nimport { StyleSheet, TextProps, TextStyle } from 'react-native'\n\ntype HeaderRightButtonProps = HeaderButtonProps & {\n children: TextProps['children']\n textStyle?: TextStyle\n}\n\nexport const HeaderRightButton = (props: HeaderRightButtonProps) => {\n const styles = StyleSheet.create({\n text: {\n fontSize: 16,\n },\n })\n\n return (\n <HeaderButton {...props} style={props.style}>\n <Text style={[styles.text, props.textStyle]} numberOfLines={1}>\n {props.children}\n </Text>\n </HeaderButton>\n )\n}\n"]}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
1
|
import { StaticParamList } from '@react-navigation/native';
|
|
3
2
|
import { NativeStackHeaderLeftProps, NativeStackHeaderRightProps } from '@react-navigation/native-stack';
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import { ConversationsScreen } from '../screens/conversations_screen';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { ConversationDetailsScreen } from '../screens/conversation_details_screen';
|
|
7
5
|
import { ConversationScreen } from '../screens/conversation_screen';
|
|
6
|
+
import { ConversationsScreen } from '../screens/conversations_screen';
|
|
8
7
|
import { MessageActionsScreen } from '../screens/message_actions_screen';
|
|
8
|
+
import { NotFound } from '../screens/not_found';
|
|
9
9
|
import { ReactionsScreen } from '../screens/reactions_screen';
|
|
10
|
+
import { ScreenLayout } from './screenLayout';
|
|
10
11
|
export declare const ChatStack: import("@react-navigation/native").TypedNavigator<{
|
|
11
12
|
ParamList: import("@react-navigation/native").ParamListBase;
|
|
12
13
|
NavigatorID: undefined;
|
|
@@ -38,6 +39,18 @@ export declare const ChatStack: import("@react-navigation/native").TypedNavigato
|
|
|
38
39
|
readonly Conversation: {
|
|
39
40
|
readonly screen: typeof ConversationScreen;
|
|
40
41
|
};
|
|
42
|
+
readonly ConversationDetails: {
|
|
43
|
+
readonly screen: typeof ConversationDetailsScreen;
|
|
44
|
+
readonly options: ({ navigation }: {
|
|
45
|
+
route: import("@react-navigation/native").RouteProp<import("@react-navigation/native").ParamListBase, string>;
|
|
46
|
+
navigation: import("@react-navigation/native-stack").NativeStackNavigationProp<import("@react-navigation/native").ParamListBase, string, undefined>;
|
|
47
|
+
theme: ReactNavigation.Theme;
|
|
48
|
+
}) => {
|
|
49
|
+
presentation: "modal";
|
|
50
|
+
title: string;
|
|
51
|
+
headerRight: (props: NativeStackHeaderRightProps) => React.JSX.Element;
|
|
52
|
+
};
|
|
53
|
+
};
|
|
41
54
|
readonly MessageActions: {
|
|
42
55
|
readonly screen: typeof MessageActionsScreen;
|
|
43
56
|
readonly options: import("@react-navigation/native-stack").NativeStackNavigationOptions;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/navigation/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/navigation/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,EAEL,0BAA0B,EAC1B,2BAA2B,EAC5B,MAAM,gCAAgC,CAAA;AACvC,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAE,yBAAyB,EAAE,MAAM,wCAAwC,CAAA;AAClF,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAA;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAA;AACrE,OAAO,EACL,oBAAoB,EAErB,MAAM,mCAAmC,CAAA;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EAAE,eAAe,EAA0B,MAAM,6BAA6B,CAAA;AAErF,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAE7C,eAAO,MAAM,SAAS;;;;;;;;;uOAVG,mBAAmB;;;;;;;;;;;;uBA6E6rf,gBAAiB,KAAK;;;4CAzD3tf,0BAA0B;qCAKjC,2BAA2B;;;;;;;;;;;uBAoDirf,gBAAiB,KAAK;;;;qCAnCluf,2BAA2B;;;;;;;;;;;;;;;;;;;;;EA0BtD,CAAA;AAEF,KAAK,kBAAkB,GAAG,eAAe,CAAC,OAAO,SAAS,CAAC,CAAA;AAE3D,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,eAAe,CAAC;QACxB,UAAU,aAAc,SAAQ,kBAAkB;SAAG;KACtD;CACF"}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { createNativeStackNavigator, } from '@react-navigation/native-stack';
|
|
3
|
-
import { NotFound } from '../screens/not_found';
|
|
4
|
-
import { ScreenLayout } from './screenLayout';
|
|
5
|
-
import { ConversationsScreen } from '../screens/conversations_screen';
|
|
6
|
-
import { ConversationScreen } from '../screens/conversation_screen';
|
|
7
1
|
import { HeaderBackButton, HeaderButton } from '@react-navigation/elements';
|
|
2
|
+
import { createNativeStackNavigator, } from '@react-navigation/native-stack';
|
|
3
|
+
import React from 'react';
|
|
8
4
|
import { Icon } from '../components';
|
|
5
|
+
import { ConversationDetailsScreen } from '../screens/conversation_details_screen';
|
|
6
|
+
import { ConversationScreen } from '../screens/conversation_screen';
|
|
7
|
+
import { ConversationsScreen } from '../screens/conversations_screen';
|
|
9
8
|
import { MessageActionsScreen, MessageActionsScreenOptions, } from '../screens/message_actions_screen';
|
|
9
|
+
import { NotFound } from '../screens/not_found';
|
|
10
10
|
import { ReactionsScreen, ReactionsScreenOptions } from '../screens/reactions_screen';
|
|
11
|
+
import { HeaderRightButton } from './header';
|
|
12
|
+
import { ScreenLayout } from './screenLayout';
|
|
11
13
|
export const ChatStack = createNativeStackNavigator({
|
|
12
14
|
screenOptions: {
|
|
13
15
|
headerBackButtonDisplayMode: 'minimal',
|
|
@@ -27,6 +29,16 @@ export const ChatStack = createNativeStackNavigator({
|
|
|
27
29
|
Conversation: {
|
|
28
30
|
screen: ConversationScreen,
|
|
29
31
|
},
|
|
32
|
+
ConversationDetails: {
|
|
33
|
+
screen: ConversationDetailsScreen,
|
|
34
|
+
options: ({ navigation }) => ({
|
|
35
|
+
presentation: 'modal',
|
|
36
|
+
title: 'Conversation details',
|
|
37
|
+
headerRight: (props) => (<HeaderRightButton {...props} onPress={navigation.goBack}>
|
|
38
|
+
Done
|
|
39
|
+
</HeaderRightButton>),
|
|
40
|
+
}),
|
|
41
|
+
},
|
|
30
42
|
MessageActions: {
|
|
31
43
|
screen: MessageActionsScreen,
|
|
32
44
|
// Something about sheetAllowedDetents declared inline breaks TS
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/navigation/index.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/navigation/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAE3E,OAAO,EACL,0BAA0B,GAG3B,MAAM,gCAAgC,CAAA;AACvC,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AACpC,OAAO,EAAE,yBAAyB,EAAE,MAAM,wCAAwC,CAAA;AAClF,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAA;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAA;AACrE,OAAO,EACL,oBAAoB,EACpB,2BAA2B,GAC5B,MAAM,mCAAmC,CAAA;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AACrF,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAE7C,MAAM,CAAC,MAAM,SAAS,GAAG,0BAA0B,CAAC;IAClD,aAAa,EAAE;QACb,2BAA2B,EAAE,SAAS;KACvC;IACD,YAAY,EAAE,YAAY;IAC1B,OAAO,EAAE;QACP,aAAa,EAAE;YACb,MAAM,EAAE,mBAAmB;YAC3B,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;gBACnC,WAAW,EAAG,KAAK,CAAC,MAA6B,EAAE,KAAK,IAAI,MAAM;gBAClE,UAAU,EAAE,CAAC,EAAE,SAAS,EAA8B,EAAE,EAAE,CAAC,CACzD,CAAC,YAAY,CACX;YAAA,CAAC,IAAI,CAAC,IAAI,CAAC,qCAAqC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,EAC9E;UAAA,EAAE,YAAY,CAAC,CAChB;gBACD,WAAW,EAAE,CAAC,KAAkC,EAAE,EAAE,CAAC,CACnD,CAAC,gBAAgB,CACf,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,EAAG,CAAC,CAC7E,OAAO,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAC3B,IAAI,KAAK,CAAC,EACV,CACH;aACF,CAAC;SACH;QACD,YAAY,EAAE;YACZ,MAAM,EAAE,kBAAkB;SAC3B;QACD,mBAAmB,EAAE;YACnB,MAAM,EAAE,yBAAyB;YACjC,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;gBAC5B,YAAY,EAAE,OAAO;gBACrB,KAAK,EAAE,sBAAsB;gBAC7B,WAAW,EAAE,CAAC,KAAkC,EAAE,EAAE,CAAC,CACnD,CAAC,iBAAiB,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CACvD;;UACF,EAAE,iBAAiB,CAAC,CACrB;aACF,CAAC;SACH;QACD,cAAc,EAAE;YACd,MAAM,EAAE,oBAAoB;YAC5B,gEAAgE;YAChE,OAAO,EAAE,2BAA2B;SACrC;QACD,SAAS,EAAE;YACT,MAAM,EAAE,eAAe;YACvB,OAAO,EAAE,sBAAsB;SAChC;QACD,QAAQ,EAAE;YACR,MAAM,EAAE,QAAQ;YAChB,OAAO,EAAE;gBACP,KAAK,EAAE,KAAK;aACb;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,GAAG;aACV;SACF;KACF;CACF,CAAC,CAAA","sourcesContent":["import { HeaderBackButton, HeaderButton } from '@react-navigation/elements'\nimport { StaticParamList } from '@react-navigation/native'\nimport {\n createNativeStackNavigator,\n NativeStackHeaderLeftProps,\n NativeStackHeaderRightProps,\n} from '@react-navigation/native-stack'\nimport React from 'react'\nimport { Icon } from '../components'\nimport { ConversationDetailsScreen } from '../screens/conversation_details_screen'\nimport { ConversationScreen } from '../screens/conversation_screen'\nimport { ConversationsScreen } from '../screens/conversations_screen'\nimport {\n MessageActionsScreen,\n MessageActionsScreenOptions,\n} from '../screens/message_actions_screen'\nimport { NotFound } from '../screens/not_found'\nimport { ReactionsScreen, ReactionsScreenOptions } from '../screens/reactions_screen'\nimport { HeaderRightButton } from './header'\nimport { ScreenLayout } from './screenLayout'\n\nexport const ChatStack = createNativeStackNavigator({\n screenOptions: {\n headerBackButtonDisplayMode: 'minimal',\n },\n screenLayout: ScreenLayout,\n screens: {\n Conversations: {\n screen: ConversationsScreen,\n options: ({ route, navigation }) => ({\n headerTitle: (route.params as { title?: string })?.title ?? 'Chat',\n headerLeft: ({ tintColor }: NativeStackHeaderLeftProps) => (\n <HeaderButton>\n <Icon name=\"general.threeReducingHorizontalBars\" size={18} color={tintColor} />\n </HeaderButton>\n ),\n headerRight: (props: NativeStackHeaderRightProps) => (\n <HeaderBackButton\n backImage={() => <Icon name=\"general.x\" size={18} color={props.tintColor} />}\n onPress={navigation.goBack}\n {...props}\n />\n ),\n }),\n },\n Conversation: {\n screen: ConversationScreen,\n },\n ConversationDetails: {\n screen: ConversationDetailsScreen,\n options: ({ navigation }) => ({\n presentation: 'modal',\n title: 'Conversation details',\n headerRight: (props: NativeStackHeaderRightProps) => (\n <HeaderRightButton {...props} onPress={navigation.goBack}>\n Done\n </HeaderRightButton>\n ),\n }),\n },\n MessageActions: {\n screen: MessageActionsScreen,\n // Something about sheetAllowedDetents declared inline breaks TS\n options: MessageActionsScreenOptions,\n },\n Reactions: {\n screen: ReactionsScreen,\n options: ReactionsScreenOptions,\n },\n NotFound: {\n screen: NotFound,\n options: {\n title: '404',\n },\n linking: {\n path: '*',\n },\n },\n },\n})\n\ntype ChatStackParamList = StaticParamList<typeof ChatStack>\n\ndeclare global {\n namespace ReactNavigation {\n interface RootParamList extends ChatStackParamList {}\n }\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { StaticScreenProps } from '@react-navigation/native';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
export type ConversationDetailsScreenProps = StaticScreenProps<{
|
|
4
|
+
conversation_id: string;
|
|
5
|
+
}>;
|
|
6
|
+
export declare function ConversationDetailsScreen({ route }: ConversationDetailsScreenProps): React.JSX.Element;
|
|
7
|
+
//# sourceMappingURL=conversation_details_screen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation_details_screen.d.ts","sourceRoot":"","sources":["../../src/screens/conversation_details_screen.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EAGlB,MAAM,0BAA0B,CAAA;AACjC,OAAO,KAA8D,MAAM,OAAO,CAAA;AAalF,MAAM,MAAM,8BAA8B,GAAG,iBAAiB,CAAC;IAC7D,eAAe,EAAE,MAAM,CAAA;CACxB,CAAC,CAAA;AAEF,wBAAgB,yBAAyB,CAAC,EAAE,KAAK,EAAE,EAAE,8BAA8B,qBAwFlF"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { useNavigation, useTheme as useNavigationTheme, } from '@react-navigation/native';
|
|
2
|
+
import React, { useCallback, useEffect, useState } from 'react';
|
|
3
|
+
import { FlatList, StyleSheet, TextInput, View } from 'react-native';
|
|
4
|
+
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
5
|
+
import { Avatar, Badge, Heading, Icon, Switch, Text } from '../components';
|
|
6
|
+
import { useSuspenseGet, useTheme } from '../hooks';
|
|
7
|
+
import { useConversation, useConversationMute, useConversationUpdate, } from '../hooks/use_conversation';
|
|
8
|
+
import { HeaderRightButton } from '../navigation/header';
|
|
9
|
+
export function ConversationDetailsScreen({ route }) {
|
|
10
|
+
const styles = useStyles();
|
|
11
|
+
const navigation = useNavigation();
|
|
12
|
+
const { data: conversation } = useConversation(route.params);
|
|
13
|
+
const canUpdate = conversation.memberAbility?.canUpdate;
|
|
14
|
+
const { data: members } = useSuspenseGet({
|
|
15
|
+
url: `/me/conversations/${route.params.conversation_id}/members`,
|
|
16
|
+
data: {
|
|
17
|
+
include: ['person'],
|
|
18
|
+
fields: {
|
|
19
|
+
Member: ['avatar', 'name', 'first_name', 'last_name', 'child', 'badges'],
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
const { muted, setMuted } = useConversationMute(route.params);
|
|
24
|
+
const { mutate: saveTitle } = useConversationUpdate(route.params);
|
|
25
|
+
const [title, setTitle] = useState(conversation.title);
|
|
26
|
+
const HeaderRight = useCallback(() => {
|
|
27
|
+
return (<HeaderRightButton onPress={() => {
|
|
28
|
+
saveTitle({ title });
|
|
29
|
+
navigation.goBack();
|
|
30
|
+
}}>
|
|
31
|
+
Done
|
|
32
|
+
</HeaderRightButton>);
|
|
33
|
+
}, [navigation, saveTitle, title]);
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
navigation.setOptions({
|
|
36
|
+
headerRight: HeaderRight,
|
|
37
|
+
});
|
|
38
|
+
}, [HeaderRight, navigation]);
|
|
39
|
+
return (<View style={styles.container}>
|
|
40
|
+
<SectionList>
|
|
41
|
+
<View style={styles.titleContainer}>
|
|
42
|
+
<View style={[styles.titleLabelContainer, !canUpdate && styles.titleInputDisabled]}>
|
|
43
|
+
<Text variant="tertiary">Title</Text>
|
|
44
|
+
{!canUpdate && <Icon name="general.lock"/>}
|
|
45
|
+
</View>
|
|
46
|
+
<TextInput editable={canUpdate} onChangeText={setTitle} style={[styles.titleInput, !canUpdate && styles.titleInputDisabled]} value={title}/>
|
|
47
|
+
</View>
|
|
48
|
+
</SectionList>
|
|
49
|
+
<SectionList>
|
|
50
|
+
<SectionListHeader>Settings</SectionListHeader>
|
|
51
|
+
<View style={styles.muteContainer}>
|
|
52
|
+
<Text variant="plain" style={styles.muteText}>
|
|
53
|
+
Mute
|
|
54
|
+
</Text>
|
|
55
|
+
<Switch value={muted} onChange={() => setMuted(!muted)}/>
|
|
56
|
+
</View>
|
|
57
|
+
</SectionList>
|
|
58
|
+
<SectionList>
|
|
59
|
+
<SectionListHeader divider={false}>Members</SectionListHeader>
|
|
60
|
+
<FlatList data={members} renderItem={({ item }) => (<View style={styles.member}>
|
|
61
|
+
<Avatar sourceUri={item.avatar}/>
|
|
62
|
+
<View style={styles.memberBody}>
|
|
63
|
+
<Text style={styles.memberName}>{item.name}</Text>
|
|
64
|
+
<View style={styles.memberBadges}>
|
|
65
|
+
{item.badges?.map((badge, index) => (<View key={index} style={styles.memberBadge}>
|
|
66
|
+
<Badge label={badge.title}/>
|
|
67
|
+
</View>))}
|
|
68
|
+
</View>
|
|
69
|
+
</View>
|
|
70
|
+
</View>)} keyExtractor={item => item.id} contentContainerStyle={styles.listContainer}/>
|
|
71
|
+
</SectionList>
|
|
72
|
+
</View>);
|
|
73
|
+
}
|
|
74
|
+
const useStyles = () => {
|
|
75
|
+
const theme = useTheme();
|
|
76
|
+
const { bottom } = useSafeAreaInsets();
|
|
77
|
+
return StyleSheet.create({
|
|
78
|
+
container: {
|
|
79
|
+
flex: 1,
|
|
80
|
+
paddingTop: 16,
|
|
81
|
+
paddingHorizontal: 16,
|
|
82
|
+
backgroundColor: theme.colors.fillColorNeutral080,
|
|
83
|
+
paddingBottom: bottom,
|
|
84
|
+
gap: 16,
|
|
85
|
+
},
|
|
86
|
+
listContainer: {
|
|
87
|
+
gap: 12,
|
|
88
|
+
},
|
|
89
|
+
member: {
|
|
90
|
+
flexDirection: 'row',
|
|
91
|
+
gap: 8,
|
|
92
|
+
},
|
|
93
|
+
memberBody: {
|
|
94
|
+
gap: 4,
|
|
95
|
+
},
|
|
96
|
+
memberName: {
|
|
97
|
+
lineHeight: 16,
|
|
98
|
+
},
|
|
99
|
+
memberBadges: {
|
|
100
|
+
flexDirection: 'row',
|
|
101
|
+
gap: 8,
|
|
102
|
+
},
|
|
103
|
+
memberBadge: {},
|
|
104
|
+
muteContainer: {
|
|
105
|
+
flexDirection: 'row',
|
|
106
|
+
justifyContent: 'space-between',
|
|
107
|
+
alignItems: 'center',
|
|
108
|
+
},
|
|
109
|
+
muteText: {
|
|
110
|
+
lineHeight: 20,
|
|
111
|
+
},
|
|
112
|
+
titleContainer: {},
|
|
113
|
+
titleLabel: {},
|
|
114
|
+
titleLabelContainer: {
|
|
115
|
+
flexDirection: 'row',
|
|
116
|
+
alignItems: 'center',
|
|
117
|
+
gap: 8,
|
|
118
|
+
},
|
|
119
|
+
titleInput: {
|
|
120
|
+
color: theme.colors.textColorDefaultPrimary,
|
|
121
|
+
},
|
|
122
|
+
titleInputDisabled: { opacity: 0.7 },
|
|
123
|
+
});
|
|
124
|
+
};
|
|
125
|
+
const SectionList = ({ children }) => {
|
|
126
|
+
const styles = useSectionListStyles();
|
|
127
|
+
return <View style={styles.container}>{children}</View>;
|
|
128
|
+
};
|
|
129
|
+
const SectionListHeader = ({ children, divider = true, }) => {
|
|
130
|
+
const styles = useSectionListStyles();
|
|
131
|
+
return (<Heading variant="h3" style={[styles.heading, divider && styles.headingDivider]}>
|
|
132
|
+
{children}
|
|
133
|
+
</Heading>);
|
|
134
|
+
};
|
|
135
|
+
const useSectionListStyles = () => {
|
|
136
|
+
const theme = useTheme();
|
|
137
|
+
const navigationTheme = useNavigationTheme();
|
|
138
|
+
return StyleSheet.create({
|
|
139
|
+
container: {
|
|
140
|
+
padding: 16,
|
|
141
|
+
backgroundColor: navigationTheme.colors.card,
|
|
142
|
+
borderRadius: 8,
|
|
143
|
+
flexDirection: 'column',
|
|
144
|
+
gap: 8,
|
|
145
|
+
},
|
|
146
|
+
heading: {
|
|
147
|
+
paddingBottom: 12,
|
|
148
|
+
},
|
|
149
|
+
headingDivider: {
|
|
150
|
+
borderBottomWidth: 1,
|
|
151
|
+
borderBottomColor: theme.colors.fillColorNeutral050Base,
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
};
|
|
155
|
+
//# sourceMappingURL=conversation_details_screen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation_details_screen.js","sourceRoot":"","sources":["../../src/screens/conversation_details_screen.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n StaticScreenProps,\n useNavigation,\n useTheme as useNavigationTheme,\n} from '@react-navigation/native'\nimport React, { PropsWithChildren, useCallback, useEffect, useState } from 'react'\nimport { FlatList, StyleSheet, TextInput, View } from 'react-native'\nimport { useSafeAreaInsets } from 'react-native-safe-area-context'\nimport { Avatar, Badge, Heading, Icon, Switch, Text } from '../components'\nimport { useSuspenseGet, useTheme } from '../hooks'\nimport {\n useConversation,\n useConversationMute,\n useConversationUpdate,\n} from '../hooks/use_conversation'\nimport { MemberResource } from '../types'\nimport { HeaderRightButton } from '../navigation/header'\n\nexport type ConversationDetailsScreenProps = StaticScreenProps<{\n conversation_id: string\n}>\n\nexport function ConversationDetailsScreen({ route }: ConversationDetailsScreenProps) {\n const styles = useStyles()\n const navigation = useNavigation()\n const { data: conversation } = useConversation(route.params)\n const canUpdate = conversation.memberAbility?.canUpdate\n\n const { data: members } = useSuspenseGet<MemberResource[]>({\n url: `/me/conversations/${route.params.conversation_id}/members`,\n data: {\n include: ['person'],\n fields: {\n Member: ['avatar', 'name', 'first_name', 'last_name', 'child', 'badges'],\n },\n },\n })\n\n const { muted, setMuted } = useConversationMute(route.params)\n const { mutate: saveTitle } = useConversationUpdate(route.params)\n const [title, setTitle] = useState(conversation.title)\n const HeaderRight = useCallback(() => {\n return (\n <HeaderRightButton\n onPress={() => {\n saveTitle({ title })\n navigation.goBack()\n }}\n >\n Done\n </HeaderRightButton>\n )\n }, [navigation, saveTitle, title])\n\n useEffect(() => {\n navigation.setOptions({\n headerRight: HeaderRight,\n })\n }, [HeaderRight, navigation])\n\n return (\n <View style={styles.container}>\n <SectionList>\n <View style={styles.titleContainer}>\n <View style={[styles.titleLabelContainer, !canUpdate && styles.titleInputDisabled]}>\n <Text variant=\"tertiary\">Title</Text>\n {!canUpdate && <Icon name=\"general.lock\" />}\n </View>\n <TextInput\n editable={canUpdate}\n onChangeText={setTitle}\n style={[styles.titleInput, !canUpdate && styles.titleInputDisabled]}\n value={title}\n />\n </View>\n </SectionList>\n <SectionList>\n <SectionListHeader>Settings</SectionListHeader>\n <View style={styles.muteContainer}>\n <Text variant=\"plain\" style={styles.muteText}>\n Mute\n </Text>\n <Switch value={muted} onChange={() => setMuted(!muted)} />\n </View>\n </SectionList>\n <SectionList>\n <SectionListHeader divider={false}>Members</SectionListHeader>\n <FlatList\n data={members}\n renderItem={({ item }) => (\n <View style={styles.member}>\n <Avatar sourceUri={item.avatar} />\n <View style={styles.memberBody}>\n <Text style={styles.memberName}>{item.name}</Text>\n <View style={styles.memberBadges}>\n {item.badges?.map((badge, index) => (\n <View key={index} style={styles.memberBadge}>\n <Badge label={badge.title} />\n </View>\n ))}\n </View>\n </View>\n </View>\n )}\n keyExtractor={item => item.id}\n contentContainerStyle={styles.listContainer}\n />\n </SectionList>\n </View>\n )\n}\n\nconst useStyles = () => {\n const theme = useTheme()\n const { bottom } = useSafeAreaInsets()\n\n return StyleSheet.create({\n container: {\n flex: 1,\n paddingTop: 16,\n paddingHorizontal: 16,\n backgroundColor: theme.colors.fillColorNeutral080,\n paddingBottom: bottom,\n gap: 16,\n },\n listContainer: {\n gap: 12,\n },\n member: {\n flexDirection: 'row',\n gap: 8,\n },\n memberBody: {\n gap: 4,\n },\n memberName: {\n lineHeight: 16,\n },\n memberBadges: {\n flexDirection: 'row',\n gap: 8,\n },\n memberBadge: {},\n muteContainer: {\n flexDirection: 'row',\n justifyContent: 'space-between',\n alignItems: 'center',\n },\n muteText: {\n lineHeight: 20,\n },\n titleContainer: {},\n titleLabel: {},\n titleLabelContainer: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 8,\n },\n titleInput: {\n color: theme.colors.textColorDefaultPrimary,\n },\n titleInputDisabled: { opacity: 0.7 },\n })\n}\n\nconst SectionList = ({ children }: PropsWithChildren) => {\n const styles = useSectionListStyles()\n\n return <View style={styles.container}>{children}</View>\n}\n\nconst SectionListHeader = ({\n children,\n divider = true,\n}: PropsWithChildren & { divider?: boolean }) => {\n const styles = useSectionListStyles()\n\n return (\n <Heading variant=\"h3\" style={[styles.heading, divider && styles.headingDivider]}>\n {children}\n </Heading>\n )\n}\n\nconst useSectionListStyles = () => {\n const theme = useTheme()\n const navigationTheme = useNavigationTheme()\n\n return StyleSheet.create({\n container: {\n padding: 16,\n backgroundColor: navigationTheme.colors.card,\n borderRadius: 8,\n flexDirection: 'column',\n gap: 8,\n },\n heading: {\n paddingBottom: 12,\n },\n headingDivider: {\n borderBottomWidth: 1,\n borderBottomColor: theme.colors.fillColorNeutral050Base,\n },\n })\n}\n"]}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { StaticScreenProps } from '@react-navigation/native';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
|
|
3
|
+
type ConversationRouteProps = {
|
|
4
4
|
conversation_id: string;
|
|
5
|
-
chat_group_graph_id
|
|
6
|
-
}
|
|
5
|
+
chat_group_graph_id?: string;
|
|
6
|
+
};
|
|
7
|
+
export type ConversationScreenProps = StaticScreenProps<ConversationRouteProps>;
|
|
7
8
|
export declare function ConversationScreen({ route }: ConversationScreenProps): React.JSX.Element;
|
|
9
|
+
export {};
|
|
8
10
|
//# sourceMappingURL=conversation_screen.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation_screen.d.ts","sourceRoot":"","sources":["../../src/screens/conversation_screen.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"conversation_screen.d.ts","sourceRoot":"","sources":["../../src/screens/conversation_screen.tsx"],"names":[],"mappings":"AACA,OAAO,EACL,iBAAiB,EAIlB,MAAM,0BAA0B,CAAA;AACjC,OAAO,KAAiC,MAAM,OAAO,CAAA;AAUrD,KAAK,sBAAsB,GAAG;IAC5B,eAAe,EAAE,MAAM,CAAA;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAC7B,CAAA;AAED,MAAM,MAAM,uBAAuB,GAAG,iBAAiB,CAAC,sBAAsB,CAAC,CAAA;AAE/E,wBAAgB,kBAAkB,CAAC,EAAE,KAAK,EAAE,EAAE,uBAAuB,qBA0CpE"}
|
|
@@ -1,30 +1,27 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
1
|
+
import { HeaderTitle, PlatformPressable } from '@react-navigation/elements';
|
|
2
|
+
import { useNavigation, useTheme as useNavigationTheme, useRoute, } from '@react-navigation/native';
|
|
3
|
+
import React, { useCallback, useEffect } from 'react';
|
|
4
|
+
import { FlatList, Platform, StyleSheet, View } from 'react-native';
|
|
4
5
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
6
|
+
import { Icon, Text } from '../components';
|
|
5
7
|
import { Message } from '../components/conversation/message';
|
|
6
8
|
import { MessageForm } from '../components/conversation/message_form';
|
|
7
9
|
import { KeyboardView } from '../components/display/keyboard_view';
|
|
10
|
+
import { useConversation } from '../hooks/use_conversation';
|
|
8
11
|
import { useConversationMessages } from '../hooks/use_conversation_messages';
|
|
9
|
-
import { useSuspenseGet } from '../hooks/use_suspense_api';
|
|
10
12
|
export function ConversationScreen({ route }) {
|
|
13
|
+
const styles = useStyles();
|
|
11
14
|
const navigation = useNavigation();
|
|
12
15
|
const { conversation_id } = route.params;
|
|
13
|
-
const
|
|
14
|
-
const { data: conversation } = useSuspenseGet({
|
|
15
|
-
url: `/me/conversations/${conversation_id}`,
|
|
16
|
-
data: {
|
|
17
|
-
fields: {
|
|
18
|
-
Conversation: ['title'],
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
});
|
|
16
|
+
const { data: conversation } = useConversation(route.params);
|
|
22
17
|
const { messages, refetch, isRefetching, fetchNextPage } = useConversationMessages({
|
|
23
18
|
conversation_id,
|
|
24
19
|
});
|
|
20
|
+
// Seems to be necessary to define this way so we get the route picked up
|
|
21
|
+
const headerTitle = useCallback((props) => <PressableHeaderTitle {...props}/>, []);
|
|
25
22
|
useEffect(() => {
|
|
26
|
-
navigation.setOptions({ title: conversation?.title });
|
|
27
|
-
}, [conversation, conversation_id, navigation]);
|
|
23
|
+
navigation.setOptions({ headerTitle, title: conversation?.title });
|
|
24
|
+
}, [conversation, conversation_id, navigation, headerTitle, conversation?.title]);
|
|
28
25
|
return (<View style={styles.container}>
|
|
29
26
|
<KeyboardView style={styles.keyboardView}>
|
|
30
27
|
<FlatList inverted contentContainerStyle={styles.listContainer} refreshing={isRefetching} onRefresh={refetch} data={messages} keyExtractor={item => item.id} renderItem={({ item }) => <Message {...item} conversation_id={conversation_id}/>} onEndReached={() => fetchNextPage()}/>
|
|
@@ -37,6 +34,37 @@ export function ConversationScreen({ route }) {
|
|
|
37
34
|
</KeyboardView>
|
|
38
35
|
</View>);
|
|
39
36
|
}
|
|
37
|
+
const PressableHeaderTitle = ({ style, children }) => {
|
|
38
|
+
const styles = usePressableHeaderStyle();
|
|
39
|
+
const navigation = useNavigation();
|
|
40
|
+
const route = useRoute();
|
|
41
|
+
const { data: conversation } = useConversation(route.params);
|
|
42
|
+
const badge = conversation.badges?.[0];
|
|
43
|
+
const subtitle = [badge?.pcoResourceType, badge?.text].filter(f => f).join(': ');
|
|
44
|
+
return (<PlatformPressable style={styles.container} onPress={() => navigation.navigate('ConversationDetails', { conversation_id: conversation?.id })}>
|
|
45
|
+
<View style={styles.titleWrapper}>
|
|
46
|
+
<HeaderTitle style={[styles.title, style]}>{children}</HeaderTitle>
|
|
47
|
+
<Icon name="general.downChevron" size={12}/>
|
|
48
|
+
</View>
|
|
49
|
+
<Text variant="tertiary">{subtitle}</Text>
|
|
50
|
+
</PlatformPressable>);
|
|
51
|
+
};
|
|
52
|
+
const usePressableHeaderStyle = () => {
|
|
53
|
+
return StyleSheet.create({
|
|
54
|
+
container: {
|
|
55
|
+
alignItems: Platform.select({ android: 'flex-start', default: 'center' }),
|
|
56
|
+
},
|
|
57
|
+
titleWrapper: {
|
|
58
|
+
alignItems: 'center',
|
|
59
|
+
columnGap: 8,
|
|
60
|
+
flexDirection: 'row',
|
|
61
|
+
},
|
|
62
|
+
title: {
|
|
63
|
+
padding: 0,
|
|
64
|
+
margin: 0,
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
};
|
|
40
68
|
const useStyles = () => {
|
|
41
69
|
const navigationTheme = useNavigationTheme();
|
|
42
70
|
const { bottom } = useSafeAreaInsets();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation_screen.js","sourceRoot":"","sources":["../../src/screens/conversation_screen.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,aAAa,EACb,QAAQ,IAAI,kBAAkB,
|
|
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 { Icon, Text } 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: string\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 subtitle = [badge?.pcoResourceType, badge?.text].filter(f => f).join(': ')\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 <Text variant=\"tertiary\">{subtitle}</Text>\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: 8,\n flexDirection: 'row',\n },\n title: {\n padding: 0,\n margin: 0,\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 +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,
|
|
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"}
|