@messenger-box/platform-mobile 10.0.3-alpha.37 → 10.0.3-alpha.40

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.
@@ -142,9 +142,6 @@ const ConversationViewComponent = ({ channelId: initialChannelId, role, isShowTh
142
142
  nextFetchPolicy: 'cache-first',
143
143
  refetchWritePolicy: 'merge',
144
144
  notifyOnNetworkStatusChange: true,
145
- onCompleted: (queryData) => {
146
- // MESSAGE QUERY COMPLETED
147
- },
148
145
  onError: (error) => {
149
146
  setError(String(error));
150
147
  },
@@ -205,24 +202,7 @@ const ConversationViewComponent = ({ channelId: initialChannelId, role, isShowTh
205
202
  parentId: null,
206
203
  skip: channelMessages.length,
207
204
  },
208
- // updateQuery: (prev, { fetchMoreResult }) => {
209
- // if (!fetchMoreResult || !fetchMoreResult.messages) return prev;
210
-
211
- // // Create a new array of all messages deduped by ID
212
- // const combinedMessages = [...prev.messages.data, ...fetchMoreResult.messages.data].filter(
213
- // (message, index, self) => index === self.findIndex((m) => m.id === message.id),
214
- // );
215
-
216
- // return {
217
- // ...prev,
218
- // messages: {
219
- // ...prev.messages,
220
- // data: combinedMessages,
221
- // totalCount: fetchMoreResult.messages.totalCount,
222
- // __typename: prev.messages.__typename,
223
- // },
224
- // };
225
- // },
205
+ // Let type policy handle the merge
226
206
  });
227
207
 
228
208
  setLoadingOldMessages(false);
@@ -252,7 +232,7 @@ const ConversationViewComponent = ({ channelId: initialChannelId, role, isShowTh
252
232
  other: { sound: Platform.OS === 'android' ? undefined : 'default' },
253
233
  };
254
234
 
255
- // Create optimistic message with consistent structure
235
+ // Create optimistic message with minimal structure required for UI rendering
256
236
  const messageId = objectId();
257
237
  const optimisticMessage = {
258
238
  __typename: 'Post' as const,
@@ -263,26 +243,27 @@ const ConversationViewComponent = ({ channelId: initialChannelId, role, isShowTh
263
243
  author: {
264
244
  __typename: 'UserAccount' as const,
265
245
  id: auth?.id,
246
+ picture: auth?.picture || '',
266
247
  givenName: auth?.givenName || '',
267
248
  familyName: auth?.familyName || '',
268
- picture: auth?.picture || '',
269
- username: auth?.username || '',
270
249
  email: auth?.email || '',
250
+ username: auth?.username || '',
271
251
  alias: [] as string[],
272
252
  tokens: [],
273
253
  },
274
254
  isDelivered: true,
275
255
  isRead: false,
276
- type: 'TEXT' as any,
256
+ type: 'TEXT' as PostTypeEnum,
277
257
  parentId: null,
278
258
  fromServer: false,
279
259
  channel: {
280
260
  __typename: 'Channel' as const,
281
261
  id: channelId,
282
262
  },
263
+ // Required fields that Apollo expects in the cache
283
264
  propsConfiguration: {
284
265
  __typename: 'MachineConfiguration' as const,
285
- resource: '' as any, // Cast to any to bypass the URI type check
266
+ resource: '' as any,
286
267
  },
287
268
  props: {},
288
269
  files: {
@@ -307,6 +288,52 @@ const ConversationViewComponent = ({ channelId: initialChannelId, role, isShowTh
307
288
  __typename: 'Mutation',
308
289
  sendMessage: optimisticMessage,
309
290
  },
291
+ update: (cache, { data }) => {
292
+ if (data?.sendMessage) {
293
+ try {
294
+ // Read the existing messages from the cache
295
+ const existingData = cache.readQuery<{
296
+ messages: {
297
+ __typename: string;
298
+ messagesRefId?: string;
299
+ data: any[];
300
+ totalCount: number;
301
+ };
302
+ }>({
303
+ query: MessagesDocument,
304
+ variables: {
305
+ channelId: channelId?.toString(),
306
+ parentId: null,
307
+ limit: MESSAGES_PER_PAGE,
308
+ skip: 0,
309
+ },
310
+ });
311
+
312
+ // If we don't have data yet in the cache, don't try to update
313
+ if (!existingData) return;
314
+
315
+ // Let the type policy handle the merging
316
+ cache.writeQuery({
317
+ query: MessagesDocument,
318
+ variables: {
319
+ channelId: channelId?.toString(),
320
+ parentId: null,
321
+ limit: MESSAGES_PER_PAGE,
322
+ skip: 0,
323
+ },
324
+ data: {
325
+ messages: {
326
+ ...existingData.messages,
327
+ data: [data.sendMessage, ...existingData.messages.data],
328
+ totalCount: (existingData.messages.totalCount || 0) + 1,
329
+ },
330
+ },
331
+ });
332
+ } catch (error) {
333
+ console.error('Error updating cache:', error);
334
+ }
335
+ }
336
+ },
310
337
  });
311
338
 
312
339
  return { message: response.data?.sendMessage };
@@ -407,21 +434,10 @@ const ConversationViewComponent = ({ channelId: initialChannelId, role, isShowTh
407
434
  const currentMessageText = messageText;
408
435
  setMessageText('');
409
436
 
410
- // Create file info for optimistic response
411
- const optimisticFileInfo = {
412
- __typename: 'FileInfo' as const,
413
- id: objectId(),
414
- url: selectedImage,
415
- name: imagesToUpload[0]?.name || 'image.jpg',
416
- extension: 'jpg',
417
- mimeType: 'image/jpeg',
418
- size: 0,
419
- refType: FileRefType.Post,
420
- height: imagesToUpload[0]?.height || 0,
421
- width: imagesToUpload[0]?.width || 0,
422
- };
437
+ // Create a unique file ID for the optimistic response
438
+ const fileId = objectId();
423
439
 
424
- // Create optimistic message with file
440
+ // Create minimal optimistic message with file
425
441
  const optimisticMessage = {
426
442
  __typename: 'Post' as const,
427
443
  id: postId,
@@ -431,26 +447,27 @@ const ConversationViewComponent = ({ channelId: initialChannelId, role, isShowTh
431
447
  author: {
432
448
  __typename: 'UserAccount' as const,
433
449
  id: auth?.id,
450
+ picture: auth?.picture || '',
434
451
  givenName: auth?.givenName || '',
435
452
  familyName: auth?.familyName || '',
436
- picture: auth?.picture || '',
437
- username: auth?.username || '',
438
453
  email: auth?.email || '',
454
+ username: auth?.username || '',
439
455
  alias: [] as string[],
440
456
  tokens: [],
441
457
  },
442
458
  isDelivered: true,
443
459
  isRead: false,
444
- type: 'TEXT' as any,
460
+ type: 'TEXT' as PostTypeEnum,
445
461
  parentId: null,
446
462
  fromServer: false,
447
463
  channel: {
448
464
  __typename: 'Channel' as const,
449
465
  id: channelId,
450
466
  },
467
+ // Required fields that Apollo expects in the cache
451
468
  propsConfiguration: {
452
469
  __typename: 'MachineConfiguration' as const,
453
- resource: '' as any, // Cast to any to bypass the URI type check
470
+ resource: '' as any,
454
471
  },
455
472
  props: {},
456
473
  files: {
@@ -458,17 +475,18 @@ const ConversationViewComponent = ({ channelId: initialChannelId, role, isShowTh
458
475
  data: [
459
476
  {
460
477
  __typename: 'FileInfo' as const,
461
- id: objectId(),
478
+ id: fileId,
462
479
  url: selectedImage,
463
480
  name: imagesToUpload[0]?.name || 'image.jpg',
464
481
  extension: 'jpg',
465
482
  mimeType: 'image/jpeg',
466
- size: 0,
467
- refType: FileRefType.Post,
468
483
  height: imagesToUpload[0]?.height || 0,
469
484
  width: imagesToUpload[0]?.width || 0,
485
+ size: imagesToUpload[0]?.fileSize || 0,
486
+ refType: 'Post' as FileRefType,
487
+ ref: postId,
470
488
  },
471
- ] as any,
489
+ ],
472
490
  totalCount: 1,
473
491
  },
474
492
  replies: {
@@ -499,6 +517,28 @@ const ConversationViewComponent = ({ channelId: initialChannelId, role, isShowTh
499
517
  const uploadedFiles = uploadResponse.data as unknown as IFileInfo[];
500
518
  const files = uploadedFiles?.map((f: any) => f.id) ?? null;
501
519
 
520
+ // Create a real version of the message with the actual file data
521
+ const realMessage = {
522
+ ...optimisticMessage,
523
+ files: {
524
+ __typename: 'FilesInfo' as const,
525
+ data: uploadedFiles.map((file) => ({
526
+ __typename: 'FileInfo' as const,
527
+ id: file.id,
528
+ url: file.url,
529
+ name: file.name,
530
+ extension: file.extension,
531
+ mimeType: file.mimeType,
532
+ height: file.height,
533
+ width: file.width,
534
+ size: file.size,
535
+ refType: file.refType,
536
+ ref: postId,
537
+ })),
538
+ totalCount: uploadedFiles.length,
539
+ },
540
+ };
541
+
502
542
  // Send the message with the uploaded files
503
543
  const response = await sendMsg({
504
544
  variables: {
@@ -510,16 +550,82 @@ const ConversationViewComponent = ({ channelId: initialChannelId, role, isShowTh
510
550
  },
511
551
  optimisticResponse: {
512
552
  __typename: 'Mutation',
513
- sendMessage: optimisticMessage,
553
+ sendMessage: realMessage, // Use the message with real file data
554
+ },
555
+ update: (cache, { data }) => {
556
+ if (data?.sendMessage) {
557
+ try {
558
+ // Read the existing messages from the cache
559
+ const existingData = cache.readQuery<{
560
+ messages: {
561
+ __typename: string;
562
+ messagesRefId?: string;
563
+ data: any[];
564
+ totalCount: number;
565
+ };
566
+ }>({
567
+ query: MessagesDocument,
568
+ variables: {
569
+ channelId: channelId?.toString(),
570
+ parentId: null,
571
+ limit: MESSAGES_PER_PAGE,
572
+ skip: 0,
573
+ },
574
+ });
575
+
576
+ // If we don't have data yet in the cache, don't try to update
577
+ if (!existingData) return;
578
+
579
+ // Ensure the message has files data
580
+ const messageWithFiles = {
581
+ ...data.sendMessage,
582
+ files: data.sendMessage.files || {
583
+ __typename: 'FilesInfo',
584
+ data: uploadedFiles.map((file) => ({
585
+ __typename: 'FileInfo',
586
+ id: file.id,
587
+ url: file.url,
588
+ name: file.name,
589
+ extension: file.extension,
590
+ mimeType: file.mimeType,
591
+ height: file.height,
592
+ width: file.width,
593
+ size: file.size,
594
+ refType: file.refType,
595
+ ref: postId,
596
+ })),
597
+ totalCount: uploadedFiles.length,
598
+ },
599
+ };
600
+
601
+ // Let the type policy handle the merging
602
+ cache.writeQuery({
603
+ query: MessagesDocument,
604
+ variables: {
605
+ channelId: channelId?.toString(),
606
+ parentId: null,
607
+ limit: MESSAGES_PER_PAGE,
608
+ skip: 0,
609
+ },
610
+ data: {
611
+ messages: {
612
+ ...existingData.messages,
613
+ data: [messageWithFiles, ...existingData.messages.data],
614
+ totalCount: (existingData.messages.totalCount || 0) + 1,
615
+ },
616
+ },
617
+ });
618
+
619
+ // Clear the images after successful send
620
+ setSelectedImage('');
621
+ setImages([]);
622
+ } catch (error) {
623
+ console.error('Error updating cache:', error);
624
+ }
625
+ }
514
626
  },
515
627
  });
516
628
 
517
- if (response?.data?.sendMessage) {
518
- // Clear the images after successful send
519
- setSelectedImage('');
520
- setImages([]);
521
- }
522
-
523
629
  setLoading(false);
524
630
  setUploadingMessageId(null);
525
631
  return { message: response.data?.sendMessage };
@@ -574,7 +680,7 @@ const ConversationViewComponent = ({ channelId: initialChannelId, role, isShowTh
574
680
  // Create unique message ID for optimistic response
575
681
  const messageId = objectId();
576
682
 
577
- // Fix the createDirectChannelImpl optimisticMessage with all required fields
683
+ // Create minimal optimistic message
578
684
  const optimisticMessage = {
579
685
  __typename: 'Post' as const,
580
686
  id: messageId,
@@ -584,26 +690,27 @@ const ConversationViewComponent = ({ channelId: initialChannelId, role, isShowTh
584
690
  author: {
585
691
  __typename: 'UserAccount' as const,
586
692
  id: auth?.id,
693
+ picture: auth?.picture || '',
587
694
  givenName: auth?.givenName || '',
588
695
  familyName: auth?.familyName || '',
589
- picture: auth?.picture || '',
590
- username: auth?.username || '',
591
696
  email: auth?.email || '',
697
+ username: auth?.username || '',
592
698
  alias: [] as string[],
593
699
  tokens: [],
594
700
  },
595
701
  isDelivered: true,
596
702
  isRead: false,
597
- type: 'TEXT' as any,
703
+ type: 'TEXT' as PostTypeEnum,
598
704
  parentId: null,
599
705
  fromServer: false,
600
706
  channel: {
601
707
  __typename: 'Channel' as const,
602
708
  id: newChannelId,
603
709
  },
710
+ // Required fields that Apollo expects in the cache
604
711
  propsConfiguration: {
605
712
  __typename: 'MachineConfiguration' as const,
606
- resource: '' as any, // Cast to any to bypass the URI type check
713
+ resource: '' as any,
607
714
  },
608
715
  props: {},
609
716
  files: {
@@ -629,6 +736,33 @@ const ConversationViewComponent = ({ channelId: initialChannelId, role, isShowTh
629
736
  __typename: 'Mutation',
630
737
  sendMessage: optimisticMessage,
631
738
  },
739
+ update: (cache, { data }) => {
740
+ if (data?.sendMessage) {
741
+ try {
742
+ // For a new channel, we don't need to read existing data
743
+ // Just write the new message to the cache
744
+ cache.writeQuery({
745
+ query: MessagesDocument,
746
+ variables: {
747
+ channelId: newChannelId,
748
+ parentId: null,
749
+ limit: MESSAGES_PER_PAGE,
750
+ skip: 0,
751
+ },
752
+ data: {
753
+ messages: {
754
+ __typename: 'Messages',
755
+ messagesRefId: newChannelId,
756
+ data: [data.sendMessage],
757
+ totalCount: 1,
758
+ },
759
+ },
760
+ });
761
+ } catch (error) {
762
+ console.error('Error updating cache:', error);
763
+ }
764
+ }
765
+ },
632
766
  });
633
767
 
634
768
  setLoading(false);
@@ -686,10 +820,16 @@ const ConversationViewComponent = ({ channelId: initialChannelId, role, isShowTh
686
820
 
687
821
  // Extract image URL from files data
688
822
  let imageUrl = null;
689
- if (msg.files?.data && msg.files.data.length > 0) {
690
- const fileData = msg.files.data[0];
691
- if (fileData && fileData.url) {
692
- imageUrl = fileData.url;
823
+ if (msg.files && typeof msg.files === 'object') {
824
+ // Handle both cases where files might be directly present or via files.data
825
+ const filesData = msg.files.data || (Array.isArray(msg.files) ? msg.files : null);
826
+
827
+ if (filesData && filesData.length > 0) {
828
+ const fileData = filesData[0];
829
+ // Make sure we have valid file data with a URL
830
+ if (fileData && typeof fileData === 'object' && fileData.url) {
831
+ imageUrl = fileData.url;
832
+ }
693
833
  }
694
834
  }
695
835
 
@@ -1279,41 +1419,7 @@ const ConversationViewComponent = ({ channelId: initialChannelId, role, isShowTh
1279
1419
  variables: {
1280
1420
  channelId: channelId?.toString(),
1281
1421
  },
1282
- // updateQuery: (prev, { subscriptionData }: any) => {
1283
- // try {
1284
- // // Check if we have valid subscription data
1285
- // if (!subscriptionData?.data?.chatMessageAdded) {
1286
- // return prev;
1287
- // }
1288
-
1289
- // const newMessage = subscriptionData.data.chatMessageAdded;
1290
-
1291
- // // Check if message is from current user - skip update as it's handled by optimistic UI
1292
- // if (newMessage.author?.id === auth?.id) {
1293
- // return prev;
1294
- // }
1295
-
1296
- // // Check if we already have this message to avoid duplicates
1297
- // const currentMessages = prev?.messages?.data || [];
1298
- // if (currentMessages.some((msg) => msg.id === newMessage.id)) {
1299
- // return prev;
1300
- // }
1301
-
1302
- // // Update Apollo cache
1303
- // const updatedData = {
1304
- // ...prev,
1305
- // messages: {
1306
- // ...prev.messages,
1307
- // data: [newMessage, ...currentMessages],
1308
- // totalCount: (prev?.messages?.totalCount || 0) + 1,
1309
- // },
1310
- // };
1311
-
1312
- // return updatedData;
1313
- // } catch (error) {
1314
- // return prev;
1315
- // }
1316
- // },
1422
+ // Let type policy handle the merge
1317
1423
  })
1318
1424
  }
1319
1425
  />
@@ -1347,6 +1453,29 @@ const ConversationViewComponent = ({ channelId: initialChannelId, role, isShowTh
1347
1453
  [onEndReached, onMomentumScrollBegin],
1348
1454
  );
1349
1455
 
1456
+ // Debug helper function to inspect files in messages
1457
+ const debugFileData = useCallback((message: any, prefix: string = 'Message') => {
1458
+ if (__DEV__) {
1459
+ console.log(
1460
+ `${prefix} ID: ${message?.id}, ` +
1461
+ `Has files object: ${!!message?.files}, ` +
1462
+ `Files typename: ${message?.files?.__typename}, ` +
1463
+ `Files data exists: ${!!message?.files?.data}, ` +
1464
+ `Files count: ${message?.files?.data?.length || 0}`,
1465
+ );
1466
+
1467
+ if (message?.files?.data && message?.files?.data?.length > 0) {
1468
+ const file = message?.files?.data[0];
1469
+ console.log(
1470
+ `File[0] ID: ${file?.id}, ` +
1471
+ `URL: ${file?.url?.substring(0, 30)}..., ` +
1472
+ `Name: ${file?.name}, ` +
1473
+ `Type: ${file?.mimeType}`,
1474
+ );
1475
+ }
1476
+ }
1477
+ }, []);
1478
+
1350
1479
  // Return optimized component with performance improvements
1351
1480
  return (
1352
1481
  <View