Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 17 additions & 10 deletions apps/desktop/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { RotatingFileSink } from "@okcode/shared/logging";
import { showDesktopConfirmDialog } from "./confirmDialog";
import { createEmptyTabsState } from "./preview";
import { DesktopPreviewController } from "./previewController";
import { resolveDesktopRendererUrl } from "./rendererUrl";
import { syncShellEnvironment } from "./syncShellEnvironment";
import { getAutoUpdateDisabledReason, shouldBroadcastDownloadProgress } from "./updateState";
import {
Expand Down Expand Up @@ -1501,13 +1502,14 @@ function registerIpcHandlers(): void {

// Load the same app URL but with a query parameter so the renderer
// can detect pop-out mode and render a simplified UI if needed.
if (isDevelopment && process.env.VITE_DEV_SERVER_URL) {
void popOut.loadURL(`${process.env.VITE_DEV_SERVER_URL}?popout=true`);
} else {
void popOut.loadFile(Path.join(__dirname, "../../web/dist/index.html"), {
query: { popout: "true" },
});
}
void popOut.loadURL(
resolveDesktopRendererUrl({
isDevelopment,
devServerUrl: process.env.VITE_DEV_SERVER_URL,
scheme: DESKTOP_SCHEME,
query: { popout: true },
}),
);
});

ipcMain.removeHandler(PREVIEW_POP_IN_CHANNEL);
Expand Down Expand Up @@ -1600,11 +1602,16 @@ function createWindow(): BrowserWindow {
window.show();
});

void window.loadURL(
resolveDesktopRendererUrl({
isDevelopment,
devServerUrl: process.env.VITE_DEV_SERVER_URL,
scheme: DESKTOP_SCHEME,
}),
);

if (isDevelopment) {
void window.loadURL(process.env.VITE_DEV_SERVER_URL as string);
window.webContents.openDevTools({ mode: "detach" });
} else {
void window.loadURL(`${DESKTOP_SCHEME}://app/index.html`);
}

window.on("closed", () => {
Expand Down
61 changes: 61 additions & 0 deletions apps/desktop/src/rendererUrl.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { describe, expect, it } from "vitest";

import { resolveDesktopRendererUrl } from "./rendererUrl";

describe("resolveDesktopRendererUrl", () => {
it("builds the packaged renderer URL from the desktop protocol", () => {
expect(
resolveDesktopRendererUrl({
isDevelopment: false,
scheme: "okcode",
}),
).toBe("okcode://app/index.html");
});

it("adds query parameters for packaged pop-out windows", () => {
expect(
resolveDesktopRendererUrl({
isDevelopment: false,
scheme: "okcode",
query: {
popout: true,
},
}),
).toBe("okcode://app/index.html?popout=true");
});

it("adds query parameters to the dev server URL", () => {
expect(
resolveDesktopRendererUrl({
isDevelopment: true,
devServerUrl: "http://127.0.0.1:5173/",
scheme: "okcode",
query: {
popout: true,
},
}),
).toBe("http://127.0.0.1:5173/?popout=true");
});

it("preserves existing dev server search params", () => {
expect(
resolveDesktopRendererUrl({
isDevelopment: true,
devServerUrl: "http://127.0.0.1:5173/?client=desktop",
scheme: "okcode",
query: {
popout: true,
},
}),
).toBe("http://127.0.0.1:5173/?client=desktop&popout=true");
});

it("requires a dev server URL in development mode", () => {
expect(() =>
resolveDesktopRendererUrl({
isDevelopment: true,
scheme: "okcode",
}),
).toThrow("VITE_DEV_SERVER_URL is required when resolving a development renderer URL.");
});
});
35 changes: 35 additions & 0 deletions apps/desktop/src/rendererUrl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
export interface DesktopRendererUrlInput {
readonly isDevelopment: boolean;
readonly devServerUrl?: string | undefined;
readonly scheme: string;
readonly query?: Record<string, string | number | boolean | null | undefined> | undefined;
}

function applyQuery(url: URL, query: DesktopRendererUrlInput["query"]): URL {
if (!query) {
return url;
}

for (const [key, value] of Object.entries(query)) {
if (value === null || value === undefined) {
url.searchParams.delete(key);
continue;
}
url.searchParams.set(key, String(value));
}

return url;
}

export function resolveDesktopRendererUrl(input: DesktopRendererUrlInput): string {
if (input.isDevelopment) {
const devServerUrl = input.devServerUrl;
if (!devServerUrl) {
throw new Error("VITE_DEV_SERVER_URL is required when resolving a development renderer URL.");
}

return applyQuery(new URL(devServerUrl), input.query).toString();
}

return applyQuery(new URL(`${input.scheme}://app/index.html`), input.query).toString();
}
2 changes: 1 addition & 1 deletion apps/web/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { getRouter } from "./router";
import { APP_DISPLAY_NAME } from "./branding";
import { DiffWorkerPoolProvider } from "./components/DiffWorkerPoolProvider";

// Electron loads the app from a file-backed shell, so hash history avoids path resolution issues.
// Electron loads the app from a desktop shell origin, so hash history avoids path resolution issues.
const history = isElectron ? createHashHistory() : createBrowserHistory();

const router = getRouter(history);
Expand Down
Loading