# HG changeset patch # User drewp@bigasterisk.com # Date 1680233980 25200 # Node ID 75b54be050bcf3d0d1235e4054ee35dbc64b5893 # Parent c8a41359505ca9dc29950c14299a2a8cc9a1eac5 show one subdir of archive at once, with folders and parents-breadcrumbs diff -r c8a41359505c -r 75b54be050bc src/VideoPage.ts --- a/src/VideoPage.ts Sat Mar 25 16:01:56 2023 -0700 +++ b/src/VideoPage.ts Thu Mar 30 20:39:40 2023 -0700 @@ -1,35 +1,92 @@ import { LitElement, html, css } from "lit"; -import { customElement } from "lit/decorators.js"; +import { customElement, property } from "lit/decorators.js"; export { VideoSection } from "./VideoSection"; interface VideoFile { webRelPath: string; label: string; } +interface Subdir { + label: string; + path: string; +} + +function subdirQuery(subdir: string): string { + return "subdir=" + encodeURIComponent(subdir); +} @customElement("video-page") export class VideoPage extends LitElement { videos: VideoFile[]; + subdirs: Subdir[]; + @property() pathSegs: { label: string; subdir: string }[]; constructor() { super(); this.videos = []; + this.subdirs = []; + this.pathSegs = []; this.loadVideos(); } + updatePathSegs(subdir: string) { + this.pathSegs = [{ label: "TOP", subdir: "/" }]; + if (subdir != "/") { + let acc = ""; + const segs = subdir.split("/"); + segs.splice(0, 1); // the root + for (let seg of segs) { + acc += "/" + seg; + this.pathSegs.push({ label: seg, subdir: acc }); + } + } + } async loadVideos() { - const resp = await (await fetch("api/videos")).json(); + const u = new URL(location.href); + const subdir = u.searchParams.get("subdir") || "/"; + this.updatePathSegs(subdir); + const resp = await (await fetch("api/videos?" + subdirQuery(subdir))).json(); this.videos = resp.videos as VideoFile[]; - this.requestUpdate() + this.subdirs = resp.subdirs as Subdir[]; + this.requestUpdate(); } - static styles=[css` - - `] + static styles = [ + css` + a { + color: white; + font-size: 20px; + } + #path-segs > span { + color: white; + padding: 11px; + display: inline-block; + background: #4ea1bd21; + margin: 5px; + border-top-left-radius: 29px; + } + #path-segs > span:after { + content: " >"; + font-size: 33px; + vertical-align: middle; + color: gray; + } + .subdir { + vertical-align: top; + color: white; + padding: 11px; + display: inline-block; + width: 300px; + background: #4ea1bd21; + margin: 5px; + border-bottom-right-radius: 29px; + } + `, + ]; // allow only 1 to play. embiggen like pbskids does. render() { return html` - - - - ${this.videos.map((v)=>html``)} +
${this.pathSegs.map((seg) => html`${seg.label}`)}
+ + ${this.subdirs.map((s) => html`
${s.label}
`)} + ${this.videos.map((v) => html``)} `; } } diff -r c8a41359505c -r 75b54be050bc video.py --- a/video.py Sat Mar 25 16:01:56 2023 -0700 +++ b/video.py Thu Mar 30 20:39:40 2023 -0700 @@ -1,15 +1,13 @@ -import asyncio import logging -from typing import List -from pathlib import Path -import uvicorn + from prometheus_client import Gauge from starlette.applications import Starlette from starlette.requests import Request from starlette.responses import HTMLResponse, JSONResponse from starlette.routing import Route from starlette_exporter import PrometheusMiddleware, handle_metrics -from video_service import findAll + +from video_service import findInDir, findSubdirs logging.basicConfig(level=logging.DEBUG) log = logging.getLogger() @@ -20,11 +18,14 @@ def videos(req: Request) -> JSONResponse: + subdir = req.query_params.get('subdir', '/') # danger user input return JSONResponse({ "videos": [{ 'webRelPath': vf.webRelPath, 'label': vf.label, - } for vf in findAll()] + } for vf in findInDir(subdir)], + "subdirs": + list(findSubdirs(subdir)), })