mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-22 06:25:41 +00:00
feat(ui-scale): re-enable scoped interface scaling
Document-level zoom broke portal positioning and Tauri window measurement,
so the slider had been forced to 100 %. Scope the zoom to a wrapper inside
.main-content instead — sidebar, queue, player bar and the Linux custom
title bar live in sibling grid cells of .app-shell and stay 1:1.
- App.tsx: drop the document-level zoom + auto-reset; wrap main-content
children in <div class="main-content-zoom" style={zoom: uiScale}>.
- layout.css: add .main-content-zoom (flex column, fills parent).
- Settings.tsx: re-enable the slider and snap it to the 6 preset stops
(80/90/100/110/125/150) so the thumb lands directly under each preset
button. Legacy off-preset values snap to the nearest stop on load.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+7
-13
@@ -127,6 +127,7 @@ function AppShell() {
|
||||
const toggleFullscreen = usePlayerStore(s => s.toggleFullscreen);
|
||||
const isQueueVisible = usePlayerStore(s => s.isQueueVisible);
|
||||
const toggleQueue = usePlayerStore(s => s.toggleQueue);
|
||||
const uiScale = useFontStore(s => s.uiScale);
|
||||
const initializeFromServerQueue = usePlayerStore(s => s.initializeFromServerQueue);
|
||||
const currentTrack = usePlayerStore(s => s.currentTrack);
|
||||
const isPlaying = usePlayerStore(s => s.isPlaying);
|
||||
@@ -341,6 +342,7 @@ function AppShell() {
|
||||
/>
|
||||
)}
|
||||
<main className="main-content">
|
||||
<div className="main-content-zoom" style={uiScale !== 1 ? { zoom: uiScale } : undefined}>
|
||||
<header className="content-header">
|
||||
<LiveSearch />
|
||||
<div className="spacer" />
|
||||
@@ -389,6 +391,7 @@ function AppShell() {
|
||||
<Route path="/device-sync" element={<DeviceSync />} />
|
||||
</Routes>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
{!isMobile && (
|
||||
<div
|
||||
@@ -919,8 +922,6 @@ export default function App() {
|
||||
useThemeStore(s => s.theme); // keep subscription so re-render on manual change
|
||||
const effectiveTheme = useThemeScheduler();
|
||||
const font = useFontStore(s => s.font);
|
||||
const uiScale = useFontStore(s => s.uiScale);
|
||||
const setUiScale = useFontStore(s => s.setUiScale);
|
||||
const [exportPickerOpen, setExportPickerOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -931,17 +932,10 @@ export default function App() {
|
||||
document.documentElement.setAttribute('data-font', font);
|
||||
}, [font]);
|
||||
|
||||
// TODO(ui-scale): UI scaling is disabled pending a cross-platform rework.
|
||||
// Reset any stored non-100% value so users aren't stuck at a broken scale.
|
||||
// When re-enabling: remove this effect AND re-enable the slider in Settings.tsx.
|
||||
useEffect(() => {
|
||||
if (uiScale !== 1.0) setUiScale(1.0);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
document.documentElement.style.zoom = String(uiScale);
|
||||
}, [uiScale]);
|
||||
// UI scaling is scoped to .main-content via an inner wrapper (see <main>
|
||||
// below). Sidebar, queue, player bar and (Linux) custom title bar stay 1:1
|
||||
// because they live in separate grid cells. Document-level zoom is not used
|
||||
// — it broke portal positioning and Tauri window measurement.
|
||||
|
||||
useEffect(() => {
|
||||
return initAudioListeners();
|
||||
|
||||
Reference in New Issue
Block a user