diff --git a/package-lock.json b/package-lock.json index 9ca9880..f4c5db3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@electron/remote": "^2.0.8", "csv-parse": "^5.2.0", "electron-log": "^4.4.7", + "electron-notification-state": "^1.0.4", "electron-squirrel-startup": "^1.0.0", "electron-updater": "^5.0.1", "is-valid-path": "^0.1.1", @@ -3668,6 +3669,14 @@ "node": ">=8" } }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -5040,6 +5049,17 @@ "resolved": "https://registry.npmjs.org/electron-log/-/electron-log-4.4.7.tgz", "integrity": "sha512-uFZQdgevOp9Fn5lDOrJMU/bmmYxDLZitbIHJM7VXN+cpB59ZnPt1FQL4bOf/Dl2gaIMPYJEfXx38GvJma5iV6A==" }, + "node_modules/electron-notification-state": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/electron-notification-state/-/electron-notification-state-1.0.4.tgz", + "integrity": "sha512-MUTLCx+u8yha0cH//B1H0p1itT1RHVZvwV71s3HP9l0Kxbhwq/WQMtikmgwptFBqF0xJ6QyzmKXO3W/n+kboqQ==", + "deprecated": "this package has been deprecated", + "dependencies": { + "macos-notification-state": "^1.1.0", + "windows-notification-state": "^1.3.0", + "windows-quiet-hours": "^1.2.2" + } + }, "node_modules/electron-osx-sign": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.6.0.tgz", @@ -6109,6 +6129,11 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, "node_modules/filelist": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", @@ -7766,6 +7791,15 @@ "node": ">=10" } }, + "node_modules/macos-notification-state": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/macos-notification-state/-/macos-notification-state-1.3.6.tgz", + "integrity": "sha512-/iL0Mepra7laWWxCWvXWQea+D8j7o73iazcgap5gYd/Lbx29JY0nfH3dYVNzWQT/AKvoB0I55fdTY/fd5JiTPg==", + "hasInstallScript": true, + "dependencies": { + "bindings": "^1.5.0" + } + }, "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -7986,6 +8020,11 @@ "multicast-dns": "cli.js" } }, + "node_modules/nan": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz", + "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==" + }, "node_modules/nanoid": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", @@ -10913,6 +10952,26 @@ "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", "dev": true }, + "node_modules/windows-notification-state": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/windows-notification-state/-/windows-notification-state-1.3.4.tgz", + "integrity": "sha512-Z2n6YLARi14AGqaY5zAlMnhButzjRjlQui0k73nXe4tVRg2U918zLeC3ZxM/i4JKho/GqV85rgQsMfLWnbTUCA==", + "hasInstallScript": true, + "dependencies": { + "bindings": "^1.5.0", + "nan": "^2.14.0" + } + }, + "node_modules/windows-quiet-hours": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/windows-quiet-hours/-/windows-quiet-hours-1.2.7.tgz", + "integrity": "sha512-PjKM2/RQhZ3ikG4COq0vPpXvmJsxckcg2YN3xmQv8kZl5l1uu00a/epSGDeY6tczDPkzBhoThBz1FKRqxBA7cQ==", + "hasInstallScript": true, + "dependencies": { + "bindings": "^1.3.0", + "nan": "^2.7.0" + } + }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -13757,6 +13816,14 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -14784,6 +14851,16 @@ "resolved": "https://registry.npmjs.org/electron-log/-/electron-log-4.4.7.tgz", "integrity": "sha512-uFZQdgevOp9Fn5lDOrJMU/bmmYxDLZitbIHJM7VXN+cpB59ZnPt1FQL4bOf/Dl2gaIMPYJEfXx38GvJma5iV6A==" }, + "electron-notification-state": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/electron-notification-state/-/electron-notification-state-1.0.4.tgz", + "integrity": "sha512-MUTLCx+u8yha0cH//B1H0p1itT1RHVZvwV71s3HP9l0Kxbhwq/WQMtikmgwptFBqF0xJ6QyzmKXO3W/n+kboqQ==", + "requires": { + "macos-notification-state": "^1.1.0", + "windows-notification-state": "^1.3.0", + "windows-quiet-hours": "^1.2.2" + } + }, "electron-osx-sign": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.6.0.tgz", @@ -15638,6 +15715,11 @@ "flat-cache": "^3.0.4" } }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, "filelist": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", @@ -16845,6 +16927,14 @@ "yallist": "^4.0.0" } }, + "macos-notification-state": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/macos-notification-state/-/macos-notification-state-1.3.6.tgz", + "integrity": "sha512-/iL0Mepra7laWWxCWvXWQea+D8j7o73iazcgap5gYd/Lbx29JY0nfH3dYVNzWQT/AKvoB0I55fdTY/fd5JiTPg==", + "requires": { + "bindings": "^1.5.0" + } + }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -17009,6 +17099,11 @@ "thunky": "^1.0.2" } }, + "nan": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz", + "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==" + }, "nanoid": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", @@ -19164,6 +19259,24 @@ "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", "dev": true }, + "windows-notification-state": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/windows-notification-state/-/windows-notification-state-1.3.4.tgz", + "integrity": "sha512-Z2n6YLARi14AGqaY5zAlMnhButzjRjlQui0k73nXe4tVRg2U918zLeC3ZxM/i4JKho/GqV85rgQsMfLWnbTUCA==", + "requires": { + "bindings": "^1.5.0", + "nan": "^2.14.0" + } + }, + "windows-quiet-hours": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/windows-quiet-hours/-/windows-quiet-hours-1.2.7.tgz", + "integrity": "sha512-PjKM2/RQhZ3ikG4COq0vPpXvmJsxckcg2YN3xmQv8kZl5l1uu00a/epSGDeY6tczDPkzBhoThBz1FKRqxBA7cQ==", + "requires": { + "bindings": "^1.3.0", + "nan": "^2.7.0" + } + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", diff --git a/package.json b/package.json index bea24cd..eac995e 100644 --- a/package.json +++ b/package.json @@ -104,6 +104,7 @@ "@electron/remote": "^2.0.8", "csv-parse": "^5.2.0", "electron-log": "^4.4.7", + "electron-notification-state": "^1.0.4", "electron-squirrel-startup": "^1.0.0", "electron-updater": "^5.0.1", "is-valid-path": "^0.1.1", diff --git a/src/components/blenderController.ts b/src/components/blenderController.ts index faa891a..1bc68c1 100644 --- a/src/components/blenderController.ts +++ b/src/components/blenderController.ts @@ -6,8 +6,15 @@ import { setLogNumber, setPastTime, setRemainingTime, setRenderDisplayProgress, import {imageLoading, imageLoaded} from "./ui/settingsSide"; import { getLogList, getLogSize, settingList } from "./settings"; import isValid from "is-valid-path"; -import { sideSetRendering, setProgress } from "../renderer"; +import { sideSetRendering, setProgress, openSide, Side } from "../renderer"; import { ipcRenderer } from "electron"; +// import { getDoNotDisturb } from "electron-notification-state"; + +export const renderInfo = { + time: "0min 0sec", + startTime: 0, + endTime: 0 +} const blenderStartString = [ templatePath, @@ -26,8 +33,6 @@ let renderingPicture = false; let renderingVideo = false; let waitingForRender = false; -let renderStartTime = new Date().getTime(); - let logPortionList:number[] = []; let currentLogPortion = 0; @@ -43,14 +48,15 @@ function setRenderProgress(log:number, init:boolean, frameCount:number, frame:nu setRenderDisplayProgress(parseFloat((progress*100).toFixed(2))); const timeNow = new Date().getTime(); - const timeDiff = timeNow - renderStartTime; + const timeDiff = timeNow - renderInfo.startTime; let timeDiffSeconds = timeDiff / 1000; let timeDiffMinutes = 0; while(timeDiffSeconds > 60) { timeDiffMinutes++; timeDiffSeconds -= 60; } - setPastTimeNow(timeDiffMinutes + "m " + timeDiffSeconds.toFixed(0) + "s"); + renderInfo.time = timeDiffMinutes + "m " + timeDiffSeconds.toFixed(0) + "s"; + setPastTimeNow(renderInfo.time); if(progress > 0) { const timeRemaining = (timeDiff / progress) * (1 - progress); @@ -108,8 +114,15 @@ function startBlender() { } if(dataStr.includes("Finished") && renderingVideo) { sideSetRendering(false); + renderInfo.endTime = new Date().getTime(); if(lastFrame == frames) { - setStatus("Finished Render Successfully!"); + openSide(Side.RenderFinish); + // TODO: only show notification if not in do not disturb mode, currently not working. Details: https://github.com/felixrieseberg/macos-notification-state/issues/30 + new Notification("Render Finished", { + body: "Rendering finished successfully!" + }).onclick = function() { + ipcRenderer.send("openApp"); + } } else { logger.errorMSG("Render Failed!"); } @@ -212,7 +225,7 @@ function blender(command:blenderCmd) { setBlenderLoading(true); blenderConsole.stdin.write("startRendering\n"); - renderStartTime = new Date().getTime(); + renderInfo.startTime = new Date().getTime(); setPastTime("0min 0sec"); setRemainingTime("calculating..."); } diff --git a/src/components/ui/menu.tsx b/src/components/ui/menu.tsx index 9126ea2..ed05d5e 100644 --- a/src/components/ui/menu.tsx +++ b/src/components/ui/menu.tsx @@ -72,6 +72,7 @@ function WindowsMenu({side, blenderLoading, blenderStatus}:{side:Side, blenderLo {(side == Side.Main)? "StickExporterTX" : null} {(side == Side.Settings)? "Settings" : null} {(side == Side.Rendering)? "Rendering" : null} + {(side == Side.RenderFinish)? "Render Finished" : null}
@@ -89,7 +90,12 @@ function WindowsMenu({side, blenderLoading, blenderStatus}:{side:Side, blenderLo function LinuxMenu({side, blenderLoading, blenderStatus}:{side:Side, blenderLoading:boolean, blenderStatus:string}) { return (
-

{(side == Side.Main)? "StickExporterTX" : "Settings"}

+

+ {(side == Side.Main)? "StickExporterTX" : null} + {(side == Side.Settings)? "Settings" : null} + {(side == Side.Rendering)? "Rendering" : null} + {(side == Side.RenderFinish)? "Render Finished" : null} +

{blenderLoading? : } diff --git a/src/components/ui/renderFinishSide.tsx b/src/components/ui/renderFinishSide.tsx new file mode 100644 index 0000000..24d69ee --- /dev/null +++ b/src/components/ui/renderFinishSide.tsx @@ -0,0 +1,46 @@ +import React, { CSSProperties } from "react"; +import {openSide, Side} from "../../renderer"; +import {renderInfo} from "../blenderController"; +import openFolder from "../openFolder"; +import {settingList} from "../settings"; + +const detailsStyle:CSSProperties = { + display: "flex", + marginBottom: "10px", +} +const detailsInnerStyle:CSSProperties = { + margin: "0px", + marginRight: "5px", +} + +function RenderFinishSide() { + return ( +
+

Render finished Successfully!

+
+

Duration:

+

{renderInfo.time}

+
+
+

Start Time:

+

{new Date(renderInfo.startTime).toLocaleString().replace(",", "")}

+
+
+

End Time:

+

{new Date(renderInfo.endTime).toLocaleString().replace(",", "")}

+
+ + +
+ ); +} + +export default RenderFinishSide; \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index c87f747..d7dd003 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,6 +4,7 @@ import path from 'path'; import { autoUpdater } from "electron-updater"; import logger from 'electron-log'; import { Platform, platform } from './components/platform'; + logger.transports.console.format = "{h}:{i}:{s} {text}"; logger.transports.file.getFile(); logger.transports.file.resolvePath = () => path.join(app.getPath('userData'), "logs", "start.log"); @@ -112,6 +113,10 @@ const createWindow = () => { mainWindow.on('close', () => { mainWindow.webContents.send('closeApp'); }); + + ipcMain.on('openApp', () => { + mainWindow.show(); + }); }; // This method will be called when Electron has finished diff --git a/src/renderer.tsx b/src/renderer.tsx index b7de22f..c6c8e86 100644 --- a/src/renderer.tsx +++ b/src/renderer.tsx @@ -4,6 +4,7 @@ import Menu from "./components/ui/menu"; import MainSide from "./components/ui/mainSide"; import SettingsSite from "./components/ui/settingsSide"; import RenderingSide from "./components/ui/renderingSide"; +import RenderFinishSide from "./components/ui/renderFinishSide"; import "./index.css"; import "./toggle-switchy.css"; import { startBlender } from "./components/blenderController"; @@ -12,7 +13,8 @@ import {ipcRenderer} from "electron"; enum Side { Main, Rendering, - Settings + Settings, + RenderFinish } let rendering = false; @@ -31,6 +33,7 @@ function openSide(side:Side) { {(side === Side.Main)? : null} {(side === Side.Settings)? : null} {(side === Side.Rendering)? : null} + {(side === Side.RenderFinish)? : null} ); }