added the ability to close a file

feature/settings-window
Michael Ochmann 3 years ago
parent ed9a15333e
commit 53c8a79171
  1. 12
      contextAPI.js
  2. 19
      src/Ation.js
  3. 7
      src/MainMenu.js
  4. 7
      src/ui/src/components/Ation.js
  5. 5
      src/ui/src/components/Toolbar.js
  6. 11
      src/ui/src/shared/SlideContext.js

@ -2,7 +2,8 @@
const {contextBridge, ipcRenderer, webFrame} = require("electron"); const {contextBridge, ipcRenderer, webFrame} = require("electron");
let fileOpenListener = null; let fileOpenListener = null;
let closeFileListener = null;
contextBridge.exposeInMainWorld("api", { contextBridge.exposeInMainWorld("api", {
openFileDialog : () => ipcRenderer.send("WindowManager::openFileDialog"), openFileDialog : () => ipcRenderer.send("WindowManager::openFileDialog"),
@ -12,9 +13,14 @@ contextBridge.exposeInMainWorld("api", {
fileOpenListener = (_, presentation) => callback(presentation); fileOpenListener = (_, presentation) => callback(presentation);
ipcRenderer.on("Ation::openFile", fileOpenListener); ipcRenderer.on("Ation::openFile", fileOpenListener);
}, },
onFileClose : callback => {
if (closeFileListener)
ipcRenderer.off("Ation::closeFile", closeFileListener);
closeFileListener = () => callback();
ipcRenderer.on("Ation::closeFile", closeFileListener);
},
openFile : filePath => ipcRenderer.send("WindowManager::openFile", filePath), openFile : filePath => ipcRenderer.send("WindowManager::openFile", filePath),
closeFile : () => ipcRenderer.send("Ation::closeFile"),
removeOnFileOpenListener : callback => ipcRenderer.off("Ation::openFile", callback),
clearCache : () => webFrame.clearCache(), clearCache : () => webFrame.clearCache(),
appVersion : async () => await ipcRenderer.invoke("Ation::appVersion") appVersion : async () => await ipcRenderer.invoke("Ation::appVersion")

@ -1,8 +1,8 @@
"use strict"; "use strict";
const {app, protocol, dialog, ipcMain} = require("electron"); const {app, protocol, dialog, ipcMain, Menu} = require("electron");
const path = require("path"); const path = require("path");
const fs = require("fs/promises"); const fs = require("fs/promises");
const fsn = require("fs"); const fsn = require("fs");
const AppInfo = require("../package.json"); const AppInfo = require("../package.json");
const WindowManager = require("./WindowManager"); const WindowManager = require("./WindowManager");
@ -30,6 +30,7 @@ class Ation {
}); });
ipcMain.handle("Ation::appVersion", () => AppInfo.version); ipcMain.handle("Ation::appVersion", () => AppInfo.version);
ipcMain.on("Ation::closeFile", () => this.closeFile());
app.whenReady().then(async () => { app.whenReady().then(async () => {
if (this.fileToOpen) if (this.fileToOpen)
@ -79,12 +80,22 @@ class Ation {
else else
this.openFile(this.currentFile, true); this.openFile(this.currentFile, true);
}); });
Menu.getApplicationMenu().getMenuItemById("close-file").enabled = this.currentFile !== "";
this.windowManager.mainWindow.send("Ation::openFile", [basePath, data]); this.windowManager.mainWindow.send("Ation::openFile", [basePath, data]);
} catch (error) { } catch (error) {
console.log(error); console.log(error);
return; return;
} }
} }
closeFile() {
this.currentFile = "";
if (this.watcher)
this.watcher.close();
this.watcher = null;
this.windowManager.mainWindow.send("Ation::closeFile");
Menu.getApplicationMenu().getMenuItemById("close-file").enabled = this.currentFile !== "";
}
} }
Ation.Instances = 0; Ation.Instances = 0;

@ -22,6 +22,13 @@ class MainMenu {
label : "Open", label : "Open",
accelerator : "CommandOrControl+O", accelerator : "CommandOrControl+O",
click : () => this.app.openFile() click : () => this.app.openFile()
},
{
id : "close-file",
label : "Close",
accelerator : "CommandOrControl+W",
click : () => this.app.closeFile(),
enabled : this.app.currentFile !== ""
} }
] ]
}, },

@ -30,6 +30,11 @@ const Ation = () => {
setBasePath(newBasePath); setBasePath(newBasePath);
setDeck(slideDeck); setDeck(slideDeck);
}); });
window.api.onFileClose(() => {
setBasePath("");
setSlide(0);
setDeck([]);
});
(async set => set(await window.api.appVersion()))(setVersion); (async set => set(await window.api.appVersion()))(setVersion);
}, [basePath, slide]); }, [basePath, slide]);
@ -42,7 +47,7 @@ const Ation = () => {
{deck.length < 1 ? {deck.length < 1 ?
<NoFile openFile={openFile} /> <NoFile openFile={openFile} />
: ( : (
<SlideContext.Provider value={{slide, setSlide, mode, setMode, basePath}}> <SlideContext.Provider value={{slide, setSlide, mode, setMode, basePath, slideCount : deck.length}}>
<section className={`window${mode === Mode.PRESENT ? " fullscreen" : ""}`}> <section className={`window${mode === Mode.PRESENT ? " fullscreen" : ""}`}>
<Toolbar openFile={openFile} setShowTips={setShowTips} version={version} /> <Toolbar openFile={openFile} setShowTips={setShowTips} version={version} />
<SlidesList deck={deck} /> <SlidesList deck={deck} />

@ -1,6 +1,6 @@
import React, {useContext} from "react"; import React, {useContext} from "react";
import {Folder2Open, Cast, InfoCircle} from "react-bootstrap-icons"; import {Folder2Open, Cast, InfoCircle, XSquare} from "react-bootstrap-icons";
import SlideContext from "../shared/SlideContext"; import SlideContext from "../shared/SlideContext";
import Mode from "../models/Mode"; import Mode from "../models/Mode";
@ -8,7 +8,7 @@ import Mode from "../models/Mode";
import {ReactComponent as Logo} from "../assets/images/logo_ation.svg"; import {ReactComponent as Logo} from "../assets/images/logo_ation.svg";
const Toolbar = ({openFile, setShowTips, version}) => { const Toolbar = ({openFile, setShowTips, version}) => {
const {setMode, setSlide} = useContext(SlideContext); const {setMode, setSlide, slideCount} = useContext(SlideContext);
const present = () => { const present = () => {
setMode(Mode.PRESENT); setMode(Mode.PRESENT);
@ -21,6 +21,7 @@ const Toolbar = ({openFile, setShowTips, version}) => {
<button onClick={openFile} title="Open file [⌘+O]"><Folder2Open /></button> <button onClick={openFile} title="Open file [⌘+O]"><Folder2Open /></button>
<button onClick={present} title="Start presentation [F5]"><Cast /></button> <button onClick={present} title="Start presentation [F5]"><Cast /></button>
<Logo /> <Logo />
<button onClick={() => window.api.closeFile()} title="Close file [⌘+W]" disabled={slideCount < 1}><XSquare /></button>
<button onClick={() => setShowTips(true)} title="Show tips [TAB]"><InfoCircle /></button> <button onClick={() => setShowTips(true)} title="Show tips [TAB]"><InfoCircle /></button>
<small>v{version}</small> <small>v{version}</small>
</nav> </nav>

@ -3,11 +3,12 @@ import {createContext} from "react";
import Mode from "../models/Mode"; import Mode from "../models/Mode";
const SlideContext = createContext({ const SlideContext = createContext({
slide : 0, slide : 0,
mode : Mode.NORMAL, slideCount : 0,
basePath : "", mode : Mode.NORMAL,
setMode : () => {}, basePath : "",
setSlide : () => {} setMode : () => {},
setSlide : () => {}
}); });
export default SlideContext; export default SlideContext;
Loading…
Cancel
Save