Опросы
This commit is contained in:
@@ -79,8 +79,7 @@ export default function ChatView({ onStartCall, onStartGroupCall }: { onStartCal
|
||||
const messagesEndRef = useRef<HTMLDivElement>(null);
|
||||
const scrollContainerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const handleJumpToMessage = async (msgId: string, cleanup?: () => void, targetCreatedAt?: string) => {
|
||||
cleanup?.();
|
||||
const handleJumpToMessage = async (msgId: string, sequenceId?: number) => {
|
||||
const tryScroll = () => {
|
||||
const el = document.getElementById(`msg-${msgId}`);
|
||||
if (el) {
|
||||
@@ -99,34 +98,26 @@ export default function ChatView({ onStartCall, onStartGroupCall }: { onStartCal
|
||||
NotificationStore.useNotificationStore.getState().addNotification('info', (t as any)('searchingHistory') || 'Searching message in history...');
|
||||
|
||||
const chatStore = useChatStore.getState();
|
||||
let found = false;
|
||||
const targetDate = targetCreatedAt ? new Date(targetCreatedAt).getTime() : 0;
|
||||
|
||||
for (let i = 0; i < 100; i++) {
|
||||
const chatMessages = chatStore.messages[activeChat] || [];
|
||||
const oldestLoaded = chatMessages.length > 0 ? new Date(chatMessages[0].createdAt).getTime() : Date.now();
|
||||
|
||||
if (targetDate && targetDate > oldestLoaded && chatMessages.some(m => m.id === msgId)) {
|
||||
|
||||
if (sequenceId !== undefined) {
|
||||
await chatStore.jumpToMessage(activeChat, sequenceId);
|
||||
// Wait a bit for React to render
|
||||
setTimeout(() => {
|
||||
if (!tryScroll()) {
|
||||
NotificationStore.useNotificationStore.getState().addNotification('warning', (t as any)('messageNotFound') || 'Message not found');
|
||||
}
|
||||
}, 300);
|
||||
} else {
|
||||
// Old fallback loop if no sequenceId
|
||||
let found = false;
|
||||
for (let i = 0; i < 50; i++) {
|
||||
await chatStore.loadMessages(activeChat, false, true);
|
||||
await new Promise(resolve => setTimeout(resolve, 150));
|
||||
if (tryScroll()) { found = true; break; }
|
||||
}
|
||||
|
||||
if (chatStore.hasMoreMessages[activeChat] === false && oldestLoaded <= targetDate) break;
|
||||
|
||||
await chatStore.loadMessages(activeChat, false, true);
|
||||
await new Promise(resolve => setTimeout(resolve, 150));
|
||||
|
||||
if (tryScroll()) {
|
||||
found = true;
|
||||
break;
|
||||
if (!found) {
|
||||
NotificationStore.useNotificationStore.getState().addNotification('warning', (t as any)('messageNotFound') || 'Message not found');
|
||||
}
|
||||
|
||||
if (targetDate && oldestLoaded < (targetDate - 1000 * 60 * 60)) {
|
||||
if (i > 10) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
NotificationStore.useNotificationStore.getState().addNotification('warning', (t as any)('messageNotFound') || 'Message not found');
|
||||
}
|
||||
};
|
||||
const searchInputRef = useRef<HTMLInputElement>(null);
|
||||
@@ -455,17 +446,31 @@ export default function ChatView({ onStartCall, onStartGroupCall }: { onStartCal
|
||||
|
||||
const st = container.scrollTop;
|
||||
const isScrollingUp = st < lastScrollTopRef.current;
|
||||
lastScrollTopRef.current = st;
|
||||
const stChanged = st !== lastScrollTopRef.current;
|
||||
|
||||
// Sticky Date Header Logic - Telegram style
|
||||
if (st > 100 && (isScrollingUp || st !== lastScrollTopRef.current)) {
|
||||
setShowStickyDate(true);
|
||||
if (stickyDateTimerRef.current) clearTimeout(stickyDateTimerRef.current);
|
||||
stickyDateTimerRef.current = setTimeout(() => setShowStickyDate(false), isScrollingUp ? 1500 : 1000);
|
||||
if (st > 100 && stChanged) {
|
||||
// Показываем плашку только при прокрутке или если она уже активна
|
||||
// При прокрутке вверх она должна быть видна всегда
|
||||
if (isScrollingUp) {
|
||||
setShowStickyDate(true);
|
||||
if (stickyDateTimerRef.current) clearTimeout(stickyDateTimerRef.current);
|
||||
// Таймер на 2 сек запустится только после остановки скролла
|
||||
stickyDateTimerRef.current = setTimeout(() => setShowStickyDate(false), 2000);
|
||||
} else {
|
||||
// При прокрутке вниз плашка обычно скрывается быстрее
|
||||
if (stickyDateTimerRef.current) {
|
||||
clearTimeout(stickyDateTimerRef.current);
|
||||
stickyDateTimerRef.current = setTimeout(() => setShowStickyDate(false), 800);
|
||||
}
|
||||
}
|
||||
} else if (st <= 100) {
|
||||
setShowStickyDate(false);
|
||||
if (stickyDateTimerRef.current) clearTimeout(stickyDateTimerRef.current);
|
||||
}
|
||||
|
||||
lastScrollTopRef.current = st;
|
||||
|
||||
const containerRect = container.getBoundingClientRect();
|
||||
const messageElements = container.querySelectorAll('[data-message-id]');
|
||||
|
||||
@@ -1172,7 +1177,7 @@ export default function ChatView({ onStartCall, onStartGroupCall }: { onStartCal
|
||||
onClick={() => {
|
||||
const currentPin = chatPinnedMessages[pinnedIndex % chatPinnedMessages.length];
|
||||
if (!currentPin) return;
|
||||
handleJumpToMessage(currentPin.id, undefined, currentPin.createdAt);
|
||||
handleJumpToMessage(currentPin.id, currentPin.sequenceId);
|
||||
if (chatPinnedMessages.length > 1) {
|
||||
setPinnedIndex(prev => (prev + 1) % chatPinnedMessages.length);
|
||||
}
|
||||
@@ -1353,7 +1358,7 @@ export default function ChatView({ onStartCall, onStartGroupCall }: { onStartCal
|
||||
userId={profileUserId}
|
||||
chatId={activeChat || undefined}
|
||||
onClose={() => setProfileUserId(null)}
|
||||
onGoToMessage={(msgId: any, createdAt: string) => handleJumpToMessage(msgId, () => setProfileUserId(null), createdAt)}
|
||||
onGoToMessage={(msgId: any) => { handleJumpToMessage(msgId); setProfileUserId(null); }}
|
||||
isSelf={profileUserId === user?.id}
|
||||
/>
|
||||
)}
|
||||
@@ -1364,7 +1369,7 @@ export default function ChatView({ onStartCall, onStartGroupCall }: { onStartCal
|
||||
<GroupSettings
|
||||
chat={chat}
|
||||
onClose={() => setShowGroupSettings(false)}
|
||||
onGoToMessage={(msgId) => handleJumpToMessage(msgId, () => setShowGroupSettings(false))}
|
||||
onGoToMessage={(msgId) => { handleJumpToMessage(msgId); setShowGroupSettings(false); }}
|
||||
/>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
|
||||
Reference in New Issue
Block a user