* docs: design spec for gesture-based brightness control (#3021) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: revise brightness-gesture spec per /autoplan review (#3021) CEO+Design+Eng dual-voice review. Key fixes: capture-phase listener (bubble-phase could not suppress foliate paginator), opt-out toggle, 18px threshold, selection guard, brightness seed race, rAF teardown, e-ink stepped overlay, contrast capsule, perceptual curve reuse, listener-level test harness. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(reader): swipe-to-adjust brightness gesture on mobile (#3021) Left-edge vertical swipe adjusts screen brightness on iOS/Android, with a Sun-icon progress overlay. Capture-phase non-passive listener suppresses the foliate paginator / page-flip / UI-toggle handlers; selection guard, strip reservation in scrolled mode, eager brightness seed, rAF throttle + teardown. Opt-out toggle in Settings > Behavior > Device (default on). Perceptual curve shared with the menu slider. Pure-helper + listener-level tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reader): detect brightness-swipe edge by screenX; i18n + shorter label (#3021) On-device fix: paginated mode lays the iframe doc out as wide side-by-side columns, so clientX/documentElement.clientWidth are document coordinates and a left-edge touch on a later page never fell inside the strip (armed stayed false). Detect with screenX against the parent window width, matching usePagination. Also: translate the two new setting strings across all locales and shorten the toggle description to 'Slide along the left edge'. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -48,6 +48,9 @@ const ControlPanel: React.FC<SettingsPanelPanelProp> = ({ bookKey, onRegisterRes
|
||||
const [isEink, setIsEink] = useState(viewSettings.isEink);
|
||||
const [isColorEink, setIsColorEink] = useState(viewSettings.isColorEink);
|
||||
const [autoScreenBrightness, setAutoScreenBrightness] = useState(settings.autoScreenBrightness);
|
||||
const [swipeBrightnessGesture, setSwipeBrightnessGesture] = useState(
|
||||
settings.swipeBrightnessGesture,
|
||||
);
|
||||
const [screenWakeLock, setScreenWakeLock] = useState(settings.screenWakeLock);
|
||||
const [allowScript, setAllowScript] = useState(viewSettings.allowScript);
|
||||
|
||||
@@ -191,6 +194,12 @@ const ControlPanel: React.FC<SettingsPanelPanelProp> = ({ bookKey, onRegisterRes
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [autoScreenBrightness]);
|
||||
|
||||
useEffect(() => {
|
||||
if (swipeBrightnessGesture === settings.swipeBrightnessGesture) return;
|
||||
saveSysSettings(envConfig, 'swipeBrightnessGesture', swipeBrightnessGesture);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [swipeBrightnessGesture]);
|
||||
|
||||
useEffect(() => {
|
||||
if (screenWakeLock === settings.screenWakeLock) return;
|
||||
saveSysSettings(envConfig, 'screenWakeLock', screenWakeLock);
|
||||
@@ -382,6 +391,15 @@ const ControlPanel: React.FC<SettingsPanelPanelProp> = ({ bookKey, onRegisterRes
|
||||
onChange={() => setAutoScreenBrightness(!autoScreenBrightness)}
|
||||
/>
|
||||
)}
|
||||
{appService?.hasScreenBrightness && (
|
||||
<SettingsSwitchRow
|
||||
label={_('Swipe for Brightness')}
|
||||
description={_('Slide along the left edge')}
|
||||
checked={swipeBrightnessGesture}
|
||||
onChange={() => setSwipeBrightnessGesture(!swipeBrightnessGesture)}
|
||||
data-setting-id='settings.control.swipeBrightnessGesture'
|
||||
/>
|
||||
)}
|
||||
<SettingsSwitchRow
|
||||
label={_('Keep Screen Awake')}
|
||||
checked={screenWakeLock}
|
||||
|
||||
Reference in New Issue
Block a user