mirror of
https://github.com/mickael-kerjean/filestash
synced 2025-12-06 08:22:24 +01:00
beautify (code): improve code + fixes
This commit is contained in:
parent
d88c845a06
commit
50749a1b6c
13 changed files with 144 additions and 103 deletions
|
|
@ -10,11 +10,11 @@ export { Loader } from './loader';
|
|||
export { Error } from './error';
|
||||
export { Fab } from './fab';
|
||||
export { Icon } from './icon';
|
||||
export { Notification } from './notification';
|
||||
export { Uploader } from './uploader';
|
||||
export { Bundle } from './bundle';
|
||||
export { Modal } from './modal';
|
||||
export { Prompt } from './prompt';
|
||||
export { ModalPrompt } from './prompt';
|
||||
export { Notification } from './notification';
|
||||
export { Alert } from './alert';
|
||||
export { Audio } from './audio';
|
||||
export { Video } from './video';
|
||||
|
|
|
|||
|
|
@ -2,49 +2,51 @@ import React from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
|
||||
import { Input, Button, Modal, NgIf } from './';
|
||||
import { prompt } from '../helpers/';
|
||||
|
||||
export class Prompt extends React.Component {
|
||||
export class ModalPrompt extends React.Component {
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.state = {
|
||||
error: this.props.error,
|
||||
value: ''
|
||||
appear: false
|
||||
};
|
||||
if(this.props.error) window.setTimeout(() => this.setState({error: ''}), 2000);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(props){
|
||||
if(props.error !== this.state.error){
|
||||
this.setState({error: props.error});
|
||||
window.setTimeout(() => this.setState({error: ''}), 2000);
|
||||
}
|
||||
componentDidMount(){
|
||||
prompt.subscribe((text, okCallback, cancelCallback, type) => {
|
||||
console.log("REQUEST FOR PROMPT");
|
||||
this.setState({
|
||||
appear: true,
|
||||
error: null,
|
||||
type: type || 'text',
|
||||
text: text || '',
|
||||
fns: {ok: okCallback, cancel: cancelCallback}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
onCancel(should_clear){
|
||||
if(this.props.onCancel) this.props.onCancel();
|
||||
onCancel(){
|
||||
this.setState({appear: false});
|
||||
this.state.fns.cancelCallback();
|
||||
}
|
||||
|
||||
onSubmit(e){
|
||||
e && e.preventDefault && e.preventDefault();
|
||||
if(this.props.onSubmit) this.props.onSubmit(this.state.value);
|
||||
}
|
||||
|
||||
onInputChange(value){
|
||||
this.setState({value: value});
|
||||
this.state.fns.okCallback(this.state.value)
|
||||
.then(() => this.setState({appear: false}))
|
||||
.catch((message) => this.setState({error: message}));
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Modal isActive={this.props.appear} onQuit={this.onCancel.bind(this)}>
|
||||
<Modal isActive={this.state.appear} onQuit={this.onCancel.bind(this)}>
|
||||
<div className="component_prompt">
|
||||
<p className="modal-message">
|
||||
{this.props.message}
|
||||
{this.state.text}
|
||||
</p>
|
||||
<form onSubmit={this.onSubmit.bind(this)}>
|
||||
<Input autoFocus={true} value={this.state.value} type={this.props.type || 'text'} autoComplete="new-password" onChange={(e) => this.onInputChange(e.target.value)} />
|
||||
|
||||
<Input autoFocus={true} value={this.state.value} type={this.state.type} autoComplete="new-password" onChange={(e) => this.setState({value: e.target.value})} />
|
||||
<div className="modal-error-message">{this.state.error} </div>
|
||||
|
||||
<div className="buttons">
|
||||
<Button type="button" onClick={this.onCancel.bind(this)}>CANCEL</Button>
|
||||
<Button type="submit" theme="secondary" onClick={this.onSubmit.bind(this)}>OK</Button>
|
||||
|
|
@ -55,12 +57,3 @@ export class Prompt extends React.Component {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
Prompt.propTypes = {
|
||||
appear: PropTypes.bool.isRequired,
|
||||
type: PropTypes.string,
|
||||
message: PropTypes.string.isRequired,
|
||||
error: PropTypes.string,
|
||||
onCancel: PropTypes.func,
|
||||
onConfirm: PropTypes.func
|
||||
};
|
||||
|
|
|
|||
8
client/helpers/dom.js
Normal file
8
client/helpers/dom.js
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
export function screenHeight(){
|
||||
const $breadcrumb = document.querySelector(".breadcrumb");
|
||||
let size = document.body.clientHeight;
|
||||
if($breadcrumb){
|
||||
size -= $breadcrumb.clientHeight;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
|
@ -8,3 +8,5 @@ export { pathBuilder, basename, dirname } from './path';
|
|||
export { memory } from './memory';
|
||||
export { prepare } from './navigate';
|
||||
export { invalidate, http_get, http_post, http_delete } from './ajax';
|
||||
export { screenHeight } from './dom';
|
||||
export { prompt } from './prompt';
|
||||
|
|
|
|||
20
client/helpers/prompt.js
Normal file
20
client/helpers/prompt.js
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
const Prompt = function (){
|
||||
let obs = null;
|
||||
return {
|
||||
emit: function(text, okCallback, cancelCallbck, type){
|
||||
console.log(obs);
|
||||
obs.emit(text, okCallback, cancelcallBack, type);
|
||||
},
|
||||
subscribe: function(){
|
||||
console.log("> SUBSCRIBE")
|
||||
return new Observable((_obs) => {
|
||||
console.log(_obs);
|
||||
obs = _obs;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const prompt = new Prompt();
|
||||
|
|
@ -8,7 +8,7 @@ import { ForkMe, RememberMe, Credentials, Form } from './connectpage/';
|
|||
import { cache } from '../helpers/';
|
||||
import config from '../../config_client';
|
||||
|
||||
import { Alert, Prompt } from '../components/';
|
||||
import { Alert } from '../components/';
|
||||
|
||||
export class ConnectPage extends React.Component {
|
||||
constructor(props){
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
|
||||
|
||||
import { Prompt } from '../../components/';
|
||||
import { ModalPrompt } from '../../components/';
|
||||
import { encrypt, decrypt, memory } from '../../helpers/';
|
||||
|
||||
export class Credentials extends React.Component {
|
||||
|
|
@ -91,7 +91,7 @@ export class Credentials extends React.Component {
|
|||
|
||||
render() {
|
||||
return (
|
||||
<Prompt
|
||||
<ModalPrompt
|
||||
type="password"
|
||||
appear={this.state.modal_appear}
|
||||
error={this.state.error}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import Path from 'path';
|
|||
import './filespage.scss';
|
||||
import { Files } from '../model/';
|
||||
import { NgIf, Loader, Error, Uploader, EventReceiver } from '../components/';
|
||||
import { debounce, goToFiles, goToViewer, event } from '../helpers/';
|
||||
import { debounce, goToFiles, goToViewer, event, screenHeight } from '../helpers/';
|
||||
import { BreadCrumb, FileSystem } from './filespage/';
|
||||
|
||||
@EventReceiver
|
||||
|
|
@ -18,7 +18,7 @@ export class FilesPage extends React.Component {
|
|||
this.state = {
|
||||
path: props.match.url.replace('/files', '') || '/',
|
||||
files: [],
|
||||
loading: false,
|
||||
loading: true,
|
||||
error: false,
|
||||
height: null
|
||||
};
|
||||
|
|
@ -29,23 +29,21 @@ export class FilesPage extends React.Component {
|
|||
}
|
||||
|
||||
componentDidMount(){
|
||||
this.onPathUpdate(this.state.path, 'directory');
|
||||
this.onRefresh(this.state.path, 'directory');
|
||||
|
||||
// subscriptions
|
||||
this.props.subscribe('file.select', this.onPathUpdate.bind(this));
|
||||
this.props.subscribe('file.upload', this.onUpload.bind(this));
|
||||
this.props.subscribe('file.create', this.onCreate.bind(this));
|
||||
this.props.subscribe('file.rename', this.onRename.bind(this));
|
||||
this.props.subscribe('file.delete', this.onDelete.bind(this));
|
||||
this.props.subscribe('file.refresh', this.onRefresh.bind(this));
|
||||
|
||||
this.resetHeight();
|
||||
this.hideError();
|
||||
this.resetHeight();
|
||||
window.addEventListener("resize", this.resetHeight);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.props.unsubscribe('file.select');
|
||||
this.props.unsubscribe('file.upload');
|
||||
this.props.unsubscribe('file.create');
|
||||
this.props.unsubscribe('file.rename');
|
||||
|
|
@ -112,8 +110,7 @@ export class FilesPage extends React.Component {
|
|||
name: file.name,
|
||||
type: 'file',
|
||||
size: file.size,
|
||||
icon: 'loading',
|
||||
virtual: true
|
||||
icon: 'loading'
|
||||
};
|
||||
});
|
||||
const files = JSON.parse(JSON.stringify(this.state.files));
|
||||
|
|
@ -204,17 +201,15 @@ export class FilesPage extends React.Component {
|
|||
<div className="component_page_filespage">
|
||||
<BreadCrumb className="breadcrumb" path={this.state.path} />
|
||||
<div style={{height: this.state.height+'px'}} className="scroll-y">
|
||||
<NgIf className="container" cond={!this.state.loading}>
|
||||
<NgIf className="container" cond={this.state.loading === false}>
|
||||
<FileSystem path={this.state.path} files={this.state.files} />
|
||||
<Uploader path={this.state.path} />
|
||||
</NgIf>
|
||||
<NgIf cond={this.state.loading}>
|
||||
<NgIf cond={this.state.error === false}>
|
||||
<Loader/>
|
||||
</NgIf>
|
||||
<NgIf className="error" cond={this.state.error !== false} onClick={this.componentDidMount.bind(this)}>
|
||||
<NgIf cond={!!this.state.error} className="error" onClick={this.componentDidMount.bind(this)}>
|
||||
<Error err={this.state.error}/>
|
||||
</NgIf>
|
||||
<NgIf cond={this.state.loading && !this.state.error}>
|
||||
<Loader/>
|
||||
</NgIf>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -81,19 +81,12 @@ export class ExistingThing extends React.Component {
|
|||
hover: null,
|
||||
message: null,
|
||||
filename: props.file.name,
|
||||
delete_request: false,
|
||||
delete_message: "Confirm by tapping \""+this._confirm_delete_text()+"\"",
|
||||
delete_error: ''
|
||||
is_renaming: false
|
||||
};
|
||||
}
|
||||
|
||||
onSelect(){
|
||||
if(this.state.icon !== 'loading' && this.state.icon !== 'error'){
|
||||
this.props.emit(
|
||||
'file.select',
|
||||
pathBuilder(this.props.path, this.props.file.name, this.props.file.type),
|
||||
this.props.file.type
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -108,8 +101,28 @@ export class ExistingThing extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
onRenameRequest(){
|
||||
this.setState({is_renaming: !this.state.is_renaming});
|
||||
}
|
||||
|
||||
onDeleteRequest(filename){
|
||||
this.setState({delete_request: true});
|
||||
console.log(prompt);
|
||||
prompt.emit(
|
||||
"Confirm by tapping \""+this._confirm_delete_text()+"\"",
|
||||
(answer) => { // click on ok
|
||||
if(answer === this._confirm_delete_text()){
|
||||
this.setState({icon: 'loading'});
|
||||
this.props.emit(
|
||||
'file.delete',
|
||||
pathBuilder(this.props.path, this.props.file.name),
|
||||
this.props.file.type
|
||||
);
|
||||
return Promise.resolve();
|
||||
}else{
|
||||
return Promise.reject("Doesn't match");
|
||||
}
|
||||
},
|
||||
() => { /* click on cancel */ });
|
||||
}
|
||||
onDeleteConfirm(answer){
|
||||
if(answer === this._confirm_delete_text()){
|
||||
|
|
@ -137,9 +150,6 @@ export class ExistingThing extends React.Component {
|
|||
if(this.props.isDragging) {
|
||||
className += "is-dragging ";
|
||||
}
|
||||
if(this.state.hover === true){
|
||||
className += "mouse-is-hover ";
|
||||
}
|
||||
if((this.props.fileIsOver && this.props.canDropFile) || (this.props.nativeFileIsOver && this.props.canDropNativeFile)) {
|
||||
className += "file-is-hover ";
|
||||
}
|
||||
|
|
@ -170,57 +180,32 @@ ExistingThing.PropTypes = {
|
|||
canDropNativeFile: PropTypes.bool.isRequired
|
||||
}
|
||||
|
||||
class Updater extends React.Component {
|
||||
class Filename extends React.Component {
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.state = {
|
||||
editing: null
|
||||
filename: props.filename
|
||||
};
|
||||
}
|
||||
|
||||
onRename(e){
|
||||
e.preventDefault();
|
||||
this.props.onRename(this.state.editing);
|
||||
this.setState({editing: null});
|
||||
}
|
||||
|
||||
onDelete(e){
|
||||
e.stopPropagation();
|
||||
this.props.onDelete();
|
||||
this.props.onRename(this.state.filename);
|
||||
}
|
||||
|
||||
|
||||
onRenameRequest(e){
|
||||
e.stopPropagation();
|
||||
if(this.state.editing === null){
|
||||
this.setState({editing: this.props.filename});
|
||||
}else{
|
||||
this.setState({editing: null});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
preventSelect(e){
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
render(){
|
||||
return (
|
||||
<span className="component_updater">
|
||||
<NgIf className="action" cond={this.props.show}>
|
||||
<NgIf cond={this.props.can_move} type="inline">
|
||||
<Icon name="edit" onClick={this.onRenameRequest.bind(this)} className="component_updater--icon" />
|
||||
</NgIf>
|
||||
<NgIf cond={this.props.can_delete !== false} type="inline">
|
||||
<Icon name="delete" onClick={this.onDelete.bind(this)} className="component_updater--icon"/>
|
||||
</NgIf>
|
||||
</NgIf>
|
||||
<Icon className="component_updater--icon" name={this.props.icon} />
|
||||
<span className="component_filename">
|
||||
<span className="file-details">
|
||||
<NgIf cond={this.state.editing === null} type='inline'>{this.props.filename}</NgIf>
|
||||
<NgIf cond={this.state.editing !== null} type='inline'>
|
||||
<NgIf cond={this.props.is_renaming === false} type='inline'>{this.state.filename}</NgIf>
|
||||
<NgIf cond={this.props.is_renaming === true} type='inline'>
|
||||
<form onClick={this.preventSelect} onSubmit={this.onRename.bind(this)}>
|
||||
<input value={this.state.editing} onChange={(e) => this.setState({editing: e.target.value})} autoFocus />
|
||||
<input value={this.state.filename} onChange={(e) => this.setState({filename: e.target.value})} autoFocus />
|
||||
</form>
|
||||
</NgIf>
|
||||
</span>
|
||||
|
|
@ -229,6 +214,30 @@ class Updater extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
const ActionButton = (props) => {
|
||||
const onRename = (e) => {
|
||||
console.log(props);
|
||||
e.preventDefault();
|
||||
props.onClickRename();
|
||||
};
|
||||
|
||||
const onDelete = (e) => {
|
||||
e.preventDefault();
|
||||
props.onClickDelete();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="component_action">
|
||||
<NgIf cond={props.can_move === true} type="inline">
|
||||
<Icon name="edit" onClick={onRename} className="component_updater--icon" />
|
||||
</NgIf>
|
||||
<NgIf cond={props.can_delete === true} type="inline">
|
||||
<Icon name="delete" onClick={onDelete} className="component_updater--icon"/>
|
||||
</NgIf>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const DateTime = (props) => {
|
||||
function displayTime(timestamp){
|
||||
function padding(number){
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
export { HomePage } from './homepage';
|
||||
export { ConnectPage } from './connectpage';
|
||||
export { LogoutPage } from './logout';
|
||||
export { NotFoundPage } from './notfound';
|
||||
export { NotFoundPage } from './notfoundpage';
|
||||
export { FilesPage } from './filespage';
|
||||
export { ViewerPage } from './viewerpage';
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import Path from 'path';
|
|||
|
||||
import { Files } from '../model/';
|
||||
import { BreadCrumb, Bundle, NgIf, Loader, Error, Container, EventReceiver, EventEmitter } from '../components/';
|
||||
import { debounce, opener } from '../helpers/';
|
||||
import { debounce, opener, screenHeight } from '../helpers/';
|
||||
import { AudioPlayer, FileDownloader, ImageViewer, PDFViewer } from './viewerpage/';
|
||||
|
||||
const VideoPlayer = (props) => (
|
||||
|
|
@ -29,9 +29,11 @@ export class ViewerPage extends React.Component {
|
|||
needSaving: false,
|
||||
isSaving: false,
|
||||
loading: true,
|
||||
error: false
|
||||
error: false,
|
||||
height: 0
|
||||
};
|
||||
this.props.subscribe('file.select', this.onPathUpdate.bind(this));
|
||||
this.resetHeight = debounce(this.resetHeight.bind(this), 100);
|
||||
}
|
||||
|
||||
componentWillMount(){
|
||||
|
|
@ -48,6 +50,7 @@ export class ViewerPage extends React.Component {
|
|||
if(err && err.code === 'CANCELLED'){ return; }
|
||||
if(err.code === 'BINARY_FILE'){
|
||||
Files.url(this.state.path).then((url) => {
|
||||
console.log(this.state.path);
|
||||
this.setState({data: url, loading: false, opener: 'download'});
|
||||
}).catch(err => {
|
||||
this.setState({error: err});
|
||||
|
|
@ -68,8 +71,13 @@ export class ViewerPage extends React.Component {
|
|||
|
||||
componentWillUnmount() {
|
||||
this.props.unsubscribe('file.select');
|
||||
window.removeEventListener("resize", this.resetHeight);
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
this.resetHeight();
|
||||
window.addEventListener("resize", this.resetHeight);
|
||||
}
|
||||
|
||||
save(file){
|
||||
this.setState({isSaving: true});
|
||||
|
|
@ -97,12 +105,18 @@ export class ViewerPage extends React.Component {
|
|||
this.setState({needSaving: bool});
|
||||
}
|
||||
|
||||
resetHeight(){
|
||||
this.setState({
|
||||
height: screenHeight()
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
let style = {height: '100%'};
|
||||
let style = {height: '100%'}; // {{height: this.state.height+'px'}}
|
||||
return (
|
||||
<div style={style}>
|
||||
<BreadCrumb needSaving={this.state.needSaving} className="breadcrumb" path={this.state.path} />
|
||||
<div style={style}>
|
||||
<div style={{height: this.state.height+'px'}}>
|
||||
<NgIf cond={this.state.loading === false} style={style}>
|
||||
<NgIf cond={this.state.opener === 'editor'} style={style}>
|
||||
<IDE needSaving={this.needSaving.bind(this)}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@
|
|||
font-size: 70%;
|
||||
}
|
||||
|
||||
|
||||
/* Highlight Theme */
|
||||
.cm-s-default .cm-header {color: #3E7AA6; font-size: 1.15em;}
|
||||
.cm-s-default .cm-keyword {color: #3E7AA6;}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||
import { BrowserRouter, Route, IndexRoute, Switch } from 'react-router-dom';
|
||||
import { NotFoundPage, ConnectPage, HomePage, LogoutPage, FilesPage, ViewerPage } from './pages/';
|
||||
import { Bundle, URL_HOME, URL_FILES, URL_VIEWER, URL_LOGIN, URL_LOGOUT } from './helpers/';
|
||||
import { Audio, Video } from './components/';
|
||||
import { ModalPrompt, Audio, Video } from './components/';
|
||||
|
||||
export default class AppRouter extends React.Component {
|
||||
render() {
|
||||
|
|
@ -20,6 +20,7 @@ export default class AppRouter extends React.Component {
|
|||
</Switch>
|
||||
</div>
|
||||
</BrowserRouter>
|
||||
<ModalPrompt />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue