Skip to content

Commit

Permalink
support ipad
Browse files Browse the repository at this point in the history
  • Loading branch information
hjyssg committed Feb 7, 2019
1 parent 6fe82ed commit eb3cf2e
Show file tree
Hide file tree
Showing 11 changed files with 137 additions and 66 deletions.
5 changes: 5 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
"react-visibility-sensor": "^5.0.2",
"string-hash": "^1.1.3",
"underscore": "^1.9.1",
"universal-cookie": "^3.0.7"
"universal-cookie": "^3.0.7",
"whatwg-fetch": "^3.0.0"
},
"devDependencies": {
"@babel/core": "^7.0.0",
Expand Down
2 changes: 1 addition & 1 deletion src/cleanCache.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ folders1.forEach(p1 => {
//nothing
}else if(stat.isDirectory()){
const subfiles = fs.readdirSync(p1);
subfiles.sort((a, b) => a.firstname.localeCompare(b.firstname))
subfiles.sort((a, b) => a.localeCompare(b));
if(subfiles.length > 3){
for(let ii = 2; ii < subfiles.length; ii++){
del(path.resolve(p1, subfiles[ii]));
Expand Down
7 changes: 4 additions & 3 deletions src/client/ExplorerPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@ import ErrorPage from './ErrorPage';
import Pagination from 'rc-pagination';
import FileChangeToolbar from './subcomponent/FileChangeToolbar';
import Spinner from './subcomponent/Spinner';
const PER_PAGE = 4 * 5;
const util = require("../util");

export default class ExplorerPage extends Component {
constructor(prop) {
super(prop);
this.state = { pageIndex: 1 };
this.failedTimes = 0;
this.perPage = util.getPerPageItemNumber();
}

getHash() {
Expand Down Expand Up @@ -133,7 +134,7 @@ export default class ExplorerPage extends Component {
//! !todo if the file is already an image file

files = files.filter(_.isCompress);
files = files.slice((this.state.pageIndex-1) * PER_PAGE, (this.state.pageIndex) * PER_PAGE);
files = files.slice((this.state.pageIndex-1) * this.perPage, (this.state.pageIndex) * this.perPage);

const zipfileItems = files.map((item) => {
const text = _.getFn(item);
Expand Down Expand Up @@ -194,7 +195,7 @@ export default class ExplorerPage extends Component {
}

return (<Pagination current={this.state.pageIndex}
pageSize={PER_PAGE}
pageSize={this.perPage}
total={fileLength}
onChange={this.handlePageChange.bind(this)} />);
}
Expand Down
71 changes: 41 additions & 30 deletions src/client/LoadingImage.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ import PropTypes from 'prop-types';
import loading from './images/loading.png';
import notAvailable from './images/not-available.png';
import Sender from './Sender';
import ImageLoader from 'react-image-file';
// const VisibilitySensor = require('react-visibility-sensor').default;

const VisibilitySensor = require('react-visibility-sensor').default;

export default class LoadingImage extends Component {
Expand All @@ -28,40 +25,50 @@ export default class LoadingImage extends Component {
}

onChange(isVisible){
if(isVisible && !this.state.loaded & !this.loading){
const {mode} = this.props;
const api = (mode === "author" || mode === "tag") ? "/api/tagFirstImagePath" : '/api/firstImage';
const body = {};
const {onChange, url, mode, fileName} = this.props;

if(mode === "author" || mode === "tag"){
body[mode] = this.props.fileName;
}else{
body["fileName"] = this.props.fileName;
}
if(isVisible){
onChange && onChange();
}

this.loading = true;
if(isVisible && !this.state.loaded & !this.loading){
if(url){
this.url = url;
this.setState({ loaded: true });
} else {
const api = (mode === "author" || mode === "tag") ? "/api/tagFirstImagePath" : '/api/firstImage';
const body = {};

fetch(api, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(body)
})
.then((res) => res.blob())
.then((res) => {
if(!this.isUnmounted){
this.url = URL.createObjectURL(res);
this.setState({ loaded: true });
if(mode === "author" || mode === "tag"){
body[mode] = fileName;
}else{
body["fileName"] = fileName;
}
});

this.loading = true;

fetch(api, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(body)
})
.then((res) => res.blob())
.then((res) => {
if(!this.isUnmounted){
this.url = URL.createObjectURL(res);
this.setState({ loaded: true });
}
});
}
}
}

render() {
let content;
const {className, fileName} = this.props;
const {className, fileName, url, bottomOffet, topOffet} = this.props;
const cn = "loading-image " + className;
let active = true;
if (this.state.failed) {
Expand All @@ -76,8 +83,8 @@ export default class LoadingImage extends Component {
return (
<VisibilitySensor
active={active}
key={fileName}
offset={{bottom:-500, top: -500}}
key={fileName||url}
offset={{bottom: bottomOffet || -200, top: topOffet || -200}}
onChange={this.onChange.bind(this)}>
{content}
</VisibilitySensor>
Expand All @@ -89,4 +96,8 @@ LoadingImage.propTypes = {
fileName: PropTypes.string,
className: PropTypes.string,
mode: PropTypes.string,
url: PropTypes.string, //predefined url, not request from this component,
bottomOffet: PropTypes.number,
topOffet: PropTypes.number,
onChange: PropTypes.func
};
76 changes: 49 additions & 27 deletions src/client/OneBook.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const spop = require("./subcomponent/spop");
import FileChangeToolbar from './subcomponent/FileChangeToolbar';
var classNames = require('classnames');
var dateFormat = require('dateformat');
import LoadingImage from './LoadingImage';

export default class OneBook extends Component {
constructor(props) {
Expand Down Expand Up @@ -61,7 +62,9 @@ export default class OneBook extends Component {

if (!res.failed) {
this.loadedHash = this.getHash();
this.setState({ files: res.files || [], index: 0, path:res.path, fileStat: res.stat });
let files = res.files || [];
files.sort((a, b) => a.localeCompare(b));
this.setState({ files: files, index: 0, path:res.path, fileStat: res.stat });
document.addEventListener('keydown', this.handleKeyDown.bind(this));
}else{
this.failTimes++;
Expand Down Expand Up @@ -109,36 +112,71 @@ export default class OneBook extends Component {
this.changePage(index);
}

renderFileList() {
const { files, index } = this.state;
const listItems = files.map((item) => (<li className="one-book-image-li" key={item}><img className="one-book-image" src={"../"+item} alt="book-image"/></li>));
return (<ul className="one-book-list">{listItems}</ul>);
}


isFailedLoading(){
return this.res && this.res.failed;
}

renderPagination() {
if(_.isPad()){ return; }
const { files, index } = this.state;
const isLast = index+1 === files.length;
const text = (index+1) + "/" + files.length;
const cn = classNames("one-book-foot-index-number", {
"is-last": isLast
})

return <div className={cn}>{text}</div>;
}

renderFileSizeAndTime(){
if(this.state.fileStat){
if (this.state.fileStat) {
const size = Math.ceil(this.state.fileStat.size/ 1000000.0) + "MB";
const mTime = dateFormat(this.state.fileStat.mtime, "isoDate");;
const text = mTime + " :: " + size;
return <div className={"file-stat"}>{text} </div>
}
}

renderImage(){
const { files, index } = this.state;
if(!_.isPad()){
return <img className="one-book-image" src={"../" + files[index]} alt="book-image"
onClick={this.next.bind(this)}
onContextMenu={this.prev.bind(this)}
index={index}
/>
} else {
const images = files.map(file => {
return <LoadingImage className={"mobile-one-book-image"}
bottomOffet={-4000}
topOffet={-3000}
url={"../" +file}
key={file}/>
});

return (<div className="mobile-one-book-container">
{images}
</div>);
}
}

renderPath() {
if (!this.state.path) {
return;
}

const parentPath = _.getDir(this.state.path);
const parentHash = stringHash(parentPath);
const toUrl = ('/explorer/'+ parentHash);
const toolbar = !_.isPad() && <FileChangeToolbar className="one-book-toolbar" file={this.state.path}/>;

return (
<div className="one-book-path">
<Link to={toUrl}>{parentPath} </Link>
{toolbar}
</div>);
}

render() {
if (this.isFailedLoading()) {
return <ErrorPage res={this.res.res}/>;
Expand Down Expand Up @@ -172,10 +210,6 @@ export default class OneBook extends Component {
</div>);
})

const parentPath = _.getDir(this.state.path);
const parentHash = stringHash(parentPath);
const toUrl =('/explorer/'+ parentHash);

if(this.state.path){
document.title = _.getFn(this.state.path);
}
Expand All @@ -184,26 +218,14 @@ export default class OneBook extends Component {
<div className="one-book-container">
<div className="one-book-wrapper">
<div className="one-book-title"><center>{_.getFn(this.state.path)}</center></div>
<img className="one-book-image" src={"../" + files[index]} alt="book-image"
onClick={this.next.bind(this)}
onContextMenu={this.prev.bind(this)}
index={index}
/>
{this.renderImage()}
</div>
{this.renderPagination()}
<div className="one-book-footer">
{tagDivs}
</div>
{this.state.path &&
<div className="one-book-path">
<Link to={toUrl}>{parentPath} </Link>
<FileChangeToolbar className="one-book-toolbar" file={this.state.path} />
</div>
}
{this.renderPath()}
{this.renderFileSizeAndTime()}
{/* {
this.state.path && <FileChangeToolbar className="one-book-toolbar" file={this.state.path} />
} */}
</div>
);
}
Expand Down
1 change: 1 addition & 0 deletions src/client/Sender.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import _ from "underscore";
import 'whatwg-fetch';

const Sender = {};

Expand Down
8 changes: 5 additions & 3 deletions src/client/TagPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ import ErrorPage from './ErrorPage';
import Spinner from './subcomponent/Spinner'
import Pagination from 'rc-pagination';
import { Redirect } from 'react-router-dom';
const PER_PAGE = 4 * 5;

const util = require("../util");

export default class TagPage extends Component {
constructor(prop) {
super(prop);
this.state = { tags: [], sortByNumber: true };
this.perPage = util.getPerPageItemNumber();
}

get pageIndex(){
Expand Down Expand Up @@ -67,7 +69,7 @@ export default class TagPage extends Component {
keys.sort((a, b) => items[b] - items[a]);
}

keys = keys.slice((this.pageIndex-1) * PER_PAGE, this.pageIndex * PER_PAGE);
keys = keys.slice((this.pageIndex-1) * this.perPage, this.pageIndex * this.perPage);

const tagItems = keys.map((tag) => {
const itemText = `${tag} (${items[tag]})`;
Expand Down Expand Up @@ -114,7 +116,7 @@ export default class TagPage extends Component {
}

return (<Pagination current={this.pageIndex}
pageSize={PER_PAGE}
pageSize={this.perPage}
total={this.getItemLength()}
onChange={this.handlePageChange.bind(this)} />);
}
Expand Down
13 changes: 12 additions & 1 deletion src/client/style/OneBook.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
text-align: center;
font-size: 3rem;
position: fixed;
left: 45%;
left: 40%;
top: 50%;
}

Expand Down Expand Up @@ -52,6 +52,17 @@
z-index: 10;
}

.mobile-one-book-image{
// width: 95%;
width: calc(100% - 10px);
margin:1px 5px;

}

.mobile-one-book-container{
width: 100%;
}

.one-book-footer {
display: flex;
justify-content: flex-start;
Expand Down
Loading

0 comments on commit eb3cf2e

Please sign in to comment.