@esvndev/es-react-template-chat 0.0.91 → 0.0.93

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/dist/index.js CHANGED
@@ -21,6 +21,14 @@ require('@draft-js-plugins/mention/lib/plugin.css');
21
21
  require('@draft-js-plugins/emoji/lib/plugin.css');
22
22
  var reactRedux = require('react-redux');
23
23
  var configureStore$1 = require('@store/configureStore');
24
+ var photo = require('@core/assets/images/icons/file-icons/icon-photo.svg');
25
+ var word = require('@core/assets/images/icons/file-icons/icon-word.svg');
26
+ var excel = require('@core/assets/images/icons/file-icons/icon-excel.svg');
27
+ var ppt = require('@core/assets/images/icons/file-icons/icon-powerpoint.svg');
28
+ var music = require('@core/assets/images/icons/file-icons/icon-music.svg');
29
+ var video = require('@core/assets/images/icons/file-icons/icon-video.svg');
30
+ var pdf = require('@core/assets/images/icons/file-icons/icon-pdf.svg');
31
+ var zip = require('@core/assets/images/icons/file-icons/icon-zip.svg');
24
32
  var reactRouterDom = require('react-router-dom');
25
33
 
26
34
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
@@ -49,6 +57,14 @@ var ReactDOM__namespace = /*#__PURE__*/_interopNamespace(ReactDOM);
49
57
  var ReactDOM__default = /*#__PURE__*/_interopDefaultLegacy(ReactDOM);
50
58
  var toast__default = /*#__PURE__*/_interopDefaultLegacy(toast);
51
59
  var avatarDefault__default = /*#__PURE__*/_interopDefaultLegacy(avatarDefault);
60
+ var photo__default = /*#__PURE__*/_interopDefaultLegacy(photo);
61
+ var word__default = /*#__PURE__*/_interopDefaultLegacy(word);
62
+ var excel__default = /*#__PURE__*/_interopDefaultLegacy(excel);
63
+ var ppt__default = /*#__PURE__*/_interopDefaultLegacy(ppt);
64
+ var music__default = /*#__PURE__*/_interopDefaultLegacy(music);
65
+ var video__default = /*#__PURE__*/_interopDefaultLegacy(video);
66
+ var pdf__default = /*#__PURE__*/_interopDefaultLegacy(pdf);
67
+ var zip__default = /*#__PURE__*/_interopDefaultLegacy(zip);
52
68
 
53
69
  var instances = 'ej2_instances';
54
70
  var uid = 0;
@@ -27397,6 +27413,16 @@ const encodeUUID = (uuid) => {
27397
27413
  return uuid;
27398
27414
  }
27399
27415
  };
27416
+ const formatBytes = (props, decimals = 2) => {
27417
+ if (!+props.size) {
27418
+ return '0 Bytes';
27419
+ }
27420
+ const k = 1024;
27421
+ const dm = decimals < 0 ? 0 : decimals;
27422
+ const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
27423
+ const i = Math.floor(Math.log(props.size) / Math.log(k));
27424
+ return `${parseFloat((props.size / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
27425
+ };
27400
27426
  const isValidUrl = (string) => {
27401
27427
  try {
27402
27428
  // eslint-disable-next-line no-new
@@ -72044,6 +72070,167 @@ const useUploadFile = () => {
72044
72070
  };
72045
72071
  };
72046
72072
 
72073
+ const IconFileTypeColor = (props) => {
72074
+ const { fileType, width, height } = props;
72075
+ const normalizedType = typeof fileType === 'string' ? fileType.toLowerCase() : '';
72076
+ let icon;
72077
+ switch (normalizedType) {
72078
+ case '.jpg':
72079
+ case '.jpeg':
72080
+ case '.png':
72081
+ icon = photo__default["default"];
72082
+ break;
72083
+ case '.mp3':
72084
+ case '.wma':
72085
+ case '.wma9':
72086
+ case '.wav':
72087
+ case '.flac':
72088
+ case '.aac':
72089
+ case '.aac+':
72090
+ case '.ogg':
72091
+ case '.aiff':
72092
+ case '.lossless':
72093
+ case '.amr':
72094
+ case '.ac3':
72095
+ icon = music__default["default"];
72096
+ break;
72097
+ case '.avi':
72098
+ case '.mp4':
72099
+ case '.mkv':
72100
+ case '.wmv':
72101
+ case '.vob':
72102
+ case '.flv':
72103
+ case '.webm':
72104
+ case '.3gp':
72105
+ case '.mpeg':
72106
+ icon = video__default["default"];
72107
+ break;
72108
+ case '.pdf':
72109
+ icon = pdf__default["default"];
72110
+ break;
72111
+ case '.ppt':
72112
+ icon = ppt__default["default"];
72113
+ break;
72114
+ case '.xlsx':
72115
+ icon = excel__default["default"];
72116
+ break;
72117
+ case '.doc':
72118
+ case '.docx':
72119
+ icon = word__default["default"];
72120
+ break;
72121
+ case '.zip':
72122
+ case '.rar':
72123
+ icon = zip__default["default"];
72124
+ break;
72125
+ default:
72126
+ icon = '';
72127
+ break;
72128
+ }
72129
+ // if (fileType === "aac") {
72130
+ // icon = "FiletypeAac"
72131
+ // } else if (fileType === ".ai") {
72132
+ // icon = "FiletypeAi"
72133
+ // } else if (fileType === ".bmp") {
72134
+ // icon = "FiletypeBmp"
72135
+ // } else if (fileType === ".cs") {
72136
+ // icon = "FiletypeCs"
72137
+ // } else if (fileType === ".css") {
72138
+ // icon = "FiletypeCss"
72139
+ // } else if (fileType === ".csv") {
72140
+ // icon = "FiletypeCsv"
72141
+ // } else if (fileType === ".doc") {
72142
+ // icon = "FiletypeDoc"
72143
+ // } else if (fileType === ".docx") {
72144
+ // icon = "FiletypeDocx"
72145
+ // } else if (fileType === ".exe") {
72146
+ // icon = "FiletypeExe"
72147
+ // } else if (fileType === ".gif") {
72148
+ // icon = "FiletypeGif"
72149
+ // } else if (fileType === ".heic") {
72150
+ // icon = "FiletypeHeic"
72151
+ // } else if (fileType === ".html") {
72152
+ // icon = "FiletypeHtml"
72153
+ // } else if (fileType === ".java") {
72154
+ // icon = "FiletypeJava"
72155
+ // } else if (fileType === ".jpg" || fileType === ".jpeg") {
72156
+ // icon = "Image"
72157
+ // } else if (fileType === ".js") {
72158
+ // icon = "FiletypeJs"
72159
+ // } else if (fileType === ".json") {
72160
+ // icon = "FiletypeJson"
72161
+ // } else if (fileType === ".jsx") {
72162
+ // icon = "FiletypeJsx"
72163
+ // } else if (fileType === ".key") {
72164
+ // icon = "FiletypeKey"
72165
+ // } else if (fileType === ".m4p") {
72166
+ // icon = "FiletypeM4p"
72167
+ // } else if (fileType === ".md") {
72168
+ // icon = "FiletypeMd"
72169
+ // } else if (fileType === ".mdx") {
72170
+ // icon = "FiletypeMdx"
72171
+ // } else if (fileType === ".mov") {
72172
+ // icon = "FiletypeMov"
72173
+ // } else if (fileType === ".mp3") {
72174
+ // icon = "FiletypeMp3"
72175
+ // } else if (fileType === ".mp4") {
72176
+ // icon = "FiletypeMp4"
72177
+ // } else if (fileType === ".otf") {
72178
+ // icon = "FiletypeOtf"
72179
+ // } else if (fileType === ".pdf") {
72180
+ // icon = "FiletypePdf"
72181
+ // } else if (fileType === ".php") {
72182
+ // icon = "FiletypePhp"
72183
+ // } else if (fileType === ".png") {
72184
+ // icon = "Image"
72185
+ // } else if (fileType === ".ppt") {
72186
+ // icon = "FiletypePpt"
72187
+ // } else if (fileType === ".pptx") {
72188
+ // icon = "FiletypePptx"
72189
+ // } else if (fileType === ".psd") {
72190
+ // icon = "FiletypePsd"
72191
+ // } else if (fileType === ".py") {
72192
+ // icon = "FiletypePy"
72193
+ // } else if (fileType === ".raw") {
72194
+ // icon = "FiletypeRaw"
72195
+ // } else if (fileType === ".rb") {
72196
+ // icon = "FiletypeRb"
72197
+ // } else if (fileType === ".sass") {
72198
+ // icon = "FiletypeSass"
72199
+ // } else if (fileType === ".scss") {
72200
+ // icon = "FiletypeScss"
72201
+ // } else if (fileType === ".sh") {
72202
+ // icon = "FiletypeSh"
72203
+ // } else if (fileType === ".sql") {
72204
+ // icon = "FiletypeSql"
72205
+ // } else if (fileType === ".svg") {
72206
+ // icon = "FiletypeSvg"
72207
+ // } else if (fileType === ".tiff") {
72208
+ // icon = "FiletypeTiff"
72209
+ // } else if (fileType === ".tsx") {
72210
+ // icon = "FiletypeTsx"
72211
+ // } else if (fileType === ".ttf") {
72212
+ // icon = "FiletypeTtf"
72213
+ // } else if (fileType === ".txt") {
72214
+ // icon = "FiletypeTxt"
72215
+ // } else if (fileType === ".wav") {
72216
+ // icon = "FiletypeWav"
72217
+ // } else if (fileType === ".woff") {
72218
+ // icon = "FiletypeWoff"
72219
+ // } else if (fileType === ".xls") {
72220
+ // icon = "FiletypeXls"
72221
+ // } else if (fileType === ".xlsx") {
72222
+ // icon = "FiletypeXlsx"
72223
+ // } else if (fileType === ".xml") {
72224
+ // icon = "FiletypeXml"
72225
+ // } else if (fileType === ".yml") {
72226
+ // icon = "FiletypeYml"
72227
+ // } else if (fileType === ".zip" || fileType === ".rar") {
72228
+ // icon = "FileZip"
72229
+ // }
72230
+ // @ts-ignore
72231
+ return jsxRuntime.jsx("img", { ...props, src: icon, style: { width: width ? width : 24, height: height ? height : 'auto', ...props.style } });
72232
+ };
72233
+
72047
72234
  const DateHeader = React.memo(({ label }) => (jsxRuntime.jsx("div", { className: "d-flex justify-content-center", children: jsxRuntime.jsx("div", { style: {
72048
72235
  backgroundColor: "rgba(0,0,0,0.2)",
72049
72236
  padding: "2px 15px",
@@ -72426,311 +72613,179 @@ const ChatLog = (props) => {
72426
72613
  return (jsxRuntime.jsx("div", { className: "group-image-item image-container", children: jsxRuntime.jsx("img", { style: { maxWidth: "100%", maxHeight: 360 }, src: `${CDN_URL_VIEW}/${it.path.trim()}`, onClick: () => handlePreview(it), alt: "" }) }, index));
72427
72614
  }) })), jsxRuntime.jsx("div", { className: "", style: { fontSize: "12px", color: "#476285" }, children: moment(chat.time).format("HH:mm") })] }) }) }));
72428
72615
  }, [expandedMessages, handlePreview, mentionItems]);
72429
- // const renderLinkPreview = (urlString: string) => {
72430
- // const { href, displayUrl, host } = getLinkPreviewData(urlString)
72431
- // return (
72432
- // <>
72433
- // <a
72434
- // href={href}
72435
- // target="_blank"
72436
- // rel="noreferrer"
72437
- // style={{
72438
- // textDecoration: 'none',
72439
- // color: 'inherit'
72440
- // }}
72441
- // >
72442
- // <div
72443
- // style={{
72444
- // marginTop: 4,
72445
- // marginBottom: 4,
72446
- // padding: '8px 10px',
72447
- // borderRadius: 8,
72448
- // backgroundColor: '#eef5ff',
72449
- // border: '1px solid #d3e2ff',
72450
- // maxWidth: 420
72451
- // }}
72452
- // >
72453
- // <div
72454
- // style={{
72455
- // fontSize: 14,
72456
- // fontWeight: 500,
72457
- // color: '#1d4f91',
72458
- // wordBreak: 'break-word'
72459
- // }}
72460
- // >
72461
- // {displayUrl}
72462
- // </div>
72463
- // {host && (
72464
- // <div
72465
- // style={{
72466
- // marginTop: 4,
72467
- // fontSize: 12,
72468
- // color: '#6f6b7d'
72469
- // }}
72470
- // >
72471
- // {host}
72472
- // </div>
72473
- // )}
72474
- // </div>
72475
- // </a>
72476
- // </>
72477
- // )
72478
- // }
72479
- // const renderNotifyLeaveGroup = useCallback((chat: any) => {
72480
- // const msg = JSON.parse(chat?.msg)
72481
- // if (chat?.createdById === dataProfile?.id) {
72482
- // return (
72483
- // <>
72484
- // <div>
72485
- // <span style={{ fontWeight: "bold", marginRight: "5px" }}>
72486
- // {msg?.name}
72487
- // </span>
72488
- // <span>được bạn xoá khỏi nhóm</span>
72489
- // </div>
72490
- // </>
72491
- // )
72492
- // }
72493
- // if (chat?.createdById === msg?.id) {
72494
- // return (
72495
- // <>
72496
- // <div>
72497
- // <span style={{ fontWeight: "bold", marginRight: "5px" }}>
72498
- // {msg?.name}
72499
- // </span>
72500
- // <span>đã rời khỏi nhóm</span>
72501
- // </div>
72502
- // </>
72503
- // )
72504
- // }
72505
- // return (
72506
- // <>
72507
- // <div>
72508
- // <span style={{ fontWeight: "bold", marginRight: "5px" }}>
72509
- // {msg?.name}
72510
- // </span>
72511
- // <span>được <span style={{ fontWeight: "bold", marginRight: "5px" }}>{chat?.createdBy?.name}</span> xoá khỏi nhóm</span>
72512
- // </div>
72513
- // </>
72514
- // )
72515
- // }, [dataProfile])
72516
- // const renderChatNotification = useCallback((chat: any) => {
72517
- // const parseChatMsg = (msg: string) => {
72518
- // if (!msg) { return [] }
72519
- // try {
72520
- // const parsed = typeof msg === 'string' ? JSON.parse(msg) : msg
72521
- // return Array.isArray(parsed) ? parsed : [parsed]
72522
- // } catch (err) {
72523
- // console.error('JSON parse error:', err)
72524
- // return []
72525
- // }
72526
- // }
72527
- // const dataParse = parseChatMsg(chat.msg)
72528
- // // ✅ FIX: Kiểm tra array trước khi dùng slice
72529
- // if (!Array.isArray(dataParse) || dataParse.length === 0) {
72530
- // return (
72531
- // <div>
72532
- // <span>Đã thay đổi trong nhóm</span>
72533
- // </div>
72534
- // )
72535
- // }
72536
- // const displayedItems = dataParse.slice(0, 2)
72537
- // const extraCount = Math.max(0, dataParse.length - displayedItems.length)
72538
- // return (
72539
- // <>
72540
- // <div>
72541
- // {displayedItems.map((item: any, index: any) => (
72542
- // <strong key={index}>
72543
- // {item.name}
72544
- // {index < displayedItems.length - 1 && ", "}
72545
- // </strong>
72546
- // ))}
72547
- // {dataParse.length > 3 && (
72548
- // <strong>
72549
- // <span style={{ fontWeight: "normal" }}>{" "}</span>{" "}
72550
- // {extraCount} người khác
72551
- // </strong>
72552
- // )}
72553
- // {" được "}
72554
- // {chat?.createdBy?.id === dataProfile?.id ? (
72555
- // <span>bạn </span>
72556
- // ) : (
72557
- // <strong style={{ marginRight: "5px" }}>{chat?.createdByName}</strong>
72558
- // )}
72559
- // thêm vào nhóm
72560
- // </div>
72561
- // </>
72562
- // )
72563
- // }, [dataProfile])
72564
- // const renderChatImage = useCallback((chat: any) => {
72565
- // const files = chat.path
72566
- // if (!files || !Array.isArray(files) || files.length === 0) {
72567
- // return null
72568
- // }
72569
- // // Ảnh đơn lẻ
72570
- // if (files.length === 1) {
72571
- // const imagePath = files[0]?.path?.trim()
72572
- // if (!imagePath) { return null }
72573
- // return (
72574
- // <>
72575
- // <div className="image-container" style={{ maxWidth: "100%", position: "relative" }}>
72576
- // <img
72577
- // src={`${CDN_URL_VIEW}/${imagePath}`}
72578
- // alt={`Chat image ${chat.id + 1}`}
72579
- // data-file-index={chat.id}
72580
- // style={{
72581
- // maxWidth: "100%",
72582
- // maxHeight: 400,
72583
- // borderRadius: 8,
72584
- // cursor: "pointer"
72585
- // }}
72586
- // onClick={() => handlePreview(files[0])}
72587
- // />
72588
- // {/* HD Badge */}
72589
- // <div
72590
- // style={{
72591
- // position: "absolute",
72592
- // top: 6,
72593
- // left: 6,
72594
- // backgroundColor: "rgba(0, 0, 0, 0.6)",
72595
- // color: "white",
72596
- // padding: "2px 6px",
72597
- // borderRadius: 4,
72598
- // fontSize: "10px",
72599
- // fontWeight: "bold"
72600
- // }}
72601
- // >
72602
- // HD
72603
- // </div>
72604
- // </div>
72605
- // <div className="px-1 py-75">{moment(chat.time).format("HH:mm")}</div>
72606
- // </>
72607
- // )
72608
- // }
72609
- // // Nhiều ảnh - hiển thị dạng grid 2 cột, tối đa 6 ảnh
72610
- // const imagesToShow = files.slice(0, 6)
72611
- // const remainingCount = files.length - 6
72612
- // return (
72613
- // <>
72614
- // <div
72615
- // className="images-grid-container"
72616
- // style={{
72617
- // display: "flex",
72618
- // flexWrap: "wrap",
72619
- // maxWidth: "600px",
72620
- // gap: "4px"
72621
- // }}
72622
- // >
72623
- // {imagesToShow.map((file: any, index: number) => {
72624
- // const imagePath = file?.path?.trim()
72625
- // if (!imagePath) { return null }
72626
- // const imageUrl = `${CDN_URL_VIEW}/${imagePath}`
72627
- // const isLastImage = index === 5 && remainingCount > 0
72628
- // // ✅ THÊM: Kiểm tra ảnh cuối khi số lượng lẻ
72629
- // const isOddCount = imagesToShow.length % 2 !== 0
72630
- // const isLastItem = index === imagesToShow.length - 1
72631
- // const isFullWidth = isOddCount && isLastItem && !isLastImage
72632
- // return (
72633
- // <div
72634
- // key={`image-${chat.id}-${index}`}
72635
- // style={{
72636
- // width: isFullWidth ? "100%" : "calc(50% - 2px)",
72637
- // height: "140px",
72638
- // position: "relative",
72639
- // overflow: "hidden",
72640
- // borderRadius: 8,
72641
- // border: "1px solid #e0e0e0"
72642
- // }}
72643
- // >
72644
- // <img
72645
- // src={imageUrl}
72646
- // alt={`Chat image ${index + 1}`}
72647
- // style={{
72648
- // width: "100%",
72649
- // height: "100%",
72650
- // objectFit: "cover",
72651
- // borderRadius: 8,
72652
- // display: "block",
72653
- // cursor: "pointer"
72654
- // }}
72655
- // onClick={() => handlePreview(file)}
72656
- // />
72657
- // {/* HD Badge */}
72658
- // <div
72659
- // style={{
72660
- // position: "absolute",
72661
- // top: 6,
72662
- // left: 6,
72663
- // backgroundColor: "rgba(0, 0, 0, 0.6)",
72664
- // color: "white",
72665
- // padding: "2px 6px",
72666
- // borderRadius: 4,
72667
- // fontSize: "10px",
72668
- // fontWeight: "bold",
72669
- // zIndex: 1
72670
- // }}
72671
- // >
72672
- // HD
72673
- // </div>
72674
- // {/* Overlay cho ảnh cuối nếu có nhiều hơn 6 ảnh */}
72675
- // {isLastImage && (
72676
- // <div
72677
- // style={{
72678
- // position: "absolute",
72679
- // top: 0,
72680
- // left: 0,
72681
- // right: 0,
72682
- // bottom: 0,
72683
- // backgroundColor: "rgba(0, 0, 0, 0.6)",
72684
- // display: "flex",
72685
- // alignItems: "center",
72686
- // justifyContent: "center",
72687
- // color: "white",
72688
- // fontSize: "20px",
72689
- // fontWeight: "bold",
72690
- // borderRadius: 8,
72691
- // cursor: "pointer"
72692
- // }}
72693
- // onClick={() => handlePreview(file)}
72694
- // >
72695
- // +{remainingCount}
72696
- // </div>
72697
- // )}
72698
- // </div>
72699
- // )
72700
- // })}
72701
- // </div>
72702
- // <div className="px-1 py-75">{moment(chat.time).format("HH:mm")}</div>
72703
- // </>
72704
- // )
72705
- // }, [handlePreview])
72706
- // const renderChatFile = useCallback((chat: any) => {
72707
- // const files = chat?.path
72708
- // return (
72709
- // <>
72710
- // {files?.map((file: any, index: number) => {
72711
- // return (
72712
- // <div key={index}>
72713
- // <div className="d-flex p-50">
72714
- // <div className="me-1" onClick={() => handlePreview(file)}>
72715
- // {/*<IconFileType fileType={file?.type} fontSize={50} />*/}
72716
- // <IconFileTypeColor fileType={file?.type} width={35} />
72717
- // </div>
72718
- // <div>
72719
- // <p className="file-name-chat">{file.name}</p>
72720
- // <p>{formatBytes({ size: file.size })}</p>
72721
- // </div>
72722
- // </div>
72723
- // {index + 1 === files.length && (
72724
- // <div className="px-1 pb-75">
72725
- // {moment(chat.time).format("HH:mm")}
72726
- // </div>
72727
- // )}
72728
- // </div>
72729
- // )
72730
- // })}
72731
- // </>
72732
- // )
72733
- // }, [handlePreview])
72616
+ const getLinkPreviewData = (urlString) => {
72617
+ try {
72618
+ const hasProtocol = /^https?:\/\//i.test(urlString);
72619
+ const href = hasProtocol ? urlString : `https://${urlString}`;
72620
+ const url = new URL(href);
72621
+ const displayUrl = urlString.length > 80 ? `${urlString.slice(0, 77)}...` : urlString;
72622
+ return {
72623
+ href,
72624
+ displayUrl,
72625
+ host: url.host
72626
+ };
72627
+ }
72628
+ catch (e) {
72629
+ return {
72630
+ href: urlString,
72631
+ displayUrl: urlString,
72632
+ host: ''
72633
+ };
72634
+ }
72635
+ };
72636
+ const renderLinkPreview = (urlString) => {
72637
+ const { href, displayUrl, host } = getLinkPreviewData(urlString);
72638
+ return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsx("a", { href: href, target: "_blank", rel: "noreferrer", style: {
72639
+ textDecoration: 'none',
72640
+ color: 'inherit'
72641
+ }, children: jsxRuntime.jsxs("div", { style: {
72642
+ marginTop: 4,
72643
+ marginBottom: 4,
72644
+ padding: '8px 10px',
72645
+ borderRadius: 8,
72646
+ backgroundColor: '#eef5ff',
72647
+ border: '1px solid #d3e2ff',
72648
+ maxWidth: 420
72649
+ }, children: [jsxRuntime.jsx("div", { style: {
72650
+ fontSize: 14,
72651
+ fontWeight: 500,
72652
+ color: '#1d4f91',
72653
+ wordBreak: 'break-word'
72654
+ }, children: displayUrl }), host && (jsxRuntime.jsx("div", { style: {
72655
+ marginTop: 4,
72656
+ fontSize: 12,
72657
+ color: '#6f6b7d'
72658
+ }, children: host }))] }) }) }));
72659
+ };
72660
+ React.useCallback((chat) => {
72661
+ const msg = JSON.parse(chat?.msg);
72662
+ if (chat?.createdById === dataProfile?.id) {
72663
+ return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("span", { style: { fontWeight: "bold", marginRight: "5px" }, children: msg?.name }), jsxRuntime.jsx("span", { children: "\u0111\u01B0\u1EE3c b\u1EA1n xo\u00E1 kh\u1ECFi nh\u00F3m" })] }) }));
72664
+ }
72665
+ if (chat?.createdById === msg?.id) {
72666
+ return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("span", { style: { fontWeight: "bold", marginRight: "5px" }, children: msg?.name }), jsxRuntime.jsx("span", { children: "\u0111\u00E3 r\u1EDDi kh\u1ECFi nh\u00F3m" })] }) }));
72667
+ }
72668
+ return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("span", { style: { fontWeight: "bold", marginRight: "5px" }, children: msg?.name }), jsxRuntime.jsxs("span", { children: ["\u0111\u01B0\u1EE3c ", jsxRuntime.jsx("span", { style: { fontWeight: "bold", marginRight: "5px" }, children: chat?.createdBy?.name }), " xo\u00E1 kh\u1ECFi nh\u00F3m"] })] }) }));
72669
+ }, [dataProfile]);
72670
+ React.useCallback((chat) => {
72671
+ const parseChatMsg = (msg) => {
72672
+ if (!msg) {
72673
+ return [];
72674
+ }
72675
+ try {
72676
+ const parsed = typeof msg === 'string' ? JSON.parse(msg) : msg;
72677
+ return Array.isArray(parsed) ? parsed : [parsed];
72678
+ }
72679
+ catch (err) {
72680
+ console.error('JSON parse error:', err);
72681
+ return [];
72682
+ }
72683
+ };
72684
+ const dataParse = parseChatMsg(chat.msg);
72685
+ // ✅ FIX: Kiểm tra array trước khi dùng slice
72686
+ if (!Array.isArray(dataParse) || dataParse.length === 0) {
72687
+ return (jsxRuntime.jsx("div", { children: jsxRuntime.jsx("span", { children: "\u0110\u00E3 c\u00F3 thay \u0111\u1ED5i trong nh\u00F3m" }) }));
72688
+ }
72689
+ const displayedItems = dataParse.slice(0, 2);
72690
+ const extraCount = Math.max(0, dataParse.length - displayedItems.length);
72691
+ return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs("div", { children: [displayedItems.map((item, index) => (jsxRuntime.jsxs("strong", { children: [item.name, index < displayedItems.length - 1 && ", "] }, index))), dataParse.length > 3 && (jsxRuntime.jsxs("strong", { children: [jsxRuntime.jsx("span", { style: { fontWeight: "normal" }, children: " và " }), " ", extraCount, " ng\u01B0\u1EDDi kh\u00E1c"] })), " được ", chat?.createdBy?.id === dataProfile?.id ? (jsxRuntime.jsx("span", { children: "b\u1EA1n " })) : (jsxRuntime.jsx("strong", { style: { marginRight: "5px" }, children: chat?.createdByName })), "th\u00EAm v\u00E0o nh\u00F3m"] }) }));
72692
+ }, [dataProfile]);
72693
+ React.useCallback((chat) => {
72694
+ const files = chat.path;
72695
+ if (!files || !Array.isArray(files) || files.length === 0) {
72696
+ return null;
72697
+ }
72698
+ // Ảnh đơn lẻ
72699
+ if (files.length === 1) {
72700
+ const imagePath = files[0]?.path?.trim();
72701
+ if (!imagePath) {
72702
+ return null;
72703
+ }
72704
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: "image-container", style: { maxWidth: "100%", position: "relative" }, children: [jsxRuntime.jsx("img", { src: `${CDN_URL_VIEW}/${imagePath}`, alt: `Chat image ${chat.id + 1}`, "data-file-index": chat.id, style: {
72705
+ maxWidth: "100%",
72706
+ maxHeight: 400,
72707
+ borderRadius: 8,
72708
+ cursor: "pointer"
72709
+ }, onClick: () => handlePreview(files[0]) }), jsxRuntime.jsx("div", { style: {
72710
+ position: "absolute",
72711
+ top: 6,
72712
+ left: 6,
72713
+ backgroundColor: "rgba(0, 0, 0, 0.6)",
72714
+ color: "white",
72715
+ padding: "2px 6px",
72716
+ borderRadius: 4,
72717
+ fontSize: "10px",
72718
+ fontWeight: "bold"
72719
+ }, children: "HD" })] }), jsxRuntime.jsx("div", { className: "px-1 py-75", children: moment(chat.time).format("HH:mm") })] }));
72720
+ }
72721
+ // Nhiều ảnh - hiển thị dạng grid 2 cột, tối đa 6 ảnh
72722
+ const imagesToShow = files.slice(0, 6);
72723
+ const remainingCount = files.length - 6;
72724
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: "images-grid-container", style: {
72725
+ display: "flex",
72726
+ flexWrap: "wrap",
72727
+ maxWidth: "600px",
72728
+ gap: "4px"
72729
+ }, children: imagesToShow.map((file, index) => {
72730
+ const imagePath = file?.path?.trim();
72731
+ if (!imagePath) {
72732
+ return null;
72733
+ }
72734
+ const imageUrl = `${CDN_URL_VIEW}/${imagePath}`;
72735
+ const isLastImage = index === 5 && remainingCount > 0;
72736
+ // THÊM: Kiểm tra ảnh cuối khi số lượng lẻ
72737
+ const isOddCount = imagesToShow.length % 2 !== 0;
72738
+ const isLastItem = index === imagesToShow.length - 1;
72739
+ const isFullWidth = isOddCount && isLastItem && !isLastImage;
72740
+ return (jsxRuntime.jsxs("div", { style: {
72741
+ width: isFullWidth ? "100%" : "calc(50% - 2px)",
72742
+ height: "140px",
72743
+ position: "relative",
72744
+ overflow: "hidden",
72745
+ borderRadius: 8,
72746
+ border: "1px solid #e0e0e0"
72747
+ }, children: [jsxRuntime.jsx("img", { src: imageUrl, alt: `Chat image ${index + 1}`, style: {
72748
+ width: "100%",
72749
+ height: "100%",
72750
+ objectFit: "cover",
72751
+ borderRadius: 8,
72752
+ display: "block",
72753
+ cursor: "pointer"
72754
+ }, onClick: () => handlePreview(file) }), jsxRuntime.jsx("div", { style: {
72755
+ position: "absolute",
72756
+ top: 6,
72757
+ left: 6,
72758
+ backgroundColor: "rgba(0, 0, 0, 0.6)",
72759
+ color: "white",
72760
+ padding: "2px 6px",
72761
+ borderRadius: 4,
72762
+ fontSize: "10px",
72763
+ fontWeight: "bold",
72764
+ zIndex: 1
72765
+ }, children: "HD" }), isLastImage && (jsxRuntime.jsxs("div", { style: {
72766
+ position: "absolute",
72767
+ top: 0,
72768
+ left: 0,
72769
+ right: 0,
72770
+ bottom: 0,
72771
+ backgroundColor: "rgba(0, 0, 0, 0.6)",
72772
+ display: "flex",
72773
+ alignItems: "center",
72774
+ justifyContent: "center",
72775
+ color: "white",
72776
+ fontSize: "20px",
72777
+ fontWeight: "bold",
72778
+ borderRadius: 8,
72779
+ cursor: "pointer"
72780
+ }, onClick: () => handlePreview(file), children: ["+", remainingCount] }))] }, `image-${chat.id}-${index}`));
72781
+ }) }), jsxRuntime.jsx("div", { className: "px-1 py-75", children: moment(chat.time).format("HH:mm") })] }));
72782
+ }, [handlePreview]);
72783
+ React.useCallback((chat) => {
72784
+ const files = chat?.path;
72785
+ return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: files?.map((file, index) => {
72786
+ return (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsxs("div", { className: "d-flex p-50", children: [jsxRuntime.jsx("div", { className: "me-1", onClick: () => handlePreview(file), children: jsxRuntime.jsx(IconFileTypeColor, { fileType: file?.type, width: 35 }) }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("p", { className: "file-name-chat", children: file.name }), jsxRuntime.jsx("p", { children: formatBytes({ size: file.size }) })] })] }), index + 1 === files.length && (jsxRuntime.jsx("div", { className: "px-1 pb-75", children: moment(chat.time).format("HH:mm") }))] }, index));
72787
+ }) }));
72788
+ }, [handlePreview]);
72734
72789
  // const renderTaskApplication = useCallback((chat: any) => {
72735
72790
  // const safeParse = (str: any) => {
72736
72791
  // if (!str) { return {} }