Commit Graph
10 Commits
Author SHA1 Message Date
spoopyghosty0 503e64367c Showcase: monitor_settled waits for the newest fake stream
The Frame card starts a stream before the Monitor tab, whose faster interval starts a new one: the hook
returned on the first stream's flag while the new one was still replaying (CI rendered 71 vs 72 fps).
Each frozen session now has its own settled flag; the hook waits for the newest one.
2026-10-17 16:42:54 -04:00
spoopyghosty0 0df1212bfe Showcase: the monitor shot waits for the frozen stream's replay
The Monitor tab asks the frozen fake stream to replay its history; on CI's slower runner the shot came
halfway through, so its numbers differed between renders ("three renders, no two alike"). New hook
monitor_settled waits until the replay is done.
2026-10-17 16:34:23 -04:00
spoopyghosty0 60d8ab021b Install walkthrough: the setup line and Allow, in the video and on the site
- Install tutorial video (docs/showcase/videos/install.yaml, re-recorded by record_video.py): Start setup, a card
  for the setup line on the Frame (with the Developer Mode route in its note), the Frame asking and Allow clicked,
  a card for what the Frame then does by itself. Showcase: the fake pairing server takes asks; hook `frame_asks`.
- Site: the Install section is a six-step walkthrough (download, Start setup, the line or Developer Mode on the
  Frame, Allow, it sets itself up, add games and play), each step with a small live scene: the download unpacks,
  Start setup shows the line, Konsole types it and finds FramePort, Allow moves on, the setup ticks off, a game
  installs. The other ways link to /setup.
2026-10-10 10:16:13 -04:00
spoopyghosty0 2480d203ec Easter eggs: portal toss, more holidays, perfect pacing, self-search, hello, full charge, upload hop, on air
- Seven logo clicks: the portal glows and rings, a cover is tossed out and falls across the window on a random arc
- Holiday badges dance on hover; new: Valentine's, Pi Day, St Patrick's, Easter weekend, April 1 (upside-down
  logo until hovered), New Year's party popper
- Monitor: a minute within 0.5 fps of target turns the fps chart into the portal gradient
- Library search "frameport": the logo spins and says "That's me!"
- Type on Frame: typing "hello" makes a headset wave (keys still go to the Frame)
- The battery ring sparkles on reaching 100 % on the charger
- Uploads over five minutes: the transit cover hops now and then
- Live view tab: a blinking ON AIR sign while streaming
- Showcase hooks perfect_pacing, battery, long_upload, press_keys
2026-10-09 14:18:08 -04:00
spoopyghosty0 c4983b6e18 Easter eggs; the Settings source link sits on the left
- ui/easter.py: seven quick clicks on the sidebar logo send a game's cover out of its portal for a somersault over
  the wordmark; the Monitor's frame rate has a mood tooltip; holiday badges on the logo (a pumpkin Oct 24-31, a
  snowflake Dec 20 - Jan 2); install milestones (confetti in the portal colours and a message at the 1st, 10th and
  100th different game on the Frame). Milestones show once ever: they count different games (updates and
  reinstalls don't), are stored as shown before they're shown, and the first use seeds from the games already on a
  Frame (no "first game" after an app update). Off with setting ui.easter_eggs; Reduce motion keeps the words only.
- C.kv puts control values on the left; C.link (no indent) for the About page's source link.
- Showcase: the demo library has the easter eggs off; steps hooks easter_eggs / fps_dip and a clicks action;
  record_video.py takes a storyboard file path (demos outside docs/).
2026-10-09 13:39:42 -04:00
spoopyghosty0 a069c79c73 Showcase: any number of videos (docs/showcase/videos/<name>.yaml), plus an install tutorial
- record_video.py replaces record_tour.py: one storyboard per video with its output, a start state (demo or
  fresh profile, Frame connected or not, start page, live or frozen stream), setup steps before filming, filmed
  scenes and instruction cards (eyebrow, heading, numbered steps, a command, a note) for what happens outside
  FramePort. --changed-since records the videos whose storyboard (or the recorder) changed; several videos record
  in separate processes.
- videos/install.yaml: download, first start, the welcome screen's tool download, the setup command, the command
  on the Frame (card), connected, scanning a folder, installing and playing a game (81 s).
- demo_home profile "fresh": FramePort's first start (empty library, welcome screen, nothing on the Frame); its
  games wait for the pretend folder scan. Fakes for a first start: no Frame discovery on the real network, the setup
  command shows the docs' example address, a pretend tool download, steps hooks first_run and pairing_done.
- CI records changed (or named) videos; releases attach every docs/media/frameport-<name>.mp4 as
  FramePort-<name>.mp4. INSTALL.md and README link the tutorial; SHOWCASE.md documents the storyboard format.
- Cards are opened by their title in both videos (a card's middle is its Install button).
2026-10-09 10:37:22 -04:00
spoopyghosty0 f7108c0ca4 Fix: a page change could die when a background thread set a control property mid-update
Flet packs a patch by iterating each control's _values dict; Prop.__set__ adds/removes keys there without a lock.
A property set on a background thread (the live Frame card's sample, job progress, the library loader) while the
event loop packed a patch raised "dictionary changed size during iteration" and the update was lost (seen in CI:
a sidebar click left the old page showing). serialize_flet_updates() now makes property writes take the same
re-entrant lock as patches (app.FLET_LOCK). Reproduced with Flet's own encoder: 16 failures in 4 s before, none
after; test_property_writes_wait_for_a_patch_being_packed. The showcase server and ui_smoke serialize like the app.
Tour re-recorded with the fix (clean, no fallback clicks).
2026-10-09 08:04:55 -04:00
spoopyghosty0 222633e462 Showcase: nav step (sidebar click checked against the page that shows; falls back to opening the route when a click's handler died in a Flet update race seen on CI); CI renders with Python 3.12 2026-10-09 01:08:16 -04:00
spoopyghosty0 80a5c0b6d6 Showcase: scripted demo tour (docs/showcase/tour.yaml -> record_tour.py)
One window on the demo library, driven by name like a person would (drawn pointer, eased curved paths, a ring on
each click), filmed with Chrome's screencast (1080p, constant 30 fps from the frame timestamps), then captioned
(lower thirds in the app's colours), given title/end cards and crossfaded by postprod.py (ffmpeg only). Writes
docs/media/frameport-tour.mp4 (+ poster, best quality within 12 MB) and the README teaser docs/images/tour-teaser.webp.
Installs in the tour run a scripted job through the real queue; --draft for quick storyboard checks, --names lists
the clickable names. Element finding prefers the innermost match (a list's text includes its rows').
2026-10-09 00:22:19 -04:00
spoopyghosty0 63f0125954 Showcase: demo library + docs screenshot renderer
scripts/showcase/: the fakes split out of ui_smoke (the pretend Frame now reads the demo library's state, fixed
dates, a Take screenshot fake, a frozen monitor stream for stills), web.py (the GUI in web mode driven by name
through Flutter's semantics tree, drawn cursor, eased pointer paths, settle detection, one browser per window),
steps.py (the step language shared by screenshots and the tour), demo_home.py (21 catalog games from
docs/showcase/demo-library.yaml + demo-analyses.json, art and store details fetched once and cached) and
render_docs.py (docs/showcase/shots.yaml -> docs/images, rewritten only on a visible change; --check for CI).
2026-10-09 00:00:13 -04:00