From 7066cabac0e873b95e682600521f811306c7247c Mon Sep 17 00:00:00 2001 From: Owais Jamil Date: Mon, 7 Sep 2026 12:36:00 -0500 Subject: [PATCH] feat: improve responsive and touch-friendly layouts --- README.md | 6 ++ src/lib/components/AppWindow.svelte | 24 +++++++- src/lib/components/CollectionBrowser.svelte | 61 ++++++++++++++++++- src/lib/components/DocumentViewer.svelte | 11 ++++ src/lib/components/EyeOfGnome.svelte | 27 ++++++++ src/lib/components/Gedit.svelte | 54 +++++++++++++++- src/lib/components/IdentityInspector.svelte | 8 +++ src/lib/components/SetupDialog.svelte | 7 +++ src/lib/components/SystemMonitor.svelte | 10 ++- src/lib/components/browser/BrowserTabs.svelte | 6 ++ .../components/browser/BrowserToolbar.svelte | 21 ++++++- src/routes/+layout.svelte | 8 ++- src/routes/lexicons/+layout.svelte | 2 + 13 files changed, 238 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 19f4cb4..26b3d6a 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,12 @@ readable schema definitions, raw Lexicon JSON, and the DNS/PDS resolution trace. A public identity window for DID documents, aliases, services, verification methods, rotation keys, handle checks, and PDS links. +### System Monitor + +A live ATProto event monitor for Jetstream, the Firehose, and [Spacedust](https://www.microcosm.blue/). +It supports stream filters, event-rate and payload statistics, source +counts, recent event browsing, and decoded JSON inspection. + ### About A small “About This Computer” window with OS, account, DID, PDS, and project links. diff --git a/src/lib/components/AppWindow.svelte b/src/lib/components/AppWindow.svelte index ec0ad5c..8f1c0d6 100644 --- a/src/lib/components/AppWindow.svelte +++ b/src/lib/components/AppWindow.svelte @@ -257,7 +257,7 @@ position: relative; display: grid; grid-template-rows: auto auto auto minmax(0, 1fr); - min-width: 320px; + min-width: min(320px, 100%); min-height: 220px; overflow: hidden; background: var(--window-surface); @@ -470,4 +470,26 @@ display: none; } } + + @media (max-width: 640px) { + .app-window { + width: 100% !important; + height: 100% !important; + min-width: 0; + min-height: 0; + transform: none !important; + } + } + + @media (pointer: coarse) { + .window-controls button { + width: 2rem; + height: 2rem; + } + + .menubar button, + .toolbar button { + min-height: 2.75rem; + } + } diff --git a/src/lib/components/CollectionBrowser.svelte b/src/lib/components/CollectionBrowser.svelte index 731f175..4bdf8f5 100644 --- a/src/lib/components/CollectionBrowser.svelte +++ b/src/lib/components/CollectionBrowser.svelte @@ -92,6 +92,12 @@ }); } + function updateMobileCollection(event: Event) { + const select = event.currentTarget; + if (!(select instanceof HTMLSelectElement) || !select.value) return; + selectCollection(select.value); + } + function updatePageSize(event: Event) { const select = event.currentTarget; if (!(select instanceof HTMLSelectElement) || !identity) return; @@ -220,6 +226,16 @@
+ +
img, + .summary-card > div:not(.summary-controls) > p:not(.eyebrow) { + display: none; } .search-box { @@ -775,4 +826,12 @@ display: none; } } + + @media (pointer: coarse) { + .collection-browser button, + .collection-browser input, + .collection-browser select { + min-height: 2.75rem; + } + } diff --git a/src/lib/components/DocumentViewer.svelte b/src/lib/components/DocumentViewer.svelte index e3650ae..caf5863 100644 --- a/src/lib/components/DocumentViewer.svelte +++ b/src/lib/components/DocumentViewer.svelte @@ -153,4 +153,15 @@ border: 1px solid #d2b991; border-radius: var(--radius-1); } + + @media (max-width: 640px) { + .document-viewer { + padding: var(--space-2); + } + + .document-page, + .document-missing { + padding: var(--space-4); + } + } diff --git a/src/lib/components/EyeOfGnome.svelte b/src/lib/components/EyeOfGnome.svelte index 63c51ca..a0dfa1b 100644 --- a/src/lib/components/EyeOfGnome.svelte +++ b/src/lib/components/EyeOfGnome.svelte @@ -470,14 +470,41 @@ @media (max-width: 760px) { .eog-viewer { grid-template-columns: 1fr; + grid-template-rows: auto minmax(0, 1fr); } .blob-sidebar { + grid-template-rows: auto; + border-right: 0; + border-bottom: 1px solid #92724a; + } + + .blob-sidebar header { display: none; } + .blob-list { + grid-auto-flow: column; + grid-auto-columns: minmax(10rem, 12rem); + overflow-x: auto; + padding: var(--space-1); + } + + .blob-list button { + min-height: 2.75rem; + } + .blob-details { grid-template-columns: 1fr; } } + + @media (pointer: coarse) { + .eog-toolbar button, + .blob-list button, + .detail-actions button, + .blob-status button { + min-height: 2.75rem; + } + } diff --git a/src/lib/components/Gedit.svelte b/src/lib/components/Gedit.svelte index 33d2684..94250a5 100644 --- a/src/lib/components/Gedit.svelte +++ b/src/lib/components/Gedit.svelte @@ -48,7 +48,9 @@ }); const externalLinks = $derived.by(() => linksForRecord(record)); - const verificationStatus = $derived(record.cid ? 'CID present from com.atproto.repo.getRecord/listRecords.' : 'No CID was returned by the PDS.'); + const verificationStatus = $derived( + record.cid ? 'CID present from com.atproto.repo.getRecord/listRecords.' : 'No CID was returned by the PDS.' + ); const themeName = 'ubuntu-iterm2b24'; const ubuntuTheme: ThemeRegistration = { @@ -890,4 +892,54 @@ text-overflow: ellipsis; white-space: nowrap; } + + @media (max-width: 640px) { + .gedit-toolbar { + display: grid; + grid-template-columns: minmax(0, 1fr); + gap: var(--space-1); + } + + .tool-group, + .record-tabs { + overflow-x: auto; + } + + .document-path { + grid-row: 1; + } + + .schema-summary { + flex-wrap: wrap; + } + + .schema-summary button { + width: 100%; + } + + dl div, + .reference-list li, + .attachment-list li { + grid-template-columns: 1fr; + } + + .attachment-actions { + flex-wrap: wrap; + } + + .statusbar { + grid-template-columns: minmax(0, 1fr) auto; + } + + .statusbar span:nth-child(2) { + display: none; + } + } + + @media (pointer: coarse) { + .gedit-toolbar button, + .attachment-actions button { + min-height: 2.75rem; + } + } diff --git a/src/lib/components/IdentityInspector.svelte b/src/lib/components/IdentityInspector.svelte index 797bd64..680713e 100644 --- a/src/lib/components/IdentityInspector.svelte +++ b/src/lib/components/IdentityInspector.svelte @@ -611,4 +611,12 @@ border-bottom: 1px solid #d0b895; } } + + @media (pointer: coarse) { + .keyring-sidebar button, + .keyring-toolbar button, + .property-row button { + min-height: 2.75rem; + } + } diff --git a/src/lib/components/SetupDialog.svelte b/src/lib/components/SetupDialog.svelte index 138c0c8..7ae7bad 100644 --- a/src/lib/components/SetupDialog.svelte +++ b/src/lib/components/SetupDialog.svelte @@ -536,4 +536,11 @@ flex: 1; } } + + @media (pointer: coarse) { + input, + button { + min-height: 2.75rem; + } + } diff --git a/src/lib/components/SystemMonitor.svelte b/src/lib/components/SystemMonitor.svelte index 1ff66ce..acdaa35 100644 --- a/src/lib/components/SystemMonitor.svelte +++ b/src/lib/components/SystemMonitor.svelte @@ -820,13 +820,17 @@ grid-template-rows: auto 10rem 18rem; } .detail-pane { - grid-template-columns: minmax(12rem, 0.7fr) minmax(18rem, 1.3fr); + grid-template-columns: minmax(0, 0.7fr) minmax(0, 1.3fr); grid-template-rows: 18rem; padding: 0 var(--space-2) var(--space-2); border-left: 0; } } @media (max-width: 560px) { + .system-monitor { + grid-template-rows: auto auto auto auto; + overflow: auto; + } .stream-tabs button { min-width: 0; flex: 1; @@ -848,6 +852,9 @@ justify-self: start; white-space: normal; } + .monitor-body { + overflow: visible; + } .stat-grid { grid-template-columns: 1fr; } @@ -866,6 +873,7 @@ } @media (pointer: coarse) { .stream-tabs button, + .connection-bar input, .connection-actions button, .json-detail button { min-height: 2.75rem; diff --git a/src/lib/components/browser/BrowserTabs.svelte b/src/lib/components/browser/BrowserTabs.svelte index c0e77f0..3dea250 100644 --- a/src/lib/components/browser/BrowserTabs.svelte +++ b/src/lib/components/browser/BrowserTabs.svelte @@ -52,4 +52,10 @@ background: linear-gradient(#cf7125, #8a5527); text-shadow: 0 1px 0 rgb(0 0 0 / 0.45); } + + @media (pointer: coarse) { + button { + min-height: 2.75rem; + } + } diff --git a/src/lib/components/browser/BrowserToolbar.svelte b/src/lib/components/browser/BrowserToolbar.svelte index 983d030..4965d09 100644 --- a/src/lib/components/browser/BrowserToolbar.svelte +++ b/src/lib/components/browser/BrowserToolbar.svelte @@ -143,11 +143,28 @@ @media (max-width: 760px) { .browser-toolbar { - grid-template-columns: 1fr; + grid-template-columns: minmax(0, 1fr) auto; + } + + .nav-buttons { + grid-column: 1 / -1; + overflow-x: auto; } .location-field { - grid-template-columns: 1fr; + grid-template-columns: minmax(0, 1fr); + } + + .location-field span, + .throbber { + display: none; + } + } + + @media (pointer: coarse) { + button, + input { + min-height: 2.75rem; } } diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 158cffe..33fce6e 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -40,7 +40,12 @@ const navigateTo = goto as (url: string, options?: Parameters[1]) => ReturnType; const routeRequiresSetup = $derived(page.route.id === '/browse' && !accountSetup.isConfigured); - const routeUsesNativeWindow = $derived(page.route.id === '/' || page.route.id?.startsWith('/docs')); + const routeUsesNativeWindow = $derived( + page.route.id === '/' || + page.route.id?.startsWith('/docs') || + page.route.id?.startsWith('/lexicons') || + page.route.id?.startsWith('/live') + ); const windowTitle = $derived.by(() => { if (routeRequiresSetup) return 'AT Protocol Account Setup'; if (page.route.id === '/') return 'Welcome to Intrepid Ibex'; @@ -607,6 +612,7 @@ } .about-window, + .document-viewer-window, .gedit-window, .identity-inspector-window, .eog-window { diff --git a/src/routes/lexicons/+layout.svelte b/src/routes/lexicons/+layout.svelte index a61101b..bd62f59 100644 --- a/src/routes/lexicons/+layout.svelte +++ b/src/routes/lexicons/+layout.svelte @@ -149,6 +149,7 @@ .browser-menubar { display: flex; gap: var(--space-3); + overflow-x: auto; padding: 0.2rem var(--space-2); background: linear-gradient(#f5efe4, #d4c1a0); border-bottom: 1px solid #9f835d; @@ -156,6 +157,7 @@ } .browser-menubar span { + flex: none; padding: 0.05rem var(--space-1); } -- knotmirror 0.0.1