diff options
author | tschicke-brown <tyler_schicke@brown.edu> | 2019-03-11 12:45:15 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-11 12:45:15 -0400 |
commit | f27de3bfc5a4b5c56e884cfcddff15a047b2519e (patch) | |
tree | 56f46c3f547d775d0cc6005ab97c2978e85cbb74 | |
parent | 3874dd9ea6efb96f01c32827d2d2fc103d66d57b (diff) | |
parent | 2bf52426b853dfa6ae9c24c2f1e5d493c524139a (diff) |
Merge pull request #47 from browngraphicslab/upload
Upload
-rw-r--r-- | package-lock.json | 19 | ||||
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | src/client/views/InkingControl.tsx | 2 | ||||
-rw-r--r-- | src/client/views/Main.tsx | 10 | ||||
-rw-r--r-- | src/client/views/collections/CollectionViewBase.tsx | 68 | ||||
-rw-r--r-- | src/server/index.ts | 22 |
6 files changed, 99 insertions, 24 deletions
diff --git a/package-lock.json b/package-lock.json index 9343a2e88..88878cf1f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -141,6 +141,11 @@ "@types/express": "*" } }, + "@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==" + }, "@types/express": { "version": "4.16.1", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.16.1.tgz", @@ -194,6 +199,15 @@ "@types/node": "*" } }, + "@types/formidable": { + "version": "1.0.31", + "resolved": "https://registry.npmjs.org/@types/formidable/-/formidable-1.0.31.tgz", + "integrity": "sha512-dIhM5t8lRP0oWe2HF8MuPvdd1TpPTjhDMAqemcq6oIZQCBQTovhBAdTQ5L5veJB4pdQChadmHuxtB0YzqvfU3Q==", + "requires": { + "@types/events": "*", + "@types/node": "*" + } + }, "@types/jquery": { "version": "3.3.29", "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.29.tgz", @@ -3370,6 +3384,11 @@ "mime-types": "^2.1.12" } }, + "formidable": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.1.tgz", + "integrity": "sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg==" + }, "forwarded": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", diff --git a/package.json b/package.json index a89d82645..0179e89d3 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "@types/express-flash": "0.0.0", "@types/express-session": "^1.15.12", "@types/express-validator": "^3.0.0", + "@types/formidable": "^1.0.31", "@types/jquery": "^3.3.29", "@types/jsonwebtoken": "^8.3.2", "@types/lodash": "^4.14.121", @@ -83,6 +84,7 @@ "express-validator": "^5.3.1", "expressjs": "^1.0.1", "flexlayout-react": "^0.3.3", + "formidable": "^1.2.1", "golden-layout": "^1.5.9", "html-to-image": "^0.1.0", "i": "^0.3.6", diff --git a/src/client/views/InkingControl.tsx b/src/client/views/InkingControl.tsx index 929fb42a1..955831fb6 100644 --- a/src/client/views/InkingControl.tsx +++ b/src/client/views/InkingControl.tsx @@ -1,5 +1,5 @@ import { observable, action, computed } from "mobx"; -import { CirclePicker, ColorResult } from 'react-color' +import { CirclePicker, ColorResult } from 'react-color'; import React = require("react"); import "./InkingCanvas.scss" import { InkTool } from "../../fields/InkField"; diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 6f08566bc..b78f59681 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -55,16 +55,16 @@ Documents.initProtos(mainDocId, (res?: Document) => { let pdfurl = "http://www.adobe.com/support/products/enterprise/knowledgecenter/media/c4611_sample_explain.pdf" let weburl = "https://cs.brown.edu/courses/cs166/"; let audiourl = "http://techslides.com/demos/samples/sample.mp3"; - let videourl = "http://techslides.com/demos/sample-videos/small.mp4"; + let videourl = "http://techslides.com/demos/sample-videos/small.mp4"; let clearDatabase = action(() => Utils.Emit(Server.Socket, MessageStore.DeleteAll, {})) let addTextNode = action(() => Documents.TextDocument({ width: 200, height: 200, title: "a text note" })) let addColNode = action(() => Documents.FreeformDocument([], { width: 200, height: 200, title: "a freeform collection" })); let addSchemaNode = action(() => Documents.SchemaDocument([Documents.TextDocument()], { width: 200, height: 200, title: "a schema collection" })); - let addVideoNode = action(() => Documents.VideoDocument(videourl, {width: 200, height:200, title: "video node"})); + let addVideoNode = action(() => Documents.VideoDocument(videourl, { width: 200, height: 200, title: "video node" })); let addPDFNode = action(() => Documents.PdfDocument(pdfurl, { width: 200, height: 200, title: "a schema collection" })); let addImageNode = action(() => Documents.ImageDocument(imgurl, { width: 200, height: 200, title: "an image of a cat" })); let addWebNode = action(() => Documents.WebDocument(weburl, { width: 200, height: 200, title: "a sample web page" })); - let addAudioNode = action(() => Documents.AudioDocument(audiourl,{ width: 200, height: 200, title: "audio node" } )) + let addAudioNode = action(() => Documents.AudioDocument(audiourl, { width: 200, height: 200, title: "audio node" })) let addClick = (creator: () => Document) => action(() => mainfreeform.GetList<Document>(KeyStore.Data, []).push(creator()) ); @@ -74,8 +74,8 @@ Documents.initProtos(mainDocId, (res?: Document) => { let webRef = React.createRef<HTMLDivElement>(); let textRef = React.createRef<HTMLDivElement>(); let schemaRef = React.createRef<HTMLDivElement>(); - let videoRef = React.createRef<HTMLDivElement>(); - let audioRef = React.createRef<HTMLDivElement>(); + let videoRef = React.createRef<HTMLDivElement>(); + let audioRef = React.createRef<HTMLDivElement>(); let colRef = React.createRef<HTMLDivElement>(); ReactDOM.render(( diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx index 0a3b965f2..38271e7bf 100644 --- a/src/client/views/collections/CollectionViewBase.tsx +++ b/src/client/views/collections/CollectionViewBase.tsx @@ -1,4 +1,4 @@ -import { action } from "mobx"; +import { action, runInAction } from "mobx"; import { Document } from "../../../fields/Document"; import { ListField } from "../../../fields/ListField"; import React = require("react"); @@ -11,6 +11,7 @@ import { Documents, DocumentOptions } from "../../documents/Documents"; import { Key } from "../../../fields/Key"; import { Transform } from "../../util/Transform"; import { CollectionView } from "./CollectionView"; +import * as request from "request"; export interface CollectionViewProps { fieldKey: Key; @@ -68,13 +69,17 @@ export class CollectionViewBase extends React.Component<SubCollectionViewProps> let html = e.dataTransfer.getData("text/html"); let text = e.dataTransfer.getData("text/plain"); if (html && html.indexOf("<img") != 0) { + console.log("not good"); let htmlDoc = Documents.HtmlDocument(html, { ...options, width: 300, height: 300 }); htmlDoc.SetText(KeyStore.DocumentText, text); this.props.addDocument(htmlDoc); return; } + console.log(e.dataTransfer.items.length); + for (let i = 0; i < e.dataTransfer.items.length; i++) { + const upload = window.location.origin + "/upload"; let item = e.dataTransfer.items[i]; if (item.kind === "string" && item.type.indexOf("uri") != -1) { e.dataTransfer.items[i].getAsString(function (s) { @@ -93,28 +98,55 @@ export class CollectionViewBase extends React.Component<SubCollectionViewProps> }) } - if (item.kind == "file" && item.type.indexOf("image")) { + let type = item.type + console.log(type) + if (item.kind == "file") { let fReader = new FileReader() let file = item.getAsFile(); - - fReader.addEventListener("load", action("drop", () => { - if (fReader.result) { - let url = "" + fReader.result; - let doc = Documents.ImageDocument(url, options) - let docs = that.props.Document.GetT(KeyStore.Data, ListField); - if (docs != FieldWaiting) { - if (!docs) { - docs = new ListField<Document>(); - that.props.Document.Set(KeyStore.Data, docs) - } - docs.Data.push(doc); - } - } - }), false) + let formData = new FormData() if (file) { - fReader.readAsDataURL(file) + formData.append('file', file) } + + fetch(upload, { + method: 'POST', + body: formData + }) + .then((res: Response) => { + return res.json() + }).then(json => { + + json.map((file: any) => { + let path = window.location.origin + file + runInAction(() => { + var doc: any; + + if (type.indexOf("image") !== -1) { + doc = Documents.ImageDocument(path, { ...options, nativeWidth: 300, width: 300, }) + } + if (type.indexOf("video") !== -1) { + doc = Documents.VideoDocument(path, { ...options, nativeWidth: 300, width: 300, }) + } + if (type.indexOf("audio") !== -1) { + doc = Documents.AudioDocument(path, { ...options, nativeWidth: 300, width: 300, }) + } + let docs = that.props.Document.GetT(KeyStore.Data, ListField); + if (docs != FieldWaiting) { + if (!docs) { + docs = new ListField<Document>(); + that.props.Document.Set(KeyStore.Data, docs) + } + if (doc) { + docs.Data.push(doc); + } + + } + }) + }) + }) + + } } } diff --git a/src/server/index.ts b/src/server/index.ts index 4c2e09661..0d0b65b22 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -4,6 +4,7 @@ import * as webpack from 'webpack' import * as wdm from 'webpack-dev-middleware'; import * as whm from 'webpack-hot-middleware'; import * as path from 'path' +import * as formidable from 'formidable' import * as passport from 'passport'; import { MessageStore, Message, SetFieldArgs, GetFieldArgs, Transferable } from "./Message"; import { Client } from './Client'; @@ -74,6 +75,27 @@ app.post("/signup", postSignup); app.get("/login", getLogin); app.post("/login", postLogin); +// IMAGE UPLOADING HANDLER +app.post("/upload", (req, res, err) => { + let form = new formidable.IncomingForm() + form.uploadDir = __dirname + "/public/files/" + form.keepExtensions = true + // let path = req.body.path; + console.log("upload") + form.parse(req, (err, fields, files) => { + console.log("parsing") + let names: any[] = []; + for (const name in files) { + let file = files[name]; + names.push(`/files/` + path.basename(file.path)); + } + res.send(names); + }); +}) + +app.use(express.static(__dirname + '/public')); +app.use('/images', express.static(__dirname + '/public')) + let FieldStore: ObservableMap<FieldId, Field> = new ObservableMap(); // define a route handler for the default home page |