LOCKING盒子版
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

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