Add "safe area inset" setting to reader

This commit is contained in:
schroda
2026-05-08 01:39:48 +02:00
parent 6d3eb4266b
commit d1e70c2609
15 changed files with 153 additions and 40 deletions

View File

@@ -20,42 +20,34 @@ export enum DirectionOffset {
NEXT = 1,
}
interface DisplayDataTranslation {
isTitleString?: never;
title: MessageDescriptor;
interface DisplayData {
title: MessageDescriptor | string;
icon: ReactNode;
}
interface DisplayDataString {
isTitleString: true;
title: string;
icon: ReactNode;
}
type DisplayData = DisplayDataTranslation | DisplayDataString;
export type ValueToDisplayData<Value extends string | number> = Record<Value, DisplayData>;
export interface MultiValueButtonBaseProps<Value extends string | number> {
export interface MultiValueButtonBaseProps<Value extends string | number, MultiValue extends Value | Value[] = Value> {
tooltip?: string;
value: Value;
value: MultiValue;
defaultValue?: Value;
values: Value[];
setValue: (value: Value) => void;
setValue: (value: MultiValue) => void;
valueToDisplayData: ValueToDisplayData<Value>;
}
export interface MultiValueButtonDefaultableProps<Value extends string | number> extends OptionalProperty<
MultiValueButtonBaseProps<Value>,
'value'
> {
export interface MultiValueButtonDefaultableProps<
Value extends string | number,
MultiValue extends Value | Value[] = Value,
> extends OptionalProperty<MultiValueButtonBaseProps<Value, MultiValue>, 'value'> {
isDefaultable?: boolean;
onDefault?: () => void;
}
export type MultiValueButtonProps<Value extends string | number> =
| (MultiValueButtonBaseProps<Value> & PropertiesNever<MultiValueButtonDefaultableProps<Value>>)
| MultiValueButtonDefaultableProps<Value>;
export type MultiValueButtonProps<Value extends string | number, MultiValue extends Value | Value[] = Value> =
| (MultiValueButtonBaseProps<Value, MultiValue> &
PropertiesNever<MultiValueButtonDefaultableProps<Value, MultiValue>>)
| MultiValueButtonDefaultableProps<Value, MultiValue>;
export enum ScrollOffset {
BACKWARD,

View File

@@ -13,7 +13,7 @@ import { CustomTooltip } from '@/base/components/CustomTooltip.tsx';
import type { MultiValueButtonProps } from '@/base/Base.types.ts';
import { Superscript } from '@/base/components/texts/Superscript.tsx';
export const ButtonSelect = <Value extends string | number>({
export const ButtonSelect = <Value extends string | number, MultiValue extends Value | Value[] = Value>({
value,
values,
defaultValue,
@@ -21,7 +21,7 @@ export const ButtonSelect = <Value extends string | number>({
valueToDisplayData,
isDefaultable,
onDefault,
}: MultiValueButtonProps<Value>) => {
}: MultiValueButtonProps<Value, MultiValue>) => {
const { t } = useLingui();
return (
@@ -33,16 +33,31 @@ export const ButtonSelect = <Value extends string | number>({
)}
{values.map((displayValue) => {
const isDefault = value === undefined && displayValue === defaultValue;
const isMultiSelect = Array.isArray(value);
const isSelected = isMultiSelect ? value.includes(displayValue) : displayValue === value;
const text = valueToDisplayData[displayValue].isTitleString
? valueToDisplayData[displayValue].title
: t(valueToDisplayData[displayValue].title);
const newValue = (() => {
if (value === undefined) {
return [displayValue];
}
if (isMultiSelect) {
return isSelected ? value.filter((v) => v !== displayValue) : [...value, displayValue];
}
return displayValue;
})() as MultiValue;
const text =
typeof valueToDisplayData[displayValue].title === 'string'
? valueToDisplayData[displayValue].title
: t(valueToDisplayData[displayValue].title);
return (
<CustomTooltip key={displayValue} title={isDefault ? t`Active setting` : ''}>
<Button
onClick={() => setValue(displayValue)}
variant={displayValue === value ? 'contained' : 'outlined'}
onClick={() => setValue(newValue)}
variant={isSelected ? 'contained' : 'outlined'}
startIcon={valueToDisplayData[displayValue].icon}
>
{isDefault ? <Superscript superscript="*" text={text} /> : text}

View File

@@ -53,7 +53,7 @@ export const ValueRotationButton = <Value extends string | number>({
<Superscript
superscript={`(${t`Default`})`}
text={
valueToDisplayData[defaultValue].isTitleString
typeof valueToDisplayData[defaultValue].title === 'string'
? valueToDisplayData[defaultValue].title
: t(valueToDisplayData[defaultValue].title)
}
@@ -77,7 +77,7 @@ export const ValueRotationButton = <Value extends string | number>({
startIcon={valueToDisplayData[value].icon}
size="large"
>
{valueToDisplayData[value].isTitleString
{typeof valueToDisplayData[value].title === 'string'
? valueToDisplayData[value].title
: t(valueToDisplayData[value].title)}
</Button>

View File

@@ -12,11 +12,11 @@ import type { ComponentProps } from 'react';
import { ButtonSelect } from '@/base/components/buttons/ButtonSelect.tsx';
export const ButtonSelectInput = <Value extends string | number>({
export const ButtonSelectInput = <Value extends string | number, MultiValue extends Value | Value[] = Value>({
label,
description,
...buttonSelectProps
}: ComponentProps<typeof ButtonSelect<Value>> & { label: string; description?: string }) => (
}: ComponentProps<typeof ButtonSelect<Value, MultiValue>> & { label: string; description?: string }) => (
<Stack>
<Typography>{label}</Typography>
{description && (