Compare commits

..
Author SHA1 Message Date
Lotus CIandClaude Opus 5.5 86b77ac9f3 fix(settings): desktop-only settings get their own Desktop section (#290)
CI / Build & Quality Checks (pull_request) Waiting to run
CI / Trigger Desktop Build (pull_request) Blocked by required conditions
CI / Secret scan (gitleaks) (pull_request) Waiting to run
CI / Docker image build & smoke test (pull_request) Blocked by required conditions
CI / Playwright smoke (e2e) (pull_request) Blocked by required conditions
Custom Window Chrome, Launch on login / When I close the window and the
keychain status sat inside Appearance, between Monochrome Mode and
Twitter Emoji. Move them to a Desktop section (above App Updates),
rendered only in the desktop app.

Fixes #290

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
2026-10-18 00:28:12 -04:00
2 changed files with 25 additions and 96 deletions
+7 -92
View File
@@ -89,9 +89,6 @@ import { zIndices } from '../styles/zIndex';
const PIP_MIN_W = 200;
const PIP_MIN_H = 112;
/** [Gitea #323] Minimised PiP bar size. */
const PIP_MINI_W = 220;
const PIP_MINI_H = 40;
type Corner = 'se' | 'sw' | 'ne' | 'nw';
@@ -984,28 +981,6 @@ export function CallEmbedProvider({ children }: CallEmbedProviderProps) {
);
const [pipIsFullscreen, setPipIsFullscreen] = useState(false);
// [Gitea #323] Minimised PiP: a small draggable bar (room name + expand)
// instead of the video. Remembered; phones start minimised.
const [pipMinimized, setPipMinimized] = useState<boolean>(() => {
try {
const v = localStorage.getItem('pip-minimized');
if (v !== null) return v === '1';
} catch {
/* storage unavailable */
}
return window.innerWidth < 600;
});
const pipFullSizeRef = React.useRef({ width: 280, height: 158 });
const togglePipMinimized = useCallback(() => {
setPipMinimized((m) => {
try {
localStorage.setItem('pip-minimized', m ? '0' : '1');
} catch {
/* storage unavailable */
}
return !m;
});
}, []);
useEffect(() => {
const onFsChange = () => setPipIsFullscreen(!!document.fullscreenElement);
document.addEventListener('fullscreenchange', onFsChange);
@@ -1103,26 +1078,6 @@ export function CallEmbedProvider({ children }: CallEmbedProviderProps) {
}
}, [pipMode, callVisible]);
// [Gitea #323] Apply the minimised / full PiP size (after the entry effect
// below has positioned and sized it). Keeps the bar on screen.
React.useEffect(() => {
const el = callEmbedRef.current;
if (!el || !pipMode) return;
if (pipMinimized) {
if (el.offsetHeight > PIP_MINI_H) {
pipFullSizeRef.current = { width: el.offsetWidth, height: el.offsetHeight };
}
el.style.width = `${PIP_MINI_W}px`;
el.style.height = `${PIP_MINI_H}px`;
} else {
el.style.width = `${pipFullSizeRef.current.width}px`;
el.style.height = `${pipFullSizeRef.current.height}px`;
}
const rect = el.getBoundingClientRect();
el.style.left = `${Math.max(0, Math.min(rect.left, window.innerWidth - el.offsetWidth))}px`;
el.style.top = `${Math.max(0, Math.min(rect.top, window.innerHeight - el.offsetHeight))}px`;
}, [pipMode, pipMinimized, callEmbedRef]);
React.useEffect(() => {
if (!pipMode) return;
const onPipWindowResize = (): void => {
@@ -1441,50 +1396,19 @@ export function CallEmbedProvider({ children }: CallEmbedProviderProps) {
position: 'absolute',
inset: 0,
zIndex: 1,
// Minimised: cover the frame so only the bar shows.
background: pipMinimized ? color.Surface.Container : 'transparent',
background: 'transparent',
cursor: 'grab',
// [Gitea #43] The call's "Share your screen?" prompt is drawn
// inside the frame: let the click reach its Share button.
pointerEvents: pipPromptOpen ? 'none' : undefined,
display: 'flex',
alignItems: 'flex-start',
justifyContent: 'flex-end',
alignItems: pipMinimized ? 'center' : 'flex-start',
padding: '6px',
}}
>
<div
style={{
display: 'flex',
gap: config.space.S100,
alignItems: 'center',
...(pipMinimized ? { width: '100%' } : {}),
}}
>
{/* Leftmost: the top-right corner is a resize handle. */}
<IconButton
type="button"
size="300"
radii="300"
variant="Surface"
fill="None"
aria-label={pipMinimized ? 'Expand call' : 'Minimise call'}
aria-pressed={pipMinimized}
onClick={(e) => {
e.stopPropagation();
togglePipMinimized();
}}
onMouseDown={(e) => e.stopPropagation()}
onTouchStart={(e) => e.stopPropagation()}
style={{
background: 'rgba(0,0,0,0.65)',
backdropFilter: 'blur(4px)',
color: '#fff',
}}
>
<Icon size="100" src={pipMinimized ? Icons.ChevronTop : Icons.Minus} />
</IconButton>
{!pipMinimized && document.fullscreenEnabled && (
<div style={{ display: 'flex', gap: config.space.S100, alignItems: 'center' }}>
{document.fullscreenEnabled && (
<IconButton
type="button"
size="300"
@@ -1516,23 +1440,14 @@ export function CallEmbedProvider({ children }: CallEmbedProviderProps) {
fontSize: '11px',
fontWeight: 600,
pointerEvents: 'none',
...(pipMinimized
? {
flexGrow: 1,
minWidth: 0,
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
}
: {}),
}}
>
{pipMinimized ? `↗ ${callEmbed.room.name ?? 'Call'}` : '↗ Return to call'}
↗ Return to call
</div>
</div>
</div>
{!pipMinimized && <PipMuteOverlay callEmbed={callEmbed} />}
{(pipMinimized ? [] : (['se', 'sw', 'ne', 'nw'] as Corner[])).map((corner) => {
<PipMuteOverlay callEmbed={callEmbed} />
{(['se', 'sw', 'ne', 'nw'] as Corner[]).map((corner) => {
const s = corner.includes('s');
const e2 = corner.includes('e');
const dots = [
+18 -4
View File
@@ -596,10 +596,6 @@ function Appearance() {
/>
</SequenceCard>
<DesktopChromeSetting />
<AutostartSetting />
<KeychainMirrorSetting />
<SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
<SettingTile
title="Twitter Emoji"
@@ -2856,6 +2852,23 @@ function PackageUpdate({ help }: { help: NonNullable<ReturnType<typeof packageUp
);
}
/**
* [Gitea #290] Desktop-only settings in their own section (they used to sit
* inside Appearance, between Monochrome Mode and Twitter Emoji). Renders
* nothing outside the desktop app.
*/
function DesktopSettings() {
if (!isTauriEnv()) return null;
return (
<Box direction="Column" gap="100">
<Text size="L400">Desktop</Text>
<AutostartSetting />
<KeychainMirrorSetting />
<DesktopChromeSetting />
</Box>
);
}
function AppUpdates() {
const { isTauri, status, check, install, installKind } = useTauriUpdater();
if (!isTauri) return null;
@@ -2964,6 +2977,7 @@ export function General({ requestClose }: GeneralProps) {
<StorageUsage />
<SettingsSyncSection />
<Calls />
<DesktopSettings />
<AppUpdates />
</Box>
</PageContent>