feat(r2): C6 the review, and C7
- The zoom route becomes the review for image, video AND audio: the native player on the stage for sound and video, the Fit/1:1 toggle for pictures only. The judgment rail, the tape and the filmstrip are each a data-region. The stage never is, so a playing track survives an in-place save. - The rail shows the whole-set number, K of M in the review ring and the position in the group; then the caption, and the flag and notes, landing back here (back=view). A pick targeting this item is answerable in place. On the last item the end-of-set block lists what was seen, the flags, and every other open question. - The keys are ← → Space F N Esc. Every one is ignored in an editable field, and Esc returns to the grid at the tile you were on. - _marks.html gains picks_only/back_view, so a pick form has one renderer wherever it sits. - In-place swaps now carry an unsaved draft across. A half-typed note survives a flag, except in the form that was just sent. - The filmstrip keeps the current frame in view. - C7: no emblem in the chrome, pinned. Browser tests cover: F typed into the note stays a letter and does not flag; F outside the note flags in place and the draft survives; Space moves; Esc lands on the grid tile. 706 passed.
This commit is contained in:
@@ -112,3 +112,39 @@ def test_a_failed_save_says_so_reloads_and_never_re_posts(browser, live):
|
||||
page.wait_for_load_state("networkidle")
|
||||
page.close()
|
||||
assert len(posts) == 1, f"re-POSTed: {posts}"
|
||||
|
||||
|
||||
def test_the_review_keys_judge_in_place_and_stay_out_of_the_note(browser, live):
|
||||
"""At full size: F typed into the note is a letter; F outside it flags IN
|
||||
PLACE (the filmstrip underline and the tape catch up, no reload); Space
|
||||
moves on; Esc goes back to the grid at the tile you were on."""
|
||||
base, root = live
|
||||
_set(root, 4)
|
||||
page = browser.new_page(viewport={"width": 1400, "height": 900})
|
||||
page.goto(f"{base}/b/g/view?f=02.png", wait_until="networkidle")
|
||||
page.evaluate("window.__noReload = 1")
|
||||
|
||||
page.locator("#vnote-text").click()
|
||||
page.keyboard.type("fff")
|
||||
assert page.locator(".vflag-btn.is-flagged").count() == 0
|
||||
assert page.locator("#vnote-text").input_value() == "fff"
|
||||
|
||||
page.locator(".vr-where").click() # focus back on the page, not a field
|
||||
page.keyboard.press("f")
|
||||
page.wait_for_selector(".vflag-btn.is-flagged", timeout=10000)
|
||||
state = page.evaluate("""() => ({
|
||||
reload: window.__noReload !== 1,
|
||||
film: [...document.querySelectorAll('.film-f.is-flagged .film-ord')].map(e => e.textContent),
|
||||
draft: document.getElementById('vnote-text').value,
|
||||
})""")
|
||||
assert not state["reload"]
|
||||
assert state["film"] == ["#2"]
|
||||
assert state["draft"] == "fff", "an unsaved note must survive a swap it was not part of"
|
||||
|
||||
with page.expect_navigation():
|
||||
page.keyboard.press(" ")
|
||||
assert page.url.endswith("/b/g/view?f=03.png")
|
||||
with page.expect_navigation():
|
||||
page.keyboard.press("Escape")
|
||||
assert page.url.endswith("/b/g/#item-03.png")
|
||||
page.close()
|
||||
|
||||
Reference in New Issue
Block a user