Sketch out mobile navigation, link title to home, write lqips to js site tree

This commit is contained in:
Simon Repp
2025-08-04 11:08:57 +02:00
parent a7760a87ec
commit 4bc4dc8513
5 changed files with 85 additions and 25 deletions
+17 -5
View File
@@ -11,7 +11,7 @@ const siteTreeElements = siteTree.querySelector('.elements');
const siteTreeStatus = siteTree.querySelector('[role="status"]');
const indexSuffix = window.location.pathname.endsWith('index.html') ? 'index.html' : '';
const rootPrefix = siteTree.dataset.rootPrefix;
const rootPrefix = document.querySelector('.home').getAttribute('href');
// We only render the site tree elements (which are displayed during
// browsing/searching) into the DOM when, or shortly before, we need them,
@@ -123,14 +123,16 @@ function initializeSiteTree() {
? traversal.map(ancestor => ancestor.title).join(' > ')
: collection.title;
const spanInfo = document.createElement('span');
spanInfo.textContent = NAVIGATION_JS_T.xxxVideos(collection.videos.length);
collection.element = document.createElement('a');
collection.element.classList.add('collection');
collection.element.href = rootPrefix + collection.sitePath + indexSuffix;
collection.element.appendChild(spanText);
collection.element.appendChild(spanInfo);
if (collection.videos.length) {
const spanInfo = document.createElement('span');
spanInfo.textContent = NAVIGATION_JS_T.xxxVideos(collection.videos.length);
collection.element.appendChild(spanInfo);
}
siteTreeElements.appendChild(collection.element);
@@ -156,6 +158,16 @@ function initializeSiteTree() {
siteTreeInitialized = true;
}
// TODO: Currently unused but kept around in case we want to pick it up again
// (the lqip property is available as video.lqip in the siteContent tree structure).
// function lqipToRadialGradient(lqip) {
// const [ne, nw, se, sw] = lqip;
// return `radial-gradient(ellipse at top right, rgb(${ne[0]},${ne[1]},${ne[2]}), transparent),` +
// `radial-gradient(ellipse at top left, rgb(${nw[0]},${nw[1]},${nw[2]}), transparent),` +
// `radial-gradient(ellipse at bottom right, rgb(${se[0]},${se[1]},${se[2]}), transparent),` +
// `radial-gradient(ellipse at bottom left, rgb(${sw[0]},${sw[1]},${sw[2]}), transparent)`;
// }
function toggleBrowse() {
function updateVideo(video) {
video.element.classList.remove('visible');
+29 -4
View File
@@ -35,9 +35,12 @@ body {
border-radius: .2rem;
cursor: pointer;
outline: none;
padding: .3rem 0;
padding: .2rem 0;
}
.browse:focus-visible {
background: var(--fg-2);
color: var(--bg-1);
}
.browse:focus-visible { background: var(--bg-3); }
button {
color: var(--fg-2);
font-size: inherit;
@@ -132,11 +135,19 @@ header {
}
header .navigation {
align-items: center;
column-gap: .1em;
display: flex;
flex-wrap: wrap;
}
header .navigation > :not(:first-child) { padding-inline-start: .35em; }
header .navigation > :not(:last-child) { padding-inline-end: .35em; }
header .navigation > :nth-child(1) { padding-inline-end: .3em; }
header .navigation > :nth-child(1) {
align-items: center;
column-gap: .3em;
display: flex;
}
header .navigation > :nth-child(2) { padding-inline: .3em; }
header .navigation > :nth-child(3) { padding-inline-start: .3em; }
header .navigation > :not(:last-child) { }
header .title { color: var(--fg-1); }
img {
display: block;
@@ -495,6 +506,7 @@ img {
background: var(--bg-1);
border: 1px solid var(--bg-3);
border-radius: .5em;
box-sizing: border-box;
display: flex;
max-height: 80dvh;
min-width: min(34rem, 100vw);
@@ -511,6 +523,7 @@ img {
}
.site_tree .elements a {
align-items: center;
border-radius: .2rem;
column-gap: .7rem;
display: flex;
padding: .5rem;
@@ -704,6 +717,18 @@ video {
@media (min-width: 44rem) {
.videos_grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 45rem) {
.site_tree {
background: linear-gradient(var(--bg-1), var(--bg-1-85));
border: none;
bottom: 0;
left: 0;
max-height: unset;
padding: .5rem;
top: 2.5rem;
width: 100vw;
}
}
@media (min-width: 53rem) {
.feed_grid { grid-template-columns: 1fr 1fr; }
}
+5 -3
View File
@@ -125,7 +125,7 @@ impl Layout {
{close_icon}
</button>
</div>
<div class="site_tree" data-root-prefix="{root_prefix}">
<div class="site_tree">
<div role="status"></div>
<div class="elements"></div>
</div>
@@ -192,8 +192,10 @@ impl Layout {
<div class="layout">
<header>
<div class="navigation">
{logo_polychrome_icon}
<span class="title">{e_site_title}</span>
<a class="home" href="{root_prefix}">
{logo_polychrome_icon}
<span class="title">{e_site_title}</span>
</a>
{browse}
{search}
</div>
+25 -13
View File
@@ -47,22 +47,34 @@ pub fn generate_navigation_js(
let translations = &site.language.translations;
fn video_js(translations: &Translations, video: &Video) -> String {
let image = video.poster
.as_ref()
.and_then(|poster| poster.assets.as_ref())
.map(|assets| assets.max_160.target_filename("poster"));
let title = video.title_or_slug_or_generic_label(&translations);
let image;
let lqip;
match &video.poster {
Some(poster) => {
image = if let Some(assets) = &poster.assets {
let target_filename = assets.max_160.target_filename("poster");
format!("image:'{target_filename}',")
} else {
String::new()
};
lqip = if let Some(poster_meta) = &poster.poster_meta {
format!("lqip:{},", poster_meta.lqip.js_array())
} else {
String::new()
};
}
None => {
image = String::new();
lqip = String::new();
}
}
let site_path = video.site_path.normalized();
let r_image = if let Some(file_name) = image {
format!("image:'{file_name}',")
} else {
String::new()
};
let title = video.title_or_slug_or_generic_label(&translations);
let title_escaped = js_escape_inside_single_quoted_string(title);
format!("{{{r_image}sitePath:'{site_path}',title:'{title_escaped}'}}")
format!("{{{lqip}{image}sitePath:'{site_path}',title:'{title_escaped}'}}")
}
fn playlist_js(playlist: &Playlist, translations: &Translations) -> String {
+9
View File
@@ -37,6 +37,15 @@ impl Lqip {
format!("background: {ne}, {nw}, {se}, {sw};")
}
pub fn js_array(&self) -> String {
let ne = format!("[{},{},{}]", self.ne.0, self.ne.1, self.ne.2);
let nw = format!("[{},{},{}]", self.nw.0, self.nw.1, self.nw.2);
let se = format!("[{},{},{}]", self.se.0, self.se.1, self.se.2);
let sw = format!("[{},{},{}]", self.sw.0, self.sw.1, self.sw.2);
format!("[{ne},{nw},{se},{sw}]")
}
pub fn new() -> Lqip {
Lqip {
ne: (0, 0, 0),