@planningcenter/chat-react-native 4.0.1-qa-staging.1 → 4.0.1-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.d.ts +2 -3
- package/build/components/conversation/message.d.ts.map +1 -1
- package/build/components/conversation/message.js +22 -23
- package/build/components/conversation/message.js.map +1 -1
- package/build/components/conversation/message_read_receipts.d.ts +4 -2
- package/build/components/conversation/message_read_receipts.d.ts.map +1 -1
- package/build/components/conversation/message_read_receipts.js +3 -2
- package/build/components/conversation/message_read_receipts.js.map +1 -1
- package/build/components/conversation/reply_shadow_message.d.ts +1 -2
- package/build/components/conversation/reply_shadow_message.d.ts.map +1 -1
- package/build/components/conversation/reply_shadow_message.js +46 -47
- package/build/components/conversation/reply_shadow_message.js.map +1 -1
- package/build/components/primitive/form_sheet.d.ts +1 -2
- package/build/components/primitive/form_sheet.d.ts.map +1 -1
- package/build/components/primitive/form_sheet.js +53 -68
- package/build/components/primitive/form_sheet.js.map +1 -1
- package/build/hooks/use_conversation_messages.d.ts.map +1 -1
- package/build/hooks/use_conversation_messages.js +28 -40
- package/build/hooks/use_conversation_messages.js.map +1 -1
- package/build/hooks/use_conversation_messages_jolt_events.d.ts.map +1 -1
- package/build/hooks/use_conversation_messages_jolt_events.js +1 -6
- package/build/hooks/use_conversation_messages_jolt_events.js.map +1 -1
- package/build/hooks/use_message_create_or_update.d.ts +4 -99
- package/build/hooks/use_message_create_or_update.d.ts.map +1 -1
- package/build/hooks/use_message_create_or_update.js +6 -47
- package/build/hooks/use_message_create_or_update.js.map +1 -1
- package/build/screens/conversation_new/components/groups_form.js +80 -71
- package/build/screens/conversation_new/components/groups_form.js.map +1 -1
- package/build/screens/conversation_screen.d.ts.map +1 -1
- package/build/screens/conversation_screen.js +365 -184
- package/build/screens/conversation_screen.js.map +1 -1
- package/build/screens/conversation_select_type_screen.d.ts.map +1 -1
- package/build/screens/conversation_select_type_screen.js +98 -82
- package/build/screens/conversation_select_type_screen.js.map +1 -1
- package/build/types/resources/message.d.ts +0 -2
- package/build/types/resources/message.d.ts.map +1 -1
- package/build/types/resources/message.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 +7 -14
- package/build/utils/cache/messages_cache.js.map +1 -1
- package/build/utils/cache/optimistically_create_message.d.ts +1 -2
- package/build/utils/cache/optimistically_create_message.d.ts.map +1 -1
- package/build/utils/cache/optimistically_create_message.js +2 -4
- package/build/utils/cache/optimistically_create_message.js.map +1 -1
- package/build/utils/client/transform_response.d.ts.map +1 -1
- package/build/utils/client/transform_response.js +5 -9
- package/build/utils/client/transform_response.js.map +1 -1
- package/build/utils/group_messages.d.ts +0 -1
- package/build/utils/group_messages.d.ts.map +1 -1
- package/build/utils/group_messages.js +1 -10
- package/build/utils/group_messages.js.map +1 -1
- package/build/utils/jolt/transform_message_event_data_to_message_resource.d.ts.map +1 -1
- package/build/utils/jolt/transform_message_event_data_to_message_resource.js +0 -1
- package/build/utils/jolt/transform_message_event_data_to_message_resource.js.map +1 -1
- package/build/utils/request/messages_data_options.d.ts.map +1 -1
- package/build/utils/request/messages_data_options.js +2 -2
- package/build/utils/request/messages_data_options.js.map +1 -1
- package/package.json +3 -3
- package/src/components/conversation/message.tsx +18 -15
- package/src/components/conversation/message_read_receipts.tsx +5 -3
- package/src/components/conversation/reply_shadow_message.tsx +7 -9
- package/src/components/primitive/form_sheet.tsx +3 -10
- package/src/hooks/use_conversation_messages.ts +1 -5
- package/src/hooks/use_conversation_messages_jolt_events.ts +0 -7
- package/src/hooks/use_message_create_or_update.ts +16 -29
- package/src/screens/conversation_new/components/groups_form.tsx +7 -2
- package/src/screens/conversation_screen.tsx +104 -11
- package/src/screens/conversation_select_type_screen.tsx +9 -3
- package/src/types/resources/message.ts +0 -2
- package/src/utils/__tests__/group_messages.test.ts +0 -48
- package/src/utils/cache/messages_cache.ts +11 -27
- package/src/utils/cache/optimistically_create_message.ts +0 -3
- package/src/utils/client/transform_response.ts +5 -7
- package/src/utils/group_messages.ts +1 -18
- package/src/utils/jolt/transform_message_event_data_to_message_resource.ts +0 -1
- package/src/utils/request/messages_data_options.ts +1 -2
- package/build/components/conversation/message_list.d.ts +0 -21
- package/build/components/conversation/message_list.d.ts.map +0 -1
- package/build/components/conversation/message_list.js +0 -273
- package/build/components/conversation/message_list.js.map +0 -1
- package/build/utils/replace_equal_by_id.d.ts +0 -6
- package/build/utils/replace_equal_by_id.d.ts.map +0 -1
- package/build/utils/replace_equal_by_id.js +0 -41
- package/build/utils/replace_equal_by_id.js.map +0 -1
- package/src/components/conversation/__tests__/message_list.test.tsx +0 -271
- package/src/components/conversation/__tests__/reply_shadow_message.test.tsx +0 -119
- package/src/components/conversation/message_list.tsx +0 -157
- package/src/hooks/__tests__/use_message_create_or_update.test.tsx +0 -110
- package/src/utils/__tests__/replace_equal_by_id.test.ts +0 -73
- package/src/utils/cache/__tests__/messages_cache.test.ts +0 -89
- package/src/utils/cache/__tests__/messages_cache_reply_roots.test.ts +0 -70
- package/src/utils/client/__tests__/transform_response.test.ts +0 -62
- package/src/utils/replace_equal_by_id.ts +0 -42
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import { getRequestQueryKey } from '../../hooks/use_suspense_api';
|
|
2
2
|
import { transformReactionEventDataToReactionCountResource } from '../jolt/transform_reaction_event_data_to_reaction_count_resource';
|
|
3
3
|
import { getMessagesRequestArgs } from '../request/get_messages';
|
|
4
|
-
import {
|
|
4
|
+
import { updateOrCreateRecordInPagesData, updateRecordInPagesData } from './page_mutations';
|
|
5
5
|
import { deleteRecordInPagesData } from './page_mutations';
|
|
6
6
|
export function updateCacheWithMessage(queryClient, queryKey, message, event) {
|
|
7
7
|
queryClient.setQueryData(queryKey, prev => {
|
|
8
8
|
if (event === 'message.created') {
|
|
9
|
-
// Before adding the new message, remove
|
|
10
|
-
//
|
|
9
|
+
// Before adding the new message, remove any pending temporary messages
|
|
10
|
+
// with matching text to prevent duplicates from race conditions
|
|
11
11
|
let dataAfterTempRemoval = prev;
|
|
12
|
-
if (prev && message.
|
|
12
|
+
if (prev && message.text && message.mine) {
|
|
13
13
|
dataAfterTempRemoval = deleteRecordInPagesData({
|
|
14
14
|
data: prev,
|
|
15
15
|
record: message,
|
|
16
|
-
matchFn: existingMessage
|
|
16
|
+
matchFn: (existingMessage, _record) => {
|
|
17
|
+
return isTemporaryMessageId(existingMessage.id) && existingMessage.text === message.text && existingMessage.mine;
|
|
18
|
+
}
|
|
17
19
|
});
|
|
18
20
|
}
|
|
19
21
|
return updateOrCreateRecordInPagesData({
|
|
@@ -45,15 +47,6 @@ export function updateCacheWithIndividualMessage(queryClient, queryKey, message)
|
|
|
45
47
|
};
|
|
46
48
|
});
|
|
47
49
|
}
|
|
48
|
-
export function updateCacheReplyRoots(queryClient, queryKey, root) {
|
|
49
|
-
queryClient.setQueryData(queryKey, prev => updateAllRecordsInPagesData({
|
|
50
|
-
data: prev,
|
|
51
|
-
processRecord: message => message.replyRoot?.id === root.id ? {
|
|
52
|
-
...message,
|
|
53
|
-
replyRoot: mergeMessageUpdate(root, message.replyRoot)
|
|
54
|
-
} : message
|
|
55
|
-
}));
|
|
56
|
-
}
|
|
57
50
|
export function updateCacheWithReaction(queryClient, queryKey, event, currentPersonId) {
|
|
58
51
|
const message = {
|
|
59
52
|
id: event.data.data.message_sort_key
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages_cache.js","names":["getRequestQueryKey","transformReactionEventDataToReactionCountResource","getMessagesRequestArgs","
|
|
1
|
+
{"version":3,"file":"messages_cache.js","names":["getRequestQueryKey","transformReactionEventDataToReactionCountResource","getMessagesRequestArgs","updateOrCreateRecordInPagesData","updateRecordInPagesData","deleteRecordInPagesData","updateCacheWithMessage","queryClient","queryKey","message","event","setQueryData","prev","dataAfterTempRemoval","text","mine","data","record","matchFn","existingMessage","_record","isTemporaryMessageId","id","processRecord","current","mergeMessageUpdate","updateCacheWithIndividualMessage","links","meta","updateCacheWithReaction","currentPersonId","message_sort_key","oldMessage","reactionCounts","foundMatch","newReactionCounts","map","reactionCount","value","oldData","newReactionCount","count","messageId","endsWith","isNewMessage","getThreadedMessagesQueryKey","conversationId","replyRootId","requestArgs","conversation_id","reply_root_id"],"sources":["../../../src/utils/cache/messages_cache.ts"],"sourcesContent":["import { InfiniteData, QueryClient } from '@tanstack/react-query'\nimport { getRequestQueryKey } from '../../hooks/use_suspense_api'\nimport { ApiCollection, ApiResource, MessageResource } from '../../types'\nimport { JoltReactionEvent } from '../../types/jolt_events'\nimport { transformReactionEventDataToReactionCountResource } from '../jolt/transform_reaction_event_data_to_reaction_count_resource'\nimport { getMessagesRequestArgs } from '../request/get_messages'\nimport { updateOrCreateRecordInPagesData, updateRecordInPagesData } from './page_mutations'\nimport { deleteRecordInPagesData } from './page_mutations'\n\nexport function updateCacheWithMessage(\n queryClient: QueryClient,\n queryKey: unknown[],\n message: MessageResource,\n event: 'message.created' | 'message.updated'\n) {\n queryClient.setQueryData<MessagesQueryData>(queryKey, prev => {\n if (event === 'message.created') {\n // Before adding the new message, remove any pending temporary messages\n // with matching text to prevent duplicates from race conditions\n let dataAfterTempRemoval = prev\n if (prev && message.text && message.mine) {\n dataAfterTempRemoval = deleteRecordInPagesData({\n data: prev,\n record: message,\n matchFn: (existingMessage, _record) => {\n return (\n isTemporaryMessageId(existingMessage.id) &&\n existingMessage.text === message.text &&\n existingMessage.mine\n )\n },\n })\n }\n\n return updateOrCreateRecordInPagesData({\n data: dataAfterTempRemoval,\n record: message,\n processRecord: (record, current) => mergeMessageUpdate(record, current),\n })\n } else {\n return updateRecordInPagesData({\n data: prev,\n record: message,\n processRecord: (record, current) => mergeMessageUpdate(record, current),\n })\n }\n })\n}\n\ntype IndividualMessageQueryData = ApiResource<MessageResource>\n\nexport function updateCacheWithIndividualMessage(\n queryClient: QueryClient,\n queryKey: unknown[],\n message: MessageResource\n) {\n queryClient.setQueryData<IndividualMessageQueryData>(queryKey, prev => {\n if (!prev) {\n return {\n data: message,\n links: {},\n meta: {},\n }\n }\n\n return {\n ...prev,\n data: mergeMessageUpdate(message, prev.data),\n }\n })\n}\n\nexport function updateCacheWithReaction(\n queryClient: QueryClient,\n queryKey: unknown[],\n event: JoltReactionEvent,\n currentPersonId: number\n) {\n const message = { id: event.data.data.message_sort_key } as MessageResource\n queryClient.setQueryData<MessagesQueryData>(queryKey, prev =>\n updateRecordInPagesData({\n data: prev,\n record: message,\n processRecord: (record, oldMessage) => {\n const reactionCounts = oldMessage.reactionCounts || []\n let foundMatch = false\n let newReactionCounts = reactionCounts.map(reactionCount => {\n if (reactionCount.value === event.data.data.value) {\n foundMatch = true\n return transformReactionEventDataToReactionCountResource({\n data: event.data.data,\n oldData: reactionCount,\n event: event.event,\n currentPersonId,\n })\n }\n return reactionCount\n })\n\n if (!foundMatch) {\n const newReactionCount = transformReactionEventDataToReactionCountResource({\n data: event.data.data,\n event: event.event,\n currentPersonId,\n })\n\n if (newReactionCount?.count) {\n newReactionCounts = [...newReactionCounts, newReactionCount]\n }\n }\n\n return { ...oldMessage, reactionCounts: newReactionCounts }\n },\n })\n )\n}\n\ntype MessagesQueryData = InfiniteData<ApiCollection<MessageResource>>\nexport function isTemporaryMessageId(messageId?: string | null): boolean {\n return !!messageId && messageId.endsWith('-temp')\n}\nexport function isNewMessage(message?: MessageResource): boolean {\n return !message?.id || isTemporaryMessageId(message.id)\n}\n\nexport function getThreadedMessagesQueryKey(conversationId: number, replyRootId: string) {\n const requestArgs = getMessagesRequestArgs({\n conversation_id: conversationId,\n reply_root_id: replyRootId,\n })\n return getRequestQueryKey(requestArgs)\n}\n\nexport function mergeMessageUpdate(\n record: MessageResource,\n current?: MessageResource\n): MessageResource {\n if (!current) {\n return record\n }\n\n return {\n ...current,\n ...record,\n // Preserve reactions from cache - they're managed via separate reaction events\n reactionCounts: current.reactionCounts || [],\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { CurrentPersonResource, MessageResource } from '../../types';
|
|
2
2
|
import { DenormalizedAttachmentResourceForCreate } from '../../types/resources/denormalized_attachment_resource_for_create';
|
|
3
|
-
export declare function optimisticallyCreateMessage({ conversationId, text, attachments, currentPerson, message, replyRootId,
|
|
3
|
+
export declare function optimisticallyCreateMessage({ conversationId, text, attachments, currentPerson, message, replyRootId, }: {
|
|
4
4
|
conversationId: number;
|
|
5
5
|
text: string;
|
|
6
6
|
attachments?: DenormalizedAttachmentResourceForCreate[];
|
|
7
7
|
currentPerson: CurrentPersonResource;
|
|
8
8
|
message?: MessageResource;
|
|
9
9
|
replyRootId?: string | null;
|
|
10
|
-
idempotentKey?: string;
|
|
11
10
|
}): MessageResource;
|
|
12
11
|
//# sourceMappingURL=optimistically_create_message.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"optimistically_create_message.d.ts","sourceRoot":"","sources":["../../../src/utils/cache/optimistically_create_message.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,qBAAqB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAEnF,OAAO,EAAE,uCAAuC,EAAE,MAAM,mEAAmE,CAAA;AAM3H,wBAAgB,2BAA2B,CAAC,EAC1C,cAAc,EACd,IAAI,EACJ,WAAW,EACX,aAAa,EACb,OAAO,EACP,WAAW,
|
|
1
|
+
{"version":3,"file":"optimistically_create_message.d.ts","sourceRoot":"","sources":["../../../src/utils/cache/optimistically_create_message.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,qBAAqB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAEnF,OAAO,EAAE,uCAAuC,EAAE,MAAM,mEAAmE,CAAA;AAM3H,wBAAgB,2BAA2B,CAAC,EAC1C,cAAc,EACd,IAAI,EACJ,WAAW,EACX,aAAa,EACb,OAAO,EACP,WAAW,GACZ,EAAE;IACD,cAAc,EAAE,MAAM,CAAA;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,uCAAuC,EAAE,CAAA;IACvD,aAAa,EAAE,qBAAqB,CAAA;IACpC,OAAO,CAAC,EAAE,eAAe,CAAA;IACzB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC5B,mBAgDA"}
|
|
@@ -9,8 +9,7 @@ export function optimisticallyCreateMessage({
|
|
|
9
9
|
attachments,
|
|
10
10
|
currentPerson,
|
|
11
11
|
message,
|
|
12
|
-
replyRootId
|
|
13
|
-
idempotentKey
|
|
12
|
+
replyRootId
|
|
14
13
|
}) {
|
|
15
14
|
const id = message?.id || generateTempMessageId();
|
|
16
15
|
|
|
@@ -40,8 +39,7 @@ export function optimisticallyCreateMessage({
|
|
|
40
39
|
lastInGroup: true,
|
|
41
40
|
pending: true,
|
|
42
41
|
replyCount: 0,
|
|
43
|
-
replyRootId: replyRootId || null
|
|
44
|
-
idempotentKey
|
|
42
|
+
replyRootId: replyRootId || null
|
|
45
43
|
};
|
|
46
44
|
|
|
47
45
|
// Add the optimistic message to the cache
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"optimistically_create_message.js","names":["chatQueryClient","getMessagesQueryKey","convertAttachmentsForCreate","generatePlaceholderUlid","updateOrCreateRecordInPagesData","optimisticallyCreateMessage","conversationId","text","attachments","currentPerson","message","replyRootId","
|
|
1
|
+
{"version":3,"file":"optimistically_create_message.js","names":["chatQueryClient","getMessagesQueryKey","convertAttachmentsForCreate","generatePlaceholderUlid","updateOrCreateRecordInPagesData","optimisticallyCreateMessage","conversationId","text","attachments","currentPerson","message","replyRootId","id","generateTempMessageId","decoratedAttachments","optimisticMessage","type","messageType","html","createdAt","Date","toISOString","deletedAt","textEditedAt","mine","attachmentsForCreate","author","reactionCounts","renderAuthor","renderTime","myLatestInConversation","lastInGroup","pending","replyCount","queryKey","conversation_id","reply_root_id","setQueryData","data","record","offsetMs"],"sources":["../../../src/utils/cache/optimistically_create_message.ts"],"sourcesContent":["import { InfiniteData } from '@tanstack/react-query'\nimport { chatQueryClient } from '../../contexts/api_provider'\nimport { ApiCollection, CurrentPersonResource, MessageResource } from '../../types'\nimport { DenormalizedAttachmentResource } from '../../types/resources/denormalized_attachment_resource'\nimport { DenormalizedAttachmentResourceForCreate } from '../../types/resources/denormalized_attachment_resource_for_create'\nimport { getMessagesQueryKey } from '../../utils/request/get_messages'\nimport { convertAttachmentsForCreate } from '../convert_attachments_for_create'\nimport { generatePlaceholderUlid } from '../generate_placeholder_ulid'\nimport { updateOrCreateRecordInPagesData } from './page_mutations'\n\nexport function optimisticallyCreateMessage({\n conversationId,\n text,\n attachments,\n currentPerson,\n message,\n replyRootId,\n}: {\n conversationId: number\n text: string\n attachments?: DenormalizedAttachmentResourceForCreate[]\n currentPerson: CurrentPersonResource\n message?: MessageResource\n replyRootId?: string | null\n}) {\n const id = message?.id || generateTempMessageId()\n\n // Convert attachments to denormalized format for optimistic UI\n const decoratedAttachments: DenormalizedAttachmentResource[] = convertAttachmentsForCreate(\n attachments || []\n )\n\n // Create an optimistic message\n const optimisticMessage: MessageResource = {\n ...message,\n type: 'Message',\n messageType: 'user',\n id,\n text,\n html: '', // Will be filled by server\n createdAt: new Date().toISOString(),\n deletedAt: null,\n textEditedAt: null,\n mine: true,\n attachments: decoratedAttachments,\n attachmentsForCreate: attachments || [],\n author: currentPerson,\n reactionCounts: [],\n renderAuthor: false,\n renderTime: true,\n myLatestInConversation: true,\n lastInGroup: true,\n pending: true,\n replyCount: 0,\n replyRootId: replyRootId || null,\n }\n\n // Add the optimistic message to the cache\n type QueryData = InfiniteData<ApiCollection<MessageResource>>\n const queryKey = getMessagesQueryKey({\n conversation_id: conversationId,\n reply_root_id: replyRootId,\n })\n\n chatQueryClient.setQueryData<QueryData>(queryKey, data =>\n updateOrCreateRecordInPagesData({\n data,\n record: optimisticMessage as MessageResource,\n })\n )\n\n return optimisticMessage\n}\n\nconst generateTempMessageId = () => {\n // Put it 5 seconds in the future to account for server lag of previously created messages\n // that are still pending. This gets overwritten by the server anyway.\n return `${generatePlaceholderUlid({ offsetMs: 5000 })}-temp`\n}\n"],"mappings":"AACA,SAASA,eAAe,QAAQ,6BAA6B;AAI7D,SAASC,mBAAmB,QAAQ,kCAAkC;AACtE,SAASC,2BAA2B,QAAQ,mCAAmC;AAC/E,SAASC,uBAAuB,QAAQ,8BAA8B;AACtE,SAASC,+BAA+B,QAAQ,kBAAkB;AAElE,OAAO,SAASC,2BAA2BA,CAAC;EAC1CC,cAAc;EACdC,IAAI;EACJC,WAAW;EACXC,aAAa;EACbC,OAAO;EACPC;AAQF,CAAC,EAAE;EACD,MAAMC,EAAE,GAAGF,OAAO,EAAEE,EAAE,IAAIC,qBAAqB,CAAC,CAAC;;EAEjD;EACA,MAAMC,oBAAsD,GAAGZ,2BAA2B,CACxFM,WAAW,IAAI,EACjB,CAAC;;EAED;EACA,MAAMO,iBAAkC,GAAG;IACzC,GAAGL,OAAO;IACVM,IAAI,EAAE,SAAS;IACfC,WAAW,EAAE,MAAM;IACnBL,EAAE;IACFL,IAAI;IACJW,IAAI,EAAE,EAAE;IAAE;IACVC,SAAS,EAAE,IAAIC,IAAI,CAAC,CAAC,CAACC,WAAW,CAAC,CAAC;IACnCC,SAAS,EAAE,IAAI;IACfC,YAAY,EAAE,IAAI;IAClBC,IAAI,EAAE,IAAI;IACVhB,WAAW,EAAEM,oBAAoB;IACjCW,oBAAoB,EAAEjB,WAAW,IAAI,EAAE;IACvCkB,MAAM,EAAEjB,aAAa;IACrBkB,cAAc,EAAE,EAAE;IAClBC,YAAY,EAAE,KAAK;IACnBC,UAAU,EAAE,IAAI;IAChBC,sBAAsB,EAAE,IAAI;IAC5BC,WAAW,EAAE,IAAI;IACjBC,OAAO,EAAE,IAAI;IACbC,UAAU,EAAE,CAAC;IACbtB,WAAW,EAAEA,WAAW,IAAI;EAC9B,CAAC;;EAED;;EAEA,MAAMuB,QAAQ,GAAGjC,mBAAmB,CAAC;IACnCkC,eAAe,EAAE7B,cAAc;IAC/B8B,aAAa,EAAEzB;EACjB,CAAC,CAAC;EAEFX,eAAe,CAACqC,YAAY,CAAYH,QAAQ,EAAEI,IAAI,IACpDlC,+BAA+B,CAAC;IAC9BkC,IAAI;IACJC,MAAM,EAAExB;EACV,CAAC,CACH,CAAC;EAED,OAAOA,iBAAiB;AAC1B;AAEA,MAAMF,qBAAqB,GAAGA,CAAA,KAAM;EAClC;EACA;EACA,OAAO,GAAGV,uBAAuB,CAAC;IAAEqC,QAAQ,EAAE;EAAK,CAAC,CAAC,OAAO;AAC9D,CAAC","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform_response.d.ts","sourceRoot":"","sources":["../../../src/utils/client/transform_response.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"transform_response.d.ts","sourceRoot":"","sources":["../../../src/utils/client/transform_response.ts"],"names":[],"mappings":"AAiGA,QAAA,MAAM,iBAAiB,yBAAyD,CAAA;AAEhF,eAAe,iBAAiB,CAAA"}
|
|
@@ -36,25 +36,21 @@ const transformRelationships = relationships => {
|
|
|
36
36
|
}
|
|
37
37
|
}, {});
|
|
38
38
|
};
|
|
39
|
-
const addIncludedRecords = (
|
|
40
|
-
const {
|
|
41
|
-
relationships
|
|
42
|
-
} = record;
|
|
39
|
+
const addIncludedRecords = (relationships, included, seen, parent) => {
|
|
43
40
|
return Object.keys(relationships || {}).reduce((acc, key) => {
|
|
44
41
|
const relationship = relationships[key];
|
|
45
42
|
if (_.isArray(relationship.data)) {
|
|
46
43
|
const records = _(relationship.data).map(elem => _.find(included, elem)).compact() // account for orphans
|
|
47
44
|
.value();
|
|
48
|
-
return _.set(acc, _.pluralize(key), _.map(records,
|
|
45
|
+
return _.set(acc, _.pluralize(key), _.map(records, record => transformRecord(record, included, seen)));
|
|
49
46
|
} else {
|
|
50
47
|
const [id, type] = _.at(relationship, ['data.id', 'data.type']);
|
|
51
48
|
if (id && type) {
|
|
52
|
-
const
|
|
53
|
-
const related = isSelfReference ? undefined : _.find(included, {
|
|
49
|
+
const record = _.find(included, {
|
|
54
50
|
id,
|
|
55
51
|
type
|
|
56
52
|
});
|
|
57
|
-
return _.set(acc, key,
|
|
53
|
+
return _.set(acc, key, record ? transformRecord(record, included, seen) : null);
|
|
58
54
|
} else {
|
|
59
55
|
return acc;
|
|
60
56
|
}
|
|
@@ -81,7 +77,7 @@ const transformRecord = (record, included, seen) => {
|
|
|
81
77
|
..._.mapKeys(attributes, (v, k) => k === 'length' ? `${type.charAt(0).toLowerCase()}${type.slice(1)}Length` : k, {})
|
|
82
78
|
};
|
|
83
79
|
seen.set(record, transformed);
|
|
84
|
-
return addIncludedRecords(
|
|
80
|
+
return addIncludedRecords(relationships, included, seen, transformed);
|
|
85
81
|
}
|
|
86
82
|
};
|
|
87
83
|
const defaultTransformResponse = response => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform_response.js","names":["_","inflection","keysToCamelCase","mixin","singular","plural","transformId","id","thru","parseInt","int","transformRelationships","relationships","Object","keys","reduce","acc","key","relationship","isArray","data","ids","map","singularize","get","type","addIncludedRecords","
|
|
1
|
+
{"version":3,"file":"transform_response.js","names":["_","inflection","keysToCamelCase","mixin","singular","plural","transformId","id","thru","parseInt","int","transformRelationships","relationships","Object","keys","reduce","acc","key","relationship","isArray","data","ids","map","singularize","get","type","addIncludedRecords","included","seen","parent","records","elem","find","compact","value","set","pluralize","record","transformRecord","at","attributes","links","has","transformed","mapKeys","v","k","charAt","toLowerCase","slice","defaultTransformResponse","response","isEmpty","meta","WeakMap","result","d","transformResponse","flowRight"],"sources":["../../../src/utils/client/transform_response.ts"],"sourcesContent":["// @ts-nocheck\n// TODO: Fix this file but write tests first\n\nimport _ from 'lodash'\nimport inflection from 'lodash-inflection/lib/lodash-inflection'\nimport { keysToCamelCase } from './utils'\n\n_.mixin({ ...inflection })\n\n// Teach some bad grammar\n_.singular(/^(media)$/i, '$1')\n_.plural(/^(media)$/i, '$1')\n\n// eslint-disable-next-line eqeqeq\nconst transformId = id => _.thru(parseInt(id, 10), int => (int == id ? int : id))\n\nconst transformRelationships = relationships => {\n return Object.keys(relationships || {}).reduce((acc, key) => {\n const relationship = relationships[key]\n if (_.isArray(relationship.data)) {\n const ids = _.map(relationship.data, ({ id }) => transformId(id))\n return { ...acc, [`${_.singularize(key)}_ids`]: ids }\n } else {\n const id = _.get(relationship, 'data.id')\n const type = _.get(relationship, 'data.type', null)\n return {\n ...acc,\n [`${key}_id`]: id ? transformId(id) : null,\n [`${key}_type`]: type,\n }\n }\n }, {})\n}\n\nconst addIncludedRecords = (relationships, included, seen, parent) => {\n return Object.keys(relationships || {}).reduce((acc, key) => {\n const relationship = relationships[key]\n if (_.isArray(relationship.data)) {\n const records = _(relationship.data)\n .map(elem => _.find(included, elem))\n .compact() // account for orphans\n .value()\n return _.set(\n acc,\n _.pluralize(key),\n _.map(records, record => transformRecord(record, included, seen))\n )\n } else {\n const [id, type] = _.at(relationship, ['data.id', 'data.type'])\n if (id && type) {\n const record = _.find(included, { id, type })\n return _.set(acc, key, record ? transformRecord(record, included, seen) : null)\n } else {\n return acc\n }\n }\n }, parent)\n}\n\nconst transformRecord = (record, included, seen) => {\n if (!record) return record\n const { id, attributes, links, relationships, type } = record\n\n if (seen.has(record)) {\n return seen.get(record)\n } else {\n const transformed = {\n id: transformId(id),\n type,\n links,\n ...transformRelationships(relationships),\n ..._.mapKeys(\n attributes,\n (v, k) => (k === 'length' ? `${type.charAt(0).toLowerCase()}${type.slice(1)}Length` : k),\n {}\n ),\n }\n\n seen.set(record, transformed)\n\n return addIncludedRecords(relationships, included, seen, transformed)\n }\n}\n\nconst defaultTransformResponse = response => {\n if (_.isEmpty(response)) return response\n const { data, included, meta, links } = response\n const seen = new WeakMap()\n\n if (_.isArray(data)) {\n const result = data.map(d => transformRecord(d, included, seen))\n return { data: result, meta, links, ...data }\n } else {\n return { data: { ...transformRecord(data, included, seen) }, meta, links }\n }\n}\n\nconst transformResponse = _.flowRight(keysToCamelCase, defaultTransformResponse)\n\nexport default transformResponse\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"group_messages.d.ts","sourceRoot":"","sources":["../../src/utils/group_messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AAMjE,MAAM,MAAM,aAAa,GAAG;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAE/E,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,oBAAoB,CAAA;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,
|
|
1
|
+
{"version":3,"file":"group_messages.d.ts","sourceRoot":"","sources":["../../src/utils/group_messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AAMjE,MAAM,MAAM,aAAa,GAAG;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAE/E,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,oBAAoB,CAAA;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,oBAAoB,EAAE,OAAO,CAAA;IAC7B,iBAAiB,EAAE,OAAO,CAAA;CAC3B,CAAA;AAED,MAAM,MAAM,eAAe,GAAG,eAAe,GAAG,aAAa,GAAG,kBAAkB,CAAA;AAElF,UAAU,kBAAkB;IAC1B,EAAE,EAAE,eAAe,EAAE,CAAA;IACrB,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,kBAAkB,GAAG,eAAe,EAAE,CAkC1F"}
|
|
@@ -6,7 +6,6 @@ export function groupMessages({
|
|
|
6
6
|
inReplyScreen
|
|
7
7
|
}) {
|
|
8
8
|
const items = [];
|
|
9
|
-
const messagesById = new Map(ms.map(message => [message.id, message]));
|
|
10
9
|
let myLatestSeen = false;
|
|
11
10
|
let nextNeighborEnriched;
|
|
12
11
|
ms.forEach((message, i) => {
|
|
@@ -23,10 +22,7 @@ export function groupMessages({
|
|
|
23
22
|
}
|
|
24
23
|
const isMyLatest = !myLatestSeen && message.mine;
|
|
25
24
|
if (isMyLatest) myLatestSeen = true;
|
|
26
|
-
const enriched = enrichRegularMessage(
|
|
27
|
-
...message,
|
|
28
|
-
replyRoot: resolveReplyRoot(message, messagesById)
|
|
29
|
-
}, prev, next, isMyLatest, !!inReplyScreen);
|
|
25
|
+
const enriched = enrichRegularMessage(message, prev, next, isMyLatest, !!inReplyScreen);
|
|
30
26
|
items.push(enriched);
|
|
31
27
|
const shadow = replyShadowFor(enriched, prev);
|
|
32
28
|
if (shadow) items.push(shadow);
|
|
@@ -43,10 +39,6 @@ function neighborsOf(arr, i) {
|
|
|
43
39
|
next: arr[i - 1]
|
|
44
40
|
};
|
|
45
41
|
}
|
|
46
|
-
function resolveReplyRoot(message, messagesById) {
|
|
47
|
-
if (!message.replyRootId || message.replyRootId === message.id) return null;
|
|
48
|
-
return messagesById.get(message.replyRootId) ?? message.replyRoot ?? null;
|
|
49
|
-
}
|
|
50
42
|
function enrichSystemMessage(message, next) {
|
|
51
43
|
return {
|
|
52
44
|
...message,
|
|
@@ -122,7 +114,6 @@ function replyShadowFor(message, prev) {
|
|
|
122
114
|
type: 'ReplyShadowMessage',
|
|
123
115
|
id: `${message.id}-${message.replyRootId}`,
|
|
124
116
|
messageId: message.replyRootId,
|
|
125
|
-
replyRoot: message.replyRoot ?? null,
|
|
126
117
|
isReplyShadowMessage: true,
|
|
127
118
|
nextRendersAuthor: message.renderAuthor ?? false
|
|
128
119
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"group_messages.js","names":["dayjs","isSystemMessage","FIVE_MINUTES_MS","groupMessages","ms","inReplyScreen","items","messagesById","Map","map","message","id","myLatestSeen","nextNeighborEnriched","forEach","i","prev","neighborsOf","next","enriched","enrichSystemMessage","push","datesDifferBetween","dateSeparator","isMyLatest","mine","enrichRegularMessage","replyRoot","resolveReplyRoot","shadow","replyShadowFor","arr","replyRootId","get","myLatestInConversation","lastInGroup","renderAuthor","nextRendersAuthor","isReplyShadowMessage","nextIsReplyShadowMessage","threadPosition","inThread","showThreadDetails","startsNewGroup","nextIntroducesReplyShadow","threadPositionFor","prevIsMyReply","undefined","nextIsMyReply","a","b","author","differsByMoreThan5Min","Math","abs","toMillis","createdAt","iso","Date","getTime","dateKey","format","type","date","isThreadRoot","isLast","current","nextInThread","nextIsThreadRoot","differentThread","enteringNewThread","messageId"],"sources":["../../src/utils/group_messages.ts"],"sourcesContent":["import type { MessageResource } from '../types/resources/message'\nimport dayjs from './dayjs'\nimport { isSystemMessage } from './system_messages'\n\nconst FIVE_MINUTES_MS = 5 * 60 * 1000\n\nexport type DateSeparator = { type: 'DateSeparator'; id: string; date: string }\n\nexport type ReplyShadowMessage = {\n type: 'ReplyShadowMessage'\n id: string\n messageId: string\n replyRoot: MessageResource | null\n isReplyShadowMessage: boolean\n nextRendersAuthor: boolean\n}\n\nexport type EnrichedMessage = MessageResource | DateSeparator | ReplyShadowMessage\n\ninterface GroupMessagesProps {\n ms: MessageResource[]\n inReplyScreen?: boolean\n}\n\nexport function groupMessages({ ms, inReplyScreen }: GroupMessagesProps): EnrichedMessage[] {\n const items: EnrichedMessage[] = []\n const messagesById = new Map(ms.map(message => [message.id, message]))\n let myLatestSeen = false\n let nextNeighborEnriched: MessageResource | undefined\n\n ms.forEach((message, i) => {\n const { prev } = neighborsOf(ms, i)\n const next = nextNeighborEnriched\n\n if (isSystemMessage(message)) {\n const enriched = enrichSystemMessage(message, next)\n items.push(enriched)\n if (datesDifferBetween(message, prev)) items.push(dateSeparator(message))\n nextNeighborEnriched = enriched\n return\n }\n\n const isMyLatest = !myLatestSeen && message.mine\n if (isMyLatest) myLatestSeen = true\n\n const enriched = enrichRegularMessage(\n { ...message, replyRoot: resolveReplyRoot(message, messagesById) },\n prev,\n next,\n isMyLatest,\n !!inReplyScreen\n )\n items.push(enriched)\n\n const shadow = replyShadowFor(enriched, prev)\n if (shadow) items.push(shadow)\n\n if (!prev || datesDifferBetween(message, prev)) {\n items.push(dateSeparator(message))\n }\n\n nextNeighborEnriched = enriched\n })\n\n return items\n}\n\nfunction neighborsOf<T>(arr: T[], i: number): { prev: T | undefined; next: T | undefined } {\n return { prev: arr[i + 1], next: arr[i - 1] }\n}\n\nfunction resolveReplyRoot(\n message: MessageResource,\n messagesById: Map<string, MessageResource>\n): MessageResource | null {\n if (!message.replyRootId || message.replyRootId === message.id) return null\n return messagesById.get(message.replyRootId) ?? message.replyRoot ?? null\n}\n\nfunction enrichSystemMessage(\n message: MessageResource,\n next: MessageResource | undefined\n): MessageResource {\n return {\n ...message,\n myLatestInConversation: false,\n lastInGroup: true,\n renderAuthor: false,\n nextRendersAuthor: next?.renderAuthor,\n isReplyShadowMessage: false,\n nextIsReplyShadowMessage: false,\n threadPosition: null,\n }\n}\n\nfunction enrichRegularMessage(\n message: MessageResource,\n prev: MessageResource | undefined,\n next: MessageResource | undefined,\n isMyLatest: boolean,\n inReplyScreen: boolean\n): MessageResource {\n const inThread = message.replyRootId !== null\n const showThreadDetails = !inReplyScreen && inThread\n\n return {\n ...message,\n myLatestInConversation: isMyLatest,\n lastInGroup: !next || startsNewGroup(next, message),\n renderAuthor: !message.mine && (!prev || startsNewGroup(message, prev)),\n nextRendersAuthor: next?.renderAuthor,\n isReplyShadowMessage: false,\n nextIsReplyShadowMessage: nextIntroducesReplyShadow(next, message),\n threadPosition: showThreadDetails ? threadPositionFor(message, next) : null,\n prevIsMyReply: showThreadDetails ? prev?.mine : undefined,\n nextIsMyReply: showThreadDetails ? next?.mine : undefined,\n }\n}\n\nfunction startsNewGroup(a: MessageResource, b: MessageResource): boolean {\n return (\n a.author?.id !== b.author?.id ||\n differsByMoreThan5Min(a, b) ||\n a.replyRootId !== b.replyRootId ||\n datesDifferBetween(a, b)\n )\n}\n\nfunction differsByMoreThan5Min(a: MessageResource, b: MessageResource): boolean {\n return Math.abs(toMillis(a.createdAt) - toMillis(b.createdAt)) > FIVE_MINUTES_MS\n}\n\nfunction toMillis(iso: string): number {\n return new Date(iso).getTime()\n}\n\nfunction datesDifferBetween(a: MessageResource, b: MessageResource | undefined): boolean {\n if (!b) return false\n return dateKey(a) !== dateKey(b)\n}\n\nfunction dateKey(message: MessageResource): string {\n return dayjs(message.createdAt).format('YYYY-MM-DD')\n}\n\nfunction dateSeparator(message: MessageResource): DateSeparator {\n return { type: 'DateSeparator', id: `day-divider-${message.id}`, date: dateKey(message) }\n}\n\nfunction threadPositionFor(\n message: MessageResource,\n next: MessageResource | undefined\n): 'first' | 'center' | 'last' | null {\n const isThreadRoot = message.replyRootId === message.id\n const isLast =\n !next || next.replyRootId !== message.replyRootId || datesDifferBetween(next, message)\n\n if (isThreadRoot && isLast) return null\n if (isThreadRoot) return 'first'\n if (isLast) return 'last'\n return 'center'\n}\n\nfunction nextIntroducesReplyShadow(\n next: MessageResource | undefined,\n current: MessageResource\n): boolean {\n if (!next) return false\n const nextInThread = next.replyRootId !== null\n const nextIsThreadRoot = next.replyRootId === next.id\n const differentThread = next.replyRootId !== current.replyRootId\n return nextInThread && !nextIsThreadRoot && (differentThread || datesDifferBetween(next, current))\n}\n\nfunction replyShadowFor(\n message: MessageResource,\n prev: MessageResource | undefined\n): ReplyShadowMessage | undefined {\n if (!message.replyRootId) return undefined\n if (message.replyRootId === message.id) return undefined\n\n const enteringNewThread =\n !prev || prev.replyRootId !== message.replyRootId || datesDifferBetween(prev, message)\n if (!enteringNewThread) return undefined\n\n return {\n type: 'ReplyShadowMessage',\n id: `${message.id}-${message.replyRootId}`,\n messageId: message.replyRootId,\n replyRoot: message.replyRoot ?? null,\n isReplyShadowMessage: true,\n nextRendersAuthor: message.renderAuthor ?? false,\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"group_messages.js","names":["dayjs","isSystemMessage","FIVE_MINUTES_MS","groupMessages","ms","inReplyScreen","items","myLatestSeen","nextNeighborEnriched","forEach","message","i","prev","neighborsOf","next","enriched","enrichSystemMessage","push","datesDifferBetween","dateSeparator","isMyLatest","mine","enrichRegularMessage","shadow","replyShadowFor","arr","myLatestInConversation","lastInGroup","renderAuthor","nextRendersAuthor","isReplyShadowMessage","nextIsReplyShadowMessage","threadPosition","inThread","replyRootId","showThreadDetails","startsNewGroup","nextIntroducesReplyShadow","threadPositionFor","prevIsMyReply","undefined","nextIsMyReply","a","b","author","id","differsByMoreThan5Min","Math","abs","toMillis","createdAt","iso","Date","getTime","dateKey","format","type","date","isThreadRoot","isLast","current","nextInThread","nextIsThreadRoot","differentThread","enteringNewThread","messageId"],"sources":["../../src/utils/group_messages.ts"],"sourcesContent":["import type { MessageResource } from '../types/resources/message'\nimport dayjs from './dayjs'\nimport { isSystemMessage } from './system_messages'\n\nconst FIVE_MINUTES_MS = 5 * 60 * 1000\n\nexport type DateSeparator = { type: 'DateSeparator'; id: string; date: string }\n\nexport type ReplyShadowMessage = {\n type: 'ReplyShadowMessage'\n id: string\n messageId: string\n isReplyShadowMessage: boolean\n nextRendersAuthor: boolean\n}\n\nexport type EnrichedMessage = MessageResource | DateSeparator | ReplyShadowMessage\n\ninterface GroupMessagesProps {\n ms: MessageResource[]\n inReplyScreen?: boolean\n}\n\nexport function groupMessages({ ms, inReplyScreen }: GroupMessagesProps): EnrichedMessage[] {\n const items: EnrichedMessage[] = []\n let myLatestSeen = false\n let nextNeighborEnriched: MessageResource | undefined\n\n ms.forEach((message, i) => {\n const { prev } = neighborsOf(ms, i)\n const next = nextNeighborEnriched\n\n if (isSystemMessage(message)) {\n const enriched = enrichSystemMessage(message, next)\n items.push(enriched)\n if (datesDifferBetween(message, prev)) items.push(dateSeparator(message))\n nextNeighborEnriched = enriched\n return\n }\n\n const isMyLatest = !myLatestSeen && message.mine\n if (isMyLatest) myLatestSeen = true\n\n const enriched = enrichRegularMessage(message, prev, next, isMyLatest, !!inReplyScreen)\n items.push(enriched)\n\n const shadow = replyShadowFor(enriched, prev)\n if (shadow) items.push(shadow)\n\n if (!prev || datesDifferBetween(message, prev)) {\n items.push(dateSeparator(message))\n }\n\n nextNeighborEnriched = enriched\n })\n\n return items\n}\n\nfunction neighborsOf<T>(arr: T[], i: number): { prev: T | undefined; next: T | undefined } {\n return { prev: arr[i + 1], next: arr[i - 1] }\n}\n\nfunction enrichSystemMessage(\n message: MessageResource,\n next: MessageResource | undefined\n): MessageResource {\n return {\n ...message,\n myLatestInConversation: false,\n lastInGroup: true,\n renderAuthor: false,\n nextRendersAuthor: next?.renderAuthor,\n isReplyShadowMessage: false,\n nextIsReplyShadowMessage: false,\n threadPosition: null,\n }\n}\n\nfunction enrichRegularMessage(\n message: MessageResource,\n prev: MessageResource | undefined,\n next: MessageResource | undefined,\n isMyLatest: boolean,\n inReplyScreen: boolean\n): MessageResource {\n const inThread = message.replyRootId !== null\n const showThreadDetails = !inReplyScreen && inThread\n\n return {\n ...message,\n myLatestInConversation: isMyLatest,\n lastInGroup: !next || startsNewGroup(next, message),\n renderAuthor: !message.mine && (!prev || startsNewGroup(message, prev)),\n nextRendersAuthor: next?.renderAuthor,\n isReplyShadowMessage: false,\n nextIsReplyShadowMessage: nextIntroducesReplyShadow(next, message),\n threadPosition: showThreadDetails ? threadPositionFor(message, next) : null,\n prevIsMyReply: showThreadDetails ? prev?.mine : undefined,\n nextIsMyReply: showThreadDetails ? next?.mine : undefined,\n }\n}\n\nfunction startsNewGroup(a: MessageResource, b: MessageResource): boolean {\n return (\n a.author?.id !== b.author?.id ||\n differsByMoreThan5Min(a, b) ||\n a.replyRootId !== b.replyRootId ||\n datesDifferBetween(a, b)\n )\n}\n\nfunction differsByMoreThan5Min(a: MessageResource, b: MessageResource): boolean {\n return Math.abs(toMillis(a.createdAt) - toMillis(b.createdAt)) > FIVE_MINUTES_MS\n}\n\nfunction toMillis(iso: string): number {\n return new Date(iso).getTime()\n}\n\nfunction datesDifferBetween(a: MessageResource, b: MessageResource | undefined): boolean {\n if (!b) return false\n return dateKey(a) !== dateKey(b)\n}\n\nfunction dateKey(message: MessageResource): string {\n return dayjs(message.createdAt).format('YYYY-MM-DD')\n}\n\nfunction dateSeparator(message: MessageResource): DateSeparator {\n return { type: 'DateSeparator', id: `day-divider-${message.id}`, date: dateKey(message) }\n}\n\nfunction threadPositionFor(\n message: MessageResource,\n next: MessageResource | undefined\n): 'first' | 'center' | 'last' | null {\n const isThreadRoot = message.replyRootId === message.id\n const isLast =\n !next || next.replyRootId !== message.replyRootId || datesDifferBetween(next, message)\n\n if (isThreadRoot && isLast) return null\n if (isThreadRoot) return 'first'\n if (isLast) return 'last'\n return 'center'\n}\n\nfunction nextIntroducesReplyShadow(\n next: MessageResource | undefined,\n current: MessageResource\n): boolean {\n if (!next) return false\n const nextInThread = next.replyRootId !== null\n const nextIsThreadRoot = next.replyRootId === next.id\n const differentThread = next.replyRootId !== current.replyRootId\n return nextInThread && !nextIsThreadRoot && (differentThread || datesDifferBetween(next, current))\n}\n\nfunction replyShadowFor(\n message: MessageResource,\n prev: MessageResource | undefined\n): ReplyShadowMessage | undefined {\n if (!message.replyRootId) return undefined\n if (message.replyRootId === message.id) return undefined\n\n const enteringNewThread =\n !prev || prev.replyRootId !== message.replyRootId || datesDifferBetween(prev, message)\n if (!enteringNewThread) return undefined\n\n return {\n type: 'ReplyShadowMessage',\n id: `${message.id}-${message.replyRootId}`,\n messageId: message.replyRootId,\n isReplyShadowMessage: true,\n nextRendersAuthor: message.renderAuthor ?? false,\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform_message_event_data_to_message_resource.d.ts","sourceRoot":"","sources":["../../../src/utils/jolt/transform_message_event_data_to_message_resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAA;AAI5E,wBAAgB,0CAA0C,CAAC,EACzD,IAAI,EACJ,eAAe,GAChB,EAAE;IACD,IAAI,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAA;IACzC,eAAe,EAAE,MAAM,CAAA;CACxB,GAAG,eAAe,
|
|
1
|
+
{"version":3,"file":"transform_message_event_data_to_message_resource.d.ts","sourceRoot":"","sources":["../../../src/utils/jolt/transform_message_event_data_to_message_resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAA;AAI5E,wBAAgB,0CAA0C,CAAC,EACzD,IAAI,EACJ,eAAe,GAChB,EAAE;IACD,IAAI,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAA;IACzC,eAAe,EAAE,MAAM,CAAA;CACxB,GAAG,eAAe,CA8BlB"}
|
|
@@ -22,7 +22,6 @@ export function transformMessageEventDataToMessageResource({
|
|
|
22
22
|
reactionCounts: [],
|
|
23
23
|
replyCount: data.reply_count || 0,
|
|
24
24
|
replyRootId: data.reply_root_id || null,
|
|
25
|
-
idempotentKey: data.idempotent_key ?? null,
|
|
26
25
|
messageType: data.message_type,
|
|
27
26
|
personIdsForSystemEvent: data.system_event_person_ids,
|
|
28
27
|
systemTextParts: data.system_text_parts ? {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform_message_event_data_to_message_resource.js","names":["deepCamelCaseKeys","transformMessageEventDataToMessageResource","data","currentPersonId","type","id","sort_key","text","html","createdAt","created_at","deletedAt","deleted_at","textEditedAt","text_edited_at","mine","author_id","attachments","author","name","author_name","avatar","author_avatar","reactionCounts","replyCount","reply_count","replyRootId","reply_root_id","
|
|
1
|
+
{"version":3,"file":"transform_message_event_data_to_message_resource.js","names":["deepCamelCaseKeys","transformMessageEventDataToMessageResource","data","currentPersonId","type","id","sort_key","text","html","createdAt","created_at","deletedAt","deleted_at","textEditedAt","text_edited_at","mine","author_id","attachments","author","name","author_name","avatar","author_avatar","reactionCounts","replyCount","reply_count","replyRootId","reply_root_id","messageType","message_type","personIdsForSystemEvent","system_event_person_ids","systemTextParts","system_text_parts","names","overflowCount","overflow_count","action"],"sources":["../../../src/utils/jolt/transform_message_event_data_to_message_resource.ts"],"sourcesContent":["import { MessageResource } from '../../types'\nimport { MessageCreatedEvent } from '../../types/jolt_events/message_events'\nimport { DenormalizedAttachmentResource } from '../../types/resources/denormalized_attachment_resource'\nimport { deepCamelCaseKeys } from '../deepCamelCaseKeys'\n\nexport function transformMessageEventDataToMessageResource({\n data,\n currentPersonId,\n}: {\n data: MessageCreatedEvent['data']['data']\n currentPersonId: number\n}): MessageResource {\n return {\n type: 'Message',\n id: data.sort_key,\n text: data.text,\n html: data.html,\n createdAt: data.created_at,\n deletedAt: data.deleted_at,\n textEditedAt: data.text_edited_at,\n mine: data.author_id === currentPersonId,\n attachments: deepCamelCaseKeys<DenormalizedAttachmentResource[]>(data.attachments) || [],\n author: {\n type: 'Person',\n id: data.author_id,\n name: data.author_name,\n avatar: data.author_avatar,\n },\n reactionCounts: [],\n replyCount: data.reply_count || 0,\n replyRootId: data.reply_root_id || null,\n messageType: data.message_type,\n personIdsForSystemEvent: data.system_event_person_ids,\n systemTextParts: data.system_text_parts\n ? {\n names: data.system_text_parts.names,\n overflowCount: data.system_text_parts.overflow_count,\n action: data.system_text_parts.action,\n }\n : null,\n }\n}\n"],"mappings":"AAGA,SAASA,iBAAiB,QAAQ,sBAAsB;AAExD,OAAO,SAASC,0CAA0CA,CAAC;EACzDC,IAAI;EACJC;AAIF,CAAC,EAAmB;EAClB,OAAO;IACLC,IAAI,EAAE,SAAS;IACfC,EAAE,EAAEH,IAAI,CAACI,QAAQ;IACjBC,IAAI,EAAEL,IAAI,CAACK,IAAI;IACfC,IAAI,EAAEN,IAAI,CAACM,IAAI;IACfC,SAAS,EAAEP,IAAI,CAACQ,UAAU;IAC1BC,SAAS,EAAET,IAAI,CAACU,UAAU;IAC1BC,YAAY,EAAEX,IAAI,CAACY,cAAc;IACjCC,IAAI,EAAEb,IAAI,CAACc,SAAS,KAAKb,eAAe;IACxCc,WAAW,EAAEjB,iBAAiB,CAAmCE,IAAI,CAACe,WAAW,CAAC,IAAI,EAAE;IACxFC,MAAM,EAAE;MACNd,IAAI,EAAE,QAAQ;MACdC,EAAE,EAAEH,IAAI,CAACc,SAAS;MAClBG,IAAI,EAAEjB,IAAI,CAACkB,WAAW;MACtBC,MAAM,EAAEnB,IAAI,CAACoB;IACf,CAAC;IACDC,cAAc,EAAE,EAAE;IAClBC,UAAU,EAAEtB,IAAI,CAACuB,WAAW,IAAI,CAAC;IACjCC,WAAW,EAAExB,IAAI,CAACyB,aAAa,IAAI,IAAI;IACvCC,WAAW,EAAE1B,IAAI,CAAC2B,YAAY;IAC9BC,uBAAuB,EAAE5B,IAAI,CAAC6B,uBAAuB;IACrDC,eAAe,EAAE9B,IAAI,CAAC+B,iBAAiB,GACnC;MACEC,KAAK,EAAEhC,IAAI,CAAC+B,iBAAiB,CAACC,KAAK;MACnCC,aAAa,EAAEjC,IAAI,CAAC+B,iBAAiB,CAACG,cAAc;MACpDC,MAAM,EAAEnC,IAAI,CAAC+B,iBAAiB,CAACI;IACjC,CAAC,GACD;EACN,CAAC;AACH","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages_data_options.d.ts","sourceRoot":"","sources":["../../../src/utils/request/messages_data_options.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB;;;;
|
|
1
|
+
{"version":3,"file":"messages_data_options.d.ts","sourceRoot":"","sources":["../../../src/utils/request/messages_data_options.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB;;;;CAkB5B,CAAA;AAED,eAAO,MAAM,kBAAkB,UAAgC,CAAA"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const getMessageFields = {
|
|
2
|
-
Message: ['text', 'text_edited_at', 'mine', 'attachments', 'created_at', 'deleted_at', 'author', 'reaction_counts', 'reply_count', 'reply_root', '
|
|
2
|
+
Message: ['text', 'text_edited_at', 'mine', 'attachments', 'created_at', 'deleted_at', 'author', 'reaction_counts', 'reply_count', 'reply_root', 'message_type', 'person_ids_for_system_event', 'system_text_parts'],
|
|
3
3
|
Person: ['name', 'avatar'],
|
|
4
4
|
ReactionCount: ['value', 'count', 'mine', 'message_id', 'author_ids']
|
|
5
5
|
};
|
|
6
|
-
export const getMessagesInclude = ['author', 'reaction_counts'
|
|
6
|
+
export const getMessagesInclude = ['author', 'reaction_counts'];
|
|
7
7
|
//# sourceMappingURL=messages_data_options.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages_data_options.js","names":["getMessageFields","Message","Person","ReactionCount","getMessagesInclude"],"sources":["../../../src/utils/request/messages_data_options.ts"],"sourcesContent":["export const getMessageFields = {\n Message: [\n 'text',\n 'text_edited_at',\n 'mine',\n 'attachments',\n 'created_at',\n 'deleted_at',\n 'author',\n 'reaction_counts',\n 'reply_count',\n 'reply_root',\n '
|
|
1
|
+
{"version":3,"file":"messages_data_options.js","names":["getMessageFields","Message","Person","ReactionCount","getMessagesInclude"],"sources":["../../../src/utils/request/messages_data_options.ts"],"sourcesContent":["export const getMessageFields = {\n Message: [\n 'text',\n 'text_edited_at',\n 'mine',\n 'attachments',\n 'created_at',\n 'deleted_at',\n 'author',\n 'reaction_counts',\n 'reply_count',\n 'reply_root',\n 'message_type',\n 'person_ids_for_system_event',\n 'system_text_parts',\n ],\n Person: ['name', 'avatar'],\n ReactionCount: ['value', 'count', 'mine', 'message_id', 'author_ids'],\n}\n\nexport const getMessagesInclude = ['author', 'reaction_counts']\n"],"mappings":"AAAA,OAAO,MAAMA,gBAAgB,GAAG;EAC9BC,OAAO,EAAE,CACP,MAAM,EACN,gBAAgB,EAChB,MAAM,EACN,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,QAAQ,EACR,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,cAAc,EACd,6BAA6B,EAC7B,mBAAmB,CACpB;EACDC,MAAM,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC;EAC1BC,aAAa,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY;AACtE,CAAC;AAED,OAAO,MAAMC,kBAAkB,GAAG,CAAC,QAAQ,EAAE,iBAAiB,CAAC","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@planningcenter/chat-react-native",
|
|
3
|
-
"version": "4.0.1-
|
|
3
|
+
"version": "4.0.1-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.0.
|
|
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": "f3267650b8c09742984cfcc7869b176db2a51986"
|
|
88
88
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useNavigation } from '@react-navigation/native'
|
|
2
2
|
import { some } from 'lodash'
|
|
3
|
-
import React, {
|
|
3
|
+
import React, { useEffect } from 'react'
|
|
4
4
|
import {
|
|
5
5
|
AccessibilityActionEvent,
|
|
6
6
|
Pressable,
|
|
@@ -44,14 +44,14 @@ import { TheirReplyConnector, MyReplyConnector, AVATAR_CONNECTOR_SPACING } from
|
|
|
44
44
|
interface MessageProps extends MessageResource {
|
|
45
45
|
canDeleteNonAuthoredMessages: boolean
|
|
46
46
|
conversation_id: number
|
|
47
|
-
|
|
47
|
+
latestReadMessageSortKey?: string
|
|
48
48
|
inReplyScreen?: boolean
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
export
|
|
51
|
+
export function Message({
|
|
52
52
|
canDeleteNonAuthoredMessages,
|
|
53
53
|
conversation_id,
|
|
54
|
-
|
|
54
|
+
latestReadMessageSortKey,
|
|
55
55
|
inReplyScreen,
|
|
56
56
|
...message
|
|
57
57
|
}: MessageProps) {
|
|
@@ -73,16 +73,11 @@ export const Message = memo(function MessageRow({
|
|
|
73
73
|
const [messageBubbleHeight, setMessageBubbleHeight] = React.useState(0)
|
|
74
74
|
const { animatedBackgroundColor, handleMessagePressIn, handleMessagePressOut } =
|
|
75
75
|
useAnimatedMessageBackgroundColor()
|
|
76
|
-
const
|
|
77
|
-
const isDeletedReplyRootMessage = isReplyRootMessage && !!message.deletedAt
|
|
78
|
-
const showReadReceipts = message.mine && !pending && !error
|
|
79
|
-
const replyToReplyRootMessage = !isReplyRootMessage && !!message.replyRootId
|
|
80
|
-
const { message: fetchedReplyRoot } = useConversationMessage({
|
|
76
|
+
const { message: replyRootMessage } = useConversationMessage({
|
|
81
77
|
conversation_id,
|
|
82
78
|
messageId: message.replyRootId || '',
|
|
83
|
-
enabled:
|
|
79
|
+
enabled: !!message.replyRootId,
|
|
84
80
|
})
|
|
85
|
-
const replyRoot = message.replyRoot ?? fetchedReplyRoot
|
|
86
81
|
|
|
87
82
|
const metaProps = {
|
|
88
83
|
authorName: author.name,
|
|
@@ -90,11 +85,14 @@ export const Message = memo(function MessageRow({
|
|
|
90
85
|
}
|
|
91
86
|
|
|
92
87
|
const renderAuthor = (!message.mine && message.renderAuthor) || false
|
|
93
|
-
const showReplyCountButton = !inReplyScreen &&
|
|
88
|
+
const showReplyCountButton = !inReplyScreen && message.replyRootId === message.id
|
|
89
|
+
const isReplyRootMessage = message.replyRootId === message.id
|
|
90
|
+
const isDeletedReplyRootMessage = isReplyRootMessage && !!message.deletedAt
|
|
91
|
+
const replyToReplyRootMessage = !isReplyRootMessage && !!message.replyRootId
|
|
94
92
|
|
|
95
93
|
const replyCountText = pluralize(message.replyCount, 'reply')
|
|
96
94
|
const messagePendingLabel = isPersisted ? 'Saving' : 'Sending'
|
|
97
|
-
const replyRootAuthorName =
|
|
95
|
+
const replyRootAuthorName = message.replyRootId ? replyRootMessage?.author.name : author.name
|
|
98
96
|
const messageText = isDeletedReplyRootMessage ? 'Message deleted' : text
|
|
99
97
|
|
|
100
98
|
const messageBottomMargin =
|
|
@@ -286,7 +284,12 @@ export const Message = memo(function MessageRow({
|
|
|
286
284
|
)}
|
|
287
285
|
{showMessageMeta && !isDeletedReplyRootMessage && (
|
|
288
286
|
<View style={styles.messageMeta}>
|
|
289
|
-
{
|
|
287
|
+
{message.mine && !pending && !error && (
|
|
288
|
+
<MessageReadReceipts
|
|
289
|
+
message={message}
|
|
290
|
+
latestReadMessageSortKey={latestReadMessageSortKey}
|
|
291
|
+
/>
|
|
292
|
+
)}
|
|
290
293
|
{error ? (
|
|
291
294
|
<View style={styles.errorContainer}>
|
|
292
295
|
{retryFailedSaveMutation.isPending ? (
|
|
@@ -335,7 +338,7 @@ export const Message = memo(function MessageRow({
|
|
|
335
338
|
</Animated.View>
|
|
336
339
|
</Pressable>
|
|
337
340
|
)
|
|
338
|
-
}
|
|
341
|
+
}
|
|
339
342
|
|
|
340
343
|
const useMessageStyles = (mine: boolean, isDeleting: boolean) => {
|
|
341
344
|
const { colors } = useTheme()
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { StyleSheet, View } from 'react-native'
|
|
3
3
|
import { useTheme } from '../../hooks'
|
|
4
|
+
import { MessageResource } from '../../types'
|
|
4
5
|
import { Icon, Text } from '../display'
|
|
5
6
|
|
|
6
7
|
interface Props {
|
|
7
|
-
|
|
8
|
+
message: MessageResource
|
|
9
|
+
latestReadMessageSortKey?: string
|
|
8
10
|
}
|
|
9
11
|
|
|
10
|
-
export function MessageReadReceipts({
|
|
12
|
+
export function MessageReadReceipts({ message, latestReadMessageSortKey }: Props) {
|
|
11
13
|
const styles = useStyles()
|
|
12
|
-
if (!
|
|
14
|
+
if (!latestReadMessageSortKey || message.id > latestReadMessageSortKey) {
|
|
13
15
|
return (
|
|
14
16
|
<View style={styles.badgeContainer}>
|
|
15
17
|
<Icon name="general.check" style={styles.icon} />
|