mirror of
https://github.com/Kuingsmile/PicList.git
synced 2025-03-13 00:18:13 -04:00
292 lines
9.2 KiB
TypeScript
292 lines
9.2 KiB
TypeScript
import fs from 'fs-extra'
|
||
import {
|
||
app,
|
||
Menu,
|
||
Tray,
|
||
dialog,
|
||
clipboard,
|
||
systemPreferences,
|
||
Notification
|
||
} from 'electron'
|
||
import uploader from 'apis/app/uploader'
|
||
import db, { GalleryDB } from '~/main/apis/core/datastore'
|
||
import windowManager from 'apis/app/window/windowManager'
|
||
import { IWindowList } from '#/types/enum'
|
||
import pasteTemplate from '~/main/utils/pasteTemplate'
|
||
import pkg from 'root/package.json'
|
||
import { ensureFilePath, handleCopyUrl } from '~/main/utils/common'
|
||
import { privacyManager } from '~/main/utils/privacyManager'
|
||
// import { T } from '#/i18n'
|
||
import { T } from '~/main/i18n'
|
||
import { isMacOSVersionGreaterThanOrEqualTo } from '~/main/utils/getMacOSVersion'
|
||
import { buildPicBedListMenu } from '~/main/events/remotes/menu'
|
||
let contextMenu: Menu | null
|
||
let menu: Menu | null
|
||
let tray: Tray | null
|
||
export function createContextMenu () {
|
||
if (process.platform === 'darwin' || process.platform === 'win32') {
|
||
const submenu = buildPicBedListMenu()
|
||
contextMenu = Menu.buildFromTemplate([
|
||
{
|
||
label: T('ABOUT'),
|
||
click () {
|
||
dialog.showMessageBox({
|
||
title: 'PicList',
|
||
message: 'PicList',
|
||
detail: `Version: ${pkg.version}\nAuthor: Kuingsmile\nGithub: https://github.com/Kuingsmile/PicList`
|
||
})
|
||
}
|
||
},
|
||
{
|
||
label: T('OPEN_MAIN_WINDOW'),
|
||
click () {
|
||
const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW)
|
||
settingWindow!.show()
|
||
settingWindow!.focus()
|
||
if (windowManager.has(IWindowList.MINI_WINDOW)) {
|
||
windowManager.get(IWindowList.MINI_WINDOW)!.hide()
|
||
}
|
||
}
|
||
},
|
||
{
|
||
label: T('CHOOSE_DEFAULT_PICBED'),
|
||
type: 'submenu',
|
||
// @ts-ignore
|
||
submenu
|
||
},
|
||
// @ts-ignore
|
||
{
|
||
label: T('OPEN_UPDATE_HELPER'),
|
||
type: 'checkbox',
|
||
checked: db.get('settings.showUpdateTip'),
|
||
click () {
|
||
const value = db.get('settings.showUpdateTip')
|
||
db.set('settings.showUpdateTip', !value)
|
||
}
|
||
},
|
||
{
|
||
label: T('PRIVACY_AGREEMENT'),
|
||
click () {
|
||
privacyManager.show(false)
|
||
}
|
||
},
|
||
{
|
||
label: T('RELOAD_APP'),
|
||
click () {
|
||
app.relaunch()
|
||
app.exit(0)
|
||
}
|
||
},
|
||
// @ts-ignore
|
||
{
|
||
role: 'quit',
|
||
label: T('QUIT')
|
||
}
|
||
])
|
||
} else if (process.platform === 'linux') {
|
||
// TODO 图床选择功能
|
||
// 由于在Linux难以像在Mac和Windows上那样在点击时构造ContextMenu,
|
||
// 暂时取消这个选单,避免引起和设置中启用的图床不一致
|
||
|
||
// TODO 重启应用功能
|
||
// 目前的实现无法正常工作
|
||
|
||
contextMenu = Menu.buildFromTemplate([
|
||
{
|
||
label: T('OPEN_MAIN_WINDOW'),
|
||
click () {
|
||
const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW)
|
||
settingWindow!.show()
|
||
settingWindow!.focus()
|
||
if (windowManager.has(IWindowList.MINI_WINDOW)) {
|
||
windowManager.get(IWindowList.MINI_WINDOW)!.hide()
|
||
}
|
||
}
|
||
},
|
||
// @ts-ignore
|
||
{
|
||
label: T('OPEN_UPDATE_HELPER'),
|
||
type: 'checkbox',
|
||
checked: db.get('settings.showUpdateTip'),
|
||
click () {
|
||
const value = db.get('settings.showUpdateTip')
|
||
db.set('settings.showUpdateTip', !value)
|
||
}
|
||
},
|
||
{
|
||
label: T('ABOUT'),
|
||
click () {
|
||
dialog.showMessageBox({
|
||
title: 'PicList',
|
||
message: 'PicList',
|
||
buttons: ['Ok'],
|
||
detail: `Version: ${pkg.version}\nAuthor: Kuingsmile\nGithub: https://github.com/Kuingsmile/PicList`
|
||
})
|
||
}
|
||
},
|
||
// @ts-ignore
|
||
{
|
||
role: 'quit',
|
||
label: T('QUIT')
|
||
}
|
||
])
|
||
}
|
||
}
|
||
|
||
const getTrayIcon = () => {
|
||
if (process.platform === 'darwin') {
|
||
const isMacOSGreaterThan11 = isMacOSVersionGreaterThanOrEqualTo('11')
|
||
return isMacOSGreaterThan11 ? `${__static}/menubar-newdarwinTemplate.png` : `${__static}/menubar.png`
|
||
} else {
|
||
return `${__static}/menubar-nodarwin.png`
|
||
}
|
||
}
|
||
|
||
export function createTray () {
|
||
const menubarPic = getTrayIcon()
|
||
tray = new Tray(menubarPic)
|
||
// click事件在Mac和Windows上可以触发(在Ubuntu上无法触发,Unity不支持)
|
||
if (process.platform === 'darwin' || process.platform === 'win32') {
|
||
tray.on('right-click', () => {
|
||
if (windowManager.has(IWindowList.TRAY_WINDOW)) {
|
||
windowManager.get(IWindowList.TRAY_WINDOW)!.hide()
|
||
}
|
||
createContextMenu()
|
||
tray!.popUpContextMenu(contextMenu!)
|
||
})
|
||
tray.on('click', (event, bounds) => {
|
||
if (process.platform === 'darwin') {
|
||
toggleWindow(bounds)
|
||
setTimeout(async () => {
|
||
const img = clipboard.readImage()
|
||
const obj: ImgInfo[] = []
|
||
if (!img.isEmpty()) {
|
||
// 从剪贴板来的图片默认转为png
|
||
// https://github.com/electron/electron/issues/9035
|
||
const imgPath = clipboard.read('public.file-url')
|
||
if (imgPath) {
|
||
const decodePath = ensureFilePath(imgPath)
|
||
if (decodePath === imgPath) {
|
||
obj.push({
|
||
imgUrl: imgPath
|
||
})
|
||
} else {
|
||
if (decodePath !== '') {
|
||
// 带有中文的路径,无法直接被img.src所使用,会被转义
|
||
const base64 = await fs.readFile(decodePath.replace('file://', ''), { encoding: 'base64' })
|
||
obj.push({
|
||
imgUrl: `data:image/png;base64,${base64}`
|
||
})
|
||
}
|
||
}
|
||
} else {
|
||
const imgUrl = img.toDataURL()
|
||
// console.log(imgUrl)
|
||
obj.push({
|
||
width: img.getSize().width,
|
||
height: img.getSize().height,
|
||
imgUrl
|
||
})
|
||
}
|
||
}
|
||
windowManager.get(IWindowList.TRAY_WINDOW)!.webContents.send('clipboardFiles', obj)
|
||
}, 0)
|
||
} else {
|
||
if (windowManager.has(IWindowList.TRAY_WINDOW)) {
|
||
windowManager.get(IWindowList.TRAY_WINDOW)!.hide()
|
||
}
|
||
const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW)
|
||
settingWindow!.show()
|
||
settingWindow!.focus()
|
||
if (windowManager.has(IWindowList.MINI_WINDOW)) {
|
||
windowManager.get(IWindowList.MINI_WINDOW)!.hide()
|
||
}
|
||
}
|
||
})
|
||
|
||
tray.on('drag-enter', () => {
|
||
if (systemPreferences.isDarkMode()) {
|
||
tray!.setImage(`${__static}/upload-dark.png`)
|
||
} else {
|
||
tray!.setImage(`${__static}/upload.png`)
|
||
}
|
||
})
|
||
|
||
tray.on('drag-end', () => {
|
||
tray!.setImage(`${__static}/menubar.png`)
|
||
})
|
||
|
||
// drop-files only be supported in macOS
|
||
// so the tray window must be available
|
||
tray.on('drop-files', async (event: Event, files: string[]) => {
|
||
const pasteStyle = db.get('settings.pasteStyle') || 'markdown'
|
||
const trayWindow = windowManager.get(IWindowList.TRAY_WINDOW)!
|
||
const imgs = await uploader
|
||
.setWebContents(trayWindow.webContents)
|
||
.upload(files)
|
||
if (imgs !== false) {
|
||
const pasteText: string[] = []
|
||
for (let i = 0; i < imgs.length; i++) {
|
||
pasteText.push(pasteTemplate(pasteStyle, imgs[i], db.get('settings.customLink')))
|
||
const notification = new Notification({
|
||
title: T('UPLOAD_SUCCEED'),
|
||
body: imgs[i].imgUrl!
|
||
// icon: files[i]
|
||
})
|
||
setTimeout(() => {
|
||
notification.show()
|
||
}, i * 100)
|
||
await GalleryDB.getInstance().insert(imgs[i])
|
||
}
|
||
handleCopyUrl(pasteText.join('\n'))
|
||
trayWindow.webContents.send('dragFiles', imgs)
|
||
}
|
||
})
|
||
// toggleWindow()
|
||
} else if (process.platform === 'linux') {
|
||
// click事件在Ubuntu上无法触发,Unity不支持(在Mac和Windows上可以触发)
|
||
// 需要使用 setContextMenu 设置菜单
|
||
createContextMenu()
|
||
tray!.setContextMenu(contextMenu)
|
||
}
|
||
}
|
||
|
||
export function createMenu () {
|
||
if (process.env.NODE_ENV !== 'development') {
|
||
const template = [{
|
||
label: 'Edit',
|
||
submenu: [
|
||
{ label: 'Undo', accelerator: 'CmdOrCtrl+Z', selector: 'undo:' },
|
||
{ label: 'Redo', accelerator: 'Shift+CmdOrCtrl+Z', selector: 'redo:' },
|
||
{ type: 'separator' },
|
||
{ label: 'Cut', accelerator: 'CmdOrCtrl+X', selector: 'cut:' },
|
||
{ label: 'Copy', accelerator: 'CmdOrCtrl+C', selector: 'copy:' },
|
||
{ label: 'Paste', accelerator: 'CmdOrCtrl+V', selector: 'paste:' },
|
||
{ label: 'Select All', accelerator: 'CmdOrCtrl+A', selector: 'selectAll:' },
|
||
{
|
||
label: 'Quit',
|
||
accelerator: 'CmdOrCtrl+Q',
|
||
click () {
|
||
app.quit()
|
||
}
|
||
}
|
||
]
|
||
}]
|
||
// @ts-ignore
|
||
menu = Menu.buildFromTemplate(template)
|
||
Menu.setApplicationMenu(menu)
|
||
}
|
||
}
|
||
|
||
const toggleWindow = (bounds: IBounds) => {
|
||
const trayWindow = windowManager.get(IWindowList.TRAY_WINDOW)!
|
||
if (trayWindow.isVisible()) {
|
||
trayWindow.hide()
|
||
} else {
|
||
trayWindow.setPosition(bounds.x - 98 + 11, bounds.y, false)
|
||
trayWindow.webContents.send('updateFiles')
|
||
trayWindow.show()
|
||
trayWindow.focus()
|
||
}
|
||
}
|