import "fs"; import React = require("react"); import { Doc } from "../../../new_fields/Doc"; import { DocServer } from "../../DocServer"; import { RouteStore } from "../../../server/RouteStore"; import { action, observable, autorun, runInAction } from "mobx"; import { FieldViewProps, FieldView } from "../../views/nodes/FieldView"; import Measure, { ContentRect } from "react-measure"; import { library } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faArrowUp, faTag, faPlus } from '@fortawesome/free-solid-svg-icons'; import { Docs, DocumentOptions } from "../../documents/Documents"; import { observer } from "mobx-react"; import KeyValue from "./KeyValue"; import { Utils } from "../../../Utils"; import { DocumentManager } from "../DocumentManager"; @observer export default class DirectoryImportBox extends React.Component { private selector = React.createRef(); @observable private top = 0; @observable private left = 0; private dimensions = 50; @observable private editingMetadata = false; @observable private metadata_guids: string[] = []; @observable private entries: KeyValue[] = []; @observable private quota = 1; @observable private remaining = 1; @observable private uploadBegun = false; public static LayoutString() { return FieldView.LayoutString(DirectoryImportBox); } constructor(props: FieldViewProps) { super(props); library.add(faArrowUp, faTag, faPlus); } @action handleSelection = async (e: React.ChangeEvent) => { this.uploadBegun = true; let promises: Promise[] = []; let docs: Doc[] = []; let files = e.target.files; if (!files || files.length === 0) return; let directory = (files.item(0) as any).webkitRelativePath.split("/", 1); let validated: File[] = []; for (let i = 0; i < files.length; i++) { let file = files.item(i); file && validated.push(file); } this.quota = validated.length; for (let uploaded_file of validated) { if (!uploaded_file) { continue; } let formData = new FormData(); formData.append('file', uploaded_file); let dropFileName = uploaded_file ? uploaded_file.name : "-empty-"; let type = uploaded_file.type; this.remaining++; let prom = fetch(DocServer.prepend(RouteStore.upload), { method: 'POST', body: formData }).then(async (res: Response) => { (await res.json()).map(action((file: any) => { let path = DocServer.prepend(file); let docPromise = Docs.getDocumentFromType(type, path, { nativeWidth: 300, width: 300, title: dropFileName }); docPromise.then(doc => { doc && docs.push(doc) && runInAction(() => this.remaining--); }); })); }); promises.push(prom); } await Promise.all(promises); docs.forEach(doc => this.entries.forEach(entry => doc[entry.key] = entry.value)); let doc = this.props.Document; let options: DocumentOptions = { title: `Import of ${directory}`, width: 1105, height: 500, x: Doc.GetT(doc, "x", "number"), y: Doc.GetT(doc, "y", "number") }; let parent = this.props.ContainingCollectionView; if (parent) { let importContainer = Docs.StackingDocument(docs, options); importContainer.singleColumn = false; Doc.AddDocToList(Doc.GetProto(parent.props.Document), "data", importContainer); this.props.removeDocument && this.props.removeDocument(doc); DocumentManager.Instance.jumpToDocument(importContainer, true); } } componentDidMount() { this.selector.current!.setAttribute("directory", ""); this.selector.current!.setAttribute("webkitdirectory", ""); } @action preserveCentering = (rect: ContentRect) => { let bounds = rect.offset!; if (bounds.width === 0 || bounds.height === 0) { return; } let offset = this.dimensions / 2; this.left = bounds.width / 2 - offset; this.top = bounds.height / 2 - offset; } @action addMetadataEntry = () => { this.metadata_guids.push(Utils.GenerateGuid()); } @action remove = (entry: KeyValue) => { let index = this.entries.indexOf(entry); let key = entry.key; this.entries.splice(index, 1); this.metadata_guids.splice(this.metadata_guids.indexOf(key), 1); } render() { let dimensions = 50; let guids = this.metadata_guids.map(el => el); let isEditing = this.editingMetadata; let remaining = this.remaining; let quota = this.quota; let percent = `${100 - (remaining / quota * 100)}`; let uploadBegun = this.uploadBegun; percent = percent.split(".")[0]; percent = percent.startsWith("100") ? "99" : percent; return ( {({ measureRef }) =>