diff --git a/bun.lock b/bun.lock index 90831c8..e3a69b4 100644 --- a/bun.lock +++ b/bun.lock @@ -19,6 +19,7 @@ "applesauce-signers": "^5.2.0", "dompurify": "^3.3.3", "lean-qr": "^2.7.1", + "lucide-svelte": "^1.0.1", "marked": "^17.0.5", "mode-watcher": "^1.1.0", "nostr-tools": "^2.23.3", @@ -697,6 +698,8 @@ "lodash.startcase": ["lodash.startcase@4.4.0", "", {}, "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg=="], + "lucide-svelte": ["lucide-svelte@1.0.1", "", { "peerDependencies": { "svelte": "^3 || ^4 || ^5.0.0-next.42" } }, "sha512-WvzZgk0pqzgda+AErLvgWxHkfg/+GgUwqKMRHvzt0IqyMdmyEDzDCk3Z+Wo/3y753oIgx8u9Q4eUbWkghFa8Jg=="], + "lz-string": ["lz-string@1.5.0", "", { "bin": { "lz-string": "bin/bin.js" } }, "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ=="], "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], diff --git a/package.json b/package.json index 2da256c..5cff5d1 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "applesauce-signers": "^5.2.0", "dompurify": "^3.3.3", "lean-qr": "^2.7.1", + "lucide-svelte": "^1.0.1", "marked": "^17.0.5", "mode-watcher": "^1.1.0", "nostr-tools": "^2.23.3", diff --git a/specs.md b/specs.md new file mode 100644 index 0000000..56324f9 --- /dev/null +++ b/specs.md @@ -0,0 +1,132 @@ +# Servers Page Redesign Specs (`/servers`) + +Reference design: Figma file `SlIJqN61r5pGbbLy1w7VC5`, page `final`, frame `Redesigned` ([link](https://www.figma.com/design/SlIJqN61r5pGbbLy1w7VC5/Context-Webpage-by-Varun?node-id=37-687&t=p1oHQuBtrWIUqKC9-1)). + +## Goal + +Implement the redesigned UI/UX for the servers listing experience while preserving existing content and search behavior, and fix the loading flow so cards do not stay in skeleton state indefinitely. + +## Scope + +In scope: +- `src/routes/servers/+page.svelte` +- `src/lib/components/ServerCard.svelte` +- `src/lib/components/LoadingCard.svelte` +- `src/lib/queries/serverQueries.ts` (loading-state reliability) +- `src/lib/stores/relay-store.svelte.ts` (default relay behavior relevant to loading) + +Shared usage impact: +- Any page using `ServerCard` should remain visually coherent after the new compact card layout. + +Out of scope: +- Changing server content fields or text copy. +- Introducing real server health checks. +- Reworking search/filter logic semantics. + +## Content Invariants (Must Stay Constant) + +Keep existing source text/information unchanged: +- Page title, subtitle, SEO title/description. +- Search semantics and identifier resolution behavior. +- Empty/no-result messages and CTA text. +- Server data fields used in cards (`name`, `about`, `created_at`, link destination). + +Only layout/styling/spacing/state presentation may change. + +## Required UI Changes + +### 1) Search Section +- Keep existing search logic and binding to `searchTerm`. +- Update visual styling to redesigned treatment: + - full-width input in the content container + - leading search icon + - compact spacing between search and result count label +- Placeholder remains functionally the same. + +### 2) Count Label +- Place a small left-aligned label directly under search. +- Format: `X Servers available`. +- Use subdued text style (`text-sm text-muted-foreground`). + +### 3) Card Grid + Density +- Responsive layout requirements: + - Mobile (`<640px`): `1` column + - Tablet (`>=640px and <1024px`): `2` columns + - Desktop (`>=1024px`): `3` columns +- Use compact spacing (`gap-3` / equivalent) to match redesigned density. + +### 4) Pagination +- Show first `6` cards by default. +- Add centered button: `Load more servers`. +- Each click increases visible cards by `6`. +- Hide button when all matched cards are shown. +- Applies to normal list and filtered results list. + +### 5) Server Card Layout +- Use redesigned compact layout (no large thumbnail block). +- Keep content fields the same: + - server name + - short description/about + - active since date from `created_at` + - visit-server link/CTA +- Status indicator: + - static green dot and `LIVE` label by default + - no runtime connectivity check yet (future enhancement) +- Keep hover affordance (`Visit server` arrow animation and subtle shadow). + +### 6) Loading Skeleton +- Add/keep a `server-row` skeleton variant that mirrors card structure. +- Use it in all loading states on `/servers`. +- Show `6` skeleton cards for loading placeholders. + +### 7) Empty + Resolve States +- Preserve existing behavior and text for: + - no servers found + - identifier resolution in progress + - resolved single server card + go-link flow +- Ensure these states also follow responsive spacing/layout. + +## Loading Reliability Requirements (Critical Fix) + +The page must not remain indefinitely in skeleton mode when relays are unreachable or no events arrive. + +Required behavior: +- Announcements query should avoid infinite pending state for timeline streams. +- UI loading branch should transition deterministically to one of: + - real cards + - empty/no-data message + - error-safe fallback + +Implementation requirements: +- Use a bounded initial wait for announcements (e.g. timeout) in query flow. +- Ensure loading condition depends on actual initial-load semantics + data presence. +- Avoid indefinite UI-only loading loops. + +## Relay Defaults + +Default selected relays should be production/public relays in development and production unless the user explicitly switches to local dev relay mode. + +Rationale: +- Prevent accidental default to `localhost` relay causing no data and persistent loading. + +## Validation Checklist + +1. Visual parity +- Search width/icon/spacing matches redesigned intent. +- Card grid density and spacing align with redesigned frame. +- Compact card hierarchy reads clearly at all breakpoints. + +2. Responsiveness +- Mobile: 1-column compact cards, full-width controls. +- Tablet: 2-column grid. +- Desktop: 3-column grid. +- No overlap/truncation regressions in card footer/meta row. + +3. Behavior +- Pagination starts at 6 and increments by 6. +- Search logic remains unchanged (only visuals changed). +- Loading skeleton transitions to real/empty states; no stuck infinite skeleton. + +4. Quality checks +- `bun run check` passes. +- Lints for touched files are clean. diff --git a/src/lib/components/LoadingCard.svelte b/src/lib/components/LoadingCard.svelte index 8196f3e..7093251 100644 --- a/src/lib/components/LoadingCard.svelte +++ b/src/lib/components/LoadingCard.svelte @@ -1,5 +1,5 @@ @@ -32,3 +32,27 @@ {/if} + +{#if layout === 'server-row'} +
+
{truncateString(server.about)}
{/if} -+ {filteredServerAnnouncements.length} Servers available +
+ +Resolved a server from this identifier using its relay hints.
-No servers found matching "{searchTerm}"
{/if} @@ -146,25 +161,15 @@ {/if}No MCP servers found. Check back later for server announcements.