global fix and add tauri app
This commit is contained in:
@@ -2,13 +2,14 @@
|
||||
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { ArrowLeft, BarChart3, CalendarDays, ImageIcon, Loader2, MessageCircle, Paperclip, Pin, Search, Send, Settings, Smile, Trash2, X } from 'lucide-react';
|
||||
import { ArrowLeft, BarChart3, CalendarDays, ImageIcon, Loader2, MessageCircle, Paperclip, Search, Send, Settings, Smile, Trash2, X } from 'lucide-react';
|
||||
import { AvatarWithPresence } from '@/components/family/avatar-with-presence';
|
||||
import { FamilyBotChat, BotMiniAppSheet } from '@/components/family/family-bot-chat';
|
||||
import { ChatRoomAvatarDisplay } from '@/components/family/chat-room-avatar-display';
|
||||
import { ChatDateSeparator } from '@/components/chat/chat-date-separator';
|
||||
import { ChatEmojiContent } from '@/components/chat/chat-emoji-content';
|
||||
import { ChatMessageContextMenu, ChatSelectionContextMenu, SelectableMessageWrapper } from '@/components/chat/chat-message-context-menu';
|
||||
import { ChatPinnedMessageBanner } from '@/components/chat/chat-pinned-message-banner';
|
||||
import { ChatDeleteMessageDialog } from '@/components/chat/chat-delete-message-dialog';
|
||||
import { ChatMessageEditBanner } from '@/components/chat/chat-message-edit-banner';
|
||||
import { ChatMessageReactions } from '@/components/chat/chat-message-reactions';
|
||||
@@ -122,6 +123,7 @@ export function MiniFamilyChat() {
|
||||
const [chatToolsOpen, setChatToolsOpen] = useState(false);
|
||||
const [chatToolsTab, setChatToolsTab] = useState<ChatToolsTab>('search');
|
||||
const messagesEndRef = useRef<HTMLDivElement>(null);
|
||||
const autoScrollStateRef = useRef<{ id: string | null; count: number }>({ id: null, count: 0 });
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
const previousGroupIdRef = useRef<string | null>(null);
|
||||
|
||||
@@ -129,6 +131,13 @@ export function MiniFamilyChat() {
|
||||
() => messages.filter((message) => !message.isDeleted),
|
||||
[messages]
|
||||
);
|
||||
const pinnedMessage = useMemo(
|
||||
() =>
|
||||
visibleMessages
|
||||
.filter((message) => message.isPinned)
|
||||
.sort((left, right) => new Date(right.pinnedAt ?? right.createdAt).getTime() - new Date(left.pinnedAt ?? left.createdAt).getTime())[0] ?? null,
|
||||
[visibleMessages]
|
||||
);
|
||||
|
||||
const {
|
||||
selectionMode,
|
||||
@@ -152,6 +161,17 @@ export function MiniFamilyChat() {
|
||||
userId: user?.id,
|
||||
token
|
||||
});
|
||||
const pinnedVisibleText = pinnedMessage
|
||||
? getE2EMessageText({
|
||||
message: pinnedMessage,
|
||||
isE2E: activeRoomIsE2E,
|
||||
peerE2eKey,
|
||||
peerKeyLoading,
|
||||
e2ePayload: pinnedMessage.isEncrypted ? e2ePayloads[pinnedMessage.id] : null,
|
||||
e2eError: e2eErrors[pinnedMessage.id]
|
||||
})
|
||||
: '';
|
||||
const pinnedPreview = pinnedMessage ? getMessagePreviewText(pinnedMessage, pinnedVisibleText) : '';
|
||||
|
||||
const loadRooms = useCallback(async () => {
|
||||
if (!group || !token) return;
|
||||
@@ -357,8 +377,21 @@ export function MiniFamilyChat() {
|
||||
}, [activeRoom, subscribe]);
|
||||
|
||||
useEffect(() => {
|
||||
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
|
||||
}, [messages]);
|
||||
autoScrollStateRef.current = { id: null, count: 0 };
|
||||
}, [activeRoom?.id]);
|
||||
|
||||
useEffect(() => {
|
||||
const lastMessage = visibleMessages[visibleMessages.length - 1];
|
||||
const previous = autoScrollStateRef.current;
|
||||
const next = { id: lastMessage?.id ?? null, count: visibleMessages.length };
|
||||
autoScrollStateRef.current = next;
|
||||
if (!next.id) return;
|
||||
const lastMessageChanged = previous.id !== next.id;
|
||||
const messageWasAppended = next.count >= previous.count;
|
||||
if (lastMessageChanged && messageWasAppended) {
|
||||
messagesEndRef.current?.scrollIntoView({ behavior: previous.id ? 'smooth' : 'auto' });
|
||||
}
|
||||
}, [visibleMessages]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!activeRoom || !token || !messages.length) return;
|
||||
@@ -914,6 +947,18 @@ export function MiniFamilyChat() {
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
{pinnedMessage ? (
|
||||
<ChatPinnedMessageBanner
|
||||
senderName={pinnedMessage.senderName}
|
||||
preview={pinnedPreview}
|
||||
className="px-3 py-2"
|
||||
onClick={() => {
|
||||
if (!scrollToChatMessage(pinnedMessage.id)) {
|
||||
showToast('Закреплённое сообщение пока не загружено в ленте');
|
||||
}
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
<div
|
||||
className={cn('flex-1 space-y-2 overflow-y-auto bg-[#eef1f6] p-3', isDragging && 'select-none')}
|
||||
style={{ maxHeight: 'min(50vh,380px)' }}
|
||||
@@ -978,12 +1023,6 @@ export function MiniFamilyChat() {
|
||||
)
|
||||
)}
|
||||
>
|
||||
{message.isPinned && !isLargeEmoji ? (
|
||||
<div className={cn('mb-1 flex items-center gap-1 text-[10px] font-medium', mine ? 'text-[#6c8f56]' : 'text-[#3390ec]')}>
|
||||
<Pin className="h-3 w-3" />
|
||||
Закреплено
|
||||
</div>
|
||||
) : null}
|
||||
{!mine && !isLargeEmoji ? (
|
||||
<p className="mb-0.5 text-[11px] font-semibold text-[#3390ec]">{message.senderName}</p>
|
||||
) : null}
|
||||
|
||||
Reference in New Issue
Block a user