mirror of
https://github.com/mickael-kerjean/filestash.git
synced 2025-11-01 10:56:31 +08:00
175 lines
6.3 KiB
JavaScript
175 lines
6.3 KiB
JavaScript
import React, { createRef } from "react";
|
|
import { Link, withRouter } from "react-router-dom";
|
|
|
|
import { Files } from "../../model/";
|
|
import { sort } from "../../pages/filespage.helper.js";
|
|
import { Icon, NgIf, EventReceiver, EventEmitter } from "../../components/";
|
|
import {
|
|
dirname, basename, settings_get, getMimeType, debounce, appendShareToUrl,
|
|
} from "../../helpers/";
|
|
import "./pager.scss";
|
|
|
|
class PagerComponent extends React.Component {
|
|
constructor(props) {
|
|
super(props);
|
|
this.state = {
|
|
files: [],
|
|
n: 0,
|
|
};
|
|
this.$page = createRef();
|
|
this.onKeyPress = this.onKeyPress.bind(this);
|
|
this.onSubmitDebounced = debounce(this.onFormSubmit.bind(this), 1000);
|
|
}
|
|
|
|
componentDidMount() {
|
|
this.setNavigation(this.props);
|
|
window.addEventListener("keyup", this.onKeyPress);
|
|
this.props.subscribe("media::next", () => {
|
|
this.navigatePage(this.calculateNextPageNumber(this.state.n));
|
|
});
|
|
this.props.subscribe("media::previous", () => {
|
|
this.navigatePage(this.calculatePrevPageNumber(this.state.n));
|
|
});
|
|
}
|
|
|
|
UNSAFE_componentWillReceiveProps(props) {
|
|
if (props.path !== this.props.path) {
|
|
this.setNavigation(props);
|
|
}
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
window.removeEventListener("keyup", this.onKeyPress);
|
|
this.props.unsubscribe("media::next");
|
|
this.props.unsubscribe("media::previous");
|
|
this.hasUnmounted = true;
|
|
}
|
|
|
|
navigatePage(n) {
|
|
if (this.state.files[n]) {
|
|
const url = appendShareToUrl(this.state.files[n].link);
|
|
if (this.$page && this.$page.current) this.$page.current.blur();
|
|
const preload_index = (
|
|
n >= this.state.n ||
|
|
(this.state.n === this.state.files.length - 1 && n === 0)
|
|
) ? this.calculateNextPageNumber(n) : this.calculatePrevPageNumber(n);
|
|
Files.url(this.state.files[preload_index].path)
|
|
.then((url) => this.props.emit("media::preload", url))
|
|
.then(() => setTimeout(() => this.props.history.push(url), 0))
|
|
.catch(() => {});
|
|
}
|
|
}
|
|
calculateNextPageNumber(n) {
|
|
if (n + 1 >= this.state.files.length) return 0;
|
|
return n + 1;
|
|
}
|
|
calculatePrevPageNumber(n) {
|
|
if (n <= 0) return this.state.files.length - 1;
|
|
return n - 1;
|
|
}
|
|
|
|
setNavigation(props) {
|
|
Files._ls_from_cache(dirname(props.path))
|
|
.then((f) => {
|
|
if (f === null) return Promise.reject({ code: "NO_DATA" });
|
|
return Promise.resolve(f);
|
|
})
|
|
.then((f) => f.results.filter((file) => {
|
|
if (file.type !== "file") return false;
|
|
const mType = getMimeType(file.name);
|
|
switch(mType.split("/")[0]) {
|
|
case "video": return true;
|
|
case "image": return true;
|
|
}
|
|
return false;
|
|
}))
|
|
.then((f) => sort(f, settings_get("filespage_sort") || "type"))
|
|
.then((f) => findPosition(f, basename(props.path)))
|
|
.then((res) => {
|
|
if (this.hasUnmounted === true) return;
|
|
if (this.props.pageChange) this.props.pageChange(res[0]);
|
|
this.setState({
|
|
files: res[0],
|
|
n: res[1],
|
|
});
|
|
})
|
|
.catch(() => {});
|
|
|
|
const findPosition = (files, filename) => {
|
|
let i;
|
|
for (i=0; i < files.length; i++) {
|
|
if (files[i].name === filename) {
|
|
break;
|
|
}
|
|
}
|
|
return [files, i];
|
|
};
|
|
}
|
|
|
|
onFormInputChange(e) {
|
|
let n = parseInt(e.target.value);
|
|
if (Number.isNaN(n)) n = undefined;
|
|
else if (n < 1) n = 0;
|
|
else if (n > this.state.files.length) n = this.state.files.length - 1;
|
|
else n = n - 1;
|
|
|
|
this.setState({ n: n });
|
|
if (n >= 0) {
|
|
this.onSubmitDebounced();
|
|
}
|
|
}
|
|
|
|
onFormSubmit(e) {
|
|
if (e) e.preventDefault();
|
|
this.navigatePage(this.state.n);
|
|
}
|
|
|
|
onKeyPress(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
if (e.target.classList.contains("prevent")) return;
|
|
if (e.keyCode === 39) {
|
|
this.navigatePage(this.calculateNextPageNumber(this.state.n));
|
|
} else if (e.keyCode === 37) {
|
|
this.navigatePage(this.calculatePrevPageNumber(this.state.n));
|
|
}
|
|
}
|
|
|
|
render() {
|
|
const inputWidth = this.state.n === undefined ?
|
|
12 : ((this.state.n + 1).toString().length) * 12;
|
|
const nextLink = () => {
|
|
const l = this.state.files[this.calculateNextPageNumber(this.state.n)];
|
|
return (((l && l.link) || "") + window.location.search) || "#";
|
|
};
|
|
const prevLink = () => {
|
|
const l = this.state.files[this.calculatePrevPageNumber(this.state.n)];
|
|
return (((l && l.link) || "") + window.location.search) || "#";
|
|
};
|
|
const current_page_number = this.state.n === undefined ? "" : this.state.n + 1;
|
|
return (
|
|
<div className="component_pager">
|
|
<div className="wrapper no-select">
|
|
<NgIf cond={this.state.files.length > 0} type="inline">
|
|
<Link to={prevLink()}><Icon name="arrow_left_white"/></Link>
|
|
<label className="pager">
|
|
<form onSubmit={this.onFormSubmit.bind(this)}>
|
|
<input
|
|
ref={this.$page} className="prevent" type="number"
|
|
style={{ width: inputWidth+"px" }}
|
|
onChange={this.onFormInputChange.bind(this)}
|
|
value={current_page_number} />
|
|
</form>
|
|
<span className="separator">/</span>
|
|
<span>{this.state.files.length}</span>
|
|
</label>
|
|
<Link to={nextLink()}><Icon name="arrow_right_white"/></Link>
|
|
</NgIf>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
export const Pager = EventEmitter(EventReceiver(withRouter(PagerComponent)));
|