import React, { createRef } from "react";
import path from "path";
import { Link } from "react-router-dom";
import { DragSource, DropTarget } from "react-dnd";
import "./thing.scss";
import { Card, NgIf, Icon, EventEmitter, img_placeholder, Input } from "../../components/";
import { pathBuilder, basename, filetype, prompt, alert, leftPad, getMimeType, debounce, memory } from "../../helpers/";
import { Files } from "../../model/";
import { ShareComponent } from "./share";
import { TagComponent } from "./tag";
import { t } from "../../locales/";
const canDrop = (props, monitor) => {
const 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;
};
const HOCDropTargetForFsFile = (Cmp) => {
const nativeFileTarget = {
canDrop,
drop(props, monitor) {
const path = pathBuilder(props.path, props.file.name, "directory");
props.emit(
"file.upload",
path,
monitor.getItem(),
);
},
};
return DropTarget(
"__NATIVE_FILE__",
nativeFileTarget,
(connect, monitor) => ({
connectDropNativeFile: connect.dropTarget(),
nativeFileIsOver: monitor.isOver(),
canDropNativeFile: monitor.canDrop(),
}),
)(Cmp);
};
const HOVDropTargetForVirtualFile = (Cmp) => {
const fileTarget = {
canDrop,
drop(props, monitor, component) {
const src = monitor.getItem();
const 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];
}),
};
}
},
};
return DropTarget(
"file",
fileTarget,
(connect, monitor) => ({
connectDropFile: connect.dropTarget(),
fileIsOver: monitor.isOver(),
canDropFile: monitor.canDrop(),
}),
)(Cmp);
};
const HOVDropSourceForVirtualFile = (Cmp) => {
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") {
const 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 new Error("unknown action");
}
}
},
};
return DragSource(
"file",
fileSource,
(connect, monitor) => ({
connectDragSource: connect.dragSource(),
isDragging: monitor.isDragging(),
}),
)(Cmp);
};
class ExistingThingComponent 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);
}
UNSAFE_componentWillReceiveProps(props) {
if (props.view !== this.props.view) {
this.updateThumbnail(props);
}
}
updateThumbnail(props) {
if (props.view === "grid" && props.icon !== "loading") {
const mimetype = getMimeType(props.file.path);
if (window.CONFIG.thumbnailer.indexOf(mimetype) !== -1) {
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 });
}
onTagRequest() {
alert.now(