fix(mobile): native settings controls + soundboard/gif/call polish (M5)
Mobile-audit batch 5. Desktop provably unchanged (two review passes). - Translate-language control: raw <select> (crowded narrow tiles + broke under non-default themes) -> the folds-native SettingsSelect used by every other dropdown in the settings screen (native-cinny; keeps aria-label). - Ringtone/Soundboard volume sliders: moved from the fixed-width tile `after` slot (which squeezed the title on phones) to a full-width slider in the tile body, matching the night-light slider pattern. - Screenshare-confirm popover: clamp maxWidth to the viewport so it can't run past the screen edges on a phone (inert on desktop). - In-call soundboard editor rows wrap on a narrow popout instead of crushing the clip-name field. - GifPicker: feed the giphy Grid the measured container width (useElementSize Observer) instead of a fixed 296px, so it doesn't overflow a <312px phone. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -338,6 +338,9 @@ export function CallControls({ callEmbed }: CallControlsProps) {
|
||||
padding: '1rem 1.25rem',
|
||||
zIndex: 100,
|
||||
minWidth: '260px',
|
||||
// Don't run past the screen edges on a narrow phone (centered via
|
||||
// translateX(-50%)); clamp to the viewport minus a small margin.
|
||||
maxWidth: `calc(100vw - 2 * ${config.space.S400})`,
|
||||
boxShadow: '0 8px 32px rgba(0,0,0,0.35)',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
|
||||
@@ -1898,27 +1898,27 @@ function Calls() {
|
||||
/>
|
||||
</SequenceCard>
|
||||
<SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
|
||||
<SettingTile
|
||||
title="Ringtone Volume"
|
||||
description="Volume of the incoming call ringtone."
|
||||
after={
|
||||
<Box direction="Row" alignItems="Center" gap="200" style={{ minWidth: '160px' }}>
|
||||
<input
|
||||
type="range"
|
||||
min="0"
|
||||
max="100"
|
||||
step="5"
|
||||
value={ringtoneVolume}
|
||||
onChange={(e) => setRingtoneVolume(parseInt(e.target.value, 10))}
|
||||
aria-label="Ringtone volume"
|
||||
style={{ flex: 1, accentColor: color.Primary.Main }}
|
||||
/>
|
||||
<Text size="T200" style={{ minWidth: '32px', textAlign: 'right' }}>
|
||||
{ringtoneVolume}%
|
||||
</Text>
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
<SettingTile title="Ringtone Volume" description="Volume of the incoming call ringtone." />
|
||||
<Box
|
||||
direction="Row"
|
||||
alignItems="Center"
|
||||
gap="200"
|
||||
style={{ padding: `0 ${config.space.S400} ${config.space.S300}` }}
|
||||
>
|
||||
<input
|
||||
type="range"
|
||||
min="0"
|
||||
max="100"
|
||||
step="5"
|
||||
value={ringtoneVolume}
|
||||
onChange={(e) => setRingtoneVolume(parseInt(e.target.value, 10))}
|
||||
aria-label="Ringtone volume"
|
||||
style={{ flex: 1, accentColor: color.Primary.Main }}
|
||||
/>
|
||||
<Text size="T200" style={{ minWidth: '32px', textAlign: 'right' }}>
|
||||
{ringtoneVolume}%
|
||||
</Text>
|
||||
</Box>
|
||||
</SequenceCard>
|
||||
<SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
|
||||
<SettingTile
|
||||
@@ -1990,26 +1990,28 @@ function Calls() {
|
||||
}
|
||||
/>
|
||||
{soundboardEnabled && (
|
||||
<SettingTile
|
||||
title="Soundboard Volume"
|
||||
after={
|
||||
<Box alignItems="Center" gap="200" style={{ minWidth: toRem(180) }}>
|
||||
<input
|
||||
type="range"
|
||||
min={0}
|
||||
max={100}
|
||||
step={5}
|
||||
value={soundboardVolume}
|
||||
onChange={(e) => setSoundboardVolume(parseInt(e.target.value, 10))}
|
||||
style={{ flexGrow: 1 }}
|
||||
aria-label="Soundboard volume"
|
||||
/>
|
||||
<Text size="T200" style={{ minWidth: toRem(36), textAlign: 'right' }}>
|
||||
{soundboardVolume}%
|
||||
</Text>
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
<>
|
||||
<SettingTile title="Soundboard Volume" />
|
||||
<Box
|
||||
alignItems="Center"
|
||||
gap="200"
|
||||
style={{ padding: `0 ${config.space.S400} ${config.space.S300}` }}
|
||||
>
|
||||
<input
|
||||
type="range"
|
||||
min={0}
|
||||
max={100}
|
||||
step={5}
|
||||
value={soundboardVolume}
|
||||
onChange={(e) => setSoundboardVolume(parseInt(e.target.value, 10))}
|
||||
style={{ flexGrow: 1 }}
|
||||
aria-label="Soundboard volume"
|
||||
/>
|
||||
<Text size="T200" style={{ minWidth: toRem(36), textAlign: 'right' }}>
|
||||
{soundboardVolume}%
|
||||
</Text>
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
</SequenceCard>
|
||||
</Box>
|
||||
@@ -2454,19 +2456,13 @@ function Messages() {
|
||||
: 'On-device translation isn’t available in this browser. Use a Chromium desktop browser (Chrome/Edge 138+) or the Lotus desktop app.'
|
||||
}
|
||||
after={
|
||||
<select
|
||||
aria-label="Translate messages into"
|
||||
disabled={!translationSupported}
|
||||
<SettingsSelect
|
||||
value={selectedTargetLang}
|
||||
onChange={(e) => setTranslateTargetLang(e.target.value)}
|
||||
style={pickerInputStyle(color, config)}
|
||||
>
|
||||
{TRANSLATE_TARGET_LANGUAGES.map((l) => (
|
||||
<option key={l.code} value={l.code}>
|
||||
{l.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
onChange={(v) => setTranslateTargetLang(v)}
|
||||
disabled={!translationSupported}
|
||||
aria-label="Translate messages into"
|
||||
options={TRANSLATE_TARGET_LANGUAGES.map((l) => ({ value: l.code, label: l.name }))}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
{translationSupported && (
|
||||
|
||||
Reference in New Issue
Block a user