From c75ffd4900acea74c55b6bf275a5e8082c15d573 Mon Sep 17 00:00:00 2001
From: Sam Wilkins <samwilkins333@gmail.com>
Date: Sun, 26 Apr 2020 19:29:50 -0700
Subject: formatted textbox disposers refactor, paragraph chunked rich text
 initialization and buxton importer updates

---
 src/client/views/collections/CollectionTreeView.tsx | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

(limited to 'src/client/views/collections/CollectionTreeView.tsx')

diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 7f5dc98f1..49eb90bc2 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -730,18 +730,31 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
                 const { TextDocument, ImageDocument, CarouselDocument } = Docs.Create;
                 const { Document } = this.props;
                 const fallbackImg = "http://www.cs.brown.edu/~bcz/face.gif";
-                const detailedTemplate = `{ "doc": { "type": "doc", "content": [  { "type": "paragraph", "content": [ { "type": "dashField", "attrs": { "fieldKey": "year" } } ] },  { "type": "paragraph", "content": [ { "type": "dashField", "attrs": { "fieldKey": "company" } } ] }  ] }, "selection":{"type":"text","anchor":1,"head":1},"storedMarks":[] }`;
 
                 const textDoc = TextDocument("", { title: "details", _autoHeight: true });
                 const detailView = Docs.Create.StackingDocument([
                     CarouselDocument([], { title: "data", _height: 350, _itemIndex: 0, backgroundColor: "#9b9b9b3F" }),
-                    // textDoc,
+                    textDoc,
                     TextDocument("", { title: "shortDescription", _autoHeight: true }),
-                    // TreeDocument([], { title: "narratives", _height: 75, treeViewHideTitle: true }),
                     TextDocument("", { title: "longDescription", _height: 350 })
+                    // TreeDocument([], { title: "narratives", _height: 75, treeViewHideTitle: true }),
                 ], { _chromeStatus: "disabled", _width: 300, _height: 300, _autoHeight: true, title: "detailView" });
-                textDoc.data = new RichTextField(detailedTemplate, "year company");
+                // const detailView = Cast(Cast(Doc.UserDoc()["template-button-detail"], Doc, null)?.dragFactor, Doc, null);
                 detailView.isTemplateDoc = makeTemplate(detailView);
+                detailView.fontFamily = "Arial";
+
+                const buxtonFieldKeys = ["year", "originalPrice", "degreesOfFreedom", "company", "attribute", "primaryKey", "secondaryKey", "dimensions"];
+                const detailedTemplate = {
+                    doc: {
+                        type: "doc", content: buxtonFieldKeys.map(fieldKey => ({
+                            type: "paragraph",
+                            content: [{ type: "dashField", attrs: { fieldKey } }]
+                        }))
+                    },
+                    selection: { type: "text", anchor: 1, head: 1 },
+                    storedMarks: []
+                };
+                textDoc.data = new RichTextField(JSON.stringify(detailedTemplate), buxtonFieldKeys.join(" "));
 
                 const heroView = ImageDocument(fallbackImg, { title: "heroView", isTemplateDoc: true, isTemplateForField: "hero", }); // this acts like a template doc and a template field ... a little weird, but seems to work?
                 heroView.proto!.layout = ImageBox.LayoutString("hero");
-- 
cgit v1.2.3-70-g09d2


From fc470b25759e8f051dc527066f9bebcaf5e7707d Mon Sep 17 00:00:00 2001
From: Sam Wilkins <samwilkins333@gmail.com>
Date: Sun, 26 Apr 2020 23:55:23 -0700
Subject: various buxton fixes

---
 src/client/documents/Documents.ts                  |  1 -
 .../views/collections/CollectionTreeView.tsx       | 24 ++++++++--------
 src/client/views/nodes/DocumentContentsView.tsx    |  8 +++---
 src/client/views/nodes/FormattedTextBox.tsx        |  9 +-----
 src/scraping/buxton/final/BuxtonImporter.ts        | 32 ++++++++++++----------
 5 files changed, 36 insertions(+), 38 deletions(-)

(limited to 'src/client/views/collections/CollectionTreeView.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 1651a6d55..5e0890e76 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -408,7 +408,6 @@ export namespace Docs {
                     const doc = StackingDocument(deviceImages, { title: device.title, _LODdisable: true });
                     const deviceProto = Doc.GetProto(doc);
                     deviceProto.hero = new ImageField(constructed[0].url);
-                    deviceProto.fontFamily = "Arial";
                     Docs.Get.FromJson({ data: device, appendToExisting: { targetDoc: deviceProto } });
                     Doc.AddDocToList(parentProto, "data", doc);
                 } else if (errors) {
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 362d43ee7..dcb5e116c 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -733,19 +733,21 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
                 const { Document } = this.props;
                 const fallbackImg = "http://www.cs.brown.edu/~bcz/face.gif";
 
+                const carousel = CarouselDocument([], { title: "data", _height: 350, _itemIndex: 0, backgroundColor: "#9b9b9b3F" });
                 const textDoc = TextDocument("", { title: "details", _autoHeight: true });
-                const detailView = Docs.Create.StackingDocument([
-                    CarouselDocument([], { title: "data", _height: 350, _itemIndex: 0, backgroundColor: "#9b9b9b3F" }),
-                    TreeDocument([
-                        // textDoc,
-                        TextDocument("", { title: "shortDescription", _autoHeight: true }),
-                        // TreeDocument([], { title: "narratives", _height: 75, treeViewHideTitle: true }),
-                        TextDocument("", { title: "longDescription", _height: 350 })
-                    ], { title: "stuff", _height: 100 })
-                ], { _chromeStatus: "disabled", _width: 300, _height: 300, _autoHeight: true, title: "detailView" });
-                // const detailView = Cast(Cast(Doc.UserDoc()["template-button-detail"], Doc, null)?.dragFactor, Doc, null);
+                const short = TextDocument("", { title: "shortDescription", _autoHeight: true });
+                const long = TextDocument("", { title: "longDescription", _height: 350 });
+                long.treeViewExpandedView = "layout";
+                const long_wrapper = TreeDocument([long], { title: "Descriptions", _height: 350 });
+
+                // const narratives = TreeDocument([], { title: "narratives", _height: 75, treeViewHideTitle: true }),
+                // const detailView = Cast(Cast(Doc.UserDoc()["template-button-detail"], Doc, null)?.dragFactory, Doc, null);
+
+                textDoc.fontFamily = short.fontFamily = long.fontFamily = carousel.fontFamily = "Arial";
+
+                const detailViewOpts = { _chromeStatus: "disabled", _width: 300, _height: 300, _autoHeight: true, title: "detailView" };
+                const detailView = Docs.Create.StackingDocument([carousel, textDoc, short, long_wrapper], detailViewOpts);
                 detailView.isTemplateDoc = makeTemplate(detailView);
-                detailView.fontFamily = "Arial";
 
                 const buxtonFieldKeys = ["year", "originalPrice", "degreesOfFreedom", "company", "attribute", "primaryKey", "secondaryKey", "dimensions"];
                 const detailedTemplate = {
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 8582f92ed..cd78ac7b3 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -78,7 +78,7 @@ export class HTMLtag extends React.Component<HTMLtagProps> {
         const style: { [key: string]: any } = {};
         const divKeys = OmitKeys(this.props, ["children", "htmltag", "RootDoc", "Document", "key", "onInput", "onClick", "__proto__"]).omit;
         Object.keys(divKeys).map((prop: string) => {
-            let p = (this.props as any)[prop] as string;
+            const p = (this.props as any)[prop] as string;
             const replacer = (match: any, expr: string, offset: any, string: any) => { // bcz: this executes a script to convert a propery expression string:  { script }  into a value
                 return ScriptField.MakeFunction(expr, { self: Doc.name, this: Doc.name })?.script.run({ self: this.props.RootDoc, this: this.props.Document }).result as string || "";
             };
@@ -178,9 +178,9 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
             }
             return undefined;
             // add input function to props
-        }
-        let onClick = makeFuncProp("onClick");
-        let onInput = makeFuncProp("onInput");
+        };
+        const onClick = makeFuncProp("onClick");
+        const onInput = makeFuncProp("onInput");
 
         const bindings = this.CreateBindings(onClick, onInput);
         //  layoutFrame = splits.length > 1 ? splits[0] + splits[1].replace(/{([^{}]|(?R))*}/, replacer4) : ""; // might have been more elegant if javascript supported recursive patterns
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 8d4b90c41..d98172823 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -860,15 +860,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
             });
             const startupText = !rtfField && this._editorView && Field.toString(this.dataDoc[fieldKey] as Field);
             if (startupText) {
-                const paragraphSegments = startupText.split("\n\n");
                 const { state: { tr }, dispatch } = this._editorView;
-                if (paragraphSegments.length) {
-                    for (const paragraph of paragraphSegments) {
-                        dispatch(tr.insertText(paragraph));
-                    }
-                } else {
-                    dispatch(tr.insertText(startupText));
-                }
+                dispatch(tr.insertText(startupText));
             }
         }
 
diff --git a/src/scraping/buxton/final/BuxtonImporter.ts b/src/scraping/buxton/final/BuxtonImporter.ts
index 64b988610..713207a07 100644
--- a/src/scraping/buxton/final/BuxtonImporter.ts
+++ b/src/scraping/buxton/final/BuxtonImporter.ts
@@ -16,7 +16,7 @@ interface DocumentContents {
     hyperlinks: string[];
     captions: string[];
     embeddedFileNames: string[];
-    longDescriptionParagraphs: string[];
+    longDescription: string;
 }
 
 export interface DeviceDocument {
@@ -269,7 +269,7 @@ async function extractFileContents(pathToDocument: string): Promise<DocumentCont
     const paragraphs = document.find('//*[name()="w:p"]').map(node => Utilities.correctSentences(node.text()).transformed!);
     const start = paragraphs.indexOf(paragraphs.find(el => /Bill Buxton[’']s Notes/.test(el))!) + 1;
     const end = paragraphs.indexOf("Device Details");
-    const longDescriptionParagraphs = paragraphs.slice(start, end);
+    const longDescription = paragraphs.slice(start, end).filter(paragraph => paragraph.length).join("\n\n");
 
     const { length } = captionTargets;
     strictEqual(length > 3, true, "No captions written.");
@@ -292,7 +292,7 @@ async function extractFileContents(pathToDocument: string): Promise<DocumentCont
 
     zip.close();
 
-    return { body, longDescriptionParagraphs, imageData, captions, embeddedFileNames, hyperlinks };
+    return { body, longDescription, imageData, captions, embeddedFileNames, hyperlinks };
 }
 
 const imageEntry = /^word\/media\/\w+\.(jpeg|jpg|png|gif)/;
@@ -308,26 +308,30 @@ async function writeImages(zip: any): Promise<ImageData[]> {
     const imageEntries = allEntries.filter(name => imageEntry.test(name));
 
     const imageUrls: ImageData[] = [];
-    for (const mediaPath of imageEntries) {
-        const getImageStream = () => new Promise<Readable>((resolve, reject) => {
-            zip.stream(mediaPath, (error: any, stream: any) => error ? reject(error) : resolve(stream));
-        });
+    const valid: any[] = [];
+
+    const getImageStream = (mediaPath: string) => new Promise<Readable>((resolve, reject) => {
+        zip.stream(mediaPath, (error: any, stream: any) => error ? reject(error) : resolve(stream));
+    });
 
+    for (const mediaPath of imageEntries) {
         const { width, height, type } = await new Promise<Dimensions>(async resolve => {
             const sizeStream = (createImageSizeStream() as PassThrough).on('size', (dimensions: Dimensions) => {
                 readStream.destroy();
                 resolve(dimensions);
             }).on("error", () => readStream.destroy());
-            const readStream = await getImageStream();
+            const readStream = await getImageStream(mediaPath);
             readStream.pipe(sizeStream);
         });
-        if (Math.abs(width - height) < 10) {
-            continue;
+
+        if (Math.abs(width - height) > 10) {
+            valid.push({ width, height, type, mediaPath });
         }
+    }
 
+    for (const { type, width, height, mediaPath } of valid) {
         const generatedFileName = `upload_${Utils.GenerateGuid()}.${type.toLowerCase()}`;
-        await DashUploadUtils.outputResizedImages(getImageStream, generatedFileName, imageDir);
-
+        await DashUploadUtils.outputResizedImages(() => getImageStream(mediaPath), generatedFileName, imageDir);
         imageUrls.push({
             url: `/files/images/buxton/${generatedFileName}`,
             nativeWidth: width,
@@ -339,11 +343,12 @@ async function writeImages(zip: any): Promise<ImageData[]> {
 }
 
 function analyze(fileName: string, contents: DocumentContents): AnalysisResult {
-    const { body, imageData, captions, hyperlinks, embeddedFileNames, longDescriptionParagraphs } = contents;
+    const { body, imageData, captions, hyperlinks, embeddedFileNames, longDescription } = contents;
     const device: any = {
         hyperlinks,
         captions,
         embeddedFileNames,
+        longDescription,
         __images: imageData
     };
     const errors: { [key: string]: string } = { fileName };
@@ -378,7 +383,6 @@ function analyze(fileName: string, contents: DocumentContents): AnalysisResult {
         return { errors };
     }
 
-    device.longDescription = longDescriptionParagraphs.join("\n\n");
     return { device };
 }
 
-- 
cgit v1.2.3-70-g09d2

