mirror of
https://github.com/mickael-kerjean/filestash.git
synced 2025-11-01 10:56:31 +08:00
improvement (UI): make the UI behave
This commit is contained in:
90
client/components/audio.js
Normal file
90
client/components/audio.js
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
import { Container, Icon, NgIf } from './';
|
||||||
|
import './audio.scss';
|
||||||
|
|
||||||
|
export class Audio extends React.Component {
|
||||||
|
constructor(props){
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
percent: 0,
|
||||||
|
state: 'play'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount(){
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
if(this.state.state === 'play'){
|
||||||
|
if(this.state.percent < 100){
|
||||||
|
this.setState({percent: this.state.percent + 0.1}, this.componentDidMount);
|
||||||
|
}else{
|
||||||
|
this.setState({percent: 0}, this.componentDidMount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onStateChange(new_state){
|
||||||
|
this.setState({state: new_state});
|
||||||
|
}
|
||||||
|
|
||||||
|
render(){
|
||||||
|
return (
|
||||||
|
<div className="component_audio">
|
||||||
|
<Container maxWidth={700}>
|
||||||
|
<div style={{display: 'flex'}}>
|
||||||
|
<Control state={this.state.state} onPlay={this.onStateChange.bind(this, 'play')} onPause={this.onStateChange.bind(this, 'pause')}/>
|
||||||
|
<Progress purcent={this.state.percent} />
|
||||||
|
<Volume />
|
||||||
|
<TrackInfo name="Cloudkicker - Let Yourself Be Huge - Explore, be curious" />
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Volume = (props) => {
|
||||||
|
return (
|
||||||
|
<div className="component_volume">
|
||||||
|
VOLUME
|
||||||
|
<div className="volume-controller-wrapper">
|
||||||
|
<div className="volume-controller">s</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Control = (props) => {
|
||||||
|
return (
|
||||||
|
<div className="component_control">
|
||||||
|
<NgIf cond={props.state === 'pause'} type="inline">
|
||||||
|
<Icon name="play" onClick={props.onPlay}/>
|
||||||
|
</NgIf>
|
||||||
|
<NgIf cond={props.state === 'play'} type="inline">
|
||||||
|
<Icon name="pause" onClick={props.onPause}/>
|
||||||
|
</NgIf>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Progress = (props) => {
|
||||||
|
return (
|
||||||
|
<div className="component_progress">
|
||||||
|
<div className="placeholder"></div>
|
||||||
|
<div className="progress-bar" style={{width: props.purcent+"%"}}></div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const TrackInfo = (props) => {
|
||||||
|
return (
|
||||||
|
<div className="component_trackinfo">
|
||||||
|
<div>
|
||||||
|
{props.name}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
60
client/components/audio.scss
Normal file
60
client/components/audio.scss
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
.component_audio{
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background: var(--super-light);
|
||||||
|
height: 40px;
|
||||||
|
bottom: 0;
|
||||||
|
border-top: 1px solid #e2e2e2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.component_progress{
|
||||||
|
width: 300px;
|
||||||
|
margin-top: 9px;
|
||||||
|
margin-left: 10px;
|
||||||
|
|
||||||
|
.placeholder{
|
||||||
|
width: 100%;
|
||||||
|
height: 2px;
|
||||||
|
background: #dadada;
|
||||||
|
}
|
||||||
|
.progress-bar{
|
||||||
|
height: 2px;
|
||||||
|
background: var(--primary);
|
||||||
|
position: relative;
|
||||||
|
top: -2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.component_control{
|
||||||
|
.component_icon {
|
||||||
|
height: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.component_trackinfo{
|
||||||
|
width: 300px;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
margin-left: 10px;
|
||||||
|
color: var(--light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.component_volume{
|
||||||
|
position: relative;
|
||||||
|
.volume-controller-wrapper{
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: -150px;
|
||||||
|
}
|
||||||
|
.volume-controller{
|
||||||
|
height: 150px;
|
||||||
|
width: 20px;
|
||||||
|
background: var(--super-light);
|
||||||
|
border: 1px solid #e2e2e2;
|
||||||
|
}
|
||||||
|
&:hover{
|
||||||
|
.volume-controller-wrapper{display: block;}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -16,6 +16,8 @@ export { Bundle } from './bundle';
|
|||||||
export { Modal } from './modal';
|
export { Modal } from './modal';
|
||||||
export { Prompt } from './prompt';
|
export { Prompt } from './prompt';
|
||||||
export { Alert } from './alert';
|
export { Alert } from './alert';
|
||||||
|
export { Audio } from './audio';
|
||||||
|
export { Video } from './video';
|
||||||
//export { Connect } from './connect';
|
//export { Connect } from './connect';
|
||||||
// Those are commented because they will delivered as a separate chunk
|
// Those are commented because they will delivered as a separate chunk
|
||||||
// export { Editor } from './editor';
|
// export { Editor } from './editor';
|
||||||
|
|||||||
27
client/components/video.js
Normal file
27
client/components/video.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
import { Icon, NgIf } from './';
|
||||||
|
import './video.scss';
|
||||||
|
|
||||||
|
|
||||||
|
export class Video extends React.Component {
|
||||||
|
constructor(props){
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
render(){
|
||||||
|
return (
|
||||||
|
<div className="component_video">
|
||||||
|
<div className="loader">
|
||||||
|
<Icon name="loading"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// <video autoPlay="true" width="300" height="200">
|
||||||
|
// <source src="https://www.w3schools.com/tags/movie.mp4" type="video/mp4" />
|
||||||
|
// </video>
|
||||||
15
client/components/video.scss
Normal file
15
client/components/video.scss
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
.component_video{
|
||||||
|
position: fixed;
|
||||||
|
bottom: 10px;
|
||||||
|
right: 10px;
|
||||||
|
width: 300px;
|
||||||
|
height: 200px;
|
||||||
|
background: var(--super-light);
|
||||||
|
border: 1px solid #e2e2e2;
|
||||||
|
border-radius: 2px;
|
||||||
|
|
||||||
|
.loader{
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -44,7 +44,7 @@ Data.prototype._vacuum = function(){
|
|||||||
/*
|
/*
|
||||||
* Fetch a record using its path, can be whether a file path or content
|
* Fetch a record using its path, can be whether a file path or content
|
||||||
*/
|
*/
|
||||||
Data.prototype.get = function(type, path, _should_update = true){
|
Data.prototype.get = function(type, path, _record_access = true){
|
||||||
if(type !== this.FILE_PATH && type !== this.FILE_CONTENT) return Promise.reject({});
|
if(type !== this.FILE_PATH && type !== this.FILE_CONTENT) return Promise.reject({});
|
||||||
return this.db.then((db) => {
|
return this.db.then((db) => {
|
||||||
const tx = db.transaction(type, "readwrite");
|
const tx = db.transaction(type, "readwrite");
|
||||||
@ -52,15 +52,13 @@ Data.prototype.get = function(type, path, _should_update = true){
|
|||||||
const query = store.get(path);
|
const query = store.get(path);
|
||||||
return new Promise((done, error) => {
|
return new Promise((done, error) => {
|
||||||
query.onsuccess = (e) => {
|
query.onsuccess = (e) => {
|
||||||
let data = query.result || null;
|
let data = query.result;
|
||||||
done(data);
|
done(query.result || null);
|
||||||
if(data && _should_update === true){
|
if(data && _record_access === true){
|
||||||
requestAnimationFrame(() => {
|
data.last_access = new Date();
|
||||||
data.last_access = new Date();
|
if(!data.access_count) data.access_count = 0;
|
||||||
if(!data.access_count) data.access_count = 0;
|
data.access_count += 1;
|
||||||
data.access_count += 1;
|
this.put(type, data.path, data);
|
||||||
this.put(type, data.path, data);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
tx.onerror = error;
|
tx.onerror = error;
|
||||||
@ -80,7 +78,6 @@ Data.prototype.put = function(type, path, data){
|
|||||||
new_data.path = path;
|
new_data.path = path;
|
||||||
}else{
|
}else{
|
||||||
new_data = Object.assign(res, data);
|
new_data = Object.assign(res, data);
|
||||||
new_data.last_update = new Date();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.db.then((db) => {
|
return this.db.then((db) => {
|
||||||
@ -115,7 +112,7 @@ Data.prototype.remove = function(type, path, exact = true){
|
|||||||
request.onsuccess = function(event) {
|
request.onsuccess = function(event) {
|
||||||
const cursor = event.target.result;
|
const cursor = event.target.result;
|
||||||
if(cursor){
|
if(cursor){
|
||||||
if(cursor.value.path.indexOf(path) === 0){
|
if(cursor.value.path.indexOf(path) === 0 && path !== cursor.value.path){
|
||||||
store.delete(cursor.value.path);
|
store.delete(cursor.value.path);
|
||||||
}
|
}
|
||||||
cursor.continue();
|
cursor.continue();
|
||||||
@ -181,4 +178,13 @@ Data.prototype.destroy = function(){
|
|||||||
|
|
||||||
|
|
||||||
export const cache = new Data();
|
export const cache = new Data();
|
||||||
window.test = cache;
|
window._cache = cache;
|
||||||
|
|
||||||
|
_cache._debug = () => {
|
||||||
|
window._cache.update_path((e) => window.log("- path: "+e.path, e.results.slice(0,5).map((f) => {
|
||||||
|
if(f.type === 'directory'){ f.name = "d:"+f.name;} else{ f.name = "f:"+f.name;}
|
||||||
|
if(f.icon === 'loading') return "("+f.name+")";
|
||||||
|
else if(f.icon === 'error') return "_"+f.name+"_";
|
||||||
|
return f.name;
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
|||||||
@ -4,7 +4,7 @@ export { debounce, throttle } from './backpressure';
|
|||||||
export { encrypt, decrypt } from './crypto';
|
export { encrypt, decrypt } from './crypto';
|
||||||
export { event } from './events';
|
export { event } from './events';
|
||||||
export { cache } from './cache';
|
export { cache } from './cache';
|
||||||
export { pathBuilder } from './path';
|
export { pathBuilder, basename, dirname } from './path';
|
||||||
export { memory } from './memory';
|
export { memory } from './memory';
|
||||||
export { prepare } from './navigate';
|
export { prepare } from './navigate';
|
||||||
export { invalidate, http_get, http_post, http_delete } from './ajax';
|
export { invalidate, http_get, http_post, http_delete } from './ajax';
|
||||||
|
|||||||
@ -8,3 +8,13 @@ export function pathBuilder(path, filename, type = 'file'){
|
|||||||
return tmp + '/';
|
return tmp + '/';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function basename(path){
|
||||||
|
return Path.basename(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function dirname(path){
|
||||||
|
const dir = Path.dirname(path);
|
||||||
|
if(dir === '/') return dir;
|
||||||
|
return dir + "/";
|
||||||
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
import { http_get, http_post, prepare } from '../helpers/';
|
import { http_get, http_post, prepare, basename, dirname } from '../helpers/';
|
||||||
import Path from 'path';
|
import Path from 'path';
|
||||||
|
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
@ -18,19 +18,20 @@ class FileSystem{
|
|||||||
|
|
||||||
return Observable.create((obs) => {
|
return Observable.create((obs) => {
|
||||||
this.obs = obs;
|
this.obs = obs;
|
||||||
this._ls_from_cache(path);
|
let keep_pulling_from_http = true;
|
||||||
|
this._ls_from_cache(path, true)
|
||||||
let keep_pulling_from_http = false;
|
.then(() => {
|
||||||
const fetch_from_http = (_path) => {
|
const fetch_from_http = (_path) => {
|
||||||
return this._ls_from_http(_path)
|
return this._ls_from_http(_path)
|
||||||
.then(() => new Promise((done, err) => {
|
.then(() => new Promise((done, err) => {
|
||||||
window.setTimeout(() => done(), 2000);
|
window.setTimeout(() => done(), 2000);
|
||||||
}))
|
}))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return keep_pulling_from_http === true? fetch_from_http(_path) : Promise.resolve();
|
return keep_pulling_from_http === true? fetch_from_http(_path) : Promise.resolve();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
fetch_from_http(path);
|
fetch_from_http(path);
|
||||||
|
});
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
keep_pulling_from_http = false;
|
keep_pulling_from_http = false;
|
||||||
@ -43,7 +44,10 @@ class FileSystem{
|
|||||||
return http_get(url).then((response) => {
|
return http_get(url).then((response) => {
|
||||||
return cache.get(cache.FILE_PATH, path, false).then((_files) => {
|
return cache.get(cache.FILE_PATH, path, false).then((_files) => {
|
||||||
if(_files && _files.results){
|
if(_files && _files.results){
|
||||||
let _files_virtual_to_keep = _files.results.filter((file) => file.icon === 'loading');
|
let _files_virtual_to_keep = _files.results.filter((file) => {
|
||||||
|
return file.icon === 'loading' &&
|
||||||
|
(new Date()).getTime() - file._timestamp < 1000*60*60;
|
||||||
|
});
|
||||||
// update file results
|
// update file results
|
||||||
for(let i=0; i<_files_virtual_to_keep.length; i++){
|
for(let i=0; i<_files_virtual_to_keep.length; i++){
|
||||||
for(let j=0; j<response.results.length; j++){
|
for(let j=0; j<response.results.length; j++){
|
||||||
@ -67,8 +71,8 @@ class FileSystem{
|
|||||||
console.log(_err);
|
console.log(_err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
_ls_from_cache(path){
|
_ls_from_cache(path, _record_access = false){
|
||||||
return cache.get(cache.FILE_PATH, path).then((_files) => {
|
return cache.get(cache.FILE_PATH, path, _record_access).then((_files) => {
|
||||||
if(_files && _files.results){
|
if(_files && _files.results){
|
||||||
if(this.current_path === path){
|
if(this.current_path === path){
|
||||||
this.obs && this.obs.next(_files.results);
|
this.obs && this.obs.next(_files.results);
|
||||||
@ -80,15 +84,15 @@ class FileSystem{
|
|||||||
|
|
||||||
rm(path){
|
rm(path){
|
||||||
const url = '/api/files/rm?path='+prepare(path);
|
const url = '/api/files/rm?path='+prepare(path);
|
||||||
this._replace(path, 'loading');
|
this._replace(path, 'loading')
|
||||||
return http_get(url)
|
.then(() => http_get(url))
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if(res.status === 'ok'){
|
if(res.status === 'ok'){
|
||||||
this._remove(path);
|
|
||||||
cache.remove(cache.FILE_CONTENT, path, false);
|
cache.remove(cache.FILE_CONTENT, path, false);
|
||||||
cache.remove(cache.FILE_PATH, Path.dirname(path) + "/", false);
|
cache.remove(cache.FILE_PATH, dirname(path), false);
|
||||||
|
return this._remove(path);
|
||||||
}else{
|
}else{
|
||||||
this._replace(path, 'error');
|
return this._replace(path, 'error');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -115,59 +119,53 @@ class FileSystem{
|
|||||||
const url = '/api/files/cat?path='+prepare(path);
|
const url = '/api/files/cat?path='+prepare(path);
|
||||||
let formData = new window.FormData();
|
let formData = new window.FormData();
|
||||||
formData.append('file', file);
|
formData.append('file', file);
|
||||||
this._replace(path, 'loading');
|
return this._replace(path, 'loading')
|
||||||
cache.put(cache.FILE_CONTENT, path, file);
|
.then(() => cache.put(cache.FILE_CONTENT, path, file))
|
||||||
return http_post(url, formData, 'multipart')
|
.then(() => http_post(url, formData, 'multipart'))
|
||||||
.then((res)=> {
|
.then((res)=> res.status === 'ok'? this._replace(path) : this._replace(path, 'error'));
|
||||||
res.status === 'ok'? this._replace(path) : this._replace(path, 'error');
|
|
||||||
return Promise.resolve(res);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mkdir(path){
|
mkdir(path){
|
||||||
const url = '/api/files/mkdir?path='+prepare(path);
|
const url = '/api/files/mkdir?path='+prepare(path);
|
||||||
this._add(path, 'loading');
|
this._add(path, 'loading')
|
||||||
cache.remove(cache.FILE_PATH, Path.dirname(path) + "/");
|
.then(() => this._add(path, 'loading'))
|
||||||
return http_get(url)
|
.then(() => http_get(url))
|
||||||
.then((res) => {
|
.then((res) => res.status === 'ok'? this._replace(path) : this._replace(path, 'error'));
|
||||||
return res.status === 'ok'? this._replace(path) : this._replace(path, 'error');
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
touch(path, file){
|
touch(path, file){
|
||||||
this._add(path, 'loading');
|
this._add(path, 'loading')
|
||||||
let req;
|
.then(() => {
|
||||||
if(file){
|
if(file){
|
||||||
const url = '/api/files/cat?path='+prepare(path);
|
const url = '/api/files/cat?path='+prepare(path);
|
||||||
let formData = new window.FormData();
|
let formData = new window.FormData();
|
||||||
formData.append('file', file);
|
formData.append('file', file);
|
||||||
req = http_post(url, formData, 'multipart');
|
return http_post(url, formData, 'multipart');
|
||||||
}else{
|
}else{
|
||||||
const url = '/api/files/touch?path='+prepare(path);
|
const url = '/api/files/touch?path='+prepare(path);
|
||||||
req = http_get(url);
|
return http_get(url);
|
||||||
}
|
}
|
||||||
|
})
|
||||||
return req
|
.then((res) => res.status === 'ok'? this._replace(path) : this._replace(path, 'error'));
|
||||||
.then((res) => {
|
|
||||||
return res.status === 'ok'? this._replace(path) : this._replace(path, 'error');
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mv(from, to){
|
mv(from, to){
|
||||||
const url = '/api/files/mv?from='+prepare(from)+"&to="+prepare(to);
|
const url = '/api/files/mv?from='+prepare(from)+"&to="+prepare(to);
|
||||||
|
|
||||||
ui_before_request(from, to)
|
ui_before_request(from, to)
|
||||||
.then(() => this._ls_from_cache(Path.dirname(from)+"/"))
|
.then(() => this._ls_from_cache(dirname(from)))
|
||||||
|
.then(() => this._ls_from_cache(dirname(to)))
|
||||||
.then(() => http_get(url)
|
.then(() => http_get(url)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if(res.status === 'ok'){
|
if(res.status === 'ok'){
|
||||||
ui_when_success(from, to)
|
return ui_when_success.call(this, from, to)
|
||||||
.then(() => this._ls_from_cache(Path.dirname(from)+"/"));
|
.then(() => this._ls_from_cache(dirname(from)))
|
||||||
|
.then(() => this._ls_from_cache(dirname(to)));
|
||||||
}else{
|
}else{
|
||||||
ui_when_fail(from, to)
|
return ui_when_fail.call(this, from, to)
|
||||||
.then(() => this._ls_from_cache(Path.dirname(from)+"/"));
|
.then(() => this._ls_from_cache(dirname(from)))
|
||||||
|
.then(() => this._ls_from_cache(dirname(to)));
|
||||||
}
|
}
|
||||||
return Promise.resolve(res);
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
function ui_before_request(from, to){
|
function ui_before_request(from, to){
|
||||||
@ -180,26 +178,27 @@ class FileSystem{
|
|||||||
});
|
});
|
||||||
|
|
||||||
function update_from(){
|
function update_from(){
|
||||||
return cache.get(cache.FILE_PATH, Path.dirname(from)+"/", false)
|
return cache.get(cache.FILE_PATH, dirname(from), false)
|
||||||
.then((res_from) => {
|
.then((res_from) => {
|
||||||
let _file = {name: Path.basename(from), type: /\/$/.test(from) ? 'directory' : 'file'};
|
let _file = {name: basename(from), type: /\/$/.test(from) ? 'directory' : 'file'};
|
||||||
res_from.results = res_from.results.map((file) => {
|
res_from.results = res_from.results.map((file) => {
|
||||||
if(file.name === Path.basename(from)){
|
if(file.name === basename(from)){
|
||||||
file.name = Path.basename(to);
|
file.name = basename(to);
|
||||||
file.icon = 'loading';
|
file.icon = 'loading';
|
||||||
|
file._timestamp = (new Date()).getTime();
|
||||||
_file = file;
|
_file = file;
|
||||||
}
|
}
|
||||||
return file;
|
return file;
|
||||||
});
|
});
|
||||||
return cache.put(cache.FILE_PATH, Path.dirname(from)+"/", res_from)
|
return cache.put(cache.FILE_PATH, dirname(from), res_from)
|
||||||
.then(() => Promise.resolve(_file));
|
.then(() => Promise.resolve(_file));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function update_to(file){
|
function update_to(file){
|
||||||
return cache.get(cache.FILE_PATH, Path.dirname(to)+"/", false).then((res_to) => {
|
return cache.get(cache.FILE_PATH, dirname(to), false).then((res_to) => {
|
||||||
if(!res_to || !res_to.results) return Promise.resolve();
|
if(!res_to || !res_to.results) return Promise.resolve();
|
||||||
res_to.results.push(file);
|
res_to.results.push(file);
|
||||||
return cache.put(cache.FILE_PATH, Path.dirname(to)+"/", res_to);
|
return cache.put(cache.FILE_PATH, dirname(to), res_to);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,38 +212,37 @@ class FileSystem{
|
|||||||
});
|
});
|
||||||
|
|
||||||
function update_from(){
|
function update_from(){
|
||||||
return cache.get(cache.FILE_PATH, Path.dirname(from)+"/", false)
|
return cache.get(cache.FILE_PATH, dirname(from), false)
|
||||||
.then((res_from) => {
|
.then((res_from) => {
|
||||||
if(!res_from || !res_from.results) return Promise.reject();
|
if(!res_from || !res_from.results) return Promise.reject();
|
||||||
res_from.results = res_from.results.map((file) => {
|
res_from.results = res_from.results.map((file) => {
|
||||||
if(file.name === Path.basename(from)){
|
if(file.name === basename(from)){
|
||||||
file.icon = 'error';
|
file.icon = 'error';
|
||||||
}
|
}
|
||||||
return file;
|
return file;
|
||||||
});
|
});
|
||||||
return cache.put(cache.FILE_PATH, Path.dirname(from)+"/", res_from)
|
return cache.put(cache.FILE_PATH, dirname(from), res_from)
|
||||||
.then(() => Promise.resolve());
|
.then(() => Promise.resolve());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function update_to(){
|
function update_to(){
|
||||||
return cache.get(cache.FILE_PATH, Path.dirname(to)+"/", false)
|
return cache.get(cache.FILE_PATH, dirname(to), false)
|
||||||
.then((res_to) => {
|
.then((res_to) => {
|
||||||
if(!res_to || !res_to.results) return Promise.resolve();
|
if(!res_to || !res_to.results) return Promise.resolve();
|
||||||
res_to.results = res_to.results.filter((file) => {
|
res_to.results = res_to.results.filter((file) => {
|
||||||
if(file.name === Path.basename(to)){
|
if(file.name === basename(to)){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
return cache.put(cache.FILE_PATH, Path.dirname(from)+"/", res_to);
|
return cache.put(cache.FILE_PATH, dirname(from), res_to);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function ui_when_success(from, to){
|
function ui_when_success(from, to){
|
||||||
if(Path.dirname(from) === Path.dirname(to)){
|
if(Path.dirname(from) === Path.dirname(to)){
|
||||||
this._replace(Path.dirname(from)+"/"+Path.basename(to), null);
|
return this._replace(dirname(from)+basename(to), null);
|
||||||
return Promise.resolve();
|
|
||||||
}else{
|
}else{
|
||||||
return update_from()
|
return update_from()
|
||||||
.then(update_to)
|
.then(update_to)
|
||||||
@ -252,35 +250,35 @@ class FileSystem{
|
|||||||
}
|
}
|
||||||
|
|
||||||
function update_from(){
|
function update_from(){
|
||||||
return cache.get(cache.FILE_PATH, Path.dirname(from)+"/", false).then((res_from) => {
|
return cache.get(cache.FILE_PATH, dirname(from), false).then((res_from) => {
|
||||||
if(!res_from || !res_from.results) return Promise.resolve();
|
if(!res_from || !res_from.results) return Promise.resolve();
|
||||||
res_from.results = res_from.results.filter((file) => {
|
res_from.results = res_from.results.filter((file) => {
|
||||||
if(file.name === Path.basename(to)){
|
if(file.name === basename(to)){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
return cache.put(cache.FILE_PATH, Path.dirname(from)+"/", res_from);
|
return cache.put(cache.FILE_PATH, dirname(from), res_from);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function update_to(){
|
function update_to(){
|
||||||
return cache.get(cache.FILE_PATH, Path.dirname(to)+"/", false).then((res_to) => {
|
return cache.get(cache.FILE_PATH, dirname(to), false).then((res_to) => {
|
||||||
const target_already_exist = res_to && res_to.results ? true : false;
|
const target_already_exist = res_to && res_to.results ? true : false;
|
||||||
if(target_already_exist){
|
if(target_already_exist){
|
||||||
res_to.results = res_to.results.map((file) => {
|
res_to.results = res_to.results.map((file) => {
|
||||||
if(file.name === Path.basename(to)){
|
if(file.name === basename(to)){
|
||||||
delete file.icon;
|
delete file.icon;
|
||||||
}
|
}
|
||||||
return file;
|
return file;
|
||||||
});
|
});
|
||||||
return cache.put(cache.FILE_PATH, Path.dirname(to)+"/", res_to);
|
return cache.put(cache.FILE_PATH, dirname(to), res_to);
|
||||||
}else{
|
}else{
|
||||||
const data = {results: [{
|
const data = {results: [{
|
||||||
name: Path.basename(to),
|
name: basename(to),
|
||||||
type: /\/$/.test(to) ? 'directory' : 'file',
|
type: /\/$/.test(to) ? 'directory' : 'file',
|
||||||
time: (new Date()).getTime()
|
time: (new Date()).getTime()
|
||||||
}]};
|
}]};
|
||||||
return cache.put(cache.FILE_PATH, Path.dirname(to)+"/", data);
|
return cache.put(cache.FILE_PATH, dirname(to), data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -302,55 +300,53 @@ class FileSystem{
|
|||||||
}
|
}
|
||||||
|
|
||||||
_replace(path, icon){
|
_replace(path, icon){
|
||||||
return cache.get(cache.FILE_PATH, Path.dirname(path) + "/", false)
|
return cache.get(cache.FILE_PATH, dirname(path), false)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if(!res) return Promise.resolve();
|
if(!res) return Promise.resolve();
|
||||||
let files = res.results.map((file) => {
|
let files = res.results.map((file) => {
|
||||||
if(file.name === Path.basename(path)){
|
if(file.name === basename(path)){
|
||||||
if(!icon) delete file.icon;
|
if(!icon){
|
||||||
if(icon) file.icon = icon;
|
delete file.icon;
|
||||||
|
delete file._timestamp;
|
||||||
|
}
|
||||||
|
if(icon){
|
||||||
|
file.icon = icon;
|
||||||
|
file._timestamp = (new Date()).getTime();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return file;
|
return file;
|
||||||
});
|
});
|
||||||
res.results = files;
|
res.results = files;
|
||||||
return cache.put(cache.FILE_PATH, Path.dirname(path) + "/", res)
|
return cache.put(cache.FILE_PATH, dirname(path), res)
|
||||||
.then((res) => {
|
.then((res) => this._ls_from_cache(Path.dirname(path)+"/"));
|
||||||
this._ls_from_cache(Path.dirname(path)+"/");
|
|
||||||
return Promise.resolve(res);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_add(path, icon){
|
_add(path, icon){
|
||||||
return cache.get(cache.FILE_PATH, Path.dirname(path) + "/", false)
|
return cache.get(cache.FILE_PATH, dirname(path), false)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if(!res) return Promise.resolve();
|
if(!res) return Promise.resolve();
|
||||||
let file = {
|
let file = {
|
||||||
name: Path.basename(path),
|
name: basename(path),
|
||||||
type: /\/$/.test(path) ? 'directory' : 'file',
|
type: /\/$/.test(path) ? 'directory' : 'file',
|
||||||
|
_timestamp: (new Date()).getTime()
|
||||||
};
|
};
|
||||||
if(icon) file.icon = icon;
|
if(icon) file.icon = icon;
|
||||||
res.results.push(file);
|
res.results.push(file);
|
||||||
return cache.put(cache.FILE_PATH, Path.dirname(path) + "/", res)
|
return cache.put(cache.FILE_PATH, dirname(path), res)
|
||||||
.then((res) => {
|
.then((res) => this._ls_from_cache(Path.dirname(path)+"/"));
|
||||||
this._ls_from_cache(Path.dirname(path)+"/");
|
|
||||||
return Promise.resolve(res);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
_remove(path){
|
_remove(path){
|
||||||
return cache.get(cache.FILE_PATH, Path.dirname(path) + "/", false)
|
return cache.get(cache.FILE_PATH, dirname(path), false)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if(!res) return Promise.resolve();
|
if(!res) return Promise.resolve();
|
||||||
let files = res.results.filter((file) => {
|
let files = res.results.filter((file) => {
|
||||||
return file.name === Path.basename(path) ? false : true;
|
return file.name === basename(path) ? false : true;
|
||||||
});
|
});
|
||||||
res.results = files;
|
res.results = files;
|
||||||
return cache.put(cache.FILE_PATH, Path.dirname(path) + "/", res)
|
return cache.put(cache.FILE_PATH, dirname(path), res)
|
||||||
.then((res) => {
|
.then((res) => this._ls_from_cache(Path.dirname(path)+"/"));
|
||||||
this._ls_from_cache(Path.dirname(path)+"/");
|
|
||||||
return Promise.resolve(res);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,6 +33,7 @@ export class NewThing extends React.Component {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if(this.state.name !== null){
|
if(this.state.name !== null){
|
||||||
this.props.emit('file.create', pathBuilder(this.props.path, this.state.name, this.state.type), this.state.type);
|
this.props.emit('file.create', pathBuilder(this.props.path, this.state.name, this.state.type), this.state.type);
|
||||||
|
this.onDelete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,19 +2,7 @@ import React from 'react';
|
|||||||
import { BrowserRouter, Route, IndexRoute, Switch } from 'react-router-dom';
|
import { BrowserRouter, Route, IndexRoute, Switch } from 'react-router-dom';
|
||||||
import { NotFoundPage, ConnectPage, HomePage, LogoutPage, FilesPage, ViewerPage } from './pages/';
|
import { NotFoundPage, ConnectPage, HomePage, LogoutPage, FilesPage, ViewerPage } from './pages/';
|
||||||
import { Bundle, URL_HOME, URL_FILES, URL_VIEWER, URL_LOGIN, URL_LOGOUT } from './helpers/';
|
import { Bundle, URL_HOME, URL_FILES, URL_VIEWER, URL_LOGIN, URL_LOGOUT } from './helpers/';
|
||||||
|
import { Audio, Video } from './components/';
|
||||||
// import {FilesPage} from './pages/filespage';
|
|
||||||
// import {ViewerPage} from './pages/viewerpage';
|
|
||||||
// const FilesPage = (props) => (
|
|
||||||
// <Bundle loader={import(/* webpackChunkName: "route" */ "./pages/filespage")} symbol="FilesPage">
|
|
||||||
// {(Comp) => <Comp {...props}/>}
|
|
||||||
// </Bundle>
|
|
||||||
// );
|
|
||||||
// const ViewerPage = (props) => (
|
|
||||||
// <Bundle loader={import(/* webpackChunkName: "route" */"./pages/viewerpage")} symbol="ViewerPage">
|
|
||||||
// {(Comp) => <Comp {...props}/>}
|
|
||||||
// </Bundle>
|
|
||||||
// );
|
|
||||||
|
|
||||||
export default class AppRouter extends React.Component {
|
export default class AppRouter extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
|
|||||||
2147
package-lock.json
generated
2147
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -20,6 +20,7 @@
|
|||||||
"aws-sdk": "^2.59.0",
|
"aws-sdk": "^2.59.0",
|
||||||
"body-parser": "^1.17.2",
|
"body-parser": "^1.17.2",
|
||||||
"cookie-parser": "^1.4.3",
|
"cookie-parser": "^1.4.3",
|
||||||
|
"cors": "^2.8.3",
|
||||||
"crypto": "0.0.3",
|
"crypto": "0.0.3",
|
||||||
"express": "^4.15.3",
|
"express": "^4.15.3",
|
||||||
"express-winston": "^2.4.0",
|
"express-winston": "^2.4.0",
|
||||||
@ -36,8 +37,7 @@
|
|||||||
"ssh2-sftp-client": "^1.1.0",
|
"ssh2-sftp-client": "^1.1.0",
|
||||||
"stream-to-string": "^1.1.0",
|
"stream-to-string": "^1.1.0",
|
||||||
"string-to-stream": "^1.1.0",
|
"string-to-stream": "^1.1.0",
|
||||||
"cors": "^2.8.3",
|
"webdav-fs": "^1.10.1",
|
||||||
"webdav-fs": "^1.0.0",
|
|
||||||
"winston": "^2.3.1",
|
"winston": "^2.3.1",
|
||||||
"winston-couchdb": "^0.6.3"
|
"winston-couchdb": "^0.6.3"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -83,7 +83,7 @@ app.get('/mv', function(req, res){
|
|||||||
if(from && to){
|
if(from && to){
|
||||||
Files.mv(from, to, req.cookies.auth)
|
Files.mv(from, to, req.cookies.auth)
|
||||||
.then((message) => {
|
.then((message) => {
|
||||||
res.send({status: 'ok', result: message})
|
res.send({status: 'ok'})
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
res.send({status: 'error', message: err.message || 'couldn\'t rename your file', trace: err})
|
res.send({status: 'error', message: err.message || 'couldn\'t rename your file', trace: err})
|
||||||
@ -115,7 +115,7 @@ app.get('/mkdir', function(req, res){
|
|||||||
if(path){
|
if(path){
|
||||||
Files.mkdir(path, req.cookies.auth)
|
Files.mkdir(path, req.cookies.auth)
|
||||||
.then((message) => {
|
.then((message) => {
|
||||||
res.send({status: 'ok', result: message})
|
res.send({status: 'ok'})
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
res.send({status: 'error', message: err.message || 'couldn\'t create a directory', trace: err})
|
res.send({status: 'error', message: err.message || 'couldn\'t create a directory', trace: err})
|
||||||
@ -130,7 +130,7 @@ app.get('/touch', function(req, res){
|
|||||||
if(path){
|
if(path){
|
||||||
Files.touch(path, req.cookies.auth)
|
Files.touch(path, req.cookies.auth)
|
||||||
.then((message) => {
|
.then((message) => {
|
||||||
res.send({status: 'ok', result: message})
|
res.send({status: 'ok'})
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
res.send({status: 'error', message: err.message || 'couldn\'t create a file', trace: err})
|
res.send({status: 'error', message: err.message || 'couldn\'t create a file', trace: err})
|
||||||
|
|||||||
@ -23,8 +23,8 @@ module.exports = {
|
|||||||
test: function(params){
|
test: function(params){
|
||||||
return new Promise((done, err) => {
|
return new Promise((done, err) => {
|
||||||
connect(params).readFile('/', function(error, res){
|
connect(params).readFile('/', function(error, res){
|
||||||
if(error){ err(error) }
|
if(error){ err(error); }
|
||||||
else{ done(params) }
|
else{ done(params); }
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -40,7 +40,7 @@ module.exports = {
|
|||||||
done(stream);
|
done(stream);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
ls: function(path, params){
|
ls: function(path, params){
|
||||||
return new Promise((done, err) => {
|
return new Promise((done, err) => {
|
||||||
@ -65,7 +65,7 @@ module.exports = {
|
|||||||
} else {
|
} else {
|
||||||
err(error);
|
err(error);
|
||||||
}
|
}
|
||||||
}, 'stat');
|
}, 'stat');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
write: function(path, content, params){
|
write: function(path, content, params){
|
||||||
@ -81,8 +81,8 @@ module.exports = {
|
|||||||
path = encode(path);
|
path = encode(path);
|
||||||
return new Promise((done, err) => {
|
return new Promise((done, err) => {
|
||||||
connect(params).unlink(path, function (error) {
|
connect(params).unlink(path, function (error) {
|
||||||
if(error){ err(error) }
|
if(error){ err(error); }
|
||||||
else{ done('ok') }
|
else{ done('ok'); }
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -91,8 +91,8 @@ module.exports = {
|
|||||||
to = encode(to);
|
to = encode(to);
|
||||||
return new Promise((done, err) => {
|
return new Promise((done, err) => {
|
||||||
connect(params).rename(from, to, function (error) {
|
connect(params).rename(from, to, function (error) {
|
||||||
if(error){ err(error) }
|
if(error){ err(error); }
|
||||||
else{ done('ok') }
|
else{ done('ok'); }
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -103,7 +103,7 @@ module.exports = {
|
|||||||
if(error){ err(error); }
|
if(error){ err(error); }
|
||||||
else{ done('done'); }
|
else{ done('done'); }
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
touch: function(path, params){
|
touch: function(path, params){
|
||||||
path = encode(path);
|
path = encode(path);
|
||||||
@ -112,6 +112,6 @@ module.exports = {
|
|||||||
if(error){ err(error); }
|
if(error){ err(error); }
|
||||||
else{ done('done'); }
|
else{ done('done'); }
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user