mirror of
https://github.com/screentinker/screentinker.git
synced 2026-08-13 13:53:12 -06:00
2 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
59c536c923 |
Keep a solo widget mounted, and size its keyboard to the viewport
Two problems on a panel showing one fullscreen widget, both visible as flashing. The player re-navigated the WebView every duration_sec. PlaylistController.next() requests a playlist refresh between plays and playCurrentItem() re-issues the item unconditionally, so a one-item playlist reloaded the same URL forever. The existing dedupe guard only covers the playlist-update path, so it logged "not restarting" AFTER the reload had already happened. On an interactive widget that also discarded whatever the viewer had typed. showWidget() is now idempotent: same URL with the widget already on screen returns without re-navigating, and the cached URL is cleared at every media-type transition so switching away and back still reloads. The refresh itself is untouched — schedule re-evaluation and dayparting still run on the timer, and widgets keep refreshing their own data client-side (directory-search polls its board every 30s and preserves the current query). The web player already behaved this way via reevaluateHeldWidget; this brings the Android player to parity. Separately, the directory-search keyboard was laid out in fixed pixels for a 1920-wide viewport. A panel's CSS viewport is its resolution over its density, so a 1080p screen at 240dpi presents 1280x720 — where four rows of 56px keys took ~37% of the height instead of ~24%, and the lone max-width:700px breakpoint never fired to correct it. Key metrics are now clamped against vh. The clamp maxima are the previous fixed values and both vh terms exceed them at 1080 tall, so a 1080 viewport renders pixel-identically; shorter viewports scale down. The breakpoint no longer re-pins .key, which would have undone the clamp. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
a15086540f
|
feat(widgets): directory-search widget (interactive search of a directory board, live-sync) (#188)
* feat(widgets): add directory-search widget
An interactive, walk-up search view of an existing directory-board. It
references a source board by id (no data copy), so a venue can run the
scrolling board on a main screen and a search view on a tablet, letting
people find an entry instantly.
Server (routes/widgets.js):
- register 'directory-search' + renderDirectorySearch(): resolves the source
board, inlines its categories as one \u003c-guarded JSON blob, renders all
text via textContent (XSS-safe), live case-insensitive filter over
identifier/name/subtitle (debounced), grouped results, available styling,
optional touch on-screen QWERTY keyboard that drives the same filter path.
- missing / non-directory-board source -> friendly full-page fallback, not a 500.
- live-sync while open is out of scope; left a // TODO for a poll hook.
Frontend editor (views/widgets.js): type + magnifier icon, source-board
dropdown (from loaded widgets, filtered to directory-board), title, logo
(reuses the board's picker), placeholder text, theme, on-screen-keyboard toggle;
getConfigFromForm case. i18n: widget.dirsearch.* + type keys in en/es/it/de/pt/fr.
docs: openapi widget_type enum. Tests: server/test/directory-search.test.js.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* feat(widgets): live-sync for directory-search (poll source board, no reload)
Reflect directory-board edits on an open directory-search page without a reload.
- New public GET /api/widgets/:id/data.json returns { categories } for a
directory-board (404 for missing/wrong-type so the page keeps last-good data
on a transient miss). CORS-open (ACAO:*) + no-store so a null-origin sandboxed
widget iframe can read it; exposes only data already public via /render.
Exempted from CSP + auth in server.js alongside /render.
- directory-search page inlines its source_widget_id and polls the board's
data.json every 30s via a relative URL (works behind a proxy/base path and
from a null-origin iframe). Only rebuilds + rerenders when the data actually
changed, so a mid-search view isn't disturbed; skips while document.hidden;
keeps last-good data on any fetch error. Flatten logic factored into
buildFlat() and reused by the poll.
Tests: data.json feed (categories, CORS header, 404s) + poll wiring in
directory-search.test.js (13/13). Verified live in a browser (page.clock
fast-forward): editing the board updates the search page with no reload.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix(android): let player WebViews take touch focus for interactive widgets
directory-search is served through the existing generic widget path
(loadUrl <server>/api/widgets/:id/render), so it already renders on Android
with JS + DOM storage + mixed-content enabled, same-origin (so its live-sync
fetch of the source board's data.json works), and no touch blocking.
Add isFocusable/isFocusableInTouchMode to the shared WebView config so the
search field reliably takes a tap/cursor inside the kiosk lock-task WebView.
Harmless for passive widgets (board/YouTube have no focusable inputs); the
widget's own on-screen keyboard still drives the filter when the system IME
is suppressed. Verified with :app:compileDebugKotlin.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
|