feat: responsive mobile layout with slide-over sidebar

On screens ≤600px the sidebar collapses off-screen. A hamburger button
in the message header opens it as a slide-over drawer with a dim
overlay; tapping a room/network or the ✕ button closes it. Desktop
layout is unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Fredrik Johansson
2026-06-29 18:52:26 +02:00
parent 1d9c9d1524
commit 32a6f46481
5 changed files with 76 additions and 8 deletions

View File

@@ -26,7 +26,7 @@ function formatTs(ts: number | undefined): string {
return new Date(ts).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' })
}
export function Sidebar() {
export function Sidebar({ onClose }: { onClose: () => void }) {
const {
localPeer, masterId, masterAlias,
networks, activeNetworkId, activeRoom,
@@ -118,6 +118,7 @@ export function Sidebar() {
<span className="peer-id">{displayId.slice(0, 16).replace(/(.{4})/g, '$1 ').trim()}</span>
</div>
<button className="sidebar-logout" onClick={handleLogout} title="Leave network"></button>
<button className="sidebar-close-mobile" onClick={onClose} title="Close"></button>
</div>
<div className="sidebar-section">
@@ -134,7 +135,7 @@ export function Sidebar() {
<button
key={n.network_id}
className={`sidebar-item ${n.network_id === activeNetworkId ? 'active' : ''}`}
onClick={() => setActiveNetwork(n.network_id)}
onClick={() => { setActiveNetwork(n.network_id); onClose() }}
>
{n.network_name}
</button>
@@ -173,7 +174,7 @@ export function Sidebar() {
<button
key={r}
className={`sidebar-item ${r === activeRoom ? 'active' : ''}`}
onClick={() => setActiveRoom(r)}
onClick={() => { setActiveRoom(r); onClose() }}
>
{r.startsWith('dm:') ? `@ ${r.slice(3, 11)}` : `# ${r}`}
</button>