aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Wilkins <samwilkins333@gmail.com>2019-08-01 02:31:07 -0400
committerSam Wilkins <samwilkins333@gmail.com>2019-08-01 02:31:07 -0400
commitcd02f494975ad44b85c08d3108f185edbea43258 (patch)
tree1c4f30004385d5ffc711032f51cb8cfc5be00898
parentec224416fc454c7fdbb62943408226c973d8c751 (diff)
parentd4accdd22cabdd78fc7bd76dd7ce3cb59e4b102f (diff)
Merge branch 'master' into speech-to-text
-rw-r--r--.vscode/launch.json4
-rw-r--r--src/client/DocServer.ts27
-rw-r--r--src/client/util/SelectionManager.ts1
-rw-r--r--src/client/util/SerializationHelper.ts5
-rw-r--r--src/client/views/DocumentDecorations.tsx4
-rw-r--r--src/client/views/collections/CollectionSchemaView.scss8
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx1
-rw-r--r--src/client/views/collections/CollectionStackingView.scss31
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx4
-rw-r--r--src/client/views/collections/CollectionStackingViewFieldColumn.tsx8
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx358
-rw-r--r--src/client/views/collections/CollectionView.tsx3
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx3
-rw-r--r--src/client/views/nodes/ImageBox.tsx2
-rw-r--r--src/new_fields/Doc.ts49
-rw-r--r--src/new_fields/util.ts3
-rw-r--r--src/server/authentication/models/current_user_utils.ts2
-rw-r--r--src/server/index.ts23
18 files changed, 259 insertions, 277 deletions
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 822a06024..e4196600e 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -25,10 +25,6 @@
{
"type": "chrome",
"request": "launch",
- "runtimeArgs": [
- "--enable-logging",
- "--v=1"
- ],
"name": "Launch Chrome against Dash server",
"sourceMaps": true,
"breakOnLoad": true,
diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts
index 258acd9cd..fc39fa364 100644
--- a/src/client/DocServer.ts
+++ b/src/client/DocServer.ts
@@ -124,16 +124,17 @@ export namespace DocServer {
// future .proto calls on the Doc won't have to go farther than the cache to get their actual value.
const deserializeField = getSerializedField.then(async fieldJson => {
// deserialize
- const field = await SerializationHelper.Deserialize(fieldJson);
+ const field = await SerializationHelper.Deserialize(fieldJson, val => {
+ if (val !== undefined) {
+ _cache[id] = val;
+ } else {
+ delete _cache[id];
+ }
+ });
+ return field;
// either way, overwrite or delete any promises cached at this id (that we inserted as flags
// to indicate that the field was in the process of being fetched). Now everything
// should be an actual value within or entirely absent from the cache.
- if (field !== undefined) {
- _cache[id] = field;
- } else {
- delete _cache[id];
- }
- return field;
});
// here, indicate that the document associated with this id is currently
// being retrieved and cached
@@ -214,15 +215,23 @@ export namespace DocServer {
const deserializeFields = getSerializedFields.then(async fields => {
const fieldMap: { [id: string]: RefField } = {};
// const protosToLoad: any = [];
+ const proms: Promise<RefField>[] = [];
for (const field of fields) {
if (field !== undefined) {
// deserialize
- let deserialized = await SerializationHelper.Deserialize(field);
- fieldMap[field.id] = deserialized;
+ let prom = SerializationHelper.Deserialize(field, val => {
+ if (val !== undefined) {
+ _cache[field.id] = field;
+ } else {
+ delete _cache[field.id];
+ }
+ }).then(deserialized => fieldMap[field.id] = deserialized);
+ proms.push(prom);
// adds to a list of promises that will be awaited asynchronously
// protosToLoad.push(deserialized.proto);
}
}
+ await Promise.all(proms);
// this actually handles the loading of prototypes
// await Promise.all(protosToLoad);
return fieldMap;
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index 9efef888d..ee623d082 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -4,6 +4,7 @@ import { DocumentView } from "../views/nodes/DocumentView";
import { FormattedTextBox } from "../views/nodes/FormattedTextBox";
import { NumCast, StrCast } from "../../new_fields/Types";
import { InkingControl } from "../views/InkingControl";
+import { CurrentUserUtils } from "../../server/authentication/models/current_user_utils";
export namespace SelectionManager {
diff --git a/src/client/util/SerializationHelper.ts b/src/client/util/SerializationHelper.ts
index 034be8f67..13302be21 100644
--- a/src/client/util/SerializationHelper.ts
+++ b/src/client/util/SerializationHelper.ts
@@ -1,6 +1,7 @@
import { PropSchema, serialize, deserialize, custom, setDefaultModelSchema, getDefaultModelSchema, primitive, SKIP } from "serializr";
import { Field, Doc } from "../../new_fields/Doc";
import { ClientUtils } from "./ClientUtils";
+import { emptyFunction } from "../../Utils";
let serializing = 0;
export function afterDocDeserialize(cb: (err: any, val: any) => void, err: any, newValue: any) {
@@ -33,7 +34,7 @@ export namespace SerializationHelper {
return json;
}
- export async function Deserialize(obj: any): Promise<any> {
+ export async function Deserialize(obj: any, cb: (val: any) => void = emptyFunction): Promise<any> {
if (obj === undefined || obj === null) {
return undefined;
}
@@ -56,7 +57,7 @@ export namespace SerializationHelper {
}
const type = serializationTypes[obj.__type];
- const value = await new Promise(res => deserialize(type.ctor, obj, (err, result) => res(result)));
+ const value = await new Promise(res => cb(deserialize(type.ctor, obj, (err, result) => res(result))));
if (type.afterDeserialize) {
await type.afterDeserialize(value);
}
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 40f2c3da9..eccfc7c30 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -29,6 +29,7 @@ import { LinkManager } from '../util/LinkManager';
import { ObjectField } from '../../new_fields/ObjectField';
import { MetadataEntryMenu } from './MetadataEntryMenu';
import { ImageBox } from './nodes/ImageBox';
+import { CurrentUserUtils } from '../../server/authentication/models/current_user_utils';
const higflyout = require("@hig/flyout");
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
@@ -144,7 +145,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
@computed
get Bounds(): { x: number, y: number, b: number, r: number } {
return SelectionManager.SelectedDocuments().reduce((bounds, documentView) => {
- if (documentView.props.renderDepth === 0) {
+ if (documentView.props.renderDepth === 0 ||
+ Doc.AreProtosEqual(documentView.props.Document, CurrentUserUtils.UserDocument)) {
return bounds;
}
let transform = (documentView.props.ScreenToLocalTransform().scale(documentView.props.ContentScaling())).inverse();
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index 3c4279eea..01744fb34 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -56,6 +56,10 @@
background: gray;
cursor: col-resize;
}
+
+ .documentView-node:first-child {
+ background: $light-color;
+ }
}
.ReactTable {
@@ -171,10 +175,6 @@
display: inline-block;
}
-.documentView-node:first-child {
- background: $light-color;
-}
-
.collectionSchema-col {
height: 100%;
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 4d6bf437f..9efd0d3ec 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -980,6 +980,7 @@ export class CollectionSchemaPreview extends React.Component<CollectionSchemaPre
style={{
transform: `translate(${this.centeringOffset}px, 0px)`,
borderRadius: this.borderRounding,
+ display: "inline",
height: "100%"
}}>
<DocumentView
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index 14c7f5edd..015955816 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -141,7 +141,7 @@
.collectionStackingView-colorPicker {
width: 78px;
-
+
.colorOptions {
display: flex;
flex-wrap: wrap;
@@ -153,7 +153,7 @@
height: 20px;
border-radius: 10px;
margin: 3px;
-
+
&.active {
border: 2px solid white;
box-shadow: 0 0 0 2px lightgray;
@@ -225,19 +225,20 @@
.rc-switch {
position: absolute;
display: inline-block;
- bottom: 15px;
- right: 15px;
- width: 125px;
- height: 54px;
+ bottom: 4px;
+ right: 4px;
+ width: 70px;
+ height: 30px;
border-radius: 40px 40px;
+ background-color: lightslategrey;
}
.rc-switch:after {
position: absolute;
- width: 36px;
- height: 36px;
- left: 7px;
- top: 9px;
+ width: 22px;
+ height: 22px;
+ left: 3px;
+ top: 4px;
border-radius: 50% 50%;
background-color: #fff;
content: " ";
@@ -253,19 +254,19 @@
}
.rc-switch-checked:after {
- left: 80px;
+ left: 44px;
}
.rc-switch-inner {
color: #fff;
- font-size: 22px;
+ font-size: 12px;
position: absolute;
- left: 50px;
- top: 14px;
+ left: 28px;
+ top: 8px;
}
.rc-switch-checked .rc-switch-inner {
- left: 17px;
+ left: 8px;
}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 5cfcc3d4b..9741b9e89 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -301,9 +301,9 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
{this.props.Document.sectionFilter ? Array.from(this.Sections.entries()).sort(this.sortFunc).
map(section => this.section(section[0], section[1])) :
this.section(undefined, this.filteredChildren)}
- {(this.props.Document.sectionFilter && this.props.CollectionView.props.Document.chromeStatus !== 'view-mode') ?
+ {(this.props.Document.sectionFilter && (this.props.CollectionView.props.Document.chromeStatus !== 'view-mode' && this.props.CollectionView.props.Document.chromeStatus !== 'disabled')) ?
<div key={`${this.props.Document[Id]}-addGroup`} className="collectionStackingView-addGroupButton"
- style={{ width: (this.columnWidth / (headings.length + (this.props.CollectionView.props.Document.chromeStatus !== 'view-mode' ? 1 : 0))) - 10, marginTop: 10 }}>
+ style={{ width: (this.columnWidth / (headings.length + ((this.props.CollectionView.props.Document.chromeStatus !== 'view-mode' && this.props.CollectionView.props.Document.chromeStatus !== 'disabled') ? 1 : 0))) - 10, marginTop: 10 }}>
<EditableView {...editableViewProps} />
</div> : null}
{this.props.CollectionView.props.Document.chromeStatus !== 'disabled' ? <Switch
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index 460359908..df03da376 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -297,7 +297,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
style={{
width: (style.columnWidth) /
((uniqueHeadings.length +
- (this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'view-mode' ? 1 : 0)) || 1)
+ ((this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'view-mode' && this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'disabled') ? 1 : 0)) || 1)
}}>
{/* the default bucket (no key value) has a tooltip that describes what it is.
Further, it does not have a color and cannot be deleted. */}
@@ -328,7 +328,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
</div> : (null);
for (let i = 0; i < cols; i++) templatecols += `${style.columnWidth}px `;
return (
- <div key={heading} style={{ width: `${100 / ((uniqueHeadings.length + (this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'view-mode' ? 1 : 0)) || 1)}%`, background: this._background }}
+ <div key={heading} style={{ width: `${100 / ((uniqueHeadings.length + ((this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'view-mode' && this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'disabled') ? 1 : 0)) || 1)}%`, background: this._background }}
ref={this.createColumnDropRef} onPointerEnter={this.pointerEntered} onPointerLeave={this.pointerLeave}>
{headingView}
<div key={`${heading}-stack`} className={`collectionStackingView-masonry${singleColumn ? "Single" : "Grid"}`}
@@ -346,9 +346,9 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
{this.children(this.props.docList)}
{singleColumn ? (null) : this.props.parent.columnDragger}
</div>
- {(this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'view-mode') ?
+ {(this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'view-mode' && this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'disabled') ?
<div key={`${heading}-add-document`} className="collectionStackingView-addDocumentButton"
- style={{ width: style.columnWidth / (uniqueHeadings.length + (this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'view-mode' ? 1 : 0)) }}>
+ style={{ width: style.columnWidth / (uniqueHeadings.length + 1) }}>
<EditableView {...newEditableViewProps} />
</div> : null}
</div>
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index b1e6eada0..7f5d78313 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -25,7 +25,6 @@ import { CollectionSchemaPreview } from './CollectionSchemaView';
import { CollectionSubView } from "./CollectionSubView";
import "./CollectionTreeView.scss";
import React = require("react");
-import { LinkManager } from '../../util/LinkManager';
import { ComputedField } from '../../../new_fields/ScriptField';
import { KeyValueBox } from '../nodes/KeyValueBox';
@@ -67,36 +66,24 @@ library.add(faPlus, faMinus);
* Component that takes in a document prop and a boolean whether it's collapsed or not.
*/
class TreeView extends React.Component<TreeViewProps> {
+ static loadId = "";
private _header?: React.RefObject<HTMLDivElement> = React.createRef();
private _treedropDisposer?: DragManager.DragDropDisposer;
private _dref = React.createRef<HTMLDivElement>();
- @computed get treeViewExpandedView() { return StrCast(this.props.document.treeViewExpandedView, "data"); }
- @computed get MAX_EMBED_HEIGHT() { return NumCast(this.props.document.maxEmbedHeight, 300); }
@observable _collapsed: boolean = true;
-
+ @computed get treeViewExpandedView() { return StrCast(this.props.document.treeViewExpandedView, "fields"); }
+ @computed get MAX_EMBED_HEIGHT() { return NumCast(this.props.document.maxEmbedHeight, 300); }
+ @computed get dataDoc() { return this.resolvedDataDoc ? this.resolvedDataDoc : this.props.document; }
@computed get fieldKey() {
- let target = this.props.document;
- let keys = Array.from(Object.keys(target)); // bcz: Argh -- make untracked to avoid this rerunning whenever 'libraryBrush' is set
- if (target.proto instanceof Doc) {
- let arr = Array.from(Object.keys(target.proto));// bcz: Argh -- make untracked to avoid this rerunning whenever 'libraryBrush' is set
- keys.push(...arr);
- while (keys.indexOf("proto") !== -1) keys.splice(keys.indexOf("proto"), 1);
- }
- let keyList: string[] = [];
- keys.map(key => {
- let docList = Cast(this.dataDoc[key], listSpec(Doc));
- if (docList && docList.length > 0) {
- keyList.push(key);
- }
- });
- let layout = StrCast(this.props.document.layout);
- if (layout.indexOf("fieldKey={\"") !== -1 && layout.indexOf("fieldExt=") === -1) {
- return layout.split("fieldKey={\"")[1].split("\"")[0];
- }
- return keyList.length ? keyList[0] : "data";
+ let splits = StrCast(this.props.document.layout).split("fieldKey={\"");
+ return splits.length > 1 ? splits[1].split("\"")[0] : "data";
+ }
+ @computed get childDocs() {
+ let layout = this.props.document.layout as Doc;
+ return (this.props.dataDoc ? Cast(this.props.dataDoc[this.fieldKey], listSpec(Doc)) : undefined) ||
+ (layout ? Cast(layout[this.fieldKey], listSpec(Doc)) : undefined) ||
+ Cast(this.props.document[this.fieldKey], listSpec(Doc));
}
-
- @computed get dataDoc() { return this.resolvedDataDoc ? this.resolvedDataDoc : this.props.document; }
@computed get resolvedDataDoc() {
if (this.props.dataDoc === undefined && this.props.document.layout instanceof Doc) {
// if there is no dataDoc (ie, we're not rendering a template layout), but this document
@@ -104,18 +91,32 @@ class TreeView extends React.Component<TreeViewProps> {
// this document as the data document for the layout.
return this.props.document;
}
- return this.props.dataDoc ? this.props.dataDoc : undefined;
+ return this.props.dataDoc;
+ }
+ @computed get boundsOfCollectionDocument() {
+ return StrCast(this.props.document.type).indexOf(DocumentType.COL) === -1 ? undefined :
+ Doc.ComputeContentBounds(DocListCast(this.props.document.data));
}
- protected createTreeDropTarget = (ele: HTMLDivElement) => {
- this._treedropDisposer && this._treedropDisposer();
- if (ele) {
- this._treedropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.treeDrop.bind(this) } });
+ @undoBatch delete = () => this.props.deleteDoc(this.dataDoc);
+ @undoBatch openRight = () => this.props.addDocTab(this.props.document, undefined, "onRight");
+ @undoBatch indent = () => this.props.addDocument(this.props.document) && this.delete();
+ @undoBatch move = (doc: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => {
+ return this.props.document !== target && this.props.deleteDoc(doc) && addDoc(doc);
+ }
+ @undoBatch @action remove = (document: Document, key: string): boolean => {
+ let children = Cast(this.dataDoc[key], listSpec(Doc), []);
+ if (children.indexOf(document) !== -1) {
+ children.splice(children.indexOf(document), 1);
+ return true;
}
+ return false;
}
- @undoBatch delete = () => this.props.deleteDoc(this.dataDoc);
- @undoBatch openRight = async () => this.props.addDocTab(this.props.document, undefined, "onRight");
+ protected createTreeDropTarget = (ele: HTMLDivElement) => {
+ this._treedropDisposer && this._treedropDisposer();
+ ele && (this._treedropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.treeDrop.bind(this) } }));
+ }
onPointerDown = (e: React.PointerEvent) => e.stopPropagation();
onPointerEnter = (e: React.PointerEvent): void => {
@@ -144,34 +145,6 @@ class TreeView extends React.Component<TreeViewProps> {
e.stopPropagation();
}
- @action
- remove = (document: Document, key: string): boolean => {
- let children = Cast(this.dataDoc[key], listSpec(Doc), []);
- if (children.indexOf(document) !== -1) {
- children.splice(children.indexOf(document), 1);
- return true;
- }
- return false;
- }
-
- @action
- move: DragManager.MoveFunction = (doc: Doc, target: Doc, addDoc) => {
- return this.props.document !== target && this.props.deleteDoc(doc) && addDoc(doc);
- }
- @action
- indent = () => this.props.addDocument(this.props.document) && this.delete()
-
- renderBullet() {
- let docList = Cast(this.dataDoc[this.fieldKey], listSpec(Doc));
- let doc = Cast(this.dataDoc[this.fieldKey], Doc);
- let isDoc = doc instanceof Doc || docList;
- let c;
- return <div className="bullet" onClick={action(() => this._collapsed = !this._collapsed)} style={{ color: StrCast(this.props.document.color, "black"), opacity: 0.4 }}>
- {<FontAwesomeIcon icon={this._collapsed ? (isDoc ? "caret-square-right" : "caret-right") : (isDoc ? "caret-square-down" : "caret-down")} />}
- </div>;
- }
-
- static loadId = "";
editableView = (key: string, style?: string) => (<EditableView
oneLine={true}
display={"inline"}
@@ -192,43 +165,6 @@ class TreeView extends React.Component<TreeViewProps> {
OnTab={() => this.props.indentDocument && this.props.indentDocument()}
/>)
- /**
- * Renders the EditableView title element for placement into the tree.
- */
- renderTitle() {
- let reference = React.createRef<HTMLDivElement>();
- let onItemDown = SetupDrag(reference, () => this.dataDoc, this.move, this.props.dropAction, this.props.treeViewId, true);
-
- let headerElements = (
- <span className="collectionTreeView-keyHeader" key={this.treeViewExpandedView}
- onPointerDown={action(() => {
- this.props.document.treeViewExpandedView = this.treeViewExpandedView === "data" ? "fields" :
- this.treeViewExpandedView === "fields" && this.props.document.layout ? "layout" : "data";
- this._collapsed = false;
- })}>
- {this.treeViewExpandedView}
- </span>);
- let dataDocs = CollectionDockingView.Instance ? Cast(CollectionDockingView.Instance.props.Document[this.fieldKey], listSpec(Doc), []) : [];
- let openRight = dataDocs && dataDocs.indexOf(this.dataDoc) !== -1 ? (null) : (
- <div className="treeViewItem-openRight" onPointerDown={this.onPointerDown} onClick={this.openRight}>
- <FontAwesomeIcon icon="angle-right" size="lg" />
- </div>);
- return <>
- <div className="docContainer" id={`docContainer-${this.props.parentKey}`} ref={reference} onPointerDown={onItemDown}
- style={{
- background: BoolCast(this.props.document.libraryBrush) ? "#06121212" : "0",
- outline: BoolCast(this.props.document.workspaceBrush) ? "dashed 1px #06123232" : undefined,
- pointerEvents: this.props.active() || SelectionManager.GetIsDragging() ? "all" : "none"
- }}
- >
- {this.editableView("title")}
- {/* {<div className="delete-button" onClick={this.delete}><FontAwesomeIcon icon="trash-alt" size="xs" /></div>} */}
- </div >
- {headerElements}
- {openRight}
- </>;
- }
-
onWorkspaceContextMenu = (e: React.MouseEvent): void => {
if (!e.isPropagationStopped()) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7
if (NumCast(this.props.document.viewType) !== CollectionViewType.Docking) {
@@ -289,39 +225,6 @@ class TreeView extends React.Component<TreeViewProps> {
let finalXf = this.props.ScreenToLocalTransform().translate(offset[0], offset[1]);
return finalXf;
}
-
- renderLinks = () => {
- let ele: JSX.Element[] = [];
- let remDoc = (doc: Doc) => this.remove(doc, this.fieldKey);
- let addDoc = (doc: Doc, addBefore?: Doc, before?: boolean) => Doc.AddDocToList(this.props.document, this.fieldKey, doc, addBefore, before);
- let groups = LinkManager.Instance.getRelatedGroupedLinks(this.props.document);
- groups.forEach((groupLinkDocs, groupType) => {
- // let destLinks = groupLinkDocs.map(d => LinkManager.Instance.getOppositeAnchor(d, this.props.document));
- let destLinks: Doc[] = [];
- groupLinkDocs.forEach((doc) => {
- let opp = LinkManager.Instance.getOppositeAnchor(doc, this.props.document);
- if (opp) {
- destLinks.push(opp);
- }
- });
- ele.push(
- <div key={"treeviewlink-" + groupType + "subtitle"}>
- <div className="collectionTreeView-subtitle">{groupType}:</div>
- {
- TreeView.GetChildElements(destLinks, this.props.treeViewId, this.props.document, this.props.dataDoc, "treeviewlink-" + groupType, addDoc, remDoc, this.move,
- this.props.dropAction, this.props.addDocTab, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, this.props.panelWidth, this.props.renderDepth)
- }
- </div>
- );
- });
- return ele;
- }
-
- @computed get boundsOfCollectionDocument() {
- if (StrCast(this.props.document.type).indexOf(DocumentType.COL) === -1) return undefined;
- let layoutDoc = this.props.document;
- return Doc.ComputeContentBounds(DocListCast(layoutDoc.data));
- }
docWidth = () => {
let aspect = NumCast(this.props.document.nativeHeight) / NumCast(this.props.document.nativeWidth);
if (aspect) return Math.min(this.props.document[WidthSym](), Math.min(this.MAX_EMBED_HEIGHT / aspect, this.props.panelWidth() - 5));
@@ -337,39 +240,29 @@ class TreeView extends React.Component<TreeViewProps> {
})());
}
- noOverlays = (doc: Doc) => ({ title: "", caption: "" });
-
- expandedField = (doc?: Doc) => {
- if (!doc) return <div />;
- let realDoc = doc;
-
+ expandedField = (doc: Doc) => {
let ids: { [key: string]: string } = {};
- Object.keys(doc).forEach(key => {
- if (!(key in ids) && realDoc[key] !== ComputedField.undefined) {
- ids[key] = key;
- }
- });
+ doc && Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key));
let rows: JSX.Element[] = [];
for (let key of Object.keys(ids).sort()) {
- let contents = realDoc[key] ? realDoc[key] : undefined;
+ let contents = doc[key];
let contentElement: JSX.Element[] | JSX.Element = [];
if (contents instanceof Doc || Cast(contents, listSpec(Doc))) {
- let docList = contents;
let remDoc = (doc: Doc) => this.remove(doc, key);
let addDoc = (doc: Doc, addBefore?: Doc, before?: boolean) => Doc.AddDocToList(this.dataDoc, key, doc, addBefore, before);
- contentElement = key === "links" ? this.renderLinks() :
- TreeView.GetChildElements(docList instanceof Doc ? [docList] : DocListCast(docList), this.props.treeViewId, realDoc, undefined, key, addDoc, remDoc, this.move,
- this.props.dropAction, this.props.addDocTab, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, this.props.panelWidth, this.props.renderDepth);
+ contentElement = TreeView.GetChildElements(contents instanceof Doc ? [contents] :
+ DocListCast(contents), this.props.treeViewId, doc, undefined, key, addDoc, remDoc, this.move,
+ this.props.dropAction, this.props.addDocTab, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, this.props.panelWidth, this.props.renderDepth);
} else {
contentElement = <EditableView
key="editableView"
- contents={contents ? contents.toString() : "null"}
+ contents={contents !== undefined ? contents.toString() : "null"}
height={13}
fontSize={12}
- GetValue={() => Field.toKeyValueString(realDoc, key)}
- SetValue={(value: string) => KeyValueBox.SetField(realDoc, key, value)} />;
+ GetValue={() => Field.toKeyValueString(doc, key)}
+ SetValue={(value: string) => KeyValueBox.SetField(doc, key, value)} />;
}
rows.push(<div style={{ display: "flex" }} key={key}>
<span style={{ fontWeight: "bold" }}>{key + ":"}</span>
@@ -380,56 +273,100 @@ class TreeView extends React.Component<TreeViewProps> {
return rows;
}
- render() {
- let contentElement: (JSX.Element | null) = null;
- let docList = Cast(this.dataDoc[this.fieldKey], listSpec(Doc));
- let remDoc = (doc: Doc) => this.remove(doc, this.fieldKey);
- let addDoc = (doc: Doc, addBefore?: Doc, before?: boolean) => Doc.AddDocToList(this.dataDoc, this.fieldKey, doc, addBefore, before);
+ noOverlays = (doc: Doc) => ({ title: "", caption: "" });
- if (!this._collapsed) {
- if (this.treeViewExpandedView === "data") {
- let doc = Cast(this.props.document[this.fieldKey], Doc);
- contentElement = <ul key={this.fieldKey + "more"}>
- {this.fieldKey === "links" ? this.renderLinks() :
- TreeView.GetChildElements(doc instanceof Doc ? [doc] : DocListCast(docList), this.props.treeViewId, this.props.document, this.resolvedDataDoc, this.fieldKey, addDoc, remDoc, this.move,
- this.props.dropAction, this.props.addDocTab, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, this.props.panelWidth, this.props.renderDepth)}
- </ul >;
- } else if (this.treeViewExpandedView === "fields") {
- contentElement = <ul><div ref={this._dref} style={{ display: "inline-block" }} key={this.props.document[Id] + this.props.document.title}>
- {this.expandedField(this.dataDoc)}
- </div></ul>;
- } else {
- let layoutDoc = this.props.document;
- contentElement = <div ref={this._dref} style={{ display: "inline-block", height: this.docHeight() }} key={this.props.document[Id] + this.props.document.title}>
- <CollectionSchemaPreview
- Document={layoutDoc}
- DataDocument={this.resolvedDataDoc}
- renderDepth={this.props.renderDepth}
- showOverlays={this.noOverlays}
- fitToBox={this.boundsOfCollectionDocument !== undefined}
- width={this.docWidth}
- height={this.docHeight}
- getTransform={this.docTransform}
- CollectionView={undefined}
- addDocument={emptyFunction as any}
- moveDocument={this.props.moveDocument}
- removeDocument={emptyFunction as any}
- active={this.props.active}
- whenActiveChanged={emptyFunction as any}
- addDocTab={this.props.addDocTab}
- setPreviewScript={emptyFunction}>
- </CollectionSchemaPreview>
- </div>;
- }
+ @computed get renderContent() {
+ if (this.treeViewExpandedView === this.fieldKey) {
+ let remDoc = (doc: Doc) => this.remove(doc, this.fieldKey);
+ let addDoc = (doc: Doc, addBefore?: Doc, before?: boolean) => Doc.AddDocToList(this.dataDoc, this.fieldKey, doc, addBefore, before);
+ return <ul key={this.fieldKey + "more"}>
+ {!this.childDocs ? (null) :
+ TreeView.GetChildElements(this.childDocs as Doc[], this.props.treeViewId, this.props.document.layout as Doc,
+ this.resolvedDataDoc, this.fieldKey, addDoc, remDoc, this.move,
+ this.props.dropAction, this.props.addDocTab, this.props.ScreenToLocalTransform,
+ this.props.outerXf, this.props.active, this.props.panelWidth, this.props.renderDepth)}
+ </ul >;
+ } else if (this.treeViewExpandedView === "fields") {
+ return <ul><div ref={this._dref} style={{ display: "inline-block" }} key={this.props.document[Id] + this.props.document.title}>
+ {this.dataDoc ? this.expandedField(this.dataDoc) : (null)}
+ </div></ul>;
+ } else {
+ let layoutDoc = this.props.document;
+ return <div ref={this._dref} style={{ display: "inline-block", height: this.docHeight() }} key={this.props.document[Id] + this.props.document.title}>
+ <CollectionSchemaPreview
+ Document={layoutDoc}
+ DataDocument={this.resolvedDataDoc}
+ renderDepth={this.props.renderDepth}
+ showOverlays={this.noOverlays}
+ fitToBox={this.boundsOfCollectionDocument !== undefined}
+ width={this.docWidth}
+ height={this.docHeight}
+ getTransform={this.docTransform}
+ CollectionView={undefined}
+ addDocument={emptyFunction as any}
+ moveDocument={this.props.moveDocument}
+ removeDocument={emptyFunction as any}
+ active={this.props.active}
+ whenActiveChanged={emptyFunction as any}
+ addDocTab={this.props.addDocTab}
+ setPreviewScript={emptyFunction}>
+ </CollectionSchemaPreview>
+ </div>;
}
+ }
+
+ @computed
+ get renderBullet() {
+ return <div className="bullet" onClick={action(() => this._collapsed = !this._collapsed)} style={{ color: StrCast(this.props.document.color, "black"), opacity: 0.4 }}>
+ {<FontAwesomeIcon icon={this._collapsed ? (this.childDocs ? "caret-square-right" : "caret-right") : (this.childDocs ? "caret-square-down" : "caret-down")} />}
+ </div>;
+ }
+ /**
+ * Renders the EditableView title element for placement into the tree.
+ */
+ @computed
+ get renderTitle() {
+ let reference = React.createRef<HTMLDivElement>();
+ let onItemDown = SetupDrag(reference, () => this.dataDoc, this.move, this.props.dropAction, this.props.treeViewId, true);
+
+ let headerElements = (
+ <span className="collectionTreeView-keyHeader" key={this.treeViewExpandedView}
+ onPointerDown={action(() => {
+ this.props.document.treeViewExpandedView = this.treeViewExpandedView === this.fieldKey ? "fields" :
+ this.treeViewExpandedView === "fields" && this.props.document.layout ? "layout" :
+ this.childDocs ? this.fieldKey : "fields";
+ this._collapsed = false;
+ })}>
+ {this.treeViewExpandedView}
+ </span>);
+ let dataDocs = CollectionDockingView.Instance ? Cast(CollectionDockingView.Instance.props.Document[this.fieldKey], listSpec(Doc), []) : [];
+ let openRight = dataDocs && dataDocs.indexOf(this.dataDoc) !== -1 ? (null) : (
+ <div className="treeViewItem-openRight" onPointerDown={this.onPointerDown} onClick={this.openRight}>
+ <FontAwesomeIcon icon="angle-right" size="lg" />
+ </div>);
+ return <>
+ <div className="docContainer" id={`docContainer-${this.props.parentKey}`} ref={reference} onPointerDown={onItemDown}
+ style={{
+ background: BoolCast(this.props.document.libraryBrush) ? "#06121212" : "0",
+ outline: BoolCast(this.props.document.workspaceBrush) ? "dashed 1px #06123232" : undefined,
+ pointerEvents: this.props.active() || SelectionManager.GetIsDragging() ? "all" : "none"
+ }} >
+ {this.editableView("title")}
+ </div >
+ {headerElements}
+ {openRight}
+ </>;
+ }
+
+ render() {
return <div className="treeViewItem-container" ref={this.createTreeDropTarget} onContextMenu={this.onWorkspaceContextMenu}>
<li className="collection-child">
<div className="treeViewItem-header" ref={this._header} onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}>
- {this.renderBullet()}
- {this.renderTitle()}
+ {this.renderBullet}
+ {this.renderTitle}
</div>
<div className="treeViewItem-border">
- {contentElement}
+ {this._collapsed ? (null) : this.renderContent}
</div>
</li>
</div>;
@@ -454,6 +391,8 @@ class TreeView extends React.Component<TreeViewProps> {
let docList = docs.filter(child => !child.excludeFromLibrary);
let rowWidth = () => panelWidth() - 20;
return docList.map((child, i) => {
+ let pair = Doc.GetLayoutDataDocPair(containingCollection, dataDoc, key, child);
+
let indent = i === 0 ? undefined : () => {
if (StrCast(docList[i - 1].layout).indexOf("CollectionView") !== -1) {
let fieldKeysub = StrCast(docList[i - 1].layout).split("fieldKey")[1];
@@ -470,8 +409,8 @@ class TreeView extends React.Component<TreeViewProps> {
return aspect ? Math.min(child[WidthSym](), rowWidth()) / aspect : child[HeightSym]();
};
return <TreeView
- document={child}
- dataDoc={dataDoc}
+ document={pair.layout}
+ dataDoc={pair.data}
containingCollection={containingCollection}
treeViewId={treeViewId}
key={child[Id]}
@@ -497,7 +436,9 @@ export class CollectionTreeView extends CollectionSubView(Document) {
private treedropDisposer?: DragManager.DragDropDisposer;
private _mainEle?: HTMLDivElement;
- @computed get chromeCollapsed() { return this.props.chromeCollapsed; }
+ @observable static NotifsCol: Opt<Doc>;
+
+ @computed get resolvedDataDoc() { return BoolCast(this.props.Document.isTemplate) && this.props.DataDoc ? this.props.DataDoc : this.props.Document; }
protected createTreeDropTarget = (ele: HTMLDivElement) => {
this.treedropDisposer && this.treedropDisposer();
@@ -529,21 +470,15 @@ export class CollectionTreeView extends CollectionSubView(Document) {
ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15);
}
}
-
- @computed get resolvedDataDoc() { return BoolCast(this.props.Document.isTemplate) && this.props.DataDoc ? this.props.DataDoc : this.props.Document; }
-
outerXf = () => Utils.GetScreenTransform(this._mainEle!);
onTreeDrop = (e: React.DragEvent) => this.onDrop(e, {});
-
-
- @observable static NotifsCol: Opt<Doc>;
-
openNotifsCol = () => {
if (CollectionTreeView.NotifsCol && CollectionDockingView.Instance) {
CollectionDockingView.Instance.AddRightSplit(CollectionTreeView.NotifsCol, undefined);
}
}
- @computed get notifsButton() {
+
+ @computed get renderNotifsButton() {
const length = CollectionTreeView.NotifsCol ? DocListCast(CollectionTreeView.NotifsCol.data).length : 0;
const notifsRef = React.createRef<HTMLDivElement>();
const dragNotifs = action(() => CollectionTreeView.NotifsCol!);
@@ -559,18 +494,15 @@ export class CollectionTreeView extends CollectionSubView(Document) {
</div>
</div >;
}
- @computed get clearButton() {
+ @computed get renderClearButton() {
return <div id="toolbar" key="toolbar">
- <div >
- <button className="toolbar-button round-button" title="Notifs"
- onClick={undoBatch(action(() => Doc.GetProto(this.props.Document)[this.props.fieldKey] = undefined))}>
- <FontAwesomeIcon icon={faTrash} size="sm" />
- </button>
- </div>
+ <button className="toolbar-button round-button" title="Notifs"
+ onClick={undoBatch(action(() => Doc.GetProto(this.props.Document)[this.props.fieldKey] = undefined))}>
+ <FontAwesomeIcon icon={faTrash} size="sm" />
+ </button>
</div >;
}
-
render() {
Doc.UpdateDocumentExtensionForField(this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey);
let dropAction = StrCast(this.props.Document.dropAction) as dropActionType;
@@ -596,8 +528,8 @@ export class CollectionTreeView extends CollectionSubView(Document) {
TreeView.loadId = doc[Id];
Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, this.childDocs.length ? this.childDocs[0] : undefined, true);
}} />
- {this.props.Document.workspaceLibrary ? this.notifsButton : (null)}
- {this.props.Document.allowClear ? this.clearButton : (null)}
+ {this.props.Document.workspaceLibrary ? this.renderNotifsButton : (null)}
+ {this.props.Document.allowClear ? this.renderClearButton : (null)}
<ul className="no-indent" style={{ width: "max-content" }} >
{
TreeView.GetChildElements(this.childDocs, this.props.Document[Id], this.props.Document, this.props.DataDoc, this.props.fieldKey, addDoc, this.remove,
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 34adc5840..57dc5879b 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -111,6 +111,9 @@ export class CollectionView extends React.Component<FieldViewProps> {
}
ContextMenu.Instance.addItem({ description: "View Modes...", subitems: subItems, icon: "eye" });
ContextMenu.Instance.addItem({ description: "Apply Template", event: () => this.props.addDocTab && this.props.addDocTab(Doc.ApplyTemplate(this.props.Document)!, undefined, "onRight"), icon: "project-diagram" });
+ ContextMenu.Instance.addItem({
+ description: this.props.Document.chromeStatus !== "disabled" ? "Hide Chrome" : "Show Chrome", event: () => this.props.Document.chromeStatus = (this.props.Document.chromeStatus !== "disabled" ? "disabled" : "enabled"), icon: "project-diagram"
+ });
}
}
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 87b1d43c1..e076efe18 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -141,7 +141,8 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
@computed get extensionDoc() { return Doc.resolvedFieldDataDoc(this.dataDoc, this.props.fieldKey, "dummy"); }
- @computed get dataDoc() { return BoolCast(this.props.Document.isTemplate) && this.props.DataDoc ? this.props.DataDoc : Doc.GetProto(this.props.Document); }
+ @computed get dataDoc() { return this.props.DataDoc && (BoolCast(this.props.Document.isTemplate) || BoolCast(this.props.DataDoc.isTemplate) || this.props.DataDoc.layout === this.props.Document) ? this.props.DataDoc : Doc.GetProto(this.props.Document); }
+
paste = (e: ClipboardEvent) => {
if (e.clipboardData && this._editorView) {
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index b60ef41fd..9a0615d68 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -68,7 +68,7 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
private dropDisposer?: DragManager.DragDropDisposer;
- @computed get dataDoc() { return BoolCast(this.props.Document.isTemplate) && this.props.DataDoc ? this.props.DataDoc : this.props.Document; }
+ @computed get dataDoc() { return this.props.DataDoc && (BoolCast(this.props.Document.isTemplate) || BoolCast(this.props.DataDoc.isTemplate) || this.props.DataDoc.layout === this.props.Document) ? this.props.DataDoc : this.props.Document; }
protected createDropTarget = (ele: HTMLDivElement) => {
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index dab0f9070..84b8589dd 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -1,4 +1,4 @@
-import { observable, action } from "mobx";
+import { observable, action, runInAction } from "mobx";
import { serializable, primitive, map, alias, list, PropSchema, custom } from "serializr";
import { autoObject, SerializationHelper, Deserializable, afterDocDeserialize } from "../client/util/SerializationHelper";
import { DocServer } from "../client/DocServer";
@@ -197,8 +197,12 @@ export namespace Doc {
}
export function Get(doc: Doc, key: string, ignoreProto: boolean = false): FieldResult {
- const self = doc[Self];
- return getField(self, key, ignoreProto);
+ try {
+ const self = doc[Self];
+ return getField(self, key, ignoreProto);
+ } catch {
+ return doc;
+ }
}
export function GetT<T extends Field>(doc: Doc, key: string, ctor: ToConstructor<T>, ignoreProto: boolean = false): FieldResult<T> {
return Cast(Get(doc, key, ignoreProto), ctor) as FieldResult<T>;
@@ -471,8 +475,12 @@ export namespace Doc {
Doc.GetProto(target).type = DocumentType.TEMPLATE;
if (targetData && targetData.layout === target) {
targetData.layout = temp;
+ targetData.miniLayout = StrCast(templateDoc.miniLayout);
+ targetData.detailedLayout = targetData.layout;
} else {
target.layout = temp;
+ target.miniLayout = StrCast(templateDoc.miniLayout);
+ target.detailedLayout = target.layout;
}
}
@@ -507,18 +515,29 @@ export namespace Doc {
setTimeout(() => fieldTemplate.proto = templateDataDoc);
}
- export async function ToggleDetailLayout(d: Doc) {
- let miniLayout = await PromiseValue(d.miniLayout);
- let detailLayout = await PromiseValue(d.detailedLayout);
- d.layout !== miniLayout ? miniLayout && (d.layout = d.miniLayout) : detailLayout && (d.layout = detailLayout);
- if (d.layout === detailLayout) Doc.GetProto(d).nativeWidth = Doc.GetProto(d).nativeHeight = undefined;
+ export function ToggleDetailLayout(d: Doc) {
+ runInAction(async () => {
+ let miniLayout = await PromiseValue(d.miniLayout);
+ let detailLayout = await PromiseValue(d.detailedLayout);
+ d.layout !== miniLayout ? miniLayout && (d.layout = d.miniLayout) : detailLayout && (d.layout = detailLayout);
+ if (d.layout === detailLayout) Doc.GetProto(d).nativeWidth = Doc.GetProto(d).nativeHeight = undefined;
+ });
}
- export async function UseDetailLayout(d: Doc) {
- let miniLayout = await PromiseValue(d.miniLayout);
- let detailLayout = await PromiseValue(d.detailedLayout);
- if (miniLayout && d.layout === miniLayout && detailLayout) {
- d.layout = detailLayout;
- d.nativeWidth = d.nativeHeight = undefined;
- }
+ export function UseDetailLayout(d: Doc) {
+ runInAction(async () => {
+ let detailLayout1 = await PromiseValue(d.detailedLayout);
+ let detailLayout = await PromiseValue(d.detailedLayout);
+ if (detailLayout) {
+ d.layout = detailLayout;
+ d.nativeWidth = d.nativeHeight = undefined;
+ if (detailLayout instanceof Doc) {
+ let delegDetailLayout = Doc.MakeDelegate(detailLayout) as Doc;
+ d.layout = delegDetailLayout;
+ let subDetailLayout1 = await PromiseValue(delegDetailLayout.detailedLayout);
+ let subDetailLayout = await PromiseValue(delegDetailLayout.detailedLayout);
+ delegDetailLayout.layout = subDetailLayout;
+ }
+ }
+ });
}
} \ No newline at end of file
diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts
index b59ec9b9a..2ebfb9e71 100644
--- a/src/new_fields/util.ts
+++ b/src/new_fields/util.ts
@@ -88,6 +88,9 @@ export function setter(target: any, prop: string | symbol | number, value: any,
}
export function getter(target: any, prop: string | symbol | number, receiver: any): any {
+ if (prop === "then") {//If we're being awaited
+ return undefined;
+ }
if (typeof prop === "symbol") {
return target.__fields[prop] || target[prop];
}
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts
index 1c52a3f11..91d7ba87d 100644
--- a/src/server/authentication/models/current_user_utils.ts
+++ b/src/server/authentication/models/current_user_utils.ts
@@ -71,7 +71,7 @@ export class CurrentUserUtils {
doc.sidebar = sidebar;
}
StrCast(doc.title).indexOf("@") !== -1 && (doc.title = StrCast(doc.title).split("@")[0] + "'s Library");
-
+ doc.width = 100;
}
public static loadCurrentUser() {
diff --git a/src/server/index.ts b/src/server/index.ts
index cb46698df..10a84c823 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -324,11 +324,24 @@ app.post("/uploadDoc", (req, res) => {
let id: string = "";
try {
for (const name in files) {
- const path = files[name].path;
- const zip = new AdmZip(path);
+ const path_2 = files[name].path;
+ const zip = new AdmZip(path_2);
zip.getEntries().forEach(entry => {
- if (!entry.name.startsWith("files/")) return;
- zip.extractEntryTo(entry.name, __dirname + RouteStore.public, true, false);
+ if (!entry.entryName.startsWith("files/")) return;
+ let dirname = path.dirname(entry.entryName) + "/";
+ let extname = path.extname(entry.entryName);
+ let basename = path.basename(entry.entryName).split(".")[0];
+ // zip.extractEntryTo(dirname + basename + "_o" + extname, __dirname + RouteStore.public, true, false);
+ // zip.extractEntryTo(dirname + basename + "_s" + extname, __dirname + RouteStore.public, true, false);
+ // zip.extractEntryTo(dirname + basename + "_m" + extname, __dirname + RouteStore.public, true, false);
+ // zip.extractEntryTo(dirname + basename + "_l" + extname, __dirname + RouteStore.public, true, false);
+ zip.extractEntryTo(entry.entryName, __dirname + RouteStore.public, true, false);
+ dirname = "/" + dirname;
+
+ fs.createReadStream(__dirname + RouteStore.public + dirname + basename + extname).pipe(fs.createWriteStream(__dirname + RouteStore.public + dirname + basename + "_o" + extname));
+ fs.createReadStream(__dirname + RouteStore.public + dirname + basename + extname).pipe(fs.createWriteStream(__dirname + RouteStore.public + dirname + basename + "_s" + extname));
+ fs.createReadStream(__dirname + RouteStore.public + dirname + basename + extname).pipe(fs.createWriteStream(__dirname + RouteStore.public + dirname + basename + "_m" + extname));
+ fs.createReadStream(__dirname + RouteStore.public + dirname + basename + extname).pipe(fs.createWriteStream(__dirname + RouteStore.public + dirname + basename + "_l" + extname));
});
const json = zip.getEntry("doc.json");
let docs: any;
@@ -343,7 +356,7 @@ app.post("/uploadDoc", (req, res) => {
res();
}, true, "newDocuments"))));
} catch (e) { console.log(e); }
- fs.unlink(path, () => { });
+ fs.unlink(path_2, () => { });
}
if (id) {
res.send(JSON.stringify(getId(id)));