feat(chat): render Media/Files + Group Info drawers inline, not overlaid
Both right-hand panels used absolute inset-y-0 right-0 and floated on top of the conversation, hiding the messages directly underneath the panel and looking unlike Discord's actual layout. Restructure: * MediaFilesDrawer: drop absolute/z-index/shadow chrome, become a static flex column (w-[380px] shrink-0) with a left border. Internal layout unchanged. * GroupInfoPanel: same treatment (w-[320px] shrink-0). Dropped the backdrop-blur and slide-up animation that only made sense as a modal. * ConversationPage: wrap the chat content (voice rail, in-call panel, messages list, drag-overlay, input form) in a new `flex min-w-0 flex-1 flex-col` chat-column, and make that column a sibling of the drawers inside a new `flex flex-1 flex-row` row. The conversation header + search bar stay full-width above the row. Result: opening a drawer narrows the chat column instead of covering it, matching Discord's behaviour. The chat-column wrapper also carries the `relative` anchor previously held by the outer wrapper so the drag-and-drop overlay positions correctly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -93,7 +93,7 @@ export function GroupInfoPanel({ open, onClose, conversation }: Props) {
|
||||
<aside
|
||||
role="dialog"
|
||||
aria-label={t('app:group.info_title')}
|
||||
className="absolute inset-y-0 right-0 z-20 flex w-[320px] flex-col border-l border-white/5 bg-ink-900/95 shadow-xl backdrop-blur-xl animate-slide-up"
|
||||
className="flex w-[320px] shrink-0 flex-col border-l border-white/5 bg-ink-900/95"
|
||||
>
|
||||
<header className="flex items-center justify-between border-b border-white/5 px-5 py-4">
|
||||
<div>
|
||||
|
||||
@@ -31,7 +31,7 @@ export function MediaFilesDrawer({ open, index, senderNameFor, onJumpToMessage,
|
||||
if (!open) return null;
|
||||
|
||||
return (
|
||||
<aside className="absolute inset-y-0 right-0 z-40 flex w-full max-w-[380px] flex-col border-l border-line bg-surface-2 shadow-2xl dark:bg-[#2b2d31]">
|
||||
<aside className="flex w-[380px] shrink-0 flex-col border-l border-line bg-surface-2 dark:bg-[#2b2d31]">
|
||||
<header className="flex min-h-[65px] items-center gap-3 border-b border-line px-4">
|
||||
<div className="flex h-10 w-10 items-center justify-center rounded-xl bg-accent/10 text-accent">
|
||||
<ImageIcon className="h-5 w-5" />
|
||||
|
||||
@@ -643,25 +643,13 @@ export function ConversationPage() {
|
||||
/>
|
||||
)}
|
||||
|
||||
{isGroup && conversation && (
|
||||
<GroupInfoPanel
|
||||
open={infoPanelOpen}
|
||||
onClose={() => setInfoPanelOpen(false)}
|
||||
conversation={conversation}
|
||||
/>
|
||||
)}
|
||||
|
||||
<MediaFilesDrawer
|
||||
open={mediaDrawerOpen}
|
||||
index={attachmentIndex}
|
||||
senderNameFor={senderNameFor}
|
||||
onJumpToMessage={(messageId) => {
|
||||
setMediaDrawerOpen(false);
|
||||
jumpToMessage(messageId);
|
||||
}}
|
||||
onClose={() => setMediaDrawerOpen(false)}
|
||||
/>
|
||||
|
||||
{/* Layout row: chat column on the left grows to fill remaining width;
|
||||
right-hand drawers (Media/Files, Group Info) render as inline
|
||||
siblings so opening one narrows the chat instead of floating on
|
||||
top of it (Discord parity). The chat-column wrapper holds the
|
||||
`relative` anchor for the drag-and-drop overlay further below. */}
|
||||
<div className="flex min-h-0 flex-1 flex-row">
|
||||
<div className="relative flex min-w-0 flex-1 flex-col">
|
||||
{/* Discord-style persistent voice-channel rail. Always visible in groups
|
||||
so anyone can pop in without an invite-ring; hidden in 1:1s unless
|
||||
someone is already waiting. Hides automatically once we're in. */}
|
||||
@@ -1019,6 +1007,27 @@ export function ConversationPage() {
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{isGroup && conversation && (
|
||||
<GroupInfoPanel
|
||||
open={infoPanelOpen}
|
||||
onClose={() => setInfoPanelOpen(false)}
|
||||
conversation={conversation}
|
||||
/>
|
||||
)}
|
||||
|
||||
<MediaFilesDrawer
|
||||
open={mediaDrawerOpen}
|
||||
index={attachmentIndex}
|
||||
senderNameFor={senderNameFor}
|
||||
onJumpToMessage={(messageId) => {
|
||||
setMediaDrawerOpen(false);
|
||||
jumpToMessage(messageId);
|
||||
}}
|
||||
onClose={() => setMediaDrawerOpen(false)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<ForwardDialog
|
||||
open={forwardTarget !== null}
|
||||
|
||||
Reference in New Issue
Block a user