mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-07-22 12:52:29 +00:00
* feat(a11y): app-wide "Interface size" setting (Accessibility) Adds a dedicated Accessibility -> Interface size control so users on large, low-DPI displays can enlarge the app's menus, buttons and text (reported: eye strain on a 32" 1440p panel with no OS scaling). Mechanism: a host-owned scale capability (window.feedBack.scale) applies a RELATIVE root font-size (a % of the user-agent base, never a px literal, so a raised browser/OS base font is respected) and publishes an always-present --fb-scale token. The rem-based v3 chrome scales together; the gameplay highway canvas (device-pixel sized) is deliberately untouched, so playback resolution and FPS are unchanged. Medium (100%) clears the override, so default rendering is byte-identical to before -- zero blast radius. - Settings -> new Accessibility tab: Small/Medium/Large/Extra-Large presets (0.90/1.00/1.15/1.30) + a fine-tune slider (to 150%). - Applied pre-paint from an inline <head> script (mirrors the ss-follower pattern) so there is no flash-of-reflow on load. - window.feedBack.scale read-API (get/set + scale:changed, fires once on load) so canvas/WebGL surfaces that cannot inherit rem can follow the size. Shape mirrors the working-tuning read-API; persists as a durable preference. - Cosmetic px->rem sweep so text scales cleanly at the larger stops (2 v3.css font-sizes + 20 text-[Npx] utilities across 8 v3 files; tailwind.min.css rebuilt byte-stable via the pinned toolchain). - One-time first-run nudge for the large/low-DPI display profile that deep-links to the control (never fires once the setting is touched, or on other displays). v3-only. Verified headless: core apply/persist/reset/reload/UI-sync + nudge gating, with no console errors. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QbexxfTt8q2tAn436MqGWF * fix(v3): regenerate tailwind.min.css to satisfy tailwind-fresh CI (PR #664 review) Regenerate static/tailwind.min.css via scripts/build-tailwind.sh (tailwindcss@3.4.19) so a fresh build matches the committed artifact and the tailwind-fresh CI job's `git diff --quiet` passes. Two consecutive regenerations are byte-identical. Also (Fix 2) switch the fine-tune interface-size slider to the documented transient-preview path: oninput now calls scale.set(v, { persist:false }) so dragging previews without writing localStorage/emitting a commit each tick, and a new onchange commits with persistence on release. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: byrongamatos <xasiklas@gmail.com>
80 lines
3.0 KiB
JavaScript
80 lines
3.0 KiB
JavaScript
// v3 first-run "Interface size" nudge.
|
|
//
|
|
// The Accessibility → Interface size control is the primary discovery path, but
|
|
// the exact person who needs it — someone on a large, low-DPI display (e.g. a
|
|
// 32" 1440p panel with no OS scaling) — is the one least likely to go hunting
|
|
// for it. So, ONCE, for that specific display profile, surface a gentle,
|
|
// dismissible toast that deep-links to the control. Never fires if the user has
|
|
// already touched the setting, on smaller/high-DPI displays, or more than once.
|
|
//
|
|
// Plain non-module script; degrades to a no-op without the bus, fbNotify, or DOM.
|
|
(function () {
|
|
'use strict';
|
|
|
|
var SEEN_KEY = 'v3-interface-size-nudged';
|
|
var SCALE_KEY = 'v3-interface-scale';
|
|
|
|
function alreadyHandled() {
|
|
try {
|
|
return localStorage.getItem(SEEN_KEY) === '1' || localStorage.getItem(SCALE_KEY) != null;
|
|
} catch (_) { return true; }
|
|
}
|
|
|
|
// The target profile: a physically large viewport rendered near 1:1 (so the
|
|
// OS isn't already enlarging things). This is the eye-strain case.
|
|
function isLargeLowDpiDisplay() {
|
|
var w = window.innerWidth || 0;
|
|
var dpr = window.devicePixelRatio || 1;
|
|
return w >= 1800 && dpr <= 1.25;
|
|
}
|
|
|
|
// Don't interrupt a first-run modal (e.g. profile onboarding). If one is up,
|
|
// leave the flag UNSET so the nudge gets another chance on a later launch.
|
|
function aModalIsOpen() {
|
|
var dialogs = document.querySelectorAll('[role="dialog"], .fixed.inset-0');
|
|
for (var i = 0; i < dialogs.length; i++) {
|
|
var el = dialogs[i];
|
|
if (el.offsetParent !== null && el.getClientRects().length) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function openSetting() {
|
|
try {
|
|
if (typeof window.showScreen === 'function') window.showScreen('settings');
|
|
document.querySelectorAll('#settings-tabbar .fb-tab').forEach(function (b) {
|
|
if (b.dataset.tab === 'accessibility') b.click();
|
|
});
|
|
} catch (_) { /* noop */ }
|
|
}
|
|
|
|
function maybeNudge() {
|
|
if (alreadyHandled()) return;
|
|
if (!isLargeLowDpiDisplay()) return;
|
|
if (!window.fbNotify || typeof window.fbNotify.show !== 'function') return;
|
|
if (aModalIsOpen()) return; // try again next launch
|
|
|
|
try { localStorage.setItem(SEEN_KEY, '1'); } catch (_) { /* private mode */ }
|
|
|
|
var card = window.fbNotify.show({
|
|
title: 'Text looking small?',
|
|
message: 'Make the menus and text larger — tap to open Interface size.',
|
|
icon: '🔍',
|
|
accent: '#0ea5e9',
|
|
durationMs: 9000,
|
|
});
|
|
if (card && card.addEventListener) card.addEventListener('click', openSetting);
|
|
}
|
|
|
|
function start() {
|
|
// Let the app settle (boot, any onboarding) before offering the nudge.
|
|
setTimeout(maybeNudge, 4000);
|
|
}
|
|
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', start, { once: true });
|
|
} else {
|
|
start();
|
|
}
|
|
})();
|