index.ts 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. import { app, BrowserWindow, Menu, ipcMain, shell } from "electron";
  2. import * as path from "path";
  3. import { Database } from "./database";
  4. import { startServer } from "./redisServer";
  5. import { translate } from "./htmlRenderer";
  6. import { isValid } from "./validateConfig";
  7. //import { Controller } from "./controller"; // this is how we wanna import dude.
  8. let mainWindow: Electron.BrowserWindow;
  9. let tray = null;
  10. let db: Database;
  11. function createWindow() {
  12. const redisServer = startServer(); // spin up redis Server.
  13. db = new Database(); // connect with ne db cli.
  14. // Create the browser window.
  15. mainWindow = new BrowserWindow({
  16. height: 600,
  17. title: "Information Management System",
  18. webPreferences: {
  19. nodeIntegration: true, // with this set we have nodeIntegration in index.html. No need to use require.js anymore.
  20. },
  21. width: 800,
  22. });
  23. //setup tray
  24. /*
  25. tray = new Tray(path.join(__dirname, "../assets/eg.png"))
  26. const contextMenu = Menu.buildFromTemplate([
  27. { label: 'Item1', type: 'radio' },
  28. { label: 'Item2', type: 'radio' },
  29. { label: 'Item3', type: 'radio', checked: true },
  30. { label: 'Item4', type: 'radio' }
  31. ])
  32. tray.setToolTip('Dies ist meine Anwendung.')
  33. tray.setContextMenu(contextMenu)
  34. */
  35. // and load the index.html of the app.
  36. mainWindow.loadFile(path.join(__dirname, "../index.html"));
  37. //let c = new Controller(); //?!?! is this how it should be done?
  38. // Emitted when the window is closed.
  39. mainWindow.on("closed", () => {
  40. // Dereference the window object, usually you would store windows
  41. // in an array if your app supports multi windows, this is the time
  42. // when you should delete the corresponding element.
  43. mainWindow = null;
  44. });
  45. const mainMenu = Menu.buildFromTemplate(mainMenuTemplate); //build the actual menu
  46. Menu.setApplicationMenu(mainMenu); // insert menu
  47. // make links open in os browser by default.
  48. const handleRedirect = (e: any, url: string) => {
  49. if (url != mainWindow.webContents.getURL()) {
  50. try {
  51. e.preventDefault();
  52. shell.openExternal(url);
  53. } catch (e) {
  54. shell.openItem(url);
  55. } finally {
  56. shell.showItemInFolder(url);
  57. }
  58. }
  59. };
  60. mainWindow.webContents.on("will-navigate", handleRedirect);
  61. mainWindow.webContents.on("new-window", handleRedirect);
  62. }
  63. // This method will be called when Electron has finished
  64. // initialization and is ready to create browser windows.
  65. // Some APIs can only be used after this event occurs.
  66. app.on("ready", createWindow);
  67. // Quit when all windows are closed.
  68. app.on("window-all-closed", () => {
  69. // On OS X it is common for applications and their menu bar
  70. // to stay active until the user quits explicitly with Cmd + Q
  71. if (process.platform !== "darwin") {
  72. app.quit();
  73. }
  74. });
  75. app.on("activate", () => {
  76. // On OS X it"s common to re-create a window in the app when the
  77. // dock icon is clicked and there are no other windows open.
  78. if (mainWindow === null) {
  79. createWindow();
  80. }
  81. });
  82. //Menu template
  83. const mainMenuTemplate: any[] = [
  84. // array need to be any so we can add empty object later.
  85. {
  86. label: app.getName(),
  87. submenu: [
  88. {
  89. label: "Quit",
  90. accelerator: "CmdOrCtrl + Q",
  91. click() {
  92. app.quit();
  93. },
  94. },
  95. ],
  96. },
  97. {
  98. label: "Edit",
  99. submenu: [
  100. {
  101. label: "Save",
  102. accelerator: "CmdOrCtrl + S",
  103. click() {
  104. handleSave();
  105. },
  106. },
  107. {
  108. label: "Clear",
  109. accelerator: "CmdOrCtrl + D",
  110. click() {
  111. handleClear();
  112. },
  113. },
  114. { type: "separator" },
  115. { label: "Undo", accelerator: "CmdOrCtrl+Z", selector: "undo:" },
  116. { label: "Redo", accelerator: "Shift+CmdOrCtrl+Z", selector: "redo:" },
  117. { type: "separator" },
  118. { label: "Cut", accelerator: "CmdOrCtrl+X", selector: "cut:" },
  119. { label: "Copy", accelerator: "CmdOrCtrl+C", selector: "copy:" },
  120. { label: "Paste", accelerator: "CmdOrCtrl+V", selector: "paste:" },
  121. { label: "Select All", accelerator: "CmdOrCtrl+A", selector: "selectAll:" },
  122. ],
  123. },
  124. ];
  125. //add developer tools if not in production
  126. if (process.env.NODE_ENV !== "production") {
  127. mainMenuTemplate.push({
  128. label: "Dev Tools",
  129. submenu: [
  130. {
  131. label: "Toggle dev tools",
  132. accelerator: process.platform == "darwin" ? "Command+I" : "Ctrl+I",
  133. click() {
  134. mainWindow.webContents.openDevTools();
  135. },
  136. },
  137. { role: "reload" },
  138. {
  139. label: "Validate config",
  140. click() {
  141. isValid();
  142. },
  143. },
  144. { role: "seperator" },
  145. {
  146. label: "Test Status Item",
  147. click() {
  148. addStatus(undefined, "But here goes text");
  149. },
  150. },
  151. {
  152. label: "Icon Status Item",
  153. click() {
  154. addStatus("assets/icons/png/icon.png", undefined);
  155. },
  156. },
  157. {
  158. label: "Clear all Status",
  159. click() {
  160. clearStatus();
  161. },
  162. },
  163. ],
  164. });
  165. }
  166. /*
  167. // If mac add empty object to resolve Electron menu item issue
  168. if (process.platform == 'darwin') {
  169. mainMenuTemplate.unshift({});
  170. }
  171. */
  172. /**
  173. * Add item to statusBar
  174. * @param iconPath represents the relative path to the icon.
  175. * @param message which shall eb shown left side of the icon. Put undefined if no message shall be shown.
  176. */
  177. function addStatus(iconPath: string, message: string) {
  178. mainWindow.webContents.send("statusItem:add", iconPath, message);
  179. }
  180. /**
  181. * Clears whole statusBar.
  182. */
  183. function clearStatus() {
  184. mainWindow.webContents.send("statusItem:clear");
  185. }
  186. // should execute js code in index.html so it send the value of the editor back to us.
  187. function handleSave() {
  188. mainWindow.webContents.send("editor:get:value");
  189. }
  190. ipcMain.on("editor:save:value", function (e, value) {
  191. clearStatus();
  192. let status: string;
  193. if (db.save(value)) {
  194. status = "Status: OK";
  195. } else {
  196. status = "Status: Failed";
  197. }
  198. addStatus(undefined, status);
  199. });
  200. // catch item:search from editor with the editors value.
  201. ipcMain.on("key:search", async function (e, item: string) {
  202. let res: string[] = [];
  203. if (!item) {
  204. clearStatus();
  205. addStatus(undefined, "Type to search...");
  206. } else {
  207. res = await db.search(item);
  208. for (let i in res) {
  209. res[i] = translate(await db.resolveHash(res[i]));
  210. }
  211. clearStatus();
  212. addStatus(undefined, "Results: " + res.length);
  213. }
  214. e.sender.send("list:update", res);
  215. });
  216. function handleClear() {
  217. mainWindow.webContents.send("editor:clear");
  218. }
  219. ipcMain.on("editor:files:save", async (e, files) => {
  220. console.log(files);
  221. });