<img width="496" height="470" alt="Screenshot 2025-10-24 200100" src="https://github.com/user-attachments/assets/e64ee081-dc08-4b54-94a6-9ed41453cfcf" /> This PR adds settings for text size, small, medium (default), large and extra large. This should help more people use Dyad more productively. Closes #1482 <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Adds adjustable workspace zoom levels (90%, 100%, 110%, 125%, 150%) to improve readability and accessibility. Changes apply instantly and persist per user, addressing issue #1482. - **New Features** - Zoom selector in Settings → General. - Persists zoomLevel in user settings and schema. - Applies zoom via Electron webFrame for consistent app scaling. - **Refactors** - Removed deprecated workspaceTextSize setting. - Removed root font-size from globals.css. <sup>Written for commit 54bad25f016a83e9f414025a07e80fdbad859366. Summary will update automatically on new commits.</sup> <!-- End of auto-generated description by cubic. --> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds adjustable app zoom levels (90–150%) with a Settings selector, persisted in user settings, and applied via Electron webFrame. > > - **UI/Settings**: > - Add `ZoomSelector` component and surface it in `Settings → General` (`src/components/ZoomSelector.tsx`, `src/pages/settings.tsx`). > - **Schema/Persistence**: > - Introduce `ZoomLevelSchema` and optional `zoomLevel` in `UserSettingsSchema` (`src/lib/schemas.ts`). > - **Electron Integration**: > - Expose `webFrame.setZoomFactor/getZoomFactor` in `window.electron` (`src/preload.ts`). > - **App Behavior**: > - Apply zoom factor on load and when settings change with default `100%` (`src/app/layout.tsx`). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 54bad25f016a83e9f414025a07e80fdbad859366. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Devforschool <138079274+Devforschool@users.noreply.github.com> Co-authored-by: Will Chen <willchen90@gmail.com>
86 lines
2.7 KiB
TypeScript
86 lines
2.7 KiB
TypeScript
import { SidebarProvider } from "@/components/ui/sidebar";
|
|
import { AppSidebar } from "@/components/app-sidebar";
|
|
import { ThemeProvider } from "../contexts/ThemeContext";
|
|
import { DeepLinkProvider } from "../contexts/DeepLinkContext";
|
|
import { Toaster } from "sonner";
|
|
import { TitleBar } from "./TitleBar";
|
|
import { useEffect, type ReactNode } from "react";
|
|
import { useRunApp } from "@/hooks/useRunApp";
|
|
import { useAtomValue } from "jotai";
|
|
import { previewModeAtom } from "@/atoms/appAtoms";
|
|
import { useSettings } from "@/hooks/useSettings";
|
|
import type { ZoomLevel } from "@/lib/schemas";
|
|
|
|
const DEFAULT_ZOOM_LEVEL: ZoomLevel = "100";
|
|
|
|
export default function RootLayout({ children }: { children: ReactNode }) {
|
|
const { refreshAppIframe } = useRunApp();
|
|
const previewMode = useAtomValue(previewModeAtom);
|
|
const { settings } = useSettings();
|
|
|
|
useEffect(() => {
|
|
const zoomLevel = settings?.zoomLevel ?? DEFAULT_ZOOM_LEVEL;
|
|
const zoomFactor = Number(zoomLevel) / 100;
|
|
|
|
const electronApi = (
|
|
window as Window & {
|
|
electron?: {
|
|
webFrame?: {
|
|
setZoomFactor: (factor: number) => void;
|
|
};
|
|
};
|
|
}
|
|
).electron;
|
|
|
|
if (electronApi?.webFrame?.setZoomFactor) {
|
|
electronApi.webFrame.setZoomFactor(zoomFactor);
|
|
|
|
return () => {
|
|
electronApi.webFrame?.setZoomFactor(Number(DEFAULT_ZOOM_LEVEL) / 100);
|
|
};
|
|
}
|
|
|
|
return () => {};
|
|
}, [settings?.zoomLevel]);
|
|
// Global keyboard listener for refresh events
|
|
useEffect(() => {
|
|
const handleKeyDown = (event: KeyboardEvent) => {
|
|
// Check for Ctrl+R (Windows/Linux) or Cmd+R (macOS)
|
|
if (event.key === "r" && (event.ctrlKey || event.metaKey)) {
|
|
event.preventDefault(); // Prevent default browser refresh
|
|
if (previewMode === "preview") {
|
|
refreshAppIframe(); // Use our custom refresh function instead
|
|
}
|
|
}
|
|
};
|
|
|
|
// Add event listener to document
|
|
document.addEventListener("keydown", handleKeyDown);
|
|
|
|
// Cleanup function to remove event listener
|
|
return () => {
|
|
document.removeEventListener("keydown", handleKeyDown);
|
|
};
|
|
}, [refreshAppIframe, previewMode]);
|
|
|
|
return (
|
|
<>
|
|
<ThemeProvider>
|
|
<DeepLinkProvider>
|
|
<SidebarProvider>
|
|
<TitleBar />
|
|
<AppSidebar />
|
|
<div
|
|
id="layout-main-content-container"
|
|
className="flex h-screenish w-full overflow-x-hidden mt-12 mb-4 mr-4 border-t border-l border-border rounded-lg bg-background"
|
|
>
|
|
{children}
|
|
</div>
|
|
<Toaster richColors />
|
|
</SidebarProvider>
|
|
</DeepLinkProvider>
|
|
</ThemeProvider>
|
|
</>
|
|
);
|
|
}
|