mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-07-22 21:01:40 +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>
56 lines
2.5 KiB
JavaScript
56 lines
2.5 KiB
JavaScript
// v3 Settings → Accessibility: keeps the "Interface size" control in sync with
|
|
// the host `feedBack.scale` capability. The buttons/slider WRITE via inline
|
|
// `feedBack.scale.set(...)`; this module only REFLECTS current state (active
|
|
// preset, slider position, % readout) so the control mirrors the live value on
|
|
// load, on every change, and each time Settings is opened.
|
|
//
|
|
// Plain non-module script, matching the rest of static/v3/*. Null-guarded so it
|
|
// no-ops on the classic v2 page (which has no Accessibility panel).
|
|
(function () {
|
|
'use strict';
|
|
|
|
function sync(state) {
|
|
if (!state) {
|
|
var cap = window.feedBack && window.feedBack.scale;
|
|
state = cap && typeof cap.get === 'function' ? cap.get() : null;
|
|
}
|
|
if (!state) return;
|
|
|
|
var seg = document.getElementById('setting-interface-size');
|
|
if (seg) {
|
|
seg.querySelectorAll('.fb-seg-btn').forEach(function (b) {
|
|
var on = Math.abs(parseFloat(b.dataset.scale) - state.value) < 0.001;
|
|
b.classList.toggle('active', on);
|
|
b.setAttribute('aria-pressed', on ? 'true' : 'false');
|
|
});
|
|
}
|
|
var slider = document.getElementById('setting-interface-size-slider');
|
|
if (slider && document.activeElement !== slider) {
|
|
slider.value = String(Math.round(state.value * 100));
|
|
}
|
|
var val = document.getElementById('setting-interface-size-val');
|
|
if (val) val.textContent = String(Math.round(state.value * 100));
|
|
}
|
|
|
|
if (window.feedBack && typeof window.feedBack.on === 'function') {
|
|
// Fires on every set() and once on load. The bus delivers a CustomEvent,
|
|
// so we ignore the arg and read the authoritative value via sync() → get().
|
|
window.feedBack.on('scale:changed', function () { sync(); });
|
|
// Re-sync when the user opens Settings (the panel may have re-rendered).
|
|
window.feedBack.on('screen:changed', function (e) {
|
|
var id = e && (e.detail ? e.detail.id : e.id);
|
|
if (id === 'settings') sync();
|
|
});
|
|
}
|
|
// Settings markup is static, but re-sync when settings.js signals it wired.
|
|
document.addEventListener('v3:settings-rendered', function () { sync(); });
|
|
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', function () { sync(); }, { once: true });
|
|
} else {
|
|
sync();
|
|
}
|
|
|
|
window.feedBackInterfaceSize = { sync: sync };
|
|
})();
|