From 77cfa255274fdcdf822e836c7ea98e769bcb865d Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Wed, 6 Oct 2021 15:27:31 +0200 Subject: mobile --- src/views/App.js | 2 ++ src/views/Clock.js | 4 +-- src/views/Clocks.js | 4 +-- src/views/Detail.js | 45 ++++++++++++++++++++++----- src/views/Gallery.js | 9 ++++-- src/views/Graph.js | 16 +++++----- src/views/Intro.js | 26 ++++++++++------ src/views/LandscapeWarning.js | 72 +++++++++++++++++++++++++++++++++++++++++++ src/views/Legend.js | 2 +- 9 files changed, 148 insertions(+), 32 deletions(-) create mode 100644 src/views/LandscapeWarning.js (limited to 'src/views') diff --git a/src/views/App.js b/src/views/App.js index 1a3ca42..0458d1a 100644 --- a/src/views/App.js +++ b/src/views/App.js @@ -8,6 +8,7 @@ import { MTLLoader, OBJLoader } from "@hbis/three-obj-mtl-loader"; import Graph from "./Graph.js"; import Intro from "./Intro.js"; +import LandscapeWarning from "./LandscapeWarning.js"; export default function App() { const [db, setDb] = useState(null); @@ -27,6 +28,7 @@ export default function App() { <> {intro && } {!intro && db && } + ); } diff --git a/src/views/Clock.js b/src/views/Clock.js index fe5039a..de0026b 100644 --- a/src/views/Clock.js +++ b/src/views/Clock.js @@ -46,7 +46,7 @@ const minuteTransform = const secondTransform = "translateX(10.2vw) translateY(11.5vw) translateX(-100%) translateY(-100%) "; -export default function Clock({ utc }) { +export default function Clock({ utc, onLoad }) { const [hour, setHour] = useState({}); const [minute, setMinute] = useState({}); const [second, setSecond] = useState({}); @@ -90,7 +90,7 @@ export default function Clock({ utc }) { return (
- +
diff --git a/src/views/Clocks.js b/src/views/Clocks.js index d984f7b..133a70d 100644 --- a/src/views/Clocks.js +++ b/src/views/Clocks.js @@ -5,10 +5,10 @@ import React from "react"; import Clock from "./Clock.js"; -export default function Clocks() { +export default function Clocks({ onLoad }) { return (
- +
); diff --git a/src/views/Detail.js b/src/views/Detail.js index 772abb1..fb17c06 100644 --- a/src/views/Detail.js +++ b/src/views/Detail.js @@ -2,7 +2,7 @@ * Detail view, displaying text plus media */ -import React from "react"; +import React, { useRef, useEffect, useState, useCallback } from "react"; import Gallery from "./Gallery.js"; import Clocks from "./Clocks.js"; @@ -10,15 +10,45 @@ import Vimeo from "@u-wave/react-vimeo"; import { pad } from "../utils/index.js"; export default function Detail({ node, visible, onClose }) { + const ref = useRef(); + const contentRef = useRef(); + const [videoReady, setVideoReady] = useState(false); + + useEffect(() => { + if (!node) { + setVideoReady(false); + } + setTimeout(() => { + ref.current.scrollTo(0, -ref.current.scrollHeight); + if (contentRef.current) { + contentRef.current.scrollTo(0, -ref.current.scrollHeight); + } + }, 10); + }, [node]); + + const handleVideoReady = useCallback(() => { + if (node.data.object) { + setTimeout(() => { + setVideoReady(true); + }, 500); + } else { + setVideoReady(true); + } + }, [node]); + + const handleLoad = useCallback(() => { + ref.current.scrollTo(0, -ref.current.scrollHeight); + }); + if (!node) { - return
; + return
; } const { id, data } = node; const index = id + 1; return ( -
-
+
+
{pad(index)}
@@ -42,10 +72,10 @@ export default function Detail({ node, visible, onClose }) {
{index === 33 ? ( - + ) : data.type === "video" ? ( visible && ( -
+
) ) : ( - + )}
diff --git a/src/views/Gallery.js b/src/views/Gallery.js index e2652df..7681e3b 100644 --- a/src/views/Gallery.js +++ b/src/views/Gallery.js @@ -5,7 +5,7 @@ import React, { useState, useEffect } from "react"; import { mod } from "../utils/index.js"; -export default function Gallery({ images, visible }) { +export default function Gallery({ images, visible, onLoad }) { const hasItems = !!images?.length; const oneItem = images?.length === 1; @@ -15,26 +15,31 @@ export default function Gallery({ images, visible }) { setIndex(0); setOpacity(0); setTimeout(() => setOpacity(1), 500); + onLoad(); }, [images]); function previous() { setOpacity(0); + onLoad(); setTimeout(() => setIndex(mod(index - 1, images.length)), 200); // setTimeout(() => setOpacity(1), 500); } function next() { setOpacity(0); + onLoad(); setTimeout(() => setIndex(mod(index + 1, images.length)), 200); // setTimeout(() => setOpacity(1), 500); } function nextOrWrap() { if (oneItem) return; setOpacity(0); + onLoad(); setTimeout(() => setIndex(mod(index + 1, images.length)), 200); // setTimeout(() => setOpacity(1), 500); } function appear() { setOpacity(1); + onLoad(); } if (!hasItems) { @@ -53,7 +58,7 @@ export default function Gallery({ images, visible }) { /> )}
-
+
{!oneItem && ( { - setGraph( - buildGraph({ - db, - handlers: { - click: handleClick, - }, - }) - ); + const graph = buildGraph({ + db, + handlers: { + click: handleClick, + }, + }); + setGraph(graph); setTimeout(() => { setIntroCurtainDone(true); + graph.onLoad(); setTimeout(() => { setIntroDone(true); }, 4000); diff --git a/src/views/Intro.js b/src/views/Intro.js index bf52d33..d27d34b 100644 --- a/src/views/Intro.js +++ b/src/views/Intro.js @@ -18,6 +18,13 @@ export default function Intro({ onComplete }) { }, 200); }, []); + const handleReady = useCallback((player) => { + setPlayer(player); + if (playing) { + player.play(); + } + }, []); + return (
{ setPlaying(true); - player.play(); + player && player.play(); }} /> + {playing && ( + + )}
); } -/* - - */ - const coverWindow = () => { const videoRatio = 1.777; const screenRatio = window.innerWidth / window.innerHeight; diff --git a/src/views/LandscapeWarning.js b/src/views/LandscapeWarning.js new file mode 100644 index 0000000..389e8a6 --- /dev/null +++ b/src/views/LandscapeWarning.js @@ -0,0 +1,72 @@ +/** + * Instruction to rotate the phone to landscape + */ + +import React, { Component } from "react"; + +import { isMobile, isiPhone } from "../utils/index.js"; + +const PhoneIcon = ( + + + +); + +const RotateIcon = ( + + + +); + +export default class LandscapeWarning extends Component { + state = { + landscape: !isMobile || window.innerWidth > window.innerHeight, + }; + + constructor(props) { + super(props); + this.handleResize = this.handleResize.bind(this); + if (isMobile) { + window.addEventListener("resize", this.handleResize); + setTimeout(this.handleResize, 100); + } + } + + handleResize() { + const landscape = !isMobile || window.innerWidth > window.innerHeight; + if (landscape !== this.state.landscape) { + this.setState({ landscape }); + } + } + + render() { + const { landscape } = this.state; + if (landscape) return null; + return ( +
+ {RotateIcon} + {PhoneIcon} + {isiPhone && ( +
+ {"Please tap "} + A + {"A and Hide Toolbar"} +
+ {"then rotate your device."} +
+ )} + {!isiPhone && ( +
{"Please rotate your device"}
+ )} +
+ ); + } +} diff --git a/src/views/Legend.js b/src/views/Legend.js index eac860c..bb56490 100644 --- a/src/views/Legend.js +++ b/src/views/Legend.js @@ -21,7 +21,7 @@ var categories = [ export default function Legend({ visible, selected, onSelect }) { return ( -
+
{selected && (
onSelect(selected)}> {"View all"} -- cgit v1.2.3-70-g09d2