@planningcenter/chat-react-native 4.2.1-qa-staging.5 → 4.3.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 +1 -2
- package/build/components/conversation/message_form.d.ts.map +1 -1
- package/build/components/conversation/message_form.js +51 -54
- package/build/components/conversation/message_form.js.map +1 -1
- package/build/components/conversation/message_list.d.ts +2 -3
- package/build/components/conversation/message_list.d.ts.map +1 -1
- package/build/components/conversation/message_list.js +66 -152
- package/build/components/conversation/message_list.js.map +1 -1
- package/build/contexts/api_provider.d.ts.map +1 -1
- package/build/contexts/api_provider.js +1 -2
- package/build/contexts/api_provider.js.map +1 -1
- package/build/contexts/conversation_context.d.ts +1 -3
- package/build/contexts/conversation_context.d.ts.map +1 -1
- package/build/contexts/conversation_context.js +18 -23
- package/build/contexts/conversation_context.js.map +1 -1
- package/build/hooks/paginator_meta.d.ts +1 -3
- package/build/hooks/paginator_meta.d.ts.map +1 -1
- package/build/hooks/paginator_meta.js +8 -25
- package/build/hooks/paginator_meta.js.map +1 -1
- package/build/hooks/use_api.d.ts.map +1 -1
- package/build/hooks/use_api.js +8 -5
- package/build/hooks/use_api.js.map +1 -1
- package/build/hooks/use_conversation_messages.d.ts +2 -9
- package/build/hooks/use_conversation_messages.d.ts.map +1 -1
- package/build/hooks/use_conversation_messages.js +45 -84
- package/build/hooks/use_conversation_messages.js.map +1 -1
- package/build/hooks/use_conversation_messages_jolt_events.d.ts +1 -17
- package/build/hooks/use_conversation_messages_jolt_events.d.ts.map +1 -1
- package/build/hooks/use_conversation_messages_jolt_events.js +80 -89
- package/build/hooks/use_conversation_messages_jolt_events.js.map +1 -1
- package/build/hooks/use_mark_latest_message_read.d.ts +1 -2
- package/build/hooks/use_mark_latest_message_read.d.ts.map +1 -1
- package/build/hooks/use_mark_latest_message_read.js +3 -4
- package/build/hooks/use_mark_latest_message_read.js.map +1 -1
- package/build/hooks/use_message_create_or_update.d.ts.map +1 -1
- package/build/hooks/use_message_create_or_update.js +80 -91
- package/build/hooks/use_message_create_or_update.js.map +1 -1
- package/build/hooks/use_message_reaction_toggle.d.ts.map +1 -1
- package/build/hooks/use_message_reaction_toggle.js +40 -45
- package/build/hooks/use_message_reaction_toggle.js.map +1 -1
- package/build/hooks/use_suspense_api.d.ts.map +1 -1
- package/build/hooks/use_suspense_api.js +8 -5
- package/build/hooks/use_suspense_api.js.map +1 -1
- package/build/screens/conversation_new/components/services_form.js +8 -9
- package/build/screens/conversation_new/components/services_form.js.map +1 -1
- package/build/screens/conversation_screen.d.ts +0 -1
- package/build/screens/conversation_screen.d.ts.map +1 -1
- package/build/screens/conversation_screen.js +254 -481
- 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 +26 -21
- package/build/screens/message_actions_screen.js.map +1 -1
- package/build/screens/message_report_screen.d.ts.map +1 -1
- package/build/screens/message_report_screen.js +44 -17
- package/build/screens/message_report_screen.js.map +1 -1
- package/build/screens/reactions_screen.d.ts.map +1 -1
- package/build/screens/reactions_screen.js +88 -70
- package/build/screens/reactions_screen.js.map +1 -1
- package/build/types/api_primitives.d.ts +0 -2
- package/build/types/api_primitives.d.ts.map +1 -1
- package/build/types/api_primitives.js.map +1 -1
- package/build/utils/cache/messages_cache.d.ts +0 -1
- package/build/utils/cache/messages_cache.d.ts.map +1 -1
- package/build/utils/cache/messages_cache.js +0 -3
- package/build/utils/cache/messages_cache.js.map +1 -1
- package/build/utils/cache/optimistically_update_message.d.ts +1 -2
- package/build/utils/cache/optimistically_update_message.d.ts.map +1 -1
- package/build/utils/cache/optimistically_update_message.js +4 -4
- package/build/utils/cache/optimistically_update_message.js.map +1 -1
- package/build/utils/client/types.d.ts +0 -1
- package/build/utils/client/types.d.ts.map +1 -1
- package/build/utils/client/types.js.map +1 -1
- package/build/utils/generate_placeholder_ulid.d.ts +6 -0
- package/build/utils/generate_placeholder_ulid.d.ts.map +1 -1
- package/build/utils/generate_placeholder_ulid.js +2 -2
- package/build/utils/generate_placeholder_ulid.js.map +1 -1
- package/build/utils/request/get_messages.d.ts +6 -18
- package/build/utils/request/get_messages.d.ts.map +1 -1
- package/build/utils/request/get_messages.js +12 -10
- package/build/utils/request/get_messages.js.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/hooks/paginator_meta.test.ts +2 -73
- package/src/components/conversation/__tests__/message_list.test.tsx +0 -42
- package/src/components/conversation/message_form.tsx +0 -3
- package/src/components/conversation/message_list.tsx +4 -58
- package/src/contexts/api_provider.tsx +1 -2
- package/src/contexts/conversation_context.tsx +1 -6
- package/src/hooks/paginator_meta.ts +5 -29
- package/src/hooks/use_api.ts +5 -4
- package/src/hooks/use_conversation_messages.ts +11 -52
- package/src/hooks/use_conversation_messages_jolt_events.ts +43 -62
- package/src/hooks/use_mark_latest_message_read.ts +3 -4
- package/src/hooks/use_message_create_or_update.ts +8 -8
- package/src/hooks/use_message_reaction_toggle.ts +1 -3
- package/src/hooks/use_suspense_api.ts +5 -4
- package/src/screens/conversation_new/components/services_form.tsx +5 -5
- package/src/screens/conversation_screen.tsx +14 -123
- package/src/screens/message_actions_screen.tsx +5 -3
- package/src/screens/message_report_screen.tsx +3 -2
- package/src/screens/reactions_screen.tsx +4 -2
- package/src/types/api_primitives.ts +0 -2
- package/src/utils/cache/__tests__/messages_cache.test.ts +1 -14
- package/src/utils/cache/messages_cache.ts +0 -3
- package/src/utils/cache/optimistically_update_message.ts +5 -2
- package/src/utils/client/types.ts +0 -1
- package/src/utils/generate_placeholder_ulid.ts +2 -2
- package/src/utils/request/get_messages.ts +14 -12
- package/build/components/conversation/anchor_not_found_boundary.d.ts +0 -18
- package/build/components/conversation/anchor_not_found_boundary.d.ts.map +0 -1
- package/build/components/conversation/anchor_not_found_boundary.js +0 -20
- package/build/components/conversation/anchor_not_found_boundary.js.map +0 -1
- package/build/hooks/use_conversation_message_lookup.d.ts +0 -7
- package/build/hooks/use_conversation_message_lookup.d.ts.map +0 -1
- package/build/hooks/use_conversation_message_lookup.js +0 -52
- package/build/hooks/use_conversation_message_lookup.js.map +0 -1
- package/build/hooks/use_fetch_newer_messages.d.ts +0 -9
- package/build/hooks/use_fetch_newer_messages.d.ts.map +0 -1
- package/build/hooks/use_fetch_newer_messages.js +0 -69
- package/build/hooks/use_fetch_newer_messages.js.map +0 -1
- package/build/hooks/use_fetch_newer_on_foreground.d.ts +0 -8
- package/build/hooks/use_fetch_newer_on_foreground.d.ts.map +0 -1
- package/build/hooks/use_fetch_newer_on_foreground.js +0 -42
- package/build/hooks/use_fetch_newer_on_foreground.js.map +0 -1
- package/build/hooks/use_held_back_messages.d.ts +0 -11
- package/build/hooks/use_held_back_messages.d.ts.map +0 -1
- package/build/hooks/use_held_back_messages.js +0 -24
- package/build/hooks/use_held_back_messages.js.map +0 -1
- package/build/utils/cache/find_message_in_caches.d.ts +0 -4
- package/build/utils/cache/find_message_in_caches.d.ts.map +0 -1
- package/build/utils/cache/find_message_in_caches.js +0 -16
- package/build/utils/cache/find_message_in_caches.js.map +0 -1
- package/build/utils/cache/invalidate_refetchable_queries.d.ts +0 -3
- package/build/utils/cache/invalidate_refetchable_queries.d.ts.map +0 -1
- package/build/utils/cache/invalidate_refetchable_queries.js +0 -8
- package/build/utils/cache/invalidate_refetchable_queries.js.map +0 -1
- package/build/utils/cache/prepend_newer_page.d.ts +0 -7
- package/build/utils/cache/prepend_newer_page.d.ts.map +0 -1
- package/build/utils/cache/prepend_newer_page.js +0 -15
- package/build/utils/cache/prepend_newer_page.js.map +0 -1
- package/build/utils/gated_message_cache.d.ts +0 -7
- package/build/utils/gated_message_cache.d.ts.map +0 -1
- package/build/utils/gated_message_cache.js +0 -13
- package/build/utils/gated_message_cache.js.map +0 -1
- package/build/utils/ulid.d.ts +0 -3
- package/build/utils/ulid.d.ts.map +0 -1
- package/build/utils/ulid.js +0 -7
- package/build/utils/ulid.js.map +0 -1
- package/src/__tests__/hooks/use_conversation_messages.test.ts +0 -22
- package/src/__tests__/hooks/use_conversation_messages_jolt_events.test.ts +0 -33
- package/src/__tests__/screens/conversation_new/components/services_form.test.tsx +0 -91
- package/src/__tests__/utils/gated_message_cache.test.ts +0 -26
- package/src/__tests__/utils/request/get_messages.test.ts +0 -24
- package/src/__tests__/utils/ulid.test.ts +0 -15
- package/src/components/conversation/__tests__/anchor_not_found_boundary.test.tsx +0 -51
- package/src/components/conversation/anchor_not_found_boundary.tsx +0 -21
- package/src/hooks/__tests__/use_fetch_newer_messages.test.tsx +0 -95
- package/src/hooks/__tests__/use_held_back_messages.test.tsx +0 -60
- package/src/hooks/__tests__/use_message_reaction_toggle.test.tsx +0 -73
- package/src/hooks/use_conversation_message_lookup.ts +0 -29
- package/src/hooks/use_fetch_newer_messages.ts +0 -52
- package/src/hooks/use_fetch_newer_on_foreground.ts +0 -25
- package/src/hooks/use_held_back_messages.ts +0 -33
- package/src/utils/cache/__tests__/find_message_in_caches.test.ts +0 -37
- package/src/utils/cache/__tests__/invalidate_refetchable_queries.test.ts +0 -23
- package/src/utils/cache/__tests__/prepend_newer_page.test.ts +0 -34
- package/src/utils/cache/find_message_in_caches.ts +0 -20
- package/src/utils/cache/invalidate_refetchable_queries.ts +0 -9
- package/src/utils/cache/prepend_newer_page.ts +0 -19
- package/src/utils/gated_message_cache.ts +0 -19
- package/src/utils/ulid.ts +0 -11
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"optimistically_update_message.js","names":["chatQueryClient","getMessagesQueryKey","updateOrCreateRecordInPagesData","optimisticallyUpdateMessage","conversationId","message","text","replyRootId","queryKey","conversation_id","reply_root_id","optimisticMessage","setQueryData","data","record","processRecord","next","prev","pending"],"sources":["../../../src/utils/cache/optimistically_update_message.ts"],"sourcesContent":["import { InfiniteData } from '@tanstack/react-query'\nimport { chatQueryClient } from '../../contexts/api_provider'\nimport { ApiCollection, MessageResource } from '../../types'\nimport { getMessagesQueryKey } from '../../utils/request/get_messages'\nimport { updateOrCreateRecordInPagesData } from './page_mutations'\n\nexport function optimisticallyUpdateMessage({\n conversationId,\n message,\n text,\n replyRootId,\n
|
|
1
|
+
{"version":3,"file":"optimistically_update_message.js","names":["chatQueryClient","getMessagesQueryKey","updateOrCreateRecordInPagesData","optimisticallyUpdateMessage","conversationId","message","text","replyRootId","queryKey","conversation_id","reply_root_id","optimisticMessage","setQueryData","data","record","processRecord","next","prev","pending"],"sources":["../../../src/utils/cache/optimistically_update_message.ts"],"sourcesContent":["import { InfiniteData } from '@tanstack/react-query'\nimport { chatQueryClient } from '../../contexts/api_provider'\nimport { ApiCollection, MessageResource } from '../../types'\nimport { getMessagesQueryKey } from '../../utils/request/get_messages'\nimport { updateOrCreateRecordInPagesData } from './page_mutations'\n\nexport function optimisticallyUpdateMessage({\n conversationId,\n message,\n text,\n replyRootId,\n}: {\n conversationId: number\n message: MessageResource\n text: string\n replyRootId?: string | null\n}) {\n type QueryData = InfiniteData<ApiCollection<MessageResource>>\n\n const queryKey = getMessagesQueryKey({\n conversation_id: conversationId,\n reply_root_id: replyRootId,\n })\n\n let optimisticMessage = message\n\n chatQueryClient.setQueryData<QueryData>(queryKey, data =>\n updateOrCreateRecordInPagesData({\n data,\n record: message,\n processRecord: (next, prev) => {\n optimisticMessage = {\n ...(prev || next),\n text,\n pending: true,\n }\n return optimisticMessage\n },\n })\n )\n\n return optimisticMessage\n}\n"],"mappings":"AACA,SAASA,eAAe,QAAQ,6BAA6B;AAE7D,SAASC,mBAAmB,QAAQ,kCAAkC;AACtE,SAASC,+BAA+B,QAAQ,kBAAkB;AAElE,OAAO,SAASC,2BAA2BA,CAAC;EAC1CC,cAAc;EACdC,OAAO;EACPC,IAAI;EACJC;AAMF,CAAC,EAAE;EAGD,MAAMC,QAAQ,GAAGP,mBAAmB,CAAC;IACnCQ,eAAe,EAAEL,cAAc;IAC/BM,aAAa,EAAEH;EACjB,CAAC,CAAC;EAEF,IAAII,iBAAiB,GAAGN,OAAO;EAE/BL,eAAe,CAACY,YAAY,CAAYJ,QAAQ,EAAEK,IAAI,IACpDX,+BAA+B,CAAC;IAC9BW,IAAI;IACJC,MAAM,EAAET,OAAO;IACfU,aAAa,EAAEA,CAACC,IAAI,EAAEC,IAAI,KAAK;MAC7BN,iBAAiB,GAAG;QAClB,IAAIM,IAAI,IAAID,IAAI,CAAC;QACjBV,IAAI;QACJY,OAAO,EAAE;MACX,CAAC;MACD,OAAOP,iBAAiB;IAC1B;EACF,CAAC,CACH,CAAC;EAED,OAAOA,iBAAiB;AAC1B","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/utils/client/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/utils/client/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","names":[],"sources":["../../../src/utils/client/types.ts"],"sourcesContent":["export interface Accumulator {\n data: Record<string, unknown>[]\n included: Record<string, unknown>[]\n meta: Record<string, unknown>\n links: Record<string, unknown>\n}\n\nexport interface WalkRequest extends GetRequest {\n acc?: Accumulator\n}\n\nexport interface GenericRequest {\n headers?: Record<string, string>\n url: string\n}\n\nexport interface GetRequest extends GenericRequest {\n data: {\n filter?: string\n fields: Record<string, string[]>\n where?: Record<string, string | number | (string | number)[]>\n include?: string[]\n order?: string\n perPage?: number\n offset?: number\n walk?: boolean\n } & Record<string, unknown>\n}\n\nexport interface Relationship {\n data: {\n type: string\n id: string\n }\n}\n\nexport type Relationships = Record<string, Relationship | Relationship[]>\nexport interface PostRequest extends GenericRequest {\n data?: {\n fields?: Record<string, string> // value should be comma separated string\n include?: string[]\n data?: {\n type: string\n attributes: Record<string, unknown>\n relationships?: Relationships\n }\n }\n}\n\nexport type PatchRequest = PostRequest\n\nexport interface DeleteRequest extends GenericRequest {}\n\nexport interface ApiClient<T = unknown> {\n get(_request: GetRequest): Promise<T>\n post(_request: PostRequest): Promise<T>\n patch(_request: PatchRequest): Promise<T>\n delete(_request: DeleteRequest): Promise<T>\n}\n\nexport type RequestData = {\n fields: Record<string, string[] | string>\n where: Record<string, string | number | (string | number)[]>\n include: string[]\n data: Record<string, unknown>\n perPage: number\n offset: number\n
|
|
1
|
+
{"version":3,"file":"types.js","names":[],"sources":["../../../src/utils/client/types.ts"],"sourcesContent":["export interface Accumulator {\n data: Record<string, unknown>[]\n included: Record<string, unknown>[]\n meta: Record<string, unknown>\n links: Record<string, unknown>\n}\n\nexport interface WalkRequest extends GetRequest {\n acc?: Accumulator\n}\n\nexport interface GenericRequest {\n headers?: Record<string, string>\n url: string\n}\n\nexport interface GetRequest extends GenericRequest {\n data: {\n filter?: string\n fields: Record<string, string[]>\n where?: Record<string, string | number | (string | number)[]>\n include?: string[]\n order?: string\n perPage?: number\n offset?: number\n walk?: boolean\n } & Record<string, unknown>\n}\n\nexport interface Relationship {\n data: {\n type: string\n id: string\n }\n}\n\nexport type Relationships = Record<string, Relationship | Relationship[]>\nexport interface PostRequest extends GenericRequest {\n data?: {\n fields?: Record<string, string> // value should be comma separated string\n include?: string[]\n data?: {\n type: string\n attributes: Record<string, unknown>\n relationships?: Relationships\n }\n }\n}\n\nexport type PatchRequest = PostRequest\n\nexport interface DeleteRequest extends GenericRequest {}\n\nexport interface ApiClient<T = unknown> {\n get(_request: GetRequest): Promise<T>\n post(_request: PostRequest): Promise<T>\n patch(_request: PatchRequest): Promise<T>\n delete(_request: DeleteRequest): Promise<T>\n}\n\nexport type RequestData = {\n fields: Record<string, string[] | string>\n where: Record<string, string | number | (string | number)[]>\n include: string[]\n data: Record<string, unknown>\n perPage: number\n offset: number\n}\n"],"mappings":"","ignoreList":[]}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The actual `ulid` library depends on a secure random number generator, which looks like it
|
|
3
|
+
* may require a native dependency to polyfill in React Native.
|
|
4
|
+
* Since this is only used as a local temporary ID, I think we can get away with a simpler
|
|
5
|
+
* implementation that doesn't require any native dependencies.
|
|
6
|
+
*/
|
|
1
7
|
export declare function generatePlaceholderUlid({ offsetMs }?: {
|
|
2
8
|
offsetMs?: number;
|
|
3
9
|
}): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate_placeholder_ulid.d.ts","sourceRoot":"","sources":["../../src/utils/generate_placeholder_ulid.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"generate_placeholder_ulid.d.ts","sourceRoot":"","sources":["../../src/utils/generate_placeholder_ulid.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAaH,wBAAgB,uBAAuB,CAAC,EAAE,QAAY,EAAE,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,CAa5F"}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { ULID_CHARS } from './ulid';
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* The actual `ulid` library depends on a secure random number generator, which looks like it
|
|
5
3
|
* may require a native dependency to polyfill in React Native.
|
|
@@ -7,6 +5,8 @@ import { ULID_CHARS } from './ulid';
|
|
|
7
5
|
* implementation that doesn't require any native dependencies.
|
|
8
6
|
*/
|
|
9
7
|
|
|
8
|
+
const ULID_CHARS = '0123456789ABCDEFGHJKMNPQRSTVWXYZ'; // Crockford's Base32
|
|
9
|
+
|
|
10
10
|
function encodeBase32(value, length) {
|
|
11
11
|
let result = '';
|
|
12
12
|
for (let i = 0; i < length; i++) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate_placeholder_ulid.js","names":["ULID_CHARS","encodeBase32","value","length","result","i","Math","floor","generatePlaceholderUlid","offsetMs","timestamp","Date","now","timeComponent","randomComponent","random"],"sources":["../../src/utils/generate_placeholder_ulid.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"generate_placeholder_ulid.js","names":["ULID_CHARS","encodeBase32","value","length","result","i","Math","floor","generatePlaceholderUlid","offsetMs","timestamp","Date","now","timeComponent","randomComponent","random"],"sources":["../../src/utils/generate_placeholder_ulid.ts"],"sourcesContent":["/**\n * The actual `ulid` library depends on a secure random number generator, which looks like it\n * may require a native dependency to polyfill in React Native.\n * Since this is only used as a local temporary ID, I think we can get away with a simpler\n * implementation that doesn't require any native dependencies.\n */\n\nconst ULID_CHARS = '0123456789ABCDEFGHJKMNPQRSTVWXYZ' // Crockford's Base32\n\nfunction encodeBase32(value: number, length: number) {\n let result = ''\n for (let i = 0; i < length; i++) {\n result = ULID_CHARS[value % 32] + result\n value = Math.floor(value / 32)\n }\n return result\n}\n\nexport function generatePlaceholderUlid({ offsetMs = 0 }: { offsetMs?: number } = {}): string {\n const timestamp = Date.now() + offsetMs // Milliseconds since epoch\n // 48 bits for timestamp (6 Base32 characters)\n const timeComponent = encodeBase32(timestamp, 10) // 48 bits = 6 bytes = 10 Base32 characters (approx, needs more precise bit shifting)\n\n // 80 bits for randomness (16 Base32 characters)\n let randomComponent = ''\n for (let i = 0; i < 16; i++) {\n // Generate 16 random Base32 chars\n randomComponent += ULID_CHARS[Math.floor(Math.random() * 32)]\n }\n\n return timeComponent + randomComponent\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAMA,UAAU,GAAG,kCAAkC,EAAC;;AAEtD,SAASC,YAAYA,CAACC,KAAa,EAAEC,MAAc,EAAE;EACnD,IAAIC,MAAM,GAAG,EAAE;EACf,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGF,MAAM,EAAEE,CAAC,EAAE,EAAE;IAC/BD,MAAM,GAAGJ,UAAU,CAACE,KAAK,GAAG,EAAE,CAAC,GAAGE,MAAM;IACxCF,KAAK,GAAGI,IAAI,CAACC,KAAK,CAACL,KAAK,GAAG,EAAE,CAAC;EAChC;EACA,OAAOE,MAAM;AACf;AAEA,OAAO,SAASI,uBAAuBA,CAAC;EAAEC,QAAQ,GAAG;AAAyB,CAAC,GAAG,CAAC,CAAC,EAAU;EAC5F,MAAMC,SAAS,GAAGC,IAAI,CAACC,GAAG,CAAC,CAAC,GAAGH,QAAQ,EAAC;EACxC;EACA,MAAMI,aAAa,GAAGZ,YAAY,CAACS,SAAS,EAAE,EAAE,CAAC,EAAC;;EAElD;EACA,IAAII,eAAe,GAAG,EAAE;EACxB,KAAK,IAAIT,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAG,EAAE,EAAEA,CAAC,EAAE,EAAE;IAC3B;IACAS,eAAe,IAAId,UAAU,CAACM,IAAI,CAACC,KAAK,CAACD,IAAI,CAACS,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;EAC/D;EAEA,OAAOF,aAAa,GAAGC,eAAe;AACxC","ignoreList":[]}
|
|
@@ -1,23 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
export declare const getMessagesRequestArgs: ({ conversation_id, reply_root_id, }: {
|
|
2
2
|
conversation_id: number;
|
|
3
3
|
reply_root_id?: string | null;
|
|
4
|
-
|
|
5
|
-
};
|
|
6
|
-
export declare const getMessagesRequestArgs: ({ conversation_id, reply_root_id, anchor, }: MessagesRequestOptions) => {
|
|
4
|
+
}) => {
|
|
7
5
|
url: string;
|
|
8
6
|
data: {
|
|
9
|
-
where: {
|
|
10
|
-
id_around: string;
|
|
11
|
-
};
|
|
12
|
-
perPage: number;
|
|
13
|
-
fields: {
|
|
14
|
-
Message: string[];
|
|
15
|
-
Person: string[];
|
|
16
|
-
ReactionCount: string[];
|
|
17
|
-
};
|
|
18
|
-
include: string[];
|
|
19
|
-
} | {
|
|
20
|
-
where?: undefined;
|
|
21
7
|
perPage: number;
|
|
22
8
|
fields: {
|
|
23
9
|
Message: string[];
|
|
@@ -28,6 +14,8 @@ export declare const getMessagesRequestArgs: ({ conversation_id, reply_root_id,
|
|
|
28
14
|
};
|
|
29
15
|
reply_root_id: string | null;
|
|
30
16
|
};
|
|
31
|
-
export declare const getMessagesQueryKey: (
|
|
32
|
-
|
|
17
|
+
export declare const getMessagesQueryKey: ({ conversation_id, reply_root_id, }: {
|
|
18
|
+
conversation_id: number;
|
|
19
|
+
reply_root_id?: string | null;
|
|
20
|
+
}) => import("../..").RequestQueryKey;
|
|
33
21
|
//# sourceMappingURL=get_messages.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get_messages.d.ts","sourceRoot":"","sources":["../../../src/utils/request/get_messages.ts"],"names":[],"mappings":"AAGA,
|
|
1
|
+
{"version":3,"file":"get_messages.d.ts","sourceRoot":"","sources":["../../../src/utils/request/get_messages.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,sBAAsB,GAAI,qCAGpC;IACD,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC9B;;;;;;;;;;;;CAeA,CAAA;AAED,eAAO,MAAM,mBAAmB,GAAI,qCAGjC;IACD,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC9B,oCAGA,CAAA"}
|
|
@@ -2,26 +2,28 @@ import { getRequestQueryKey } from '../../hooks/use_suspense_api';
|
|
|
2
2
|
import { getMessageFields, getMessagesInclude } from './messages_data_options';
|
|
3
3
|
export const getMessagesRequestArgs = ({
|
|
4
4
|
conversation_id,
|
|
5
|
-
reply_root_id
|
|
6
|
-
anchor
|
|
5
|
+
reply_root_id
|
|
7
6
|
}) => {
|
|
8
7
|
const normalizedReplyRootId = reply_root_id ?? null;
|
|
9
8
|
const url = normalizedReplyRootId ? `/me/conversations/${conversation_id}/messages/${normalizedReplyRootId}/replies` : `/me/conversations/${conversation_id}/messages`;
|
|
10
|
-
const anchored = anchor ? {
|
|
11
|
-
where: {
|
|
12
|
-
id_around: anchor
|
|
13
|
-
}
|
|
14
|
-
} : {};
|
|
15
9
|
return {
|
|
16
10
|
url,
|
|
17
11
|
data: {
|
|
18
12
|
perPage: 25,
|
|
19
13
|
fields: getMessageFields,
|
|
20
|
-
include: getMessagesInclude
|
|
21
|
-
...anchored
|
|
14
|
+
include: getMessagesInclude
|
|
22
15
|
},
|
|
23
16
|
reply_root_id: normalizedReplyRootId
|
|
24
17
|
};
|
|
25
18
|
};
|
|
26
|
-
export const getMessagesQueryKey =
|
|
19
|
+
export const getMessagesQueryKey = ({
|
|
20
|
+
conversation_id,
|
|
21
|
+
reply_root_id
|
|
22
|
+
}) => {
|
|
23
|
+
const requestArgs = getMessagesRequestArgs({
|
|
24
|
+
conversation_id,
|
|
25
|
+
reply_root_id
|
|
26
|
+
});
|
|
27
|
+
return getRequestQueryKey(requestArgs);
|
|
28
|
+
};
|
|
27
29
|
//# sourceMappingURL=get_messages.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get_messages.js","names":["getRequestQueryKey","getMessageFields","getMessagesInclude","getMessagesRequestArgs","conversation_id","reply_root_id","
|
|
1
|
+
{"version":3,"file":"get_messages.js","names":["getRequestQueryKey","getMessageFields","getMessagesInclude","getMessagesRequestArgs","conversation_id","reply_root_id","normalizedReplyRootId","url","data","perPage","fields","include","getMessagesQueryKey","requestArgs"],"sources":["../../../src/utils/request/get_messages.ts"],"sourcesContent":["import { getRequestQueryKey } from '../../hooks/use_suspense_api'\nimport { getMessageFields, getMessagesInclude } from './messages_data_options'\n\nexport const getMessagesRequestArgs = ({\n conversation_id,\n reply_root_id,\n}: {\n conversation_id: number\n reply_root_id?: string | null\n}) => {\n const normalizedReplyRootId = reply_root_id ?? null\n const url = normalizedReplyRootId\n ? `/me/conversations/${conversation_id}/messages/${normalizedReplyRootId}/replies`\n : `/me/conversations/${conversation_id}/messages`\n\n return {\n url,\n data: {\n perPage: 25,\n fields: getMessageFields,\n include: getMessagesInclude,\n },\n reply_root_id: normalizedReplyRootId,\n }\n}\n\nexport const getMessagesQueryKey = ({\n conversation_id,\n reply_root_id,\n}: {\n conversation_id: number\n reply_root_id?: string | null\n}) => {\n const requestArgs = getMessagesRequestArgs({ conversation_id, reply_root_id })\n return getRequestQueryKey(requestArgs)\n}\n"],"mappings":"AAAA,SAASA,kBAAkB,QAAQ,8BAA8B;AACjE,SAASC,gBAAgB,EAAEC,kBAAkB,QAAQ,yBAAyB;AAE9E,OAAO,MAAMC,sBAAsB,GAAGA,CAAC;EACrCC,eAAe;EACfC;AAIF,CAAC,KAAK;EACJ,MAAMC,qBAAqB,GAAGD,aAAa,IAAI,IAAI;EACnD,MAAME,GAAG,GAAGD,qBAAqB,GAC7B,qBAAqBF,eAAe,aAAaE,qBAAqB,UAAU,GAChF,qBAAqBF,eAAe,WAAW;EAEnD,OAAO;IACLG,GAAG;IACHC,IAAI,EAAE;MACJC,OAAO,EAAE,EAAE;MACXC,MAAM,EAAET,gBAAgB;MACxBU,OAAO,EAAET;IACX,CAAC;IACDG,aAAa,EAAEC;EACjB,CAAC;AACH,CAAC;AAED,OAAO,MAAMM,mBAAmB,GAAGA,CAAC;EAClCR,eAAe;EACfC;AAIF,CAAC,KAAK;EACJ,MAAMQ,WAAW,GAAGV,sBAAsB,CAAC;IAAEC,eAAe;IAAEC;EAAc,CAAC,CAAC;EAC9E,OAAOL,kBAAkB,CAACa,WAAW,CAAC;AACxC,CAAC","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@planningcenter/chat-react-native",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.3.0-rc.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@fortawesome/fontawesome-svg-core": "^7.2.0",
|
|
35
35
|
"@fortawesome/react-native-fontawesome": "^0.3.2",
|
|
36
|
-
"@planningcenter/emoji-keyboard": "4.
|
|
36
|
+
"@planningcenter/emoji-keyboard": "4.0.0",
|
|
37
37
|
"lodash-inflection": "^1.5.0"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
@@ -84,5 +84,5 @@
|
|
|
84
84
|
"sf-symbols-typescript": "^2.2.0",
|
|
85
85
|
"typescript": "~6.0.3"
|
|
86
86
|
},
|
|
87
|
-
"gitHead": "
|
|
87
|
+
"gitHead": "2d5f97948a3f69f26435fa88e8cbfdd264270022"
|
|
88
88
|
}
|
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getNewerPageParam,
|
|
3
|
-
getNextPageParamFromMeta,
|
|
4
|
-
mergePageWhere,
|
|
5
|
-
} from '../../hooks/paginator_meta'
|
|
6
|
-
import { NextPageCursor } from '../../types/api_primitives'
|
|
7
|
-
import { RequestData } from '../../utils/client'
|
|
1
|
+
import { getNextPageParamFromMeta } from '../../hooks/paginator_meta'
|
|
8
2
|
|
|
9
3
|
describe('getNextPageParamFromMeta', () => {
|
|
10
|
-
it.each
|
|
4
|
+
it.each([
|
|
11
5
|
[undefined, undefined],
|
|
12
6
|
[{}, undefined],
|
|
13
7
|
[{ idLt: '01ABC' }, { where: { id_lt: '01ABC' } }],
|
|
@@ -15,72 +9,7 @@ describe('getNextPageParamFromMeta', () => {
|
|
|
15
9
|
[{ idGt: '01ABC' }, { where: { id_gt: '01ABC' } }],
|
|
16
10
|
[{ idGte: '01ABC' }, { where: { id_gte: '01ABC' } }],
|
|
17
11
|
[{ offset: '40' }, { offset: 40 }],
|
|
18
|
-
[
|
|
19
|
-
{ idLt: '01ABC', order: 'desc' },
|
|
20
|
-
{ where: { id_lt: '01ABC' }, order: 'desc' },
|
|
21
|
-
],
|
|
22
|
-
[
|
|
23
|
-
{ idGt: '01ABC', order: 'asc' },
|
|
24
|
-
{ where: { id_gt: '01ABC' }, order: 'asc' },
|
|
25
|
-
],
|
|
26
12
|
])('maps %p to %p', (input, expected) => {
|
|
27
13
|
expect(getNextPageParamFromMeta(input)).toEqual(expected)
|
|
28
14
|
})
|
|
29
15
|
})
|
|
30
|
-
|
|
31
|
-
describe('getNewerPageParam', () => {
|
|
32
|
-
const page = (meta: { next?: NextPageCursor; prev?: NextPageCursor }) => ({
|
|
33
|
-
data: [],
|
|
34
|
-
links: {},
|
|
35
|
-
meta: { count: 0, totalCount: 0, ...meta },
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
it('follows meta.prev on the anchored page', () => {
|
|
39
|
-
const anchored = page({
|
|
40
|
-
next: { idLt: '01A', order: 'desc' },
|
|
41
|
-
prev: { idGt: '01E', order: 'asc' },
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
expect(getNewerPageParam(anchored, {})).toEqual({ where: { id_gt: '01E' }, order: 'asc' })
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
it('stops when the anchored page has no newer side', () => {
|
|
48
|
-
expect(getNewerPageParam(page({ next: { idLt: '01A', order: 'desc' } }), {})).toBeUndefined()
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
it('follows meta.next on an ascending page', () => {
|
|
52
|
-
const newer = page({ next: { idGt: '01H', order: 'asc' } })
|
|
53
|
-
|
|
54
|
-
expect(getNewerPageParam(newer, { order: 'asc' })).toEqual({
|
|
55
|
-
where: { id_gt: '01H' },
|
|
56
|
-
order: 'asc',
|
|
57
|
-
})
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
it('stops once an ascending page has no meta.next', () => {
|
|
61
|
-
expect(getNewerPageParam(page({}), { order: 'asc' })).toBeUndefined()
|
|
62
|
-
})
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
describe('mergePageWhere', () => {
|
|
66
|
-
it('lets a page cursor replace the request bound instead of stacking bounds', () => {
|
|
67
|
-
expect(mergePageWhere({ id_around: '01ANCHOR' }, { id_gt: '01NEWER' })).toEqual({
|
|
68
|
-
id_gt: '01NEWER',
|
|
69
|
-
})
|
|
70
|
-
expect(mergePageWhere({ id_around: '01ANCHOR' }, { id_lt: '01OLDER' })).toEqual({
|
|
71
|
-
id_lt: '01OLDER',
|
|
72
|
-
})
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
it('keeps non-cursor filters alongside the cursor', () => {
|
|
76
|
-
expect(mergePageWhere({ source_type: 'Group' }, { id_lt: '01OLDER' })).toEqual({
|
|
77
|
-
source_type: 'Group',
|
|
78
|
-
id_lt: '01OLDER',
|
|
79
|
-
})
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
it('leaves the request where alone when the page has no cursor', () => {
|
|
83
|
-
expect(mergePageWhere({ id_around: '01ANCHOR' }, {})).toEqual({ id_around: '01ANCHOR' })
|
|
84
|
-
expect(mergePageWhere(undefined, undefined)).toEqual({})
|
|
85
|
-
})
|
|
86
|
-
})
|
|
@@ -104,7 +104,6 @@ let queryClient: QueryClient
|
|
|
104
104
|
|
|
105
105
|
// A top-level rerender would rebuild the wrapper context and redraw every row.
|
|
106
106
|
let setHarnessConversation: (next: ConversationResource) => void = () => {}
|
|
107
|
-
let harnessAnchorMessageId: string | null = null
|
|
108
107
|
|
|
109
108
|
function Harness() {
|
|
110
109
|
const [current, setCurrent] = React.useState(conversation)
|
|
@@ -118,7 +117,6 @@ function Harness() {
|
|
|
118
117
|
conversation={current}
|
|
119
118
|
conversationId={CONVERSATION_ID}
|
|
120
119
|
messages={loaded}
|
|
121
|
-
anchorMessageId={harnessAnchorMessageId}
|
|
122
120
|
hasNextPage
|
|
123
121
|
onEndReached={() => {}}
|
|
124
122
|
/>
|
|
@@ -178,49 +176,9 @@ beforeEach(() => {
|
|
|
178
176
|
afterEach(() => {
|
|
179
177
|
queryClient.clear()
|
|
180
178
|
jest.clearAllMocks()
|
|
181
|
-
harnessAnchorMessageId = null
|
|
182
179
|
})
|
|
183
180
|
|
|
184
181
|
describe('MessageList', () => {
|
|
185
|
-
it('pins the anchor row to the bottom edge as content lays out, until the user drags', () => {
|
|
186
|
-
const scrollToIndex = jest.spyOn(FlatList.prototype, 'scrollToIndex').mockImplementation()
|
|
187
|
-
harnessAnchorMessageId = messages[3].id
|
|
188
|
-
renderList()
|
|
189
|
-
const list = screen.UNSAFE_getByType(FlatList)
|
|
190
|
-
const anchorIndex = list.props.data.findIndex(
|
|
191
|
-
(item: { id: string }) => item.id === messages[3].id
|
|
192
|
-
)
|
|
193
|
-
|
|
194
|
-
act(() => list.props.onLayout({ nativeEvent: { layout: { height: 600 } } }))
|
|
195
|
-
act(() => list.props.onContentSizeChange(0, 400))
|
|
196
|
-
expect(scrollToIndex).not.toHaveBeenCalled()
|
|
197
|
-
|
|
198
|
-
act(() => list.props.onContentSizeChange(0, 1000))
|
|
199
|
-
act(() => list.props.onContentSizeChange(0, 2000))
|
|
200
|
-
expect(anchorIndex).toBeGreaterThan(0)
|
|
201
|
-
expect(scrollToIndex).toHaveBeenCalledTimes(2)
|
|
202
|
-
expect(scrollToIndex).toHaveBeenLastCalledWith({
|
|
203
|
-
index: anchorIndex,
|
|
204
|
-
viewPosition: 0,
|
|
205
|
-
animated: false,
|
|
206
|
-
})
|
|
207
|
-
|
|
208
|
-
act(() => list.props.onScrollBeginDrag({ nativeEvent: {} }))
|
|
209
|
-
act(() => list.props.onContentSizeChange(0, 3000))
|
|
210
|
-
expect(scrollToIndex).toHaveBeenCalledTimes(2)
|
|
211
|
-
})
|
|
212
|
-
|
|
213
|
-
it('leaves the offset alone when there is no anchor', () => {
|
|
214
|
-
const scrollToIndex = jest.spyOn(FlatList.prototype, 'scrollToIndex').mockImplementation()
|
|
215
|
-
renderList()
|
|
216
|
-
const list = screen.UNSAFE_getByType(FlatList)
|
|
217
|
-
|
|
218
|
-
act(() => list.props.onLayout({ nativeEvent: { layout: { height: 600 } } }))
|
|
219
|
-
act(() => list.props.onContentSizeChange(0, 1000))
|
|
220
|
-
|
|
221
|
-
expect(scrollToIndex).not.toHaveBeenCalled()
|
|
222
|
-
})
|
|
223
|
-
|
|
224
182
|
it('redraws only the reacted row when a reaction arrives', () => {
|
|
225
183
|
renderList()
|
|
226
184
|
const target = messages[3]
|
|
@@ -71,7 +71,6 @@ interface MessagesFormRootProps extends ViewProps {
|
|
|
71
71
|
replyRootId?: string | null
|
|
72
72
|
replyRootAuthorFirstName?: string | null
|
|
73
73
|
onFlaggedInMessageForm?: (id: string) => void
|
|
74
|
-
onBeforeSubmit?: () => void
|
|
75
74
|
}
|
|
76
75
|
|
|
77
76
|
const MessageFormContext = React.createContext<{
|
|
@@ -114,7 +113,6 @@ function MessageFormRoot({
|
|
|
114
113
|
replyRootId,
|
|
115
114
|
replyRootAuthorFirstName,
|
|
116
115
|
onFlaggedInMessageForm,
|
|
117
|
-
onBeforeSubmit,
|
|
118
116
|
}: MessagesFormRootProps) {
|
|
119
117
|
const { giphyApiKey } = useContext(ChatContext)
|
|
120
118
|
const canGiphy = !!giphyApiKey && !currentlyEditingMessage
|
|
@@ -250,7 +248,6 @@ function MessageFormRoot({
|
|
|
250
248
|
mutateAsync({ text: messageText })
|
|
251
249
|
reset()
|
|
252
250
|
} else {
|
|
253
|
-
onBeforeSubmit?.()
|
|
254
251
|
mutateAsync({ text: messageText, attachments: attachmentsForSubmit })
|
|
255
252
|
reset()
|
|
256
253
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { date as formatDate } from '@planningcenter/datetime-fmt'
|
|
2
|
-
import {
|
|
3
|
-
import React, { RefObject, useRef } from 'react'
|
|
2
|
+
import React, { RefObject } from 'react'
|
|
4
3
|
import { FlatList, FlatListProps, StyleSheet, View } from 'react-native'
|
|
5
4
|
import { useTheme } from '../../hooks'
|
|
6
5
|
import { ConversationResource } from '../../types/resources/conversation'
|
|
@@ -17,15 +16,7 @@ import { SystemMessage } from './system_message'
|
|
|
17
16
|
|
|
18
17
|
type ScrollHandlers = Pick<
|
|
19
18
|
FlatListProps<EnrichedMessage>,
|
|
20
|
-
| '
|
|
21
|
-
| 'onLayout'
|
|
22
|
-
| 'onContentSizeChange'
|
|
23
|
-
| 'onScrollEndDrag'
|
|
24
|
-
| 'onMomentumScrollEnd'
|
|
25
|
-
| 'onScrollBeginDrag'
|
|
26
|
-
| 'onStartReached'
|
|
27
|
-
| 'onStartReachedThreshold'
|
|
28
|
-
| 'maintainVisibleContentPosition'
|
|
19
|
+
'onScroll' | 'onLayout' | 'onContentSizeChange' | 'onScrollEndDrag' | 'onMomentumScrollEnd'
|
|
29
20
|
>
|
|
30
21
|
|
|
31
22
|
interface MessageListProps extends ScrollHandlers {
|
|
@@ -34,7 +25,6 @@ interface MessageListProps extends ScrollHandlers {
|
|
|
34
25
|
conversationId: number
|
|
35
26
|
messages: MessageResource[]
|
|
36
27
|
replyRootId?: string | null
|
|
37
|
-
anchorMessageId?: string | null
|
|
38
28
|
hasNextPage: boolean
|
|
39
29
|
onEndReached: () => void
|
|
40
30
|
}
|
|
@@ -48,7 +38,6 @@ export function MessageList({
|
|
|
48
38
|
conversationId,
|
|
49
39
|
messages,
|
|
50
40
|
replyRootId,
|
|
51
|
-
anchorMessageId,
|
|
52
41
|
hasNextPage,
|
|
53
42
|
onEndReached,
|
|
54
43
|
onScroll,
|
|
@@ -56,10 +45,6 @@ export function MessageList({
|
|
|
56
45
|
onContentSizeChange,
|
|
57
46
|
onScrollEndDrag,
|
|
58
47
|
onMomentumScrollEnd,
|
|
59
|
-
onScrollBeginDrag,
|
|
60
|
-
onStartReached,
|
|
61
|
-
onStartReachedThreshold,
|
|
62
|
-
maintainVisibleContentPosition,
|
|
63
48
|
}: MessageListProps) {
|
|
64
49
|
const styles = useStyles()
|
|
65
50
|
const inReplyScreen = !!replyRootId
|
|
@@ -67,40 +52,6 @@ export function MessageList({
|
|
|
67
52
|
conversation.memberAbility?.canDeleteNonAuthoredMessages ?? false
|
|
68
53
|
const latestRead = conversation.latestReadMessageSortKey
|
|
69
54
|
const messagesWithSeparators = groupMessages({ ms: messages, inReplyScreen })
|
|
70
|
-
const anchorIndex = anchorMessageId
|
|
71
|
-
? messagesWithSeparators.findIndex(item => item.id === anchorMessageId)
|
|
72
|
-
: -1
|
|
73
|
-
const layoutHeight = useRef(0)
|
|
74
|
-
const contentHeight = useRef(0)
|
|
75
|
-
const userHasScrolled = useRef(false)
|
|
76
|
-
|
|
77
|
-
const pinAnchorToBottomEdge = () => {
|
|
78
|
-
if (anchorIndex < 0 || userHasScrolled.current) return
|
|
79
|
-
const scrollable = layoutHeight.current > 0 && contentHeight.current > layoutHeight.current
|
|
80
|
-
if (!scrollable) return
|
|
81
|
-
|
|
82
|
-
listRef.current?.scrollToIndex({ index: anchorIndex, viewPosition: 0, animated: false })
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const handleLayout: FlatListProps<EnrichedMessage>['onLayout'] = event => {
|
|
86
|
-
onLayout?.(event)
|
|
87
|
-
layoutHeight.current = event.nativeEvent.layout.height
|
|
88
|
-
pinAnchorToBottomEdge()
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const handleContentSizeChange: FlatListProps<EnrichedMessage>['onContentSizeChange'] = (
|
|
92
|
-
width,
|
|
93
|
-
height
|
|
94
|
-
) => {
|
|
95
|
-
onContentSizeChange?.(width, height)
|
|
96
|
-
contentHeight.current = height
|
|
97
|
-
pinAnchorToBottomEdge()
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const handleScrollBeginDrag: FlatListProps<EnrichedMessage>['onScrollBeginDrag'] = event => {
|
|
101
|
-
userHasScrolled.current = true
|
|
102
|
-
onScrollBeginDrag?.(event)
|
|
103
|
-
}
|
|
104
55
|
|
|
105
56
|
return (
|
|
106
57
|
<FlatList
|
|
@@ -110,9 +61,8 @@ export function MessageList({
|
|
|
110
61
|
data={messagesWithSeparators}
|
|
111
62
|
keyExtractor={item => item.id}
|
|
112
63
|
onScroll={onScroll}
|
|
113
|
-
onLayout={
|
|
114
|
-
onContentSizeChange={
|
|
115
|
-
onScrollToIndexFailed={noop}
|
|
64
|
+
onLayout={onLayout}
|
|
65
|
+
onContentSizeChange={onContentSizeChange}
|
|
116
66
|
onScrollEndDrag={onScrollEndDrag}
|
|
117
67
|
onMomentumScrollEnd={onMomentumScrollEnd}
|
|
118
68
|
scrollEventThrottle={10}
|
|
@@ -152,10 +102,6 @@ export function MessageList({
|
|
|
152
102
|
)
|
|
153
103
|
}}
|
|
154
104
|
onEndReached={onEndReached}
|
|
155
|
-
onScrollBeginDrag={handleScrollBeginDrag}
|
|
156
|
-
onStartReached={onStartReached}
|
|
157
|
-
onStartReachedThreshold={onStartReachedThreshold}
|
|
158
|
-
maintainVisibleContentPosition={maintainVisibleContentPosition}
|
|
159
105
|
ListHeaderComponent={<View style={styles.listHeader} />}
|
|
160
106
|
/>
|
|
161
107
|
)
|
|
@@ -13,7 +13,6 @@ import { appGrantsRequestArgs } from '../hooks/use_chat_permissions'
|
|
|
13
13
|
import { featuresQueryOptions } from '../hooks/use_features'
|
|
14
14
|
import { getRequestQueryKey, RequestQueryKey } from '../hooks/use_suspense_api'
|
|
15
15
|
import { emitAuthRefresh } from '../utils/auth_events'
|
|
16
|
-
import { invalidateRefetchableQueries } from '../utils/cache/invalidate_refetchable_queries'
|
|
17
16
|
import { ResponseError } from '../utils/response_error'
|
|
18
17
|
import { ChatContext, ChatContextValue } from './chat_context'
|
|
19
18
|
|
|
@@ -60,7 +59,7 @@ export function ApiProvider({ children }: ViewProps) {
|
|
|
60
59
|
emitAuthRefresh()
|
|
61
60
|
|
|
62
61
|
if (chatQueryClient.isFetching()) {
|
|
63
|
-
|
|
62
|
+
chatQueryClient.invalidateQueries()
|
|
64
63
|
return
|
|
65
64
|
}
|
|
66
65
|
|
|
@@ -3,34 +3,29 @@ import React, { createContext, PropsWithChildren, useContext, useMemo } from 're
|
|
|
3
3
|
interface ConversationContextValue {
|
|
4
4
|
conversationId: number
|
|
5
5
|
currentPageReplyRootId: string | null
|
|
6
|
-
messagesQueryKey: unknown[] | null
|
|
7
6
|
}
|
|
8
7
|
|
|
9
8
|
interface ConversationContextProviderProps extends PropsWithChildren {
|
|
10
9
|
conversationId: number
|
|
11
10
|
currentPageReplyRootId: string | null
|
|
12
|
-
messagesQueryKey?: unknown[] | null
|
|
13
11
|
}
|
|
14
12
|
|
|
15
13
|
const ConversationContext = createContext<ConversationContextValue>({
|
|
16
14
|
conversationId: 0,
|
|
17
15
|
currentPageReplyRootId: null,
|
|
18
|
-
messagesQueryKey: null,
|
|
19
16
|
})
|
|
20
17
|
|
|
21
18
|
export const ConversationContextProvider = ({
|
|
22
19
|
children,
|
|
23
20
|
conversationId,
|
|
24
21
|
currentPageReplyRootId,
|
|
25
|
-
messagesQueryKey = null,
|
|
26
22
|
}: ConversationContextProviderProps) => {
|
|
27
23
|
const value = useMemo(
|
|
28
24
|
() => ({
|
|
29
25
|
conversationId,
|
|
30
26
|
currentPageReplyRootId,
|
|
31
|
-
messagesQueryKey,
|
|
32
27
|
}),
|
|
33
|
-
[conversationId, currentPageReplyRootId
|
|
28
|
+
[conversationId, currentPageReplyRootId]
|
|
34
29
|
)
|
|
35
30
|
|
|
36
31
|
return <ConversationContext.Provider value={value}>{children}</ConversationContext.Provider>
|
|
@@ -1,37 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NextPageCursor } from '../types/api_primitives'
|
|
2
2
|
import { RequestData } from '../utils/client'
|
|
3
3
|
|
|
4
4
|
export const getNextPageParamFromMeta = (
|
|
5
5
|
next: NextPageCursor = {}
|
|
6
6
|
): Partial<RequestData> | undefined => {
|
|
7
|
-
if (next.idLt) return
|
|
8
|
-
if (next.idGt) return
|
|
9
|
-
if (next.idLte) return
|
|
10
|
-
if (next.idGte) return
|
|
7
|
+
if (next.idLt) return { where: { id_lt: next.idLt } }
|
|
8
|
+
if (next.idGt) return { where: { id_gt: next.idGt } }
|
|
9
|
+
if (next.idLte) return { where: { id_lte: next.idLte } }
|
|
10
|
+
if (next.idGte) return { where: { id_gte: next.idGte } }
|
|
11
11
|
if (next.offset) return { offset: Number(next.offset) }
|
|
12
12
|
return undefined
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
const withOrder = (param: Partial<RequestData>, order: NextPageCursor['order']) =>
|
|
16
|
-
order ? { ...param, order } : param
|
|
17
|
-
|
|
18
|
-
const BOUND_KEYS = ['id_lt', 'id_lte', 'id_gt', 'id_gte', 'id_around']
|
|
19
|
-
|
|
20
|
-
export const mergePageWhere = (
|
|
21
|
-
argsWhere: RequestData['where'] = {},
|
|
22
|
-
pageWhere: RequestData['where'] = {}
|
|
23
|
-
): RequestData['where'] => {
|
|
24
|
-
const pageHasCursor = BOUND_KEYS.some(key => key in pageWhere)
|
|
25
|
-
const base = pageHasCursor
|
|
26
|
-
? Object.fromEntries(Object.entries(argsWhere).filter(([key]) => !BOUND_KEYS.includes(key)))
|
|
27
|
-
: argsWhere
|
|
28
|
-
return { ...base, ...pageWhere }
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export const getNewerPageParam = (
|
|
32
|
-
page: ApiCollection<ResourceObject>,
|
|
33
|
-
pageParam: Partial<RequestData> | undefined
|
|
34
|
-
): Partial<RequestData> | undefined => {
|
|
35
|
-
const isAscendingPage = pageParam?.order === 'asc'
|
|
36
|
-
return getNextPageParamFromMeta(isAscendingPage ? page.meta?.next : page.meta?.prev)
|
|
37
|
-
}
|
package/src/hooks/use_api.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { ChatContext } from '../contexts/chat_context'
|
|
|
4
4
|
import { ApiCollection, ApiResource, ResourceObject } from '../types'
|
|
5
5
|
import { GetRequest, RequestData } from '../utils/client'
|
|
6
6
|
import { ResponseError, throwResponseError } from '../utils/response_error'
|
|
7
|
-
import { getNextPageParamFromMeta
|
|
7
|
+
import { getNextPageParamFromMeta } from './paginator_meta'
|
|
8
8
|
import { App, useApiClient } from './use_api_client'
|
|
9
9
|
import { getRequestQueryKey, RequestQueryKey } from './use_suspense_api'
|
|
10
10
|
|
|
@@ -61,11 +61,12 @@ export const useApiPaginator = <T extends ResourceObject>(
|
|
|
61
61
|
>({
|
|
62
62
|
queryKey: getRequestQueryKey(args),
|
|
63
63
|
queryFn: ({ pageParam }) => {
|
|
64
|
-
const
|
|
64
|
+
const pageParmWhere = pageParam?.where || {}
|
|
65
|
+
const argsWhere = args.data.where || {}
|
|
66
|
+
const where = { ...argsWhere, ...pageParmWhere }
|
|
65
67
|
const app = args.app || 'chat'
|
|
66
68
|
const offset = pageParam?.offset || args.data.offset
|
|
67
|
-
const
|
|
68
|
-
const data = { ...args.data, where, offset, order }
|
|
69
|
+
const data = { ...args.data, where, offset }
|
|
69
70
|
|
|
70
71
|
return apiClient[app].get<ApiCollection<T>>({ url: args.url, data }).catch(throwResponseError)
|
|
71
72
|
},
|