max / makenotwork
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
5 files changed,
+86 insertions,
-87 deletions
| @@ -2875,7 +2875,7 @@ | |||
| 2875 | 2875 | checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" | |
| 2876 | 2876 | dependencies = [ | |
| 2877 | 2877 | "libc", | |
| 2878 | - | "windows-sys 0.59.0", | |
| 2878 | + | "windows-sys 0.52.0", | |
| 2879 | 2879 | ] | |
| 2880 | 2880 | ||
| 2881 | 2881 | [[package]] | |
| @@ -4811,7 +4811,7 @@ | |||
| 4811 | 4811 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 4812 | 4812 | checksum = "82cb6a9f675da968c63b6208c641b9dca58fc0133ae53375736b1767b0cab8bd" | |
| 4813 | 4813 | dependencies = [ | |
| 4814 | - | "windows-sys 0.59.0", | |
| 4814 | + | "windows-sys 0.61.2", | |
| 4815 | 4815 | ] | |
| 4816 | 4816 | ||
| 4817 | 4817 | [[package]] | |
| @@ -5722,7 +5722,7 @@ | |||
| 5722 | 5722 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 5723 | 5723 | checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" | |
| 5724 | 5724 | dependencies = [ | |
| 5725 | - | "windows-sys 0.59.0", | |
| 5725 | + | "windows-sys 0.61.2", | |
| 5726 | 5726 | ] | |
| 5727 | 5727 | ||
| 5728 | 5728 | [[package]] | |
| @@ -6636,7 +6636,7 @@ | |||
| 6636 | 6636 | ||
| 6637 | 6637 | [[package]] | |
| 6638 | 6638 | name = "quasi-axum" | |
| 6639 | - | version = "0.68.0" | |
| 6639 | + | version = "0.69.0" | |
| 6640 | 6640 | dependencies = [ | |
| 6641 | 6641 | "axum", | |
| 6642 | 6642 | "http 1.4.2", | |
| @@ -6647,7 +6647,7 @@ | |||
| 6647 | 6647 | ||
| 6648 | 6648 | [[package]] | |
| 6649 | 6649 | name = "quasi-basics" | |
| 6650 | - | version = "0.68.0" | |
| 6650 | + | version = "0.69.0" | |
| 6651 | 6651 | dependencies = [ | |
| 6652 | 6652 | "makeover-layout", | |
| 6653 | 6653 | "quasi-router", | |
| @@ -6655,7 +6655,7 @@ | |||
| 6655 | 6655 | ||
| 6656 | 6656 | [[package]] | |
| 6657 | 6657 | name = "quasi-http" | |
| 6658 | - | version = "0.68.0" | |
| 6658 | + | version = "0.69.0" | |
| 6659 | 6659 | dependencies = [ | |
| 6660 | 6660 | "form_urlencoded", | |
| 6661 | 6661 | "http 1.4.2", | |
| @@ -6664,7 +6664,7 @@ | |||
| 6664 | 6664 | ||
| 6665 | 6665 | [[package]] | |
| 6666 | 6666 | name = "quasi-router" | |
| 6667 | - | version = "0.68.0" | |
| 6667 | + | version = "0.69.0" | |
| 6668 | 6668 | dependencies = [ | |
| 6669 | 6669 | "makeover-layout", | |
| 6670 | 6670 | ] | |
| @@ -6687,7 +6687,7 @@ | |||
| 6687 | 6687 | ||
| 6688 | 6688 | [[package]] | |
| 6689 | 6689 | name = "quasi-webview" | |
| 6690 | - | version = "0.68.0" | |
| 6690 | + | version = "0.69.0" | |
| 6691 | 6691 | dependencies = [ | |
| 6692 | 6692 | "docengine", | |
| 6693 | 6693 | "makeover-layout", | |
| @@ -6763,7 +6763,7 @@ | |||
| 6763 | 6763 | "once_cell", | |
| 6764 | 6764 | "socket2", | |
| 6765 | 6765 | "tracing", | |
| 6766 | - | "windows-sys 0.59.0", | |
| 6766 | + | "windows-sys 0.52.0", | |
| 6767 | 6767 | ] | |
| 6768 | 6768 | ||
| 6769 | 6769 | [[package]] | |
| @@ -7326,7 +7326,7 @@ | |||
| 7326 | 7326 | "errno", | |
| 7327 | 7327 | "libc", | |
| 7328 | 7328 | "linux-raw-sys 0.4.15", | |
| 7329 | - | "windows-sys 0.59.0", | |
| 7329 | + | "windows-sys 0.52.0", | |
| 7330 | 7330 | ] | |
| 7331 | 7331 | ||
| 7332 | 7332 | [[package]] | |
| @@ -7339,7 +7339,7 @@ | |||
| 7339 | 7339 | "errno", | |
| 7340 | 7340 | "libc", | |
| 7341 | 7341 | "linux-raw-sys 0.12.1", | |
| 7342 | - | "windows-sys 0.59.0", | |
| 7342 | + | "windows-sys 0.52.0", | |
| 7343 | 7343 | ] | |
| 7344 | 7344 | ||
| 7345 | 7345 | [[package]] | |
| @@ -7419,7 +7419,7 @@ | |||
| 7419 | 7419 | "security-framework 3.7.0", | |
| 7420 | 7420 | "security-framework-sys", | |
| 7421 | 7421 | "webpki-root-certs", | |
| 7422 | - | "windows-sys 0.59.0", | |
| 7422 | + | "windows-sys 0.52.0", | |
| 7423 | 7423 | ] | |
| 7424 | 7424 | ||
| 7425 | 7425 | [[package]] | |
| @@ -8545,7 +8545,7 @@ | |||
| 8545 | 8545 | "getrandom 0.4.3", | |
| 8546 | 8546 | "once_cell", | |
| 8547 | 8547 | "rustix 1.1.4", | |
| 8548 | - | "windows-sys 0.59.0", | |
| 8548 | + | "windows-sys 0.52.0", | |
| 8549 | 8549 | ] | |
| 8550 | 8550 | ||
| 8551 | 8551 | [[package]] | |
| @@ -10759,6 +10759,22 @@ | |||
| 10759 | 10759 | "pkg-config", | |
| 10760 | 10760 | ] | |
| 10761 | 10761 | ||
| 10762 | + | [[patch.unused]] | |
| 10763 | + | name = "quasi-immediate" | |
| 10764 | + | version = "0.69.0" | |
| 10765 | + | ||
| 10766 | + | [[patch.unused]] | |
| 10767 | + | name = "quasi-notifs" | |
| 10768 | + | version = "0.69.0" | |
| 10769 | + | ||
| 10770 | + | [[patch.unused]] | |
| 10771 | + | name = "quasi-store" | |
| 10772 | + | version = "0.1.0" | |
| 10773 | + | ||
| 10774 | + | [[patch.unused]] | |
| 10775 | + | name = "quasi-tauri" | |
| 10776 | + | version = "0.69.0" | |
| 10777 | + | ||
| 10762 | 10778 | [[patch.unused]] | |
| 10763 | 10779 | name = "synckit-client" | |
| 10764 | 10780 | version = "0.9.1" | |
| @@ -10778,19 +10794,3 @@ | |||
| 10778 | 10794 | [[patch.unused]] | |
| 10779 | 10795 | name = "painhours" | |
| 10780 | 10796 | version = "0.1.0" | |
| 10781 | - | ||
| 10782 | - | [[patch.unused]] | |
| 10783 | - | name = "quasi-immediate" | |
| 10784 | - | version = "0.68.0" | |
| 10785 | - | ||
| 10786 | - | [[patch.unused]] | |
| 10787 | - | name = "quasi-notifs" | |
| 10788 | - | version = "0.68.0" | |
| 10789 | - | ||
| 10790 | - | [[patch.unused]] | |
| 10791 | - | name = "quasi-store" | |
| 10792 | - | version = "0.1.0" | |
| 10793 | - | ||
| 10794 | - | [[patch.unused]] | |
| 10795 | - | name = "quasi-tauri" | |
| 10796 | - | version = "0.68.0" |
| @@ -163,7 +163,7 @@ | |||
| 163 | 163 | # through quasi beside its Askama equivalent, so the cost of describing a screen | |
| 164 | 164 | # here is measured rather than argued. Not load-bearing for any shipped route. | |
| 165 | 165 | # See wiki look-wave-2, tier G. | |
| 166 | - | quasi-router = { git = "https://makenot.work/git/max/quasi.git", version = "0.68" } | |
| 166 | + | quasi-router = { git = "https://makenot.work/git/max/quasi.git", version = "0.69" } | |
| 167 | 167 | # The description vocabulary quasi's screen types are built from. Pinned here | |
| 168 | 168 | # rather than reached through quasi-router's re-export because a described | |
| 169 | 169 | # screen names FieldKind and Tone directly; it has to track what quasi-router | |
| @@ -179,13 +179,13 @@ | |||
| 179 | 179 | # For the request head the per-viewer state factory reads. axum re-exports it, | |
| 180 | 180 | # but the factory's signature is quasi-axum's and names `http::request::Parts`. | |
| 181 | 181 | http = "1.3.1" | |
| 182 | - | quasi-axum = { git = "https://makenot.work/git/max/quasi.git", version = "0.68" } | |
| 183 | - | quasi-webview = { git = "https://makenot.work/git/max/quasi.git", version = "0.68" } | |
| 182 | + | quasi-axum = { git = "https://makenot.work/git/max/quasi.git", version = "0.69" } | |
| 183 | + | quasi-webview = { git = "https://makenot.work/git/max/quasi.git", version = "0.69" } | |
| 184 | 184 | # The first-party widget set. The carousel was proved here against three pages | |
| 185 | 185 | # and then moved there; what is left in `quasi/widgets/carousel.rs` is the | |
| 186 | 186 | # Askama glue. Not `makeover-basics`: a widget is an assembly of `Node`s, so it | |
| 187 | 187 | # sits above quasi-router rather than inside the description suite. | |
| 188 | - | quasi-basics = { git = "https://makenot.work/git/max/quasi.git", version = "0.68" } | |
| 188 | + | quasi-basics = { git = "https://makenot.work/git/max/quasi.git", version = "0.69" } | |
| 189 | 189 | ||
| 190 | 190 | # Git source browser | |
| 191 | 191 | gix = { version = "0.86", default-features = false, features = ["blame", "mailmap", "revision", "sha1", "max-performance-safe"] } | |
| @@ -277,7 +277,7 @@ | |||
| 277 | 277 | # Written from the crate rather than copied into the repo for the reason the | |
| 278 | 278 | # constants exist: a stale copy in a static directory is a silently dead bulk | |
| 279 | 279 | # bar, and the version has to be the one the emitter agrees with. | |
| 280 | - | quasi-webview = { git = "https://makenot.work/git/max/quasi.git", version = "0.68" } | |
| 280 | + | quasi-webview = { git = "https://makenot.work/git/max/quasi.git", version = "0.69" } | |
| 281 | 281 | ||
| 282 | 282 | [dev-dependencies] | |
| 283 | 283 | tower = { version = "0.5.3", features = ["util"] } |
| @@ -11949,14 +11949,20 @@ | |||
| 11949 | 11949 | margin-top: var(--gap-section); | |
| 11950 | 11950 | } | |
| 11951 | 11951 | ||
| 11952 | - | [data-widget="media-tile"] { | |
| 11952 | + | /* The tile IS the control, since quasi 0.69.0 (`Act::shows`). It was a | |
| 11953 | + | `media-tile` region holding a picture and a button as siblings, and only the | |
| 11954 | + | button answered a press; a reader aiming at the thumbnail hit nothing. The | |
| 11955 | + | widget name went with the region, so the tile is addressed as the button | |
| 11956 | + | inside the grid. */ | |
| 11957 | + | [data-widget="media-picker-grid"] .button { | |
| 11953 | 11958 | display: flex; | |
| 11954 | 11959 | flex-direction: column; | |
| 11955 | 11960 | gap: var(--gap-peer); | |
| 11956 | - | padding: var(--gap-peer); | |
| 11957 | - | border: 1px solid var(--border); | |
| 11958 | - | background: var(--surface-raised); | |
| 11959 | 11961 | min-width: 0; | |
| 11962 | + | /* The file name wraps rather than pushing the tile wide. */ | |
| 11963 | + | overflow-wrap: anywhere; | |
| 11964 | + | text-align: left; | |
| 11965 | + | font-size: var(--text-note); | |
| 11960 | 11966 | } | |
| 11961 | 11967 | ||
| 11962 | 11968 | /* A cap, not a height, and never a bare `img`. The design system already sets | |
| @@ -11965,16 +11971,6 @@ | |||
| 11965 | 11971 | drift check refuses, and it is right to. `max-height` is not one of them, and | |
| 11966 | 11972 | it is all this needs: `Fit::Contain` is in the description, so a capped | |
| 11967 | 11973 | picture letterboxes inside the cap rather than being cropped or stretched. */ | |
| 11968 | - | [data-widget="media-tile"] .picture-img { | |
| 11974 | + | [data-widget="media-picker-grid"] .picture-img { | |
| 11969 | 11975 | max-height: 80px; | |
| 11970 | 11976 | } | |
| 11971 | - | ||
| 11972 | - | /* The file name is the control, so it wraps rather than pushing the tile wide. | |
| 11973 | - | `Act` is a label and nothing in the vocabulary says a control reads as a | |
| 11974 | - | picture, so the thumbnail above it is a sibling and only this half answers a | |
| 11975 | - | press. Filed rather than faked; see the module header. */ | |
| 11976 | - | [data-widget="media-tile"] .button { | |
| 11977 | - | overflow-wrap: anywhere; | |
| 11978 | - | text-align: left; | |
| 11979 | - | font-size: var(--text-note); | |
| 11980 | - | } |
| @@ -110,19 +110,21 @@ | |||
| 110 | 110 | // A document that does ask fails visibly on the first control pressed, | |
| 111 | 111 | // and nothing here asks: every control is an external link. | |
| 112 | 112 | // | |
| 113 | - | // Six `without_` calls now. quasi 0.54.0 added the fill script, and | |
| 114 | - | // 0.59.0 and 0.60.0 added the reveal and repeat scripts. All three are | |
| 115 | - | // independent of htmx by design — what they read is attributes on a | |
| 116 | - | // control, a region or a fieldset — so dropping the transport does not | |
| 117 | - | // drop them, and each has to be refused by name. An embed names no | |
| 118 | - | // destination field, no conditional region and no repeating question, | |
| 119 | - | // so all three have nothing to read here. | |
| 113 | + | // Seven `without_` calls now. quasi 0.54.0 added the fill script, | |
| 114 | + | // 0.59.0 and 0.60.0 the reveal and repeat scripts, and 0.68.0 the copy | |
| 115 | + | // script. All four are independent of htmx by design — what they read | |
| 116 | + | // is attributes on a control, a region or a fieldset — so dropping the | |
| 117 | + | // transport does not drop them, and each has to be refused by name. An | |
| 118 | + | // embed names no destination field, no conditional region, no repeating | |
| 119 | + | // question and no act that copies, so all four have nothing to read | |
| 120 | + | // here. | |
| 120 | 121 | .without_htmx() | |
| 121 | 122 | .without_hyperscript() | |
| 122 | 123 | .without_clock() | |
| 123 | 124 | .without_fill() | |
| 124 | 125 | .without_reveal() | |
| 125 | 126 | .without_repeat() | |
| 127 | + | .without_copy() | |
| 126 | 128 | .with_chrome(Chrome::new()) | |
| 127 | 129 | .with_head_first(head_first()); | |
| 128 | 130 | shell.body_class = body_class.map(str::to_owned); | |
| @@ -290,6 +292,7 @@ | |||
| 290 | 292 | .without_fill() | |
| 291 | 293 | .without_reveal() | |
| 292 | 294 | .without_repeat() | |
| 295 | + | .without_copy() | |
| 293 | 296 | .with_chrome(Chrome::new()) | |
| 294 | 297 | .with_head_first(format!("{}<style>{PLAYER_CSS}</style>", head_first())); | |
| 295 | 298 | shell.body_class = Some("embed-player".to_owned()); |
| @@ -165,9 +165,6 @@ | |||
| 165 | 165 | /// What the grid of tiles is called. | |
| 166 | 166 | const GRID_WIDGET: &str = "media-picker-grid"; | |
| 167 | 167 | ||
| 168 | - | /// What one tile is called. | |
| 169 | - | const TILE: &str = "media-tile"; | |
| 170 | - | ||
| 171 | 168 | /// A named assembly, which is the hook a stylesheet attaches to. | |
| 172 | 169 | /// | |
| 173 | 170 | /// `RegionKind::Widget` rather than `Group` on all three, because that is what | |
| @@ -313,49 +310,45 @@ | |||
| 313 | 310 | )); | |
| 314 | 311 | } | |
| 315 | 312 | for entry in entries { | |
| 316 | - | slot = slot.with(Node::Region(card(entry, into))); | |
| 313 | + | slot = slot.with(card(entry, into)); | |
| 317 | 314 | } | |
| 318 | 315 | slot | |
| 319 | 316 | } | |
| 320 | 317 | ||
| 321 | - | /// One tile: the thumbnail, and the control that deposits its reference. | |
| 318 | + | /// One tile: one control, showing the thumbnail and saying the file name. | |
| 322 | 319 | /// | |
| 323 | - | /// The control's label is the file name, which is the fact the shipped script | |
| 324 | - | /// lost to a misspelled JSON key. Its deposit is `markdown_ref` verbatim, which | |
| 325 | - | /// is the fact that script wrapped twice. | |
| 320 | + | /// The label is the file name, which is the fact the shipped script lost to a | |
| 321 | + | /// misspelled JSON key. The deposit is `markdown_ref` verbatim, which is the | |
| 322 | + | /// fact that script wrapped twice. | |
| 326 | 323 | /// | |
| 327 | 324 | /// `Action::local()`, so the press makes no request. The old picker made none | |
| 328 | 325 | /// either; what it did instead was 155 lines of DOM building. | |
| 329 | 326 | /// | |
| 330 | - | /// # Two members and half a tile, which is the gap this conversion found | |
| 327 | + | /// # This was two members and half a tile until quasi 0.69.0 | |
| 331 | 328 | /// | |
| 332 | - | /// The shipped card is one pressable box with a picture in it. Here the picture | |
| 333 | - | /// and the control are siblings, and only the control answers a press, because | |
| 334 | - | /// **an [`Act`] is a label and nothing in the vocabulary says a control reads as | |
| 335 | - | /// a picture.** `Cell::new` and `Row::new` both take a string, so a picture | |
| 336 | - | /// cannot sit beside a control in a table or a list either: [`Node::Image`] | |
| 337 | - | /// goes in a region body and nowhere else. | |
| 329 | + | /// The conversion found that an [`Act`] was a label and nothing said a control | |
| 330 | + | /// reads as a picture, so the tile was a region holding the picture and the | |
| 331 | + | /// control as siblings and only the file name answered a press -- a reader | |
| 332 | + | /// aiming at the thumbnail, which is the whole affordance of a picture picker, | |
| 333 | + | /// hit nothing. `Act::shows` (quasicoherent `db998898`) is that member, and the | |
| 334 | + | /// tile is one control again. | |
| 338 | 335 | /// | |
| 339 | - | /// So a tile is a region, which is why [`Entry::id`] exists. Filed rather than | |
| 340 | - | /// faked, the same way the caret was: a description that drew a pressable | |
| 341 | - | /// picture by putting the picture in the label would be spelling markup in a | |
| 342 | - | /// string. | |
| 343 | - | fn card(entry: &Entry, into: &str) -> Slot { | |
| 344 | - | let mut slot = Slot::new(format!("media-card-{}", entry.id), widget(TILE)); | |
| 336 | + | /// The region went with it, and so did the id it needed. [`Entry::id`] is kept | |
| 337 | + | /// for the caller's convenience and no longer addresses anything. | |
| 338 | + | fn card(entry: &Entry, into: &str) -> Node { | |
| 339 | + | let mut act = Act::new(&entry.filename, Action::local()).filling(into, &entry.reference); | |
| 345 | 340 | if entry.image { | |
| 346 | 341 | // The alt is the file name, because that is what the tile is for: a | |
| 347 | 342 | // reader who cannot see the thumbnail is choosing between file names, | |
| 348 | - | // which is exactly what the control below says. | |
| 343 | + | // which is exactly what the control says. | |
| 349 | 344 | let mut picture = Picture::new(&entry.url, &entry.filename).lazy(); | |
| 350 | 345 | // The letterbox, which is what the shipped tile did with | |
| 351 | 346 | // `object-fit: contain`: a thumbnail grid whose files are not all one | |
| 352 | 347 | // shape, and the whole picture matters more than filling the square. | |
| 353 | 348 | picture.fit = Fit::Contain; | |
| 354 | - | slot = slot.with(Node::Image(picture)); | |
| 349 | + | act = act.showing(picture); | |
| 355 | 350 | } | |
| 356 | - | slot.with(Node::Act( | |
| 357 | - | Act::new(&entry.filename, Action::local()).filling(into, &entry.reference), | |
| 358 | - | )) | |
| 351 | + | Node::Act(act) | |
| 359 | 352 | } | |
| 360 | 353 | ||
| 361 | 354 | /// The typed filter. | |
| @@ -472,13 +465,20 @@ | |||
| 472 | 465 | // owns this picture's width, height and background, and an app rule | |
| 473 | 466 | // taking one of those is what `makeover-build`'s drift check refuses. | |
| 474 | 467 | assert!(html.contains(r#"data-fit="contain""#), "{html}"); | |
| 475 | - | // And the tile is a region, which is the only place a picture can sit | |
| 476 | - | // beside a control. Its id is the file's, so a library of two hundred | |
| 477 | - | // does not have two hundred elements answering to one name. | |
| 468 | + | // And the tile is the control, since quasi 0.69.0: the picture is | |
| 469 | + | // inside the element that answers the press, so aiming at the thumbnail | |
| 470 | + | // picks the file. It was a `media-card-<id>` region holding the picture | |
| 471 | + | // and the button as siblings, and only the button answered. | |
| 478 | 472 | assert!( | |
| 479 | - | html.contains(r#"id="media-card-11111111-1111-1111-1111-111111111111""#), | |
| 480 | - | "{html}" | |
| 473 | + | !html.contains("media-card-"), | |
| 474 | + | "the per-tile region is gone: {html}" | |
| 481 | 475 | ); | |
| 476 | + | let control = html | |
| 477 | + | .split_once("<button") | |
| 478 | + | .and_then(|(_, rest)| rest.split_once("</button>")) | |
| 479 | + | .map_or("", |(inner, _)| inner); | |
| 480 | + | assert!(control.contains("<img"), "{html}"); | |
| 481 | + | assert!(control.contains("kick.png"), "{html}"); | |
| 482 | 482 | } | |
| 483 | 483 | ||
| 484 | 484 | /// A video has no thumbnail to show, so it is the control alone rather than |