@esvndev/es-react-template-chat 0.0.89 → 0.0.90
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 +172 -197
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +172 -197
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -72041,7 +72041,7 @@ const ChatLog = (props) => {
|
|
|
72041
72041
|
const { typeChat, contactId, chatRoomId, active, messageByGroup, pinnedMessages, setScroll, checkScroll, pinMessageChatRoom, deleteMessageApi, recallMessageApi, get_message_by_group_cursor_api, getPinMessageChatRoomApi, deletePinMessage,
|
|
72042
72042
|
//updateGroupTagApi,
|
|
72043
72043
|
createReminderApi, senMessageApi, typingUsers } = useChat();
|
|
72044
|
-
useAppSelector((state) => state.hubNotification);
|
|
72044
|
+
const { connection } = useAppSelector((state) => state.hubNotification);
|
|
72045
72045
|
const [dynamicMenuItems, setDynamicMenuItems] = useState([]);
|
|
72046
72046
|
useEffect(() => {
|
|
72047
72047
|
const fetchFormConfig = async () => {
|
|
@@ -72082,38 +72082,68 @@ const ChatLog = (props) => {
|
|
|
72082
72082
|
], [dynamicMenuItems]);
|
|
72083
72083
|
// Menu items cho Hành chính (chỉ administrative)
|
|
72084
72084
|
useMemo(() => ADMINISTRATIVE_ITEMS, []);
|
|
72085
|
-
useRef(false);
|
|
72086
|
-
useRef(null);
|
|
72087
|
-
useRef(null);
|
|
72085
|
+
const isTypingRef = useRef(false);
|
|
72086
|
+
const typingTimeoutRef = useRef(null);
|
|
72088
72087
|
useRef(null);
|
|
72089
72088
|
useRef(null);
|
|
72089
|
+
const inputContainer = useRef(null);
|
|
72090
72090
|
const containerChatRef = useRef(null);
|
|
72091
72091
|
const { connectHub, dataInfo, dataProfile, handleUser, handleUserSidebarRight, handleSidebar, handleSidebarRight, userSidebarLeft, dataHistory, chatGetType, approveUpdateStatus, handleModalAdministrative, setDataItem, handleModalAddUserGroup, handleModalGroup, typeOpenModalAdd, setTypeOpenModalAdd, unpinMessage, getPinnedMessages } = props;
|
|
72092
72092
|
const groupChatUsers = dataHistory?.find((dt) => dt.id === active);
|
|
72093
72093
|
//const dataInfoAvatar = dataInfo && dataInfo.avatar ? dataInfo.avatar : DEFAULT_AVATAR
|
|
72094
|
-
useState([]);
|
|
72095
|
-
useState(false);
|
|
72094
|
+
const [imgCopy, setImgCopy] = useState([]);
|
|
72095
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
72096
72096
|
const [openModalPreview, setOpenModalPreview] = useState(false);
|
|
72097
72097
|
useState(false);
|
|
72098
72098
|
useState(false);
|
|
72099
72099
|
useState(false);
|
|
72100
72100
|
useState('');
|
|
72101
72101
|
useState(null);
|
|
72102
|
-
useState(null);
|
|
72103
|
-
useState(null);
|
|
72104
|
-
useState({ x: 0, y: 0 });
|
|
72105
|
-
useState(undefined);
|
|
72106
|
-
useState(undefined);
|
|
72102
|
+
const [currentMessage, setCurrentMessage] = useState(null);
|
|
72103
|
+
const [replyMessage, setReplyMessage] = useState(null);
|
|
72104
|
+
const [position, setPosition] = useState({ x: 0, y: 0 });
|
|
72105
|
+
const [listContextShow, setListContextShow] = useState(undefined);
|
|
72106
|
+
const [listContextHide, setListContextHide] = useState(undefined);
|
|
72107
72107
|
const [selectedMessage, setSelectedMessage] = useState(null);
|
|
72108
|
-
useState(false);
|
|
72109
|
-
useState(true);
|
|
72110
|
-
useRef(0);
|
|
72108
|
+
const [isMultiLine, setIsMultiLine] = useState(false);
|
|
72109
|
+
const [isAtBottom, setIsAtBottom] = useState(true);
|
|
72110
|
+
const prevListLength = useRef(0);
|
|
72111
72111
|
useState(0);
|
|
72112
72112
|
useState(true);
|
|
72113
72113
|
useState(new Set());
|
|
72114
|
-
useState(null);
|
|
72114
|
+
const [clickedImageFile, setClickedImageFile] = useState(null);
|
|
72115
72115
|
useState(false);
|
|
72116
72116
|
useState(new Set());
|
|
72117
|
+
const BASE_CONTEXT_ITEMS = [
|
|
72118
|
+
"reply", "share", "pin", "bookmark",
|
|
72119
|
+
"selectMultiMessage", "detail", "other", "recall", "delete"
|
|
72120
|
+
];
|
|
72121
|
+
const CONTEXT_CONFIG = {
|
|
72122
|
+
selection: {
|
|
72123
|
+
show: ["copyRangeText", ...BASE_CONTEXT_ITEMS, "save"],
|
|
72124
|
+
hide: ["copyText", "save", "copyImage"]
|
|
72125
|
+
},
|
|
72126
|
+
image: {
|
|
72127
|
+
show: ["copyImage", ...BASE_CONTEXT_ITEMS, "save"],
|
|
72128
|
+
hide: ["copyText", "copyRangeText"]
|
|
72129
|
+
},
|
|
72130
|
+
file: {
|
|
72131
|
+
show: [...BASE_CONTEXT_ITEMS, "save"],
|
|
72132
|
+
hide: ["copyText", "copyRangeText", "copyImage"]
|
|
72133
|
+
},
|
|
72134
|
+
text: {
|
|
72135
|
+
show: ["copyText", ...BASE_CONTEXT_ITEMS],
|
|
72136
|
+
hide: ["copyRangeText", "save", "copyImage"]
|
|
72137
|
+
},
|
|
72138
|
+
voucher: {
|
|
72139
|
+
show: ["copyText", ...BASE_CONTEXT_ITEMS],
|
|
72140
|
+
hide: ["copyRangeText", "save", "copyImage"]
|
|
72141
|
+
},
|
|
72142
|
+
default: {
|
|
72143
|
+
show: ["copyText", ...BASE_CONTEXT_ITEMS],
|
|
72144
|
+
hide: ["copyRangeText", "save", "copyImage"]
|
|
72145
|
+
}
|
|
72146
|
+
};
|
|
72117
72147
|
useState(true);
|
|
72118
72148
|
const scrollToBottom = () => {
|
|
72119
72149
|
const messagesEndEle = document.getElementById('messagesEnd');
|
|
@@ -72149,188 +72179,133 @@ const ChatLog = (props) => {
|
|
|
72149
72179
|
}, []);
|
|
72150
72180
|
useState(false);
|
|
72151
72181
|
useDispatch();
|
|
72152
|
-
|
|
72153
|
-
|
|
72154
|
-
|
|
72155
|
-
|
|
72156
|
-
|
|
72157
|
-
|
|
72158
|
-
|
|
72159
|
-
|
|
72160
|
-
|
|
72161
|
-
|
|
72162
|
-
|
|
72163
|
-
|
|
72164
|
-
|
|
72165
|
-
|
|
72166
|
-
|
|
72167
|
-
|
|
72168
|
-
|
|
72169
|
-
|
|
72170
|
-
|
|
72171
|
-
|
|
72172
|
-
|
|
72173
|
-
|
|
72174
|
-
|
|
72175
|
-
|
|
72176
|
-
|
|
72177
|
-
|
|
72178
|
-
|
|
72179
|
-
|
|
72180
|
-
|
|
72181
|
-
|
|
72182
|
-
|
|
72183
|
-
|
|
72184
|
-
|
|
72185
|
-
|
|
72186
|
-
|
|
72187
|
-
|
|
72188
|
-
|
|
72189
|
-
|
|
72190
|
-
|
|
72191
|
-
|
|
72192
|
-
|
|
72193
|
-
|
|
72194
|
-
|
|
72195
|
-
|
|
72196
|
-
|
|
72197
|
-
|
|
72198
|
-
|
|
72199
|
-
|
|
72200
|
-
|
|
72201
|
-
|
|
72202
|
-
|
|
72203
|
-
|
|
72204
|
-
|
|
72205
|
-
|
|
72206
|
-
|
|
72207
|
-
|
|
72208
|
-
|
|
72209
|
-
|
|
72210
|
-
|
|
72211
|
-
|
|
72212
|
-
|
|
72213
|
-
|
|
72214
|
-
|
|
72215
|
-
|
|
72216
|
-
|
|
72217
|
-
|
|
72218
|
-
|
|
72219
|
-
|
|
72220
|
-
|
|
72221
|
-
|
|
72222
|
-
//
|
|
72223
|
-
|
|
72224
|
-
|
|
72225
|
-
|
|
72226
|
-
|
|
72227
|
-
|
|
72228
|
-
|
|
72229
|
-
|
|
72230
|
-
|
|
72231
|
-
|
|
72232
|
-
|
|
72233
|
-
|
|
72234
|
-
|
|
72235
|
-
|
|
72236
|
-
|
|
72237
|
-
|
|
72238
|
-
|
|
72239
|
-
|
|
72240
|
-
|
|
72241
|
-
|
|
72242
|
-
|
|
72243
|
-
|
|
72244
|
-
|
|
72245
|
-
|
|
72246
|
-
|
|
72247
|
-
|
|
72248
|
-
|
|
72249
|
-
|
|
72250
|
-
|
|
72251
|
-
|
|
72252
|
-
|
|
72253
|
-
|
|
72254
|
-
|
|
72255
|
-
|
|
72256
|
-
|
|
72257
|
-
|
|
72258
|
-
|
|
72259
|
-
|
|
72260
|
-
|
|
72261
|
-
|
|
72262
|
-
|
|
72263
|
-
|
|
72264
|
-
|
|
72265
|
-
|
|
72266
|
-
|
|
72267
|
-
|
|
72268
|
-
|
|
72269
|
-
|
|
72270
|
-
|
|
72271
|
-
|
|
72272
|
-
|
|
72273
|
-
|
|
72274
|
-
|
|
72275
|
-
|
|
72276
|
-
|
|
72277
|
-
|
|
72278
|
-
|
|
72279
|
-
// //chatRoomId,
|
|
72280
|
-
// //chatGetType
|
|
72281
|
-
// ])
|
|
72282
|
-
// // Chuyển phòng thì load lại message + pinned messages
|
|
72283
|
-
// useEffect(() => {
|
|
72284
|
-
// if (!chatRoomId && handleSidebar) { return }
|
|
72285
|
-
// chatGetType(chatRoomId, undefined, "", "", undefined, undefined, 0, 0)
|
|
72286
|
-
// if (chatRoomId) {
|
|
72287
|
-
// getPinMessageChatRoomApi(chatRoomId)
|
|
72288
|
-
// }
|
|
72289
|
-
// }, [chatRoomId])
|
|
72290
|
-
// const handleUnpinMessage = useCallback(async (message: any) => {
|
|
72291
|
-
// const pinId = message?.pinId || message?.id
|
|
72292
|
-
// if (!pinId) { return }
|
|
72293
|
-
// await deletePinMessage(pinId)
|
|
72294
|
-
// }, [deletePinMessage, chatRoomId])
|
|
72295
|
-
// const handleViewPinnedMessage = useCallback((message: any) => {
|
|
72296
|
-
// if (message?.id) {
|
|
72297
|
-
// //setViewingPinnedMessage(message.id)
|
|
72298
|
-
// // Tìm message element
|
|
72299
|
-
// const element = document.getElementById(`msg-${message.id}`)
|
|
72300
|
-
// const chatContainer = document.getElementById('scrollableDivChat')
|
|
72301
|
-
// if (element && chatContainer) {
|
|
72302
|
-
// // Lấy vị trí của element và container
|
|
72303
|
-
// const elementRect = element.getBoundingClientRect()
|
|
72304
|
-
// const containerRect = chatContainer.getBoundingClientRect()
|
|
72305
|
-
// // Tính toán scroll position để đưa element vào giữa container
|
|
72306
|
-
// const scrollTop = chatContainer.scrollTop
|
|
72307
|
-
// const offset = elementRect.top - containerRect.top - (containerRect.height / 2) + (elementRect.height / 2)
|
|
72308
|
-
// // Scroll trong container, không scroll toàn page
|
|
72309
|
-
// chatContainer.scrollTo({
|
|
72310
|
-
// top: scrollTop + offset,
|
|
72311
|
-
// behavior: 'smooth'
|
|
72312
|
-
// })
|
|
72313
|
-
// // Highlight message
|
|
72314
|
-
// const originalBg = element.style.backgroundColor
|
|
72315
|
-
// const originalZIndex = element.style.zIndex
|
|
72316
|
-
// element.style.backgroundColor = '#fff3cd'
|
|
72317
|
-
// element.style.zIndex = '1000'
|
|
72318
|
-
// element.style.position = 'relative'
|
|
72319
|
-
// element.style.transition = 'background-color 0.3s'
|
|
72320
|
-
// // Auto close sau 500ms
|
|
72321
|
-
// setTimeout(() => {
|
|
72322
|
-
// element.style.backgroundColor = originalBg || ''
|
|
72323
|
-
// element.style.zIndex = originalZIndex || ''
|
|
72324
|
-
// //setViewingPinnedMessage(null)
|
|
72325
|
-
// }, 500)
|
|
72326
|
-
// } else {
|
|
72327
|
-
// console.log('Message not found in current view, may need to load more messages')
|
|
72328
|
-
// setTimeout(() => {
|
|
72329
|
-
// //setViewingPinnedMessage(null)
|
|
72330
|
-
// }, 2000)
|
|
72331
|
-
// }
|
|
72332
|
-
// }
|
|
72333
|
-
// }, [])
|
|
72182
|
+
useCallback((idx) => {
|
|
72183
|
+
const newArr = [...imgCopy];
|
|
72184
|
+
newArr.splice(idx, 1);
|
|
72185
|
+
setImgCopy(newArr);
|
|
72186
|
+
}, [imgCopy]);
|
|
72187
|
+
useCallback((e, chatMessage) => {
|
|
72188
|
+
const selection = window.document.getSelection();
|
|
72189
|
+
setIsOpen(true);
|
|
72190
|
+
setPosition({ x: e.clientX, y: e.clientY });
|
|
72191
|
+
if (e.target) {
|
|
72192
|
+
setCurrentMessage(chatMessage);
|
|
72193
|
+
}
|
|
72194
|
+
// Detect ảnh được click từ data attribute
|
|
72195
|
+
const fileIndex = e.target?.dataset?.fileIndex;
|
|
72196
|
+
if (fileIndex !== undefined && chatMessage?.path) {
|
|
72197
|
+
setClickedImageFile(chatMessage.path[parseInt(fileIndex)]);
|
|
72198
|
+
}
|
|
72199
|
+
else {
|
|
72200
|
+
setClickedImageFile(null);
|
|
72201
|
+
}
|
|
72202
|
+
e.preventDefault();
|
|
72203
|
+
const contextType = selection.toString() ? 'selection' : chatMessage?.type ? chatMessage.type : 'default';
|
|
72204
|
+
const config = CONTEXT_CONFIG[contextType];
|
|
72205
|
+
setListContextShow({ list: config.show, type: "SHOW" });
|
|
72206
|
+
setListContextHide({ list: config.hide, type: "HIDE" });
|
|
72207
|
+
}, []);
|
|
72208
|
+
const handleTypingStart = () => {
|
|
72209
|
+
if (!isTypingRef.current && connection && chatRoomId) {
|
|
72210
|
+
connection.invoke('StartTyping', chatRoomId).catch(console.error);
|
|
72211
|
+
isTypingRef.current = true;
|
|
72212
|
+
}
|
|
72213
|
+
};
|
|
72214
|
+
const handleTypingStop = () => {
|
|
72215
|
+
if (typingTimeoutRef.current) {
|
|
72216
|
+
clearTimeout(typingTimeoutRef.current);
|
|
72217
|
+
}
|
|
72218
|
+
typingTimeoutRef.current = setTimeout(() => {
|
|
72219
|
+
if (isTypingRef.current && connection && chatRoomId) {
|
|
72220
|
+
connection.invoke('StopTyping', chatRoomId).catch(console.error);
|
|
72221
|
+
isTypingRef.current = false;
|
|
72222
|
+
}
|
|
72223
|
+
}, 2000);
|
|
72224
|
+
};
|
|
72225
|
+
useCallback((editorState) => {
|
|
72226
|
+
if (inputContainer &&
|
|
72227
|
+
inputContainer.current &&
|
|
72228
|
+
inputContainer.current.clientHeight > 50) {
|
|
72229
|
+
setIsMultiLine(true);
|
|
72230
|
+
}
|
|
72231
|
+
else {
|
|
72232
|
+
setIsMultiLine(false);
|
|
72233
|
+
}
|
|
72234
|
+
editorState.read(() => {
|
|
72235
|
+
handleTypingStart();
|
|
72236
|
+
handleTypingStop();
|
|
72237
|
+
});
|
|
72238
|
+
}, [inputContainer, connection, chatRoomId]);
|
|
72239
|
+
useEffect(() => {
|
|
72240
|
+
if (active) {
|
|
72241
|
+
setReplyMessage(null);
|
|
72242
|
+
setImgCopy([]);
|
|
72243
|
+
setIsAtBottom(true);
|
|
72244
|
+
prevListLength.current = 0;
|
|
72245
|
+
}
|
|
72246
|
+
}, [
|
|
72247
|
+
active,
|
|
72248
|
+
dataInfo
|
|
72249
|
+
//chatRoomId,
|
|
72250
|
+
//chatGetType
|
|
72251
|
+
]);
|
|
72252
|
+
// Chuyển phòng thì load lại message + pinned messages
|
|
72253
|
+
useEffect(() => {
|
|
72254
|
+
if (!chatRoomId && handleSidebar) {
|
|
72255
|
+
return;
|
|
72256
|
+
}
|
|
72257
|
+
chatGetType(chatRoomId, undefined, "", "", undefined, undefined, 0, 0);
|
|
72258
|
+
if (chatRoomId) {
|
|
72259
|
+
getPinMessageChatRoomApi(chatRoomId);
|
|
72260
|
+
}
|
|
72261
|
+
}, [chatRoomId]);
|
|
72262
|
+
useCallback(async (message) => {
|
|
72263
|
+
const pinId = message?.pinId || message?.id;
|
|
72264
|
+
if (!pinId) {
|
|
72265
|
+
return;
|
|
72266
|
+
}
|
|
72267
|
+
await deletePinMessage(pinId);
|
|
72268
|
+
}, [deletePinMessage, chatRoomId]);
|
|
72269
|
+
useCallback((message) => {
|
|
72270
|
+
if (message?.id) {
|
|
72271
|
+
//setViewingPinnedMessage(message.id)
|
|
72272
|
+
// Tìm message element
|
|
72273
|
+
const element = document.getElementById(`msg-${message.id}`);
|
|
72274
|
+
const chatContainer = document.getElementById('scrollableDivChat');
|
|
72275
|
+
if (element && chatContainer) {
|
|
72276
|
+
// Lấy vị trí của element và container
|
|
72277
|
+
const elementRect = element.getBoundingClientRect();
|
|
72278
|
+
const containerRect = chatContainer.getBoundingClientRect();
|
|
72279
|
+
// Tính toán scroll position để đưa element vào giữa container
|
|
72280
|
+
const scrollTop = chatContainer.scrollTop;
|
|
72281
|
+
const offset = elementRect.top - containerRect.top - (containerRect.height / 2) + (elementRect.height / 2);
|
|
72282
|
+
// Scroll trong container, không scroll toàn page
|
|
72283
|
+
chatContainer.scrollTo({
|
|
72284
|
+
top: scrollTop + offset,
|
|
72285
|
+
behavior: 'smooth'
|
|
72286
|
+
});
|
|
72287
|
+
// Highlight message
|
|
72288
|
+
const originalBg = element.style.backgroundColor;
|
|
72289
|
+
const originalZIndex = element.style.zIndex;
|
|
72290
|
+
element.style.backgroundColor = '#fff3cd';
|
|
72291
|
+
element.style.zIndex = '1000';
|
|
72292
|
+
element.style.position = 'relative';
|
|
72293
|
+
element.style.transition = 'background-color 0.3s';
|
|
72294
|
+
// Auto close sau 500ms
|
|
72295
|
+
setTimeout(() => {
|
|
72296
|
+
element.style.backgroundColor = originalBg || '';
|
|
72297
|
+
element.style.zIndex = originalZIndex || '';
|
|
72298
|
+
//setViewingPinnedMessage(null)
|
|
72299
|
+
}, 500);
|
|
72300
|
+
}
|
|
72301
|
+
else {
|
|
72302
|
+
console.log('Message not found in current view, may need to load more messages');
|
|
72303
|
+
setTimeout(() => {
|
|
72304
|
+
//setViewingPinnedMessage(null)
|
|
72305
|
+
}, 2000);
|
|
72306
|
+
}
|
|
72307
|
+
}
|
|
72308
|
+
}, []);
|
|
72334
72309
|
// const onKeyDown = (event: any) => {
|
|
72335
72310
|
// if (event.code === 'NumpadEnter') {
|
|
72336
72311
|
// event.preventDefault()
|