fix(ui): chat background covers full screen regardless of glassmorphism
CI / Build & Quality Checks (push) Successful in 10m27s
Trigger Desktop Build / trigger (push) Successful in 19s

Previously the background was applied directly to <Page> (room view
only) when glassmorphism was off, and to document.body only when
glassmorphism was on. This caused two bugs:
- Without glassmorphism: background only visible in the chat panel,
  not behind the sidebar
- With glassmorphism: Page reverted to its opaque theme surface color,
  so the body background only showed through the glass sidebar

Fix: SidebarNav now always applies the active background to
document.body (regardless of glassmorphism). RoomView's <Page> is
made transparent whenever a background is active so the body
background shows through both the sidebar and the chat area.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-14 18:09:03 -04:00
parent 97d808585a
commit 7f329e3b31
2 changed files with 13 additions and 21 deletions
+7 -19
View File
@@ -17,8 +17,6 @@ import { RoomViewFollowing, RoomViewFollowingPlaceholder } from './RoomViewFollo
import { Page } from '../../components/page';
import { useSetting } from '../../state/hooks/settings';
import { settingsAtom } from '../../state/settings';
import { useTheme, ThemeKind } from '../../hooks/useTheme';
import { getChatBg } from '../lotus/chatBackground';
import { useKeyDown } from '../../hooks/useKeyDown';
import { editableActiveElement } from '../../utils/dom';
import { useRoomPermissions } from '../../hooks/useRoomPermissions';
@@ -61,10 +59,7 @@ export function RoomView({ eventId }: { eventId?: string }) {
const roomViewRef = useRef<HTMLDivElement>(null) as React.RefObject<HTMLDivElement>;
const [chatBackground] = useSetting(settingsAtom, 'chatBackground');
const [lotusTerminal] = useSetting(settingsAtom, 'lotusTerminal');
const [pauseAnimations] = useSetting(settingsAtom, 'pauseAnimations');
const [glassmorphismSidebar] = useSetting(settingsAtom, 'glassmorphismSidebar');
const theme = useTheme();
const isDark = theme.kind === ThemeKind.Dark;
const [hideActivity] = useSetting(settingsAtom, 'hideActivity');
@@ -98,20 +93,13 @@ export function RoomView({ eventId }: { eventId?: string }) {
),
);
// When glassmorphism is active, document.body already carries the background so the
// sidebar blur has something to work through. Skip applying it here to avoid running
// the same CSS animation twice (one per layer = double GPU work).
const chatBgStyle = useMemo(
() =>
glassmorphismSidebar
? {}
: getChatBg(
lotusTerminal && chatBackground === 'none' ? 'tactical' : chatBackground,
isDark,
pauseAnimations,
),
[chatBackground, lotusTerminal, isDark, pauseAnimations, glassmorphismSidebar],
);
// document.body always carries the active background (set by SidebarNav).
// Make Page transparent so the body background shows through the chat area.
// When no background is active, Page keeps its default theme surface color.
const chatBgStyle = useMemo(() => {
const hasBg = chatBackground !== 'none' || glassmorphismSidebar || lotusTerminal;
return hasBg ? ({ background: 'transparent' } as React.CSSProperties) : {};
}, [chatBackground, glassmorphismSidebar, lotusTerminal]);
return (
<Page ref={roomViewRef} style={chatBgStyle}>
+6 -2
View File
@@ -40,7 +40,9 @@ export function SidebarNav() {
// Fix: mirror the active chat background onto document.body so the sidebar blurs through it.
useEffect(() => {
const { style } = document.body;
if (!glassmorphismSidebar) {
const hasBg = chatBackground !== 'none' || glassmorphismSidebar || lotusTerminal;
if (!hasBg) {
style.removeProperty('background-image');
style.removeProperty('background-color');
style.removeProperty('background-size');
@@ -48,13 +50,15 @@ export function SidebarNav() {
style.removeProperty('animation');
return;
}
const effectiveBg = chatBackground === 'none' ? 'tactical' : chatBackground;
const effectiveBg = chatBackground !== 'none' ? chatBackground : 'tactical';
const bgStyle = getChatBg(effectiveBg, isDark, pauseAnimations);
style.backgroundImage = (bgStyle.backgroundImage as string | undefined) ?? '';
style.backgroundColor = (bgStyle.backgroundColor as string | undefined) ?? '';
style.backgroundSize = (bgStyle.backgroundSize as string | undefined) ?? '';
style.backgroundPosition = (bgStyle.backgroundPosition as string | undefined) ?? '';
style.animation = (bgStyle.animation as string | undefined) ?? '';
return () => {
style.removeProperty('background-image');
style.removeProperty('background-color');