From 51c85792dc78af4f0204d0101ce664b83d2a42ba Mon Sep 17 00:00:00 2001 From: David Acosta Date: Tue, 20 Dec 2022 17:45:35 -0800 Subject: [PATCH] Add minimized window option --- package.json | 1 - src/assets/icon/connect-white.svg | 3 + .../icon/microphone-slash-solid-white.svg | 10 + src/assets/icon/microphone-solid-white.svg | 10 + src/assets/icon/microphone-white.svg | 4 - src/assets/icon/play-white.svg | 3 + src/assets/icon/video-slash-solid-white.svg | 10 + src/assets/icon/video-solid-white.svg | 10 + src/background.js | 23 +- src/components/ControlPanel.vue | 1222 +++++++++-------- src/components/MinimizeControlWrapper.vue | 333 +++++ src/components/TimelineWrapper.vue | 2 +- src/components/__tests__/ControlPanel.spec.js | 509 +------ .../__tests__/ReviewWrapper.spec.js | 26 +- src/components/settings/GeneralTab.vue | 2 +- .../settings/__tests__/GeneralTab.spec.js | 2 +- src/layouts/Default.vue | 2 +- src/layouts/Minimize.vue | 11 +- src/menu.js | 9 +- src/modules/BrowserWindowUtility.js | 23 + src/modules/CaptureUtility.js | 307 +---- src/modules/DatabaseUtility.js | 12 + src/modules/IpcHandlers.js | 48 +- src/modules/MenuUtility.js | 14 +- src/modules/WindowUtility.js | 382 ++++++ src/modules/constants.js | 21 + src/router/index.js | 25 + src/views/AddSession.vue | 4 +- src/views/EditSession.vue | 22 +- src/views/EndSessionView.vue | 118 ++ src/views/MainView.vue | 4 +- src/views/MinimizeView.vue | 224 +-- src/views/NoteEditorView.vue | 159 +++ src/views/ResultView.vue | 1 + src/views/SourcePickerView.vue | 183 +++ src/views/SummaryEditorView.vue | 125 ++ vue.config.js | 2 + 37 files changed, 2367 insertions(+), 1499 deletions(-) create mode 100644 src/assets/icon/connect-white.svg create mode 100644 src/assets/icon/microphone-slash-solid-white.svg create mode 100644 src/assets/icon/microphone-solid-white.svg delete mode 100644 src/assets/icon/microphone-white.svg create mode 100644 src/assets/icon/play-white.svg create mode 100644 src/assets/icon/video-slash-solid-white.svg create mode 100644 src/assets/icon/video-solid-white.svg create mode 100644 src/components/MinimizeControlWrapper.vue create mode 100644 src/modules/WindowUtility.js create mode 100644 src/views/EndSessionView.vue create mode 100644 src/views/NoteEditorView.vue create mode 100644 src/views/SourcePickerView.vue create mode 100644 src/views/SummaryEditorView.vue diff --git a/package.json b/package.json index 8af7f0f5..0b79be65 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,6 @@ "postuninstall": "electron-builder install-app-deps", "publish": "vue-cli-service electron:build -p always" }, - "main": "background.js", "dependencies": { "@fortawesome/fontawesome-free": "^6.2.1", "@johmun/vue-tags-input": "^2.1.0", diff --git a/src/assets/icon/connect-white.svg b/src/assets/icon/connect-white.svg new file mode 100644 index 00000000..e34fcfa9 --- /dev/null +++ b/src/assets/icon/connect-white.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icon/microphone-slash-solid-white.svg b/src/assets/icon/microphone-slash-solid-white.svg new file mode 100644 index 00000000..be18a8d5 --- /dev/null +++ b/src/assets/icon/microphone-slash-solid-white.svg @@ -0,0 +1,10 @@ + + + +Created with Fabric.js 4.6.0 + + + + + + \ No newline at end of file diff --git a/src/assets/icon/microphone-solid-white.svg b/src/assets/icon/microphone-solid-white.svg new file mode 100644 index 00000000..38fc0ec9 --- /dev/null +++ b/src/assets/icon/microphone-solid-white.svg @@ -0,0 +1,10 @@ + + + +Created with Fabric.js 4.6.0 + + + + + + \ No newline at end of file diff --git a/src/assets/icon/microphone-white.svg b/src/assets/icon/microphone-white.svg deleted file mode 100644 index eaccc705..00000000 --- a/src/assets/icon/microphone-white.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/assets/icon/play-white.svg b/src/assets/icon/play-white.svg new file mode 100644 index 00000000..9b899e84 --- /dev/null +++ b/src/assets/icon/play-white.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icon/video-slash-solid-white.svg b/src/assets/icon/video-slash-solid-white.svg new file mode 100644 index 00000000..c42c2c8e --- /dev/null +++ b/src/assets/icon/video-slash-solid-white.svg @@ -0,0 +1,10 @@ + + + +Created with Fabric.js 4.6.0 + + + + + + \ No newline at end of file diff --git a/src/assets/icon/video-solid-white.svg b/src/assets/icon/video-solid-white.svg new file mode 100644 index 00000000..681d405b --- /dev/null +++ b/src/assets/icon/video-solid-white.svg @@ -0,0 +1,10 @@ + + + +Created with Fabric.js 4.6.0 + + + + + + \ No newline at end of file diff --git a/src/background.js b/src/background.js index a40520b5..95ce19df 100644 --- a/src/background.js +++ b/src/background.js @@ -5,13 +5,14 @@ import { createProtocol } from "vue-cli-plugin-electron-builder/lib"; import installExtension, { VUEJS_DEVTOOLS } from "electron-devtools-installer"; import createMenu from "./menu"; +import { VIEW_MODE } from "./modules/constants"; const isDevelopment = process.env.NODE_ENV !== "production"; const browserUtility = require("./modules/BrowserWindowUtility"); const databaseUtility = require("./modules/DatabaseUtility"); +const windowUtility = require("./modules/WindowUtility"); -const path = require("path"); require("./modules/IpcHandlers"); // initialize session @@ -24,25 +25,9 @@ protocol.registerSchemesAsPrivileged([ async function createWindow() { // Create the browser window. - const win = new BrowserWindow({ - width: 800, - height: 600, - minWidth: 800, - minHeight: 600, - center: true, - icon: path.join(__dirname, "../public/logo.png"), - webPreferences: { - // Use pluginOptions.nodeIntegration, leave this alone - // See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info - nodeIntegration: true, - webSecurity: false, - contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION, - enableRemoteModule: true, - preload: path.join(app.getAppPath(), "preload.js"), - }, - }); - + const win = windowUtility.getMainWindow(); browserUtility.setBrowserWindow(win); + browserUtility.setViewMode(VIEW_MODE.NORMAL); if (process.env.WEBPACK_DEV_SERVER_URL) { // Load the url of the dev server if in development mode diff --git a/src/components/ControlPanel.vue b/src/components/ControlPanel.vue index e373dcb3..b3146a4e 100644 --- a/src/components/ControlPanel.vue +++ b/src/components/ControlPanel.vue @@ -1,431 +1,450 @@ @@ -441,23 +460,21 @@ import NewSessionDialog from "./dialogs/NewSessionDialog.vue"; import DurationConfirmDialog from "./dialogs/DurationConfirmDialog.vue"; import AudioErrorDialog from "./dialogs/AudioErrorDialog.vue"; import EndSessionDialog from "./dialogs/EndSessionDialog.vue"; - +import MinimizeControlWrapper from "../components/MinimizeControlWrapper.vue"; import { IPC_HANDLERS, IPC_FUNCTIONS, + IPC_BIND_KEYS, SESSION_STATUSES, VIDEO_RESOLUTION, } from "../modules/constants"; - import { DEFAULT_MAP_NODES, DEFAULT_MAP_CONNECTIONS, } from "../modules/constants"; - let mediaRecorder; let audioContext; let dest; - export default { name: "ControlPanel", components: { @@ -475,6 +492,7 @@ export default { DurationConfirmDialog, AudioErrorDialog, EndSessionDialog, + MinimizeControlWrapper, }, props: { items: { @@ -493,9 +511,13 @@ export default { type: Boolean, default: () => false, }, - postSessionData: { - type: Object, - default: () => {}, + viewMode: { + type: String, + default: () => "normal", + }, + srcId: { + type: String, + default: () => "", }, }, created() { @@ -517,21 +539,32 @@ export default { this.config = newValue; }, }, + computed: { + postSessionData() { + if (this.config.checklist) return this.config.checklist.postsession; + else return {}; + }, + elapsedTime() { + const timer = this.timer; + const date = new Date(null); + date.setSeconds(timer); + const result = date.toISOString().substr(11, 8); + return result; + }, + }, data() { return { sourcePickerDialog: false, noteDialog: false, summaryDialog: false, - deleteConfirmDialog: false, resetConfirmDialog: false, newSessionDialog: false, durationConfirmDialog: false, audioErrorDialog: false, endSessionDialog: false, - sources: [], - sourceId: "", + sourceId: this.srcId, itemLists: this.items, config: this.configItem, audioDevices: [], @@ -539,57 +572,165 @@ export default { status: this.$store.state.status, recordVideoStarted: false, recordAudioStarted: false, - interval: null, timer: 0, duration: 0, isDuration: false, started: "", ended: "", - selected: [], }; }, mounted() { this.$root.$on("close-sourcepickerdialog", this.hideSourcePickerDialog); this.$root.$on("close-notedialog", this.hideNoteDialog); + this.$root.$on("close-summarydialog", () => { + this.summaryDialog = false; + this.endSessionProcess(); + }); - if (this.status === SESSION_STATUSES.START) { + if ( + this.$store.state.status === SESSION_STATUSES.START || + this.$store.state.status === SESSION_STATUSES.PAUSE || + this.$store.state.status === SESSION_STATUSES.RESUME + ) { this.status = this.$store.state.status; this.timer = this.$store.state.timer; this.duration = this.$store.state.duration; - this.startInterval(); + if (this.$store.state.status === SESSION_STATUSES.START) { + this.startSession(this.sourceId); + } } - this.$root.$on("close-summarydialog", () => { - this.summaryDialog = false; - this.endSessionProcess(); - }); + this.bindIPCEvent(); }, beforeDestroy() { this.$root.$off("close-sourcepickerdialog", this.hideSourcePickerDialog); this.$root.$on("close-notedialog", this.hideNoteDialog); - // clear timer clearInterval(this.interval); this.timer = 0; }, methods: { - showSourcePickerDialog() { + bindIPCEvent() { + if (!window.ipc) return; + + window.ipc.on(IPC_BIND_KEYS.CLOSED_NOTE_DIALOG, (data) => { + this.addNote(data); + }); + window.ipc.on(IPC_BIND_KEYS.CLOSED_SUMMARY_DIALOG, (data) => { + window.ipc.invoke(IPC_HANDLERS.WINDOW, { + func: IPC_FUNCTIONS.CLOSE_SESSION_AND_MINIIMIZED_WINDOW, + data: { + data: { + status: this.status, + timer: this.timer, + duration: this.duration, + sourceId: this.sourceId, + summary: data, + }, + bindKey: IPC_BIND_KEYS.END_SESSION, + }, + }); + }); + window.ipc.on(IPC_BIND_KEYS.CLOSED_ENDSESSION_DIALOG, (data) => { + if (data.passed) { + this.showSummaryDialog(); + } + }); + window.ipc.on(IPC_BIND_KEYS.CLOSED_SOURCEPICKER_DIALOG, (data) => { + if (data.sourceId) { + this.sourceId = data.sourceId; + this.$root.$emit("source-id-changed", this.sourceId); + } + }); + window.ipc.on(IPC_BIND_KEYS.END_SESSION, (data) => { + if (data) { + this.timer = data.timer; + this.status = data.status; + this.duration = data.duration; + this.sourceId = data.sourceId; + this.updateStoreSession(); + if (data.summary) { + this.addSummary(data.summary); + } else { + this.endSessionProcess(); + } + } else { + this.endSessionProcess(); + } + }); + window.ipc.on(IPC_BIND_KEYS.CLOSED_MINIMIZE_WINDOW, (data) => { + this.status = data.status; + this.duration = data.duration; + this.timer = data.timer; + this.sourceId = data.sourceId; + + if ( + this.status !== data.status && + data.status === SESSION_STATUSES.START + ) { + this.startSession(this.sourceId); + } else if (data.status === SESSION_STATUSES.PAUSE) { + this.pauseSession(); + } + }); + }, + startNewSession() { if (!this.checkedStatusOfPreSessionTask) { this.$emit("handle-pressesion-task-error", true); return; } this.$emit("handle-pressesion-task-error", false); - this.sourcePickerDialog = true; - this.getSourceList(); + this.showSourcePickerDialog(); + }, + showSourcePickerDialog() { + if (!window.ipc) return; + window.ipc + .invoke(IPC_HANDLERS.CAPTURE, { + func: IPC_FUNCTIONS.GET_MEDIA_SOURCE, + }) + .then((data) => { + this.loaded = true; + this.sources = data.filter((source) => source.name !== "yattie"); + if (this.viewMode === "normal") { + this.sourcePickerDialog = true; + } else { + window.ipc.invoke(IPC_HANDLERS.WINDOW, { + func: IPC_FUNCTIONS.OPEN_MODAL_WINDOW, + data: { + path: "sourcepicker", + size: { + width: 600, + height: 500, + }, + data: this.sources, + }, + }); + } + }); }, hideSourcePickerDialog() { this.sourcePickerDialog = false; }, showNoteDialog() { - this.noteDialog = true; + if (this.viewMode === "normal") { + this.noteDialog = true; + } else { + if (!window.ipc) return; + window.ipc.invoke(IPC_HANDLERS.WINDOW, { + func: IPC_FUNCTIONS.OPEN_MODAL_WINDOW, + data: { + path: "noteEditor", + size: { + width: 400, + height: 550, + }, + data: this.config, + }, + }); + } }, hideNoteDialog() { this.noteDialog = false; @@ -600,7 +741,6 @@ export default { if (this.duration > 0) { this.duration -= 1; } - this.updateStoreSession(); if (this.isDuration && this.duration === 0) { this.durationConfirmDialog = true; @@ -623,20 +763,18 @@ export default { startSession(id) { this.sourceId = id; this.sourcePickerDialog = false; - - if (this.status === SESSION_STATUSES.PENDING) { - this.status = SESSION_STATUSES.START; - this.timer = this.$store.state.timer; - this.duration = this.$store.state.duration; - if (this.duration > 0) { - this.isDuration = true; - } - this.started = this.getCurrentDateTime(); - this.$store.commit("setStarted", this.started); - - this.startInterval(); - this.changeSessionStatus(SESSION_STATUSES.START); - + this.status = SESSION_STATUSES.START; + this.timer = this.$store.state.timer; + this.duration = this.$store.state.duration; + if (this.duration > 0) { + this.isDuration = true; + } + this.started = this.getCurrentDateTime(); + this.$store.commit("setStarted", this.started); + console.log("start interval-2"); + this.startInterval(); + this.changeSessionStatus(SESSION_STATUSES.START); + if (this.viewMode === "normal") { const currentPath = this.$router.history.current.path; if (currentPath !== "/main/workspace") { this.$router.push({ path: "/main/workspace" }); @@ -649,31 +787,29 @@ export default { this.stopInterval(); }, resumeSession() { - this.status = SESSION_STATUSES.RESUME; + this.status = SESSION_STATUSES.START; this.timer = this.$store.state.timer; + console.log("start interval-3"); this.startInterval(); }, endSession() { if (this.postSessionData.status) { - this.endSessionDialog = true; + this.showEndSessionDialog(); return; } else { - this.summaryDialog = true; + this.showSummaryDialog(); return; } }, - endSessionProcess() { + async endSessionProcess() { this.sourceId = ""; - this.ended = this.getCurrentDateTime(); this.$store.commit("setEnded", this.ended); - this.status = SESSION_STATUSES.END; this.changeSessionStatus(SESSION_STATUSES.END); this.stopInterval(); - if (window.ipc) { - window.ipc.invoke(IPC_HANDLERS.CAPTURE, { + window.ipc.invoke(IPC_HANDLERS.WINDOW, { func: IPC_FUNCTIONS.SET_WINDOW_SIZE, data: { width: 1440, @@ -683,30 +819,63 @@ export default { }, }); } - - this.$router.push({ path: "/result" }); + this.$router.push({ path: "/result" }).catch(() => {}); + }, + showSummaryDialog() { + if (this.viewMode === "normal") { + this.summaryDialog = true; + } else { + if (!window.ipc) return; + window.ipc.invoke(IPC_HANDLERS.WINDOW, { + func: IPC_FUNCTIONS.OPEN_MODAL_WINDOW, + data: { + path: "summaryEditor", + size: { + width: 500, + height: 500, + }, + data: this.config, + }, + }); + } + }, + showEndSessionDialog() { + if (this.viewMode === "normal") { + this.endSessionDialog = true; + } else { + if (!window.ipc) return; + window.ipc.invoke(IPC_HANDLERS.WINDOW, { + func: IPC_FUNCTIONS.OPEN_MODAL_WINDOW, + data: { + path: "endsession", + size: { + width: 350, + height: 500, + }, + data: this.config, + }, + }); + } + }, + closeEndSessionDialog(status) { + this.endSessionDialog = false; + if (status) { + this.summaryDialog = true; + } }, resume() { this.status = SESSION_STATUSES.PAUSE; this.changeSessionStatus(SESSION_STATUSES.PAUSE); this.timer = this.$store.state.timer; this.updateStoreSession(); - this.removeSummary(); this.$router.push({ path: "/main/workspace" }); }, - closeEndSessionDialog(status) { - this.endSessionDialog = false; - if (status) { - this.summaryDialog = true; - } - }, reset() { this.resetConfirmDialog = false; this.status = SESSION_STATUSES.PENDING; this.changeSessionStatus(SESSION_STATUSES.PENDING); this.$store.commit("resetState"); - try { // reset database window.ipc.invoke(IPC_HANDLERS.DATABASE, { @@ -715,11 +884,9 @@ export default { } catch (e) { console.log(e); } - this.stopInterval(); this.$router.push({ path: "/main" }); }, - end() { this.durationConfirmDialog = false; this.endSession(); @@ -728,28 +895,14 @@ export default { this.durationConfirmDialog = false; this.status = SESSION_STATUSES.PROCEED; this.changeSessionStatus(SESSION_STATUSES.PROCEED); + console.log("start interval-1"); this.startInterval(); }, - updateStatus(value) { this.status = value; this.changeSessionStatus(this.status); this.$store.commit("setStatus", this.status); }, - async getSourceList() { - try { - await window.ipc - .invoke(IPC_HANDLERS.CAPTURE, { - func: IPC_FUNCTIONS.GET_MEDIA_SOURCE, - }) - .then((data) => { - this.loaded = true; - this.sources = data; - }); - } catch (e) { - console.log(e); - } - }, async screenshot() { this.handleStream = (stream) => { const video = document.createElement("video"); @@ -783,11 +936,9 @@ export default { } }; }; - this.handleError = (error) => { console.log(error); }; - try { const stream = await navigator.mediaDevices.getUserMedia({ audio: false, @@ -815,10 +966,8 @@ export default { mediaRecorder = new MediaRecorder(stream, { mimeType: "video/webm;codecs=h264", }); - let poster; let frames = []; - mediaRecorder.onstart = () => { this.recordVideoStarted = true; const video = document.createElement("video"); @@ -842,13 +991,11 @@ export default { }); }; }; - mediaRecorder.ondataavailable = (e) => { if (e.data.size > 0) { frames.push(e.data); } }; - mediaRecorder.onstop = async () => { this.recordVideoStarted = false; const blob = new Blob(frames, { type: "video/webm;codecs=h264" }); @@ -872,16 +1019,12 @@ export default { }); } }; - frames = []; - mediaRecorder.start(1000); }; - this.handleError = (error) => { console.log(error); }; - try { const videoQuality = this.config.videoQuality; let resolution; @@ -904,18 +1047,14 @@ export default { }, }, }; - if (this.config.audioCapture) { this.audioDevices = await this.getAudioSources(); if (this.audioDevices.length > 0) { await this.setAudio(this.audioDevices); } } - const stream = await navigator.mediaDevices.getUserMedia(constraints); - stream.getVideoTracks()[0].applyConstraints({ frameRate: 30 }); - this.handleStream(stream); } catch (e) { console.log(e); @@ -961,40 +1100,31 @@ export default { latency: 0.0, }, }); - this.handleStream(stream); } catch (e) { this.handleError(e); } }; - this.handleStream = (stream) => { let recordedChunks = []; - const option = { mimeType: "audio/webm", }; - mediaRecorder = new MediaRecorder(stream, option); - mediaRecorder.onstart = () => { this.recordAudioStarted = true; }; - mediaRecorder.ondataavailable = (e) => { if (e.data.size > 0) { recordedChunks.push(e.data); } }; - mediaRecorder.onstop = async () => { this.recordAudioStarted = false; const blob = new Blob(recordedChunks, { type: "audio/mpeg-3", }); - const buffer = await blob.arrayBuffer(); - if (window.ipc) { await window.ipc .invoke(IPC_HANDLERS.CAPTURE, { @@ -1010,20 +1140,16 @@ export default { time: this.timer, poster: "", }; - this.openAddWindow(data); }); } recordedChunks = []; }; - mediaRecorder.start(1000); }; - this.handleError = (error) => { console.log("Error:", error); }; - // try { // this.audioDevices = await this.getAudioSources(); // if (!this.audioDevices.length) { @@ -1035,7 +1161,6 @@ export default { // } catch (e) { // console.log(e); // } - await navigator.mediaDevices.enumerateDevices().then((devices) => { this.audioDevices = devices.filter( (d) => @@ -1043,12 +1168,11 @@ export default { d.deviceId != "communications" && d.deviceId != "default" ); - + console.log("audio devices:", this.audioDevices); if (!this.audioDevices.length) { this.audioErrorDialog = true; return; } - this.setAudioSource(); }); }, @@ -1060,7 +1184,8 @@ export default { } }, async openAddWindow(data) { - await window.ipc.invoke(IPC_HANDLERS.CAPTURE, { + if (!window.ipc) return; + await window.ipc.invoke(IPC_HANDLERS.WINDOW, { func: IPC_FUNCTIONS.OPEN_ADD_WINDOW, data: { width: 700, height: 800, data: data }, }); @@ -1068,7 +1193,6 @@ export default { async addNote(value) { const date = dayjs().format("MM/DD/YYYY HH:mm:ss"); const fileName = dayjs().format("YYYY-MM-DD_HH-mm-ss-ms") + ".txt"; - if (window.ipc) { // Save Note await window.ipc @@ -1090,12 +1214,10 @@ export default { this.$emit("add-item", newItem); }); } - this.noteDialog = false; }, async addSummary(value) { const date = dayjs().format("MM/DD/YYYY HH:mm:ss"); - const data = { id: Date.now(), sessionType: "Summary", @@ -1103,7 +1225,6 @@ export default { time: this.timer, createdAt: date, }; - this.$emit("add-item", data); this.summaryDialog = false; this.endSessionProcess(); @@ -1137,22 +1258,30 @@ export default { this.openAddWindow(data); }, async minimize() { - await window.ipc.invoke(IPC_HANDLERS.CAPTURE, { + const data = { + status: this.status, + timer: this.timer, + duration: this.duration, + sourceId: this.sourceId, + }; + // console.log(data); + localStorage.setItem("state-data", JSON.stringify(data)); + if (!window.ipc) return; + await window.ipc.invoke(IPC_HANDLERS.WINDOW, { func: IPC_FUNCTIONS.OPEN_MINIMIZE_WINDOW, - data: { width: 700, height: 800 }, + data: { width: 400, height: 84 }, }); }, async deleteItems() { + if (!window.ipc) return; await window.ipc.invoke(IPC_HANDLERS.DATABASE, { func: IPC_FUNCTIONS.DELETE_ITEMS, data: this.selected, }); - await window.ipc.invoke(IPC_HANDLERS.DATABASE, { func: IPC_FUNCTIONS.DELETE_NOTES, data: this.selected, }); - this.selected = []; this.$root.$emit("update-selected", this.selected); this.deleteConfirmDialog = false; @@ -1164,7 +1293,6 @@ export default { data: this.selected, }); } - this.selected = []; this.$root.$emit("update-selected", this.selected); }, @@ -1181,6 +1309,7 @@ export default { ended: this.$store.state.ended, path: this.$route.path, }; + if (!window.ipc) return; await window.ipc.invoke(IPC_HANDLERS.FILE_SYSTEM, { func: IPC_FUNCTIONS.SAVE_SESSION, data: data, @@ -1204,17 +1333,18 @@ export default { String(now.getDate()).padStart(2, "0") + "-" + now.getFullYear(); - return currentDateTime; }, changeSessionStatus(status) { + if (!window.ipc) return; window.ipc.invoke(IPC_HANDLERS.MENU, { func: IPC_FUNCTIONS.CHANGE_MENUITEM_STATUS, data: { sessionStatus: status }, }); }, async showNotePanel() { - await window.ipc.invoke(IPC_HANDLERS.CAPTURE, { + if (!window.ipc) return; + await window.ipc.invoke(IPC_HANDLERS.WINDOW, { func: IPC_FUNCTIONS.OPEN_NOTES_WINDOW, data: { width: 700, height: 800 }, }); @@ -1224,10 +1354,16 @@ export default { diff --git a/src/components/MinimizeControlWrapper.vue b/src/components/MinimizeControlWrapper.vue new file mode 100644 index 00000000..e9e22a36 --- /dev/null +++ b/src/components/MinimizeControlWrapper.vue @@ -0,0 +1,333 @@ + + + diff --git a/src/components/TimelineWrapper.vue b/src/components/TimelineWrapper.vue index 9b83c8b4..814aab7f 100644 --- a/src/components/TimelineWrapper.vue +++ b/src/components/TimelineWrapper.vue @@ -469,7 +469,7 @@ export default { async openEditorModal(data) { if (!window.ipc) return; - await window.ipc.invoke(IPC_HANDLERS.CAPTURE, { + await window.ipc.invoke(IPC_HANDLERS.WINDOW, { func: IPC_FUNCTIONS.OPEN_ADD_WINDOW, data: { width: 700, height: 800, data: data }, }); diff --git a/src/components/__tests__/ControlPanel.spec.js b/src/components/__tests__/ControlPanel.spec.js index 6734f165..4370ab28 100644 --- a/src/components/__tests__/ControlPanel.spec.js +++ b/src/components/__tests__/ControlPanel.spec.js @@ -1,5 +1,6 @@ import Vuetify from "vuetify"; import Vuex from "vuex"; +import VueRouter from "vue-router"; import ControlPanel from "../ControlPanel.vue"; import SourcePickerDialog from "../dialogs/SourcePickerDialog.vue"; @@ -19,6 +20,9 @@ import { SESSION_STATUSES } from "../../modules/constants"; const vuetify = new Vuetify(); const localVue = createLocalVue(); localVue.use(Vuex); +localVue.use(VueRouter); + +const router = new VueRouter(); describe("ControlPanel.vue", () => { const dataInfo = { @@ -41,8 +45,21 @@ describe("ControlPanel.vue", () => { status: true, tasks: [], }, + configItem: { + checklist: { + presession: { + status: false, + tasks: [], + }, + postsession: { + status: false, + tasks: [], + }, + }, + }, }, localVue, + router, store: { ...store, state: { @@ -79,8 +96,21 @@ describe("ControlPanel.vue", () => { status: true, tasks: [], }, + configItem: { + checklist: { + presession: { + status: false, + tasks: [], + }, + postsession: { + status: false, + tasks: [], + }, + }, + }, }, localVue, + router, store: { ...store, state: { @@ -106,8 +136,21 @@ describe("ControlPanel.vue", () => { status: true, tasks: [], }, + configItem: { + checklist: { + presession: { + status: false, + tasks: [], + }, + postsession: { + status: false, + tasks: [], + }, + }, + }, }, localVue, + router, store: { ...store, state: { @@ -119,7 +162,7 @@ describe("ControlPanel.vue", () => { }); expect(wrapper.find("#btn_resume").exists()).toBe(false); - expect(wrapper.find("#btn_plus").exists()).toBe(false); + expect(wrapper.find("#btn_save").exists()).toBe(false); expect(wrapper.find("#btn_reset").exists()).toBe(false); expect(wrapper.find("#btn_pause_session").exists()).toBe(true); @@ -132,468 +175,4 @@ describe("ControlPanel.vue", () => { expect(wrapper.find("#btn_stop_record_audio").exists()).toBe(false); expect(wrapper.find("#btn_note").exists()).toBe(true); }); - - test('show the "pause", "reset", "new session" buttons', () => { - const wrapper = mount(ControlPanel, { - data() { - return { - selected: ["selected"], - }; - }, - propsData: { - postSessionData: { - status: true, - tasks: [], - }, - }, - localVue, - store: { - ...store, - state: { - ...store.status, - status: SESSION_STATUSES.END, - }, - }, - vuetify, - }); - - expect(wrapper.find("#btn_resume").exists()).toBe(true); - expect(wrapper.find("#btn_plus").exists()).toBe(true); - expect(wrapper.find("#btn_reset").exists()).toBe(true); - }); - - test('trigger the click event of "new session" button', () => { - const wrapper = mount(ControlPanel, { - propsData: { - postSessionData: { - status: true, - tasks: [], - }, - }, - localVue, - store: { - ...store, - state: { - status: SESSION_STATUSES.PENDING, - }, - }, - vuetify, - }); - - const button = wrapper.find("#btn_new_session"); - const event = jest.fn(); - - button.vm.$on("click", event); - button.trigger("click"); - - expect(event).toHaveBeenCalled(); - }); - - test('trigger the click event of "delete" button', () => { - const wrapper = mount(ControlPanel, { - data() { - return { - selected: ["selected"], - }; - }, - propsData: { - postSessionData: { - status: true, - tasks: [], - }, - }, - localVue, - store: { - ...store, - state: { - status: SESSION_STATUSES.START, - }, - }, - vuetify, - }); - - const button = wrapper.find("#btn_delete"); - const event = jest.fn(); - - button.vm.$on("click", event); - button.trigger("click"); - - expect(event).toHaveBeenCalled(); - }); - - test('trigger the click event of "download" button', () => { - const wrapper = mount(ControlPanel, { - data() { - return { - selected: ["selected"], - }; - }, - propsData: { - postSessionData: { - status: true, - tasks: [], - }, - }, - localVue, - store: { - ...store, - state: { - status: SESSION_STATUSES.START, - }, - }, - vuetify, - }); - - const button = wrapper.find("#btn_download"); - const event = jest.fn(); - - button.vm.$on("click", event); - button.trigger("click"); - - expect(event).toHaveBeenCalled(); - }); - - test('trigger the click event of "resume" button', () => { - const wrapper = mount(ControlPanel, { - propsData: { - postSessionData: { - status: true, - tasks: [], - }, - }, - localVue, - store: { - ...store, - state: { - status: SESSION_STATUSES.END, - }, - }, - vuetify, - }); - - const button = wrapper.find("#btn_resume"); - const event = jest.fn(); - - button.vm.$on("click", event); - button.trigger("click"); - - expect(event).toHaveBeenCalled(); - }); - - test('trigger the click event of "plus" button', () => { - const wrapper = mount(ControlPanel, { - propsData: { - postSessionData: { - status: true, - tasks: [], - }, - }, - localVue, - store: { - ...store, - state: { - status: SESSION_STATUSES.END, - }, - }, - vuetify, - }); - - const button = wrapper.find("#btn_plus"); - const event = jest.fn(); - - button.vm.$on("click", event); - button.trigger("click"); - - expect(event).toHaveBeenCalled(); - }); - - test('trigger the click event of "reset" button', () => { - const wrapper = mount(ControlPanel, { - propsData: { - postSessionData: { - status: true, - tasks: [], - }, - }, - localVue, - store: { - ...store, - state: { - status: SESSION_STATUSES.END, - }, - }, - vuetify, - }); - - const button = wrapper.find("#btn_reset"); - const event = jest.fn(); - - button.vm.$on("click", event); - button.trigger("click"); - - expect(event).toHaveBeenCalled(); - }); - - test('trigger the click event of "pause session" button', () => { - const wrapper = mount(ControlPanel, { - propsData: { - postSessionData: { - status: true, - tasks: [], - }, - }, - localVue, - store: { - ...store, - state: { - status: SESSION_STATUSES.START, - }, - }, - vuetify, - }); - - const button = wrapper.find("#btn_pause_session"); - const event = jest.fn(); - - button.vm.$on("click", event); - button.trigger("click"); - - expect(event).toHaveBeenCalled(); - }); - - test('trigger the click event of "resume session" button', () => { - const wrapper = mount(ControlPanel, { - propsData: { - postSessionData: { - status: true, - tasks: [], - }, - }, - localVue, - store: { - ...store, - state: { - status: SESSION_STATUSES.PAUSE, - }, - }, - vuetify, - }); - - const button = wrapper.find("#btn_resume_session"); - const event = jest.fn(); - - button.vm.$on("click", event); - button.trigger("click"); - - expect(event).toHaveBeenCalled(); - }); - - test('trigger the click event of "end session" button', () => { - const wrapper = mount(ControlPanel, { - propsData: { - postSessionData: { - status: true, - tasks: [], - }, - }, - localVue, - store: { - ...store, - state: { - status: SESSION_STATUSES.START, - }, - }, - vuetify, - }); - - const button = wrapper.find("#btn_end_session"); - const event = jest.fn(); - - button.vm.$on("click", event); - button.trigger("click"); - - expect(event).toHaveBeenCalled(); - }); - - test('trigger the click event of "start video record" button', () => { - const wrapper = mount(ControlPanel, { - data() { - return { - recordVideoStarted: false, - }; - }, - propsData: { - postSessionData: { - status: true, - tasks: [], - }, - }, - localVue, - store: { - ...store, - state: { - status: SESSION_STATUSES.START, - }, - }, - vuetify, - }); - - const button = wrapper.find("#btn_start_record_video"); - const event = jest.fn(); - - button.vm.$on("click", event); - button.trigger("click"); - - expect(event).toHaveBeenCalled(); - }); - - test('trigger the click event of "stop video record" button', () => { - const wrapper = mount(ControlPanel, { - data() { - return { - recordVideoStarted: true, - }; - }, - propsData: { - postSessionData: { - status: true, - tasks: [], - }, - }, - localVue, - store: { - ...store, - state: { - status: SESSION_STATUSES.START, - }, - }, - vuetify, - }); - - const button = wrapper.find("#btn_stop_record_video"); - const event = jest.fn(); - - button.vm.$on("click", event); - button.trigger("click"); - - expect(event).toHaveBeenCalled(); - }); - - test('trigger the click event of "screenshot" button', async () => { - const wrapper = mount(ControlPanel, { - propsData: { - postSessionData: { - status: true, - tasks: [], - }, - }, - localVue, - store: { - ...store, - state: { - status: SESSION_STATUSES.PAUSE, - }, - }, - vuetify, - }); - - const button = wrapper.find("#btn_screenshot"); - const event = jest.fn(); - - button.vm.$on("click", event); - button.trigger("click"); - - // expect(event).toHaveBeenCalled(); - }); - - test('trigger the click event of "start record audio" button', () => { - const wrapper = mount(ControlPanel, { - localVue, - data() { - return { - recordAudioStarted: false, - }; - }, - propsData: { - postSessionData: { - status: true, - tasks: [], - }, - }, - store: { - ...store, - state: { - status: SESSION_STATUSES.START, - }, - }, - vuetify, - }); - - const button = wrapper.find(".btn:first-child"); - const event = jest.fn(); - - button.vm.$on("click", event); - button.trigger("click"); - - expect(event).toHaveBeenCalled(); - }); - - test('trigger the click event of "stop record audio" button', () => { - const wrapper = mount(ControlPanel, { - data() { - return { - recordAudioStarted: true, - }; - }, - propsData: { - postSessionData: { - status: true, - tasks: [], - }, - }, - localVue, - store: { - ...store, - state: { - status: SESSION_STATUSES.START, - }, - }, - vuetify, - }); - - const button = wrapper.find("#btn_stop_record_audio"); - const event = jest.fn(); - - button.vm.$on("click", event); - button.trigger("click"); - - expect(event).toHaveBeenCalled(); - }); - - test('trigger the click event of "note" button', async () => { - const wrapper = mount(ControlPanel, { - propsData: { - postSessionData: { - status: true, - tasks: [], - }, - }, - localVue, - store: { - ...store, - state: { - status: SESSION_STATUSES.START, - }, - }, - vuetify, - }); - - const button = wrapper.find("#btn_note"); - const event = jest.fn(); - - button.vm.$on("click", event); - button.trigger("click"); - - expect(event).toHaveBeenCalled(); - }); }); diff --git a/src/components/__tests__/ReviewWrapper.spec.js b/src/components/__tests__/ReviewWrapper.spec.js index 97e653c9..0f9ad075 100644 --- a/src/components/__tests__/ReviewWrapper.spec.js +++ b/src/components/__tests__/ReviewWrapper.spec.js @@ -23,36 +23,46 @@ describe("ReivewWrapper.vue", () => { triggerSave: false, autoSave: false, currentView: false, + config: { + defaultColor: "#000000", + }, + }, + data() { + return { + sessionItem: { + fileType: "mindmap", + }, + }; }, vuetify, }); expect(wrapper.findComponent(MindmapEditor).exists()).toBe(true); - await wrapper.setProps({ - item: { + await wrapper.setData({ + sessionItem: { fileType: "image", }, }); expect(wrapper.findComponent(ImageEditor).exists()).toBe(true); - await wrapper.setProps({ - item: { + await wrapper.setData({ + sessionItem: { fileType: "video", }, }); expect(wrapper.findComponent(VideoWrapper).exists()).toBe(true); - await wrapper.setProps({ - item: { + await wrapper.setData({ + sessionItem: { fileType: "audio", }, }); expect(wrapper.findComponent(AudioWrapper).exists()).toBe(true); - await wrapper.setProps({ - item: { + await wrapper.setData({ + sessionItem: { fileType: "other", }, }); diff --git a/src/components/settings/GeneralTab.vue b/src/components/settings/GeneralTab.vue index e9eb5ff7..fc1fff84 100644 --- a/src/components/settings/GeneralTab.vue +++ b/src/components/settings/GeneralTab.vue @@ -89,7 +89,7 @@ {{ $t("message.default_color_description") }}.

-
+
{ ); expect( wrapper - .find(".content-wrapper .screenshot-section .switch-control") + .find(".content-wrapper .screenshot-section .color-picker-wrapper") .exists() ).toBe(true); diff --git a/src/layouts/Default.vue b/src/layouts/Default.vue index d660c4d0..7ccb4aee 100644 --- a/src/layouts/Default.vue +++ b/src/layouts/Default.vue @@ -33,7 +33,7 @@ export default { this.$forceUpdate(); }); window.ipc.on("APP_SETTING", async () => { - await window.ipc.invoke(IPC_HANDLERS.CAPTURE, { + await window.ipc.invoke(IPC_HANDLERS.WINDOW, { func: IPC_FUNCTIONS.OPEN_SETTING_WINDOW, }); }); diff --git a/src/layouts/Minimize.vue b/src/layouts/Minimize.vue index 9b583732..42ff1f27 100644 --- a/src/layouts/Minimize.vue +++ b/src/layouts/Minimize.vue @@ -1,5 +1,9 @@ + diff --git a/src/menu.js b/src/menu.js index 32248be0..90d84c46 100644 --- a/src/menu.js +++ b/src/menu.js @@ -8,6 +8,7 @@ const createMenu = (win, dev) => { const template = [ { label: i18n.t("menu.file"), + id: "menu_file", submenu: [ { label: i18n.t("menu.new_session"), accelerator: "Ctrl+Shift+C" }, { label: i18n.t("menu.new_session_test"), accelerator: "Ctrl+Shift+T" }, @@ -21,13 +22,19 @@ const createMenu = (win, dev) => { label: i18n.t("menu.save_session"), accelerator: "Alt+Ctrl+S", enabled: false, + id: "menu_save_session", }, { label: i18n.t("menu.save_as_charter"), accelerator: "Ctrl+Shift+X", enabled: false, + id: "menu_save_as_charter", + }, + { + label: i18n.t("menu.reset_session"), + enabled: false, + id: "menu_reset_session", }, - { label: i18n.t("menu.reset_session"), enabled: false }, { type: "separator" }, { label: i18n.tc("menu.app_setting", 1), diff --git a/src/modules/BrowserWindowUtility.js b/src/modules/BrowserWindowUtility.js index e5f7bf9f..1c349d8b 100644 --- a/src/modules/BrowserWindowUtility.js +++ b/src/modules/BrowserWindowUtility.js @@ -1,3 +1,5 @@ +const { VIEW_MODE } = require("./constants"); + module.exports.setBrowserWindow = (browserWindow) => { this._browserWindow = browserWindow; }; @@ -5,3 +7,24 @@ module.exports.setBrowserWindow = (browserWindow) => { module.exports.getBrowserWindow = () => { return this._browserWindow; }; + +module.exports.setMinimizedWindow = (minimizedWindow) => { + this._minimizedWindow = minimizedWindow; +}; + +module.exports.getMinimizedWindow = () => { + return this._minimizedWindow; +}; + +module.exports.setViewMode = (viewMode) => { + this._viewMode = viewMode; +}; + +module.exports.getViewMode = () => { + return this._viewMode; +}; + +module.exports.getParentWindow = () => { + if (this._viewMode === VIEW_MODE.NORMAL) return this._browserWindow; + else return this._minimizedWindow; +}; diff --git a/src/modules/CaptureUtility.js b/src/modules/CaptureUtility.js index b71b89f6..605701a0 100644 --- a/src/modules/CaptureUtility.js +++ b/src/modules/CaptureUtility.js @@ -1,12 +1,4 @@ -const { - app, - remote, - dialog, - desktopCapturer, - BrowserWindow, - screen, -} = require("electron"); -const browserUtility = require("./BrowserWindowUtility"); +const { app, remote, dialog, desktopCapturer } = require("electron"); const path = require("path"); const fs = require("fs"); const dayjs = require("dayjs"); @@ -26,12 +18,11 @@ const ffprobePath = require("ffprobe-static").path.replace( ffmpeg.setFfmpegPath(ffmpegPath); ffmpeg.setFfprobePath(ffprobePath.path); +const browserUtility = require("./BrowserWindowUtility"); const { STATUSES } = require("./constants"); const configDir = (app || remote.app).getPath("userData"); -let addWin, editWin, settingsWin, minimizeWin, notesWin; - module.exports.getMediaSource = async () => { const sources = await desktopCapturer.getSources({ thumbnailSize: { @@ -307,254 +298,6 @@ module.exports.saveUserMedia = (data) => { return data; }; -module.exports.openAddWindow = ({ width, height, data }) => { - const browserWindow = browserUtility.getBrowserWindow(); - const modalPath = - process.env.NODE_ENV === "development" - ? "http://localhost:8080/#/addSession" - : `file://${__dirname}/index.html#addSession`; - - if (!addWin) { - addWin = new BrowserWindow({ - width: width, - height: height, - minWidth: width, - minHeight: height, - center: true, - parent: browserWindow, - icon: path.join(__dirname, "../public/logo.png"), - webPreferences: { - devTools: true, - nodeIntegration: true, - webSecurity: false, - enableRemoteModule: true, - preload: path.join(app.getAppPath(), "preload.js"), - }, - }); - - addWin.loadURL(modalPath); - addWin.setMenuBarVisibility(false); - addWin.once("ready-to-show", () => { - addWin.webContents.openDevTools(); - addWin.show(); - browserWindow.webContents.send("OPEN_CHILD_WINDOW"); - }); - - addWin.webContents.on("did-finish-load", () => { - addWin.webContents.send("ACTIVE_SESSION", data); - }); - - addWin.on("close", () => { - browserWindow.webContents.send("CLOSE_CHILD_WINDOW", { data: "add" }); - addWin = null; - }); - } -}; - -module.exports.openAddWindow = ({ width, height, data }) => { - const browserWindow = browserUtility.getBrowserWindow(); - const modalPath = - process.env.NODE_ENV === "development" - ? "http://localhost:8080/#/addSession" - : `file://${__dirname}/index.html#addSession`; - - if (!addWin) { - addWin = new BrowserWindow({ - width: width, - height: height, - minWidth: width, - minHeight: height, - center: true, - parent: browserWindow, - icon: path.join(__dirname, "../public/logo.png"), - webPreferences: { - devTools: true, - nodeIntegration: true, - webSecurity: false, - enableRemoteModule: true, - preload: path.join(app.getAppPath(), "preload.js"), - }, - }); - - addWin.loadURL(modalPath); - addWin.setMenuBarVisibility(false); - addWin.once("ready-to-show", () => { - addWin.webContents.openDevTools(); - addWin.show(); - browserWindow.webContents.send("OPEN_CHILD_WINDOW"); - }); - - addWin.webContents.on("did-finish-load", () => { - addWin.webContents.send("ACTIVE_SESSION", data); - }); - - addWin.on("close", () => { - browserWindow.webContents.send("CLOSE_CHILD_WINDOW", { data: "add" }); - addWin = null; - }); - } -}; - -module.exports.closeAddWindow = () => { - addWin.close(); -}; - -module.exports.openEditWindow = (data) => { - const browserWindow = browserUtility.getBrowserWindow(); - const url = - process.env.NODE_ENV === "development" - ? "http://localhost:8080/#/editSession" - : `file://${__dirname}/index.html#editSession`; - - if (!editWin) { - editWin = new BrowserWindow({ - width: 800, - height: 800, - minWidth: 800, - minHeight: 800, - center: true, - parent: browserWindow, - icon: path.join(__dirname, "../public/logo.png"), - webPreferences: { - devTools: true, - nodeIntegration: true, - webSecurity: false, - enableRemoteModule: true, - preload: path.join(app.getAppPath(), "preload.js"), - }, - }); - - editWin.loadURL(url); - editWin.setMenuBarVisibility(false); - - editWin.once("ready-to-show", () => { - editWin.webContents.openDevTools(); - editWin.show(); - browserWindow.webContents.send("OPEN_CHILD_WINDOW"); - }); - - editWin.webContents.on("did-finish-load", () => { - editWin.webContents.send("ACTIVE_SESSION", data); - }); - - editWin.on("close", () => { - browserWindow.webContents.send("CLOSE_CHILD_WINDOW", { data: "edit" }); - editWin = null; - }); - } -}; - -module.exports.closeEditWindow = () => { - editWin.close(); -}; - -module.exports.openSettingWindow = () => { - const browserWindow = browserUtility.getBrowserWindow(); - const url = - process.env.NODE_ENV === "development" - ? "http://localhost:8080/#/settings" - : `file://${__dirname}/index.html#settings`; - - if (!settingsWin) { - settingsWin = new BrowserWindow({ - width: 800, - height: 600, - minWidth: 800, - minHeight: 600, - center: true, - parent: browserWindow, - icon: path.join(__dirname, "../public/logo.png"), - webPreferences: { - devTools: true, - nodeIntegration: true, - webSecurity: false, - enableRemoteModule: true, - preload: path.join(app.getAppPath(), "preload.js"), - }, - }); - - settingsWin.loadURL(url); - settingsWin.setMenuBarVisibility(false); - - settingsWin.once("ready-to-show", () => { - settingsWin.webContents.openDevTools(); - settingsWin.show(); - browserWindow.webContents.send("OPEN_CHILD_WINDOW"); - }); - - settingsWin.on("close", () => { - browserWindow.webContents.send("CLOSE_CHILD_WINDOW", { data: "setting" }); - settingsWin = null; - }); - } -}; - -module.exports.closeSettingWindow = () => { - settingsWin.close(); -}; - -module.exports.openMinimizeWindow = () => { - const browserWindow = browserUtility.getBrowserWindow(); - browserWindow.hide(); - const url = - process.env.NODE_ENV === "development" - ? "http://localhost:8080/#/minimize" - : `file://${__dirname}/index.html#minimize`; - console.log("minimize window:", minimizeWin); - if (minimizeWin == null) { - let display = screen.getPrimaryDisplay(); - let displayWidth = display.bounds.width; - minimizeWin = new BrowserWindow({ - width: 400, - height: 84, - minWidth: 350, - minHeight: 84, - x: displayWidth - 400, - y: 50, - transparent: true, - frame: false, - resizable: false, - icon: path.join(__dirname, "../public/logo.png"), - webPreferences: { - devTools: true, - nodeIntegration: true, - webSecurity: false, - enableRemoteModule: true, - preload: path.join(app.getAppPath(), "preload.js"), - }, - }); - - minimizeWin.loadURL(url); - minimizeWin.setMenuBarVisibility(false); - - minimizeWin.once("ready-to-show", () => { - // minimizeWin.webContents.openDevTools(); - minimizeWin.show(); - }); - - minimizeWin.on("close", () => { - minimizeWin = null; - browserWindow.show(); - }); - } else { - browserWindow.hide(); - minimizeWin.show(); - } -}; - -module.exports.closeMinimizeWindow = () => { - const browserWindow = browserUtility.getBrowserWindow(); - minimizeWin.hide(); - browserWindow.show(); -}; - -module.exports.setWindowSize = ({ width, height, minWidth, minHeight }) => { - const browserWindow = browserUtility.getBrowserWindow(); - browserWindow.setSize(width, height); - browserWindow.setMinimumSize(minWidth, minHeight); - browserWindow.center(); -}; - module.exports.setApperance = ({ apperance }) => { const browserWindow = browserUtility.getBrowserWindow(); browserWindow.webContents.send("SET_THEME", { apperance }); @@ -568,49 +311,3 @@ module.exports.getImageData = (filePath) => { function base64_encode(file) { return "data:image/png;base64," + fs.readFileSync(file, "base64"); } - -module.exports.openNotesWindow = (data) => { - const browserWindow = browserUtility.getBrowserWindow(); - const modalPath = - process.env.NODE_ENV === "development" - ? "http://localhost:8080/#/note" - : `file://${__dirname}/index.html#note`; - - if (!notesWin) { - notesWin = new BrowserWindow({ - width: data.width, - height: data.height, - minWidth: data.width, - minHeight: data.height, - center: true, - parent: browserWindow, - icon: path.join(__dirname, "../public/logo.png"), - webPreferences: { - devTools: true, - nodeIntegration: true, - webSecurity: false, - enableRemoteModule: true, - preload: path.join(app.getAppPath(), "preload.js"), - }, - }); - - notesWin.loadURL(modalPath); - notesWin.setMenuBarVisibility(false); - notesWin.once("ready-to-show", () => { - notesWin.webContents.openDevTools(); - notesWin.show(); - browserWindow.webContents.send("OPEN_CHILD_WINDOW"); - }); - - notesWin.webContents.on("did-finish-load", () => {}); - - notesWin.on("close", () => { - browserWindow.webContents.send("CLOSE_CHILD_WINDOW", { data: "notes" }); - notesWin = null; - }); - } - - module.exports.closeNotesWindow = () => { - notesWin.close(); - }; -}; diff --git a/src/modules/DatabaseUtility.js b/src/modules/DatabaseUtility.js index 4d58612e..d033c4a2 100644 --- a/src/modules/DatabaseUtility.js +++ b/src/modules/DatabaseUtility.js @@ -155,6 +155,18 @@ module.exports.getItems = () => { } }; +module.exports.addItem = (item) => { + try { + let items = dataDb.get("items"); + items.push(item); + dataDb.set("items", items); + browserWindow = browserUtility.getBrowserWindow(); + browserWindow.webContents.send("DATA_CHANGE"); + } catch (error) { + console.log(error); + } +}; + module.exports.updateItems = (items) => { try { dataDb.set("items", items); diff --git a/src/modules/IpcHandlers.js b/src/modules/IpcHandlers.js index c006801d..1a358fbf 100644 --- a/src/modules/IpcHandlers.js +++ b/src/modules/IpcHandlers.js @@ -4,6 +4,7 @@ const captureUtility = require("./CaptureUtility"); const databaseUtility = require("./DatabaseUtility"); const fileSystemUtility = require("./FileSystemUtility"); const menuUtility = require("./MenuUtility"); +const windowUtility = require("./WindowUtility"); ipcMain.handle(IPC_HANDLERS.CAPTURE, async (event, args) => { switch (args.func) { @@ -34,33 +35,48 @@ ipcMain.handle(IPC_HANDLERS.CAPTURE, async (event, args) => { case IPC_FUNCTIONS.UPDATE_USER_MEDIA: return captureUtility.updateUserMedia(args.data); + case IPC_FUNCTIONS.GET_IMAGE_DATA: + return captureUtility.getImageData(args.data); + case IPC_FUNCTIONS.SET_APPERANCE: + return captureUtility.setApperance(args.data); + default: + return null; + } +}); + +ipcMain.handle(IPC_HANDLERS.WINDOW, async (event, args) => { + switch (args.func) { case IPC_FUNCTIONS.OPEN_ADD_WINDOW: - return captureUtility.openAddWindow(args.data); + return windowUtility.openAddWindow(args.data); case IPC_FUNCTIONS.CLOSE_ADD_WINDOW: - return captureUtility.closeAddWindow(args.data); + return windowUtility.closeAddWindow(args.data); case IPC_FUNCTIONS.OPEN_EDIT_WINDOW: - return captureUtility.openEditWindow(args.data); + return windowUtility.openEditWindow(args.data); case IPC_FUNCTIONS.CLOSE_EDIT_WINDOW: - return captureUtility.closeEditWindow(args.data); + return windowUtility.closeEditWindow(args.data); case IPC_FUNCTIONS.OPEN_SETTING_WINDOW: - return captureUtility.openSettingWindow(args.data); + return windowUtility.openSettingWindow(args.data); case IPC_FUNCTIONS.CLOSE_SETTING_WINDOW: - return captureUtility.closeSettingWindow(args.data); + return windowUtility.closeSettingWindow(args.data); case IPC_FUNCTIONS.OPEN_MINIMIZE_WINDOW: - return captureUtility.openMinimizeWindow(args.data); + return windowUtility.openMinimizeWindow(args.data); case IPC_FUNCTIONS.CLOSE_MINIMIZE_WINDOW: - return captureUtility.closeMinimizeWindow(args.data); + return windowUtility.closeMinimizeWindow(args.data); + case IPC_FUNCTIONS.CLOSE_SESSION_AND_MINIIMIZED_WINDOW: + return windowUtility.closeSessionAndMinimizedWindow(args.data); case IPC_FUNCTIONS.SET_WINDOW_SIZE: - return captureUtility.setWindowSize(args.data); - case IPC_FUNCTIONS.GET_IMAGE_DATA: - return captureUtility.getImageData(args.data); - case IPC_FUNCTIONS.SET_APPERANCE: - return captureUtility.setApperance(args.data); + return windowUtility.setWindowSize(args.data); + case IPC_FUNCTIONS.OPEN_MODAL_WINDOW: + return windowUtility.openModalWindow(args.data); + case IPC_FUNCTIONS.CLOSE_MODAL_WINDOW: + return windowUtility.closeModalWindow(args.data); case IPC_FUNCTIONS.OPEN_NOTES_WINDOW: console.log("handler", args.data); - return captureUtility.openNotesWindow(args.data); + return windowUtility.openNotesWindow(args.data); case IPC_FUNCTIONS.CLOSE_NOTES_WINDOW: - return captureUtility.closeNotesWindow(); + return windowUtility.closeNotesWindow(); + case IPC_FUNCTIONS.MOVE_WINDOW: + return windowUtility.moveWindow(args.data); default: return null; } @@ -70,6 +86,8 @@ ipcMain.handle(IPC_HANDLERS.DATABASE, async (event, args) => { switch (args.func) { case IPC_FUNCTIONS.INITIALIZE_SESSION: return databaseUtility.initializeSession(); + case IPC_FUNCTIONS.ADD_ITEM: + return databaseUtility.addItem(args.data); case IPC_FUNCTIONS.GET_ITEMS: return databaseUtility.getItems(); case IPC_FUNCTIONS.UPDATE_ITEMS: diff --git a/src/modules/MenuUtility.js b/src/modules/MenuUtility.js index e6f6eafe..7c2f217a 100644 --- a/src/modules/MenuUtility.js +++ b/src/modules/MenuUtility.js @@ -4,20 +4,20 @@ const { SESSION_STATUSES } = require("./constants"); module.exports.changeMenuItemStatus = ({ sessionStatus }) => { const mainMenu = Menu.getApplicationMenu(); - const fileMenu = mainMenu.items.find((item) => item.label === "File"); + const fileMenu = mainMenu.items.find((item) => item.id === "menu_file"); const fileSubMenus = fileMenu.submenu.items; if (sessionStatus === SESSION_STATUSES.PENDING) { - fileSubMenus.find((item) => item.label === "Save Session").enabled = false; + fileSubMenus.find((item) => item.id === "menu_save_session").enabled = false; fileSubMenus.find( - (item) => item.label === "Save As Test Charter" + (item) => item.id === "menu_save_as_charter" ).enabled = false; - fileSubMenus.find((item) => item.label === "Reset Session").enabled = false; + fileSubMenus.find((item) => item.id === "menu_reset_session").enabled = false; } else { - fileSubMenus.find((item) => item.label === "Save Session").enabled = true; + fileSubMenus.find((item) => item.id === "menu_save_session").enabled = true; fileSubMenus.find( - (item) => item.label === "Save As Test Charter" + (item) => item.id === "menu_save_as_charter" ).enabled = true; - fileSubMenus.find((item) => item.label === "Reset Session").enabled = true; + fileSubMenus.find((item) => item.id === "menu_reset_session").enabled = true; } }; diff --git a/src/modules/WindowUtility.js b/src/modules/WindowUtility.js new file mode 100644 index 00000000..3b8a2d2f --- /dev/null +++ b/src/modules/WindowUtility.js @@ -0,0 +1,382 @@ +const { app, BrowserWindow, screen } = require("electron"); + +let addWin, editWin, settingsWin, notesWin, modalWin; + +const browserUtility = require("./BrowserWindowUtility"); +const path = require("path"); + +const { VIEW_MODE, IPC_BIND_KEYS } = require("./constants"); + +module.exports.getMainWindow = () => { + const win = new BrowserWindow({ + width: 800, + height: 600, + minWidth: 800, + minHeight: 600, + center: true, + icon: path.join(__dirname, "../public/logo.png"), + webPreferences: { + // Use pluginOptions.nodeIntegration, leave this alone + // See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info + nodeIntegration: true, + webSecurity: false, + contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION, + enableRemoteModule: true, + preload: path.join(app.getAppPath(), "preload.js"), + }, + }); + + return win; +}; + +module.exports.openMinimizeWindow = (data) => { + const browserWindow = browserUtility.getBrowserWindow(); + const minimizedWindow = browserUtility.getMinimizedWindow(); + + const url = + process.env.NODE_ENV === "development" + ? "http://localhost:8080/#/minimize" + : `file://${__dirname}/index.html#minimize`; + + if (!minimizedWindow || minimizedWindow.isDestroyed) { + let display = screen.getPrimaryDisplay(); + let displayWidth = display.bounds.width; + let minimizeWin = new BrowserWindow({ + width: 480, + height: 84, + minWidth: 480, + minHeight: 84, + x: displayWidth - 480, + y: 50, + frame: false, + transparent: true, + resizable: false, + icon: path.join(__dirname, "../public/logo.png"), + webPreferences: { + devTools: false, + nodeIntegration: true, + webSecurity: false, + enableRemoteModule: true, + preload: path.join(app.getAppPath(), "preload.js"), + }, + }); + + // let minimizeWin = new BrowserWindow({ + // width: 800, + // height: 600, + // minWidth: 800, + // minHeight: 600, + // center: true, + // icon: path.join(__dirname, "../public/logo.png"), + // webPreferences: { + // // Use pluginOptions.nodeIntegration, leave this alone + // // See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info + // nodeIntegration: true, + // webSecurity: false, + // contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION, + // enableRemoteModule: true, + // preload: path.join(app.getAppPath(), "preload.js"), + // }, + // }); + + minimizeWin.loadURL(url); + minimizeWin.setMenuBarVisibility(false); + minimizeWin.setAlwaysOnTop(true); + + minimizeWin.once("ready-to-show", () => { + // minimizeWin.webContents.openDevTools(); + minimizeWin.webContents.send("STATE_DATA", data.data); + minimizeWin.show(); + }); + + minimizeWin.on("close", () => { + minimizeWin = null; + browserUtility.setMinimizedWindow(null); + browserWindow.show(); + }); + + browserUtility.setMinimizedWindow(minimizeWin); + browserWindow.hide(); + } else { + browserWindow.hide(); + minimizedWindow.webContents.send("STATE_DATA", data.data); + minimizedWindow.show(); + } + + browserUtility.setViewMode(VIEW_MODE.MINI); +}; + +module.exports.closeMinimizeWindow = (data) => { + const browserWindow = browserUtility.getBrowserWindow(); + const minimizedWindow = browserUtility.getMinimizedWindow(); + minimizedWindow.close(); + browserWindow.webContents.send(data.bindKey, data.data); + browserUtility.setViewMode(VIEW_MODE.NORMAL); +}; + +module.exports.closeSessionAndMinimizedWindow = (data) => { + const browserWindow = browserUtility.getBrowserWindow(); + const minimizedWindow = browserUtility.getMinimizedWindow(); + minimizedWindow.hide(); + browserWindow.webContents.send(IPC_BIND_KEYS.END_SESSION, data.data); + browserWindow.show(); + browserUtility.setViewMode(VIEW_MODE.NORMAL); +}; + +module.exports.openAddWindow = ({ width, height, data }) => { + const parentWindow = browserUtility.getParentWindow(); + + const modalPath = + process.env.NODE_ENV === "development" + ? "http://localhost:8080/#/addSession" + : `file://${__dirname}/index.html#addSession`; + + if (!addWin) { + addWin = new BrowserWindow({ + width: width, + height: height, + minWidth: width, + minHeight: height, + center: true, + parent: parentWindow, + icon: path.join(__dirname, "../public/logo.png"), + webPreferences: { + devTools: true, + nodeIntegration: true, + webSecurity: false, + enableRemoteModule: true, + preload: path.join(app.getAppPath(), "preload.js"), + }, + }); + + addWin.loadURL(modalPath); + addWin.setMenuBarVisibility(false); + addWin.once("ready-to-show", () => { + addWin.webContents.openDevTools(); + addWin.show(); + + parentWindow.webContents.send("OPEN_CHILD_WINDOW"); + }); + + addWin.webContents.on("did-finish-load", () => { + addWin.webContents.send("ACTIVE_SESSION", data); + }); + + addWin.on("close", () => { + parentWindow.webContents.send("CLOSE_CHILD_WINDOW", { data: "add" }); + addWin = null; + }); + } +}; + +module.exports.closeAddWindow = () => { + addWin.close(); +}; + +module.exports.openEditWindow = (data) => { + const browserWindow = browserUtility.getBrowserWindow(); + const url = + process.env.NODE_ENV === "development" + ? "http://localhost:8080/#/editSession" + : `file://${__dirname}/index.html#editSession`; + + if (!editWin) { + editWin = new BrowserWindow({ + width: 800, + height: 800, + minWidth: 800, + minHeight: 800, + center: true, + parent: browserWindow, + icon: path.join(__dirname, "../public/logo.png"), + webPreferences: { + devTools: true, + nodeIntegration: true, + webSecurity: false, + enableRemoteModule: true, + preload: path.join(app.getAppPath(), "preload.js"), + }, + }); + + editWin.loadURL(url); + editWin.setMenuBarVisibility(false); + + editWin.once("ready-to-show", () => { + editWin.webContents.openDevTools(); + editWin.show(); + browserWindow.webContents.send("OPEN_CHILD_WINDOW"); + }); + + editWin.webContents.on("did-finish-load", () => { + editWin.webContents.send("ACTIVE_SESSION", data); + }); + + editWin.on("close", () => { + browserWindow.webContents.send("CLOSE_CHILD_WINDOW", { data: "edit" }); + editWin = null; + }); + } +}; + +module.exports.closeEditWindow = () => { + editWin.close(); +}; + +module.exports.openSettingWindow = () => { + const browserWindow = browserUtility.getBrowserWindow(); + const url = + process.env.NODE_ENV === "development" + ? "http://localhost:8080/#/settings" + : `file://${__dirname}/index.html#settings`; + + if (!settingsWin) { + settingsWin = new BrowserWindow({ + width: 800, + height: 600, + minWidth: 800, + minHeight: 600, + center: true, + parent: browserWindow, + icon: path.join(__dirname, "../public/logo.png"), + webPreferences: { + devTools: true, + nodeIntegration: true, + webSecurity: false, + enableRemoteModule: true, + preload: path.join(app.getAppPath(), "preload.js"), + }, + }); + + settingsWin.loadURL(url); + settingsWin.setMenuBarVisibility(false); + + settingsWin.once("ready-to-show", () => { + settingsWin.webContents.openDevTools(); + settingsWin.show(); + browserWindow.webContents.send("OPEN_CHILD_WINDOW"); + }); + + settingsWin.on("close", () => { + browserWindow.webContents.send("CLOSE_CHILD_WINDOW", { data: "setting" }); + settingsWin = null; + }); + } +}; + +module.exports.closeSettingWindow = () => { + settingsWin.close(); +}; + +module.exports.setWindowSize = ({ width, height, minWidth, minHeight }) => { + const browserWindow = browserUtility.getBrowserWindow(); + browserWindow.setSize(width, height); + browserWindow.setMinimumSize(minWidth, minHeight); + browserWindow.center(); +}; + +module.exports.openModalWindow = (data) => { + const parentWindow = browserUtility.getParentWindow(); + const url = + process.env.NODE_ENV === "development" + ? `http://localhost:8080/#/${data.path}` + : `file://${__dirname}/index.html#${data.path}`; + + if (!modalWin) { + modalWin = new BrowserWindow({ + width: data.size.width, + height: data.size.height, + minWidth: data.size.minWidth, + minHeight: data.size.minHeight, + center: true, + parent: parentWindow, + resizable: false, + icon: path.join(__dirname, "../public/logo.png"), + webPreferences: { + devTools: true, + nodeIntegration: true, + webSecurity: false, + enableRemoteModule: true, + preload: path.join(app.getAppPath(), "preload.js"), + }, + }); + + modalWin.loadURL(url); + modalWin.setMenuBarVisibility(false); + + modalWin.once("ready-to-show", () => { + modalWin.webContents.openDevTools(); + modalWin.webContents.send(IPC_BIND_KEYS.MODAL_DATA, data.data); + modalWin.show(); + parentWindow.webContents.send("OPEN_CHILD_WINDOW"); + }); + + modalWin.on("close", () => { + parentWindow.webContents.send("CLOSE_CHILD_WINDOW"); + modalWin = null; + }); + } +}; + +module.exports.closeModalWindow = (data) => { + if (data) { + const parentWindow = browserUtility.getParentWindow(); + parentWindow.webContents.send(data.bindKey, data.data); + } + modalWin.close(); +}; + +module.exports.openNotesWindow = (data) => { + const browserWindow = browserUtility.getBrowserWindow(); + const modalPath = + process.env.NODE_ENV === "development" + ? "http://localhost:8080/#/note" + : `file://${__dirname}/index.html#note`; + + if (!notesWin) { + notesWin = new BrowserWindow({ + width: data.width, + height: data.height, + minWidth: data.width, + minHeight: data.height, + center: true, + parent: browserWindow, + icon: path.join(__dirname, "../public/logo.png"), + webPreferences: { + devTools: true, + nodeIntegration: true, + webSecurity: false, + enableRemoteModule: true, + preload: path.join(app.getAppPath(), "preload.js"), + }, + }); + + notesWin.loadURL(modalPath); + notesWin.setMenuBarVisibility(false); + notesWin.once("ready-to-show", () => { + notesWin.webContents.openDevTools(); + notesWin.show(); + browserWindow.webContents.send("OPEN_CHILD_WINDOW"); + }); + + notesWin.webContents.on("did-finish-load", () => {}); + + notesWin.on("close", () => { + browserWindow.webContents.send("CLOSE_CHILD_WINDOW", { data: "notes" }); + notesWin = null; + }); + } +}; + +module.exports.closeNotesWindow = () => { + notesWin.close(); +}; + +module.exports.moveWindow = (data) => { + const minimizeWindow = browserUtility.getMinimizedWindow(); + + const currentPosition = minimizeWindow.getPosition(); + minimizeWindow.setPosition( + currentPosition[0] + data.x, + currentPosition[1] + data.y + ); +}; diff --git a/src/modules/constants.js b/src/modules/constants.js index 285b143f..49e44206 100644 --- a/src/modules/constants.js +++ b/src/modules/constants.js @@ -4,6 +4,7 @@ export const IPC_HANDLERS = { FILE_SYSTEM: "fileSystem", STORE: "store", MENU: "menu", + WINDOW: "window", }; export const IPC_FUNCTIONS = { @@ -28,13 +29,18 @@ export const IPC_FUNCTIONS = { CLOSE_SETTING_WINDOW: "closeSettingWindow", OPEN_MINIMIZE_WINDOW: "openMinimizeWindow", CLOSE_MINIMIZE_WINDOW: "closeMinimizeWindow", + CLOSE_SESSION_AND_MINIIMIZED_WINDOW: "closeSessionAndMinimizedWindow", + OPEN_MODAL_WINDOW: "openModalWindow", + CLOSE_MODAL_WINDOW: "closeModalWindow", SET_WINDOW_SIZE: "setWindowSize", GET_IMAGE_DATA: "getImageData", SET_APPERANCE: "setApperance", OPEN_NOTES_WINDOW: "openNotesWindow", CLOSE_NOTES_WINDOW: "closeNotesWindow", + MOVE_WINDOW: "moveWindow", INITIALIZE_SESSION: "initializeSession", + ADD_ITEM: "addItem", GET_ITEMS: "getItems", UPDATE_ITEMS: "updateItems", DELETE_ITEMS: "deleteItems", @@ -54,6 +60,16 @@ export const IPC_FUNCTIONS = { CHANGE_MENUITEM_STATUS: "changeMenuItemStatus", }; +export const IPC_BIND_KEYS = { + CLOSED_NOTE_DIALOG: "note_dialog_closed", + CLOSED_SUMMARY_DIALOG: "summary_dialog_closed", + MODAL_DATA: "modal_data", + END_SESSION: "end_session", + CLOSED_MINIMIZE_WINDOW: "minimize_window_closed", + CLOSED_ENDSESSION_DIALOG: "endsession_dialog_closed", + CLOSED_SOURCEPICKER_DIALOG: "sourcepicker_dialog_closed", +}; + export const STATUSES = { SUCCESS: "success", ERROR: "error", @@ -78,6 +94,11 @@ export const SESSION_TYPES = [ "Mindmap", ]; +export const VIEW_MODE = { + NORMAL: "normal", + MINI: "minimized", +}; + export const TEXT_TYPES = [ "Comment", "Problem", diff --git a/src/router/index.js b/src/router/index.js index 603198f8..8afa5517 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -24,6 +24,11 @@ import TemplateTab from "@/components/settings/TemplateTab.vue"; import ConfigCheckListTab from "@/components/settings/ConfigCheckListTab.vue"; import ReportsTab from "@/components/settings/ReportsTab.vue"; +import NoteEidtorview from "../views/NoteEditorView.vue"; +import SummaryEditorView from "../views/SummaryEditorView.vue"; +import EndSessionView from "../views/EndSessionView.vue"; +import SourcePickerView from "../views/SourcePickerView.vue"; + Vue.use(VueRouter); const routes = [ @@ -145,6 +150,26 @@ const routes = [ meta: { layout: "minimize" }, component: MinimizeView, }, + { + path: "/noteEditor", + name: "noteEditor", + component: NoteEidtorview, + }, + { + path: "/summaryEditor", + name: "summaryEditor", + component: SummaryEditorView, + }, + { + path: "/endsession", + name: "endsession", + component: EndSessionView, + }, + { + path: "/sourcepicker", + name: "sourcePicker", + component: SourcePickerView, + }, ]; const router = new VueRouter({ diff --git a/src/views/AddSession.vue b/src/views/AddSession.vue index bd82f5d8..1e30b9ab 100644 --- a/src/views/AddSession.vue +++ b/src/views/AddSession.vue @@ -196,7 +196,7 @@ export default { func: IPC_FUNCTIONS.DELETE_FILE, data: { filePath: this.item.poster }, }); - window.ipc.invoke(IPC_HANDLERS.CAPTURE, { + window.ipc.invoke(IPC_HANDLERS.WINDOW, { func: IPC_FUNCTIONS.CLOSE_ADD_WINDOW, }); }, @@ -219,7 +219,7 @@ export default { data: this.items, }) .then(() => { - window.ipc.invoke(IPC_HANDLERS.CAPTURE, { + window.ipc.invoke(IPC_HANDLERS.WINDOW, { func: IPC_FUNCTIONS.CLOSE_ADD_WINDOW, }); }); diff --git a/src/views/EditSession.vue b/src/views/EditSession.vue index 28563b2f..87c1da03 100644 --- a/src/views/EditSession.vue +++ b/src/views/EditSession.vue @@ -157,7 +157,7 @@ export default { handleDiscard() { if (!window.ipc) return; - window.ipc.invoke(IPC_HANDLERS.CAPTURE, { + window.ipc.invoke(IPC_HANDLERS.WINDOW, { func: IPC_FUNCTIONS.CLOSE_EDIT_WINDOW, }); }, @@ -182,16 +182,18 @@ export default { return temp; }); - window.ipc - .invoke(IPC_HANDLERS.DATABASE, { - func: IPC_FUNCTIONS.UPDATE_ITEMS, - data: this.items, - }) - .then(() => { - window.ipc.invoke(IPC_HANDLERS.CAPTURE, { - func: IPC_FUNCTIONS.CLOSE_EDIT_WINDOW, + if (window.ipc) { + window.ipc + .invoke(IPC_HANDLERS.DATABASE, { + func: IPC_FUNCTIONS.UPDATE_ITEMS, + data: this.items, + }) + .then(() => { + window.ipc.invoke(IPC_HANDLERS.WINDOW, { + func: IPC_FUNCTIONS.CLOSE_EDIT_WINDOW, + }); }); - }); + } }, }, }; diff --git a/src/views/EndSessionView.vue b/src/views/EndSessionView.vue new file mode 100644 index 00000000..b0b0f41c --- /dev/null +++ b/src/views/EndSessionView.vue @@ -0,0 +1,118 @@ + + + diff --git a/src/views/MainView.vue b/src/views/MainView.vue index 186094f4..0e66b6a2 100644 --- a/src/views/MainView.vue +++ b/src/views/MainView.vue @@ -59,7 +59,7 @@ " :selectedItems="selected" :checkedStatusOfPreSessionTask="checkedStatusOfPreSessionTask" - :postSessionData="postsession" + view-mode="normal" />
@@ -233,7 +233,7 @@ export default { // this.updateItems(); }, openEditWindow(data) { - window.ipc.invoke(IPC_HANDLERS.CAPTURE, { + window.ipc.invoke(IPC_HANDLERS.WINDOW, { func: IPC_FUNCTIONS.OPEN_EDIT_WINDOW, data: data, }); diff --git a/src/views/MinimizeView.vue b/src/views/MinimizeView.vue index 13c0d062..ef5ad239 100644 --- a/src/views/MinimizeView.vue +++ b/src/views/MinimizeView.vue @@ -1,77 +1,121 @@ diff --git a/src/views/ResultView.vue b/src/views/ResultView.vue index 54bf551c..3a70a1ce 100644 --- a/src/views/ResultView.vue +++ b/src/views/ResultView.vue @@ -76,6 +76,7 @@ :selectedItems="selected" :items="items" :configItem="config" + view-mode="normal" />
diff --git a/src/views/SourcePickerView.vue b/src/views/SourcePickerView.vue new file mode 100644 index 00000000..d22f15fe --- /dev/null +++ b/src/views/SourcePickerView.vue @@ -0,0 +1,183 @@ + + + diff --git a/src/views/SummaryEditorView.vue b/src/views/SummaryEditorView.vue new file mode 100644 index 00000000..fd8cfd2c --- /dev/null +++ b/src/views/SummaryEditorView.vue @@ -0,0 +1,125 @@ + + + diff --git a/vue.config.js b/vue.config.js index 58cb457e..7cd77c6d 100644 --- a/vue.config.js +++ b/vue.config.js @@ -14,6 +14,8 @@ module.exports = { "src/modules/CaptureUtility.js", "src/modules/DatabaseUtility.js", "src/modules/FileSystemUtility.js", + "src/modules/MenuUtility.js", + "src/modules/WindowUtility.js", ], builderOptions: { productName: "YATTIE",