diff options
| author | Michael Foiani <sotech117@michaels-mbp-3.devices.brown.edu> | 2022-04-28 17:24:37 -0400 | 
|---|---|---|
| committer | Michael Foiani <sotech117@michaels-mbp-3.devices.brown.edu> | 2022-04-28 17:24:37 -0400 | 
| commit | 22fe2791b6a6e92cc4d0ad953363120b51bd6e2c (patch) | |
| tree | 0896be213b50026fdf5a05afb64b28328253d757 /src/client/util | |
| parent | 42819362e50bc35b3bca228607fcc516d528bb1b (diff) | |
| parent | 99ae2ccde9dbcf6bae75edea231d4b10c736a692 (diff) | |
Merge with jenny
Diffstat (limited to 'src/client/util')
| -rw-r--r-- | src/client/util/CurrentUserUtils.ts | 42 | ||||
| -rw-r--r-- | src/client/util/DocumentManager.ts | 51 | ||||
| -rw-r--r-- | src/client/util/DragManager.ts | 6 | ||||
| -rw-r--r-- | src/client/util/LinkManager.ts | 21 | 
4 files changed, 82 insertions, 38 deletions
| diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index edb362a37..3165e38a6 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -9,7 +9,7 @@ import { RichTextField } from "../../fields/RichTextField";  import { listSpec } from "../../fields/Schema";  import { ComputedField, ScriptField } from "../../fields/ScriptField";  import { BoolCast, Cast, DateCast, NumCast, PromiseValue, StrCast } from "../../fields/Types"; -import { nullAudio } from "../../fields/URLField"; +import { ImageField, nullAudio } from "../../fields/URLField";  import { SharingPermissions } from "../../fields/util";  import { Utils } from "../../Utils";  import { DocServer } from "../DocServer"; @@ -292,7 +292,7 @@ export class CurrentUserUtils {          if (doc["template-icon-view"] === undefined) {              const iconView = Docs.Create.LabelDocument({                  title: "icon", textTransform: "unset", letterSpacing: "unset", layout: LabelBox.LayoutString("title"), _backgroundColor: "dimgray", -                _width: 150, _height: 70, _xPadding: 10, _yPadding: 10, isTemplateDoc: true, onDoubleClick: ScriptField.MakeScript("deiconifyView(documentView)", { documentView: "any" }), system: true +                _width: 150, _height: 70, _xPadding: 10, _yPadding: 10, isTemplateDoc: true, onClick: ScriptField.MakeScript("deiconifyView(documentView)", { documentView: "any" }), system: true              });              //  Docs.Create.TextDocument("", {              //     title: "icon", _width: 150, _height: 30, isTemplateDoc: true, onDoubleClick: ScriptField.MakeScript("deiconifyView(documentView)", { documentView: "any" }) @@ -303,8 +303,9 @@ export class CurrentUserUtils {          }          if (doc["template-icon-view-rtf"] === undefined) {              const iconRtfView = Docs.Create.LabelDocument({ -                title: "icon_" + DocumentType.RTF, textTransform: "unset", letterSpacing: "unset", layout: LabelBox.LayoutString("text"), -                _width: 150, _height: 70, _xPadding: 10, _yPadding: 10, isTemplateDoc: true, onDoubleClick: ScriptField.MakeScript("deiconifyView(documentView)", { documentView: "any" }), system: true +                title: "icon_" + DocumentType.RTF, _showTitle: "creationDate", textTransform: "unset", letterSpacing: "unset", layout: LabelBox.LayoutString("text"), +                _singleLine: false, _minFontSize: 18, _maxFontSize: 24, +                _width: 150, _height: 70, _xPadding: 10, _yPadding: 10, isTemplateDoc: true, onClick: ScriptField.MakeScript("deiconifyView(documentView)", { documentView: "any" }), system: true              });              iconRtfView.isTemplateDoc = makeTemplate(iconRtfView, true, "icon_" + DocumentType.RTF);              doc["template-icon-view-rtf"] = new PrefetchProxy(iconRtfView); @@ -319,19 +320,41 @@ export class CurrentUserUtils {          }          if (doc["template-icon-view-img"] === undefined) {              const iconImageView = Docs.Create.ImageDocument("http://www.cs.brown.edu/~bcz/face.gif", { -                title: "data", _width: 50, isTemplateDoc: true, onDoubleClick: ScriptField.MakeScript("deiconifyView(documentView)", { documentView: "any" }), system: true +                title: "data", _width: 150, isTemplateDoc: true, _showTitle: "title", onClick: ScriptField.MakeScript("deiconifyView(documentView)", { documentView: "any" }), system: true              });              iconImageView.isTemplateDoc = makeTemplate(iconImageView, true, "icon_" + DocumentType.IMG);              doc["template-icon-view-img"] = new PrefetchProxy(iconImageView);          }          if (doc["template-icon-view-col"] === undefined) { -            const iconColView = Docs.Create.TreeDocument([], { title: "data", _width: 180, _height: 80, onDoubleClick: ScriptField.MakeScript("deiconifyView(documentView)", { documentView: "any" }), system: true }); +            const iconColView = Docs.Create.ImageDocument("", { title: "icon", _showTitle: "title", _width: 360 / 4, _height: 270 / 4, onClick: ScriptField.MakeScript("deiconifyView(documentView)", { documentView: "any" }), system: true });              iconColView.isTemplateDoc = makeTemplate(iconColView, true, "icon_" + DocumentType.COL); +            const proto = iconColView.proto as Doc; +            proto["icon-nativeWidth"] = 360 / 4; +            proto["icon-nativeHeight"] = 270 / 4; +            proto.icon = new ImageField("http://www.cs.brown.edu/~bcz/noImage.png");              doc["template-icon-view-col"] = new PrefetchProxy(iconColView);          } +        if (doc["template-icon-view-video"] === undefined) { +            const iconVidView = Docs.Create.ImageDocument("", { title: "icon", _width: 360 / 4, _height: 270 / 4, _showTitle: "title", onClick: ScriptField.MakeScript("deiconifyView(documentView)", { documentView: "any" }), system: true }); +            iconVidView.isTemplateDoc = makeTemplate(iconVidView, true, "icon_" + DocumentType.VID); +            const proto = iconVidView.proto as Doc; +            proto["icon-nativeWidth"] = 360 / 4; +            proto["icon-nativeHeight"] = 270 / 4; +            proto.icon = new ImageField("http://www.cs.brown.edu/~bcz/noImage.png"); +            doc["template-icon-view-video"] = new PrefetchProxy(iconVidView); +        } +        if (doc["template-icon-view-pdf"] === undefined) { +            const iconPdfView = Docs.Create.ImageDocument("", { title: "icon", _width: 360 / 4, _height: 270 / 4, _showTitle: "title", onClick: ScriptField.MakeScript("deiconifyView(documentView)", { documentView: "any" }), system: true }); +            iconPdfView.isTemplateDoc = makeTemplate(iconPdfView, true, "icon_" + DocumentType.PDF); +            const proto = iconPdfView.proto as Doc; +            proto["icon-nativeWidth"] = 360 / 4; +            proto["icon-nativeHeight"] = 270 / 4; +            proto.icon = new ImageField("http://www.cs.brown.edu/~bcz/noImage.png"); +            doc["template-icon-view-pdf"] = new PrefetchProxy(iconPdfView); +        }          if (doc["template-icons"] === undefined) {              doc["template-icons"] = new PrefetchProxy(Docs.Create.TreeDocument([doc["template-icon-view"] as Doc, doc["template-icon-view-img"] as Doc, doc["template-icon-view-button"] as Doc, -            doc["template-icon-view-col"] as Doc, doc["template-icon-view-rtf"] as Doc, doc["template-icon-view-pdf"] as Doc], { title: "icon templates", _height: 75, system: true })); +            doc["template-icon-view-col"] as Doc, doc["template-icon-view-rtf"] as Doc, doc["template-icon-view-video"] as Doc, doc["template-icon-view-pdf"] as Doc], { title: "icon templates", _height: 75, system: true }));          } else {              const templateIconsDoc = Cast(doc["template-icons"], Doc, null);              const requiredTypes = [doc["template-icon-view"] as Doc, doc["template-icon-view-img"] as Doc, doc["template-icon-view-button"] as Doc, @@ -366,7 +389,7 @@ export class CurrentUserUtils {              const textDoc = Docs.Create.TreeDocument([], {                  title: "Slide", _viewType: CollectionViewType.Tree, treeViewHasOverlay: true, _fontSize: "20px", _autoHeight: true,                  allowOverlayDrop: true, treeViewType: "outline", _xMargin: 0, _yMargin: 0, _width: 300, _height: 200, _singleLine: true, -                backgroundColor: "transparent", system: true, cloneFieldFilter: new List<string>(["system"]) +                backgroundColor: "white", system: true, cloneFieldFilter: new List<string>(["system"])              });              Doc.GetProto(textDoc).title = ComputedField.MakeFunction('self.text?.Text');              FormattedTextBox.SelectOnLoad = textDoc[Id]; @@ -1321,9 +1344,6 @@ export class CurrentUserUtils {              // undefined means ColorScheme.Light until all CSS is updated with values for each color scheme (e.g., see MainView.scss, DocumentDecorations.scss)              doc.activeDashboard.colorScheme = doc.activeDashboard.colorScheme === ColorScheme.Light ? undefined : doc.activeDashboard.colorScheme;          } -        if (doc.activeCollectionBackground === "white") { // temporary to avoid having to rebuild the databse for old accounts that have this set by default. -            doc.activeCollectionBackground = undefined; -        }          return doc;      } diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index ad6d90bc3..b6c28d2fe 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -168,30 +168,43 @@ export class DocumentManager {          originalTarget = originalTarget ?? targetDoc;          const getFirstDocView = LightboxView.LightboxDoc ? DocumentManager.Instance.getLightboxDocumentView : DocumentManager.Instance.getFirstDocumentView;          const docView = getFirstDocView(targetDoc, originatingDoc); -        const wasHidden = targetDoc.hidden;  //  -        if (wasHidden) runInAction(() => targetDoc.hidden = false);  // if the target is hidden, un-hide it here. +        const annotatedDoc = Cast(targetDoc.annotationOn, Doc, null); +        const resolvedTarget = targetDoc.type === DocumentType.MARKER ? annotatedDoc ?? targetDoc : targetDoc; // if target is a marker, then focus toggling should apply to the document it's on since the marker itself doesn't have a hidden field +        var wasHidden = resolvedTarget.hidden; +        if (wasHidden) { +            runInAction(() => { +                resolvedTarget.hidden = false;  // if the target is hidden, un-hide it here. +                docView?.props.bringToFront(resolvedTarget); +            }); +        }          const focusAndFinish = (didFocus: boolean) => { +            const finalTargetDoc = resolvedTarget;              if (originatingDoc?.isPushpin) {                  if (!didFocus && !wasHidden) {  // don't toggle the hidden state if the doc was already un-hidden as part of this document traversal -                    targetDoc.hidden = !targetDoc.hidden; +                    finalTargetDoc.hidden = !finalTargetDoc.hidden;                  }              } else { -                targetDoc.hidden && (targetDoc.hidden = undefined); +                finalTargetDoc.hidden && (finalTargetDoc.hidden = undefined);                  !noSelect && docView?.select(false);              }              finished?.(); -            return false;          }; -        const annotatedDoc = Cast(targetDoc.annotationOn, Doc, null); -        const annoContainerView = annotatedDoc && getFirstDocView(annotatedDoc); +        const annoContainerView = (!wasHidden || resolvedTarget !== annotatedDoc) && annotatedDoc && getFirstDocView(annotatedDoc);          const contextDocs = docContext ? await DocListCastAsync(docContext.data) : undefined;          const contextDoc = contextDocs?.find(doc => Doc.AreProtosEqual(doc, targetDoc) || Doc.AreProtosEqual(doc, annotatedDoc)) ? docContext : undefined;          const targetDocContext = contextDoc || annotatedDoc;          const targetDocContextView = (targetDocContext && getFirstDocView(targetDocContext)) ||              (wasHidden && annoContainerView);// if we have an annotation container and the target was hidden, then try again because we just un-hid the document above          const focusView = !docView && targetDoc.type === DocumentType.MARKER && annoContainerView ? annoContainerView : docView; -        if (!docView && annoContainerView) { -            annoContainerView.focus(targetDoc);  // this allows something like a PDF view to remove its doc filters to expose the target so that it can be found in the retry code below +        if ((!docView && targetDoc.type !== DocumentType.MARKER) && annoContainerView) { +            if (annoContainerView.props.Document.layoutKey === "layout_icon") { +                annoContainerView.iconify(() => this.jumpToDocument( +                    targetDoc, willZoom, createViewFunc, docContext, linkDoc, closeContextIfNotFound, originatingDoc, +                    finished, originalTarget, noSelect, presZoom)); +                return; +            } else { +                annoContainerView.focus(targetDoc);  // this allows something like a PDF view to remove its doc filters to expose the target so that it can be found in the retry code below +            }          }          if (focusView) {              !noSelect && Doc.linkFollowHighlight(focusView.rootDoc); //TODO:glr make this a setting in PresBox @@ -207,10 +220,17 @@ export class DocumentManager {                  createViewFunc(Doc.BrushDoc(targetDoc), finished); // bcz: should we use this?: Doc.MakeAlias(targetDoc)));              } else {  // otherwise try to get a view of the context of the target                  if (targetDocContextView) { // we found a context view and aren't forced to create a new one ... focus on the context first.. +                    wasHidden = wasHidden || targetDocContextView.rootDoc.hidden; +                    targetDocContextView.rootDoc.hidden = false; // make sure context isn't hidden                      targetDocContext._viewTransition = "transform 500ms";                      targetDocContextView.props.focus(targetDocContextView.rootDoc, {                          willZoom, afterFocus: async () => {                              targetDocContext._viewTransition = undefined; +                            if (targetDocContext.layoutKey === "layout_icon") { +                                targetDocContextView.iconify(() => this.jumpToDocument( +                                    targetDoc, willZoom, createViewFunc, docContext, linkDoc, closeContextIfNotFound, originatingDoc, +                                    finished, originalTarget, noSelect, presZoom)); +                            }                              return ViewAdjustment.doNothing;                          }                      }); @@ -221,27 +241,27 @@ export class DocumentManager {                          finished?.();                      } else { // no timecode means we need to find the context view and focus on our target                          const findView = (delay: number) => { -                            const retryDocView = getFirstDocView(targetDoc);  // test again for the target view snce we presumably created the context above by focusing on it -                            if (retryDocView) {   // we found the target in the context +                            const retryDocView = getFirstDocView(resolvedTarget);  // test again for the target view snce we presumably created the context above by focusing on it +                            if (retryDocView) {   // we found the target in the context.                                   Doc.linkFollowHighlight(retryDocView.rootDoc); -                                retryDocView.props.focus(targetDoc, { +                                retryDocView.focus(targetDoc, {                                      willZoom, afterFocus: (didFocus: boolean) =>                                          new Promise<ViewAdjustment>(res => {                                              !noSelect && focusAndFinish(didFocus);                                              res(ViewAdjustment.doNothing);                                          })                                  }); // focus on the target in the context -                            } else if (delay > 1500) { +                            } else if (delay > 1000) {                                  // we didn't find the target, so it must have moved out of the context.  Go back to just creating it.                                  if (closeContextIfNotFound) targetDocContextView.props.removeDocument?.(targetDocContextView.rootDoc);                                  if (targetDoc.layout) { // there will no layout for a TEXTANCHOR type document                                      createViewFunc(Doc.BrushDoc(targetDoc), finished); //  create a new view of the target                                  }                              } else { -                                setTimeout(() => findView(delay + 250), 250); +                                setTimeout(() => findView(delay + 200), 200);                              }                          }; -                        findView(0); +                        setTimeout(() => findView(0), 0);                      }                  } else {  // there's no context view so we need to create one first and try again when that finishes                      const finishFunc = () => this.jumpToDocument(targetDoc, true, createViewFunc, docContext, linkDoc, true /* if we don't find the target, we want to get rid of the context just created */, undefined, finished, originalTarget); @@ -251,7 +271,6 @@ export class DocumentManager {              }          }      } -  }  export function DocFocusOrOpen(doc: any, collectionDoc?: Doc) {      const cv = collectionDoc && DocumentManager.Instance.getDocumentView(collectionDoc); diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 47b7ce0e7..8ac28bc89 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -384,8 +384,8 @@ export namespace DragManager {                  }              }              const rect = ele.getBoundingClientRect(); -            const scaleX = rect.width / ele.offsetWidth; -            const scaleY = ele.offsetHeight ? rect.height / ele.offsetHeight : scaleX; +            const scaleX = rect.width / (ele.offsetWidth || rect.width); +            const scaleY = ele.offsetHeight ? rect.height / (ele.offsetHeight || rect.height) : scaleX;              elesCont.left = Math.min(rect.left, elesCont.left);              elesCont.top = Math.min(rect.top, elesCont.top); @@ -409,7 +409,7 @@ export namespace DragManager {                  Array.from(pdfBox).filter(pb => pb.width && pb.height).map((pb, i) => pb.getContext('2d')!.drawImage(pdfBoxSrc[i], 0, 0));              }              [dragElement, ...Array.from(dragElement.getElementsByTagName('*'))].forEach(ele => -                ele.hasAttribute("style") && ((ele as any).style.pointerEvents = "none")); +                (ele as any).style && ((ele as any).style.pointerEvents = "none"));              dragDiv.appendChild(dragElement);              if (dragElement !== ele) { diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts index df2c02a8d..9445533dc 100644 --- a/src/client/util/LinkManager.ts +++ b/src/client/util/LinkManager.ts @@ -29,6 +29,7 @@ export class LinkManager {      public static currentLink: Opt<Doc>;      public static get Instance() { return LinkManager._instance; }      public static addLinkDB = (linkDb: any) => LinkManager.userLinkDBs.push(linkDb); +    public static AutoKeywords = "keywords:Usages";      static links: Doc[] = [];      constructor() {          LinkManager._instance = this; @@ -149,9 +150,11 @@ export class LinkManager {      public getRelatedGroupedLinks(anchor: Doc): Map<string, Array<Doc>> {          const anchorGroups = new Map<string, Array<Doc>>();          this.relatedLinker(anchor).forEach(link => { -            if (!link.linkRelationship || link?.linkRelationship !== "-ungrouped-") { -                const group = anchorGroups.get(StrCast(link.linkRelationship)); -                anchorGroups.set(StrCast(link.linkRelationship), group ? [...group, link] : [link]); +            if (link.linkRelationship && link.linkRelationship !== "-ungrouped-") { +                const relation = StrCast(link.linkRelationship); +                const anchorRelation = relation.indexOf(":") !== -1 ? relation.split(":")[Doc.AreProtosEqual(Cast(link.anchor1, Doc, null), anchor) ? 0 : 1] : relation; +                const group = anchorGroups.get(anchorRelation); +                anchorGroups.set(anchorRelation, group ? [...group, link] : [link]);              } else {                  // if link is in no groups then put it in default group                  const group = anchorGroups.get("*"); @@ -221,7 +224,9 @@ export class LinkManager {          const backLinkWithoutTargetView = secondDocs.find(d => DocumentManager.Instance.getDocumentViews(d.anchor1 as Doc).length === 0);          const linkWithoutTargetDoc = traverseBacklink === undefined ? fwdLinkWithoutTargetView || backLinkWithoutTargetView : traverseBacklink ? backLinkWithoutTargetView : fwdLinkWithoutTargetView;          const linkDocList = linkWithoutTargetDoc ? [linkWithoutTargetDoc] : (traverseBacklink === undefined ? firstDocs.concat(secondDocs) : traverseBacklink ? secondDocs : firstDocs); -        const followLinks = linkDocList.length ? (sourceDoc.isPushpin ? linkDocList : [linkDocList[0]]) : []; +        const followLinks = sourceDoc.isPushpin ? linkDocList : linkDocList.slice(0, 1); +        var count = 0; +        const allFinished = () => ++count === followLinks.length && finished?.();          followLinks.forEach(async linkDoc => {              if (linkDoc) {                  const target = (sourceDoc === linkDoc.anchor1 ? linkDoc.anchor2 : sourceDoc === linkDoc.anchor2 ? linkDoc.anchor1 : @@ -232,20 +237,20 @@ export class LinkManager {                          const tour = DocListCast(target[fieldKey]).reverse();                          LightboxView.SetLightboxDoc(currentContext, undefined, tour);                          setTimeout(LightboxView.Next); -                        finished?.(); +                        allFinished();                      } else {                          const containerAnnoDoc = Cast(target.annotationOn, Doc, null);                          const containerDoc = containerAnnoDoc || target;                          const containerDocContext = Cast(containerDoc?.context, Doc, null);                          const targetContext = LightboxView.LightboxDoc ? containerAnnoDoc || containerDocContext : containerDocContext;                          const targetNavContext = !Doc.AreProtosEqual(targetContext, currentContext) ? targetContext : undefined; -                        DocumentManager.Instance.jumpToDocument(target, zoom, (doc, finished) => createViewFunc(doc, StrCast(linkDoc.followLinkLocation, "lightbox"), finished), targetNavContext, linkDoc, undefined, sourceDoc, finished); +                        DocumentManager.Instance.jumpToDocument(target, zoom, (doc, finished) => createViewFunc(doc, StrCast(linkDoc.followLinkLocation, "lightbox"), finished), targetNavContext, linkDoc, undefined, sourceDoc, allFinished);                      }                  } else { -                    finished?.(); +                    allFinished();                  }              } else { -                finished?.(); +                allFinished();              }          });      } | 
