Skip to content

Commit

Permalink
Add separate module for settings window
Browse files Browse the repository at this point in the history
  • Loading branch information
oliverschwendener committed Dec 14, 2024
1 parent 4f1c554 commit 042d615
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 100 deletions.
4 changes: 0 additions & 4 deletions src/main/Core/BrowserWindow/BrowserWindowModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,6 @@ export class BrowserWindowModule {
dependencyRegistry.get("EnvironmentVariableProvider"),
"search.html",
);

ipcMain.on("openSettings", () => {
console.log("open settings window", { pathname: "/settings/general" });
});
}

private static registerBrowserWindowEventListeners(
Expand Down
56 changes: 56 additions & 0 deletions src/main/Core/SettingsWindow/SettingsWindowModule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import type { Dependencies } from "@Core/Dependencies";
import type { DependencyRegistry } from "@Core/DependencyRegistry";
import { BrowserWindow } from "electron";
import { join } from "path";

export class SettingsWindowModule {
public static async bootstrap(dependencyRegistry: DependencyRegistry<Dependencies>) {
const ipcMain = dependencyRegistry.get("IpcMain");

let settingsWindow = await this.createSettingsWindow(dependencyRegistry);

ipcMain.on("openSettings", async () => {
if (settingsWindow.isDestroyed()) {
settingsWindow = await this.createSettingsWindow(dependencyRegistry);
}

settingsWindow.focus();
settingsWindow.show();
});
}

private static async createSettingsWindow(
dependencyRegistry: DependencyRegistry<Dependencies>,
): Promise<BrowserWindow> {
const app = dependencyRegistry.get("App");
const environmentVariableProvider = dependencyRegistry.get("EnvironmentVariableProvider");

const settingsWindow = new BrowserWindow({
show: false,
backgroundMaterial: "mica",
autoHideMenuBar: true,
webPreferences: {
preload: join(__dirname, "..", "dist-preload", "index.js"),
spellcheck: false,

// The dev tools should only be available in development mode. Once the app is packaged, the dev tools
// should be disabled.
devTools: !app.isPackaged,

// The following options are needed for images with `file://` URLs to work during development
allowRunningInsecureContent: !app.isPackaged,
webSecurity: app.isPackaged,
},
});

if (app.isPackaged) {
await settingsWindow.loadFile(join(__dirname, "..", "dist-renderer", "settings.html"));
} else {
await settingsWindow.loadURL(
`${environmentVariableProvider.get("VITE_DEV_SERVER_URL")}/${"settings.html"}`,
);
}

return settingsWindow;
}
}
1 change: 1 addition & 0 deletions src/main/Core/SettingsWindow/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./SettingsWindowModule";
1 change: 1 addition & 0 deletions src/main/Core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export * from "./Settings";
export * from "./SettingsFile";
export * from "./SettingsManager";
export * from "./SettingsReader";
export * from "./SettingsWindow";
export * from "./SettingsWriter";
export * from "./Shell";
export * from "./TaskScheduler";
Expand Down
3 changes: 2 additions & 1 deletion src/main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,9 @@ if (!app.requestSingleInstanceLock()) {
Extensions.ExtensionLoader.bootstrap(dependencyRegistry);
await Core.ExtensionManagerModule.bootstrap(dependencyRegistry);

// BrowserWindow
// Windows
await Core.BrowserWindowModule.bootstrap(dependencyRegistry);
await Core.SettingsWindowModule.bootstrap(dependencyRegistry);

Core.RescanOrchestratorModule.bootstrap(dependencyRegistry);
})();
141 changes: 78 additions & 63 deletions src/renderer/Core/Settings/Settings.tsx
Original file line number Diff line number Diff line change
@@ -1,81 +1,96 @@
import type { KeyboardEvent } from "react";
import { Route, Routes, useNavigate } from "react-router";
import { useScrollBar } from "@Core/Hooks";
import { useI18n } from "@Core/I18n";
import { getTheme } from "@Core/Theme";
import { ThemeContext } from "@Core/ThemeContext";
import { useAppCssProperties } from "@Core/useAppCssProperties";
import { FluentProvider, type Theme } from "@fluentui/react-components";
import { useEffect, useState } from "react";
import { Route, Routes } from "react-router";
import { ExtensionSettings } from "./ExtensionSettings";
import { Navigation } from "./Navigation";
import { settingsPages } from "./Pages";
import { SettingsHeader } from "./SettingsHeader";

export const Settings = () => {
const navigate = useNavigate();
const closeSettings = () => navigate({ pathname: "/" });
const [theme, setTheme] = useState<Theme>(getTheme(window.ContextBridge));

const handleKeyDownEvent = (event: KeyboardEvent) => {
if (event.key === "Escape") {
event.preventDefault();
closeSettings();
}
};
const [shouldPreferDarkColors, setShouldPreferDarkColors] = useState<boolean>(
window.matchMedia("(prefers-color-scheme: dark)").matches,
);

return (
<div
style={{ display: "flex", flexDirection: "column", height: "100%" }}
onKeyDown={handleKeyDownEvent}
tabIndex={-1}
>
<div style={{ flexShrink: 0 }}>
<SettingsHeader onCloseSettingsClicked={closeSettings} />
</div>
const { appCssProperties } = useAppCssProperties();

useI18n();
useScrollBar({ document, theme });

useEffect(() => {
const nativeThemeChangedEventHandler = () => {
setTheme(getTheme(window.ContextBridge));
setShouldPreferDarkColors(window.matchMedia("(prefers-color-scheme: dark)").matches);
};

<div
style={{
flexGrow: 1,
display: "flex",
flexDirection: "row",
boxSizing: "border-box",
height: "100%",
width: "100%",
overflow: "hidden",
}}
>
<div style={{ display: "flex", flexShrink: 0 }}>
window.ContextBridge.ipcRenderer.on("nativeThemeChanged", nativeThemeChangedEventHandler);

return () => {
window.ContextBridge.ipcRenderer.off("nativeThemeChanged", nativeThemeChangedEventHandler);
};
}, []);

return (
<ThemeContext.Provider value={{ theme, setTheme, shouldPreferDarkColors }}>
<FluentProvider theme={theme} style={appCssProperties}>
<div style={{ display: "flex", flexDirection: "column", height: "100%" }} tabIndex={-1}>
<div
style={{
flexGrow: 1,
display: "flex",
flexDirection: "column",
padding: 10,
gap: 20,
flexDirection: "row",
boxSizing: "border-box",
overflowX: "auto",
overflowY: "auto",
height: "100%",
width: "100%",
overflow: "hidden",
}}
>
<Navigation
settingsPages={settingsPages}
enabledExtensions={window.ContextBridge.getEnabledExtensions()}
/>
<div style={{ display: "flex", flexShrink: 0 }}>
<div
style={{
display: "flex",
flexDirection: "column",
padding: 10,
gap: 20,
boxSizing: "border-box",
overflowX: "auto",
overflowY: "auto",
}}
>
<Navigation
settingsPages={settingsPages}
enabledExtensions={window.ContextBridge.getEnabledExtensions()}
/>
</div>
</div>
<div
style={{
height: "100%",
flexGrow: 1,
overflowY: "auto",
padding: 20,
boxSizing: "border-box",
}}
>
<Routes>
{settingsPages.map(({ element, relativePath }) => (
<Route
key={`settings-page-content-${relativePath}`}
path={relativePath}
element={element}
/>
))}
<Route path="extension/:extensionId" element={<ExtensionSettings />} />
</Routes>
</div>
</div>
</div>
<div
style={{
height: "100%",
flexGrow: 1,
overflowY: "auto",
padding: 20,
boxSizing: "border-box",
}}
>
<Routes>
{settingsPages.map(({ element, relativePath }) => (
<Route
key={`settings-page-content-${relativePath}`}
path={relativePath}
element={element}
/>
))}
<Route path="extension/:extensionId" element={<ExtensionSettings />} />
</Routes>
</div>
</div>
</div>
</FluentProvider>
</ThemeContext.Provider>
);
};
31 changes: 0 additions & 31 deletions src/renderer/Core/Settings/SettingsHeader.tsx

This file was deleted.

3 changes: 2 additions & 1 deletion src/renderer/settings.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Settings } from "@Core/Settings";
import { createRoot } from "react-dom/client";
import { HashRouter } from "react-router-dom";

document.addEventListener("DOMContentLoaded", () => {
createRoot(document.getElementById("react-app") as HTMLDivElement).render(
<HashRouter>
<h1> Hello from settings </h1>
<Settings />
</HashRouter>,
);
});

0 comments on commit 042d615

Please sign in to comment.