LOCKING盒子版
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 

228 řádky
6.1 KiB

  1. const {
  2. app,
  3. BrowserWindow,
  4. dialog,
  5. ipcMain,
  6. shell,
  7. Tray,
  8. Menu,
  9. screen,
  10. } = require('electron');
  11. const path = require('path');
  12. const url = require('url');
  13. const { initialStorageEvents, storage } = require('./storage');
  14. const gotTheLock = app.requestSingleInstanceLock();
  15. if (!gotTheLock) {
  16. app.quit();
  17. return;
  18. }
  19. let mainWindow;
  20. const isDev = process.env.NODE_ENV === 'development';
  21. function createWindow() {
  22. //创建窗口
  23. mainWindow = new BrowserWindow({
  24. webPreferences: {
  25. preload: path.join(__dirname, 'preload.js'),
  26. webSecurity: false,
  27. nodeIntegration: true,
  28. },
  29. backgroundColor: '#2e2c29',
  30. darkTheme: true,
  31. title: 'Locking',
  32. width: 720,
  33. height: 600,
  34. frame: false,
  35. minWidth: 720,
  36. minHeight: 600,
  37. });
  38. // 隐藏菜单栏
  39. mainWindow.setMenuBarVisibility(false);
  40. if (process.env.NODE_ENV === 'development') {
  41. // 开发环境
  42. // 加载页面并打开调试工具,根据 NODE_ENV
  43. // umijs 在dev时会给出相应的url,直接加载即可
  44. mainWindow.loadURL('http://localhost:8000/');
  45. mainWindow.webContents.openDevTools();
  46. } else {
  47. //生产环境
  48. // 加载html文件
  49. // 这里的路径是umi输出的html路径,如果没有修改过,路径和下面是一样的
  50. mainWindow.loadFile(path.join(__dirname, './dist/index.html'));
  51. // mainWindow.webContents.openDevTools();
  52. // mainWindow.loadURL(
  53. // url.format({
  54. // pathname: path.join(__dirname, '../dist/index.html'),
  55. // protocol: 'file:',
  56. // slashes: true,
  57. // }),
  58. // );
  59. }
  60. mainWindow.webContents.on('did-finish-load', () => {
  61. // 加载初始localStorage数据
  62. mainWindow.webContents.send('initialStorageData', storage.getAllItem());
  63. });
  64. mainWindow.on('closed', () => {
  65. mainWindow = null;
  66. });
  67. // 创建系统通知区菜单
  68. tray = new Tray(path.join(__dirname, 'logo.ico'));
  69. const contextMenu = Menu.buildFromTemplate([
  70. {
  71. label: '最大化',
  72. click: () => {
  73. mainWindow.maximize();
  74. },
  75. },
  76. {
  77. label: '最小化',
  78. click: () => {
  79. mainWindow.minimize();
  80. },
  81. },
  82. {
  83. label: '还原',
  84. click: () => {
  85. mainWindow.restore();
  86. },
  87. },
  88. {
  89. label: '退出',
  90. click: () => {
  91. mainWindow.destroy();
  92. notifyWindow.destroy();
  93. },
  94. }, //我们需要在这里有一个真正的退出(这里直接强制退出)
  95. ]);
  96. tray.setToolTip('LOCKING盒子');
  97. tray.setContextMenu(contextMenu);
  98. tray.on('click', () => {
  99. if (!mainWindow) {
  100. return;
  101. }
  102. //我们这里模拟桌面程序点击通知区图标实现打开关闭应用的功能
  103. mainWindow.isVisible() ? mainWindow.hide() : mainWindow.show();
  104. mainWindow.isVisible()
  105. ? mainWindow.setSkipTaskbar(false)
  106. : mainWindow.setSkipTaskbar(true);
  107. });
  108. }
  109. // 窗口操作事件
  110. ipcMain.handle('window:close', (event) => {
  111. const iWindow = BrowserWindow.fromId(event.sender.id);
  112. iWindow.hide();
  113. if (iWindow === mainWindow) {
  114. iWindow.setSkipTaskbar(true);
  115. }
  116. event.preventDefault();
  117. // BrowserWindow.fromId(event.sender.id)?.close();
  118. });
  119. ipcMain.handle('window:zoom', (event) => {
  120. const iWindow = BrowserWindow.fromId(event.sender.id);
  121. if (!iWindow) return;
  122. iWindow.isMaximized() ? iWindow.unmaximize() : iWindow.maximize();
  123. });
  124. ipcMain.handle('window:minimize', (event) => {
  125. BrowserWindow.fromId(event.sender.id)?.minimize();
  126. });
  127. ipcMain.handle('window:hide', (event) => {
  128. // console.log(event.sender.id, event.senderFrame, event);
  129. BrowserWindow.fromId(event.sender.id)?.hide();
  130. });
  131. // 选择文件夹
  132. ipcMain.handle('select-folder', async (event, args) => {
  133. const res = await dialog.showOpenDialog({
  134. properties: ['openDirectory'],
  135. });
  136. return res;
  137. });
  138. // 打开浏览器
  139. ipcMain.handle('open-browser', (event, url) => {
  140. shell.openExternal(url);
  141. });
  142. // 打开文件所在位置
  143. ipcMain.handle('open-file-position', (event, message) => {
  144. shell.showItemInFolder(message.absolutePath);
  145. });
  146. // 主窗口给消息窗口notifyWindow发送消息
  147. ipcMain.handle('notify', (event, messageObj) => {
  148. notifyWindow.show();
  149. notifyWindow.webContents.send('on-notify', messageObj);
  150. });
  151. // 消息窗口给主窗口发送重新同步文件的命令
  152. ipcMain.handle('re-sync-file', (event, messageObj) => {
  153. mainWindow.webContents.send('request-resync-file', messageObj);
  154. });
  155. ipcMain.handle('download-file', (event, messageObj) => {
  156. mainWindow.webContents.send('request-download-file', messageObj);
  157. });
  158. // 初始化electron-store相关API
  159. initialStorageEvents(ipcMain);
  160. app.on('ready', () => {
  161. const { width: windowWidth, height: windowHeight } =
  162. screen.getPrimaryDisplay().workAreaSize;
  163. createWindow();
  164. createNotifycationWindow(windowWidth, windowHeight);
  165. app.on('activate', function () {
  166. // On macOS it's common to re-create a window in the app when the
  167. // dock icon is clicked and there are no other windows open.
  168. if (BrowserWindow.getAllWindows().length === 0) createWindow();
  169. });
  170. });
  171. app.on('second-instance', (event, commandLine, workingDirectory) => {
  172. // 当运行第二个实例时,将会聚焦到mainWindow这个窗口
  173. if (mainWindow) {
  174. if (mainWindow.isMinimized()) mainWindow.restore();
  175. mainWindow.focus();
  176. mainWindow.show();
  177. }
  178. });
  179. app.on('window-all-closed', () => {
  180. if (process.platform !== 'darwin') {
  181. app.quit();
  182. }
  183. });
  184. let notifyWindow;
  185. function createNotifycationWindow(windowWidth, windowHeight) {
  186. if (notifyWindow) return notifyWindow;
  187. //创建窗口
  188. notifyWindow = new BrowserWindow({
  189. width: 504,
  190. height: 219, // 184,
  191. x: windowWidth - 480 - 20,
  192. y: windowHeight - 219 + 10,
  193. webPreferences: {
  194. preload: path.join(__dirname, 'preload.js'),
  195. webSecurity: false,
  196. nodeIntegration: true,
  197. },
  198. frame: false,
  199. resizable: false,
  200. transparent: true,
  201. alwaysOnTop: true,
  202. });
  203. // 这里的路径是umi输出的html路径,如果没有修改过,路径和下面是一样的
  204. if (isDev) {
  205. notifyWindow.webContents.openDevTools();
  206. }
  207. notifyWindow.loadFile(path.join(__dirname, 'notifycation.html'));
  208. notifyWindow.setSkipTaskbar(true);
  209. notifyWindow.hide();
  210. // return notifyWindow;
  211. }