refactor(app): remove window state migration

This commit is contained in:
Brendan Allan
2026-07-01 14:28:37 +08:00
parent cbcc661854
commit b9e595f212
13 changed files with 15 additions and 75 deletions
@@ -45,7 +45,7 @@ export async function installStressSessionTabs(page: Page, input?: { draftID?: s
}),
)
localStorage.setItem(
"opencode.global.dat:tabs",
"opencode.window.browser.dat:tabs",
JSON.stringify([
...sessionIDs.map((sessionId) => ({
type: "session",
@@ -14,7 +14,7 @@ test("closing the active server's last tab opens the remaining server tab", asyn
localStorage.setItem("settings.v3", JSON.stringify({ general: { newLayoutDesigns: true } }))
localStorage.setItem("opencode.global.dat:server", JSON.stringify({ list: [serverB] }))
localStorage.setItem(
"opencode.global.dat:tabs",
"opencode.window.browser.dat:tabs",
JSON.stringify([
{ type: "session", server: "http://127.0.0.1:4096", sessionId: sessionA },
{ type: "session", server: serverB, sessionId: sessionB },
@@ -52,7 +52,7 @@ test("legacy session routes preserve an existing tab's server", async ({ page })
localStorage.setItem("settings.v3", JSON.stringify({ general: { newLayoutDesigns: true } }))
localStorage.setItem("opencode.global.dat:server", JSON.stringify({ list: [serverB] }))
localStorage.setItem(
"opencode.global.dat:tabs",
"opencode.window.browser.dat:tabs",
JSON.stringify([{ type: "session", server: serverB, sessionId: sessionB }]),
)
},
@@ -145,7 +145,7 @@ async function configurePage(page: Page) {
}),
)
localStorage.setItem(
"opencode.global.dat:tabs",
"opencode.window.browser.dat:tabs",
JSON.stringify(sessionIDs.map((sessionId) => ({ type: "session", server, dirBase64, sessionId }))),
)
},
@@ -127,7 +127,7 @@ test.describe("smoke: session timeline", () => {
await page.addInitScript(
({ dirBase64, sourceID, targetID }) => {
localStorage.setItem(
"opencode.global.dat:tabs",
"opencode.window.browser.dat:tabs",
JSON.stringify(
[sourceID, targetID].map((sessionId) => ({
type: "session",
@@ -253,7 +253,7 @@ test.describe("smoke: session timeline", () => {
await page.addInitScript(
({ dirBase64, sourceID, targetID }) => {
localStorage.setItem(
"opencode.global.dat:tabs",
"opencode.window.browser.dat:tabs",
JSON.stringify(
[sourceID, targetID].map((sessionId) => ({
type: "session",
-3
View File
@@ -67,9 +67,6 @@ type PlatformBase = {
/** Stable platform window identity for window-scoped persistence */
windowID?: string
/** Whether window-scoped persistence should migrate legacy global values */
migrateGlobalWindowState?: boolean
/** Application-global desktop updater */
updater?: UpdaterPlatform
+1 -15
View File
@@ -210,13 +210,12 @@ describe("persist localStorage resilience", () => {
expect(Persist.serverGlobal("a:b" as ServerScope, "c")).not.toEqual(Persist.serverGlobal("a" as ServerScope, "b:c"))
})
test("window target scopes browser storage and migrates global values", () => {
test("window target scopes browser storage", () => {
const target = persistTesting.resolveTarget(Persist.window("tabs"), { platform: "web" } as ResolvePlatform)
expect(target).toEqual({
scope: "window",
storage: persistTesting.windowStorage("browser"),
legacyStorageNames: ["opencode.global.dat"],
key: "tabs",
legacy: undefined,
})
@@ -226,13 +225,11 @@ describe("persist localStorage resilience", () => {
const target = persistTesting.resolveTarget(Persist.window("tabs"), {
platform: "desktop",
windowID: "window-a",
migrateGlobalWindowState: false,
} as ResolvePlatform)
expect(target).toEqual({
scope: "window",
storage: persistTesting.windowStorage("window-a"),
legacyStorageNames: undefined,
key: "tabs",
legacy: undefined,
})
@@ -241,7 +238,6 @@ describe("persist localStorage resilience", () => {
test("window target preserves global desktop storage without a window id", () => {
const target = persistTesting.resolveTarget(Persist.window("tabs"), {
platform: "desktop",
migrateGlobalWindowState: true,
} as ResolvePlatform)
expect(target).toEqual({
@@ -251,14 +247,4 @@ describe("persist localStorage resilience", () => {
legacy: undefined,
})
})
test("window target lets one desktop window migrate global values", () => {
const target = persistTesting.resolveTarget(Persist.window("tabs"), {
platform: "desktop",
windowID: "window-a",
migrateGlobalWindowState: true,
} as ResolvePlatform)
expect(target.legacyStorageNames).toEqual(["opencode.global.dat"])
})
})
-2
View File
@@ -519,11 +519,9 @@ function resolveTarget(target: PersistTarget, platform: Platform): PersistTarget
if (target.scope !== "window") return target
if (platform.platform === "desktop" && !platform.windowID) return { ...target, storage: GLOBAL_STORAGE }
const windowID = platform.platform === "desktop" ? (platform.windowID ?? "browser") : "browser"
const shouldMigrate = platform.platform !== "desktop" || platform.migrateGlobalWindowState === true
return {
...target,
storage: windowStorage(windowID),
legacyStorageNames: shouldMigrate ? [GLOBAL_STORAGE, ...(target.legacyStorageNames ?? [])] : target.legacyStorageNames,
}
}
-7
View File
@@ -12,7 +12,6 @@ import { getStore } from "./store"
import {
getPinchZoomEnabled,
getWindowID,
getWindowMigrateGlobalState,
setPinchZoomEnabled,
setTitlebar,
updateTitlebar,
@@ -205,12 +204,6 @@ export function registerIpcHandlers(deps: Deps) {
return id
})
ipcMain.handle("get-window-migrate-global-state", (event: IpcMainInvokeEvent) => {
const win = BrowserWindow.fromWebContents(event.sender)
if (!win) return false
return getWindowMigrateGlobalState(win)
})
ipcMain.handle("get-window-focused", (event: IpcMainInvokeEvent) => {
const win = BrowserWindow.fromWebContents(event.sender)
return win?.isFocused() ?? false
-1
View File
@@ -3,4 +3,3 @@ export const DEFAULT_SERVER_URL_KEY = "defaultServerUrl"
export const WSL_SERVERS_KEY = "wslServers"
export const PINCH_ZOOM_ENABLED_KEY = "pinchZoomEnabled"
export const WINDOW_IDS_KEY = "windowIds"
export const WINDOW_GLOBAL_STATE_MIGRATION_ID_KEY = "windowGlobalStateMigrationId"
+2 -17
View File
@@ -9,7 +9,7 @@ import { fileURLToPath, pathToFileURL } from "node:url"
import type { TitlebarTheme } from "../preload/types"
import { exportDebugLogs, write as writeLog } from "./logging"
import { getStore } from "./store"
import { PINCH_ZOOM_ENABLED_KEY, WINDOW_GLOBAL_STATE_MIGRATION_ID_KEY, WINDOW_IDS_KEY } from "./store-keys"
import { PINCH_ZOOM_ENABLED_KEY, WINDOW_IDS_KEY } from "./store-keys"
import { createUnresponsiveSampler } from "./unresponsive"
const root = dirname(fileURLToPath(import.meta.url))
@@ -45,7 +45,6 @@ let relaunchHandler = () => {
}
let appQuitting = false
let lastFocusedWindowID: string | undefined
let windowGlobalStateMigrationID: string | undefined
const titlebarThemes = new WeakMap<BrowserWindow, Partial<TitlebarTheme>>()
const pinchZoomEnabled = new WeakMap<BrowserWindow, boolean>()
const windowIDs = new WeakMap<BrowserWindow, string>()
@@ -125,10 +124,6 @@ export function getWindowID(win: BrowserWindow) {
return windowIDs.get(win)
}
export function getWindowMigrateGlobalState(win: BrowserWindow) {
return getWindowID(win) === windowGlobalStateMigrationID
}
export function getLastFocusedWindow() {
const focused = BrowserWindow.getFocusedWindow()
if (focused) return focused
@@ -140,9 +135,7 @@ export function getLastFocusedWindow() {
export function restoreMainWindows() {
const ids = readWindowIDs()
const next = ids.length ? ids : [randomUUID()]
windowGlobalStateMigrationID = readWindowGlobalStateMigrationID(next)
return next.map((id) => createMainWindow(id))
return (ids.length ? ids : [randomUUID()]).map((id) => createMainWindow(id))
}
export function setDockIcon() {
@@ -252,14 +245,6 @@ function removeWindowID(id: string) {
writeWindowIDs(readWindowIDs().filter((item) => item !== id))
}
function readWindowGlobalStateMigrationID(ids: string[]) {
const value = getStore().get(WINDOW_GLOBAL_STATE_MIGRATION_ID_KEY)
if (typeof value === "string" && ids.includes(value)) return value
const next = ids[0]
if (next) getStore().set(WINDOW_GLOBAL_STATE_MIGRATION_ID_KEY, next)
return next
}
export function registerRendererProtocol() {
if (protocol.isProtocolHandled(rendererProtocol)) return
-1
View File
@@ -74,7 +74,6 @@ const api: ElectronAPI = {
getWindowCount: () => ipcRenderer.invoke("get-window-count"),
getWindowID: () => ipcRenderer.invoke("get-window-id"),
getWindowMigrateGlobalState: () => ipcRenderer.invoke("get-window-migrate-global-state"),
onMenuCommand: (cb) => {
const handler = (_: unknown, id: string) => cb(id)
ipcRenderer.on("menu-command", handler)
-1
View File
@@ -63,7 +63,6 @@ export type ElectronAPI = {
getWindowCount: () => Promise<number>
getWindowID: () => Promise<string>
getWindowMigrateGlobalState: () => Promise<boolean>
onMenuCommand: (cb: (id: string) => void) => () => void
onDeepLink: (cb: (urls: string[]) => void) => () => void
+6 -22
View File
@@ -63,11 +63,9 @@ const [updaterState, setUpdaterState] = createSignal<UpdaterState>({ status: "di
void window.api.updater.subscribe(setUpdaterState)
const deepLinkEvent = "opencode:deep-link"
const lastActiveUrlKey = "opencode.desktop.last-active-url"
type DesktopWindowState = {
id?: string
migrateGlobalWindowState: boolean
}
const emitDeepLinks = (urls: string[]) => {
@@ -87,12 +85,10 @@ function windowLastActiveUrlKey(windowID: string) {
return `opencode.desktop.window.${windowID}.last-active-url`
}
function getLastActiveUrl(windowID: string, migrateGlobalWindowState: boolean) {
function getLastActiveUrl(windowID: string) {
if (typeof localStorage !== "object") return "/"
try {
const value =
localStorage.getItem(windowLastActiveUrlKey(windowID)) ??
(migrateGlobalWindowState ? localStorage.getItem(lastActiveUrlKey) : null)
const value = localStorage.getItem(windowLastActiveUrlKey(windowID))
if (value?.startsWith("/") && !value.startsWith("//")) return value
} catch {}
return "/"
@@ -105,9 +101,9 @@ function setLastActiveUrl(windowID: string, value: string) {
} catch {}
}
function DesktopMemoryRouter(props: BaseRouterProps & { windowID: string; migrateGlobalWindowState: boolean }) {
function DesktopMemoryRouter(props: BaseRouterProps & { windowID: string }) {
const history = createMemoryHistory()
const initialUrl = getLastActiveUrl(props.windowID, props.migrateGlobalWindowState)
const initialUrl = getLastActiveUrl(props.windowID)
if (initialUrl !== "/") history.set({ value: initialUrl, replace: true, scroll: false })
onCleanup(history.listen((value) => setLastActiveUrl(props.windowID, value)))
return <MemoryRouter {...props} history={history} />
@@ -173,7 +169,6 @@ const createPlatform = (windowState: DesktopWindowState): Platform => {
os,
version: pkg.version,
windowID: windowState.id,
migrateGlobalWindowState: windowState.migrateGlobalWindowState,
async openDirectoryPickerDialog(opts) {
return window.api.openDirectoryPicker({
@@ -349,13 +344,7 @@ function DesktopRoot(props: { windowState: DesktopWindowState }) {
const [defaultServer] = createResource(() => platform.getDefaultServer?.())
const [locale] = createResource(loadLocale)
const router = (props: BaseRouterProps) => (
<DesktopMemoryRouter
{...props}
windowID={platform.windowID ?? "browser"}
migrateGlobalWindowState={platform.migrateGlobalWindowState === true}
/>
)
const router = (props: BaseRouterProps) => <DesktopMemoryRouter {...props} windowID={platform.windowID ?? "browser"} />
function handleClick(e: MouseEvent) {
const link = (e.target as HTMLElement).closest("a.external-link") as HTMLAnchorElement | null
@@ -443,13 +432,8 @@ render(() => {
const [windowState] = createResource(async () => {
const api = window.api as typeof window.api & {
getWindowID?: () => Promise<string>
getWindowMigrateGlobalState?: () => Promise<boolean>
}
const id = await api.getWindowID?.()
return {
id,
migrateGlobalWindowState: id ? await (api.getWindowMigrateGlobalState?.() ?? false) : false,
}
return { id: await api.getWindowID?.() }
})
return (