added `Tips` screen

pull/2/head
Michael Ochmann 3 years ago
parent 280a4f5a50
commit 6683223a49
  1. 1
      src/Ation.js
  2. 2
      src/ui/src/assets/css/_forms.scss
  3. 1
      src/ui/src/assets/css/_slide.scss
  4. 1
      src/ui/src/assets/css/_slidesList.scss
  5. 46
      src/ui/src/assets/css/_tips.scss
  6. 1
      src/ui/src/assets/css/_window.scss
  7. 1
      src/ui/src/assets/css/ation.scss
  8. 7
      src/ui/src/components/Ation.js
  9. 26
      src/ui/src/components/KeyboardControl.js
  10. 33
      src/ui/src/components/Tips.js
  11. 7
      src/ui/src/components/Toolbar.js

@ -15,7 +15,6 @@ class Ation {
app.whenReady().then(async () => { app.whenReady().then(async () => {
protocol.registerFileProtocol("slideimg", (request, callback) => { protocol.registerFileProtocol("slideimg", (request, callback) => {
const path = request.url.replace(/^slideimg:\/\//, ""); const path = request.url.replace(/^slideimg:\/\//, "");
console.log(path);
callback(path); callback(path);
}); });
}); });

@ -1,5 +1,6 @@
button { button {
border: none; border: none;
outline: 0 !important;
background: color(scrollbar); background: color(scrollbar);
color: color(foreground); color: color(foreground);
padding: 0.5rem 2rem; padding: 0.5rem 2rem;
@ -20,6 +21,7 @@ button {
svg { svg {
margin-right: 0.3rem; margin-right: 0.3rem;
vertical-align: middle; vertical-align: middle;
color: color(hightlight);
} }
} }

@ -5,7 +5,6 @@
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
user-select: none;
padding: 8vw; padding: 8vw;
text-align: center; text-align: center;
aspect-ratio: 1.333; aspect-ratio: 1.333;

@ -14,6 +14,7 @@
.slide { .slide {
width: 100vw; width: 100vw;
height: auto; height: auto;
user-select: none;
margin: 5% 0 0 5%; margin: 5% 0 0 5%;
aspect-ratio: 1.333; aspect-ratio: 1.333;
-webkit-transform-origin: top left; -webkit-transform-origin: top left;

@ -0,0 +1,46 @@
.tips {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
left: 0;
width: 100vw;
user-select: none;
height: 100vh;
z-index: 2000;
background: rgba(0,0,0,0.5);
backdrop-filter: blur(6px);
.inner {
background: color(mainBackground);
box-shadow: 0 0 2rem rgba(0,0,0,0.6);
text-transform: uppercase;
width: 80%;
height: 70%;
max-width: 800px;
max-height: 600px;
border-radius: 1rem;
padding: 0 4rem;
text-align: center;
opacity: 0.9;
h1 {
font-family: "Iosevka", sans-serif;
font-weight: normal;
font-size: 2rem;
}
article {
display: grid;
grid-template-columns: 3fr 1fr;
text-align: left;
line-height: 2rem;
kbd {
font-size: 1rem;
text-align: right;
}
}
}
}

@ -27,6 +27,7 @@
& > .slide:first-child { & > .slide:first-child {
position: absolute; position: absolute;
margin: 0; margin: 0;
user-select: none;
top: 0; top: 0;
left: 0; left: 0;
width: 100vw; width: 100vw;

@ -7,6 +7,7 @@
@import "window"; @import "window";
@import "noFile"; @import "noFile";
@import "tips";
@import "slidesList"; @import "slidesList";
@import "slide"; @import "slide";
@import "blackout"; @import "blackout";

@ -7,6 +7,7 @@ import KeyboardControl from "./KeyboardControl";
import Blackout from "./Blackout"; import Blackout from "./Blackout";
import NoFile from "./NoFile"; import NoFile from "./NoFile";
import Toolbar from "./Toolbar"; import Toolbar from "./Toolbar";
import Tips from "./Tips";
import SlideContext from "../shared/SlideContext"; import SlideContext from "../shared/SlideContext";
@ -15,6 +16,7 @@ const Ation = () => {
const [deck, setDeck] = useState([]); const [deck, setDeck] = useState([]);
const [slide, setSlide] = useState(0); const [slide, setSlide] = useState(0);
const [basePath, setBasePath] = useState(""); const [basePath, setBasePath] = useState("");
const [showTips, setShowTips] = useState(false);
const openFile = async () => { const openFile = async () => {
const [basePath, slideDeck] = await window.api.openFile(); const [basePath, slideDeck] = await window.api.openFile();
@ -31,14 +33,15 @@ const Ation = () => {
return ( return (
<SlideContext.Provider value={{slide, setSlide, mode, setMode, basePath}}> <SlideContext.Provider value={{slide, setSlide, mode, setMode, basePath}}>
<section className={`window${mode === Mode.PRESENT ? " fullscreen" : ""}`}> <section className={`window${mode === Mode.PRESENT ? " fullscreen" : ""}`}>
<Toolbar openFile={openFile} /> <Toolbar openFile={openFile} setShowTips={setShowTips} />
<SlidesList deck={deck} /> <SlidesList deck={deck} />
<main className="main"> <main className="main">
<Slide data={deck[slide] || null} /> <Slide data={deck[slide] || null} />
</main> </main>
<Tips show={showTips} />
</section> </section>
<Blackout show={mode === Mode.BLACKOUT} /> <Blackout show={mode === Mode.BLACKOUT} />
<KeyboardControl mode={mode} setMode={setMode} deck={deck} openFile={openFile} /> <KeyboardControl mode={mode} setMode={setMode} deck={deck} openFile={openFile} setShowTips={setShowTips} />
</SlideContext.Provider> </SlideContext.Provider>
); );
}; };

@ -1,12 +1,22 @@
import {useContext, useEffect} from "react"; import {useContext, useEffect, version} from "react";
import SlideContext from "../shared/SlideContext"; import SlideContext from "../shared/SlideContext";
import Mode from "../models/Mode"; import Mode from "../models/Mode";
const KeyboardControl = ({openFile, mode, setMode, deck}) => { const KeyboardControl = ({openFile, mode, setMode, deck, setShowTips}) => {
const {slide, setSlide} = useContext(SlideContext); const {slide, setSlide} = useContext(SlideContext);
useEffect(() => { useEffect(() => {
const keyUpHandler = event => {
switch(event.key) {
case "Tab":
setShowTips(false);
break;
default:
return;
}
}
const keyHandler = event => { const keyHandler = event => {
switch(event.key) { switch(event.key) {
case "o": case "o":
@ -15,9 +25,9 @@ const KeyboardControl = ({openFile, mode, setMode, deck}) => {
openFile(); openFile();
break; break;
default: default:
console.log(event.key); break;
} }
if (!mode || !setMode || !deck) if (!mode || !setMode || !deck || !setShowTips)
return; return;
switch (event.key) { switch (event.key) {
@ -45,6 +55,10 @@ const KeyboardControl = ({openFile, mode, setMode, deck}) => {
return; return;
setMode(mode === Mode.BLACKOUT ? Mode.PRESENT : Mode.BLACKOUT); setMode(mode === Mode.BLACKOUT ? Mode.PRESENT : Mode.BLACKOUT);
break; break;
case "Tab":
event.preventDefault();
setShowTips(true);
break;
default: default:
return; return;
} }
@ -56,14 +70,16 @@ const KeyboardControl = ({openFile, mode, setMode, deck}) => {
}; };
window.addEventListener("keydown", keyHandler); window.addEventListener("keydown", keyHandler);
window.addEventListener("keyup", keyUpHandler);
window.addEventListener("fullscreenchange", fullscreenHandler); window.addEventListener("fullscreenchange", fullscreenHandler);
return () => { return () => {
window.removeEventListener("keydown", keyHandler); window.removeEventListener("keydown", keyHandler);
window.removeEventListener("keyup", keyUpHandler);
window.removeEventListener("fullscreenchange", fullscreenHandler); window.removeEventListener("fullscreenchange", fullscreenHandler);
} }
}, [slide, setSlide, mode, setMode, deck]); }, [slide, setSlide, mode, setMode, deck, setShowTips, openFile]);
}; };
export default KeyboardControl; export default KeyboardControl;

@ -0,0 +1,33 @@
import React, {Fragment} from "react";
const Cheatsheet = Object.freeze([
["Start presentation", "F5"],
["Stop presentation", "ESC"],
["Open file", "Ctrl+O"],
["Next slide", "→, Page up"],
["Last slide", "←, Page down"],
["Black screen out", "B"],
["Show/Hide tips", "TAB"]
]);
const Tips = ({show}) => {
return (
show ?
<section className="tips">
<section className="inner">
<h1>Cheatsheet</h1>
<article>
{Cheatsheet.map(([description, key]) => (
<Fragment key={key}>
<label>{description}</label>
<kbd>{key}</kbd>
</Fragment>
))}
</article>
</section>
</section>
: null
);
};
export default Tips;

@ -1,11 +1,11 @@
import React, {useContext} from "react"; import React, {useContext} from "react";
import {Folder2Open, Cast} from "react-bootstrap-icons"; import {Folder2Open, Cast, InfoCircle} from "react-bootstrap-icons";
import SlideContext from "../shared/SlideContext"; import SlideContext from "../shared/SlideContext";
import Mode from "../models/Mode"; import Mode from "../models/Mode";
const Toolbar = ({openFile}) => { const Toolbar = ({openFile, setShowTips}) => {
const {setMode, setSlide} = useContext(SlideContext); const {setMode, setSlide} = useContext(SlideContext);
const present = () => { const present = () => {
@ -16,8 +16,9 @@ const Toolbar = ({openFile}) => {
return ( return (
<nav className="toolbar"> <nav className="toolbar">
<button onClick={openFile} title="Open file"><Folder2Open /></button> <button onClick={openFile} title="Open file [Ctrl+O]"><Folder2Open /></button>
<button onClick={present} title="Start presentation [F5]"><Cast /></button> <button onClick={present} title="Start presentation [F5]"><Cast /></button>
<button onClick={() => setShowTips(true)} title="Show tips [TAB]"><InfoCircle /></button>
</nav> </nav>
); );
}; };

Loading…
Cancel
Save