feature (metadata): attach metadata to ls to enable/disable features

This commit is contained in:
Mickael Kerjean
2018-07-18 14:10:33 +10:00
parent 1c7a7bf8df
commit c5f2839fd7
8 changed files with 43 additions and 45 deletions

1
.gitignore vendored
View File

@ -2,6 +2,7 @@ node_modules/
babel_cache/
dist/
.DS_Store
package-lock.json
\#*\#
.\#*
*.log

View File

@ -53,6 +53,7 @@ class FileSystem{
path: path,
results: null,
access_count: 0,
metadata: null
}, _files);
store.access_count += 1;
store.results = response.results || [];
@ -60,6 +61,7 @@ class FileSystem{
f.path = pathBuilder(path, f.name);
return f;
});
store.metadata = response.metadata;
if(_files && _files.results){
// find out which entry we want to keep from the cache
@ -82,7 +84,11 @@ class FileSystem{
}
if(this.current_path === path){
this.obs && this.obs.next({status: 'ok', results: store.results});
this.obs && this.obs.next({
status: 'ok',
results: store.results,
metadata: store.metadata
});
}
store.last_update = new Date();
store.last_access = new Date();
@ -99,7 +105,11 @@ class FileSystem{
return cache.get(cache.FILE_PATH, path).then((response) => {
if(!response || !response.results) return null;
if(this.current_path === path){
this.obs && this.obs.next({status: 'ok', results: response.results});
this.obs && this.obs.next({
status: 'ok',
results: response.results,
metadata: response.metadata
});
}
return response;
});
@ -107,7 +117,11 @@ class FileSystem{
return cache.upsert(cache.FILE_PATH, path, (response) => {
if(!response || !response.results) return null;
if(this.current_path === path){
this.obs && this.obs.next({status: 'ok', results: response.results});
this.obs && this.obs.next({
status: 'ok',
results: response.results,
metadata: response.metadata
});
}
response.last_access = new Date();
response.access_count += 1;

View File

@ -25,6 +25,7 @@ export class FilesPage extends React.Component {
show_hidden: settings_get('filespage_show_hidden') || CONFIG["display_hidden"],
view: settings_get('filespage_view') || 'grid',
files: [],
metadata: null,
frequents: [],
page_number: PAGE_NUMBER_INIT,
loading: true,
@ -101,7 +102,12 @@ export class FilesPage extends React.Component {
if(this.state.show_hidden === false){
files = files.filter((file) => file.name[0] === "." ? false : true);
}
this.setState({files: sort(files, this.state.sort), loading: false, page_number: PAGE_NUMBER_INIT});
this.setState({
metadata: res.metadata,
files: sort(files, this.state.sort),
loading: false,
page_number: PAGE_NUMBER_INIT
});
}else{
notify.send(res, 'error');
}
@ -172,7 +178,7 @@ export class FilesPage extends React.Component {
<NgIf cond={this.state.path === '/'}>
<FrequentlyAccess files={this.state.frequents}/>
</NgIf>
<FileSystem path={this.state.path} sort={this.state.sort} view={this.state.view} onSort={this.onSort.bind(this)} onView={this.onView.bind(this)} files={this.state.files.slice(0, this.state.page_number * 24)} />
<FileSystem path={this.state.path} sort={this.state.sort} view={this.state.view} onSort={this.onSort.bind(this)} onView={this.onView.bind(this)} files={this.state.files.slice(0, this.state.page_number * 24)} metadata={this.state.metadata} />
<Uploader path={this.state.path} />
</NgIf>
</InfiniteScroll>

View File

@ -18,31 +18,15 @@ import { FileZone } from './filezone';
export class FileSystem extends React.Component {
constructor(props){
super(props);
this.state = {
creating: null,
access_right: this._findAccessRight(props.files)
};
}
_findAccessRight(files){
for(let i=0, l=files.length; i< l; i++){
let file = files[i];
if(file.name === './' && file.type === 'metadata'){
return file;
}
}
return {can_create_file: true, can_create_directory: true};
}
onComponentPropsUpdate(props){
this.setState({access_right: this._findAccessRight(props.files)});
}
render() {
const metadata = this.props.metadata || {};
return this.props.connectDropFile(
<div className="component_filesystem">
<Container>
<NewThing path={this.props.path} sort={this.props.sort} view={this.props.view} onViewUpdate={(value) => this.props.onView(value)} onSortUpdate={(value) => {this.props.onSort(value);}} accessRight={this.state.access_right}></NewThing>
<NewThing path={this.props.path} sort={this.props.sort} view={this.props.view} onViewUpdate={(value) => this.props.onView(value)} onSortUpdate={(value) => {this.props.onSort(value);}} accessRight={metadata}></NewThing>
<NgIf cond={this.props.fileIsOver}>
<FileZone path={this.props.path} />
</NgIf>
@ -51,13 +35,13 @@ export class FileSystem extends React.Component {
{
this.props.files.map((file, index) => {
if(file.type === 'directory' || file.type === 'file' || file.type === 'link' || file.type === 'bucket'){
return ( <ExistingThing view={this.props.view} key={file.name+(file.icon || '')} file={file} path={this.props.path} /> );
return ( <ExistingThing view={this.props.view} key={file.name+(file.icon || '')} file={file} path={this.props.path} metadata={metadata} /> );
}
})
}
</ReactCSSTransitionGroup>
</NgIf>
<NgIf className="error" cond={this.props.files.length === 0 && !this.state.creating}>
<NgIf className="error" cond={this.props.files.length === 0}>
There is nothing here
</NgIf>
</Container>
@ -68,5 +52,6 @@ export class FileSystem extends React.Component {
FileSystem.PropTypes = {
path: PropTypes.string.isRequired,
files: PropTypes.array.isRequired
files: PropTypes.array.isRequired,
metadata: PropTypes.object.isRequired
}

View File

@ -19,6 +19,9 @@ const fileSource = {
};
},
canDrag(props, monitor){
if (props.metadata.can_move === false){
return false;
}
return props.file.icon === 'loading'? false : true;
},
endDrag(props, monitor, component){
@ -211,7 +214,7 @@ export class ExistingThing extends React.Component {
<Filename filename={this.props.file.name} filesize={this.props.file.size} filetype={this.props.file.type} onRename={this.onRename.bind(this)} is_renaming={this.state.is_renaming} onRenameCancel={this.onRenameRequest.bind(this, false)}/>
<Message message={this.state.message} />
<DateTime show={this.state.icon !== 'loading'} timestamp={this.props.file.time} />
<ActionButton onClickRename={this.onRenameRequest.bind(this)} onClickDelete={this.onDeleteRequest.bind(this)} is_renaming={this.state.is_renaming} can_move={this.props.file.can_move !== false} can_delete={this.props.file.can_delete !== false} />
<ActionButton onClickRename={this.onRenameRequest.bind(this)} onClickDelete={this.onDeleteRequest.bind(this)} is_renaming={this.state.is_renaming} can_rename={this.props.metadata.can_rename !== false} can_delete={this.props.metadata.can_delete !== false} />
</Card>
</Link>
</div>
@ -291,10 +294,10 @@ const ActionButton = (props) => {
return (
<div className="component_action">
<NgIf cond={props.can_move === true && props.is_renaming === false} type="inline">
<NgIf cond={props.can_rename !== false && props.is_renaming === false} type="inline">
<Icon name="edit" onClick={onRename} className="component_updater--icon" />
</NgIf>
<NgIf cond={props.can_delete === true} type="inline">
<NgIf cond={props.can_delete !== false} type="inline">
<Icon name="delete" onClick={onDelete} className="component_updater--icon"/>
</NgIf>
</div>

View File

@ -57,20 +57,12 @@ export class NewThing extends React.Component {
this.props.onSortUpdate(e);
}
// SEARCH BAR: WIP
// <div className="search">
// <label>
// <input type="text" />
// <Icon name="search_dark"/>
// </label>
// </div>
render(){
return (
<div>
<div className="menubar no-select">
<NgIf cond={this.props.accessRight.can_create_file === true} onClick={this.onNew.bind(this, 'file')} type="inline">New File</NgIf>
<NgIf cond={this.props.accessRight.can_create_directory === true} onClick={this.onNew.bind(this, 'directory')} type="inline">New Directory</NgIf>
<NgIf cond={this.props.accessRight.can_create_file !== false} onClick={this.onNew.bind(this, 'file')} type="inline">New File</NgIf>
<NgIf cond={this.props.accessRight.can_create_directory !== false} onClick={this.onNew.bind(this, 'directory')} type="inline">New Directory</NgIf>
<Dropdown className="view sort" onChange={this.onSortChange.bind(this)}>
<DropdownButton>
<Icon name="sort"/>

View File

@ -10,10 +10,11 @@ export class FileDownloader extends React.Component{
}
onClick(){
document.cookie = "download=yes; path=/; max-age=120;";
this.setState({
loading: true,
id: window.setInterval(function(){
if(document.cookie){
if(/download=yes/.test(document.cookie) === false){
this.setState({loading: false})
window.clearInterval(this.state.id);
}

View File

@ -38,10 +38,6 @@ class DownloadButton extends React.Component {
loading: true
});
// This my friend is a dirty hack aiming to detect when we the download effectively start
// so that we can display a spinner instead of having a user clicking the download button
// 10 times. It works by sniffing a cookie in our session that will get destroy when
// the server actually send a response
document.cookie = "download=yes; path=/; max-age=120;";
this.state.id = window.setInterval(() => {
if(/download=yes/.test(document.cookie) === false){