feat(desktop): add desktop inject

pull/100/head
moonrailgun 2 years ago
parent eb83f784a1
commit 27eee90034

@ -0,0 +1,36 @@
import { app } from 'electron';
/**
* Webviewjs
*/
export function generateInstallPluginScript() {
/**
* manifest copy from:
* com.msgbyte.env.rn/manifest.json
*/
const inner = `function main() {
window.tailchat
.installPlugin({
label: 'Electron Support',
'label.zh-CN': 'Electron 支持',
name: 'com.msgbyte.env.electron',
url: '/plugins/com.msgbyte.env.electron/index.js',
version: '0.0.0',
author: 'moonrailgun',
description: 'Add support for Electron environment in Tailchat',
'description.zh-CN': '在 Tailchat 添加对 Electron 环境的支持',
requireRestart: true,
});
}`;
const raw = `(${inner})()`;
return raw;
}
export function generateInjectedScript(): string {
return [generateDeviceInfo()].join(';');
}
function generateDeviceInfo() {
return `window.__electronDeviceInfo = { version: "${app.getVersion()}", name: "${app.getName()}" }`;
}

@ -0,0 +1,15 @@
import { generateInstallPluginScript } from '.';
import log from 'electron-log';
export function handleTailchatMessage(
type: string,
payload: any,
webview: Electron.WebContents
) {
log.info('onMessage receive:', type, payload);
if (type === 'init') {
webview.executeJavaScript(generateInstallPluginScript());
return;
}
}

@ -17,6 +17,8 @@ import { getMainWindowUrl } from './util';
import windowStateKeeper from 'electron-window-state';
import is from 'electron-is';
import { initScreenshots } from './screenshots';
import { generateInjectedScript } from './inject';
import { handleTailchatMessage } from './inject/message-handler';
log.info('Start...');
@ -103,6 +105,7 @@ const createWindow = async () => {
width: mainWindowState.width,
icon: getAssetPath('icon.png'),
webPreferences: {
nodeIntegration: false,
preload: app.isPackaged
? path.join(__dirname, 'preload.js')
: path.join(__dirname, '../../.erb/dll/preload.js'),
@ -142,6 +145,21 @@ const createWindow = async () => {
});
}
mainWindow.webContents.on('did-start-navigation', () => {
if (mainWindow) {
mainWindow.webContents.executeJavaScript(generateInjectedScript());
}
});
mainWindow.webContents.on('ipc-message', (e, channel, data) => {
if (channel === 'webview-message') {
const obj = JSON.parse(data);
if (typeof obj === 'object' && obj._isTailchat === true && mainWindow) {
handleTailchatMessage(obj.type, obj.payload, mainWindow.webContents);
}
}
});
mainWindow.on('ready-to-show', () => {
if (!mainWindow) {
throw new Error('"mainWindow" is not defined');
@ -167,6 +185,8 @@ const createWindow = async () => {
return { action: 'deny' };
});
mainWindowState.manage(mainWindow);
// Remove this if your app does not use auto updates
new AppUpdater();
} catch (err) {

@ -1,11 +1,16 @@
import { contextBridge, ipcRenderer, IpcRendererEvent } from 'electron';
import {
contextBridge,
ipcRenderer,
IpcRendererEvent,
webFrame,
} from 'electron';
export type Channels = 'ipc-example';
export type Channels = 'ipc-example' | 'webview-message';
contextBridge.exposeInMainWorld('electron', {
ipcRenderer: {
sendMessage(channel: Channels, args: unknown[]) {
ipcRenderer.send(channel, args);
sendMessage(channel: Channels, ...args: unknown[]) {
ipcRenderer.send(channel, ...args);
},
on(channel: Channels, func: (...args: unknown[]) => void) {
const subscription = (_event: IpcRendererEvent, ...args: unknown[]) =>
@ -19,3 +24,9 @@ contextBridge.exposeInMainWorld('electron', {
},
},
});
const postMessageOverride = `window.postMessage = function (data) {
window.electron.ipcRenderer.sendMessage('webview-message', JSON.stringify(data));
};`;
webFrame.executeJavaScript(postMessageOverride);

@ -2,6 +2,7 @@ import React from 'react';
import { Translate } from './translate';
interface WindowElectronDeviceInfo {
name: string;
version: string;
}
@ -10,6 +11,9 @@ export const DeviceInfoPanel: React.FC = React.memo(() => {
(window as any).__electronDeviceInfo ?? {};
return (
<div>
<div>
{Translate.clientName}: {deviceInfo.name}
</div>
<div>
{Translate.clientVersion}: {deviceInfo.version}
</div>

@ -5,6 +5,10 @@ export const Translate = {
'zh-CN': '设备信息',
'en-US': 'Device Info',
}),
clientName: localTrans({
'zh-CN': '客户端名称',
'en-US': 'Client Name',
}),
clientVersion: localTrans({
'zh-CN': '客户端版本号',
'en-US': 'Client Version',

Loading…
Cancel
Save