Mercurial > code > home > repos > video
annotate src/VideoPage.ts @ 41:44bd161e4779
layout
author | drewp@bigasterisk.com |
---|---|
date | Thu, 05 Dec 2024 21:33:25 -0800 |
parents | b5b29f6ef5cb |
children | 1d2c65d260d1 |
rev | line source |
---|---|
39 | 1 import { LitElement, PropertyValues, TemplateResult, css, html, unsafeCSS } from "lit"; |
5
75b54be050bc
show one subdir of archive at once, with folders and parents-breadcrumbs
drewp@bigasterisk.com
parents:
4
diff
changeset
|
2 import { customElement, property } from "lit/decorators.js"; |
22
ff73b95fc72f
frontend cleanups and improvements. this commit contains some future work too
drewp@bigasterisk.com
parents:
13
diff
changeset
|
3 import { PagePlayer, ShakaVideoElement } from "./PagePlayer"; |
ff73b95fc72f
frontend cleanups and improvements. this commit contains some future work too
drewp@bigasterisk.com
parents:
13
diff
changeset
|
4 import maincss from "./main.css?inline"; |
24 | 5 export { SlProgressBar } from "@shoelace-style/shoelace"; |
22
ff73b95fc72f
frontend cleanups and improvements. this commit contains some future work too
drewp@bigasterisk.com
parents:
13
diff
changeset
|
6 export { PagePlayer } from "./PagePlayer"; |
2
78c1a2983010
rewrite UI and file serving parts; use vite
drewp@bigasterisk.com
parents:
diff
changeset
|
7 export { VideoSection } from "./VideoSection"; |
38
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
8 import { Routes, Router } from "@lit-labs/router"; |
13
b73941c4dc0a
more wip on ingest page; shared styles
drewp@bigasterisk.com
parents:
12
diff
changeset
|
9 |
4
c8a41359505c
server provides video listing from disk
drewp@bigasterisk.com
parents:
2
diff
changeset
|
10 interface VideoFile { |
c8a41359505c
server provides video listing from disk
drewp@bigasterisk.com
parents:
2
diff
changeset
|
11 webRelPath: string; |
39 | 12 webDataPath: string; |
4
c8a41359505c
server provides video listing from disk
drewp@bigasterisk.com
parents:
2
diff
changeset
|
13 label: string; |
c8a41359505c
server provides video listing from disk
drewp@bigasterisk.com
parents:
2
diff
changeset
|
14 } |
39 | 15 |
5
75b54be050bc
show one subdir of archive at once, with folders and parents-breadcrumbs
drewp@bigasterisk.com
parents:
4
diff
changeset
|
16 interface Subdir { |
75b54be050bc
show one subdir of archive at once, with folders and parents-breadcrumbs
drewp@bigasterisk.com
parents:
4
diff
changeset
|
17 label: string; |
75b54be050bc
show one subdir of archive at once, with folders and parents-breadcrumbs
drewp@bigasterisk.com
parents:
4
diff
changeset
|
18 path: string; |
75b54be050bc
show one subdir of archive at once, with folders and parents-breadcrumbs
drewp@bigasterisk.com
parents:
4
diff
changeset
|
19 } |
75b54be050bc
show one subdir of archive at once, with folders and parents-breadcrumbs
drewp@bigasterisk.com
parents:
4
diff
changeset
|
20 |
39 | 21 interface VideoListings { |
22 videos: VideoFile[]; | |
23 subdirs: Subdir[]; | |
24 } | |
25 | |
5
75b54be050bc
show one subdir of archive at once, with folders and parents-breadcrumbs
drewp@bigasterisk.com
parents:
4
diff
changeset
|
26 function subdirQuery(subdir: string): string { |
75b54be050bc
show one subdir of archive at once, with folders and parents-breadcrumbs
drewp@bigasterisk.com
parents:
4
diff
changeset
|
27 return "subdir=" + encodeURIComponent(subdir); |
75b54be050bc
show one subdir of archive at once, with folders and parents-breadcrumbs
drewp@bigasterisk.com
parents:
4
diff
changeset
|
28 } |
4
c8a41359505c
server provides video listing from disk
drewp@bigasterisk.com
parents:
2
diff
changeset
|
29 |
39 | 30 class route { |
31 path = "/video/*"; | |
32 videoListings: VideoListings | null = null; | |
33 showVid: string | null = null; | |
34 dirName?: string; | |
35 | |
36 link(wrp: string): string { | |
37 return "/video/" + wrp; | |
38 } | |
39 | |
40 async enter(params: { [key: string]: string | undefined }): Promise<boolean> { | |
41 const webRelPath = "/" + params[0]!; | |
42 this.dirName = webRelPath.replace(/.*\/([^/]+)/, "$1"); | |
43 const resp = await fetch("/video/api/videos?" + subdirQuery(webRelPath)); | |
44 if (resp.status == 404) { | |
45 return false; | |
46 } | |
47 this.videoListings = await resp.json(); | |
48 | |
49 if (webRelPath.endsWith("/")) { | |
50 this.showVid = null; | |
51 } else { | |
52 this.showVid = webRelPath; | |
53 } | |
54 | |
55 return true; | |
56 } | |
57 | |
58 render(p: { [key: string]: string | undefined }) { | |
59 return html`<video-page2 | |
60 .link=${this.link.bind(this)} | |
61 .showVid=${this.showVid} | |
62 .videoListings=${this.videoListings} | |
63 .dirName=${this.dirName} | |
64 ></video-page2>`; | |
65 } | |
66 } | |
67 | |
2
78c1a2983010
rewrite UI and file serving parts; use vite
drewp@bigasterisk.com
parents:
diff
changeset
|
68 @customElement("video-page") |
78c1a2983010
rewrite UI and file serving parts; use vite
drewp@bigasterisk.com
parents:
diff
changeset
|
69 export class VideoPage extends LitElement { |
38
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
70 static styles = [unsafeCSS(maincss)]; |
39 | 71 private _router = new Router(this, [new route()], {}); |
38
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
72 |
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
73 render() { |
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
74 const requestedPath = this._router.params[0]; |
39 | 75 const segs = ["."].concat(requestedPath || "".split("/")); |
76 const crumbs = []; | |
77 // todo: goal is to have '🏠 TOP' and every level not including current dir | |
78 for (let i = 0; i < segs.length; i++) { | |
79 const seg = segs[i]; | |
80 const href = "../".repeat(segs.length - i - 1); | |
81 const label = i == 0 ? html`<sl-icon name="house"></sl-icon>` : seg; | |
82 console.log(href, label); | |
83 crumbs.push(html`<sl-breadcrumb-item><a href=${href}>${label}</a></sl-breadcrumb-item>`); | |
84 } | |
38
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
85 return html` |
39 | 86 <header> |
87 <img src="${this._router.link("/video/logo1.png")}" title="JelloBello" /> | |
88 <sl-breadcrumb>${crumbs}</sl-breadcrumb> | |
89 </header> | |
90 <main>${this._router.outlet()}</main> | |
41 | 91 <footer> |
92 <bigast-loginbar></bigast-loginbar> | |
93 <span><a href="ingest/">Add new videos...</a></span> | |
94 </footer> | |
38
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
95 `; |
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
96 } |
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
97 } |
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
98 |
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
99 @customElement("video-page2") |
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
100 export class VideoPage2 extends LitElement { |
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
101 @property() showVid?: string; |
39 | 102 @property() videoListings?: VideoListings; |
38
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
103 @property() link!: (s: string) => string; |
39 | 104 @property() dirName?: string; |
38
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
105 |
31 | 106 protected firstUpdated(_changedProperties: PropertyValues): void { |
107 document.addEventListener("keydown", (e) => { | |
108 if (e.key == "Escape") { | |
109 this.closePlayer(); | |
110 } | |
111 }); | |
112 } | |
39 | 113 |
38
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
114 protected update(changedProperties: PropertyValues<this>): void { |
39 | 115 const resp = changedProperties.has("videoListings"); |
38
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
116 if (resp) { |
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
117 // if (this.showVid) { |
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
118 // this.openPlayer(); |
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
119 // } else { |
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
120 // this.closePlayer(); |
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
121 // } |
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
122 } |
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
123 super.update(changedProperties); |
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
124 } |
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
125 |
5
75b54be050bc
show one subdir of archive at once, with folders and parents-breadcrumbs
drewp@bigasterisk.com
parents:
4
diff
changeset
|
126 static styles = [ |
13
b73941c4dc0a
more wip on ingest page; shared styles
drewp@bigasterisk.com
parents:
12
diff
changeset
|
127 unsafeCSS(maincss), |
5
75b54be050bc
show one subdir of archive at once, with folders and parents-breadcrumbs
drewp@bigasterisk.com
parents:
4
diff
changeset
|
128 css` |
38
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
129 :host { |
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
130 display: block; |
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
131 } |
41 | 132 |
133 video-section { | |
134 margin: 8px; | |
135 } | |
136 | |
12 | 137 .listing a { |
5
75b54be050bc
show one subdir of archive at once, with folders and parents-breadcrumbs
drewp@bigasterisk.com
parents:
4
diff
changeset
|
138 font-size: 20px; |
6
ccfea3625cf6
render thumbs and display them (no video player at all atm)
drewp@bigasterisk.com
parents:
5
diff
changeset
|
139 text-transform: uppercase; |
ccfea3625cf6
render thumbs and display them (no video player at all atm)
drewp@bigasterisk.com
parents:
5
diff
changeset
|
140 text-underline-offset: 10px; |
5
75b54be050bc
show one subdir of archive at once, with folders and parents-breadcrumbs
drewp@bigasterisk.com
parents:
4
diff
changeset
|
141 } |
38
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
142 |
41 | 143 .listing a .subdir { |
144 transition: background 0.5s; | |
145 transition-delay: 0.1s; | |
146 background: #4ea1bd21; | |
147 } | |
148 | |
149 .listing a:hover .subdir { | |
150 transition: background 0.5s; | |
151 background: #4ea1bd66; | |
152 } | |
153 | |
5
75b54be050bc
show one subdir of archive at once, with folders and parents-breadcrumbs
drewp@bigasterisk.com
parents:
4
diff
changeset
|
154 .subdir { |
75b54be050bc
show one subdir of archive at once, with folders and parents-breadcrumbs
drewp@bigasterisk.com
parents:
4
diff
changeset
|
155 vertical-align: top; |
75b54be050bc
show one subdir of archive at once, with folders and parents-breadcrumbs
drewp@bigasterisk.com
parents:
4
diff
changeset
|
156 color: white; |
75b54be050bc
show one subdir of archive at once, with folders and parents-breadcrumbs
drewp@bigasterisk.com
parents:
4
diff
changeset
|
157 padding: 11px; |
75b54be050bc
show one subdir of archive at once, with folders and parents-breadcrumbs
drewp@bigasterisk.com
parents:
4
diff
changeset
|
158 display: inline-block; |
75b54be050bc
show one subdir of archive at once, with folders and parents-breadcrumbs
drewp@bigasterisk.com
parents:
4
diff
changeset
|
159 width: 300px; |
75b54be050bc
show one subdir of archive at once, with folders and parents-breadcrumbs
drewp@bigasterisk.com
parents:
4
diff
changeset
|
160 margin: 5px; |
41 | 161 border-radius: 2px; |
5
75b54be050bc
show one subdir of archive at once, with folders and parents-breadcrumbs
drewp@bigasterisk.com
parents:
4
diff
changeset
|
162 } |
41 | 163 |
164 .subdir:after { | |
165 content: " › "; | |
166 color: #979797; | |
167 } | |
168 | |
8
f80f8c22752d
start PagePlayer, a singleton player that appears on top
drewp@bigasterisk.com
parents:
6
diff
changeset
|
169 #scrim { |
22
ff73b95fc72f
frontend cleanups and improvements. this commit contains some future work too
drewp@bigasterisk.com
parents:
13
diff
changeset
|
170 position: fixed; |
8
f80f8c22752d
start PagePlayer, a singleton player that appears on top
drewp@bigasterisk.com
parents:
6
diff
changeset
|
171 background: #000000b5; |
f80f8c22752d
start PagePlayer, a singleton player that appears on top
drewp@bigasterisk.com
parents:
6
diff
changeset
|
172 inset: 0; |
f80f8c22752d
start PagePlayer, a singleton player that appears on top
drewp@bigasterisk.com
parents:
6
diff
changeset
|
173 display: none; |
f80f8c22752d
start PagePlayer, a singleton player that appears on top
drewp@bigasterisk.com
parents:
6
diff
changeset
|
174 } |
5
75b54be050bc
show one subdir of archive at once, with folders and parents-breadcrumbs
drewp@bigasterisk.com
parents:
4
diff
changeset
|
175 `, |
75b54be050bc
show one subdir of archive at once, with folders and parents-breadcrumbs
drewp@bigasterisk.com
parents:
4
diff
changeset
|
176 ]; |
39 | 177 |
178 thumbSrc(v: VideoFile) { | |
179 return "/video/api/thumbnail?webRelPath=" + encodeURIComponent(v.webRelPath); | |
180 } | |
181 | |
182 renderSubdir(subdir: Subdir): TemplateResult { | |
183 return html`<div class="subdir"><a href="${this.link(subdir.path) + "/"}">${subdir.label}</a></div>`; | |
184 } | |
185 | |
186 renderVideoListing(video: VideoFile) { | |
187 return html`<video-section | |
188 @playVideo=${this.playVideo} | |
189 thumbRelPath=${this.thumbSrc(video)} | |
190 title="${video.label}" | |
191 manifest="/video/files/${video.webDataPath}" | |
192 ></video-section>`; | |
193 } | |
194 | |
2
78c1a2983010
rewrite UI and file serving parts; use vite
drewp@bigasterisk.com
parents:
diff
changeset
|
195 render() { |
39 | 196 if (this.videoListings == null) { |
197 return html`<div>Loading...</div>`; | |
198 } | |
199 const listings = [ | |
200 html`${this.videoListings.subdirs.map((s) => this.renderSubdir(s))}`, // | |
201 html`${this.videoListings.videos.map((v) => this.renderVideoListing(v))}`, | |
202 ]; | |
2
78c1a2983010
rewrite UI and file serving parts; use vite
drewp@bigasterisk.com
parents:
diff
changeset
|
203 return html` |
39 | 204 <h2>${this.dirName}</h2> |
205 <div class="listing">${listings}</div> | |
5
75b54be050bc
show one subdir of archive at once, with folders and parents-breadcrumbs
drewp@bigasterisk.com
parents:
4
diff
changeset
|
206 |
8
f80f8c22752d
start PagePlayer, a singleton player that appears on top
drewp@bigasterisk.com
parents:
6
diff
changeset
|
207 <div id="scrim" @click=${this.closePlayer}></div> |
f80f8c22752d
start PagePlayer, a singleton player that appears on top
drewp@bigasterisk.com
parents:
6
diff
changeset
|
208 <page-player manifest=""></page-player> |
2
78c1a2983010
rewrite UI and file serving parts; use vite
drewp@bigasterisk.com
parents:
diff
changeset
|
209 `; |
78c1a2983010
rewrite UI and file serving parts; use vite
drewp@bigasterisk.com
parents:
diff
changeset
|
210 } |
39 | 211 |
38
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
212 escapeALittle(fileUri: string): string { |
0aea9e55899b
hack in path router - dirs kind of work; putting a video in the path doesn't
drewp@bigasterisk.com
parents:
37
diff
changeset
|
213 return fileUri.replace("#", encodeURIComponent("#")); |
33
6ee4c73decf4
fix playability of vids with # in their titles
drewp@bigasterisk.com
parents:
31
diff
changeset
|
214 } |
39 | 215 |
8
f80f8c22752d
start PagePlayer, a singleton player that appears on top
drewp@bigasterisk.com
parents:
6
diff
changeset
|
216 playVideo(ev: CustomEvent) { |
f80f8c22752d
start PagePlayer, a singleton player that appears on top
drewp@bigasterisk.com
parents:
6
diff
changeset
|
217 const player = this.shadowRoot!.querySelector("page-player")! as PagePlayer; |
f80f8c22752d
start PagePlayer, a singleton player that appears on top
drewp@bigasterisk.com
parents:
6
diff
changeset
|
218 |
33
6ee4c73decf4
fix playability of vids with # in their titles
drewp@bigasterisk.com
parents:
31
diff
changeset
|
219 player.manifest = this.escapeALittle(ev.detail.manifest); |
8
f80f8c22752d
start PagePlayer, a singleton player that appears on top
drewp@bigasterisk.com
parents:
6
diff
changeset
|
220 const sv = player.shadowRoot!.querySelector("shaka-video")! as ShakaVideoElement; |
f80f8c22752d
start PagePlayer, a singleton player that appears on top
drewp@bigasterisk.com
parents:
6
diff
changeset
|
221 |
33
6ee4c73decf4
fix playability of vids with # in their titles
drewp@bigasterisk.com
parents:
31
diff
changeset
|
222 sv.src = player.manifest; |
34 | 223 sv.autoplay = true; |
8
f80f8c22752d
start PagePlayer, a singleton player that appears on top
drewp@bigasterisk.com
parents:
6
diff
changeset
|
224 player.size = "big"; |
f80f8c22752d
start PagePlayer, a singleton player that appears on top
drewp@bigasterisk.com
parents:
6
diff
changeset
|
225 this.shadowRoot!.querySelector("#scrim")!.style.display = "block"; |
f80f8c22752d
start PagePlayer, a singleton player that appears on top
drewp@bigasterisk.com
parents:
6
diff
changeset
|
226 } |
f80f8c22752d
start PagePlayer, a singleton player that appears on top
drewp@bigasterisk.com
parents:
6
diff
changeset
|
227 closePlayer() { |
f80f8c22752d
start PagePlayer, a singleton player that appears on top
drewp@bigasterisk.com
parents:
6
diff
changeset
|
228 const player = this.shadowRoot!.querySelector("page-player")! as PagePlayer; |
f80f8c22752d
start PagePlayer, a singleton player that appears on top
drewp@bigasterisk.com
parents:
6
diff
changeset
|
229 player.size = "hidden"; |
f80f8c22752d
start PagePlayer, a singleton player that appears on top
drewp@bigasterisk.com
parents:
6
diff
changeset
|
230 |
f80f8c22752d
start PagePlayer, a singleton player that appears on top
drewp@bigasterisk.com
parents:
6
diff
changeset
|
231 this.shadowRoot!.querySelector("#scrim")!.style.display = "none"; |
f80f8c22752d
start PagePlayer, a singleton player that appears on top
drewp@bigasterisk.com
parents:
6
diff
changeset
|
232 } |
2
78c1a2983010
rewrite UI and file serving parts; use vite
drewp@bigasterisk.com
parents:
diff
changeset
|
233 } |