Files
client/plans/template-update-plan.md
2026-04-17 16:52:51 -04:00

9.6 KiB

Template.html Update Plan

Overview

Update www/template.html to match the formatting and features from www/blobs.html without adding blob/blossom server functionality. The template should serve as a clean starting point for future pages.

Key Changes Required

1. Header Updates

Current State (template.html):

  • Uses static SVG hamburger menu with hardcoded path
  • Simple SVG structure in #divSvgHam

Target State (blobs.html):

  • Uses HamburgerMorphing library for animated hamburger menu
  • Hamburger morphs to X when sidenav opens
  • Container div for HamburgerMorphing injection

Changes:

  • Replace static SVG with container div for HamburgerMorphing
  • Add SVG.js library dependency (required by HamburgerMorphing)
  • Import HamburgerMorphing module
  • Initialize hamburger instance with morphing animation
  • Update click handlers to trigger morphing animations

Current State (template.html):

<div id="divFooter">
  <div id="divFoot01" class="divFooterBox"></div>
  <div id="divFoot02" class="divFooterBox"></div>
  <div id="divFoot03" class="divFooterBox"></div>
  <div id="divFoot04" class="divFooterBox"></div>
  <div id="divFoot05" class="divFooterBox"></div>
</div>

Target State (blobs.html):

<div id="divFooter" style="display: flex; flex-direction: row; justify-content: space-between; align-items: center;">
  <div id="divFooterLeft" class="divFooterSection" style="flex: 1; height: 100%; display: flex; justify-content: flex-start; align-items: center; padding: 0 10px; border-right: 3px solid var(--primary-color); gap: 5px;"></div>
  <div id="divFooterCenter" class="divFooterSection" style="flex: 1; height: 100%; display: flex; justify-content: center; align-items: center; padding: 0 10px; border-right: 3px solid var(--primary-color);"></div>
  <div id="divFooterRight" class="divFooterSection" style="flex: 1; height: 100%; display: flex; justify-content: flex-end; align-items: center; padding: 0 10px;"></div>
</div>

Changes:

  • Replace 5-box footer with 3-section layout (left, center, right)
  • Add flexbox styling for proper alignment
  • Left section: Relay status animations (HamburgerMorphing instances)
  • Center section: General status info
  • Right section: Additional info

Current State (template.html):

  • No footer in sidenav
  • Sidenav ends with divSideNavBody

Target State (blobs.html):

<div id="divVersionBar" style="flex-shrink: 0; height: max(var(--header-height), var(--header-min-height)); min-height: var(--header-min-height); background-color: var(--secondary-color); border-top: 3px solid var(--primary-color); display: flex; align-items: center; justify-content: space-between; padding: 0 20px; box-sizing: border-box;">
  <span id="versionDisplay" style="font-size: 14px; color: var(--primary-color); font-weight: 500;">v0.0.1</span>
  <div style="display: flex; gap: 10px; align-items: center;">
    <button id="themeToggleButton" style="background: none; border: none; cursor: pointer; padding: 8px; border-radius: 50%; display: flex; align-items: center; justify-content: center; transition: background-color 0.3s ease;" title="Toggle Dark/Light Mode">
      <div id="themeToggleHamburgerContainer" style="width: 24px; height: 24px; display: flex; align-items: center; justify-content: center;"></div>
    </button>
    <button id="logoutButton" style="background: none; border: none; cursor: pointer; padding: 8px; border-radius: 50%; display: flex; align-items: center; justify-content: center; transition: background-color 0.3s ease;" title="Logout">
      <div id="logoutHamburgerContainer" style="width: 24px; height: 24px; display: flex; align-items: center; justify-content: center;"></div>
    </button>
  </div>
</div>

Changes:

  • Add version bar footer to sidenav
  • Include version display
  • Add theme toggle button with HamburgerMorphing icon (moon/circle)
  • Add logout button with HamburgerMorphing icon (X)
  • Initialize HamburgerMorphing instances for both buttons

4. Relay Status Visualization

Current State (template.html):

  • No relay status visualization
  • Footer shows static pubkey info

Target State (blobs.html):

  • Dynamic relay status icons in footer left section
  • Each connected relay gets a HamburgerMorphing instance
  • Icons morph based on relay activity:
    • plus: Connected, can read and write
    • arrow_up: Only uploads
    • arrow_down: More downloads
    • carrot_up: Active write (temporary, 3 seconds)
    • carrot_down: Active read (temporary, 3 seconds)

Changes:

  • Import getRelayData and getRelayStats from init-ndk.mjs
  • Add relay status tracking variables:
    • relayStatusInstances (Map): relay URL → HamburgerMorphing instance
    • relayActivityStates (Map): relay URL → { activity, timeout }
    • lastRelayShapes (Map): relay URL → last rendered shape
  • Implement updateRelayStatusVisuals() function
  • Implement setRelayActivityState() function
  • Listen for 'ndkRelayActivity' events from worker
  • Update footer periodically with relay status

5. JavaScript Structure Updates

Variables to Add:

// Hamburger menu
let hamburgerInstance = null;
let isNavOpen = false;

// Relay status visualization
let relayStatusInstances = new Map();
let relayActivityStates = new Map();
let lastRelayShapes = new Map();

// Version bar buttons
let logoutHamburger = null;
let themeToggleHamburger = null;
let isDarkMode = false;

Functions to Add:

// Hamburger menu initialization
function initHamburgerMenu() { ... }

// Sidenav functions (update to use morphing)
function openNav() { ... }
function closeNav() { ... }
function toggleNav() { ... }

// Relay status visualization
async function updateRelayStatusVisuals() { ... }
function setRelayActivityState(relayUrl, activity) { ... }

// Update footer
const UpdateFooter = async () => { ... }

Event Listeners to Update:

// Hamburger click handler
divSvgHam.addEventListener('click', toggleNav);

// Listen for relay activity
window.addEventListener('ndkRelayActivity', (event) => { ... });
window.addEventListener('message', (event) => { ... });

// Theme toggle button
themeToggleButton.addEventListener('click', () => { ... });

// Logout button
logoutButton.addEventListener('click', async () => { ... });

6. Import Updates

Add to imports:

import { initNDKPage, getPubkey, subscribe, publishEvent, disconnect, getRelayData, getRelayStats } from './js/init-ndk.mjs';
import { HamburgerMorphing } from "./hamburger_morphing/hamburger.mjs";

Add to head:

<!-- SVG.js library (required by HamburgerMorphing) -->
<script src="https://cdn.jsdelivr.net/npm/@svgdotjs/svg.js@3.0/dist/svg.min.js"></script>

7. Initialization Sequence Updates

Current:

  1. Initialize NDK
  2. Get pubkey
  3. Start update loop

Target:

  1. Initialize hamburger menu
  2. Add click handler to hamburger
  3. Initialize version bar buttons (lazy load when sidenav opens)
  4. Initialize NDK
  5. Get pubkey
  6. Listen for relay activity events
  7. Start update loop (includes relay status updates)

Implementation Steps

Step 1: Update HTML Structure

  • Add SVG.js library to <head>
  • Replace hamburger SVG with container div
  • Update footer structure (5 boxes → 3 sections)
  • Add version bar to sidenav

Step 2: Update JavaScript Imports

  • Add HamburgerMorphing import
  • Add getRelayData and getRelayStats imports

Step 3: Add Variables

  • Add hamburger menu variables
  • Add relay status tracking variables
  • Add version bar button variables

Step 4: Implement Functions

  • Implement initHamburgerMenu()
  • Update openNav() with morphing animation
  • Update closeNav() with morphing animation
  • Add toggleNav() function
  • Implement updateRelayStatusVisuals()
  • Implement setRelayActivityState()
  • Update UpdateFooter() to include relay status

Step 5: Update Event Listeners

  • Update hamburger click handler
  • Add relay activity event listeners
  • Add theme toggle button listener
  • Add logout button listener

Step 6: Update Initialization

  • Initialize hamburger menu first
  • Lazy load version bar buttons when sidenav opens
  • Add relay activity event listeners
  • Update footer update loop

Key Differences to Maintain

Keep from template.html:

  • Generic page structure (no blob-specific functionality)
  • Example subscription/publish code in comments
  • Educational comments explaining architecture
  • Simple, clean body content

Remove from template.html:

  • Static hamburger SVG
  • 5-box footer layout
  • Simple pubkey display in footer

Add from blobs.html:

  • HamburgerMorphing animations
  • 3-section footer with relay status
  • Sidenav version bar with theme toggle and logout
  • Relay status visualization
  • Dynamic footer updates

Testing Checklist

After implementation:

  • Hamburger menu morphs to X when clicked
  • Hamburger morphs back to burger when sidenav closes
  • Footer shows relay status icons (if relays connected)
  • Relay icons animate on activity
  • Theme toggle button shows correct icon (moon/circle)
  • Theme toggle works correctly
  • Logout button shows X icon
  • Logout button works correctly
  • Footer updates every second
  • No blob-specific functionality present

Notes

  • The template should remain generic and educational
  • All HamburgerMorphing instances should be properly initialized
  • Relay status visualization should gracefully handle no relays
  • Version bar buttons should lazy load to avoid initialization errors
  • Keep all the helpful comments from template.html
  • Maintain the distributed architecture documentation