Skip to main content

max / audiofiles

Declare the advanced section Same container rule as the licence section: it took the settings body and handed it back, so it becomes a Vec<Node> the screen extends. The read needs no struct. The whole of what varies is whether this host has a library mirror, and `Advanced::mirror` already answers that with an Option, so the section takes it and everything under the Library Mirror heading sits in a loop over it. That is one place saying the mirror may be absent, where a predicate would have said it seven times. No production earned. The checkbox's on-or-empty value is a value dispatch and the failed-write banner is a loop over its Option.
Author: Max Johnson <me@maxj.phd> · 2026-09-04 20:39 UTC
Signed with PGP, not checked
Commit: 1b8680bd4b4528fc7b0a072711216bb969a96b91
Parent: 448ac5f
2 files changed, +34 insertions, -40 deletions
@@ -33,11 +33,11 @@
33 33 //! [`Outcome::File`]: quasi_router::Outcome::File
34 34 //! [`Outcome::Locate`]: quasi_router::Outcome::Locate
35 35
36 - use quasi_router::layout::{FieldKind, Tone};
37 - use quasi_router::{
38 - Accepted, Act, Action, Field, Locating, Node, Request, Response, RouteError, Router, Slot,
39 - Sought,
40 - };
36 + use quasi_declare::declare;
37 + use quasi_router::layout::Tone;
38 + use quasi_router::{Accepted, Action, Locating, Request, Response, RouteError, Router, Sought};
39 +
40 + use super::Mirror;
41 41
42 42 use super::Panels;
43 43
@@ -139,45 +139,39 @@
139 139 Ok(super::settings::screen(state)?.into())
140 140 }
141 141
142 - /// The rest of the section, added below Export current theme.
143 - pub(super) fn section(body: Slot, state: &Panels<'_>) -> Slot {
144 - let body = body
145 - .with(Node::text(
146 - "Importing reads a theme .toml and adds it to your custom themes.",
147 - ))
148 - .with(Node::Act(Act::new(
149 - "Import theme...",
150 - Action::post("/settings/advanced/theme/import"),
151 - )));
142 + declare! {
143 + /// The rest of the section, spliced in below Export current theme.
144 + ///
145 + /// The mirror is a whole host's worth of the section and it is absent on
146 + /// hosts that have none, so everything under the heading sits inside a loop
147 + /// over the `Option` rather than behind a predicate repeated seven times.
148 + pub(super) shape section(mirror: Option<&Mirror>) -> Vec<Node>;
152 149
153 - let Some(mirror) = state.advanced.mirror() else {
154 - return body;
155 - };
150 + text "Importing reads a theme .toml and adds it to your custom themes.";
151 + act "Import theme..." to post "/settings/advanced/theme/import";
152 +
153 + for &mirror in mirror.iter() {
154 + let keeping = given mirror.enabled {
155 + true -> "on",
156 + otherwise -> "",
157 + };
158 +
159 + section "Library Mirror";
160 + text "Create a symlink tree so DAWs can browse your library as a normal folder.";
161 +
162 + field Checkbox "enabled" "Enable library mirror" {
163 + value keeping;
164 + writes Action::post("/settings/advanced/mirror/enabled");
165 + }
156 166
157 - let mut body = body
158 - .with(Node::section("Library Mirror"))
159 - .with(Node::text(
160 - "Create a symlink tree so DAWs can browse your library as a normal folder.",
161 - ))
162 - .with(Node::Field(Box::new(
163 - Field::new(FieldKind::Checkbox, "enabled", "Enable library mirror")
164 - .value(if mirror.enabled { "on" } else { "" })
165 - .writes(Action::post("/settings/advanced/mirror/enabled")),
166 - )))
167 167 // Said before it is enabled rather than after, which is the shipped
168 168 // section's own reasoning: the reader should know where the tree will
169 169 // be built without hunting for a hidden config.
170 - .with(Node::text(format!("Mirror location: {}", mirror.shown)))
171 - .with(Node::Act(Act::new(
172 - "Change...",
173 - Action::post("/settings/advanced/mirror/folder"),
174 - )));
170 + text "Mirror location: {mirror.shown}";
171 + act "Change..." to post "/settings/advanced/mirror/folder";
175 172
176 - if let Some(failed) = mirror.failed {
177 - body = body.with(Node::banner(
178 - Tone::Warning,
179 - format!("Mirror setting not saved: {failed}. It applies to this session only."),
180 - ));
173 + for failed in mirror.failed.iter() {
174 + banner Tone::Warning "Mirror setting not saved: {failed}. It applies to this session only.";
175 + }
181 176 }
182 - body
183 177 }
@@ -225,7 +225,7 @@
225 225 Action::post("/settings/theme/export"),
226 226 )));
227 227 }
228 - body = super::advanced::section(body, state);
228 + body = body.extend(super::advanced::section(state.advanced.mirror().as_ref()));
229 229
230 230 Ok(Screen::sidebar_content("Settings").with(body))
231 231 }