refactor(electron): global caller
Signed-off-by: Innei <i@innei.in>
This commit is contained in:
parent
ff4d0af262
commit
8f1efb256f
|
|
@ -1,4 +1,4 @@
|
|||
import { callGlobalContextMethod } from "@follow/shared/bridge"
|
||||
import { callWindowExpose } from "@follow/shared/bridge"
|
||||
import { dialog } from "electron"
|
||||
|
||||
import { getMainWindow } from "~/window"
|
||||
|
|
@ -17,6 +17,7 @@ export const clearAllData = async () => {
|
|||
message: t("dialog.clearAllData"),
|
||||
buttons: [t("dialog.yes"), t("dialog.no")],
|
||||
})
|
||||
const caller = callWindowExpose(win)
|
||||
|
||||
if (result.response === 1) {
|
||||
return
|
||||
|
|
@ -36,11 +37,12 @@ export const clearAllData = async () => {
|
|||
"cookies",
|
||||
],
|
||||
})
|
||||
callGlobalContextMethod(win, "toast.success", ["App data reset successfully"])
|
||||
|
||||
caller.toast.success("App data reset successfully")
|
||||
|
||||
// reload the app
|
||||
win.reload()
|
||||
} catch (error: any) {
|
||||
callGlobalContextMethod(win, "toast.error", [`Error resetting app data: ${error.message}`])
|
||||
caller.toast.error(`Error resetting app data: ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import path from "node:path"
|
||||
|
||||
import { getRendererHandlers } from "@egoist/tipc/main"
|
||||
import { callGlobalContextMethod } from "@follow/shared/bridge"
|
||||
import { callWindowExpose } from "@follow/shared/bridge"
|
||||
import type { BrowserWindow } from "electron"
|
||||
import { app, clipboard, dialog, screen } from "electron"
|
||||
|
||||
|
|
@ -199,13 +199,17 @@ export const appRoute = {
|
|||
await downloadFile(input, result.filePath).catch((err) => {
|
||||
const senderWindow = (sender as Sender).getOwnerBrowserWindow()
|
||||
if (!senderWindow) return
|
||||
callGlobalContextMethod(senderWindow, "toast.error", ["Download failed!"])
|
||||
callWindowExpose(senderWindow).toast.error("Download failed!", {
|
||||
duration: 1000,
|
||||
})
|
||||
throw err
|
||||
})
|
||||
|
||||
const senderWindow = (sender as Sender).getOwnerBrowserWindow()
|
||||
if (!senderWindow) return
|
||||
callGlobalContextMethod(senderWindow, "toast.success", ["Download success!"])
|
||||
callWindowExpose(senderWindow).toast.success("Download success!", {
|
||||
duration: 1000,
|
||||
})
|
||||
}),
|
||||
|
||||
getAppPath: t.procedure.action(async () => app.getAppPath()),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import fs from "node:fs"
|
|||
import { createRequire } from "node:module"
|
||||
import path from "node:path"
|
||||
|
||||
import { callGlobalContextMethod } from "@follow/shared/bridge"
|
||||
import { callWindowExpose } from "@follow/shared/bridge"
|
||||
import { app, BrowserWindow } from "electron"
|
||||
import { MsEdgeTTS, OUTPUT_FORMAT } from "msedge-tts"
|
||||
|
||||
|
|
@ -54,12 +54,9 @@ export const readerRoute = {
|
|||
if (!window) {
|
||||
return
|
||||
}
|
||||
callGlobalContextMethod(window, "toast.error", [
|
||||
error.message,
|
||||
{
|
||||
duration: 1000,
|
||||
},
|
||||
])
|
||||
callWindowExpose(window).toast.error(error.message, {
|
||||
duration: 1000,
|
||||
})
|
||||
}
|
||||
}),
|
||||
|
||||
|
|
@ -70,12 +67,9 @@ export const readerRoute = {
|
|||
}
|
||||
|
||||
await tts.setMetadata(input, OUTPUT_FORMAT.WEBM_24KHZ_16BIT_MONO_OPUS).catch((error) => {
|
||||
callGlobalContextMethod(window, "toast.error", [
|
||||
error.message,
|
||||
{
|
||||
duration: 1000,
|
||||
},
|
||||
])
|
||||
callWindowExpose(window).toast.error(error.message, {
|
||||
duration: 1000,
|
||||
})
|
||||
})
|
||||
}),
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import path from "node:path"
|
|||
import { fileURLToPath } from "node:url"
|
||||
|
||||
import { is } from "@electron-toolkit/utils"
|
||||
import { callGlobalContextMethod } from "@follow/shared/bridge"
|
||||
import { callWindowExpose } from "@follow/shared/bridge"
|
||||
import { imageRefererMatches } from "@follow/shared/image"
|
||||
import type { BrowserWindowConstructorOptions } from "electron"
|
||||
import { BrowserWindow, screen, shell } from "electron"
|
||||
|
|
@ -219,7 +219,8 @@ export const createMainWindow = () => {
|
|||
window.hide()
|
||||
}
|
||||
|
||||
callGlobalContextMethod(window, "electronClose")
|
||||
const caller = callWindowExpose(window)
|
||||
caller.electronClose()
|
||||
} else {
|
||||
windows.mainWindow = null
|
||||
}
|
||||
|
|
@ -228,11 +229,13 @@ export const createMainWindow = () => {
|
|||
window.on("show", () => {
|
||||
cancelPollingUpdateUnreadCount()
|
||||
|
||||
callGlobalContextMethod(window, "electronShow")
|
||||
const caller = callWindowExpose(window)
|
||||
caller.electronShow()
|
||||
})
|
||||
|
||||
window.on("hide", async () => {
|
||||
const settings = await callGlobalContextMethod(window, "getUISettings")
|
||||
const caller = callWindowExpose(window)
|
||||
const settings = await caller.getUISettings()
|
||||
|
||||
if (settings.showDockBadge) {
|
||||
pollingUpdateUnreadCount()
|
||||
|
|
@ -247,7 +250,8 @@ export const createSettingWindow = (path?: string) => {
|
|||
// if we open a new window then the state between the two windows will be out of sync.
|
||||
if (windows.mainWindow && windows.mainWindow.isVisible()) {
|
||||
windows.mainWindow.show()
|
||||
callGlobalContextMethod(windows.mainWindow, "showSetting", [path])
|
||||
|
||||
callWindowExpose(windows.mainWindow).showSetting(path)
|
||||
return
|
||||
}
|
||||
if (windows.settingWindow) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import type { toast } from "sonner"
|
|||
import type { GeneralSettings, UISettings } from "./interface/settings"
|
||||
|
||||
const PREFIX = "__follow"
|
||||
|
||||
interface RenderGlobalContext {
|
||||
showSetting: (path?: string) => void
|
||||
getGeneralSettings: () => GeneralSettings
|
||||
|
|
@ -19,22 +20,32 @@ export const registerGlobalContext = (context: RenderGlobalContext) => {
|
|||
globalThis[PREFIX] = context
|
||||
}
|
||||
|
||||
export function callGlobalContextMethod<T extends keyof RenderGlobalContext>(
|
||||
window: BrowserWindow,
|
||||
method: T,
|
||||
function createProxy<T extends RenderGlobalContext>(window: BrowserWindow, path: string[] = []): T {
|
||||
return new Proxy((() => {}) as any, {
|
||||
get(_, prop: string) {
|
||||
const newPath = [...path, prop]
|
||||
|
||||
// @ts-expect-error
|
||||
args: Parameters<RenderGlobalContext[T]> = [] as any,
|
||||
): Promise<ReturnType<RenderGlobalContext[T]>>
|
||||
export function callGlobalContextMethod(window: BrowserWindow, method: string, args?: any[]): void
|
||||
return createProxy(window, newPath)
|
||||
},
|
||||
apply(_, __, args: any[]) {
|
||||
const methodPath = path.join(".")
|
||||
|
||||
export function callGlobalContextMethod<T extends keyof RenderGlobalContext>(
|
||||
window: BrowserWindow,
|
||||
method: T,
|
||||
|
||||
args: Parameters<RenderGlobalContext[T]> = [] as any,
|
||||
) {
|
||||
return window.webContents.executeJavaScript(
|
||||
`globalThis.${PREFIX}.${method}(${args.map((arg) => JSON.stringify(arg)).join(",")})`,
|
||||
)
|
||||
return window.webContents.executeJavaScript(
|
||||
`globalThis.${PREFIX}.${methodPath}(${args.map((arg) => JSON.stringify(arg)).join(",")})`,
|
||||
)
|
||||
},
|
||||
})
|
||||
}
|
||||
type AddPromise<T> = T extends (...args: infer A) => Promise<infer R>
|
||||
? (...args: A) => Promise<R>
|
||||
: T extends (...args: infer A) => infer R
|
||||
? (...args: A) => Promise<Awaited<R>>
|
||||
: any
|
||||
|
||||
type Fn<T> = {
|
||||
[K in keyof T]: AddPromise<T[K]> &
|
||||
(T[K] extends object ? { [P in keyof T[K]]: AddPromise<T[K][P]> } : never)
|
||||
}
|
||||
export function callWindowExpose<T extends RenderGlobalContext>(window: BrowserWindow) {
|
||||
return createProxy(window) as Fn<T>
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue