diff --git a/package-lock.json b/package-lock.json
index 5b8489b8..1bcfa131 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9809,6 +9809,11 @@
"integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==",
"dev": true
},
+ "whatwg-fetch": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz",
+ "integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q=="
+ },
"which": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
diff --git a/package.json b/package.json
index 4d490e39..63f72328 100644
--- a/package.json
+++ b/package.json
@@ -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",
diff --git a/src/cleanCache.js b/src/cleanCache.js
index f41d78d7..eb29db68 100644
--- a/src/cleanCache.js
+++ b/src/cleanCache.js
@@ -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]));
diff --git a/src/client/ExplorerPage.js b/src/client/ExplorerPage.js
index be196a06..8f0a7f82 100644
--- a/src/client/ExplorerPage.js
+++ b/src/client/ExplorerPage.js
@@ -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() {
@@ -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);
@@ -194,7 +195,7 @@ export default class ExplorerPage extends Component {
}
return ();
}
diff --git a/src/client/LoadingImage.js b/src/client/LoadingImage.js
index 1e873f47..23779f49 100644
--- a/src/client/LoadingImage.js
+++ b/src/client/LoadingImage.js
@@ -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 {
@@ -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) {
@@ -76,8 +83,8 @@ export default class LoadingImage extends Component {
return (
{content}
@@ -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
};
diff --git a/src/client/OneBook.js b/src/client/OneBook.js
index 3e20b6a4..39894bf5 100644
--- a/src/client/OneBook.js
+++ b/src/client/OneBook.js
@@ -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) {
@@ -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++;
@@ -109,29 +112,24 @@ export default class OneBook extends Component {
this.changePage(index);
}
- renderFileList() {
- const { files, index } = this.state;
- const listItems = files.map((item) => (
));
- return ();
- }
-
+
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 {text}
;
}
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;
@@ -139,6 +137,46 @@ export default class OneBook extends Component {
}
}
+ renderImage(){
+ const { files, index } = this.state;
+ if(!_.isPad()){
+ return
+ } else {
+ const images = files.map(file => {
+ return
+ });
+
+ return (
+ {images}
+
);
+ }
+ }
+
+ renderPath() {
+ if (!this.state.path) {
+ return;
+ }
+
+ const parentPath = _.getDir(this.state.path);
+ const parentHash = stringHash(parentPath);
+ const toUrl = ('/explorer/'+ parentHash);
+ const toolbar = !_.isPad() && ;
+
+ return (
+
+ {parentPath}
+ {toolbar}
+
);
+ }
+
render() {
if (this.isFailedLoading()) {
return ;
@@ -172,10 +210,6 @@ export default class OneBook extends Component {
);
})
- const parentPath = _.getDir(this.state.path);
- const parentHash = stringHash(parentPath);
- const toUrl =('/explorer/'+ parentHash);
-
if(this.state.path){
document.title = _.getFn(this.state.path);
}
@@ -184,26 +218,14 @@ export default class OneBook extends Component {
{_.getFn(this.state.path)}
-

+ {this.renderImage()}
{this.renderPagination()}
{tagDivs}
- {this.state.path &&
-
- {parentPath}
-
-
- }
+ {this.renderPath()}
{this.renderFileSizeAndTime()}
- {/* {
- this.state.path &&
- } */}
);
}
diff --git a/src/client/Sender.js b/src/client/Sender.js
index 3cea6d33..5cfa223e 100644
--- a/src/client/Sender.js
+++ b/src/client/Sender.js
@@ -1,4 +1,5 @@
import _ from "underscore";
+import 'whatwg-fetch';
const Sender = {};
diff --git a/src/client/TagPage.js b/src/client/TagPage.js
index a362d400..952b91ff 100644
--- a/src/client/TagPage.js
+++ b/src/client/TagPage.js
@@ -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(){
@@ -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]})`;
@@ -114,7 +116,7 @@ export default class TagPage extends Component {
}
return ();
}
diff --git a/src/client/style/OneBook.scss b/src/client/style/OneBook.scss
index 9037c4f2..2d91fdac 100644
--- a/src/client/style/OneBook.scss
+++ b/src/client/style/OneBook.scss
@@ -2,7 +2,7 @@
text-align: center;
font-size: 3rem;
position: fixed;
- left: 45%;
+ left: 40%;
top: 50%;
}
@@ -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;
diff --git a/src/util.js b/src/util.js
index e77afc70..8067b8ce 100644
--- a/src/util.js
+++ b/src/util.js
@@ -24,9 +24,25 @@ module.exports.getFn = function (fn) {
return tokens[tokens.length - 1];
};
+const isPad = module.exports.isPad = function(){
+ // https://stackoverflow.com/questions/9038625/detect-if-device-is-ios
+ return /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
+}
+
+module.exports.getPerPageItemNumber = function() {
+ if(isPad()){
+ return 3 * 6;
+ }else{
+ return 4 * 5;
+ }
+}
+
module.exports.attach = function (obj) {
obj.isImage = module.exports.isImage;
obj.isCompress = module.exports.isCompress;
obj.getDir = module.exports.getDir;
obj.getFn = module.exports.getFn;
+ obj.isPad = module.exports.isPad;
+ obj.getPerPageItemNumber = module.exports.getPerPageItemNumber;
}
+
diff --git a/webpack.config.js b/webpack.config.js
index baeb5fb5..304c0c4a 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -40,6 +40,7 @@ module.exports = {
port: 3000,
open: false,
host: '0.0.0.0',
+ disableHostCheck: true,
historyApiFallback: true,
publicPath: "/",
proxy: {