global fix and update bot Api

This commit is contained in:
lendry
2026-06-26 13:01:52 +03:00
parent d3ea470d02
commit aa228d84eb
29 changed files with 980 additions and 221 deletions

View File

@@ -14,6 +14,7 @@ import {
Loader2,
Mic,
Paperclip,
Pin,
Plus,
Search,
Send,
@@ -37,7 +38,7 @@ import { ChatDateSeparator } from '@/components/chat/chat-date-separator';
import { ChatToolsDialog, type ChatToolsTab } from '@/components/chat/chat-tools-dialog';
import { ChatDeleteMessageDialog } from '@/components/chat/chat-delete-message-dialog';
import { ChatMessageEditBanner } from '@/components/chat/chat-message-edit-banner';
import { ChatMessageContextMenu, SelectableMessageWrapper } from '@/components/chat/chat-message-context-menu';
import { ChatMessageContextMenu, ChatSelectionContextMenu, SelectableMessageWrapper } from '@/components/chat/chat-message-context-menu';
import { ChatMessageReactions } from '@/components/chat/chat-message-reactions';
import { ChatSelectionToolbar } from '@/components/chat/chat-selection-toolbar';
import { EmojiPicker } from '@/components/chat/emoji-picker';
@@ -78,6 +79,7 @@ import {
removeFamilyMember,
reportChatTyping,
sendChatMessage,
setChatMessagePinned,
setChatRoomMuted,
toggleChatMessageReaction,
updateFamilyGroup,
@@ -922,6 +924,39 @@ export function FamilyGroupView({ groupId }: { groupId: string }) {
}
}
async function handleTogglePin(message: ChatMessage) {
if (!token) return;
try {
const updated = await setChatMessagePinned(message.id, !message.isPinned, token);
setMessages((current) => current.map((item) => (item.id === updated.id ? updated : item)));
showToast(updated.isPinned ? 'Сообщение закреплено' : 'Сообщение откреплено');
} catch (error) {
showToast(getApiErrorMessage(error, 'Не удалось изменить закрепление') ?? 'Ошибка');
}
}
function handleSelectionReply() {
const selected = getSelectedMessages();
if (selected.length !== 1) {
showToast('Ответить можно только на одно сообщение');
return;
}
exitSelectionMode();
setReplyToMessage(selected[0]!);
setEditingMessageId(null);
setDraft('');
setEmojiOpen(false);
}
function handleSelectionPin() {
const selected = getSelectedMessages();
if (selected.length !== 1) {
showToast('Закрепить можно только одно сообщение');
return;
}
void handleTogglePin(selected[0]!);
}
function getSelectedMessages() {
const selected = new Set(selectedMessageIds);
return visibleMessages.filter((message) => selected.has(message.id));
@@ -1483,6 +1518,12 @@ export function FamilyGroupView({ groupId }: { groupId: string }) {
)
)}
>
{message.isPinned && !isLargeEmoji ? (
<div className={cn('mb-1 flex items-center gap-1 text-[11px] font-medium', mine ? 'text-[#6c8f56]' : 'text-[#3390ec]')}>
<Pin className="h-3 w-3" />
Закреплено
</div>
) : null}
{!mine ? <p className="mb-1 text-xs font-semibold text-[#3390ec]">{message.senderName}</p> : null}
{forwardedFrom ? (
<p className="mb-1 text-xs font-medium text-[#3390ec]"> Переслано от {forwardedFrom.senderName}</p>
@@ -1648,14 +1689,26 @@ export function FamilyGroupView({ groupId }: { groupId: string }) {
/>
) : null}
{selectionMode ? (
<SelectableMessageWrapper
selected={isSelected}
selectionMode
align={mine ? 'right' : 'left'}
onClick={() => toggleSelectedMessage(message.id)}
<ChatSelectionContextMenu
count={selectedMessageIds.length}
canPin={selectedMessageIds.length === 1}
pinned={getSelectedMessages()[0]?.isPinned}
onReply={handleSelectionReply}
onCopy={() => void handleBulkCopy()}
onForward={() => setForwardDialogOpen(true)}
onDelete={() => void handleBulkDelete()}
onTogglePin={handleSelectionPin}
onCancel={exitSelectionMode}
>
{bubble}
</SelectableMessageWrapper>
<SelectableMessageWrapper
selected={isSelected}
selectionMode
align={mine ? 'right' : 'left'}
onClick={() => toggleSelectedMessage(message.id)}
>
{bubble}
</SelectableMessageWrapper>
</ChatSelectionContextMenu>
) : (
<ChatMessageContextMenu
message={message}
@@ -1675,6 +1728,7 @@ export function FamilyGroupView({ groupId }: { groupId: string }) {
setSelectedMessageIds([message.id]);
setForwardDialogOpen(true);
}}
onTogglePin={() => void handleTogglePin(message)}
onSelect={() => enterSelectionMode(message.id)}
onToggleReaction={(emoji) => void handleToggleReaction(message.id, emoji)}
onCopy={() => showToast('Текст скопирован')}