mirror of
https://github.com/mickael-kerjean/filestash
synced 2025-12-15 12:55:41 +01:00
migration (component): move over to functional component
This commit is contained in:
parent
dec9e2f60d
commit
3a01b70681
5 changed files with 189 additions and 224 deletions
|
|
@ -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 (
|
||||
<div className="component_audioplayer">
|
||||
<MenuBar title={this.props.filename} download={this.props.data} />
|
||||
<div className="audioplayer_container">
|
||||
<NgIf cond={this.state.error !== null} className="audioplayer_error">
|
||||
{this.state.error}
|
||||
return (
|
||||
<div className="component_audioplayer">
|
||||
<MenuBar title={filename} download={data} />
|
||||
<div className="audioplayer_container">
|
||||
<NgIf cond={error !== null} className="audioplayer_error">
|
||||
{error}
|
||||
</NgIf>
|
||||
<NgIf cond={error === null}>
|
||||
<NgIf cond={isLoading === true}>
|
||||
<Icon name="loading" />
|
||||
</NgIf>
|
||||
<NgIf cond={this.state.error === null}>
|
||||
<NgIf cond={this.state.loading === true}>
|
||||
<Icon name="loading" />
|
||||
</NgIf>
|
||||
<div className="audioplayer_box"
|
||||
style={{ opacity: this.state.loading? "0" : "1" }}>
|
||||
<div className="audioplayer_control">
|
||||
<NgIf cond={this.state.isPlaying === false}>
|
||||
<span onClick={this.onPlay.bind(this)}>
|
||||
<Icon name="play"/>
|
||||
</span>
|
||||
</NgIf>
|
||||
<NgIf cond={this.state.isPlaying === true}>
|
||||
<span onClick={this.onPause.bind(this)}>
|
||||
<Icon name="pause"/>
|
||||
</span>
|
||||
</NgIf>
|
||||
</div>
|
||||
<div id="waveform"></div>
|
||||
<div className="audioplayer_box"
|
||||
style={{ opacity: isLoading? "0" : "1" }}>
|
||||
<div className="audioplayer_control">
|
||||
<NgIf cond={isPlaying === false}>
|
||||
<span onClick={onPlay}>
|
||||
<Icon name="play"/>
|
||||
</span>
|
||||
</NgIf>
|
||||
<NgIf cond={isPlaying === true}>
|
||||
<span onClick={onPause}>
|
||||
<Icon name="pause"/>
|
||||
</span>
|
||||
</NgIf>
|
||||
</div>
|
||||
</NgIf>
|
||||
</div>
|
||||
<div id="waveform"></div>
|
||||
</div>
|
||||
</NgIf>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
right: 10px;
|
||||
z-index: 2;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
|
||||
> div {
|
||||
display: inline;
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<div className="component_filedownloader">
|
||||
<div className="download_button">
|
||||
<a download={this.props.filename} href={this.props.data}>
|
||||
<NgIf onClick={this.onClick.bind(this)} cond={!this.state.loading}>
|
||||
{ t("DOWNLOAD") }
|
||||
</NgIf>
|
||||
</a>
|
||||
<NgIf cond={this.state.loading}>
|
||||
<Icon name="loading"/>
|
||||
return (
|
||||
<div className="component_filedownloader">
|
||||
<div className="download_button">
|
||||
<a download={filename} href={data}>
|
||||
<NgIf onClick={onClick} cond={!isDownloading}>
|
||||
{ t("DOWNLOAD") }
|
||||
</NgIf>
|
||||
</div>
|
||||
</a>
|
||||
<NgIf cond={isDownloading}>
|
||||
<Icon name="loading"/>
|
||||
</NgIf>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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, "<a href=\"$2\">$1</a>")
|
||||
.replace(/\n/g, "<br>");
|
||||
}
|
||||
};
|
||||
|
||||
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 (
|
||||
<label className={"no-select"}>
|
||||
<div>
|
||||
<span>
|
||||
{
|
||||
this.beautify(struct.label)
|
||||
}<span className="mandatory">{struct.required ? "*" : ""}</span>
|
||||
</span>
|
||||
<div style={{ width: "100%" }}>
|
||||
{ $input }
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<span className="nothing"></span>
|
||||
<div style={{ width: "100%" }}>
|
||||
{
|
||||
struct.description ? (
|
||||
<div
|
||||
className="description"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: this.simpleMarkdown(struct.description),
|
||||
}}
|
||||
/>
|
||||
) : null
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
);
|
||||
};
|
||||
const renderForm = ($input, props, struct, onChange) => {
|
||||
return (
|
||||
<div className="component_formviewer">
|
||||
<MenuBar title={this.props.filename} download={this.props.data} />
|
||||
<div className="formviewer_container">
|
||||
<Container>
|
||||
<form className="sticky box">
|
||||
<FormBuilder
|
||||
form={this.state.form}
|
||||
onChange={this.onChange.bind(this)}
|
||||
render={renderForm}
|
||||
/>
|
||||
</form>
|
||||
</Container>
|
||||
<ReactCSSTransitionGroup
|
||||
transitionName="fab" transitionLeave={true} transitionEnter={true}
|
||||
transitionAppear={true} transitionAppearTimeout={400}
|
||||
transitionEnterTimeout={400} transitionLeaveTimeout={200}>
|
||||
<NgIf key={this.props.needSaving} cond={this.props.needSaving}>
|
||||
<NgIf cond={!this.props.isSaving}>
|
||||
<Fab onClick={this.save.bind(this)}>
|
||||
<Icon
|
||||
name="save"
|
||||
style={{ height: "100%", width: "100%" }}
|
||||
/>
|
||||
</Fab>
|
||||
</NgIf>
|
||||
<NgIf cond={this.props.isSaving}>
|
||||
<Fab>
|
||||
<Icon
|
||||
name="loading"
|
||||
style={{ height: "100%", width: "100%" }}
|
||||
/>
|
||||
</Fab>
|
||||
</NgIf>
|
||||
</NgIf>
|
||||
</ReactCSSTransitionGroup>
|
||||
<label className={"no-select"}>
|
||||
<div>
|
||||
<span>
|
||||
{
|
||||
beautify(struct.label)
|
||||
}<span className="mandatory">{struct.required ? "*" : ""}</span>
|
||||
</span>
|
||||
<div style={{ width: "100%" }}>
|
||||
{ $input }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<span className="nothing"></span>
|
||||
<div style={{ width: "100%" }}>
|
||||
{
|
||||
struct.description ? (
|
||||
<div
|
||||
className="description"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: simpleMarkdown(struct.description),
|
||||
}}
|
||||
/>
|
||||
) : null
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="component_formviewer">
|
||||
<MenuBar title={filename} download={data} />
|
||||
<div className="formviewer_container">
|
||||
<Container>
|
||||
<form className="sticky box">
|
||||
<FormBuilder
|
||||
form={form}
|
||||
onChange={onFormChange}
|
||||
render={renderForm}
|
||||
/>
|
||||
</form>
|
||||
</Container>
|
||||
<ReactCSSTransitionGroup
|
||||
transitionName="fab" transitionLeave={true} transitionEnter={true}
|
||||
transitionAppear={true} transitionAppearTimeout={400}
|
||||
transitionEnterTimeout={400} transitionLeaveTimeout={200}>
|
||||
<NgIf key={needSaving} cond={needSaving}>
|
||||
<NgIf cond={!isSaving}>
|
||||
<Fab onClick={onClickSave}>
|
||||
<Icon
|
||||
name="save"
|
||||
style={{ height: "100%", width: "100%" }}
|
||||
/>
|
||||
</Fab>
|
||||
</NgIf>
|
||||
<NgIf cond={isSaving}>
|
||||
<Fab>
|
||||
<Icon
|
||||
name="loading"
|
||||
style={{ height: "100%", width: "100%" }}
|
||||
/>
|
||||
</Fab>
|
||||
</NgIf>
|
||||
</NgIf>
|
||||
</ReactCSSTransitionGroup>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,20 +9,22 @@ const PDFJSViewer = (props) => (
|
|||
</Bundle>
|
||||
);
|
||||
|
||||
|
||||
export const PDFViewer = ({ data, filename }) => {
|
||||
const ViewerComponent = "application/pdf" in navigator.mimeTypes ?
|
||||
<embed
|
||||
src={`${data}#toolbar=0`}
|
||||
type="application/pdf"
|
||||
style={{ height: "100%", width: "100%" }}>
|
||||
</embed> : <PDFJSViewer src={data} />;
|
||||
|
||||
export function PDFViewer({ filename, data }) {
|
||||
return (
|
||||
<div className="component_pdfviewer">
|
||||
<MenuBar title={filename} download={data} />
|
||||
<div className="pdfviewer_container">
|
||||
{ ViewerComponent }
|
||||
{
|
||||
"application/pdf" in navigator.mimeTypes ? (
|
||||
<embed
|
||||
src={`${data}#toolbar=0`}
|
||||
type="application/pdf"
|
||||
style={{ height: "100%", width: "100%" }}>
|
||||
</embed>
|
||||
) : (
|
||||
<PDFJSViewer src={data} />
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue