From 1119cc65b8e81ce7f2fa27b9836cfff64e8bebb7 Mon Sep 17 00:00:00 2001 From: benya Date: Sun, 8 Mar 2026 10:30:38 +0300 Subject: [PATCH] fix(web): chat sidebar layout, media context actions, and scrollable chat info --- web/src/components/ChatInfoPanel.tsx | 108 +++++++----- web/src/components/ChatList.tsx | 2 +- web/src/components/MessageList.tsx | 245 ++++++++++++++++++++++----- web/src/components/NewChatPanel.tsx | 4 +- 4 files changed, 271 insertions(+), 88 deletions(-) diff --git a/web/src/components/ChatInfoPanel.tsx b/web/src/components/ChatInfoPanel.tsx index 4db4c43..0213fe4 100644 --- a/web/src/components/ChatInfoPanel.tsx +++ b/web/src/components/ChatInfoPanel.tsx @@ -45,12 +45,21 @@ export function ChatInfoPanel({ chatId, open, onClose }: Props) { const [attachments, setAttachments] = useState([]); const [attachmentsLoading, setAttachmentsLoading] = useState(false); const [attachmentCtx, setAttachmentCtx] = useState<{ x: number; y: number; url: string } | null>(null); + const [attachmentsTab, setAttachmentsTab] = useState<"media" | "files">("media"); const myRole = useMemo(() => members.find((m) => m.user_id === me?.id)?.role, [members, me?.id]); const isGroupLike = chat?.type === "group" || chat?.type === "channel"; const showMembersSection = Boolean(chat && isGroupLike && !chat.is_saved); const canManageMembers = Boolean(isGroupLike && (myRole === "owner" || myRole === "admin")); const canChangeRoles = Boolean(isGroupLike && myRole === "owner"); + const mediaAttachments = useMemo( + () => attachments.filter((item) => item.file_type.startsWith("image/") || item.file_type.startsWith("video/")), + [attachments] + ); + const fileAttachments = useMemo( + () => attachments.filter((item) => !item.file_type.startsWith("image/") && !item.file_type.startsWith("video/")), + [attachments] + ); async function refreshMembers(targetChatId: number) { const nextMembers = await listChatMembers(targetChatId); @@ -139,17 +148,18 @@ export function ChatInfoPanel({ chatId, open, onClose }: Props) { onClose(); }} > -