max / makenotwork
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
- Claude-Session
- https://claude.ai/code/session_01P8ostB2UmZJGj5WjSHRSot
1 file changed,
+39 insertions,
-22 deletions
| @@ -11,34 +11,51 @@ | |||
| 11 | 11 | //! because it has no idea this host prefixes its tags with `mnw-`. The template | |
| 12 | 12 | //! puts one around the other and both halves stay honest. | |
| 13 | 13 | ||
| 14 | - | use quasi_basics::Frame; | |
| 15 | - | use quasi_router::Node; | |
| 14 | + | use quasi_basics::{Frame, Gallery}; | |
| 15 | + | use quasi_declare::declare; | |
| 16 | 16 | ||
| 17 | - | /// The widget, for a screen that owns its whole document. | |
| 17 | + | use crate::templates::CarouselFrame; | |
| 18 | + | ||
| 19 | + | /// One template frame as the widget's own. | |
| 18 | 20 | /// | |
| 19 | - | /// [`html`] is the Askama half and this is the described half. Both come out of | |
| 20 | - | /// `quasi_basics::carousel`, so the project page's gallery and the three | |
| 21 | - | /// templates that still call the macro cannot be two different carousels. | |
| 22 | - | #[must_use] | |
| 23 | - | pub fn region(id: &str, items: &[crate::templates::CarouselFrame]) -> Node { | |
| 24 | - | Node::Region(quasi_basics::carousel( | |
| 25 | - | id, | |
| 26 | - | items.iter().map(|frame| { | |
| 27 | - | let mut built = Frame::new(&frame.image, &frame.alt); | |
| 28 | - | if let Some((w, h)) = frame.intrinsic { | |
| 29 | - | built = built.intrinsic(w, h); | |
| 30 | - | } | |
| 31 | - | match &frame.caption { | |
| 32 | - | Some(caption) => built.caption(caption), | |
| 33 | - | None => built, | |
| 34 | - | } | |
| 35 | - | }), | |
| 36 | - | )) | |
| 21 | + | /// The conversion, and the whole of what stayed in MNW. Written as two matches | |
| 22 | + | /// rather than a `let mut` and an `if let` because a description reads a value | |
| 23 | + | /// and a builder that reassigns itself is not one, which is the same reason | |
| 24 | + | /// [`gallery`] is a supplier and not part of the declaration below. | |
| 25 | + | fn frame(source: &CarouselFrame) -> Frame { | |
| 26 | + | let sized = match source.intrinsic { | |
| 27 | + | Some((width, height)) => Frame::new(&source.image, &source.alt).intrinsic(width, height), | |
| 28 | + | None => Frame::new(&source.image, &source.alt), | |
| 29 | + | }; | |
| 30 | + | match &source.caption { | |
| 31 | + | Some(caption) => sized.caption(caption), | |
| 32 | + | None => sized, | |
| 33 | + | } | |
| 34 | + | } | |
| 35 | + | ||
| 36 | + | /// The template's frames as the widget's read. | |
| 37 | + | /// | |
| 38 | + | /// [`Gallery::new`] is where the first frame becomes the one on screen, so this | |
| 39 | + | /// is the one place the order is looked at. Everything after it reads a fact. | |
| 40 | + | fn gallery(items: &[CarouselFrame]) -> Gallery { | |
| 41 | + | items.iter().map(frame).collect() | |
| 42 | + | } | |
| 43 | + | ||
| 44 | + | declare! { | |
| 45 | + | /// The widget, for a screen that owns its whole document. | |
| 46 | + | /// | |
| 47 | + | /// [`html`] is the Askama half and this is the described half. Both come out | |
| 48 | + | /// of `quasi_basics::carousel`, so the project page's gallery and the three | |
| 49 | + | /// templates that still call the macro cannot be two different carousels. | |
| 50 | + | #[must_use] | |
| 51 | + | pub shape region(id: &str, items: &[CarouselFrame]) -> Node; | |
| 52 | + | ||
| 53 | + | include quasi_basics::carousel(id, &gallery(items)); | |
| 37 | 54 | } | |
| 38 | 55 | ||
| 39 | 56 | /// The markup, for an Askama template to drop in. | |
| 40 | 57 | #[must_use] | |
| 41 | - | pub fn html(id: &str, items: &[crate::templates::CarouselFrame]) -> String { | |
| 58 | + | pub fn html(id: &str, items: &[CarouselFrame]) -> String { | |
| 42 | 59 | use quasi_axum::Serves as _; | |
| 43 | 60 | ||
| 44 | 61 | let node = region(id, items); |