aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections
diff options
context:
space:
mode:
authorAndy Rickert <andrew_rickert@brown.edu>2020-08-10 21:04:34 -0400
committerAndy Rickert <andrew_rickert@brown.edu>2020-08-10 21:04:34 -0400
commita1147c3c3e6ef3d16f850ef61f1c88099e3ab686 (patch)
treefa86e54f4673bb1fbe5de55b6b29c8a5a6dd30be /src/client/views/collections
parentcf45a2398dce7af290bed364fa1bb8681134ce15 (diff)
parent8001f8aa447729d667f8e903f9d3dc7766ef3320 (diff)
reverting back to earlier algorithm
Diffstat (limited to 'src/client/views/collections')
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx12
-rw-r--r--src/client/views/collections/CollectionLinearView.tsx2
-rw-r--r--src/client/views/collections/CollectionSchemaCells.tsx21
-rw-r--r--src/client/views/collections/CollectionSchemaHeaders.tsx7
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx2
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx7
-rw-r--r--src/client/views/collections/CollectionSubView.tsx44
-rw-r--r--src/client/views/collections/CollectionView.tsx13
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx2
-rw-r--r--src/client/views/collections/collectionFreeForm/FormatShapePane.tsx72
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx58
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx8
-rw-r--r--src/client/views/collections/collectionFreeForm/PropertiesView.scss66
-rw-r--r--src/client/views/collections/collectionFreeForm/PropertiesView.tsx50
14 files changed, 231 insertions, 133 deletions
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 7e096fa37..3691e844f 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -513,7 +513,11 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
const doc = await DocServer.GetRefField(tab.contentItem.config.props.documentId) as Doc;
if (doc instanceof Doc) {
- tab.titleElement[0].onclick = (e: any) => tab.titleElement[0].focus();
+ tab.titleElement[0].onclick = (e: any) => {
+ if (Date.now() - tab.titleElement[0].lastClick < 1000) tab.titleElement[0].select();
+ tab.titleElement[0].lastClick = Date.now();
+ tab.titleElement[0].focus();
+ };
tab.titleElement[0].onchange = (e: any) => {
tab.titleElement[0].size = e.currentTarget.value.length + 1;
Doc.GetProto(doc).title = e.currentTarget.value, true;
@@ -691,8 +695,8 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
return (this.props as any).glContainer.parent.parent;
}
get _tab(): any {
- const tab = (this.props as any).glContainer.tab.element[0] as HTMLElement;
- return tab.getElementsByClassName("lm_title")?.[0];
+ const tab = (this.props as any).glContainer.tab?.element[0] as HTMLElement;
+ return tab?.getElementsByClassName("lm_title")?.[0];
}
constructor(props: any) {
super(props);
@@ -757,7 +761,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
this._tabReaction = reaction(() => ({ views: SelectionManager.SelectedDocuments(), color: StrCast(this._document?._backgroundColor, "white") }),
(data) => {
const selected = data.views.some(v => Doc.AreProtosEqual(v.props.Document, this._document));
- this._tab.style.backgroundColor = selected ? data.color : "";
+ this._tab && (this._tab.style.backgroundColor = selected ? data.color : "");
}
);
}
diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx
index a9e812ad3..3cf46dbed 100644
--- a/src/client/views/collections/CollectionLinearView.tsx
+++ b/src/client/views/collections/CollectionLinearView.tsx
@@ -176,7 +176,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
}}
onPointerDown={e => e.stopPropagation()} >
<span className="bottomPopup-text" >
- Creating link from: {DocumentLinksButton.StartLink.props.Document.title}
+ Creating link from: {DocumentLinksButton.AnnotationId ? "Annotation in " : " "} {StrCast(DocumentLinksButton.StartLink.title).length < 51 ? DocumentLinksButton.StartLink.title : StrCast(DocumentLinksButton.StartLink.title).slice(0, 50) + '...'}
</span>
<Tooltip title={<><div className="dash-tooltip">{LinkDescriptionPopup.showDescriptions ? "Turn off description pop-up" :
diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index 2069255f7..20ae74b44 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -169,18 +169,18 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
StrCast(this.props.Document._searchString)
const length = StrCast(this.props.Document._searchString).length;
- results.push(<span style={{ color: contents ? "black" : "grey" }}>{contents ? contents.slice(0, positions[0]) : "enter value"}</span>);
+ results.push(<span style={{ color: contents ? "black" : "grey" }}>{contents ? contents.slice(0, positions[0]) : "undefined"}</span>);
positions.forEach((num, cur) => {
- results.push(<span style={{ backgroundColor: "#FFFF00", color: contents ? "black" : "grey" }}>{contents ? contents.slice(num, num + length) : "enter value"}</span>);
+ results.push(<span style={{ backgroundColor: "#FFFF00", color: contents ? "black" : "grey" }}>{contents ? contents.slice(num, num + length) : "undefined"}</span>);
let end = 0;
cur === positions.length - 1 ? end = contents.length : end = positions[cur + 1];
- results.push(<span style={{ color: contents ? "black" : "grey" }}>{contents ? contents.slice(num + length, end) : "enter value"}</span>);
+ results.push(<span style={{ color: contents ? "black" : "grey" }}>{contents ? contents.slice(num + length, end) : "undefined"}</span>);
}
);
return results;
}
else {
- return <span style={{ color: contents ? "black" : "grey" }}>{contents ? contents?.valueOf() : "enter value"}</span>;
+ return <span style={{ color: contents ? "black" : "grey" }}>{contents ? contents?.valueOf() : "undefined"}</span>;
}
}
@@ -214,7 +214,14 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
ContentScaling: returnOne
};
- const field = props.Document[props.fieldKey];
+ let matchedKeys = [props.fieldKey];
+ if (props.fieldKey.startsWith("*")) {
+ const allKeys = Array.from(Object.keys(props.Document));
+ allKeys.push(...Array.from(Object.keys(Doc.GetProto(props.Document))));
+ matchedKeys = allKeys.filter(key => key.includes(props.fieldKey.substring(1)));
+ }
+ const fieldKey = matchedKeys.length ? matchedKeys[0] : props.fieldKey;
+ const field = props.Document[fieldKey];
const doc = FieldValue(Cast(field, Doc));
const fieldIsDoc = (type === "document" && typeof field === "object") || (typeof field === "object" && doc);
@@ -247,7 +254,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
};
let contents: any = "incorrect type";
- if (type === undefined) contents = <FieldView {...props} />;
+ if (type === undefined) contents = <FieldView {...props} fieldKey={fieldKey} />;
if (type === "number") contents = typeof field === "number" ? NumCast(field) : "--" + typeof field + "--";
if (type === "string") contents = typeof field === "string" ? (StrCast(field) === "" ? "--" : StrCast(field)) : "--" + typeof field + "--";
if (type === "boolean") contents = typeof field === "boolean" ? (BoolCast(field) ? "true" : "false") : "--" + typeof field + "--";
@@ -335,7 +342,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
//contents={StrCast(contents)}
height={"auto"}
maxHeight={Number(MAX_ROW_HEIGHT)}
- placeholder={"enter value"}
+ placeholder={"undefined"}
bing={() => {
const cfield = ComputedField.WithoutComputed(() => FieldValue(props.Document[props.fieldKey]));
if (cfield !== undefined) {
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index e8dd74dab..b7d6f212f 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -348,7 +348,7 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
onKeyDown = (e: React.KeyboardEvent): void => {
if (e.key === "Enter") {
let keyOptions = this._searchTerm === "" ? this.props.possibleKeys : this.props.possibleKeys.filter(key => key.toUpperCase().indexOf(this._searchTerm.toUpperCase()) > -1);
- let blockedkeys = ["proto", "x", "y", "_width", "_height", "_autoHeight", "_fontSize", "_fontFamily", "context", "zIndex", "_timeStampOnEnter", "lines", "highlighting", "searchMatch", "creationDate", "isPrototype", "text-annotations", "aliases", "text-lastModified", "text-noTemplate", "layoutKey", "baseProto", "_xMargin", "_yMargin", "layout", "layout_keyValue", "links"];
+ let blockedkeys = ["_scrollTop", "customTitle", "limitHeight", "proto", "x", "y", "_width", "_height", "_autoHeight", "_fontSize", "_fontFamily", "context", "zIndex", "_timeStampOnEnter", "lines", "highlighting", "searchMatch", "creationDate", "isPrototype", "text-annotations", "aliases", "text-lastModified", "text-noTemplate", "layoutKey", "baseProto", "_xMargin", "_yMargin", "layout", "layout_keyValue", "links"];
keyOptions = keyOptions.filter(n => !blockedkeys.includes(n));
if (keyOptions.length) {
this.onSelect(keyOptions[0]);
@@ -450,9 +450,10 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
keyOptions.push(key);
}
});
-
+ //checked={() =>{Cast(this.props.Document!._docRangeFilters, listSpec("string"))!.includes(key)}}
const options = keyOptions.map(key => {
+ //Doc.setDocFilter(this.props.Document!, this._key, key, undefined);
return <div key={key} className="key-option" style={{
border: "1px solid lightgray", width: this.props.width, maxWidth: this.props.width, overflowX: "hidden", background: "white", backgroundColor: "white",
}}
@@ -656,7 +657,7 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
e.stopPropagation();
}} onFocus={this.onFocus} onBlur={this.onBlur}></input>
<div className="keys-options-wrapper" style={{
- width: this.props.width, maxWidth: this.props.width, overflow: "scroll", height: "auto",
+ width: this.props.width, maxWidth: this.props.width, height: "auto",
}}
onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerOut}>
{this._searchTerm.includes(":") ?
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 7409640eb..3f879b489 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -643,7 +643,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
</div>;
return <div className={name}
style={{
- overflow: this.props.overflow === true ? "auto" : undefined,
+ overflow: this.props.overflow === true ? "scroll" : undefined,
pointerEvents: !this.props.active() && !SnappingManager.GetIsDragging() ? "none" : undefined,
width: this.props.PanelWidth() || "100%", height: this.props.PanelHeight() || "100%", position: "relative",
}} >
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index fe3d57bdb..b27af66ba 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -4,7 +4,7 @@ import { CursorProperty } from "csstype";
import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx";
import { observer } from "mobx-react";
import Switch from 'rc-switch';
-import { DataSym, Doc, HeightSym, WidthSym } from "../../../fields/Doc";
+import { DataSym, Doc, HeightSym, WidthSym, DocListCastAsync } from "../../../fields/Doc";
import { collectionSchema, documentSchema } from "../../../fields/documentSchemas";
import { Id } from "../../../fields/FieldSymbols";
import { List } from "../../../fields/List";
@@ -28,6 +28,7 @@ import { CollectionViewType } from "./CollectionView";
import { SnappingManager } from "../../util/SnappingManager";
import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView";
import { DocUtils } from "../../documents/Documents";
+import { MainViewNotifs } from "../MainViewNotifs";
const _global = (window /* browser */ || global /* node */) as any;
type StackingDocument = makeInterface<[typeof collectionSchema, typeof documentSchema]>;
@@ -298,6 +299,10 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument)
const srcInd = docs.indexOf(doc);
docs.splice(srcInd, 1);
docs.splice((targInd > srcInd ? targInd - 1 : targInd) + plusOne, 0, doc);
+ DocListCastAsync(docs).then(resolvedDocs => {
+ const pos = resolvedDocs?.findIndex(shareDoc => shareDoc.icon === "users") || 0; // hopefully find out if the sharing doc has been moved
+ if (MainViewNotifs.NotifsCol && pos !== -1) MainViewNotifs.NotifsCol.position = pos;
+ });
} else if (i < (newDocs.length / 2)) { //glr: for some reason dragged documents are duplicated
if (targInd === -1) targInd = docs.length;
else targInd = docs.indexOf(newDocs[0]) + 1;
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 0a1bb3594..9be5a5d99 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -112,7 +112,6 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
[...this.props.docFilters(), ...Cast(this.props.Document._docFilters, listSpec("string"), [])];
}
@computed get childDocs() {
- //DO NOT CHANGE the new algorithm in this class without emailing andy r. first!!
let rawdocs: (Doc | Promise<Doc>)[] = [];
if (this.dataField instanceof Doc) { // if collection data is just a document, then promote it to a singleton list;
rawdocs = [this.dataField];
@@ -131,7 +130,6 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
const searchDocs = DocListCast(this.props.Document._searchDocs);
- //DO NOT CHANGE the new algorithm in this class without emailing andy r. first!!
let docsforFilter: Doc[] = childDocs;
if (searchDocs !== undefined && searchDocs.length > 0) {
@@ -141,7 +139,7 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
if (d.data !== undefined) {
let newdocs = DocListCast(d.data);
if (newdocs.length > 0) {
- let vibecheck: boolean | undefined = undefined;
+ let displaycheck: boolean | undefined = undefined;
let newarray: Doc[] = [];
while (newdocs.length > 0) {
newarray = [];
@@ -153,12 +151,12 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
});
}
if (searchDocs.includes(t)) {
- vibecheck = true;
+ displaycheck = true;
}
});
newdocs = newarray;
}
- if (vibecheck === true) {
+ if (displaycheck === true) {
docsforFilter.push(d);
}
}
@@ -171,8 +169,6 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
}
childDocs = docsforFilter;
-
- const docFilters = this.docFilters();
const docRangeFilters = this.props.ignoreFields?.includes("_docRangeFilters") ? [] : Cast(this.props.Document._docRangeFilters, listSpec("string"), []);
return this.props.Document.dontRegisterView ? childDocs : DocUtils.FilterDocs(childDocs, this.docFilters(), docRangeFilters, viewSpecScript);
@@ -391,14 +387,28 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
// }
}
if (uriList) {
- this.addDocument(Docs.Create.WebDocument(uriList, {
- ...options,
- title: uriList,
- _width: 400,
- _height: 315,
- _nativeWidth: 850,
- _nativeHeight: 962
- }));
+ const existingWebDoc = await Hypothesis.findWebDoc(uriList);
+ if (existingWebDoc) {
+ const alias = Doc.MakeAlias(existingWebDoc);
+ alias.x = options.x;
+ alias.y = options.y;
+ alias._nativeWidth = 850;
+ alias._nativeHeight = 962;
+ alias._width = 400;
+ this.addDocument(alias);
+ } else {
+ const newDoc = Docs.Create.WebDocument(uriList, {
+ ...options,
+ title: uriList.split("#annotations:")[0],
+ _width: 400,
+ _height: 315,
+ _nativeWidth: 850,
+ _nativeHeight: 962,
+ UseCors: true
+ });
+ newDoc.data = new WebField(uriList.split("#annotations:")[0]); // clean hypothes.is URLs that reference a specific annotation (eg. https://en.wikipedia.org/wiki/Cartoon#annotations:t7qAeNbCEeqfG5972KR2Ig)
+ this.addDocument(newDoc);
+ }
return;
}
@@ -480,4 +490,6 @@ import { FormattedTextBox, GoogleRef } from "../nodes/formattedText/FormattedTex
import { CollectionView, CollectionViewType } from "./CollectionView";
import { SelectionManager } from "../../util/SelectionManager";
import { OverlayView } from "../OverlayView";
-import { setTimeout } from "timers"; \ No newline at end of file
+import { setTimeout } from "timers";
+import { Hypothesis } from "../../util/HypothesisUtils";
+
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 73a5566d6..fe30cb05a 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -152,7 +152,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
if (this.props.Document[AclSym]) {
added.forEach(d => {
for (const [key, value] of Object.entries(this.props.Document[AclSym])) {
- if (d.author === Doc.CurrentUserEmail && !d.aliasOf) distributeAcls(key, SharingPermissions.Admin, d, true);
+ if (d.author === key.substring(4).replace("_", ".") && !d.aliasOf) distributeAcls(key, SharingPermissions.Admin, d, true);
else distributeAcls(key, this.AclMap.get(value) as SharingPermissions, d, true);
}
});
@@ -595,12 +595,11 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
Utils.CorsProxy(Cast(d.data, ImageField)!.url.href) : Cast(d.data, ImageField)!.url.href
:
""))}
- {/* {(Doc.UserDoc()?.noviceMode || !this.props.isSelected() && !this.props.Document.forceActive) || this.props.Document.hideFilterView ? (null) : */}
- <div className="collectionView-filterDragger" title="library View Dragger" onPointerDown={this.onPointerDown}
- style={{ right: this.facetWidth() - 1, top: this.props.Document._viewType === CollectionViewType.Docking ? "25%" : "55%" }} />
- {/* } */}
- {/* {Doc.UserDoc()?.noviceMode || this.facetWidth() < 10 ? (null) : this.filterView} */}
- {this.filterView};
+ {(Doc.UserDoc()?.noviceMode || !this.props.isSelected() && !this.props.Document.forceActive) || this.props.Document.hideFilterView ? (null) :
+ <div className="collectionView-filterDragger" title="library View Dragger" onPointerDown={this.onPointerDown}
+ style={{ right: this.facetWidth() - 1, top: this.props.Document._viewType === CollectionViewType.Docking ? "25%" : "60%" }} />
+ }
+ {Doc.UserDoc()?.noviceMode || this.facetWidth() < 10 ? (null) : this.filterView}
</div>);
}
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index ef4b7b9d2..2b8e949b1 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1257,7 +1257,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
!this.props.isAnnotationOverlay && !Doc.UserDoc().noviceMode &&
optionItems.push({ description: (this.showTimeline ? "Close" : "Open") + " Animation Timeline", event: action(() => this.showTimeline = !this.showTimeline), icon: faEye });
this.props.ContainingCollectionView &&
- optionItems.push({ description: "Promote Collection", event: this.promoteCollection, icon: "table" });
+ optionItems.push({ description: "Undo Collection", event: this.promoteCollection, icon: "table" });
optionItems.push({ description: this.layoutDoc._lockedTransform ? "Unlock Transform" : "Lock Transform", event: this.toggleLockTransform, icon: this.layoutDoc._lockedTransform ? "unlock" : "lock" });
optionItems.push({ description: "Use Background Color as Default", event: () => Cast(Doc.UserDoc().emptyCollection, Doc, null)._backgroundColor = StrCast(this.layoutDoc._backgroundColor), icon: "palette" });
if (!Doc.UserDoc().noviceMode) {
diff --git a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx
index 6263be261..1ffa2fbed 100644
--- a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx
+++ b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx
@@ -163,6 +163,78 @@ export default class FormatShapePane extends AntimodeMenu {
@undoBatch
@action
+ addPoints = (x: number, y: number, pts: { X: number, Y: number }[], index: number, control: { X: number, Y: number }[]) => {
+ this.selectedInk?.forEach(action(inkView => {
+ if (this.selectedInk?.length === 1) {
+ const doc = Document(inkView.rootDoc);
+ if (doc.type === DocumentType.INK) {
+ const ink = Cast(doc.data, InkField)?.inkData;
+ if (ink) {
+ const newPoints: { X: number, Y: number }[] = [];
+ var counter = 0;
+ for (var k = 0; k < index; k++) {
+ control.forEach(pt => (pts[k].X === pt.X && pts[k].Y === pt.Y) && counter++);
+ }
+ //decide where to put the new coordinate
+ const spNum = Math.floor(counter / 2) * 4 + 2;
+
+ for (var i = 0; i < spNum; i++) {
+ newPoints.push({ X: ink[i].X, Y: ink[i].Y });
+ }
+ for (var j = 0; j < 4; j++) {
+ newPoints.push({ X: x, Y: y });
+
+ }
+ for (var i = spNum; i < ink.length; i++) {
+ newPoints.push({ X: ink[i].X, Y: ink[i].Y });
+ }
+ this._currPoint = -1;
+ doc.data = new InkField(newPoints);
+ }
+ }
+ }
+ }));
+ }
+
+ @undoBatch
+ @action
+ deletePoints = () => {
+ this.selectedInk?.forEach(action(inkView => {
+ if (this.selectedInk?.length === 1 && this._currPoint !== -1) {
+ const doc = Document(inkView.rootDoc);
+ if (doc.type === DocumentType.INK) {
+ const ink = Cast(doc.data, InkField)?.inkData;
+ if (ink && ink.length > 4) {
+ const newPoints: { X: number, Y: number }[] = [];
+
+ console.log(ink.length, this._currPoint, Math.floor((this._currPoint + 2) / 4));
+
+ const toRemove = Math.floor(((this._currPoint + 2) / 4));
+ for (var i = 0; i < ink.length; i++) {
+ if (Math.floor((i + 2) / 4) !== toRemove) {
+ console.log(i, toRemove);
+ newPoints.push({ X: ink[i].X, Y: ink[i].Y });
+ }
+ }
+ this._currPoint = -1;
+ doc.data = new InkField(newPoints);
+ if (newPoints.length === 4) {
+ const newerPoints: { X: number, Y: number }[] = [];
+ newerPoints.push({ X: newPoints[0].X, Y: newPoints[0].Y });
+ newerPoints.push({ X: newPoints[0].X, Y: newPoints[0].Y });
+ newerPoints.push({ X: newPoints[3].X, Y: newPoints[3].Y });
+ newerPoints.push({ X: newPoints[3].X, Y: newPoints[3].Y });
+ doc.data = new InkField(newerPoints);
+
+ }
+ }
+ }
+ }
+ }));
+ }
+
+ @undoBatch
+ @action
rotate = (angle: number) => {
const _centerPoints: { X: number, Y: number }[] = [];
SelectionManager.SelectedDocuments().forEach(action(inkView => {
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
index db4b674b5..f1df7998b 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
@@ -3,6 +3,8 @@ import AntimodeMenu from "../../AntimodeMenu";
import { observer } from "mobx-react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { unimplementedFunction } from "../../../../Utils";
+import { undoBatch } from "../../../util/UndoManager";
+import { Tooltip } from "@material-ui/core";
@observer
export default class MarqueeOptionsMenu extends AntimodeMenu {
@@ -23,34 +25,34 @@ export default class MarqueeOptionsMenu extends AntimodeMenu {
render() {
const buttons = [
- <button
- className="antimodeMenu-button"
- title="Create a Collection"
- key="group"
- onPointerDown={this.createCollection}>
- <FontAwesomeIcon icon="object-group" size="lg" />
- </button>,
- <button
- className="antimodeMenu-button"
- title="Summarize Documents"
- key="summarize"
- onPointerDown={this.summarize}>
- <FontAwesomeIcon icon="compress-arrows-alt" size="lg" />
- </button>,
- <button
- className="antimodeMenu-button"
- title="Delete Documents"
- key="delete"
- onPointerDown={this.delete}>
- <FontAwesomeIcon icon="trash-alt" size="lg" />
- </button>,
- <button
- className="antimodeMenu-button"
- title="Change to Text"
- key="inkToText"
- onPointerDown={this.inkToText}>
- <FontAwesomeIcon icon="font" size="lg" />
- </button>,
+ <Tooltip key="group" title={<><div className="dash-tooltip">Create a Collection</div></>} placement="bottom">
+ <button
+ className="antimodeMenu-button"
+ onPointerDown={this.createCollection}>
+ <FontAwesomeIcon icon="object-group" size="lg" />
+ </button>
+ </Tooltip>,
+ <Tooltip key="summarize" title={<><div className="dash-tooltip">Summarize Documents</div></>} placement="bottom">
+ <button
+ className="antimodeMenu-button"
+ onPointerDown={this.summarize}>
+ <FontAwesomeIcon icon="compress-arrows-alt" size="lg" />
+ </button>
+ </Tooltip>,
+ <Tooltip key="delete" title={<><div className="dash-tooltip">Delete Documents</div></>} placement="bottom">
+ <button
+ className="antimodeMenu-button"
+ onPointerDown={this.delete}>
+ <FontAwesomeIcon icon="trash-alt" size="lg" />
+ </button>
+ </Tooltip>,
+ <Tooltip key="inkToText" title={<><div className="dash-tooltip">Change to Text</div></>} placement="bottom">
+ <button
+ className="antimodeMenu-button"
+ onPointerDown={this.inkToText}>
+ <FontAwesomeIcon icon="font" size="lg" />
+ </button>
+ </Tooltip>,
];
return this.getElement(buttons);
}
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 88fe03efd..1a708d67d 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -74,7 +74,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
if (e.key === "?") {
ContextMenu.Instance.setDefaultItem("?", (str: string) => {
const textDoc = Docs.Create.WebDocument(`https://bing.com/search?q=${str}`, {
- _width: 200, x, y, _nativeHeight: 962, _nativeWidth: 800, isAnnotating: false,
+ _width: 200, x, y, _nativeHeight: 962, _nativeWidth: 850, isAnnotating: false,
title: "bing", UseCors: true
});
this.props.addDocTab(textDoc, "onRight");
@@ -390,7 +390,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
this.hideMarquee();
}
- @action
+ @undoBatch @action
collection = (e: KeyboardEvent | React.PointerEvent | undefined) => {
const bounds = this.Bounds;
const selected = this.marqueeSelect(false);
@@ -415,7 +415,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
this.hideMarquee();
}
- @action
+ @undoBatch @action
syntaxHighlight = (e: KeyboardEvent | React.PointerEvent | undefined) => {
const selected = this.marqueeSelect(false);
if (e instanceof KeyboardEvent ? e.key === "i" : true) {
@@ -491,7 +491,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
}
}
- @action
+ @undoBatch @action
summary = (e: KeyboardEvent | React.PointerEvent | undefined) => {
const bounds = this.Bounds;
const selected = this.marqueeSelect(false);
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.scss b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
index 5e0c9fcbb..aee28366a 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.scss
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
@@ -23,8 +23,9 @@
height: 20px;
padding-left: 38px;
margin-top: -5px;
- right: 19;
- position: absolute;
+ align-items: flex-end;
+ margin-left: auto;
+ margin-right: 10px;
&:hover {
color: grey;
@@ -66,9 +67,9 @@
.propertiesView-settings-title-icon {
float: right;
- right: 0;
- position: absolute;
- margin-left: 2px;
+ justify-items: right;
+ align-items: flex-end;
+ margin-left: auto;
margin-right: 9px;
&:hover {
@@ -104,9 +105,9 @@
.propertiesView-sharing-title-icon {
float: right;
- right: 0;
- position: absolute;
- margin-left: 2px;
+ justify-items: right;
+ align-items: flex-end;
+ margin-left: auto;
margin-right: 9px;
&:hover {
@@ -154,9 +155,9 @@
.propertiesView-appearance-title-icon {
float: right;
- right: 0;
- position: absolute;
- margin-left: 2px;
+ justify-items: right;
+ align-items: flex-end;
+ margin-left: auto;
margin-right: 9px;
&:hover {
@@ -191,9 +192,9 @@
.propertiesView-transform-title-icon {
float: right;
- right: 0;
- position: absolute;
- margin-left: 2px;
+ justify-items: right;
+ align-items: flex-end;
+ margin-left: auto;
margin-right: 9px;
&:hover {
@@ -285,9 +286,8 @@
.propertiesView-sharingTable-item-permission {
display: flex;
- right: 34;
- float: right;
- position: absolute;
+ align-items: flex-end;
+ margin-left: auto;
.permissions-select {
z-index: 1;
@@ -326,25 +326,18 @@
cursor: pointer;
}
- .propertiesView-fields-title-name {
- font-size: 12.5px;
- font-weight: bold;
- white-space: nowrap;
- width: 35px;
- display: flex;
- }
-
.propertiesView-fields-title-icon {
float: right;
- right: 0;
- position: absolute;
- margin-left: 2px;
+ justify-items: right;
+ align-items: flex-end;
+ margin-left: auto;
margin-right: 9px;
&:hover {
cursor: pointer;
}
}
+
}
.propertiesView-fields-checkbox {
@@ -407,9 +400,9 @@
.propertiesView-layout-title-icon {
float: right;
- right: 0;
- position: absolute;
- margin-left: 2px;
+ justify-items: right;
+ align-items: flex-end;
+ margin-left: auto;
margin-right: 9px;
&:hover {
@@ -444,9 +437,9 @@
.propertiesView-presTrails-title-icon {
float: right;
- right: 0;
- position: absolute;
- margin-left: 2px;
+ justify-items: right;
+ align-items: flex-end;
+ margin-left: auto;
margin-right: 9px;
&:hover {
@@ -730,4 +723,9 @@
&:hover {
border: 0.75px solid rgb(122, 28, 28);
}
+}
+
+
+.properties-flyout {
+ grid-column: 2/4;
} \ No newline at end of file
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index 15900aa33..e0f3eca44 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -52,7 +52,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
@computed get selectedDocumentView() {
if (SelectionManager.SelectedDocuments().length) {
return SelectionManager.SelectedDocuments()[0];
- } else if (PresBox.Instance?._selectedArray.length) {
+ } else if (PresBox.Instance && PresBox.Instance._selectedArray.length) {
return DocumentManager.Instance.getDocumentView(PresBox.Instance.rootDoc);
} else { return undefined; }
}
@@ -248,7 +248,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
}
@observable transform: Transform = Transform.Identity();
- getTransform = () => { return this.transform; }
+ getTransform = () => this.transform;
propertiesDocViewRef = (ref: HTMLDivElement) => {
const observer = new _global.ResizeObserver(action((entries: any) => {
const cliRect = ref.getBoundingClientRect();
@@ -645,16 +645,19 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
set colorStk(value) { value && (this._lastLine = value); this.selectedDoc && (this.selectedDoc.color = value ? value : undefined); }
colorButton(value: string, type: string, setter: () => {}) {
- return <Flyout anchorPoint={anchorPoints.LEFT_TOP}
- content={type === "fill" ? this.fillPicker : this.linePicker}>
- <div className="color-button" key="color" onPointerDown={undoBatch(action(e => setter()))}>
- <div className="color-button-preview" style={{
- backgroundColor: value ?? "121212", width: 15, height: 15,
- display: value === "" || value === "transparent" ? "none" : ""
- }} />
- {value === "" || value === "transparent" ? <p style={{ fontSize: 25, color: "red", marginTop: -14, position: "fixed" }}>☒</p> : ""}
- </div>
- </Flyout>;
+ // return <div className="properties-flyout" onPointerEnter={e => this.changeScrolling(false)}
+ // onPointerLeave={e => this.changeScrolling(true)}>
+ // <Flyout anchorPoint={anchorPoints.LEFT_TOP}
+ // content={type === "fill" ? this.fillPicker : this.linePicker}>
+ return <div className="color-button" key="color" onPointerDown={undoBatch(action(e => setter()))}>
+ <div className="color-button-preview" style={{
+ backgroundColor: value ?? "121212", width: 15, height: 15,
+ display: value === "" || value === "transparent" ? "none" : ""
+ }} />
+ {value === "" || value === "transparent" ? <p style={{ fontSize: 25, color: "red", marginTop: -14 }}>☒</p> : ""}
+ </div>;
+ // </Flyout>
+ // </div>;
}
@@ -699,8 +702,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
<div className="stroke-button">{this.lineButton}</div>
</div>
</div>
- {/* {this._fillBtn ? this.fillPicker : ""}
- {this._lineBtn ? this.linePicker : ""} */}
+ {this._fillBtn ? this.fillPicker : ""}
+ {this._lineBtn ? this.linePicker : ""}
</div>;
}
@@ -826,7 +829,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
if (this.selectedDoc && !this.isPres) {
return <div className="propertiesView" style={{
width: this.props.width,
- // overflowY: this.inActions ? "visible" : "scroll"
+ //overflowY: this.scrolling ? "scroll" : "visible"
}} >
<div className="propertiesView-title" style={{ width: this.props.width }}>
Properties
@@ -931,11 +934,9 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
<div className="propertiesView-fields-title"
onPointerDown={() => runInAction(() => { this.openFields = !this.openFields; })}
style={{ backgroundColor: this.openFields ? "black" : "" }}>
- <div className="propertiesView-fields-title-name">
- Fields {"&"} Tags
+ Fields {"&"} Tags
<div className="propertiesView-fields-title-icon">
- <FontAwesomeIcon icon={this.openFields ? "caret-down" : "caret-right"} size="lg" color="white" />
- </div>
+ <FontAwesomeIcon icon={this.openFields ? "caret-down" : "caret-right"} size="lg" color="white" />
</div>
</div>
{!novice && this.openFields ? <div className="propertiesView-fields-checkbox">
@@ -962,19 +963,16 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
}
if (this.isPres) {
const selectedItem: boolean = PresBox.Instance?._selectedArray.length > 0;
- return <div className="propertiesView" style={{ width: this.props.width }} >
- <div className="propertiesView-title" style={{ width: this.props.width }}>
+ return <div className="propertiesView">
+ <div className="propertiesView-title">
Presentation
- <div className="propertiesView-title-icon" onPointerDown={this.props.onDown}>
- <FontAwesomeIcon icon="times" color="black" size="sm" />
- </div>
</div>
<div className="propertiesView-name">
{this.editableTitle}
<div className="propertiesView-presSelected">
- {PresBox.Instance?._selectedArray.length} selected
+ {PresBox.Instance._selectedArray.length} selected
<div className="propertiesView-selectedList">
- {PresBox.Instance?.listOfSelected}
+ {PresBox.Instance.listOfSelected}
</div>
</div>
</div>