diff --git a/client/pages/viewerpage/audioplayer.js b/client/pages/viewerpage/audioplayer.js index 6d22a14d..340f85b0 100644 --- a/client/pages/viewerpage/audioplayer.js +++ b/client/pages/viewerpage/audioplayer.js @@ -1,25 +1,18 @@ -import React from "react"; +import React, { useState, useEffect, useLayoutEffect } from "react"; import WaveSurfer from "wavesurfer.js"; import { MenuBar } from "./menubar"; import { NgIf, Icon } from "../../components/"; import "./audioplayer.scss"; -export class AudioPlayer extends React.Component { - constructor(props) { - super(props); - this.state = { - wafesurfer: null, - loading: true, - isPlaying: true, - error: null, - }; - this.toggle = this.toggle.bind(this); - window.addEventListener("keypress", this.toggle); - } +export function AudioPlayer({ filename, data }) { + const [isPlaying, setIsPlaying] = useState(false); + const [isLoading, setIsLoading] = useState(true); + const [wavesurfer, setWavesurfer] = useState(null); + const [error, setError] = useState(null); - componentDidMount() { - const wavesurfer = WaveSurfer.create({ + useLayoutEffect(() => { + const _ws = WaveSurfer.create({ container: "#waveform", waveColor: "#323639", progressColor: "#6f6f6f", @@ -28,81 +21,75 @@ export class AudioPlayer extends React.Component { height: 250, barWidth: 1, }); - this.setState({ wavesurfer: wavesurfer }); - wavesurfer.on("ready", () => { - this.setState({ loading: false }); - if (this.state.isPlaying === true) { - wavesurfer.play(); - } + + _ws.on("ready", () => { + setIsLoading(false); }); - wavesurfer.on("error", (err) => { - this.setState({ error: err, loading: false }); + _ws.on("error", (err) => { + setIsLoading(false); + setError(err) }); - wavesurfer.load(this.props.data); - } + _ws.load(data); + setWavesurfer(_ws); + return () => _ws.destroy(); + }, []); - componentWillUnmount() { - if (this.state.wavesurfer) { - this.state.wavesurfer.destroy(); + useEffect(() => { + if(wavesurfer === null) return; + window.addEventListener("keypress", onKeyPressHandler); + return () => window.removeEventListener("keypress", onKeyPressHandler); + }, [wavesurfer, isPlaying]) + + const onKeyPressHandler = (e) => { + if(e.code !== "Space") { + return } - window.removeEventListener("keypress", this.toggle); - } + isPlaying ? onPause(e) : onPlay(e); + }; - toggle() { - if (this.state.isPlaying === true) { - this.setState({ isPlaying: false }); - this.state.wavesurfer.pause(); - } else { - this.setState({ isPlaying: true }); - this.state.wavesurfer.play(); - } - } - - onPlay(e) { + const onPlay = (e) => { e.preventDefault(); e.stopPropagation(); - this.setState({ isPlaying: true }); - this.state.wavesurfer.play(); + wavesurfer.play(); + setIsPlaying(true); } - onPause(e) { + const onPause = (e) => { e.preventDefault(); e.stopPropagation(); - this.setState({ isPlaying: false }); - this.state.wavesurfer.pause(); + wavesurfer.pause(); + setIsPlaying(false); } - render() { - return ( -
- -
- - {this.state.error} + return ( +
+ +
+ + {error} + + + + - - - - -
-
- - - - - - - - - - -
-
+
+
+ + + + + + + + + +
- -
+
+
+
- ); - } +
+ ) } diff --git a/client/pages/viewerpage/audioplayer.scss b/client/pages/viewerpage/audioplayer.scss index 45998300..8693eb93 100644 --- a/client/pages/viewerpage/audioplayer.scss +++ b/client/pages/viewerpage/audioplayer.scss @@ -33,6 +33,7 @@ right: 10px; z-index: 2; height: 30px; + width: 30px; > div { display: inline; diff --git a/client/pages/viewerpage/filedownloader.js b/client/pages/viewerpage/filedownloader.js index c6dca52f..4f81ca6a 100644 --- a/client/pages/viewerpage/filedownloader.js +++ b/client/pages/viewerpage/filedownloader.js @@ -1,46 +1,38 @@ -import React from "react"; +import React, { useState, useEffect } from "react"; import { NgIf, Icon } from "../../components/"; import "./filedownloader.scss"; import { t } from "../../locales/"; -export class FileDownloader extends React.Component { - constructor(props) { - super(props); - this.state = { loading: false, id: null }; - } - - onClick() { +export function FileDownloader({ filename, data }) { + const [isDownloading, setIsDownloading] = useState(false); + const onClick = () => { document.cookie = "download=yes; path=/; max-age=60;"; - this.setState({ - loading: true, - id: window.setInterval(function() { - if (/download=yes/.test(document.cookie) === false) { - this.setState({ loading: false }); - window.clearInterval(this.state.id); - } - }.bind(this), 80), - }); - } + setIsDownloading(true); + }; - componentWillUnmount() { - window.clearInterval(this.state.id); - } + useEffect(() => { + if(!isDownloading) return; + const t = setInterval(() => { + if (/download=yes/.test(document.cookie) === false) { + setIsDownloading(false); + } + }, 250); + return () => clearInterval(t); + }, [isDownloading]); - render() { - return ( -
-
- - - { t("DOWNLOAD") } - - - - + return ( + - ); - } +
+ ); } diff --git a/client/pages/viewerpage/formviewer.js b/client/pages/viewerpage/formviewer.js index b96d416f..77ace0a4 100644 --- a/client/pages/viewerpage/formviewer.js +++ b/client/pages/viewerpage/formviewer.js @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useState } from "react"; import ReactCSSTransitionGroup from "react-addons-css-transition-group"; import { MenuBar } from "./menubar"; @@ -6,41 +6,25 @@ import { Container, FormBuilder, NgIf, Icon, Fab } from "../../components/"; import { appendShareToUrl } from "../../helpers/"; import "./formviewer.scss"; -export class FormViewer extends React.Component { - constructor(props) { - super(props); - this.state = { - form: {}, - }; - } +export function FormViewer({ + filename, data, content, + needSaving, isSaving, needSavingUpdate, onSave, +}) { + const [form, setForm] = useState(JSON.parse(content)); - componentDidMount() { - this.setState({ - form: JSON.parse(this.props.content), - }); - } + const onFormChange = () => { + JSON.stringify(form) === content ? needSavingUpdate(false) : needSavingUpdate(true); + }; - onChange() { - this.setState({ refresh: Math.random() }); - if (JSON.stringify(this.state.form) === this.props.content) { - this.props.needSavingUpdate(false); - } else { - this.props.needSavingUpdate(true); - } - } - - save() { - if (this.props.needSaving === false) return; + const onClickSave = () => { + if (needSaving === false) return; const blob = new window.Blob([ - JSON.stringify(this.state.form), + JSON.stringify(form), ], { type: "text/plain" }); + return onSave(blob).then(() => needSavingUpdate(false)); + }; - return this.props - .onSave(blob) - .then(() => this.props.needSavingUpdate(false)); - } - - simpleMarkdown(text) { + const simpleMarkdown = (text) => { const regLink = /\[([^\]]*)\]\(([^\)]+)\)/g; return text .replace(regLink, function(str) { @@ -50,9 +34,9 @@ export class FormViewer extends React.Component { }) .replace(regLink, "$1") .replace(/\n/g, "
"); - } + }; - beautify(label) { + const beautify = (label) => { return label .split("_") .map((t) => { @@ -61,78 +45,77 @@ export class FormViewer extends React.Component { return t[0].toUpperCase() + t.substring(1); }) .join(" "); - } + }; - render() { - const renderForm = ($input, props, struct, onChange) => { - return ( -