diff options
Diffstat (limited to 'src/client')
-rw-r--r-- | src/client/documents/Documents.ts | 2 | ||||
-rw-r--r-- | src/client/util/Import & Export/DirectoryImportBox.tsx | 12 | ||||
-rw-r--r-- | src/client/util/Import & Export/ImageUtils.ts | 31 | ||||
-rw-r--r-- | src/client/views/collections/CollectionSubView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/collections/CollectionView.tsx | 2 |
5 files changed, 45 insertions, 4 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 34e146f0e..9d1a6ed3e 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -256,7 +256,7 @@ export namespace Docs { let title = prototypeId.toUpperCase().replace(upper, `_${upper}`); // synthesize the default options, the type and title from computed values and // whatever options pertain to this specific prototype - let options = { title: title, type: type, baseProto: true, ...defaultOptions, ...(template.options || {}) }; + let options = { title, type, baseProto: true, ...defaultOptions, ...(template.options || {}) }; let primary = layout.view.LayoutString(layout.ext); let collectionView = layout.collectionView; if (collectionView) { diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx index d3f81b992..d74b51993 100644 --- a/src/client/util/Import & Export/DirectoryImportBox.tsx +++ b/src/client/util/Import & Export/DirectoryImportBox.tsx @@ -22,13 +22,15 @@ import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField"; import "./DirectoryImportBox.scss"; import { Identified } from "../../Network"; import { BatchedArray } from "array-batcher"; +import { ExifData } from "exif"; const unsupported = ["text/html", "text/plain"]; -interface FileResponse { +interface ImageUploadResponse { name: string; path: string; type: string; + exif: any; } @observer @@ -117,7 +119,7 @@ export default class DirectoryImportBox extends React.Component<FieldViewProps> const responses = await Identified.PostFormDataToServer(RouteStore.upload, formData); runInAction(() => this.completed += batch.length); - return responses as FileResponse[]; + return responses as ImageUploadResponse[]; }); await Promise.all(uploads.map(async upload => { @@ -129,7 +131,11 @@ export default class DirectoryImportBox extends React.Component<FieldViewProps> title: upload.name }; const document = await Docs.Get.DocumentFromType(type, path, options); - document && docs.push(document); + const { data, error } = upload.exif; + if (document) { + Doc.GetProto(document).exif = error || Docs.Get.DocumentHierarchyFromJson(data); + docs.push(document); + } })); for (let i = 0; i < docs.length; i++) { diff --git a/src/client/util/Import & Export/ImageUtils.ts b/src/client/util/Import & Export/ImageUtils.ts new file mode 100644 index 000000000..c9abf38fa --- /dev/null +++ b/src/client/util/Import & Export/ImageUtils.ts @@ -0,0 +1,31 @@ +import { Doc, DocListCast, DocListCastAsync, Opt } from "../../../new_fields/Doc"; +import { ImageField } from "../../../new_fields/URLField"; +import { Cast, StrCast } from "../../../new_fields/Types"; +import { RouteStore } from "../../../server/RouteStore"; +import { Docs } from "../../documents/Documents"; +import { Identified } from "../../Network"; +import { Id } from "../../../new_fields/FieldSymbols"; +import { Utils } from "../../../Utils"; + +export namespace ImageUtils { + + export const ExtractExif = async (document: Doc): Promise<boolean> => { + const field = Cast(document.data, ImageField); + if (!field) { + return false; + } + const source = field.url.href; + const response = await Identified.PostToServer(RouteStore.inspectImage, { source }); + const { error, data } = response.exifData; + document.exif = error || Docs.Get.DocumentHierarchyFromJson(data); + return data !== undefined; + }; + + export const ExportHierarchyToFileSystem = async (collection: Doc): Promise<void> => { + const a = document.createElement("a"); + a.href = Utils.prepend(`${RouteStore.imageHierarchyExport}/${collection[Id]}`); + a.download = `Dash Export [${StrCast(collection.title)}].zip`; + a.click(); + }; + +}
\ No newline at end of file diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 28d1eb384..2a536a0f4 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -24,6 +24,7 @@ import { CollectionView } from "./CollectionView"; import React = require("react"); var path = require('path'); import { GooglePhotos } from "../../apis/google_docs/GooglePhotosClientUtils"; +import { ImageUtils } from "../../util/Import & Export/ImageUtils"; export interface CollectionViewProps extends FieldViewProps { addDocument: (document: Doc, allowDuplicates?: boolean) => boolean; @@ -194,6 +195,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) { if (img) { let split = img.split("src=\"")[1].split("\"")[0]; let doc = Docs.Create.ImageDocument(split, { ...options, width: 300 }); + ImageUtils.ExtractExif(doc); this.props.addDocument(doc, false); return; } else { diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 534246326..893763840 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -18,6 +18,7 @@ import { CollectionSchemaView } from "./CollectionSchemaView"; import { CollectionStackingView } from './CollectionStackingView'; import { CollectionTreeView } from "./CollectionTreeView"; import { CollectionViewBaseChrome } from './CollectionViewChromes'; +import { ImageUtils } from '../../util/Import & Export/ImageUtils'; export const COLLECTION_BORDER_WIDTH = 2; library.add(faTh, faTree, faSquare, faProjectDiagram, faSignature, faThList, faFingerprint, faColumns, faEllipsisV, faImage, faEye as any, faCopy); @@ -123,6 +124,7 @@ export class CollectionView extends React.Component<FieldViewProps> { let layoutItems: ContextMenuProps[] = existing && "subitems" in existing ? existing.subitems : []; layoutItems.push({ description: `${this.props.Document.forceActive ? "Select" : "Force"} Contents Active`, event: () => this.props.Document.forceActive = !this.props.Document.forceActive, icon: "project-diagram" }); !existing && ContextMenu.Instance.addItem({ description: "Layout...", subitems: layoutItems, icon: "hand-point-right" }); + ContextMenu.Instance.addItem({ description: "Export Image Hierarchy", icon: "columns", event: () => ImageUtils.ExportHierarchyToFileSystem(this.props.Document) }); } } |