Files
client/plans/blossom-sidenav-section.md
2026-04-17 16:52:51 -04:00

5.7 KiB

Blossom Server Sidenav Section

Overview

Add a Blossom Servers section to the sidenav on all pages, mirroring the existing relay section pattern. This replaces the current server management UI that lives only in the blobs.html sidenav body with a compact, fixed-position section visible across the entire app.

Current Architecture

Relay Section Pattern (to mirror)

The relay section follows this architecture across all 20 pages:

  1. HTML — A #divRelaySection div sits between #divSideNavBody and #divVersionBar in the sidenav
  2. CSS — Global styles in www/css/client.css define #divRelaySection, #divRelaySectionTitle, #divRelayList
  3. Modulewww/js/relay-ui.mjs exports initSidenavRelaySection() and updateSidenavRelaySection()
  4. Per-page wiring — Each page imports from relay-ui.mjs, calls initSidenavRelaySection() at startup, and updateSidenavRelaySection() in its periodic UpdateFooter() loop

Current Blossom Server Management (blobs.html only)

  • Server list stored in USER_SERVER_LIST array with health status
  • Server list fetched via Nostr kind 10063 subscription
  • Full management UI (add/remove/test/publish) rendered in loadSideNav() into #divSideNavBody
  • Health checking via checkServerHealth() function

Proposed Architecture

graph TD
    A[www/js/blossom-ui.mjs] --> B[initBlossomSection]
    A --> C[updateBlossomSection]
    A --> D[getBlossomServers]
    
    B --> E[Creates HamburgerMorphing indicators]
    C --> F[Updates health status indicators]
    D --> G[Subscribes to kind 10063 events]
    D --> H[Checks server health]
    
    I[www/css/client.css] --> J[#divBlossomSection]
    I --> K[#divBlossomSectionTitle]
    I --> L[#divBlossomList]
    
    M[Every HTML page] --> N[HTML: divBlossomSection in sidenav]
    M --> O[JS: import and call blossom-ui.mjs]

Sidenav Layout Order

#divSideNav
  ├── #divSideNavHeader
  ├── #divSideNavBody        (flex: 1, scrollable)
  ├── #divRelaySection       (fixed, max-height: 200px)
  ├── #divBlossomSection     (fixed, max-height: 200px)  ← NEW
  └── #divVersionBar         (fixed height)

Implementation Steps

1. Create www/js/blossom-ui.mjs

A new module mirroring relay-ui.mjs with these exports:

  • initBlossomSection() — Called once at page init. Sets up the section, subscribes to kind 10063 events via subscribe() from init-ndk.mjs
  • updateBlossomSection() — Called periodically from UpdateFooter(). Refreshes server health indicators
  • getBlossomServers() — Returns the current server list array (for use by blobs.html and other pages that need server data)

The module will:

  • Subscribe to kind 10063 events to get the user's blossom server list
  • Parse server tags from the event
  • Perform health checks on each server
  • Render a compact list in #divBlossomList showing:
    • Server domain name
    • Health status indicator (HamburgerMorphing shape: circle=unchecked, plus=healthy, x=unhealthy)
    • Upload/mirror capability indicators

2. Add CSS to www/css/client.css

Add styles for #divBlossomSection, #divBlossomSectionTitle, #divBlossomList — identical structure to the relay section styles:

#divBlossomSection {
  flex-shrink: 0;
  max-height: 200px;
  overflow-y: auto;
  background-color: var(--secondary-color);
  border-top: 3px solid var(--primary-color);
  padding: 10px;
}

#divBlossomSectionTitle {
  font-family: pageKanji;
  font-size: 100%;
  font-weight: bold;
  margin-bottom: 10px;
  padding-bottom: 5px;
  border-bottom: 1px solid var(--muted-color);
}

#divBlossomList {
  font-size: 70%;
  font-family: var(--font-family);
}

3. Add HTML to all 20 pages

Insert between #divRelaySection and #divVersionBar:

<div id="divBlossomSection">
  <div id="divBlossomSectionTitle">ブロッサム</div>
  <div id="divBlossomList">Loading servers...</div>
</div>

4. Update all 20 pages JavaScript

Add import and initialization calls:

// Import
import { initBlossomSection, updateBlossomSection } from './js/blossom-ui.mjs';

// In main init
initBlossomSection();

// In UpdateFooter
await updateBlossomSection();

5. Refactor blobs.html

  • Remove the server management UI from loadSideNav() (the サーバー管理 section)
  • Import getBlossomServers from blossom-ui.mjs instead of maintaining its own USER_SERVER_LIST
  • Keep blob-specific functionality (upload, delete, sync, grid/list view) but source server data from the shared module
  • The sidenav body can be repurposed for blob-specific controls or left minimal

Pages to Update (20 total)

  1. www/ai.html
  2. www/blobs.html
  3. www/cal.html
  4. www/cashu.html
  5. www/db.html
  6. www/didactyl.html
  7. www/event.html
  8. www/index.html
  9. www/links.html
  10. www/msg.html
  11. www/music.html
  12. www/note.html
  13. www/npub.html
  14. www/post.html
  15. www/profile.html
  16. www/relays.html
  17. www/skills-demo.html
  18. www/strudel.html
  19. www/template.html
  20. www/todo.html
  21. www/tools.html

Key Design Decisions

  1. Japanese title: ブロッサム (Burossamu = Blossom) to match リレー pattern
  2. Health indicators: Use HamburgerMorphing shapes consistent with relay indicators
  3. Shared state: The module manages its own server list state, exposed via getBlossomServers() for pages like blobs.html that need to interact with servers
  4. Subscription: Each page subscribes to kind 10063 independently through the shared NDK worker — the module handles deduplication
  5. Health check frequency: Health checks run on init and then periodically (every 60 seconds) to avoid excessive network requests