import React from 'react';
import path from 'path';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import { DragSource, DropTarget } from 'react-dnd';
import { createSelectable } from 'react-selectable';
import './thing.scss';
import { Card, NgIf, Icon, EventEmitter, Button, img_placeholder } from '../../components/';
import { pathBuilder, basename, filetype, prompt, alert, leftPad, getMimeType, debounce, memory } from '../../helpers/';
import { Files } from '../../model/';
import { ShareComponent } from './share';
import { t } from '../../locales/';
const fileSource = {
beginDrag(props, monitor, component) {
return {
path: props.path,
name: props.file.name,
type: props.file.type
};
},
canDrag(props, monitor){
if (props.metadata.can_move === false){
return false;
}
if(props.file.icon === "loading") return false;
else if(props.selected === false && props.currentSelection.length > 0) return false;
return true;
},
endDrag(props, monitor, component){
if(monitor.didDrop() && component.state.icon !== 'loading'){
let result = monitor.getDropResult();
if(result.action === 'rename'){
props.emit.apply(component, ['file.rename'].concat(result.args));
}else if(result.action === "rename.multiple"){
props.emit.call(component, "file.rename.multiple", result.args);
}else{
throw 'unknown action';
}
}
}
};
const fileTarget = {
canDrop(props, monitor){
let file = monitor.getItem();
if(props.file.type !== "directory") return false;
else if(file.name === props.file.name) return false;
else if(props.file.icon === "loading") return false;
else if(props.selected === true) return false;
return true;
},
drop(props, monitor, component){
let src = monitor.getItem();
let dest = props.file;
if(props.currentSelection.length === 0){
const from = pathBuilder(props.path, src.name, src.type);
const to = pathBuilder(props.path, './'+dest.name+'/'+src.name, src.type);
return {action: 'rename', args: [from, to, src.type], ctx: 'existingfile'};
} else {
return {action: 'rename.multiple', args: props.currentSelection.map((selectionPath) => {
const from = selectionPath;
const to = pathBuilder(
props.path,
"./"+dest.name+"/"+basename(selectionPath),
filetype(selectionPath)
);
return [ from, to ];
})};
}
}
};
const nativeFileTarget = {
canDrop: fileTarget.canDrop,
drop(props, monitor){
let path = pathBuilder(props.path, props.file.name, 'directory');
props.emit('file.upload', path, monitor.getItem());
}
};
@createSelectable
@EventEmitter
@DropTarget('__NATIVE_FILE__', nativeFileTarget, (connect, monitor) => ({
connectDropNativeFile: connect.dropTarget(),
nativeFileIsOver: monitor.isOver(),
canDropNativeFile: monitor.canDrop()
}))
@DropTarget('file', fileTarget, (connect, monitor) => ({
connectDropFile: connect.dropTarget(),
fileIsOver: monitor.isOver(),
canDropFile: monitor.canDrop()
}))
@DragSource('file', fileSource, (connect, monitor) => ({
connectDragSource: connect.dragSource(),
isDragging: monitor.isDragging()
}))
export class ExistingThing extends React.Component {
constructor(props){
super(props);
this.state = {
hover: null,
filename: props.file.name,
is_renaming: false,
preview: null
};
}
shouldComponentUpdate(nextProps, nextState){
if(nextState.hover !== this.state.hover ||
nextState.is_renaming !== this.state.is_renaming ||
nextProps.view !== this.props.view ||
this.state.preview !== nextState.preview ||
this.props.fileIsOver !== nextProps.fileIsOver ||
this.props.canDropFile !== nextProps.canDropFile ||
this.props.nativeFileIsOver !== nextProps.nativeFileIsOver ||
this.props.canDropNativeFile !== nextProps.canDropNativeFile ||
this.props.selected !== nextProps.selected
){
return true;
}
return false;
}
componentDidMount(){
this.updateThumbnail(this.props);
}
componentWillReceiveProps(props){
if(props.view !== this.props.view){
this.updateThumbnail(props);
}
}
updateThumbnail(props){
if(props.view === "grid" && props.icon !== "loading"){
const type = getMimeType(props.file.path).split("/")[0];
if(type === "image"){
Files.url(props.file.path).then((url) => {
this.setState({preview: url+"&thumbnail=true"});
});
}
}
}
onRename(newFilename){
if(typeof newFilename === "string"){
this.props.emit(
'file.rename',
pathBuilder(this.props.path, this.props.file.name, this.props.file.type),
pathBuilder(this.props.path, newFilename, this.props.file.type),
this.props.file.type
);
}
this.setState({is_renaming: false});
}
onRenameRequest(force){
let new_state = !this.state.is_renaming;
if(typeof force === "boolean"){
new_state = force;
}
this.setState({is_renaming: new_state});
}
onDeleteRequest(filename){
prompt.now(
t("Confirm by typing") +" \""+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),
this.props.file.type
);
return Promise.resolve();
}else{
return Promise.reject(t("Doesn't match"));
}
},
() => { /* click on cancel */ });
}
onDeleteConfirm(answer){
if(answer === this._confirm_delete_text()){
this.setState({icon: 'loading', delete_request: false});
this.props.emit(
'file.delete',
pathBuilder(this.props.path, this.props.file.name, this.props.file.type),
this.props.file.type
);
}else{
this.setState({delete_error: t("Doesn't match")});
}
}
onDeleteCancel(){
this.setState({delete_request: false});
}
onShareRequest(filename){
alert.now(