fix(settings): validate seasonalThemeOverride; commit page zoom on blur; GIF picker opt-in
- seasonalThemeOverride is coerced to 'auto' when the persisted value is outside the union, like every other enum setting (tested). - PageZoomInput commits on blur as well as Enter. - New gifPickerEnabled setting (default off) with a disclosure that GIF searches go to Giphy; the picker doesn't mount and the composer button is hidden while off. Fixes #74 Fixes #75 Fixes #68 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
@@ -241,7 +241,10 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
||||
const showFormat = composerToolbarButtons?.showFormat ?? true;
|
||||
const showEmoji = composerToolbarButtons?.showEmoji ?? true;
|
||||
const showSticker = composerToolbarButtons?.showSticker ?? true;
|
||||
const showGif = composerToolbarButtons?.showGif ?? true;
|
||||
// [Gitea #68] The GIF picker is opt-in (searches go to Giphy); hide the
|
||||
// toolbar button entirely when it's off so it never opens an empty popover.
|
||||
const [gifPickerEnabled] = useSetting(settingsAtom, 'gifPickerEnabled');
|
||||
const showGif = (composerToolbarButtons?.showGif ?? true) && gifPickerEnabled;
|
||||
const showLocation = composerToolbarButtons?.showLocation ?? true;
|
||||
const showPoll = composerToolbarButtons?.showPoll ?? true;
|
||||
const showVoice = composerToolbarButtons?.showVoice ?? true;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, {
|
||||
ChangeEventHandler,
|
||||
FocusEventHandler,
|
||||
FormEventHandler,
|
||||
KeyboardEventHandler,
|
||||
MouseEventHandler,
|
||||
@@ -395,6 +396,16 @@ function PageZoomInput() {
|
||||
setCurrentZoom(evt.target.value);
|
||||
};
|
||||
|
||||
// Shared by Enter and blur so a typed-but-unconfirmed value is never
|
||||
// silently dropped when the input loses focus.
|
||||
const commitZoom = (value: string) => {
|
||||
const newZoom = parseInt(value, 10);
|
||||
if (Number.isNaN(newZoom)) return;
|
||||
const safeZoom = Math.max(Math.min(newZoom, 150), 75);
|
||||
setPageZoom(safeZoom);
|
||||
setCurrentZoom(safeZoom.toString());
|
||||
};
|
||||
|
||||
const handleZoomEnter: KeyboardEventHandler<HTMLInputElement> = (evt) => {
|
||||
if (isKeyHotkey('escape', evt)) {
|
||||
evt.stopPropagation();
|
||||
@@ -405,14 +416,14 @@ function PageZoomInput() {
|
||||
'value' in evt.target &&
|
||||
typeof evt.target.value === 'string'
|
||||
) {
|
||||
const newZoom = parseInt(evt.target.value, 10);
|
||||
if (Number.isNaN(newZoom)) return;
|
||||
const safeZoom = Math.max(Math.min(newZoom, 150), 75);
|
||||
setPageZoom(safeZoom);
|
||||
setCurrentZoom(safeZoom.toString());
|
||||
commitZoom(evt.target.value);
|
||||
}
|
||||
};
|
||||
|
||||
const handleZoomBlur: FocusEventHandler<HTMLInputElement> = (evt) => {
|
||||
commitZoom(evt.target.value);
|
||||
};
|
||||
|
||||
return (
|
||||
<Input
|
||||
style={{ width: toRem(100) }}
|
||||
@@ -426,6 +437,7 @@ function PageZoomInput() {
|
||||
value={currentZoom}
|
||||
onChange={handleZoomChange}
|
||||
onKeyDown={handleZoomEnter}
|
||||
onBlur={handleZoomBlur}
|
||||
after={<Text size="T300">%</Text>}
|
||||
outlined
|
||||
/>
|
||||
@@ -2344,6 +2356,7 @@ function Messages() {
|
||||
'translateTargetLang',
|
||||
);
|
||||
const [autoTranslate, setAutoTranslate] = useSetting(settingsAtom, 'autoTranslate');
|
||||
const [gifPickerEnabled, setGifPickerEnabled] = useSetting(settingsAtom, 'gifPickerEnabled');
|
||||
const translationSupported = chromeTranslationEngine.isSupported();
|
||||
const selectedTargetLang = isSupportedTargetLang(translateTargetLang)
|
||||
? normalizeLang(translateTargetLang)
|
||||
@@ -2446,6 +2459,15 @@ function Messages() {
|
||||
}
|
||||
/>
|
||||
</SequenceCard>
|
||||
<SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
|
||||
<SettingTile
|
||||
title="GIF Picker"
|
||||
description="Every search term (and your IP address) is sent directly to Giphy, not through your homeserver. Off by default."
|
||||
after={
|
||||
<Switch variant="Primary" value={gifPickerEnabled} onChange={setGifPickerEnabled} />
|
||||
}
|
||||
/>
|
||||
</SequenceCard>
|
||||
<SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
|
||||
<SettingTile
|
||||
title="Show Hidden Events"
|
||||
|
||||
Reference in New Issue
Block a user