fix(threads): thread panel no longer squeezes the composers (#218)
CI / Build & Quality Checks (push) Canceled after 0s
CI / Trigger Desktop Build (push) Canceled after 0s
CI / Secret scan (gitleaks) (push) Canceled after 0s
CI / Docker image build & smoke test (push) Canceled after 0s
CI / Playwright smoke (e2e) (push) Canceled after 0s
CI / Build & Quality Checks (push) Canceled after 0s
CI / Trigger Desktop Build (push) Canceled after 0s
CI / Secret scan (gitleaks) (push) Canceled after 0s
CI / Docker image build & smoke test (push) Canceled after 0s
CI / Playwright smoke (e2e) (push) Canceled after 0s
Two causes. (1) Three right-hand columns don't fit under ~1500 px: the member
drawer now yields to an open content panel (thread / gallery / widgets /
threads list) on desktops ≤ 1500 px and returns when it closes, like Element.
(2) The thread composer rendered the full ten-button toolbar inside a 360 px
panel, leaving 24 px for the input ('S…') at every width — RoomInput gains a
compactLayout prop (the phone one-row '+ | input | emoji | send' layout) and
ThreadPanel uses it.
Measured headless: 1400 px thread open → drawer hidden, composers 328/168 px
(was 422 → 'Send a mes…' + 24 px); 1600 px → drawer stays, thread composer 168 px.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
const read = (query: string): boolean =>
|
||||
typeof window !== 'undefined' &&
|
||||
typeof window.matchMedia === 'function' &&
|
||||
window.matchMedia(query).matches;
|
||||
|
||||
/** Reactive `window.matchMedia(query).matches`. SSR-safe (false). */
|
||||
export function useMediaQuery(query: string): boolean {
|
||||
const [matches, setMatches] = useState<boolean>(() => read(query));
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {
|
||||
return undefined;
|
||||
}
|
||||
const mql = window.matchMedia(query);
|
||||
const onChange = (event: MediaQueryListEvent) => setMatches(event.matches);
|
||||
setMatches(mql.matches);
|
||||
mql.addEventListener('change', onChange);
|
||||
return () => mql.removeEventListener('change', onChange);
|
||||
}, [query]);
|
||||
|
||||
return matches;
|
||||
}
|
||||
Reference in New Issue
Block a user