Feat: all - support URL protocol
This commit is contained in:
11
package.json
11
package.json
@@ -6,17 +6,22 @@
|
|||||||
"author": "example.com",
|
"author": "example.com",
|
||||||
"homepage": "https://electron-vite.org",
|
"homepage": "https://electron-vite.org",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "electron-vite dev",
|
"dev": "electron-vite dev --sourcemap --remote-debugging-port=9000",
|
||||||
"format": "prettier --write .",
|
"format": "prettier --write .",
|
||||||
"lint": "eslint . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix",
|
"lint": "eslint . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix",
|
||||||
"typecheck": "tsc",
|
"typecheck": "tsc",
|
||||||
"start": "electron-vite preview",
|
"start": "electron-vite preview",
|
||||||
"build": "electron-vite build && npm run typecheck",
|
"build": "electron-vite build && npm run typecheck",
|
||||||
|
"build-test": "electron-vite build --mode testing && npm run typecheck",
|
||||||
"postinstall": "electron-builder install-app-deps",
|
"postinstall": "electron-builder install-app-deps",
|
||||||
"build:unpack": "npm run build && electron-builder --dir",
|
"build:unpack": "npm run build && electron-builder --dir",
|
||||||
|
"build-test:unpack": "npm run build-test && electron-builder --dir",
|
||||||
"build:win": "npm run build && electron-builder --win",
|
"build:win": "npm run build && electron-builder --win",
|
||||||
"build:mac": "electron-vite build && electron-builder --mac",
|
"build-test:win": "npm run build-test && electron-builder --win",
|
||||||
"build:linux": "electron-vite build && electron-builder --linux"
|
"build:mac": "npm run build && electron-builder --mac",
|
||||||
|
"build-test:mac": "npm run build-test && electron-builder --mac",
|
||||||
|
"build:linux": "npm run build && electron-builder --linux",
|
||||||
|
"build-test:linux": "npm run build-test && electron-builder --linux"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@electron-toolkit/preload": "^3.0.0",
|
"@electron-toolkit/preload": "^3.0.0",
|
||||||
|
|||||||
13
src/main/global.d.ts
vendored
Normal file
13
src/main/global.d.ts
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
type Platform = 'WEB' | 'DESKTOP' | 'ANDROID'
|
||||||
|
|
||||||
|
interface ImportMetaEnv {
|
||||||
|
readonly VITE_PLATFORM: Platform
|
||||||
|
readonly VITE_PROTOCOL: string
|
||||||
|
readonly VITE_API_URL: string
|
||||||
|
readonly VITE_API_TOKEN_URL: string
|
||||||
|
readonly VITE_TURNSTILE_SITE_KEY: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ImportMeta {
|
||||||
|
readonly env: ImportMetaEnv
|
||||||
|
}
|
||||||
@@ -1,11 +1,58 @@
|
|||||||
import { app, shell, BrowserWindow, ipcMain } from 'electron'
|
import { app, shell, BrowserWindow, ipcMain, webContents } from 'electron'
|
||||||
import { join } from 'path'
|
import { join } from 'path'
|
||||||
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
|
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
|
||||||
import icon from '../../resources/logo.ico?asset'
|
import icon from '../../resources/logo.ico?asset'
|
||||||
|
import * as path from 'node:path'
|
||||||
|
|
||||||
|
let mainWindow: BrowserWindow
|
||||||
|
|
||||||
|
// Application singleton execution
|
||||||
|
if (!app.requestSingleInstanceLock()) {
|
||||||
|
app.quit()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register protocol client
|
||||||
|
const args: string[] = []
|
||||||
|
if (!app.isPackaged) {
|
||||||
|
args.push(path.resolve(process.argv[1]))
|
||||||
|
}
|
||||||
|
args.push('--')
|
||||||
|
app.setAsDefaultProtocolClient(import.meta.env.VITE_PROTOCOL, process.execPath, args)
|
||||||
|
|
||||||
|
const handleArgv = (argv: string[]) => {
|
||||||
|
const prefix = `${import.meta.env.VITE_PROTOCOL}:`
|
||||||
|
const offset = app.isPackaged ? 1 : 2
|
||||||
|
const url = argv.find((arg, index) => index >= offset && arg.startsWith(prefix))
|
||||||
|
if (url) {
|
||||||
|
handleUrl(url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleUrl = (url: string) => {
|
||||||
|
const { hostname, pathname } = new URL(url)
|
||||||
|
if (hostname === 'openurl') {
|
||||||
|
webContents.getAllWebContents().forEach((webContent) => {
|
||||||
|
webContent.send('open-url', pathname)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Windows
|
||||||
|
handleArgv(process.argv)
|
||||||
|
app.on('second-instance', (_, argv) => {
|
||||||
|
if (process.platform === 'win32') {
|
||||||
|
handleArgv(argv)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// macOS
|
||||||
|
app.on('open-url', (_, argv) => {
|
||||||
|
handleUrl(argv)
|
||||||
|
})
|
||||||
|
|
||||||
function createWindow(): void {
|
function createWindow(): void {
|
||||||
// Create the browser window.
|
// Create the browser window.
|
||||||
const mainWindow = new BrowserWindow({
|
mainWindow = new BrowserWindow({
|
||||||
width: 900,
|
width: 900,
|
||||||
height: 670,
|
height: 670,
|
||||||
show: false,
|
show: false,
|
||||||
|
|||||||
@@ -9,15 +9,15 @@ const api = {}
|
|||||||
// just add to the DOM global.
|
// just add to the DOM global.
|
||||||
if (process.contextIsolated) {
|
if (process.contextIsolated) {
|
||||||
try {
|
try {
|
||||||
contextBridge.exposeInMainWorld('electron', electronAPI)
|
contextBridge.exposeInMainWorld('electronAPI', electronAPI)
|
||||||
contextBridge.exposeInMainWorld('api', api)
|
contextBridge.exposeInMainWorld('api', api)
|
||||||
contextBridge.exposeInMainWorld('notification', Notification)
|
contextBridge.exposeInMainWorld('Notification', Notification)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// @ts-expect-error (define in dts)
|
// @ts-expect-error (define in dts)
|
||||||
window.electron = electronAPI
|
window.electronAPI = electronAPI
|
||||||
// @ts-expect-error (define in dts)
|
// @ts-expect-error (define in dts)
|
||||||
window.api = api
|
window.api = api
|
||||||
// @ts-expect-error (define in dts)
|
// @ts-expect-error (define in dts)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { getRedirectUrl } from '@/util/route'
|
|||||||
import { getLoginStatus, getVerifyStatus_async } from '@/util/auth'
|
import { getLoginStatus, getVerifyStatus_async } from '@/util/auth'
|
||||||
|
|
||||||
const AuthRoute = () => {
|
const AuthRoute = () => {
|
||||||
|
const navigate = useNavigate()
|
||||||
const [searchParams] = useSearchParams()
|
const [searchParams] = useSearchParams()
|
||||||
const matches = useMatches()
|
const matches = useMatches()
|
||||||
const lastMatch = matches.reduce((_, second) => second)
|
const lastMatch = matches.reduce((_, second) => second)
|
||||||
@@ -12,6 +13,12 @@ const AuthRoute = () => {
|
|||||||
const isLogin = getLoginStatus()
|
const isLogin = getLoginStatus()
|
||||||
const isVerify = getVerifyStatus_async()
|
const isVerify = getVerifyStatus_async()
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.electronAPI.ipcRenderer.on('open-url', (_, url: string) => {
|
||||||
|
navigate(url)
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
document.title = `${handle?.titlePrefix ?? ''}${
|
document.title = `${handle?.titlePrefix ?? ''}${
|
||||||
handle?.title ? handle?.title : PRODUCTION_NAME
|
handle?.title ? handle?.title : PRODUCTION_NAME
|
||||||
|
|||||||
8
src/renderer/src/electron.d.ts
vendored
Normal file
8
src/renderer/src/electron.d.ts
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { ElectronAPI } from "@electron-toolkit/preload";
|
||||||
|
import { Notification } from "electron";
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
type _ElectronAPI = ElectronAPI
|
||||||
|
|
||||||
|
class _Notification extends Notification {}
|
||||||
|
}
|
||||||
7
src/renderer/src/global.d.ts
vendored
7
src/renderer/src/global.d.ts
vendored
@@ -1,10 +1,12 @@
|
|||||||
/// <reference types="vite/client" />
|
/// <reference types="vite/client" />
|
||||||
|
/// <reference types="./electron" />
|
||||||
/// <reference types="./ant-design" />
|
/// <reference types="./ant-design" />
|
||||||
|
|
||||||
type Platform = 'WEB' | 'DESKTOP' | 'ANDROID'
|
type Platform = 'WEB' | 'DESKTOP' | 'ANDROID'
|
||||||
|
|
||||||
interface ImportMetaEnv {
|
interface ImportMetaEnv {
|
||||||
readonly VITE_PLATFORM: Platform
|
readonly VITE_PLATFORM: Platform
|
||||||
|
readonly VITE_PROTOCOL: string
|
||||||
readonly VITE_API_URL: string
|
readonly VITE_API_URL: string
|
||||||
readonly VITE_API_TOKEN_URL: string
|
readonly VITE_API_TOKEN_URL: string
|
||||||
readonly VITE_TURNSTILE_SITE_KEY: string
|
readonly VITE_TURNSTILE_SITE_KEY: string
|
||||||
@@ -14,6 +16,11 @@ interface ImportMeta {
|
|||||||
readonly env: ImportMetaEnv
|
readonly env: ImportMetaEnv
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Window {
|
||||||
|
electronAPI: _ElectronAPI
|
||||||
|
Notification: typeof _Notification
|
||||||
|
}
|
||||||
|
|
||||||
interface RouteJsonObject {
|
interface RouteJsonObject {
|
||||||
path: string
|
path: string
|
||||||
absolutePath: string
|
absolutePath: string
|
||||||
|
|||||||
Reference in New Issue
Block a user