feat(blur): reveal all, and the booth blur control (r2b merge 1: D2 + D2b)
The operator ruled blur A, and made it urgent: "per booth blurring is now
important since we are showing up to 4 images."
- Reveal all: one control per booth, in the booth header and the review's
top bar, outside every data-region. It is in the markup only when
something is blurred, always `hidden` until the script shows it.
- The state is sessionStorage per booth, per tab, and nothing reaches
the server. It is carried as one `reveal-all` class on <html>, applied
before first paint from the page's own data-booth, so booth A's reveal
cannot follow you into booth B and the index is never revealed.
- Per-item reveal buttons stand down by stylesheet, and an item's own
reveal is never touched, so "blur again" restores each item as it was.
- A storage write that throws still applies the click.
- The booth blur control: a plain form to booth-dev's POST /blurbooth, so
it works with scripts off. Its label follows is_booth_blurred; from the
review it carries `back` and lands on the same item. A fogged booth's
Desk row says "◉ blurred".
- Found by rendering it: under a fogged booth every item reported
`blurred`, so an item blurred only by the booth offered an un-blur that
visibly did nothing. The gallery now carries `blurred_self`, and such an
item shows "◉ booth", a label rather than a control.
Contract docs/contracts/r2b_desk_reveal_theme.contract.md (heid contract
panel 4/4, folded). tests/mutations/r2b.toml: 14/14 proved. 765 passed.
This commit is contained in:
@@ -680,6 +680,8 @@ def list_booths(data_dir: Path, ttl_seconds: float, now: float | None = None) ->
|
||||
"has_index": (child / "index.html").is_file(),
|
||||
"uploaded": (child / UPLOAD_MARKER).exists(),
|
||||
"kept": is_kept(child),
|
||||
# r2b D2b: the whole-booth fog, so a blurred strip says why.
|
||||
"booth_blurred": is_booth_blurred(child),
|
||||
"marks_total": len(marks),
|
||||
# `open_marks` and nothing else (INV-2). The count this replaced
|
||||
# tested `answer is None`, so a half-answered pick read as closed
|
||||
@@ -746,6 +748,10 @@ def build_gallery(child: Path) -> list[dict]:
|
||||
suite reaches for it by name in nine places.
|
||||
"""
|
||||
out = []
|
||||
# r2b D2b: the item's OWN blur, apart from the booth's. `blurred` is the
|
||||
# composed fact the surfaces render; the per-item control changes only
|
||||
# this, and must not claim an un-blur the booth flag would override.
|
||||
own_blur = read_blurred(child)
|
||||
for it in booth_items(child):
|
||||
body = render_doc_body(child, it)
|
||||
rendered, rendered_html = body if body is not None else (None, False)
|
||||
@@ -768,6 +774,7 @@ def build_gallery(child: Path) -> list[dict]:
|
||||
"rendered": rendered,
|
||||
"rendered_html": rendered_html,
|
||||
"blurred": it.blurred,
|
||||
"blurred_self": it.rel in own_blur,
|
||||
}
|
||||
)
|
||||
return out
|
||||
@@ -1193,6 +1200,8 @@ def create_app(
|
||||
# The page could not previously tell keep from release, so it
|
||||
# offered neither and you had to go back to the index.
|
||||
"kept": is_kept(booth),
|
||||
# r2b D2b: the header's blur-booth control says what IS.
|
||||
"booth_blurred": is_booth_blurred(booth),
|
||||
# THE GRID RENDERS `shown`; everything else reads `gallery`.
|
||||
# Filtering is a VIEW: `shown` is `gallery` with non-matching
|
||||
# items removed and NOTHING re-sorted, so "the third one" means
|
||||
@@ -1824,6 +1833,8 @@ def create_app(
|
||||
**base_ctx,
|
||||
"name": name,
|
||||
"name_url": quote(name, safe=""),
|
||||
# r2b D2b: the review's blur-booth control says what IS.
|
||||
"booth_blurred": is_booth_blurred(booth),
|
||||
"file": f,
|
||||
"file_url": quote(f, safe="/"),
|
||||
# The facts this route never used to carry.
|
||||
|
||||
Reference in New Issue
Block a user