diff --git a/src/background.ts b/src/background.ts index 7f8ca3c..907554e 100644 --- a/src/background.ts +++ b/src/background.ts @@ -1,18 +1,6 @@ -'use strict' - import { app, - BrowserWindow, - Tray, - Menu, - Notification, - clipboard, - ipcMain, globalShortcut, - dialog, - systemPreferences, - WebContents, - IpcMainEvent, protocol } from 'electron' import { @@ -20,14 +8,16 @@ import { installVueDevtools } from 'vue-cli-plugin-electron-builder/lib' import db from '#/datastore' -import picgo from '~/main/apis/picgo' -import uploader from '~/main/apis/uploader' +import { IWindowList } from '~/main/apis/window/constants' +import windowManager from '~/main/apis/window/windowManager' +import { + uploadChoosedFiles, + uploadClipboardFiles +} from '~/main/apis/uploader/api' import beforeOpen from '~/main/utils/beforeOpen' -import pasteTemplate from '#/utils/pasteTemplate' import updateChecker from '~/main/utils/updateChecker' -import getPicBeds from '~/main/utils/getPicBeds' -import pkg from 'root/package.json' -import picgoCoreIPC from '~/main/utils/picgoCoreIPC' +import ipcList from '~/main/apis/eventCenter/ipcList' +import busEventList from '~/main/apis/eventCenter/busEventList' import fixPath from 'fix-path' import { getUploadFiles } from '~/main/utils/handleArgv' import bus from '~/main/utils/eventBus' @@ -35,412 +25,21 @@ import { updateShortKeyFromVersion212 } from '~/main/migrate' import shortKeyHandler from '~/main/apis/shortKey/shortKeyHandler' -import logger from '~/main/utils/logger' -import { - UPLOAD_WITH_FILES, - UPLOAD_WITH_FILES_RESPONSE, - UPLOAD_WITH_CLIPBOARD_FILES, - UPLOAD_WITH_CLIPBOARD_FILES_RESPONSE, - GET_WINDOW_ID, - GET_WINDOW_ID_REPONSE, - GET_SETTING_WINDOW_ID, - GET_SETTING_WINDOW_ID_RESPONSE, - CREATE_APP_MENU -} from '~/main/apis/bus/constants' import server from '~/main/server/index' -import { IWindowList } from '~/main/apis/window/constants' -import windowManager from '~/main/apis/window/windowManager' +import { + createTray +} from '~/main/apis/app' const isDevelopment = process.env.NODE_ENV !== 'production' protocol.registerSchemesAsPrivileged([{ scheme: 'picgo', privileges: { secure: true, standard: true } }]) beforeOpen() -let tray: Tray | null -let menu: Menu | null -let contextMenu: Menu | null -const winURL = isDevelopment - ? (process.env.WEBPACK_DEV_SERVER_URL as string) - : `picgo://./index.html` -const settingWinURL = isDevelopment - ? `${(process.env.WEBPACK_DEV_SERVER_URL as string)}#setting/upload` - : `picgo://./index.html#setting/upload` -const miniWinURL = isDevelopment - ? `${(process.env.WEBPACK_DEV_SERVER_URL as string)}#mini-page` - : `picgo://./index.html#mini-page` - // fix the $PATH in macOS fixPath() -function createContextMenu () { - const picBeds = getPicBeds() - const submenu = picBeds.filter(item => item.visible).map(item => { - return { - label: item.name, - type: 'radio', - checked: db.get('picBed.current') === item.type, - click () { - picgo.saveConfig({ - 'picBed.current': item.type - }) - if (windowManager.has(IWindowList.SETTING_WINDOW)) { - windowManager.get(IWindowList.SETTING_WINDOW)!.webContents.send('syncPicBed') - } - } - } - }) - contextMenu = Menu.buildFromTemplate([ - { - label: '关于', - click () { - dialog.showMessageBox({ - title: 'PicGo', - message: 'PicGo', - detail: `Version: ${pkg.version}\nAuthor: Molunerfinn\nGithub: https://github.com/Molunerfinn/PicGo` - }) - } - }, - { - label: '打开详细窗口', - 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: '选择默认图床', - type: 'submenu', - // @ts-ignore - submenu - }, - // @ts-ignore - { - label: '打开更新助手', - type: 'checkbox', - checked: db.get('settings.showUpdateTip'), - click () { - const value = db.get('settings.showUpdateTip') - db.set('settings.showUpdateTip', !value) - } - }, - { - label: '重启应用', - click () { - app.relaunch() - app.exit(0) - } - }, - // @ts-ignore - { - role: 'quit', - label: '退出' - } - ]) -} - -function createTray () { - const menubarPic = process.platform === 'darwin' ? `${__static}/menubar.png` : `${__static}/menubar-nodarwin.png` - tray = new Tray(menubarPic) - 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(() => { - let img = clipboard.readImage() - let obj: ImgInfo[] = [] - if (!img.isEmpty()) { - // 从剪贴板来的图片默认转为png - // @ts-ignore - const imgUrl = 'data:image/png;base64,' + Buffer.from(img.toPNG(), 'binary').toString('base64') - 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`) - }) - - 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) { - for (let i = 0; i < imgs.length; i++) { - clipboard.writeText(pasteTemplate(pasteStyle, imgs[i])) - const notification = new Notification({ - title: '上传成功', - body: imgs[i].imgUrl!, - icon: files[i] - }) - setTimeout(() => { - notification.show() - }, i * 100) - db.insert('uploaded', imgs[i]) - } - trayWindow.webContents.send('dragFiles', imgs) - } - }) - // toggleWindow() -} - -const 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() - } -} - -const uploadClipboardFiles = async (): Promise => { - const win = windowManager.getAvailableWindow() - let img = await uploader.setWebContents(win!.webContents).upload() - if (img !== false) { - if (img.length > 0) { - const trayWindow = windowManager.get(IWindowList.TRAY_WINDOW)! - const pasteStyle = db.get('settings.pasteStyle') || 'markdown' - clipboard.writeText(pasteTemplate(pasteStyle, img[0])) - const notification = new Notification({ - title: '上传成功', - body: img[0].imgUrl!, - icon: img[0].imgUrl - }) - notification.show() - db.insert('uploaded', img[0]) - trayWindow.webContents.send('clipboardFiles', []) - trayWindow.webContents.send('uploadFiles', img) - if (windowManager.has(IWindowList.SETTING_WINDOW)) { - windowManager.get(IWindowList.SETTING_WINDOW)!.webContents.send('updateGallery') - } - return img[0].imgUrl as string - } else { - const notification = new Notification({ - title: '上传不成功', - body: '你剪贴板最新的一条记录不是图片哦' - }) - notification.show() - return '' - } - } else { - return '' - } -} - -const uploadChoosedFiles = async (webContents: WebContents, files: IFileWithPath[]): Promise => { - const input = files.map(item => item.path) - const imgs = await uploader.setWebContents(webContents).upload(input) - const result = [] - if (imgs !== false) { - const pasteStyle = db.get('settings.pasteStyle') || 'markdown' - let pasteText = '' - for (let i = 0; i < imgs.length; i++) { - pasteText += pasteTemplate(pasteStyle, imgs[i]) + '\r\n' - const notification = new Notification({ - title: '上传成功', - body: imgs[i].imgUrl!, - icon: files[i].path - }) - setTimeout(() => { - notification.show() - }, i * 100) - db.insert('uploaded', imgs[i]) - result.push(imgs[i].imgUrl!) - } - clipboard.writeText(pasteText) - windowManager.get(IWindowList.TRAY_WINDOW)!.webContents.send('uploadFiles', imgs) - if (windowManager.has(IWindowList.SETTING_WINDOW)) { - windowManager.get(IWindowList.SETTING_WINDOW)!.webContents.send('updateGallery') - } - return result - } else { - return [] - } -} - -picgoCoreIPC() - -// from macOS tray -ipcMain.on('uploadClipboardFiles', async () => { - const trayWindow = windowManager.get(IWindowList.TRAY_WINDOW)! - const img = await uploader.setWebContents(trayWindow.webContents).upload() - if (img !== false) { - const pasteStyle = db.get('settings.pasteStyle') || 'markdown' - clipboard.writeText(pasteTemplate(pasteStyle, img[0])) - const notification = new Notification({ - title: '上传成功', - body: img[0].imgUrl!, - // icon: file[0] - icon: img[0].imgUrl - }) - notification.show() - db.insert('uploaded', img[0]) - trayWindow.webContents.send('clipboardFiles', []) - if (windowManager.has(IWindowList.SETTING_WINDOW)) { - windowManager.get(IWindowList.SETTING_WINDOW)!.webContents.send('updateGallery') - } - } - trayWindow.webContents.send('uploadFiles') -}) - -ipcMain.on('uploadClipboardFilesFromUploadPage', () => { - uploadClipboardFiles() -}) - -ipcMain.on('uploadChoosedFiles', async (evt: IpcMainEvent, files: IFileWithPath[]) => { - return uploadChoosedFiles(evt.sender, files) -}) - -ipcMain.on('updateShortKey', (evt: IpcMainEvent, item: IShortKeyConfig, oldKey: string, from: string) => { - const result = shortKeyHandler.updateShortKey(item, oldKey, from) - evt.sender.send('updateShortKeyResponse', result) - if (result) { - const notification = new Notification({ - title: '操作成功', - body: '你的快捷键已经修改成功' - }) - notification.show() - } else { - const notification = new Notification({ - title: '操作失败', - body: '快捷键冲突,请重新设置' - }) - notification.show() - } -}) - -ipcMain.on('bindOrUnbindShortKey', (evt: IpcMainEvent, item: IShortKeyConfig, from: string) => { - const result = shortKeyHandler.bindOrUnbindShortKey(item, from) - if (result) { - const notification = new Notification({ - title: '操作成功', - body: '你的快捷键已经修改成功' - }) - notification.show() - } else { - const notification = new Notification({ - title: '操作失败', - body: '快捷键冲突,请重新设置' - }) - notification.show() - } -}) - -ipcMain.on('updateCustomLink', () => { - const notification = new Notification({ - title: '操作成功', - body: '你的自定义链接格式已经修改成功' - }) - notification.show() -}) - -ipcMain.on('autoStart', (evt: IpcMainEvent, val: boolean) => { - app.setLoginItemSettings({ - openAtLogin: val - }) -}) - -ipcMain.on('openSettingWindow', () => { - windowManager.get(IWindowList.SETTING_WINDOW)!.show() - if (windowManager.has(IWindowList.MINI_WINDOW)) { - windowManager.get(IWindowList.MINI_WINDOW)!.hide() - } -}) - -ipcMain.on('openMiniWindow', () => { - const miniWindow = windowManager.get(IWindowList.MINI_WINDOW)! - const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW)! - miniWindow.show() - miniWindow.focus() - settingWindow.hide() -}) - -// from mini window -ipcMain.on('syncPicBed', () => { - if (windowManager.has(IWindowList.SETTING_WINDOW)) { - windowManager.get(IWindowList.SETTING_WINDOW)!.webContents.send('syncPicBed') - } -}) - -ipcMain.on('getPicBeds', (evt: IpcMainEvent) => { - const picBeds = getPicBeds() - evt.sender.send('getPicBeds', picBeds) - evt.returnValue = picBeds -}) - -ipcMain.on('toggleShortKeyModifiedMode', (evt: IpcMainEvent, val: boolean) => { - bus.emit('toggleShortKeyModifiedMode', val) -}) - -ipcMain.on('updateServer', () => { - server.restart() -}) +ipcList.listen() +busEventList.listen() const gotTheLock = app.requestSingleInstanceLock() @@ -493,7 +92,6 @@ app.on('ready', async () => { } db.set('needReload', false) updateChecker() - initEventCenter() // 不需要阻塞 process.nextTick(() => { updateShortKeyFromVersion212(db, db.get('settings.shortKey')) @@ -539,41 +137,6 @@ app.setLoginItemSettings({ openAtLogin: db.get('settings.autoStart') || false }) -function initEventCenter () { - const eventList: any = { - 'picgo:upload': uploadClipboardFiles, - [UPLOAD_WITH_CLIPBOARD_FILES]: busCallUploadClipboardFiles, - [UPLOAD_WITH_FILES]: busCallUploadFiles, - [GET_WINDOW_ID]: busCallGetWindowId, - [GET_SETTING_WINDOW_ID]: busCallGetSettingWindowId, - [CREATE_APP_MENU]: createMenu - } - for (let i in eventList) { - bus.on(i, eventList[i]) - } -} - -async function busCallUploadClipboardFiles () { - const imgUrl = await uploadClipboardFiles() - bus.emit(UPLOAD_WITH_CLIPBOARD_FILES_RESPONSE, imgUrl) -} - -async function busCallUploadFiles (pathList: IFileWithPath[]) { - const win = windowManager.getAvailableWindow() - const urls = await uploadChoosedFiles(win.webContents, pathList) - bus.emit(UPLOAD_WITH_FILES_RESPONSE, urls) -} - -function busCallGetWindowId () { - const win = windowManager.getAvailableWindow() - bus.emit(GET_WINDOW_ID_REPONSE, win.id) -} - -function busCallGetSettingWindowId () { - const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW)! - bus.emit(GET_SETTING_WINDOW_ID_RESPONSE, settingWindow.id) -} - // Exit cleanly on request from parent process in development mode. if (isDevelopment) { if (process.platform === 'win32') { diff --git a/src/main/apis/app/index.ts b/src/main/apis/app/index.ts new file mode 100644 index 0000000..1f5ef63 --- /dev/null +++ b/src/main/apis/app/index.ts @@ -0,0 +1,206 @@ +import { + app, + Menu, + Tray, + dialog, + clipboard, + systemPreferences, + Notification +} from 'electron' +import uploader from '~/main/apis/uploader' +import getPicBeds from '~/main/utils/getPicBeds' +import db from '#/datastore' +import windowManager from '~/main/apis/window/windowManager' +import { IWindowList } from '~/main/apis/window/constants' +import picgo from '~/main/apis/picgo' +import pasteTemplate from '#/utils/pasteTemplate' +import pkg from 'root/package.json' +let contextMenu: Menu | null +let menu: Menu | null +let tray: Tray | null +export function createContextMenu () { + const picBeds = getPicBeds() + const submenu = picBeds.filter(item => item.visible).map(item => { + return { + label: item.name, + type: 'radio', + checked: db.get('picBed.current') === item.type, + click () { + picgo.saveConfig({ + 'picBed.current': item.type + }) + if (windowManager.has(IWindowList.SETTING_WINDOW)) { + windowManager.get(IWindowList.SETTING_WINDOW)!.webContents.send('syncPicBed') + } + } + } + }) + contextMenu = Menu.buildFromTemplate([ + { + label: '关于', + click () { + dialog.showMessageBox({ + title: 'PicGo', + message: 'PicGo', + detail: `Version: ${pkg.version}\nAuthor: Molunerfinn\nGithub: https://github.com/Molunerfinn/PicGo` + }) + } + }, + { + label: '打开详细窗口', + 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: '选择默认图床', + type: 'submenu', + // @ts-ignore + submenu + }, + // @ts-ignore + { + label: '打开更新助手', + type: 'checkbox', + checked: db.get('settings.showUpdateTip'), + click () { + const value = db.get('settings.showUpdateTip') + db.set('settings.showUpdateTip', !value) + } + }, + { + label: '重启应用', + click () { + app.relaunch() + app.exit(0) + } + }, + // @ts-ignore + { + role: 'quit', + label: '退出' + } + ]) +} + +export function createTray () { + const menubarPic = process.platform === 'darwin' ? `${__static}/menubar.png` : `${__static}/menubar-nodarwin.png` + tray = new Tray(menubarPic) + 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(() => { + let img = clipboard.readImage() + let obj: ImgInfo[] = [] + if (!img.isEmpty()) { + // 从剪贴板来的图片默认转为png + // @ts-ignore + const imgUrl = 'data:image/png;base64,' + Buffer.from(img.toPNG(), 'binary').toString('base64') + 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`) + }) + + 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) { + for (let i = 0; i < imgs.length; i++) { + clipboard.writeText(pasteTemplate(pasteStyle, imgs[i])) + const notification = new Notification({ + title: '上传成功', + body: imgs[i].imgUrl!, + icon: files[i] + }) + setTimeout(() => { + notification.show() + }, i * 100) + db.insert('uploaded', imgs[i]) + } + trayWindow.webContents.send('dragFiles', imgs) + } + }) + // toggleWindow() +} + +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() + } +} diff --git a/src/main/apis/eventCenter/busEventList.ts b/src/main/apis/eventCenter/busEventList.ts new file mode 100644 index 0000000..f5c69d3 --- /dev/null +++ b/src/main/apis/eventCenter/busEventList.ts @@ -0,0 +1,61 @@ +import bus from '~/main/utils/eventBus' +import { + uploadClipboardFiles, + uploadChoosedFiles +} from '~/main/apis/uploader/api' +import { + createMenu +} from '~/main/apis/app' +import { IWindowList } from '~/main/apis/window/constants' +import windowManager from '~/main/apis/window/windowManager' +import { + UPLOAD_WITH_FILES, + UPLOAD_WITH_FILES_RESPONSE, + UPLOAD_WITH_CLIPBOARD_FILES, + UPLOAD_WITH_CLIPBOARD_FILES_RESPONSE, + GET_WINDOW_ID, + GET_WINDOW_ID_REPONSE, + GET_SETTING_WINDOW_ID, + GET_SETTING_WINDOW_ID_RESPONSE, + CREATE_APP_MENU +} from '~/main/apis/bus/constants' +function initEventCenter () { + const eventList: any = { + 'picgo:upload': uploadClipboardFiles, + [UPLOAD_WITH_CLIPBOARD_FILES]: busCallUploadClipboardFiles, + [UPLOAD_WITH_FILES]: busCallUploadFiles, + [GET_WINDOW_ID]: busCallGetWindowId, + [GET_SETTING_WINDOW_ID]: busCallGetSettingWindowId, + [CREATE_APP_MENU]: createMenu + } + for (let i in eventList) { + bus.on(i, eventList[i]) + } +} + +async function busCallUploadClipboardFiles () { + const imgUrl = await uploadClipboardFiles() + bus.emit(UPLOAD_WITH_CLIPBOARD_FILES_RESPONSE, imgUrl) +} + +async function busCallUploadFiles (pathList: IFileWithPath[]) { + const win = windowManager.getAvailableWindow() + const urls = await uploadChoosedFiles(win.webContents, pathList) + bus.emit(UPLOAD_WITH_FILES_RESPONSE, urls) +} + +function busCallGetWindowId () { + const win = windowManager.getAvailableWindow() + bus.emit(GET_WINDOW_ID_REPONSE, win.id) +} + +function busCallGetSettingWindowId () { + const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW)! + bus.emit(GET_SETTING_WINDOW_ID_RESPONSE, settingWindow.id) +} + +export default { + listen () { + initEventCenter() + } +} diff --git a/src/main/apis/eventCenter/ipcList.ts b/src/main/apis/eventCenter/ipcList.ts new file mode 100644 index 0000000..6e41545 --- /dev/null +++ b/src/main/apis/eventCenter/ipcList.ts @@ -0,0 +1,143 @@ +import { + app, + ipcMain, + clipboard, + Notification, + IpcMainEvent +} from 'electron' +import windowManager from '~/main/apis/window/windowManager' +import { IWindowList } from '~/main/apis/window/constants' +import uploader from '~/main/apis/uploader' +import pasteTemplate from '#/utils/pasteTemplate' +import db from '#/datastore' +import server from '~/main/server' +import getPicBeds from '~/main/utils/getPicBeds' +import shortKeyHandler from '~/main/apis/shortKey/shortKeyHandler' +import bus from '~/main/utils/eventBus' +import { + uploadClipboardFiles, + uploadChoosedFiles +} from '~/main/apis/uploader/api' +import picgoCoreIPC from './picgoCoreIPC' + +export default { + listen () { + picgoCoreIPC.listen() + // from macOS tray + ipcMain.on('uploadClipboardFiles', async () => { + const trayWindow = windowManager.get(IWindowList.TRAY_WINDOW)! + const img = await uploader.setWebContents(trayWindow.webContents).upload() + if (img !== false) { + const pasteStyle = db.get('settings.pasteStyle') || 'markdown' + clipboard.writeText(pasteTemplate(pasteStyle, img[0])) + const notification = new Notification({ + title: '上传成功', + body: img[0].imgUrl!, + // icon: file[0] + icon: img[0].imgUrl + }) + notification.show() + db.insert('uploaded', img[0]) + trayWindow.webContents.send('clipboardFiles', []) + if (windowManager.has(IWindowList.SETTING_WINDOW)) { + windowManager.get(IWindowList.SETTING_WINDOW)!.webContents.send('updateGallery') + } + } + trayWindow.webContents.send('uploadFiles') + }) + + ipcMain.on('uploadClipboardFilesFromUploadPage', () => { + uploadClipboardFiles() + }) + + ipcMain.on('uploadChoosedFiles', async (evt: IpcMainEvent, files: IFileWithPath[]) => { + return uploadChoosedFiles(evt.sender, files) + }) + + ipcMain.on('updateShortKey', (evt: IpcMainEvent, item: IShortKeyConfig, oldKey: string, from: string) => { + const result = shortKeyHandler.updateShortKey(item, oldKey, from) + evt.sender.send('updateShortKeyResponse', result) + if (result) { + const notification = new Notification({ + title: '操作成功', + body: '你的快捷键已经修改成功' + }) + notification.show() + } else { + const notification = new Notification({ + title: '操作失败', + body: '快捷键冲突,请重新设置' + }) + notification.show() + } + }) + + ipcMain.on('bindOrUnbindShortKey', (evt: IpcMainEvent, item: IShortKeyConfig, from: string) => { + const result = shortKeyHandler.bindOrUnbindShortKey(item, from) + if (result) { + const notification = new Notification({ + title: '操作成功', + body: '你的快捷键已经修改成功' + }) + notification.show() + } else { + const notification = new Notification({ + title: '操作失败', + body: '快捷键冲突,请重新设置' + }) + notification.show() + } + }) + + ipcMain.on('updateCustomLink', () => { + const notification = new Notification({ + title: '操作成功', + body: '你的自定义链接格式已经修改成功' + }) + notification.show() + }) + + ipcMain.on('autoStart', (evt: IpcMainEvent, val: boolean) => { + app.setLoginItemSettings({ + openAtLogin: val + }) + }) + + ipcMain.on('openSettingWindow', () => { + windowManager.get(IWindowList.SETTING_WINDOW)!.show() + if (windowManager.has(IWindowList.MINI_WINDOW)) { + windowManager.get(IWindowList.MINI_WINDOW)!.hide() + } + }) + + ipcMain.on('openMiniWindow', () => { + const miniWindow = windowManager.get(IWindowList.MINI_WINDOW)! + const settingWindow = windowManager.get(IWindowList.SETTING_WINDOW)! + miniWindow.show() + miniWindow.focus() + settingWindow.hide() + }) + + // from mini window + ipcMain.on('syncPicBed', () => { + if (windowManager.has(IWindowList.SETTING_WINDOW)) { + windowManager.get(IWindowList.SETTING_WINDOW)!.webContents.send('syncPicBed') + } + }) + + ipcMain.on('getPicBeds', (evt: IpcMainEvent) => { + const picBeds = getPicBeds() + evt.sender.send('getPicBeds', picBeds) + evt.returnValue = picBeds + }) + + ipcMain.on('toggleShortKeyModifiedMode', (evt: IpcMainEvent, val: boolean) => { + bus.emit('toggleShortKeyModifiedMode', val) + }) + + ipcMain.on('updateServer', () => { + server.restart() + }) + }, + dispose () {} +} diff --git a/src/main/utils/picgoCoreIPC.ts b/src/main/apis/eventCenter/picgoCoreIPC.ts similarity index 95% rename from src/main/utils/picgoCoreIPC.ts rename to src/main/apis/eventCenter/picgoCoreIPC.ts index 5029ace..b7834c4 100644 --- a/src/main/utils/picgoCoreIPC.ts +++ b/src/main/apis/eventCenter/picgoCoreIPC.ts @@ -1,17 +1,15 @@ import path from 'path' -import GuiApi from '../apis/gui' +import GuiApi from '../gui' import { dialog, shell, - IpcMain, IpcMainEvent, - App, ipcMain, app } from 'electron' import PicGoCore from '~/universal/types/picgo' import { IPicGoHelperType } from '#/types/enum' -import shortKeyHandler from '../apis/shortKey/shortKeyHandler' +import shortKeyHandler from '../shortKey/shortKeyHandler' import picgo from '~/main/apis/picgo' // eslint-disable-next-line @@ -213,13 +211,15 @@ const handlePicGoSaveData = () => { }) } -export default () => { - handleGetPluginList() - handlePluginInstall() - handlePluginUninstall() - handlePluginUpdate() - handleGetPicBedConfig() - handlePluginActions() - handleRemoveFiles() - handlePicGoSaveData() +export default { + listen () { + handleGetPluginList() + handlePluginInstall() + handlePluginUninstall() + handlePluginUpdate() + handleGetPicBedConfig() + handlePluginActions() + handleRemoveFiles() + handlePicGoSaveData() + } } diff --git a/src/main/apis/gui/index.ts b/src/main/apis/gui/index.ts index 92eb9dc..2179b0d 100644 --- a/src/main/apis/gui/index.ts +++ b/src/main/apis/gui/index.ts @@ -3,9 +3,7 @@ import { BrowserWindow, clipboard, Notification, - WebContents, - ipcMain, - webContents + ipcMain } from 'electron' import db from '#/datastore' import uploader from '../uploader' diff --git a/src/main/apis/uploader/api.ts b/src/main/apis/uploader/api.ts new file mode 100644 index 0000000..c570f54 --- /dev/null +++ b/src/main/apis/uploader/api.ts @@ -0,0 +1,74 @@ +import { + clipboard, + Notification, + WebContents +} from 'electron' +import windowManager from '~/main/apis/window/windowManager' +import { IWindowList } from '~/main/apis/window/constants' +import uploader from './' +import pasteTemplate from '#/utils/pasteTemplate' +import db from '#/datastore' +export const uploadClipboardFiles = async (): Promise => { + const win = windowManager.getAvailableWindow() + let img = await uploader.setWebContents(win!.webContents).upload() + if (img !== false) { + if (img.length > 0) { + const trayWindow = windowManager.get(IWindowList.TRAY_WINDOW)! + const pasteStyle = db.get('settings.pasteStyle') || 'markdown' + clipboard.writeText(pasteTemplate(pasteStyle, img[0])) + const notification = new Notification({ + title: '上传成功', + body: img[0].imgUrl!, + icon: img[0].imgUrl + }) + notification.show() + db.insert('uploaded', img[0]) + trayWindow.webContents.send('clipboardFiles', []) + trayWindow.webContents.send('uploadFiles', img) + if (windowManager.has(IWindowList.SETTING_WINDOW)) { + windowManager.get(IWindowList.SETTING_WINDOW)!.webContents.send('updateGallery') + } + return img[0].imgUrl as string + } else { + const notification = new Notification({ + title: '上传不成功', + body: '你剪贴板最新的一条记录不是图片哦' + }) + notification.show() + return '' + } + } else { + return '' + } +} + +export const uploadChoosedFiles = async (webContents: WebContents, files: IFileWithPath[]): Promise => { + const input = files.map(item => item.path) + const imgs = await uploader.setWebContents(webContents).upload(input) + const result = [] + if (imgs !== false) { + const pasteStyle = db.get('settings.pasteStyle') || 'markdown' + let pasteText = '' + for (let i = 0; i < imgs.length; i++) { + pasteText += pasteTemplate(pasteStyle, imgs[i]) + '\r\n' + const notification = new Notification({ + title: '上传成功', + body: imgs[i].imgUrl!, + icon: files[i].path + }) + setTimeout(() => { + notification.show() + }, i * 100) + db.insert('uploaded', imgs[i]) + result.push(imgs[i].imgUrl!) + } + clipboard.writeText(pasteText) + windowManager.get(IWindowList.TRAY_WINDOW)!.webContents.send('uploadFiles', imgs) + if (windowManager.has(IWindowList.SETTING_WINDOW)) { + windowManager.get(IWindowList.SETTING_WINDOW)!.webContents.send('updateGallery') + } + return result + } else { + return [] + } +} diff --git a/src/main/utils/ipcList.ts b/src/universal/events/constants.ts similarity index 100% rename from src/main/utils/ipcList.ts rename to src/universal/events/constants.ts