aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Wilkins <samwilkins333@gmail.com>2020-01-27 05:50:15 -0500
committerSam Wilkins <samwilkins333@gmail.com>2020-01-27 05:50:15 -0500
commitc5d618538d4fd9669476dc7eb66ddd45783e5fa6 (patch)
tree79655ab3296881416ad78f9eb265a6df1e807f1e
parentb2aa0b80843e6e58f737e2937c45351d653255fa (diff)
nativewidth and nativeheight extension key fix and implemented UI to manually download a remotely hosted image
-rw-r--r--src/client/util/Import & Export/DirectoryImportBox.tsx4
-rw-r--r--src/client/util/Import & Export/ImageUtils.ts4
-rw-r--r--src/client/views/DocComponent.tsx2
-rw-r--r--src/client/views/collections/CollectionSubView.tsx2
-rw-r--r--src/client/views/nodes/AudioBox.tsx2
-rw-r--r--src/client/views/nodes/ImageBox.scss24
-rw-r--r--src/client/views/nodes/ImageBox.tsx28
-rw-r--r--src/mobile/ImageUpload.tsx2
-rw-r--r--src/server/ApiManagers/UploadManager.ts14
-rw-r--r--src/server/DashUploadUtils.ts12
10 files changed, 69 insertions, 25 deletions
diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx
index c7c94abed..071015193 100644
--- a/src/client/util/Import & Export/DirectoryImportBox.tsx
+++ b/src/client/util/Import & Export/DirectoryImportBox.tsx
@@ -116,13 +116,13 @@ export default class DirectoryImportBox extends React.Component<FieldViewProps>
formData.append(Utils.GenerateGuid(), file);
});
- collector.push(...(await Networking.PostFormDataToServer("/upload", formData)));
+ collector.push(...(await Networking.PostFormDataToServer("/uploadFormData", formData)));
runInAction(() => this.completed += batch.length);
});
await Promise.all(uploads.map(async ({ name, type, clientAccessPath, exifData }) => {
const path = Utils.prepend(clientAccessPath);
- const document = await Docs.Get.DocumentFromType(type, path, { width: 300, title: name });
+ const document = await Docs.Get.DocumentFromType(type, path, { _width: 300, title: name });
const { data, error } = exifData;
if (document) {
Doc.GetProto(document).exif = error || Docs.Get.DocumentHierarchyFromJson(data);
diff --git a/src/client/util/Import & Export/ImageUtils.ts b/src/client/util/Import & Export/ImageUtils.ts
index 2f4db0e17..ff909cc6b 100644
--- a/src/client/util/Import & Export/ImageUtils.ts
+++ b/src/client/util/Import & Export/ImageUtils.ts
@@ -22,8 +22,8 @@ export namespace ImageUtils {
} = await Networking.PostToServer("/inspectImage", { source });
document.exif = error || Docs.Get.DocumentHierarchyFromJson(data);
const proto = Doc.GetProto(document);
- proto.nativeWidth = nativeWidth;
- proto.nativeHeight = nativeHeight;
+ proto["data-nativeWidth"] = nativeWidth;
+ proto["data-nativeHeight"] = nativeHeight;
proto.contentSize = contentSize;
return data !== undefined;
};
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index d98301cf6..6f3eb6808 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -61,7 +61,7 @@ export function DocAnnotatableComponent<P extends DocAnnotatableProps, T>(schema
_annotationKey: string = "annotations";
public set annotationKey(val: string) { this._annotationKey = val; }
- public get annotationKey() { return this._annotationKey }
+ public get annotationKey() { return this._annotationKey; }
@action.bound
removeDocument(doc: Doc): boolean {
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index b96b86929..80fcc33aa 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -324,7 +324,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
formData.append('file', file);
const dropFileName = file ? file.name : "-empty-";
- promises.push(Networking.PostFormDataToServer("/upload", formData).then(results => {
+ promises.push(Networking.PostFormDataToServer("/uploadFormData", formData).then(results => {
results.map(action((result: any) => {
const { clientAccessPath, nativeWidth, nativeHeight, contentSize } = result;
const full = { ...options, _width: 300, title: dropFileName };
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 8ede79edc..62a479b2a 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -138,7 +138,7 @@ export class AudioBox extends DocExtendableComponent<FieldViewProps, AudioDocume
self._recorder.ondataavailable = async function (e: any) {
const formData = new FormData();
formData.append("file", e.data);
- const res = await fetch(Utils.prepend("/upload"), {
+ const res = await fetch(Utils.prepend("/uploadFormData"), {
method: 'POST',
body: formData
});
diff --git a/src/client/views/nodes/ImageBox.scss b/src/client/views/nodes/ImageBox.scss
index cf5d999a7..43f4a0ba9 100644
--- a/src/client/views/nodes/ImageBox.scss
+++ b/src/client/views/nodes/ImageBox.scss
@@ -1,10 +1,12 @@
-.imageBox, .imageBox-dragging{
+.imageBox,
+.imageBox-dragging {
pointer-events: all;
border-radius: inherit;
- width:100%;
- height:100%;
+ width: 100%;
+ height: 100%;
position: absolute;
transform-origin: top left;
+
.imageBox-fader {
pointer-events: all;
}
@@ -16,6 +18,14 @@
}
}
+#upload-icon {
+ position: absolute;
+ bottom: 0;
+ right: 0;
+ width: 20px;
+ height: 20px;
+}
+
.imageBox-cont {
padding: 0vw;
position: absolute;
@@ -25,7 +35,8 @@
max-width: 100%;
max-height: 100%;
pointer-events: none;
- background:transparent;
+ background: transparent;
+
img {
height: auto;
width: 100%;
@@ -55,9 +66,10 @@
padding: 3px;
background: white;
cursor: pointer;
- opacity:0.15;
+ opacity: 0.15;
}
-#google-photos:hover{
+
+#google-photos:hover {
opacity: 1;
}
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 8db66d367..3d15bcb15 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -29,6 +29,7 @@ import { TraceMobx } from '../../../new_fields/util';
import { SelectionManager } from '../../util/SelectionManager';
import { cache } from 'sharp';
import { ObjectField } from '../../../new_fields/ObjectField';
+import { Networking } from '../../Network';
const requestImageSize = require('../../util/request-image-size');
const path = require('path');
const { Howl } = require('howler');
@@ -104,7 +105,7 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
recorder.ondataavailable = async function (e: any) {
const formData = new FormData();
formData.append("file", e.data);
- const res = await fetch(Utils.prepend("/upload"), {
+ const res = await fetch(Utils.prepend("/uploadFormData"), {
method: 'POST',
body: formData
});
@@ -287,6 +288,30 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
return !tags ? (null) : (<img id={"google-tags"} src={"/assets/google_tags.png"} />);
}
+ @computed
+ private get considerDownloadIcon() {
+ const data = this.dataDoc[this.props.fieldKey];
+ if (!(data instanceof ImageField)) {
+ return (null);
+ }
+ const primary = data.url.href;
+ if (primary.includes(window.location.origin)) {
+ return (null);
+ }
+ return (
+ <img
+ id={"upload-icon"}
+ src={"/assets/downarrow.png"}
+ onClick={async () => {
+ const { dataDoc } = this;
+ const [{ clientAccessPath }] = await Networking.PostToServer("/uploadRemoteImage", { sources: [primary] });
+ dataDoc.originalUrl = primary;
+ dataDoc[this.props.fieldKey] = new ImageField(Utils.prepend(clientAccessPath));
+ }}
+ />
+ );
+ }
+
@computed get nativeSize() {
const pw = typeof this.props.PanelWidth === "function" ? this.props.PanelWidth() : typeof this.props.PanelWidth === "number" ? (this.props.PanelWidth as any) as number : 50;
const nativeWidth = NumCast(this.dataDoc[this.props.fieldKey + "-nativeWidth"], pw);
@@ -347,6 +372,7 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
style={{ color: [DocListCast(this.dataDoc[this.props.fieldKey + "-audioAnnotations"]).length ? "blue" : "gray", "green", "red"][this._audioState] }}
icon={!DocListCast(this.dataDoc[this.props.fieldKey + "-audioAnnotations"]).length ? "microphone" : faFileAudio} size="sm" />
</div>
+ {this.considerDownloadIcon}
{this.considerGooglePhotosLink()}
<FaceRectangles document={this.dataDoc} color={"#0000FF"} backgroundColor={"#0000FF"} />
</div>;
diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx
index dab4de110..1583e3d5d 100644
--- a/src/mobile/ImageUpload.tsx
+++ b/src/mobile/ImageUpload.tsx
@@ -45,7 +45,7 @@ class Uploader extends React.Component {
const formData = new FormData();
formData.append("file", files[0]);
- const upload = window.location.origin + "/upload";
+ const upload = window.location.origin + "/uploadFormData";
this.status = "uploading image";
const res = await fetch(upload, {
method: 'POST',
diff --git a/src/server/ApiManagers/UploadManager.ts b/src/server/ApiManagers/UploadManager.ts
index 583eaa59b..a92b613b7 100644
--- a/src/server/ApiManagers/UploadManager.ts
+++ b/src/server/ApiManagers/UploadManager.ts
@@ -40,7 +40,7 @@ export default class UploadManager extends ApiManager {
register({
method: Method.POST,
- subscription: "/upload",
+ subscription: "/uploadFormData",
secureHandler: async ({ req, res }) => {
const form = new formidable.IncomingForm();
form.uploadDir = pathToDirectory(Directory.parsed_files);
@@ -61,6 +61,18 @@ export default class UploadManager extends ApiManager {
register({
method: Method.POST,
+ subscription: "/uploadRemoteImage",
+ secureHandler: async ({ req, res }) => {
+ const { sources } = req.body;
+ if (Array.isArray(sources)) {
+ return res.send(await Promise.all(sources.map(url => DashUploadUtils.UploadImage(url))));
+ }
+ res.send();
+ }
+ });
+
+ register({
+ method: Method.POST,
subscription: "/uploadDoc",
secureHandler: ({ req, res }) => {
const form = new formidable.IncomingForm();
diff --git a/src/server/DashUploadUtils.ts b/src/server/DashUploadUtils.ts
index b826b4882..cb7104757 100644
--- a/src/server/DashUploadUtils.ts
+++ b/src/server/DashUploadUtils.ts
@@ -108,13 +108,7 @@ export namespace DashUploadUtils {
return MoveParsedFile(absolutePath, Directory.pdfs);
}
- const generate = (prefix: string, url: string) => `${prefix}upload_${Utils.GenerateGuid()}${sanitizeExtension(url)}`;
- const sanitizeExtension = (source: string) => {
- let extension = path.extname(source);
- extension = extension.toLowerCase();
- extension = extension.split("?")[0];
- return extension;
- };
+ const generate = (prefix: string, extension: string) => `${prefix}upload_${Utils.GenerateGuid()}.${extension}`;
/**
* Uploads an image specified by the @param source to Dash's /public/files/
@@ -209,8 +203,8 @@ export namespace DashUploadUtils {
export const UploadInspectedImage = async (metadata: InspectionResults, filename?: string, format?: string, prefix = ""): Promise<ImageUploadInformation> => {
const { requestable, source, ...remaining } = metadata;
- const resolved = filename || generate(prefix, requestable);
- const extension = format || sanitizeExtension(requestable || resolved);
+ const extension = remaining.contentType.toLowerCase().split("/")[1]; //format || sanitizeExtension(requestable || resolved);
+ const resolved = filename || generate(prefix, extension);
const information: ImageUploadInformation = {
clientAccessPath: clientPathToFile(Directory.images, resolved),
serverAccessPaths: {},