refactor: remove minapp.html
This commit is contained in:
parent
4c2014f1d6
commit
461458e5ec
@ -7,15 +7,7 @@ export default defineConfig({
|
|||||||
plugins: [externalizeDepsPlugin()]
|
plugins: [externalizeDepsPlugin()]
|
||||||
},
|
},
|
||||||
preload: {
|
preload: {
|
||||||
plugins: [externalizeDepsPlugin()],
|
plugins: [externalizeDepsPlugin()]
|
||||||
build: {
|
|
||||||
rollupOptions: {
|
|
||||||
input: {
|
|
||||||
index: resolve(__dirname, 'src/preload/index.ts'),
|
|
||||||
minapp: resolve(__dirname, 'src/preload/minapp.ts')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
renderer: {
|
renderer: {
|
||||||
resolve: {
|
resolve: {
|
||||||
|
|||||||
@ -1,70 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>MinApp</title>
|
|
||||||
<style>
|
|
||||||
html,
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
header {
|
|
||||||
height: 40px;
|
|
||||||
background-color: #303030;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
-webkit-app-region: drag;
|
|
||||||
}
|
|
||||||
#header-left {
|
|
||||||
margin-left: 10px;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
||||||
#header-center {
|
|
||||||
color: #fff;
|
|
||||||
font-size: 14px;
|
|
||||||
margin-left: 10px;
|
|
||||||
}
|
|
||||||
#header-right {
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: 10px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
button {
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
color: white;
|
|
||||||
cursor: pointer;
|
|
||||||
width: 26px;
|
|
||||||
height: 26px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 14px;
|
|
||||||
border-radius: 3px;
|
|
||||||
-webkit-app-region: no-drag;
|
|
||||||
}
|
|
||||||
button:hover {
|
|
||||||
background-color: #555;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<header>
|
|
||||||
<div id="header-left"></div>
|
|
||||||
<div id="header-center"></div>
|
|
||||||
<div id="header-right"></div>
|
|
||||||
</header>
|
|
||||||
<script type="module">
|
|
||||||
import { getQueryParam } from './js/utils.js'
|
|
||||||
const title = getQueryParam('title')
|
|
||||||
document.getElementById('header-center').innerHTML = title
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -50,7 +50,13 @@ app.whenReady().then(() => {
|
|||||||
ipcMain.handle('save-file', saveFile)
|
ipcMain.handle('save-file', saveFile)
|
||||||
|
|
||||||
ipcMain.handle('minapp', (_, args) => {
|
ipcMain.handle('minapp', (_, args) => {
|
||||||
createMinappWindow(args)
|
createMinappWindow({
|
||||||
|
url: args.url,
|
||||||
|
windowOptions: {
|
||||||
|
...mainWindow.getBounds(),
|
||||||
|
...args.windowOptions
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.handle('set-theme', (_, theme: 'light' | 'dark') => {
|
ipcMain.handle('set-theme', (_, theme: 'light' | 'dark') => {
|
||||||
|
|||||||
@ -1,32 +0,0 @@
|
|||||||
/**
|
|
||||||
* 将 JavaScript 对象转换为 URL 查询参数字符串
|
|
||||||
* @param obj - 要转换的对象
|
|
||||||
* @param options - 配置选项
|
|
||||||
* @returns 转换后的查询参数字符串
|
|
||||||
*/
|
|
||||||
export function objectToQueryParams(
|
|
||||||
obj: Record<string, string | number | boolean | null | undefined | object>,
|
|
||||||
options: {
|
|
||||||
skipNull?: boolean
|
|
||||||
skipUndefined?: boolean
|
|
||||||
} = {}
|
|
||||||
): string {
|
|
||||||
const { skipNull = false, skipUndefined = false } = options
|
|
||||||
|
|
||||||
const params = new URLSearchParams()
|
|
||||||
|
|
||||||
for (const [key, value] of Object.entries(obj)) {
|
|
||||||
if (skipNull && value === null) continue
|
|
||||||
if (skipUndefined && value === undefined) continue
|
|
||||||
|
|
||||||
if (Array.isArray(value)) {
|
|
||||||
value.forEach((item) => params.append(key, String(item)))
|
|
||||||
} else if (typeof value === 'object' && value !== null) {
|
|
||||||
params.append(key, JSON.stringify(value))
|
|
||||||
} else if (value !== undefined && value !== null) {
|
|
||||||
params.append(key, String(value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return params.toString()
|
|
||||||
}
|
|
||||||
@ -1,11 +1,10 @@
|
|||||||
import { is } from '@electron-toolkit/utils'
|
import { is } from '@electron-toolkit/utils'
|
||||||
import { app, BrowserView, BrowserWindow, Menu, MenuItem, shell } from 'electron'
|
import { BrowserWindow, Menu, MenuItem, shell } from 'electron'
|
||||||
import windowStateKeeper from 'electron-window-state'
|
import windowStateKeeper from 'electron-window-state'
|
||||||
import { join } from 'path'
|
import { join } from 'path'
|
||||||
|
|
||||||
import icon from '../../build/icon.png?asset'
|
import icon from '../../build/icon.png?asset'
|
||||||
import { appConfig, titleBarOverlayDark, titleBarOverlayLight } from './config'
|
import { appConfig, titleBarOverlayDark, titleBarOverlayLight } from './config'
|
||||||
import { objectToQueryParams } from './utils'
|
|
||||||
|
|
||||||
export function createMainWindow() {
|
export function createMainWindow() {
|
||||||
// Load the previous state with fallback to defaults
|
// Load the previous state with fallback to defaults
|
||||||
@ -62,14 +61,7 @@ export function createMainWindow() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
mainWindow.webContents.setWindowOpenHandler((details) => {
|
mainWindow.webContents.setWindowOpenHandler((details) => {
|
||||||
const websiteReg = /accounts.google.com/i
|
shell.openExternal(details.url)
|
||||||
|
|
||||||
if (websiteReg.test(details.url)) {
|
|
||||||
createMinappWindow({ url: details.url, windowOptions: { width: 1000, height: 680 } })
|
|
||||||
} else {
|
|
||||||
shell.openExternal(details.url)
|
|
||||||
}
|
|
||||||
|
|
||||||
return { action: 'deny' }
|
return { action: 'deny' }
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -107,45 +99,23 @@ export function createMinappWindow({
|
|||||||
url: string
|
url: string
|
||||||
windowOptions?: Electron.BrowserWindowConstructorOptions
|
windowOptions?: Electron.BrowserWindowConstructorOptions
|
||||||
}) {
|
}) {
|
||||||
const width = 1000
|
const width = windowOptions?.width || 1000
|
||||||
const height = 680
|
const height = windowOptions?.height || 680
|
||||||
const headerHeight = 40
|
|
||||||
|
|
||||||
const minappWindow = new BrowserWindow({
|
const minappWindow = new BrowserWindow({
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
autoHideMenuBar: true,
|
autoHideMenuBar: true,
|
||||||
alwaysOnTop: true,
|
title: 'Cherry Studio',
|
||||||
titleBarOverlay: titleBarOverlayDark,
|
|
||||||
titleBarStyle: 'hidden',
|
|
||||||
...windowOptions,
|
...windowOptions,
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
preload: join(__dirname, '../preload/minapp.js'),
|
preload: join(__dirname, '../preload/minapp.js'),
|
||||||
sandbox: false
|
sandbox: false,
|
||||||
|
contextIsolation: false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const view = new BrowserView()
|
minappWindow.loadURL(url)
|
||||||
view.setBounds({ x: 0, y: headerHeight, width, height: height - headerHeight })
|
|
||||||
view.webContents.loadURL(url)
|
|
||||||
|
|
||||||
const minappWindowParams = {
|
|
||||||
title: windowOptions?.title || 'CherryStudio'
|
|
||||||
}
|
|
||||||
|
|
||||||
const appPath = app.getAppPath()
|
|
||||||
const minappHtmlPath = appPath + '/resources/minapp.html'
|
|
||||||
|
|
||||||
minappWindow.loadURL('file://' + minappHtmlPath + '?' + objectToQueryParams(minappWindowParams))
|
|
||||||
minappWindow.setBrowserView(view)
|
|
||||||
minappWindow.on('resize', () => {
|
|
||||||
view.setBounds({
|
|
||||||
x: 0,
|
|
||||||
y: headerHeight,
|
|
||||||
width: minappWindow.getBounds().width,
|
|
||||||
height: minappWindow.getBounds().height - headerHeight
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
return minappWindow
|
return minappWindow
|
||||||
}
|
}
|
||||||
|
|||||||
2
src/preload/index.d.ts
vendored
2
src/preload/index.d.ts
vendored
@ -14,7 +14,7 @@ declare global {
|
|||||||
setProxy: (proxy: string | undefined) => void
|
setProxy: (proxy: string | undefined) => void
|
||||||
saveFile: (path: string, content: string) => void
|
saveFile: (path: string, content: string) => void
|
||||||
setTheme: (theme: 'light' | 'dark') => void
|
setTheme: (theme: 'light' | 'dark') => void
|
||||||
minApp: (url: string) => void
|
minApp: (options: { url: string; windowOptions?: Electron.BrowserWindowConstructorOptions }) => void
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,14 +0,0 @@
|
|||||||
import { contextBridge } from 'electron'
|
|
||||||
|
|
||||||
const api = {}
|
|
||||||
|
|
||||||
if (process.contextIsolated) {
|
|
||||||
try {
|
|
||||||
contextBridge.exposeInMainWorld('api', api)
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// @ts-ignore (define in dts)
|
|
||||||
window.api = api
|
|
||||||
}
|
|
||||||
@ -354,7 +354,7 @@ export const PROVIDER_CONFIG = {
|
|||||||
},
|
},
|
||||||
app: {
|
app: {
|
||||||
name: 'Groq',
|
name: 'Groq',
|
||||||
url: 'https://groq.com/',
|
url: 'https://chat.groq.com/',
|
||||||
logo: GroqProviderLogo
|
logo: GroqProviderLogo
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -12,6 +12,13 @@ const App: FC<Props> = ({ app }) => {
|
|||||||
const { theme } = useTheme()
|
const { theme } = useTheme()
|
||||||
|
|
||||||
const onClick = () => {
|
const onClick = () => {
|
||||||
|
const websiteReg = /claude|chatgpt|groq/i
|
||||||
|
|
||||||
|
if (websiteReg.test(app.url)) {
|
||||||
|
window.api.minApp({ url: app.url, windowOptions: { title: app.name } })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
MinApp.start(app)
|
MinApp.start(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user