first version commit
This commit is contained in:
@@ -0,0 +1,7 @@
|
|||||||
|
.vscode
|
||||||
|
# Dependency directory
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
# Ignore built ts files
|
||||||
|
/bin/
|
||||||
|
dist/**/*
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
# Google Translate Desktop
|
||||||
|
Google Translate网页版的封装,通过[Electron](https://www.electronjs.org)构建。
|
||||||
|
|
||||||
|
首先说一下建立此仓库的目的。平时写代码经常需要查词,尝试了很多翻译软件,它们都很棒,但总是有些细节让人抓狂。或许作为一个翻译软件它们并没有什么问题,但在我个人的使用条件下,它们无法满足我的需求。
|
||||||
|
|
||||||
|
下面是我用过的软件,以及它们为什么不继续使用:
|
||||||
|
* 任何网页版翻译:需要打开浏览器,太慢
|
||||||
|
* 金山词霸:不支持DPI自适应,太丑(现在不知道支不支持)
|
||||||
|
* 有道翻译:关键时刻掉链子,经常需要等待一会才能得到结果。划词窗口偶尔卡半天才出来。最致命的是MINI窗口经常不能自动处于输入状态,得鼠标点一下,大大降低了效率
|
||||||
|
* Micosoft Translator:启动太慢,又不支持mini窗口。不支持开机自启动。如果一直保持打开得忍受任务栏多出一项,这对于某些强迫症患者(我)来说是难以忍受的
|
||||||
|
|
||||||
|
于是我有了使用Electron封装一个网页版翻译的想法,对比之下Google翻译似乎比微软翻译出结果快那么一点点,于是决定封装Google翻译。需要说明的是,我测试的是translate.google.cn,至于google.com没试...I am in China🙃
|
||||||
|
|
||||||
|
封装Google翻译的目的是用于写代码时快速查词,就这一个单纯的目的。因此它的功能可以很简单,但必须具备一些必要的功能,另外使用它可能需要忍受一些事情:
|
||||||
|
* 功能简陋
|
||||||
|
* 必须联网
|
||||||
|
* 自定义程度低,配置得直接修改配置文件
|
||||||
|
* 只能在Windows上用(用到了Windows系统API)
|
||||||
|
* 在Google Translate页面完全加载前Mini窗口不会自动获取焦点,而这可能需要等待好几十秒
|
||||||
|
|
||||||
|
|
||||||
|
## 特性
|
||||||
|
* 支持主窗口最小化到托盘;
|
||||||
|
* 允许配置快捷键打开Mini窗口;
|
||||||
|
* 允许配置默认主窗口尺寸;
|
||||||
|
* Mini窗口自动获取输入焦点;
|
||||||
|
* 支持开机启动;
|
||||||
|
|
||||||
|
* 不支持离线使用;
|
||||||
|
* 不支持取词划词;
|
||||||
|
* 未测试Windows之外的平台;
|
||||||
|
|
||||||
|
对于Mini窗口自动获取输入焦点,由于是通过`dom-ready`事件注入JavaScript实现,因此在`dom-ready`之前Mini窗口无法自动获取焦点。而这需要大概十几秒,因为`translate.google.cn`尝试从`google.com`获取一些资源,而访问google.com会等待超时后失败(国内环境),但这些资源并不是完成翻译功能所必须的,因此并不影响翻译功能的使用。但未完成的非ajax请求会让`dom-ready`事件迟迟不能触发,导致依赖此事件注入JavaScript的代码直到请求超时后才执行。
|
||||||
|
但这只在程序启动时发生,个人认为勉强能够忍受,就没有再折腾。如果有必要,或许可以通过`ServiceWorker`拦截?
|
||||||
|
|
||||||
|
对于封装的url,本程序仅对translate.google.cn做了样式微调,如果换成其它的url,可能需要自行调整样式。配置项中允许更改url参数来加载其他网页。如果需要,还可以通过提供额外CSS来调整样式,它们将被注入页面,见[配置项](##配置项)。
|
||||||
|
注意,你可能需要为你的样式加上!important标记以覆盖更高优先级的原始样式,因为CSS以嵌入式CSS的方式插入。
|
||||||
|
|
||||||
|
|
||||||
|
## 实现
|
||||||
|
通过Electron简单的封装https://translate.google.cn作为主窗口。
|
||||||
|
|
||||||
|
### Mini窗口
|
||||||
|
Mini窗口的大小是固定的,想要修改只能修改代码。为了在更小区域呈现界面,本程序通过注入css隐藏了Mini窗口的Google Translate头部,还做了一些微调以减小其尺寸。
|
||||||
|
|
||||||
|
## 使用
|
||||||
|
克隆本仓库到本地,然后执行`npm install`。
|
||||||
|
|
||||||
|
### 运行
|
||||||
|
`npm start`
|
||||||
|
|
||||||
|
### 打包
|
||||||
|
`npm run package`
|
||||||
|
|
||||||
|
通过`electron-packager`进行打包。当然您也可以使用其它Electron打包工具,例如[electron-builder](https://github.com/electron-userland/electron-builder)。但请劳烦您自行配置。
|
||||||
|
|
||||||
|
|
||||||
|
## 配置项
|
||||||
|
|
||||||
|
配置文件只能是运行目录下的`config.json`。修改配置可能需要重启程序以应用修改。
|
||||||
|
|
||||||
|
| 配置名称 | 类型 | 默认值 | 备注 |
|
||||||
|
| ----------------------- | ------- | --------------------------- |
|
||||||
|
| mainWindowWidth | number | 1024 | 主窗口宽
|
||||||
|
| mainWindowHeight | number | 586 | 主窗口高
|
||||||
|
| url | string | https://translate.google.cn | 加载的url,其它地址没测试过
|
||||||
|
| autoStart | boolean | false | 开机自启动
|
||||||
|
| miniWindowEnabled | boolean | true | 启用Mini窗口快捷键
|
||||||
|
| miniShortcut | string | CmdOrCtrl+Alt+M | 设置Mini窗口快捷键
|
||||||
|
| extraCssForMain | string | "" | 额外插入主窗口的CSS
|
||||||
|
| extraCssForMini | string | "" | 额外插入Mini窗口的的CSS
|
||||||
|
| minimizeToTrayWhenClose | boolean | true | 关闭主窗口时最小化到托盘
|
||||||
|
| minimizeToTrayWenStart | boolean | true | 启动时自动隐藏主窗口
|
||||||
|
|
||||||
|
|
||||||
|
## 使用截图
|
||||||
|
|
||||||
|
<img src="./blob/main.png" alt="主窗口" />
|
||||||
|
|
||||||
|
<img src="./blob/main-input.png" alt="主窗口-有内容" />
|
||||||
|
|
||||||
|
<img src="./blob/mini.png" alt="迷你窗口-有内容" />
|
||||||
|
|
||||||
|
<img src="./blob/mini-input.png" alt="迷你窗口-有内容" />
|
||||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 77 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 9.9 KiB |
Generated
+1408
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"name": "google-translate-electron",
|
||||||
|
"author": "mattuy<mattuylee@outlook.com>",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"main": "./src/index.js",
|
||||||
|
"description": "Google Translate for Windows Desktop, built with Electron",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"start": "electron .",
|
||||||
|
"package": "electron-packager ./ --overwrite --win --out ./bin --icon ./appicon.ico --app-copyright \"copyright@mattuy<mattuylee@outlook.com>\" --win32metadata.CompanyName=\"\""
|
||||||
|
},
|
||||||
|
"productName": "Google Translate Desktop",
|
||||||
|
"originalFilename": "Google Translate Desktop",
|
||||||
|
"dependencies": {
|
||||||
|
"lodash": "^4.17.15"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/lodash": "^4.14.155",
|
||||||
|
"electron": "^5.0.6",
|
||||||
|
"electron-packager": "^14.2.1",
|
||||||
|
"typescript": "^3.5.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,40 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const { promisify } = require('util');
|
||||||
|
const toast = require('./notify');
|
||||||
|
const { debounce } = require('lodash');
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
mainWindowWidth: 1024,
|
||||||
|
mainWindowHeight: 586,
|
||||||
|
url: 'https://translate.google.cn/',
|
||||||
|
autoStart: false,
|
||||||
|
miniWindowEnabled: true,
|
||||||
|
miniShortcut: 'CmdOrCtrl+Alt+M',
|
||||||
|
extraCssForMain: '',
|
||||||
|
extraCssForMini: '',
|
||||||
|
minimizeToTrayWhenClose: true,
|
||||||
|
minimizeToTrayWenStart: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
let userConfig = fs.readFileSync('./config.json');
|
||||||
|
if (userConfig) {
|
||||||
|
Object.assign(config, JSON.parse(userConfig.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
|
||||||
|
async function flushConfig() {
|
||||||
|
const flush = promisify(fs.writeFile.bind(fs));
|
||||||
|
try {
|
||||||
|
await flush('./config.json', JSON.stringify(config, null, 4));
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
toast.show("保存配置失败。", { messageType: 'error' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
config,
|
||||||
|
flushConfig: debounce(flushConfig, 1000, { trailing: true })
|
||||||
|
};
|
||||||
+166
@@ -0,0 +1,166 @@
|
|||||||
|
const path = require('path');
|
||||||
|
const { app, globalShortcut, BrowserWindow, Menu, Tray } = require('electron');
|
||||||
|
const createMiniWindow = require('./mini');
|
||||||
|
const createMainWindow = require('./main');
|
||||||
|
const getMenu = require('./menu');
|
||||||
|
const { config, flushConfig } = require('./config');
|
||||||
|
const toast = require('./notify');
|
||||||
|
|
||||||
|
//将tray保存到全局变量,防止其被自动回收
|
||||||
|
let tray;
|
||||||
|
|
||||||
|
/** @type BrowserWindow */
|
||||||
|
let mainWindow;
|
||||||
|
/** @type BrowserWindow */
|
||||||
|
let miniWindow;
|
||||||
|
|
||||||
|
app.on('ready', () => {
|
||||||
|
setupTray();
|
||||||
|
toggleAutoStart(true);
|
||||||
|
|
||||||
|
mainWindow = createMainWindow();
|
||||||
|
mainWindow.on('close', ev => {
|
||||||
|
if (config.minimizeToTrayWhenClose) {
|
||||||
|
ev.preventDefault();
|
||||||
|
mainWindow.hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mainWindow.on('closed', () => {
|
||||||
|
if (miniWindow) {
|
||||||
|
toast.dismiss();
|
||||||
|
globalShortcut.unregisterAll();
|
||||||
|
miniWindow.destroy();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//主窗口隐藏时设置mini窗口的父窗口为主窗口,防止主窗口意外关闭但mini窗口还保留着导致程序残留在内存中
|
||||||
|
mainWindow.on('hide', () => {
|
||||||
|
if (miniWindow) {
|
||||||
|
miniWindow.setParentWindow(mainWindow);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//主窗口显示时如果mini窗口的父窗口是主窗口,mini窗口获得焦点时父窗口也会弹出来。。emm又没找到其他靠谱的方法
|
||||||
|
mainWindow.on('show', () => {
|
||||||
|
if (miniWindow) {
|
||||||
|
miniWindow.setParentWindow(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!config.minimizeToTrayWenStart) {
|
||||||
|
mainWindow.show();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
toast.show("Google Translate Desktop已在后台运行。", null, {
|
||||||
|
use: 'notification',
|
||||||
|
clickCallback: () => mainWindow.show()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
registerMiniWindow();
|
||||||
|
const mainMenu = getMenu(mainWindow, miniWindow, mainWindow);
|
||||||
|
mainWindow.setMenu(mainMenu);
|
||||||
|
});
|
||||||
|
|
||||||
|
function registerMiniWindow() {
|
||||||
|
// if (!config.miniWindowEnabled) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
miniWindow = createMiniWindow();
|
||||||
|
miniWindow.setParentWindow(mainWindow);
|
||||||
|
const miniMenu = getMenu(mainWindow, miniWindow, miniWindow);
|
||||||
|
miniWindow.setMenu(miniMenu);
|
||||||
|
if (config.miniWindowEnabled) {
|
||||||
|
toggleMiniShortcut(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupTray() {
|
||||||
|
tray = new Tray(path.resolve(__dirname, 'assets/icon.ico'));
|
||||||
|
const contextMenu = Menu.buildFromTemplate([
|
||||||
|
{ label: "显示主界面", click: () => toggleMainWindowVisibility() },
|
||||||
|
{ label: "显示Mini窗口", click: () => toggleMiniWindowVisibility() },
|
||||||
|
{
|
||||||
|
type: 'checkbox',
|
||||||
|
label: "开机启动",
|
||||||
|
checked: config.autoStart,
|
||||||
|
click: menu => menu.checked = toggleAutoStart()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'checkbox',
|
||||||
|
label: "启用MINI窗口快捷键",
|
||||||
|
checked: config.miniWindowEnabled,
|
||||||
|
click: menu => menu.checked = toggleMiniShortcut()
|
||||||
|
},
|
||||||
|
{ label: "退出", click: () => app.exit() }
|
||||||
|
]);
|
||||||
|
tray.setToolTip("Google Translate Desktop");
|
||||||
|
tray.on('click', () => toggleMainWindowVisibility());
|
||||||
|
tray.setContextMenu(contextMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleAutoStart(initial) {
|
||||||
|
if (!initial) {
|
||||||
|
config.autoStart = !config.autoStart;
|
||||||
|
}
|
||||||
|
app.setLoginItemSettings({
|
||||||
|
openAtLogin: config.autoStart,
|
||||||
|
path: process.execPath,
|
||||||
|
openAsHidden: false,
|
||||||
|
args: [
|
||||||
|
'--autoStart'
|
||||||
|
]
|
||||||
|
});
|
||||||
|
if (config.autoStart) {
|
||||||
|
toast.show("已允许Google Translate Desktop在您登录时自动启动。", "提示");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
toast.show("已禁止Google Translate Desktop在您登录时自动启动。", "提示");
|
||||||
|
}
|
||||||
|
if (!initial) {
|
||||||
|
flushConfig();
|
||||||
|
}
|
||||||
|
return config.autoStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
//启用/禁用mini窗口快捷键
|
||||||
|
function toggleMiniShortcut(initial) {
|
||||||
|
let enabled = initial ? config.miniWindowEnabled : !config.miniWindowEnabled;
|
||||||
|
let success = true;
|
||||||
|
if (enabled) {
|
||||||
|
if (!globalShortcut.register(config.miniShortcut, () => toggleMiniWindowVisibility())) {
|
||||||
|
toast.show("快捷键注册失败,请检查设置的快捷键是否被其他软件占用。", "错误", {
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
globalShortcut.unregister(config.miniShortcut);
|
||||||
|
}
|
||||||
|
if (success) {
|
||||||
|
config.miniWindowEnabled = enabled;
|
||||||
|
if (!initial) {
|
||||||
|
flushConfig();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleMiniWindowVisibility() {
|
||||||
|
if (!miniWindow) { return; }
|
||||||
|
if (miniWindow.isVisible()) {
|
||||||
|
miniWindow.hide();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
miniWindow.show();
|
||||||
|
miniWindow.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleMainWindowVisibility() {
|
||||||
|
if (!mainWindow) { return; }
|
||||||
|
if (mainWindow.isVisible()) {
|
||||||
|
mainWindow.hide();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mainWindow.show();
|
||||||
|
mainWindow.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
const path = require('path');
|
||||||
|
const { BrowserWindow } = require('electron');
|
||||||
|
const getMenu = require('./menu');
|
||||||
|
const { config } = require('./config');
|
||||||
|
|
||||||
|
function createMainWindow() {
|
||||||
|
const win = new BrowserWindow({
|
||||||
|
width: config.mainWindowWidth,
|
||||||
|
height: config.mainWindowHeight,
|
||||||
|
icon: path.resolve(__dirname, './assets/icon.ico'),
|
||||||
|
title: 'Google Translate',
|
||||||
|
show: false,
|
||||||
|
webPreferences: {
|
||||||
|
nodeIntegration: false
|
||||||
|
},
|
||||||
|
useContentSize: true,
|
||||||
|
autoHideMenuBar: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
win.loadURL(config.url);
|
||||||
|
win.webContents.on('dom-ready', () => {
|
||||||
|
win.webContents.insertCSS(`
|
||||||
|
/* 隐藏通知 */
|
||||||
|
.notification-area {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
/* 防止高度较小时出现双滚动条 */
|
||||||
|
.frame {
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
if (config.extraCssForMain) {
|
||||||
|
win.webContents.insertCSS(config.extraCssForMain);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return win;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = createMainWindow;
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
const { Menu } = require('electron');
|
||||||
|
|
||||||
|
function getMenu(/** @type Electron.BrowserWindow */mainWindow, miniWindow, current) {
|
||||||
|
const template = [{
|
||||||
|
label: "选项",
|
||||||
|
submenu: Menu.buildFromTemplate([
|
||||||
|
{
|
||||||
|
label: "显示主界面",
|
||||||
|
click: () => {
|
||||||
|
if (!mainWindow) { return; }
|
||||||
|
mainWindow.show();
|
||||||
|
mainWindow.focus();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "显示MINI窗口",
|
||||||
|
click: () => {
|
||||||
|
if (!miniWindow) { return; }
|
||||||
|
miniWindow.show();
|
||||||
|
miniWindow.focus();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "打开调试控制台",
|
||||||
|
click: () => current.webContents.openDevTools()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "退出",
|
||||||
|
role: 'quit'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
}];
|
||||||
|
return Menu.buildFromTemplate(template);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = getMenu;
|
||||||
+110
@@ -0,0 +1,110 @@
|
|||||||
|
const path = require('path');
|
||||||
|
const { BrowserWindow } = require('electron');
|
||||||
|
const getMenu = require('./menu');
|
||||||
|
const { config } = require('./config');
|
||||||
|
|
||||||
|
function createMiniWindow () {
|
||||||
|
let miniWindow = new BrowserWindow({
|
||||||
|
width: 500,
|
||||||
|
height: 315,
|
||||||
|
minWidth: 500,
|
||||||
|
minHeight: 315,
|
||||||
|
maxWidth: 500,
|
||||||
|
maxHeight: 315,
|
||||||
|
icon: path.resolve(__dirname, './assets/icon.ico'),
|
||||||
|
webPreferences: {
|
||||||
|
nodeIntegration: false
|
||||||
|
},
|
||||||
|
title: "Google Translate Mini",
|
||||||
|
autoHideMenuBar: true,
|
||||||
|
show: false,
|
||||||
|
minimizable: false,
|
||||||
|
maximizable: true,
|
||||||
|
alwaysOnTop: true,
|
||||||
|
fullscreenable: false,
|
||||||
|
skipTaskbar: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
miniWindow.on('focus', () => {
|
||||||
|
miniWindow.setOpacity(1);
|
||||||
|
});
|
||||||
|
miniWindow.on('blur', () => {
|
||||||
|
miniWindow.setOpacity(0.618);
|
||||||
|
});
|
||||||
|
miniWindow.on('close', ev => {
|
||||||
|
ev.preventDefault();
|
||||||
|
miniWindow.hide();
|
||||||
|
});
|
||||||
|
|
||||||
|
miniWindow.loadURL(config.url);
|
||||||
|
miniWindow.webContents.on('dom-ready', () => {
|
||||||
|
miniWindow.webContents.executeJavaScript(`
|
||||||
|
setTimeout(() => {
|
||||||
|
console.log('throw');
|
||||||
|
throw('crashed');
|
||||||
|
}, 10000);
|
||||||
|
var source = document.getElementById('source');
|
||||||
|
if (source) {
|
||||||
|
document.addEventListener('visibilitychange', () => {
|
||||||
|
if (document.visibilityState === 'hidden') {
|
||||||
|
source.value = '';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
source.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
miniWindow.webContents.insertCSS(`
|
||||||
|
/* 隐藏通知,文本/文件切换栏 */
|
||||||
|
.container .input-button-container,
|
||||||
|
.notification-area {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
/* mini窗口隐藏header和历史记录按钮和拼音 */
|
||||||
|
.tlid-source-transliteration-container.source-transliteration-container,
|
||||||
|
header.gb_sa.gb_2a.gb_5e.gb_ta, .gp-footer {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
/* 防止高度较小时出现双滚动条 */
|
||||||
|
.frame {
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
|
/* 去除语言选择栏顶部边框 */
|
||||||
|
.tlid-language-bar.ls-wrap {
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
/* 减小输入内容高度 */
|
||||||
|
.tlid-copy-target {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
/* 减小结果内容高度 */
|
||||||
|
.result.tlid-copy-target {
|
||||||
|
height: 72px;
|
||||||
|
min-height: 72px;
|
||||||
|
}
|
||||||
|
/* 缩小语言选择栏高度 */
|
||||||
|
a.ls-select.new-ls-select {
|
||||||
|
line-height: 32px;
|
||||||
|
}
|
||||||
|
.tlid-language-bar.ls-wrap {
|
||||||
|
height: 40px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.swap-wrap {
|
||||||
|
transform: translateY(-8px);
|
||||||
|
}
|
||||||
|
/* 取消结果栏聚焦时的外边框(一般来说不应该这样做) */
|
||||||
|
.result-shield-container.tlid-copy-target {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
if (config.extraCssForMini) {
|
||||||
|
miniWindow.insertCSS(config.extraCssForMini);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return miniWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = createMiniWindow;
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
const path = require('path');
|
||||||
|
const { Notification, dialog } = require('electron');
|
||||||
|
|
||||||
|
let current = null;
|
||||||
|
|
||||||
|
function notify(message, title, ops) {
|
||||||
|
const use = ops ? ops.use : 'auto';
|
||||||
|
if (use === 'dialog' || (!Notification.isSupported() && use !== 'notification')) {
|
||||||
|
let options = { message, title: title || "信息" };
|
||||||
|
if (ops && ops.messageType) {
|
||||||
|
options.type = ops.messageType;
|
||||||
|
}
|
||||||
|
dialog.showMessageBox(null, options);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (current) {
|
||||||
|
current.close();
|
||||||
|
}
|
||||||
|
current = new Notification({
|
||||||
|
title: "Google Translate Desktop",
|
||||||
|
body: message,
|
||||||
|
subtitle: ops && ops.subtitle,
|
||||||
|
icon: path.resolve(__dirname, './assets/icon.ico')
|
||||||
|
});
|
||||||
|
current.show();
|
||||||
|
if (ops && ops.clickCallback) {
|
||||||
|
current.on('click', ops.clickCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function dismiss() {
|
||||||
|
current && current.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
show: notify,
|
||||||
|
dismiss
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user