@droppii-org/chat-mobile 0.2.14 → 0.2.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/lib/module/components/ThreadCard/ThreadCard.js +2 -1
  2. package/lib/module/components/ThreadCard/ThreadCard.js.map +1 -1
  3. package/lib/module/components/messages/imageMessage/index.js.map +1 -1
  4. package/lib/module/hooks/useImageAttachment.js +34 -63
  5. package/lib/module/hooks/useImageAttachment.js.map +1 -1
  6. package/lib/module/hooks/useLinkPreview/useFetchUrlMetadata.js +3 -2
  7. package/lib/module/hooks/useLinkPreview/useFetchUrlMetadata.js.map +1 -1
  8. package/lib/module/index.js +1 -1
  9. package/lib/module/index.js.map +1 -1
  10. package/lib/module/screens/MediaView/index.js +1 -1
  11. package/lib/module/screens/chat-detail/ChatComposer.js +10 -3
  12. package/lib/module/screens/chat-detail/ChatComposer.js.map +1 -1
  13. package/lib/module/screens/chat-detail/hooks/useAttachmentSendHandler.js +66 -25
  14. package/lib/module/screens/chat-detail/hooks/useAttachmentSendHandler.js.map +1 -1
  15. package/lib/module/services/attachmentHandlers/imageAttachmentHandler.js +6 -3
  16. package/lib/module/services/attachmentHandlers/imageAttachmentHandler.js.map +1 -1
  17. package/lib/module/services/auth.js +69 -0
  18. package/lib/module/services/auth.js.map +1 -1
  19. package/lib/module/services/imageUpload.js +84 -58
  20. package/lib/module/services/imageUpload.js.map +1 -1
  21. package/lib/module/utils/chatImageDimens.js +18 -1
  22. package/lib/module/utils/chatImageDimens.js.map +1 -1
  23. package/lib/module/utils/dateTimeUtils.js +44 -0
  24. package/lib/module/utils/dateTimeUtils.js.map +1 -0
  25. package/lib/module/utils/device.js +2 -1
  26. package/lib/module/utils/device.js.map +1 -1
  27. package/lib/module/utils/imageUtils.js +4 -2
  28. package/lib/module/utils/imageUtils.js.map +1 -1
  29. package/lib/module/{components/ThreadCard/thread-card.utils.js → utils/messageUtils.js} +18 -42
  30. package/lib/module/utils/messageUtils.js.map +1 -0
  31. package/lib/module/utils/videoThumbnail.js +11 -5
  32. package/lib/module/utils/videoThumbnail.js.map +1 -1
  33. package/lib/typescript/src/components/ThreadCard/ThreadCard.d.ts.map +1 -1
  34. package/lib/typescript/src/components/messages/imageMessage/index.d.ts.map +1 -1
  35. package/lib/typescript/src/hooks/useImageAttachment.d.ts.map +1 -1
  36. package/lib/typescript/src/hooks/useLinkPreview/useFetchUrlMetadata.d.ts.map +1 -1
  37. package/lib/typescript/src/index.d.ts +1 -1
  38. package/lib/typescript/src/index.d.ts.map +1 -1
  39. package/lib/typescript/src/screens/chat-detail/ChatComposer.d.ts.map +1 -1
  40. package/lib/typescript/src/screens/chat-detail/hooks/useAttachmentSendHandler.d.ts.map +1 -1
  41. package/lib/typescript/src/services/attachmentHandlers/imageAttachmentHandler.d.ts.map +1 -1
  42. package/lib/typescript/src/services/auth.d.ts +32 -0
  43. package/lib/typescript/src/services/auth.d.ts.map +1 -1
  44. package/lib/typescript/src/services/imageUpload.d.ts.map +1 -1
  45. package/lib/typescript/src/utils/chatImageDimens.d.ts +1 -0
  46. package/lib/typescript/src/utils/chatImageDimens.d.ts.map +1 -1
  47. package/lib/typescript/src/utils/dateTimeUtils.d.ts +6 -0
  48. package/lib/typescript/src/utils/dateTimeUtils.d.ts.map +1 -0
  49. package/lib/typescript/src/utils/device.d.ts.map +1 -1
  50. package/lib/typescript/src/utils/imageUtils.d.ts.map +1 -1
  51. package/lib/typescript/src/utils/messageUtils.d.ts +8 -0
  52. package/lib/typescript/src/utils/messageUtils.d.ts.map +1 -0
  53. package/lib/typescript/src/utils/videoThumbnail.d.ts +1 -0
  54. package/lib/typescript/src/utils/videoThumbnail.d.ts.map +1 -1
  55. package/package.json +3 -3
  56. package/src/components/ThreadCard/ThreadCard.tsx +2 -1
  57. package/src/components/messages/imageMessage/index.tsx +0 -1
  58. package/src/hooks/useImageAttachment.ts +45 -70
  59. package/src/hooks/useLinkPreview/useFetchUrlMetadata.ts +3 -2
  60. package/src/index.tsx +8 -1
  61. package/src/screens/MediaView/index.tsx +1 -1
  62. package/src/screens/chat-detail/ChatComposer.tsx +9 -3
  63. package/src/screens/chat-detail/hooks/useAttachmentSendHandler.ts +81 -25
  64. package/src/services/attachmentHandlers/imageAttachmentHandler.ts +11 -1
  65. package/src/services/auth.ts +77 -0
  66. package/src/services/imageUpload.ts +116 -73
  67. package/src/utils/chatImageDimens.ts +21 -1
  68. package/src/utils/dateTimeUtils.ts +48 -0
  69. package/src/utils/device.ts +1 -0
  70. package/src/utils/imageUtils.ts +10 -2
  71. package/src/{components/ThreadCard/thread-card.utils.ts → utils/messageUtils.ts} +18 -56
  72. package/src/utils/videoThumbnail.ts +14 -3
  73. package/lib/module/components/ThreadCard/thread-card.utils.js.map +0 -1
  74. package/lib/typescript/src/components/ThreadCard/thread-card.utils.d.ts +0 -4
  75. package/lib/typescript/src/components/ThreadCard/thread-card.utils.d.ts.map +0 -1
@@ -1,8 +1,13 @@
1
1
  "use strict";
2
2
 
3
+ /**
4
+ * Message formatting and preview utilities
5
+ */
6
+
3
7
  import { MessageType } from '@droppii/openim-rn-client-sdk';
4
- import { DChatMessageType } from "../../types/message.js";
5
- const extractTextContent = message => {
8
+ import { DChatMessageType } from "../types/message.js";
9
+ import { formatDuration } from "./dateTimeUtils.js";
10
+ export const extractTextContent = message => {
6
11
  if (message.textElem?.content) return message.textElem.content;
7
12
  try {
8
13
  const parsed = JSON.parse(message.content);
@@ -11,12 +16,7 @@ const extractTextContent = message => {
11
16
  return message.content ?? '';
12
17
  }
13
18
  };
14
- const formatDuration = seconds => {
15
- const mins = Math.floor(seconds / 60);
16
- const secs = seconds % 60;
17
- return `${mins}:${secs.toString().padStart(2, '0')}`;
18
- };
19
- const getMessagePreview = message => {
19
+ export const getMessagePreview = message => {
20
20
  // Check custom message type first
21
21
  if (message.contentType === MessageType.CustomMessage) {
22
22
  try {
@@ -43,8 +43,8 @@ const getMessagePreview = message => {
43
43
  return '[Hình ảnh]';
44
44
  case MessageType.VideoMessage:
45
45
  try {
46
- const videoData = JSON.parse(message.content);
47
- const duration = videoData.duration || 0;
46
+ const videoData = message?.videoElem;
47
+ const duration = videoData?.duration || 0;
48
48
  const durationStr = duration > 0 ? ` ${formatDuration(duration)}` : '';
49
49
  return `[Video]${durationStr}`;
50
50
  } catch {
@@ -65,7 +65,7 @@ const getMessagePreview = message => {
65
65
  if (mergeData?.multiMessage) {
66
66
  const imageCount = mergeData.multiMessage.filter(msg => msg.contentType === MessageType.PictureMessage).length;
67
67
  if (imageCount > 0) {
68
- return `${imageCount} [Hình ảnh]`;
68
+ return '[Hình ảnh]';
69
69
  }
70
70
  }
71
71
  } catch {
@@ -89,39 +89,15 @@ export const getLastMessageText = (message, currentUserId) => {
89
89
  const preview = getMessagePreview(message);
90
90
  if (!preview) return '';
91
91
 
92
- // Add sender name
92
+ // Add sender name for outgoing messages
93
93
  if (currentUserId && message.sendID === currentUserId) {
94
94
  return `Bạn: ${preview}`;
95
95
  }
96
- return preview;
97
- };
98
- export const formatTimestamp = ts => {
99
- if (!ts) return '';
100
- try {
101
- const date = new Date(ts);
102
- if (isNaN(date.getTime())) return '';
103
- const now = new Date();
104
- const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
105
- const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000);
106
- const dateOnly = new Date(date.getFullYear(), date.getMonth(), date.getDate());
107
- if (dateOnly.getTime() === today.getTime()) {
108
- const h = date.getHours().toString().padStart(2, '0');
109
- const m = date.getMinutes().toString().padStart(2, '0');
110
- return `${h}:${m}`;
111
- }
112
- if (dateOnly.getTime() === yesterday.getTime()) {
113
- return 'Hôm qua';
114
- }
115
- const daysAgo = Math.floor((today.getTime() - dateOnly.getTime()) / (24 * 60 * 60 * 1000));
116
- if (daysAgo > 0 && daysAgo < 7) {
117
- const dayNames = ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'];
118
- return dayNames[date.getDay()] ?? '';
119
- }
120
- const d = date.getDate().toString().padStart(2, '0');
121
- const mo = (date.getMonth() + 1).toString().padStart(2, '0');
122
- return `${d}/${mo}`;
123
- } catch {
124
- return '';
96
+
97
+ // Add sender nickname for incoming messages
98
+ if (message.senderNickname) {
99
+ return `${message.senderNickname}: ${preview}`;
125
100
  }
101
+ return preview;
126
102
  };
127
- //# sourceMappingURL=thread-card.utils.js.map
103
+ //# sourceMappingURL=messageUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["MessageType","DChatMessageType","formatDuration","extractTextContent","message","textElem","content","parsed","JSON","parse","getMessagePreview","contentType","CustomMessage","data","dataType","type","Link","linkText","title","Order","orderCode","code","TextMessage","PictureMessage","VideoMessage","videoData","videoElem","duration","durationStr","FileMessage","fileData","fileName","name","MergeMessage","mergeData","mergeElem","multiMessage","imageCount","filter","msg","length","UrlTextMessage","urlText","urlTextElem","urls","console","log","AtTextMessage","QuoteMessage","getLastMessageText","currentUserId","preview","sendID","senderNickname"],"sourceRoot":"../../../src","sources":["utils/messageUtils.ts"],"mappings":"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","ignoreList":[]}
@@ -5,22 +5,28 @@ import { createThumbnail } from 'react-native-create-thumbnail';
5
5
  export const VideoThumbnailUtil = {
6
6
  generateThumbnail: async (videoPath, options = {}) => {
7
7
  const {
8
- time = 1000,
9
- quality = 80
8
+ time = 800,
9
+ quality = 80,
10
+ cacheId
10
11
  } = options; // time in milliseconds
11
12
 
12
13
  try {
14
+ // Generate unique cache name per video to avoid conflicts with concurrent generations
15
+ // Uses provided cacheId or generates one from videoPath filename
16
+ const fileName = videoPath.split('/').pop() || String(Date.now());
17
+ const cacheName = cacheId || `thumb-${fileName.replace(/[^a-zA-Z0-9-_]/g, '')}-${Math.abs(fileName.charCodeAt(0) + fileName.charCodeAt(fileName.length - 1))}`;
13
18
  console.log('[VideoThumbnail] Generating thumbnail', {
14
19
  videoPath,
15
20
  timeMs: time,
16
- quality
21
+ quality,
22
+ cacheName
17
23
  });
18
24
  const result = await createThumbnail({
19
25
  url: videoPath,
20
26
  timeStamp: time,
21
- format: 'jpeg',
27
+ format: 'png',
22
28
  dirSize: 100,
23
- cacheName: 'video-thumbnails'
29
+ cacheName
24
30
  });
25
31
  console.log('✅ [VideoThumbnail] THUMBNAIL PATH:', result.path);
26
32
  console.log('[VideoThumbnail] Thumbnail generated', {
@@ -1 +1 @@
1
- {"version":3,"names":["RNFS","createThumbnail","VideoThumbnailUtil","generateThumbnail","videoPath","options","time","quality","console","log","timeMs","result","url","timeStamp","format","dirSize","cacheName","path","width","height","error","cleanupThumbnail","thumbnailPath","unlink","err","warn","batchGenerateThumbnails","videoPaths","results","thumbnail","push"],"sourceRoot":"../../../src","sources":["utils/videoThumbnail.ts"],"mappings":";;AAAA,OAAOA,IAAI,MAAM,iBAAiB;AAClC,SAASC,eAAe,QAAQ,+BAA+B;AAa/D,OAAO,MAAMC,kBAAkB,GAAG;EAChCC,iBAAiB,EAAE,MAAAA,CACjBC,SAAiB,EACjBC,OAAyB,GAAG,CAAC,CAAC,KACM;IACpC,MAAM;MAAEC,IAAI,GAAG,IAAI;MAAEC,OAAO,GAAG;IAAG,CAAC,GAAGF,OAAO,CAAC,CAAC;;IAE/C,IAAI;MACFG,OAAO,CAACC,GAAG,CAAC,uCAAuC,EAAE;QACnDL,SAAS;QACTM,MAAM,EAAEJ,IAAI;QACZC;MACF,CAAC,CAAC;MAEF,MAAMI,MAAM,GAAG,MAAMV,eAAe,CAAC;QACnCW,GAAG,EAAER,SAAS;QACdS,SAAS,EAAEP,IAAI;QACfQ,MAAM,EAAE,MAAM;QACdC,OAAO,EAAE,GAAG;QACZC,SAAS,EAAE;MACb,CAAC,CAAC;MAEFR,OAAO,CAACC,GAAG,CAAC,oCAAoC,EAAEE,MAAM,CAACM,IAAI,CAAC;MAC9DT,OAAO,CAACC,GAAG,CAAC,sCAAsC,EAAE;QAClDQ,IAAI,EAAEN,MAAM,CAACM,IAAI;QACjBC,KAAK,EAAEP,MAAM,CAACO,KAAK,IAAI,CAAC;QACxBC,MAAM,EAAER,MAAM,CAACQ,MAAM,IAAI;MAC3B,CAAC,CAAC;MAEF,OAAO;QACLF,IAAI,EAAEN,MAAM,CAACM,IAAI;QACjBC,KAAK,EAAEP,MAAM,CAACO,KAAK,IAAI,CAAC;QACxBC,MAAM,EAAER,MAAM,CAACQ,MAAM,IAAI;MAC3B,CAAC;IACH,CAAC,CAAC,OAAOC,KAAK,EAAE;MACdZ,OAAO,CAACY,KAAK,CAAC,+CAA+C,EAAEA,KAAK,CAAC;MACrE,OAAO,IAAI;IACb;EACF,CAAC;EAEDC,gBAAgB,EAAE,MAAOC,aAAqB,IAAoB;IAChE,IAAI;MACF,IAAI,CAACA,aAAa,EAAE;MACpB,MAAMtB,IAAI,CAACuB,MAAM,CAACD,aAAa,CAAC;MAChCd,OAAO,CAACC,GAAG,CAAC,8BAA8B,EAAEa,aAAa,CAAC;IAC5D,CAAC,CAAC,OAAOE,GAAG,EAAE;MACZhB,OAAO,CAACiB,IAAI,CAAC,kCAAkC,EAAED,GAAG,CAAC;IACvD;EACF,CAAC;EAEDE,uBAAuB,EAAE,MAAAA,CACvBC,UAAoB,EACpBtB,OAAyB,GAAG,CAAC,CAAC,KACC;IAC/B,MAAMuB,OAA0B,GAAG,EAAE;IAErC,KAAK,MAAMxB,SAAS,IAAIuB,UAAU,EAAE;MAClC,MAAME,SAAS,GAAG,MAAM3B,kBAAkB,CAACC,iBAAiB,CAC1DC,SAAS,EACTC,OACF,CAAC;MACD,IAAIwB,SAAS,EAAE;QACbD,OAAO,CAACE,IAAI,CAACD,SAAS,CAAC;MACzB;IACF;IAEA,OAAOD,OAAO;EAChB;AACF,CAAC;AAED,eAAe1B,kBAAkB","ignoreList":[]}
1
+ {"version":3,"names":["RNFS","createThumbnail","VideoThumbnailUtil","generateThumbnail","videoPath","options","time","quality","cacheId","fileName","split","pop","String","Date","now","cacheName","replace","Math","abs","charCodeAt","length","console","log","timeMs","result","url","timeStamp","format","dirSize","path","width","height","error","cleanupThumbnail","thumbnailPath","unlink","err","warn","batchGenerateThumbnails","videoPaths","results","thumbnail","push"],"sourceRoot":"../../../src","sources":["utils/videoThumbnail.ts"],"mappings":";;AAAA,OAAOA,IAAI,MAAM,iBAAiB;AAClC,SAASC,eAAe,QAAQ,+BAA+B;AAc/D,OAAO,MAAMC,kBAAkB,GAAG;EAChCC,iBAAiB,EAAE,MAAAA,CACjBC,SAAiB,EACjBC,OAAyB,GAAG,CAAC,CAAC,KACM;IACpC,MAAM;MAAEC,IAAI,GAAG,GAAG;MAAEC,OAAO,GAAG,EAAE;MAAEC;IAAQ,CAAC,GAAGH,OAAO,CAAC,CAAC;;IAEvD,IAAI;MACF;MACA;MACA,MAAMI,QAAQ,GAAGL,SAAS,CAACM,KAAK,CAAC,GAAG,CAAC,CAACC,GAAG,CAAC,CAAC,IAAIC,MAAM,CAACC,IAAI,CAACC,GAAG,CAAC,CAAC,CAAC;MACjE,MAAMC,SAAS,GACbP,OAAO,IACP,SAASC,QAAQ,CAACO,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,IAAIC,IAAI,CAACC,GAAG,CAC1DT,QAAQ,CAACU,UAAU,CAAC,CAAC,CAAC,GAAGV,QAAQ,CAACU,UAAU,CAACV,QAAQ,CAACW,MAAM,GAAG,CAAC,CAClE,CAAC,EAAE;MAELC,OAAO,CAACC,GAAG,CAAC,uCAAuC,EAAE;QACnDlB,SAAS;QACTmB,MAAM,EAAEjB,IAAI;QACZC,OAAO;QACPQ;MACF,CAAC,CAAC;MAEF,MAAMS,MAAM,GAAG,MAAMvB,eAAe,CAAC;QACnCwB,GAAG,EAAErB,SAAS;QACdsB,SAAS,EAAEpB,IAAI;QACfqB,MAAM,EAAE,KAAK;QACbC,OAAO,EAAE,GAAG;QACZb;MACF,CAAC,CAAC;MAEFM,OAAO,CAACC,GAAG,CAAC,oCAAoC,EAAEE,MAAM,CAACK,IAAI,CAAC;MAC9DR,OAAO,CAACC,GAAG,CAAC,sCAAsC,EAAE;QAClDO,IAAI,EAAEL,MAAM,CAACK,IAAI;QACjBC,KAAK,EAAEN,MAAM,CAACM,KAAK,IAAI,CAAC;QACxBC,MAAM,EAAEP,MAAM,CAACO,MAAM,IAAI;MAC3B,CAAC,CAAC;MAEF,OAAO;QACLF,IAAI,EAAEL,MAAM,CAACK,IAAI;QACjBC,KAAK,EAAEN,MAAM,CAACM,KAAK,IAAI,CAAC;QACxBC,MAAM,EAAEP,MAAM,CAACO,MAAM,IAAI;MAC3B,CAAC;IACH,CAAC,CAAC,OAAOC,KAAK,EAAE;MACdX,OAAO,CAACW,KAAK,CAAC,+CAA+C,EAAEA,KAAK,CAAC;MACrE,OAAO,IAAI;IACb;EACF,CAAC;EAEDC,gBAAgB,EAAE,MAAOC,aAAqB,IAAoB;IAChE,IAAI;MACF,IAAI,CAACA,aAAa,EAAE;MACpB,MAAMlC,IAAI,CAACmC,MAAM,CAACD,aAAa,CAAC;MAChCb,OAAO,CAACC,GAAG,CAAC,8BAA8B,EAAEY,aAAa,CAAC;IAC5D,CAAC,CAAC,OAAOE,GAAG,EAAE;MACZf,OAAO,CAACgB,IAAI,CAAC,kCAAkC,EAAED,GAAG,CAAC;IACvD;EACF,CAAC;EAEDE,uBAAuB,EAAE,MAAAA,CACvBC,UAAoB,EACpBlC,OAAyB,GAAG,CAAC,CAAC,KACC;IAC/B,MAAMmC,OAA0B,GAAG,EAAE;IAErC,KAAK,MAAMpC,SAAS,IAAImC,UAAU,EAAE;MAClC,MAAME,SAAS,GAAG,MAAMvC,kBAAkB,CAACC,iBAAiB,CAC1DC,SAAS,EACTC,OACF,CAAC;MACD,IAAIoC,SAAS,EAAE;QACbD,OAAO,CAACE,IAAI,CAACD,SAAS,CAAC;MACzB;IACF;IAEA,OAAOD,OAAO;EAChB;AACF,CAAC;AAED,eAAetC,kBAAkB","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"ThreadCard.d.ts","sourceRoot":"","sources":["../../../../../src/components/ThreadCard/ThreadCard.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAQ1D,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,qBAAqB,CAAA;KAAE,KAAK,IAAI,CAAC;CAC5E;AAED,QAAA,MAAM,UAAU,0DAA4B,eAAe,iCAgHzD,CAAC;AAIH,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"ThreadCard.d.ts","sourceRoot":"","sources":["../../../../../src/components/ThreadCard/ThreadCard.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAS1D,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,qBAAqB,CAAA;KAAE,KAAK,IAAI,CAAC;CAC5E;AAED,QAAA,MAAM,UAAU,0DAA4B,eAAe,iCAgHzD,CAAC;AAIH,eAAe,UAAU,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/components/messages/imageMessage/index.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAEvD,eAAO,MAAM,YAAY,kEACK,sBAAsB,iCAyGnD,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/components/messages/imageMessage/index.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAEvD,eAAO,MAAM,YAAY,kEACK,sBAAsB,iCAwGnD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useImageAttachment.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useImageAttachment.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,IAAI,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAQ3E,UAAU,qBAAqB;IAC7B,KAAK,EAAE,WAAW,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,wBAAwB;IACvC,cAAc,EAAE,qBAAqB,EAAE,CAAC;IACxC,qBAAqB,EAAE,OAAO,CAAC;IAC/B,iBAAiB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,cAAc,EAAE,MAAM,IAAI,CAAC;CAC5B;AAED,eAAO,MAAM,kBAAkB,QAAO,wBA+TrC,CAAC"}
1
+ {"version":3,"file":"useImageAttachment.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useImageAttachment.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,IAAI,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAQ3E,UAAU,qBAAqB;IAC7B,KAAK,EAAE,WAAW,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,wBAAwB;IACvC,cAAc,EAAE,qBAAqB,EAAE,CAAC;IACxC,qBAAqB,EAAE,OAAO,CAAC;IAC/B,iBAAiB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,cAAc,EAAE,MAAM,IAAI,CAAC;CAC5B;AAED,eAAO,MAAM,kBAAkB,QAAO,wBAuSrC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useFetchUrlMetadata.d.ts","sourceRoot":"","sources":["../../../../../src/hooks/useLinkPreview/useFetchUrlMetadata.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,mBAAmB,GAAI,MAAM,MAAM;;;;;UAc5C,CAAC"}
1
+ {"version":3,"file":"useFetchUrlMetadata.d.ts","sourceRoot":"","sources":["../../../../../src/hooks/useLinkPreview/useFetchUrlMetadata.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,mBAAmB,GAAI,MAAM,MAAM;;;;;UAc5C,CAAC"}
@@ -1,5 +1,5 @@
1
1
  export { ChatAPI } from './services';
2
- export { setAuthToken, getAuthToken, clearAuthToken } from './services/auth';
2
+ export { setAuthToken, getAuthToken, clearAuthToken, setTokenRefreshCallback, setTokenRefreshFailedCallback, refreshAuthToken, } from './services/auth';
3
3
  export { initBaseUrl, getBaseUrl } from './config/configuration';
4
4
  export { Config } from './config';
5
5
  export * from './core';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,YAAY,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAC;AAC7E,OAAO,EAAE,6BAA6B,EAAE,MAAM,mCAAmC,CAAC;AAClF,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,eAAe,EACf,uBAAuB,EACvB,gBAAgB,EAChB,qBAAqB,EACrB,eAAe,EACf,qBAAqB,EACrB,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,4BAA4B,EAC5B,wBAAwB,GACzB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EACL,4BAA4B,EAC5B,6BAA6B,GAC9B,MAAM,2BAA2B,CAAC;AACnC,YAAY,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,uBAAuB,EACvB,6BAA6B,EAC7B,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,YAAY,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAC;AAC7E,OAAO,EAAE,6BAA6B,EAAE,MAAM,mCAAmC,CAAC;AAClF,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,eAAe,EACf,uBAAuB,EACvB,gBAAgB,EAChB,qBAAqB,EACrB,eAAe,EACf,qBAAqB,EACrB,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,4BAA4B,EAC5B,wBAAwB,GACzB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EACL,4BAA4B,EAC5B,6BAA6B,GAC9B,MAAM,2BAA2B,CAAC;AACnC,YAAY,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ChatComposer.d.ts","sourceRoot":"","sources":["../../../../../src/screens/chat-detail/ChatComposer.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAajD,eAAO,MAAM,YAAY,+TAkBpB,iBAAiB,iCA2VrB,CAAC"}
1
+ {"version":3,"file":"ChatComposer.d.ts","sourceRoot":"","sources":["../../../../../src/screens/chat-detail/ChatComposer.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAajD,eAAO,MAAM,YAAY,+TAkBpB,iBAAiB,iCAgWrB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useAttachmentSendHandler.d.ts","sourceRoot":"","sources":["../../../../../../src/screens/chat-detail/hooks/useAttachmentSendHandler.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,UAAU,cAAc;IACtB,KAAK,EAAE,GAAG,CAAC;IACX,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,UAAU,6BAA6B;IACrC,cAAc,EAAE,cAAc,EAAE,CAAC;IACjC,eAAe,EAAE,CACf,KAAK,EAAE,GAAG,EAAE,EACZ,CAAC,EAAE,GAAG,EACN,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,KAC5C,OAAO,CAAC,OAAO,CAAC,CAAC;IACtB,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,GAAG,CAAC;IAClB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;CACxD;AAED,eAAO,MAAM,wBAAwB,GAAI,mHAStC,6BAA6B;;CA0P/B,CAAC"}
1
+ {"version":3,"file":"useAttachmentSendHandler.d.ts","sourceRoot":"","sources":["../../../../../../src/screens/chat-detail/hooks/useAttachmentSendHandler.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,UAAU,cAAc;IACtB,KAAK,EAAE,GAAG,CAAC;IACX,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,UAAU,6BAA6B;IACrC,cAAc,EAAE,cAAc,EAAE,CAAC;IACjC,eAAe,EAAE,CACf,KAAK,EAAE,GAAG,EAAE,EACZ,CAAC,EAAE,GAAG,EACN,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,KAC5C,OAAO,CAAC,OAAO,CAAC,CAAC;IACtB,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,GAAG,CAAC;IAClB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;CACxD;AAED,eAAO,MAAM,wBAAwB,GAAI,mHAStC,6BAA6B;;CAkT/B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"imageAttachmentHandler.d.ts","sourceRoot":"","sources":["../../../../../src/services/attachmentHandlers/imageAttachmentHandler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAGxE,eAAO,MAAM,sBAAsB,EAAE,kBAiDpC,CAAC"}
1
+ {"version":3,"file":"imageAttachmentHandler.d.ts","sourceRoot":"","sources":["../../../../../src/services/attachmentHandlers/imageAttachmentHandler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAGxE,eAAO,MAAM,sBAAsB,EAAE,kBA2DpC,CAAC"}
@@ -12,6 +12,38 @@ export declare const setAuthToken: (token: string) => void;
12
12
  * @throws Error if token not set
13
13
  */
14
14
  export declare const getAuthToken: () => string;
15
+ /**
16
+ * Set callback for token refresh when 401 Unauthorized occurs
17
+ * Callback should refresh token from server and return the new token
18
+ * Example:
19
+ * setTokenRefreshCallback(async () => {
20
+ * const newToken = await api.post('/auth/refresh');
21
+ * return newToken;
22
+ * });
23
+ */
24
+ export declare const setTokenRefreshCallback: (callback: () => Promise<string>) => void;
25
+ /**
26
+ * Set callback when token refresh fails
27
+ * Called when token refresh throws error or returns invalid token
28
+ * Use this to redirect to login, show error message, etc.
29
+ * Example:
30
+ * setTokenRefreshFailedCallback(() => {
31
+ * navigation.navigate('Login');
32
+ * showToast('Your session expired. Please login again.');
33
+ * });
34
+ */
35
+ export declare const setTokenRefreshFailedCallback: (callback: () => void) => void;
36
+ /**
37
+ * Refresh auth token when 401 Unauthorized occurs
38
+ * Calls the refresh callback and updates the stored token
39
+ * If refresh fails:
40
+ * 1. Clears the invalid token
41
+ * 2. Calls tokenRefreshFailedCallback (if set) to notify app
42
+ * 3. Throws error
43
+ * @returns new auth token
44
+ * @throws Error if callback not set or refresh fails
45
+ */
46
+ export declare const refreshAuthToken: () => Promise<string>;
15
47
  /**
16
48
  * Clear token (logout)
17
49
  */
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../../src/services/auth.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;GAEG;AACH,eAAO,MAAM,YAAY,GAAI,OAAO,MAAM,SAEzC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,YAAY,QAAO,MAO/B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,cAAc,YAE1B,CAAC"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../../src/services/auth.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH;;GAEG;AACH,eAAO,MAAM,YAAY,GAAI,OAAO,MAAM,SAEzC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,YAAY,QAAO,MAO/B,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,uBAAuB,GAClC,UAAU,MAAM,OAAO,CAAC,MAAM,CAAC,KAC9B,IAEF,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,6BAA6B,GAAI,UAAU,MAAM,IAAI,KAAG,IAEpE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,QAAa,OAAO,CAAC,MAAM,CAiCvD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,cAAc,YAG1B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"imageUpload.d.ts","sourceRoot":"","sources":["../../../../src/services/imageUpload.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,SAAS,EACT,aAAa,EACb,iBAAiB,EAClB,MAAM,sBAAsB,CAAC;AAE9B,yBAAiB,cAAc,CAAC;IACvB,MAAM,eAAe,GAC1B,MAAM,SAAS,EACf,aAAa,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,KACtC,OAAO,CAAC,aAAa,CA6FvB,CAAC;IAEK,MAAM,gBAAgB,GAC3B,OAAO,SAAS,EAAE,EAClB,SAAQ,iBAAsB,EAC9B,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,KACtD,OAAO,CAAC,aAAa,EAAE,CAqCzB,CAAC;IAEK,MAAM,gBAAgB,GAAU,UAAU,MAAM,KAAG,OAAO,CAAC,IAAI,CAMrE,CAAC;CACH"}
1
+ {"version":3,"file":"imageUpload.d.ts","sourceRoot":"","sources":["../../../../src/services/imageUpload.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,SAAS,EACT,aAAa,EACb,iBAAiB,EAClB,MAAM,sBAAsB,CAAC;AAE9B,yBAAiB,cAAc,CAAC;IAqDvB,MAAM,eAAe,GAC1B,MAAM,SAAS,EACf,aAAa,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,KACtC,OAAO,CAAC,aAAa,CAoFvB,CAAC;IAEK,MAAM,gBAAgB,GAC3B,OAAO,SAAS,EAAE,EAClB,SAAQ,iBAAsB,EAC9B,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,KACtD,OAAO,CAAC,aAAa,EAAE,CAqCzB,CAAC;IAEK,MAAM,gBAAgB,GAAU,UAAU,MAAM,KAAG,OAAO,CAAC,IAAI,CAMrE,CAAC;CACH"}
@@ -27,6 +27,7 @@ declare class ChatImageDimens {
27
27
  /**
28
28
  * Get optimized image URL with custom dimensions (generic approach)
29
29
  * Useful for dynamic sizing based on actual content
30
+ * Automatically applies pixel ratio for high-DPI displays
30
31
  */
31
32
  static getOptimizedImageUrlWithDimensions(url: string | undefined, width: number, height: number): string;
32
33
  }
@@ -1 +1 @@
1
- {"version":3,"file":"chatImageDimens.d.ts","sourceRoot":"","sources":["../../../../src/utils/chatImageDimens.ts"],"names":[],"mappings":"AAGA;;;GAGG;AAEH,oBAAY,sBAAsB;IAChC,oBAAoB,yBAAyB;IAC7C,mBAAmB,wBAAwB;IAC3C,iBAAiB,sBAAsB;IACvC,kBAAkB,uBAAuB;IACzC,iBAAiB,sBAAsB;CACxC;AAED,UAAU,cAAc;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAsDD,cAAM,eAAe;IACnB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAkB;IACzC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAa;IAClC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAuC;IAC9D,OAAO,CAAC,MAAM,CAAC,MAAM,CAE4B;gBAErC,MAAM,EAAE,MAAM;IAK1B,OAAO,CAAC,mBAAmB;WAeb,WAAW;WAOX,YAAY,CAAC,MAAM,EAAE,MAAM;WAO3B,aAAa,CAAC,MAAM,EAAE,sBAAsB,GAAG,cAAc;WAO7D,oBAAoB,CAChC,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,MAAM,EAAE,sBAAsB,GAC7B,MAAM;IAaT;;;OAGG;WACW,kCAAkC,CAC9C,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,MAAM;CA6BV;AAED,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"chatImageDimens.d.ts","sourceRoot":"","sources":["../../../../src/utils/chatImageDimens.ts"],"names":[],"mappings":"AAGA;;;GAGG;AAEH,oBAAY,sBAAsB;IAChC,oBAAoB,yBAAyB;IAC7C,mBAAmB,wBAAwB;IAC3C,iBAAiB,sBAAsB;IACvC,kBAAkB,uBAAuB;IACzC,iBAAiB,sBAAsB;CACxC;AAED,UAAU,cAAc;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAsDD,cAAM,eAAe;IACnB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAkB;IACzC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAa;IAClC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAuC;IAC9D,OAAO,CAAC,MAAM,CAAC,MAAM,CAE4B;gBAErC,MAAM,EAAE,MAAM;IAK1B,OAAO,CAAC,mBAAmB;WAeb,WAAW;WAOX,YAAY,CAAC,MAAM,EAAE,MAAM;WAO3B,aAAa,CAAC,MAAM,EAAE,sBAAsB,GAAG,cAAc;WAO7D,oBAAoB,CAChC,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,MAAM,EAAE,sBAAsB,GAC7B,MAAM;IAaT;;;;OAIG;WACW,kCAAkC,CAC9C,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,MAAM;CAgDV;AAED,eAAe,eAAe,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Date and time formatting utilities
3
+ */
4
+ export declare const formatDuration: (durationMs: number) => string;
5
+ export declare const formatTimestamp: (ts: number | string | null) => string;
6
+ //# sourceMappingURL=dateTimeUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dateTimeUtils.d.ts","sourceRoot":"","sources":["../../../../src/utils/dateTimeUtils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,cAAc,GAAI,YAAY,MAAM,KAAG,MAMnD,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,IAAI,MAAM,GAAG,MAAM,GAAG,IAAI,KAAG,MAmC5D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../../../src/utils/device.ts"],"names":[],"mappings":"AAEA,QAAA,MAAM,WAAW;iCACmB,OAAO;iCAkCP,OAAO;CAgC1C,CAAC;AAEF,eAAe,WAAW,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../../../src/utils/device.ts"],"names":[],"mappings":"AAEA,QAAA,MAAM,WAAW;iCACmB,OAAO;iCAmCP,OAAO;CAgC1C,CAAC;AAEF,eAAe,WAAW,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"imageUtils.d.ts","sourceRoot":"","sources":["../../../../src/utils/imageUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD,eAAO,MAAM,YAAY,QAAO,MAE/B,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,UAAU,MAAM,GAAG,SAAS,KAAG,OAI1D,CAAC;AAGF,eAAO,MAAM,iBAAiB,GAAI,YAAY,GAAG,KAAG,OAInD,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,UAAU,MAAM,KAAG,MA6B9C,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,KAAG,MAM9C,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,MAAM,SAAS,KAAG,MAAM,GAAG,IAa5D,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,SAAS,MAAM,KAAG,MAExD,CAAC"}
1
+ {"version":3,"file":"imageUtils.d.ts","sourceRoot":"","sources":["../../../../src/utils/imageUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD,eAAO,MAAM,YAAY,QAAO,MAE/B,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,UAAU,MAAM,GAAG,SAAS,KAAG,OAI1D,CAAC;AAGF,eAAO,MAAM,iBAAiB,GAAI,YAAY,GAAG,KAAG,OAInD,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,UAAU,MAAM,KAAG,MA+B9C,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,KAAG,MAM9C,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,MAAM,SAAS,KAAG,MAAM,GAAG,IAmB5D,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,SAAS,MAAM,KAAG,MAExD,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Message formatting and preview utilities
3
+ */
4
+ import type { DMessageItem } from '../types/chat';
5
+ export declare const extractTextContent: (message: DMessageItem) => string;
6
+ export declare const getMessagePreview: (message: DMessageItem) => string;
7
+ export declare const getLastMessageText: (message: DMessageItem | undefined, currentUserId?: string) => string;
8
+ //# sourceMappingURL=messageUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messageUtils.d.ts","sourceRoot":"","sources":["../../../../src/utils/messageUtils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAIlD,eAAO,MAAM,kBAAkB,GAAI,SAAS,YAAY,KAAG,MAQ1D,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,SAAS,YAAY,KAAG,MA+EzD,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,SAAS,YAAY,GAAG,SAAS,EACjC,gBAAgB,MAAM,KACrB,MAiBF,CAAC"}
@@ -1,6 +1,7 @@
1
1
  interface ThumbnailOptions {
2
2
  time?: number;
3
3
  quality?: number;
4
+ cacheId?: string;
4
5
  }
5
6
  interface ThumbnailResult {
6
7
  path: string;
@@ -1 +1 @@
1
- {"version":3,"file":"videoThumbnail.d.ts","sourceRoot":"","sources":["../../../../src/utils/videoThumbnail.ts"],"names":[],"mappings":"AAGA,UAAU,gBAAgB;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,kBAAkB;mCAEhB,MAAM,YACR,gBAAgB,KACxB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;sCAoCM,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;0CAWhD,MAAM,EAAE,YACX,gBAAgB,KACxB,OAAO,CAAC,eAAe,EAAE,CAAC;CAe9B,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"videoThumbnail.d.ts","sourceRoot":"","sources":["../../../../src/utils/videoThumbnail.ts"],"names":[],"mappings":"AAGA,UAAU,gBAAgB;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,kBAAkB;mCAEhB,MAAM,YACR,gBAAgB,KACxB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;sCA8CM,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;0CAWhD,MAAM,EAAE,YACX,gBAAgB,KACxB,OAAO,CAAC,eAAe,EAAE,CAAC;CAe9B,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@droppii-org/chat-mobile",
3
- "version": "0.2.14",
3
+ "version": "0.2.16",
4
4
  "description": "Droppii chat mobile",
5
5
  "keywords": [
6
6
  "react-native",
@@ -69,7 +69,7 @@
69
69
  "example-legacy": "yarn workspace @droppii-org/chat-mobile-example-legacy"
70
70
  },
71
71
  "dependencies": {
72
- "@droppii/openim-rn-client-sdk": "git+ssh://git@github.com/droppii/open-im-sdk-reactnative.git#v1.0.0-rc9",
72
+ "@droppii/openim-rn-client-sdk": "git+ssh://git@github.com/droppii/open-im-sdk-reactnative.git#v1.0.0-rc10",
73
73
  "@legendapp/list": "^3.0.6",
74
74
  "axios": "^1.16.1",
75
75
  "lodash": "^4.18.1",
@@ -119,7 +119,7 @@
119
119
  "react-native-mmkv": "4.0.0",
120
120
  "react-native-permissions": "^5.6.0",
121
121
  "react-native-photo-view": "git+ssh://git@github.com/droppii/react-native-photo-view.git",
122
- "react-native-reanimated": "3.19.1",
122
+ "react-native-reanimated": "^4.4.0",
123
123
  "react-native-safe-area-context": "^5.8.0",
124
124
  "react-native-snap-carousel": "3.9.0",
125
125
  "react-native-svg": "^15.15.5",
@@ -4,7 +4,8 @@ import { KContainer, KImage, KLabel, KColors } from '@droppii/libs';
4
4
  import { AvatarSection } from './AvatarSection';
5
5
  import { NamePrefixIcon } from './NamePrefixIcon';
6
6
  import { UnreadBadge } from './UnreadBadge';
7
- import { formatTimestamp, getLastMessageText } from './thread-card.utils';
7
+ import { formatTimestamp } from '../../utils/dateTimeUtils';
8
+ import { getLastMessageText } from '../../utils/messageUtils';
8
9
  import { useConversation, useUserStore } from '../../store';
9
10
 
10
11
  interface ThreadCardProps {
@@ -84,7 +84,6 @@ export const ImageMessage = memo(
84
84
  imageDimensions.width,
85
85
  imageDimensions.height
86
86
  );
87
-
88
87
  return (
89
88
  <KContainer.View style={[messageStyles.wrapper, styles.wrapper]}>
90
89
  <KContainer.Touchable
@@ -1,5 +1,4 @@
1
1
  import { useCallback, useState } from 'react';
2
- import RNFS from 'react-native-fs';
3
2
  import type { Image as PickedImage } from 'react-native-image-crop-picker';
4
3
  import DeviceUtils from '../utils/device';
5
4
  import UIUtils from '../utils/ui';
@@ -48,7 +47,6 @@ export const useImageAttachment = (): UseImageAttachmentReturn => {
48
47
  const uploadImage = useCallback(
49
48
  async (index: number, image: PickedImage) => {
50
49
  console.log('Upload', 'Step 1: Starting upload for image', { index });
51
- let cachedFilePath: string | null = null;
52
50
 
53
51
  try {
54
52
  console.log('Upload', 'Step 2: Updating status to uploading...');
@@ -58,27 +56,10 @@ export const useImageAttachment = (): UseImageAttachmentReturn => {
58
56
  uploadProgress: 0,
59
57
  });
60
58
 
61
- try {
62
- console.log('Upload', 'Step 3: Preparing file...', {
63
- originalPath: image.path,
64
- filename: image.filename,
65
- });
66
- const ext = image.filename?.split('.').pop() || 'jpg';
67
- const fileName = `temp-image-${Date.now()}-${index}.${ext}`;
68
- cachedFilePath = `${RNFS.DocumentDirectoryPath}/${fileName}`;
69
-
70
- console.log('Upload', 'Step 4: Copying file to cache...', {
71
- from: image.path,
72
- to: cachedFilePath,
73
- });
74
- await RNFS.copyFile(image.path, cachedFilePath);
75
- console.log('Upload', 'Step 5: File copied successfully');
76
- } catch (fileError: any) {
77
- console.error('Upload', 'File copy error', fileError);
78
- throw new Error(
79
- `Failed to prepare file: ${fileError?.message || 'Unknown error'}`
80
- );
81
- }
59
+ // ✅ OPTIMIZED: Use original path directly, no copy
60
+ const filePath = image.path.startsWith('file://')
61
+ ? image.path.replace('file://', '')
62
+ : image.path;
82
63
 
83
64
  const filename = image.filename || 'image.jpg';
84
65
 
@@ -93,13 +74,14 @@ export const useImageAttachment = (): UseImageAttachmentReturn => {
93
74
 
94
75
  let uploadedImage;
95
76
  try {
96
- console.log('Upload', 'Step 6: Uploading to server...', {
77
+ console.log('Upload', 'Uploading to server...', {
97
78
  filename,
98
79
  size: image.size,
80
+ filePath,
99
81
  });
100
82
  uploadedImage = await ImageUploadAPI.uploadImageFile(
101
83
  {
102
- path: cachedFilePath || '',
84
+ path: filePath,
103
85
  filename,
104
86
  size: image.size || 0,
105
87
  width: image.width || 0,
@@ -108,7 +90,7 @@ export const useImageAttachment = (): UseImageAttachmentReturn => {
108
90
  },
109
91
  setProgress
110
92
  );
111
- console.log('Upload', 'Step 7: Upload successful!', {
93
+ console.log('Upload', 'Upload successful!', {
112
94
  url: uploadedImage?.url,
113
95
  });
114
96
  } catch (uploadError: any) {
@@ -122,27 +104,14 @@ export const useImageAttachment = (): UseImageAttachmentReturn => {
122
104
  throw new Error('No URL returned from server');
123
105
  }
124
106
 
125
- console.log('Upload', 'Step 8: Upload complete, preparing data...');
107
+ console.log('Upload', 'Upload complete, updating status...');
126
108
  updateImageStatus(index, {
127
109
  isUploading: false,
128
110
  uploadProgress: 100,
129
111
  uploadedUrl: uploadedImage.url,
130
112
  });
131
113
 
132
- console.log(
133
- 'Upload',
134
- 'Step 9: Ready to send - waiting for user confirmation'
135
- );
136
-
137
- console.log('Upload', 'Step 11: Cleaning up cache file...');
138
- try {
139
- if (cachedFilePath) {
140
- await ImageUploadAPI.cleanupImageFile(cachedFilePath);
141
- }
142
- } catch (cleanupError) {
143
- console.warn('Upload', 'Cleanup warning', cleanupError);
144
- }
145
- console.log('Upload', 'Step 12: COMPLETE ✓');
114
+ console.log('Upload', 'COMPLETE ✓');
146
115
  } catch (error: any) {
147
116
  console.error('Upload', 'ERROR', error);
148
117
  const errorMsg = error?.message || trans('chat:image_upload_failed');
@@ -151,14 +120,6 @@ export const useImageAttachment = (): UseImageAttachmentReturn => {
151
120
  error: errorMsg,
152
121
  });
153
122
 
154
- try {
155
- if (cachedFilePath) {
156
- await ImageUploadAPI.cleanupImageFile(cachedFilePath);
157
- }
158
- } catch (cleanupError) {
159
- console.warn('Upload', 'Cleanup after error', cleanupError);
160
- }
161
-
162
123
  console.error('uploadImage', 'Full error', error);
163
124
  }
164
125
  },
@@ -168,27 +129,48 @@ export const useImageAttachment = (): UseImageAttachmentReturn => {
168
129
  const generateVideoThumbnail = useCallback(
169
130
  async (index: number, image: PickedImage) => {
170
131
  if (!isVideoFromPicker(image)) return; // Only for videos
132
+ console.log('[ImageAttach] Generating thumbnail for video:', image);
171
133
 
172
134
  try {
173
- console.log('[ImageAttach] Generating thumbnail for video:', {
174
- index,
175
- filename: image.filename,
176
- });
135
+ let videoDuration = (image as any).duration || 0;
136
+
137
+ // ✅ FIX: Validate duration is reasonable
138
+ if (videoDuration <= 0 || videoDuration > 3600000) {
139
+ // Duration should be between 0 and 1 hour (3600000ms)
140
+ console.warn(
141
+ '[ImageAttach] Invalid duration, using default:',
142
+ videoDuration
143
+ );
144
+ videoDuration = 5000; // Default 5 seconds
145
+ }
177
146
 
178
- const videoDuration = (image as any).duration || 0;
179
- const timeMs = Math.min(1000, Math.floor(videoDuration / 2));
147
+ // FIX: Choose frame at 35% for better representation
148
+ const timeMs = Math.min(
149
+ Math.max(1000, Math.floor(videoDuration * 0.35)),
150
+ videoDuration - 1000
151
+ );
180
152
 
181
- // Copy video to safe location
182
- const ext = image.filename?.split('.').pop() || 'mp4';
183
- const cachedFileName = `thumb-cache-${Date.now()}-${index}.${ext}`;
184
- const cachedVideoPath = `${RNFS.DocumentDirectoryPath}/${cachedFileName}`;
153
+ // OPTIMIZED: Use original path directly, no copy
154
+ const videoPath = image.path.startsWith('file://')
155
+ ? image.path.replace('file://', '')
156
+ : image.path;
185
157
 
186
- await RNFS.copyFile(image.path, cachedVideoPath);
158
+ console.log('[ImageAttach] Generating thumbnail for video:', {
159
+ filename: image.filename,
160
+ videoPath,
161
+ videoDuration,
162
+ timeMs,
163
+ });
187
164
 
188
- // Generate thumbnail
165
+ // Generate thumbnail directly from original path
166
+ console.log('[ImageAttach] Generating thumbnail at timeMs:', timeMs);
189
167
  const thumbnail = await VideoThumbnailUtil.generateThumbnail(
190
- cachedVideoPath,
191
- { time: timeMs, quality: 80 }
168
+ videoPath,
169
+ {
170
+ time: timeMs,
171
+ quality: 80,
172
+ cacheId: `thumb-${index}-${Date.now()}`,
173
+ }
192
174
  );
193
175
 
194
176
  if (!thumbnail) throw new Error('Thumbnail generation failed');
@@ -225,13 +207,6 @@ export const useImageAttachment = (): UseImageAttachmentReturn => {
225
207
  console.log(
226
208
  `✅ [ImageAttach] THUMBNAIL URL (picked): ${uploadedThumbnail.url}`
227
209
  );
228
-
229
- // Cleanup cached video
230
- try {
231
- await RNFS.unlink(cachedVideoPath);
232
- } catch (err) {
233
- console.warn('[ImageAttach] Failed to clean cached video:', err);
234
- }
235
210
  } catch (error) {
236
211
  console.error('[ImageAttach] Video thumbnail generation error:', error);
237
212
  UIUtils.toast.open({
@@ -4,12 +4,13 @@ import { apiInstance } from '../../services/apis';
4
4
  import type { BaseResponse } from '../../types/auth';
5
5
  import type { IUrlMetadata } from '../../types/common';
6
6
  import { ENDPOINTS } from '../../services/endpoints';
7
+ import { normalizeUrl } from '../../utils/url';
7
8
 
8
9
  export const useFetchUrlMetadata = (url?: string) =>
9
10
  useQuery({
10
- queryKey: commonQueryKeys.urlMetadata(url || ''),
11
+ queryKey: commonQueryKeys.urlMetadata(normalizeUrl(url || '')),
11
12
  queryFn: async () => {
12
- const path = `${ENDPOINTS.chatService.urlMetadata}?url=${url}`;
13
+ const path = `${ENDPOINTS.chatService.urlMetadata}?url=${normalizeUrl(url || '')}`;
13
14
  const res = await apiInstance?.get<BaseResponse<IUrlMetadata>>(path);
14
15
  return res?.data?.data?.title
15
16
  ? {
package/src/index.tsx CHANGED
@@ -1,5 +1,12 @@
1
1
  export { ChatAPI } from './services';
2
- export { setAuthToken, getAuthToken, clearAuthToken } from './services/auth';
2
+ export {
3
+ setAuthToken,
4
+ getAuthToken,
5
+ clearAuthToken,
6
+ setTokenRefreshCallback,
7
+ setTokenRefreshFailedCallback,
8
+ refreshAuthToken,
9
+ } from './services/auth';
3
10
  export { initBaseUrl, getBaseUrl } from './config/configuration';
4
11
  export { Config } from './config';
5
12
  export * from './core';
@@ -249,7 +249,7 @@ const styles = StyleSheet.create({
249
249
  right: 0,
250
250
  zIndex: 100,
251
251
  minHeight: 100,
252
- paddingTop: 20,
252
+ paddingTop: 30,
253
253
  },
254
254
  // Figma: Header-First-Row — flex row, padding 8, alignItems center
255
255
  headerRow: {