changeset 42:1d2c65d260d1

factor out breadcrumbs
author drewp@bigasterisk.com
date Thu, 05 Dec 2024 21:34:00 -0800
parents 44bd161e4779
children a7b644dc1b4b
files src/VBreadcrumbs.ts src/VideoPage.ts src/breadcrumb_test.html
diffstat 3 files changed, 62 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/VBreadcrumbs.ts	Thu Dec 05 21:34:00 2024 -0800
@@ -0,0 +1,40 @@
+import { html, LitElement, TemplateResult } from "lit";
+import { customElement, property } from "lit/decorators.js";
+
+@customElement("v-breadcrumbs")
+export class VBreadcrumbs extends LitElement {
+  // Like "/dir1/dir2/" or "/dir1/dir2/vid1", each of which will make two
+  // crumbs: TOP and dir1 (because dir2 appears elsewhere on the page)
+  @property() dirPath?: string;
+
+  render() {
+    if (this.dirPath == null) return html` dirpath==null `;
+
+    const crumbs = this.getCrumbs();
+    return html` <sl-breadcrumb>${crumbs.map((c) => html` <sl-breadcrumb-item><a href=${c.href}>${c.label}</a> </sl-breadcrumb-item> `)}</sl-breadcrumb> `;
+  }
+
+  private getCrumbs() {
+    if (this.dirPath == null) throw new Error("dirPath is null");
+    const segs: Array<string | TemplateResult> = this.dirPath.split("/");
+    if (segs[0] != "") {
+      throw new Error(`bad path: ${this.dirPath}`);
+    }
+
+    segs[0] = html`<sl-icon name="house"></sl-icon> TOP`;
+    const tailSegCount = 1;
+
+    const currentPageSegCount = 1;
+    segs.splice(segs.length - (tailSegCount + currentPageSegCount), tailSegCount + currentPageSegCount);
+    const crumbs = [];
+    let cur = "/";
+    for (const seg of segs) {
+      if (seg !== segs[0]) {
+        cur += seg + "/";
+      }
+      const href = "/video" + cur;
+      crumbs.push({ href: href, label: seg });
+    }
+    return crumbs;
+  }
+}
--- a/src/VideoPage.ts	Thu Dec 05 21:33:25 2024 -0800
+++ b/src/VideoPage.ts	Thu Dec 05 21:34:00 2024 -0800
@@ -6,7 +6,7 @@
 export { PagePlayer } from "./PagePlayer";
 export { VideoSection } from "./VideoSection";
 import { Routes, Router } from "@lit-labs/router";
-
+export { VBreadcrumbs } from "./VBreadcrumbs";
 interface VideoFile {
   webRelPath: string;
   webDataPath: string;
@@ -71,21 +71,12 @@
   private _router = new Router(this, [new route()], {});
 
   render() {
-    const requestedPath = this._router.params[0];
-    const segs = ["."].concat(requestedPath || "".split("/"));
-    const crumbs = [];
-    // todo: goal is to have '🏠 TOP' and every level not including current dir
-    for (let i = 0; i < segs.length; i++) {
-      const seg = segs[i];
-      const href = "../".repeat(segs.length - i - 1);
-      const label = i == 0 ? html`<sl-icon name="house"></sl-icon>` : seg;
-      console.log(href, label);
-      crumbs.push(html`<sl-breadcrumb-item><a href=${href}>${label}</a></sl-breadcrumb-item>`);
-    }
+    const requestedPath = "/" + this._router.params[0];
+
     return html`
       <header>
-        <img src="${this._router.link("/video/logo1.png")}" title="JelloBello" />
-        <sl-breadcrumb>${crumbs}</sl-breadcrumb>
+        <img src=${this._router.link("/video/logo1.png")} title="JelloBello" />
+        <v-breadcrumbs .link=${this._router.link} dirPath=${requestedPath}></v-breadcrumbs>
       </header>
       <main>${this._router.outlet()}</main>
       <footer>
@@ -180,7 +171,7 @@
   }
 
   renderSubdir(subdir: Subdir): TemplateResult {
-    return html`<div class="subdir"><a href="${this.link(subdir.path) + "/"}">${subdir.label}</a></div>`;
+    return html`<a href="${this.link(subdir.path) + "/"}"><div class="subdir">${subdir.label}</div></a>`;
   }
 
   renderVideoListing(video: VideoFile) {
@@ -200,8 +191,9 @@
       html`${this.videoListings.subdirs.map((s) => this.renderSubdir(s))}`, //
       html`${this.videoListings.videos.map((v) => this.renderVideoListing(v))}`,
     ];
+    const dirTitle = this.dirName ? html`<h2>${this.dirName.slice(0, -1)}</h2>` : html``;
     return html`
-      <h2>${this.dirName}</h2>
+      ${dirTitle}
       <div class="listing">${listings}</div>
 
       <div id="scrim" @click=${this.closePlayer}></div>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/breadcrumb_test.html	Thu Dec 05 21:34:00 2024 -0800
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>video on bigasterisk</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1" />
+    <link rel="stylesheet" type="text/css" media="screen" href="./main.css" />
+    <script type="module" src="./main.ts"></script>
+  </head>
+  <body style="background: #020f16" class="sl-theme-dark">
+    <p>test1 <v-breadcrumbs dirPath="/dir1/dir2/"></v-breadcrumbs></p>
+    <p>test2 <v-breadcrumbs dirPath="/dir1/dir2/vid1"></v-breadcrumbs></p>
+    <p>test3 <v-breadcrumbs dirPath="/"></v-breadcrumbs></p>
+  </body>
+</html>