aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2020-07-03 20:46:59 -0400
committerGitHub <noreply@github.com>2020-07-03 20:46:59 -0400
commitdf00289aad1c35e3811c02aada6479a5490e9650 (patch)
tree09cb1933ad5805c2df8fa32db2dadd8f85f24f51 /src
parenta979ebce6cf3b3aaa0fb6ea3870988b6edc6a889 (diff)
parent397f9811b6675dce5e770082ee68435b7e560f7f (diff)
Merge pull request #432 from browngraphicslab/anika_linking
Initial Linking Changes
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/Documents.ts4
-rw-r--r--src/client/views/DocumentButtonBar.tsx2
-rw-r--r--src/client/views/GlobalKeyHandler.ts8
-rw-r--r--src/client/views/MainView.tsx8
-rw-r--r--src/client/views/collections/CollectionLinearView.scss64
-rw-r--r--src/client/views/collections/CollectionLinearView.tsx34
-rw-r--r--src/client/views/collections/CollectionView.tsx11
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx34
-rw-r--r--src/client/views/linking/LinkMenu.scss9
-rw-r--r--src/client/views/linking/LinkMenu.tsx11
-rw-r--r--src/client/views/linking/LinkMenuGroup.tsx4
-rw-r--r--src/client/views/linking/LinkMenuItem.scss11
-rw-r--r--src/client/views/linking/LinkMenuItem.tsx47
-rw-r--r--src/client/views/nodes/DocumentLinksButton.scss2
-rw-r--r--src/client/views/nodes/DocumentLinksButton.tsx84
-rw-r--r--src/client/views/nodes/DocumentView.tsx22
-rw-r--r--src/client/views/nodes/LinkAnchorBox.scss7
-rw-r--r--src/client/views/nodes/LinkCreatedBox.scss21
-rw-r--r--src/client/views/nodes/LinkCreatedBox.tsx31
-rw-r--r--src/client/views/nodes/LinkDocPreview.tsx54
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx40
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBoxComment.scss86
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx154
-rw-r--r--src/fields/Doc.ts2
24 files changed, 625 insertions, 125 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 85da621e0..f81c25bab 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -1,4 +1,4 @@
-import { runInAction } from "mobx";
+import { runInAction, action } from "mobx";
import { extname, basename } from "path";
import { DateField } from "../../fields/DateField";
import { Doc, DocListCast, DocListCastAsync, Field, HeightSym, Opt, WidthSym } from "../../fields/Doc";
@@ -866,6 +866,7 @@ export namespace DocUtils {
export function MakeLinkToActiveAudio(doc: Doc) {
DocUtils.ActiveRecordings.map(d => DocUtils.MakeLink({ doc: doc }, { doc: d }, "audio link", "audio timeline"));
}
+
export function MakeLink(source: { doc: Doc }, target: { doc: Doc }, linkRelationship: string = "", id?: string) {
const sv = DocumentManager.Instance.getDocumentView(source.doc);
if (sv && sv.props.ContainingCollectionDoc === target.doc) return;
@@ -877,6 +878,7 @@ export namespace DocUtils {
Doc.GetProto(source.doc).links = ComputedField.MakeFunction("links(self)");
Doc.GetProto(target.doc).links = ComputedField.MakeFunction("links(self)");
+
return linkDoc;
}
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 40a9d0c45..1667b2f65 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -271,7 +271,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
const considerPush = isText && this.considerGoogleDocsPush;
return <div className="documentButtonBar">
<div className="documentButtonBar-button">
- <DocumentLinksButton View={this.view0} AlwaysOn={true} />
+ <DocumentLinksButton View={this.view0} AlwaysOn={true} InMenu={true} />
</div>
<div className="documentButtonBar-button">
{this.templateButton}
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index ff8380965..34f666f62 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -79,7 +79,15 @@ export default class KeyManager {
// MarqueeView.DragMarquee = !MarqueeView.DragMarquee; // bcz: this needs a better disclosure UI
break;
case "escape":
+ // if (DocumentLinksButton.StartLink) {
+ // if (DocumentLinksButton.StartLink.Document) {
+ // action((e: React.PointerEvent<HTMLDivElement>) => {
+ // Doc.UnBrushDoc(DocumentLinksButton.StartLink?.Document as Doc);
+ // });
+ // }
+ // }
DocumentLinksButton.StartLink = undefined;
+
const main = MainView.Instance;
Doc.SetSelectedTool(InkTool.None);
var doDeselect = true;
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index fab1798e2..15f818d1f 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -4,7 +4,7 @@ import {
faTerminal, faToggleOn, faFile as fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard,
faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
- faLongArrowAltRight, faMicrophone, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote,
+ faLongArrowAltRight, faMicrophone, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote, faTimesCircle,
faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faArrowsAlt, faQuoteLeft, faSortAmountDown, faAlignLeft, faAlignCenter, faAlignRight
} from '@fortawesome/free-solid-svg-icons';
import { ANTIMODEMENU_HEIGHT } from './globalCssVariables.scss';
@@ -59,6 +59,8 @@ import { DocumentManager } from '../util/DocumentManager';
import { DocumentLinksButton } from './nodes/DocumentLinksButton';
import { LinkMenu } from './linking/LinkMenu';
import { LinkDocPreview } from './nodes/LinkDocPreview';
+import { Fade } from '@material-ui/core';
+import { LinkCreatedBox } from './nodes/LinkCreatedBox';
@observer
export class MainView extends React.Component {
@@ -82,7 +84,6 @@ export class MainView extends React.Component {
public isPointerDown = false;
-
componentDidMount() {
DocServer.setPlaygroundFields(["dataTransition", "_viewTransition", "_panX", "_panY", "_viewScale", "_viewType"]); // can play with these fields on someone else's
@@ -138,7 +139,7 @@ export class MainView extends React.Component {
}
library.add(faTasks, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus,
- faTerminal, faToggleOn, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard, fileSolid,
+ faTerminal, faToggleOn, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faTimesCircle, faWindowMaximize, faAddressCard, fileSolid,
faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt,
faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter,
faLongArrowAltRight, faMicrophone, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote, faTrashAlt, faAngleRight, faBell,
@@ -606,6 +607,7 @@ export class MainView extends React.Component {
{this.mainContent}
</GestureOverlay>
<PreviewCursor />
+ <LinkCreatedBox />
{DocumentLinksButton.EditLink ? <LinkMenu location={DocumentLinksButton.EditLinkLoc} docView={DocumentLinksButton.EditLink} addDocTab={DocumentLinksButton.EditLink.props.addDocTab} changeFlyout={emptyFunction} /> : (null)}
{LinkDocPreview.LinkInfo ? <LinkDocPreview location={LinkDocPreview.LinkInfo.Location} backgroundColor={this.defaultBackgroundColors}
linkDoc={LinkDocPreview.LinkInfo.linkDoc} linkSrc={LinkDocPreview.LinkInfo.linkSrc} href={LinkDocPreview.LinkInfo.href}
diff --git a/src/client/views/collections/CollectionLinearView.scss b/src/client/views/collections/CollectionLinearView.scss
index 123a27deb..5ada79a28 100644
--- a/src/client/views/collections/CollectionLinearView.scss
+++ b/src/client/views/collections/CollectionLinearView.scss
@@ -1,12 +1,51 @@
@import "../globalCssVariables";
@import "../_nodeModuleOverrides";
-.collectionLinearView-outer{
+.collectionLinearView-outer {
overflow: hidden;
- height:100%;
+ height: 100%;
+
.collectionLinearView {
- display:flex;
+ display: flex;
height: 100%;
+
+ >span {
+ background: $dark-color;
+ color: $light-color;
+ border-radius: 18px;
+ margin-right: 6px;
+ cursor: pointer;
+ }
+
+ .bottomPopup-background {
+ padding-right: 14px;
+ height: 35;
+ transform: translate3d(6px, 5px, 0px);
+ padding-top: 6.5px;
+ padding-bottom: 7px;
+ padding-left: 5px;
+ }
+
+ .bottomPopup-text {
+ display: inline;
+ white-space: nowrap;
+ padding-left: 8px;
+ padding-right: 4px;
+ vertical-align: middle;
+ font-size: 12.5px;
+ }
+
+ .bottomPopup-exit {
+ display: inline;
+ white-space: nowrap;
+ padding-left: 8px;
+ padding-right: 8px;
+ vertical-align: middle;
+ background-color: lightgrey;
+ border-radius: 5.5px;
+ color: black;
+ }
+
>label {
margin-top: "auto";
margin-bottom: "auto";
@@ -17,15 +56,15 @@
font-size: 12.5px;
width: 18px;
height: 18px;
- margin-top:auto;
- margin-bottom:auto;
+ margin-top: auto;
+ margin-bottom: auto;
margin-right: 3px;
cursor: pointer;
transition: transform 0.2s;
}
label p {
- padding-left:5px;
+ padding-left: 5px;
}
label:hover {
@@ -36,6 +75,7 @@
>input {
display: none;
}
+
>input:not(:checked)~.collectionLinearView-content {
display: none;
}
@@ -52,12 +92,14 @@
position: relative;
margin-top: auto;
- .collectionLinearView-docBtn, .collectionLinearView-docBtn-scalable {
- position:relative;
- margin:auto;
+ .collectionLinearView-docBtn,
+ .collectionLinearView-docBtn-scalable {
+ position: relative;
+ margin: auto;
margin-left: 3px;
transform-origin: center 80%;
}
+
.collectionLinearView-docBtn-scalable:hover {
transform: scale(1.15);
}
@@ -68,10 +110,10 @@
border-radius: 18px;
font-size: 15px;
}
-
+
.collectionLinearView-round-button:hover {
transform: scale(1.15);
}
}
}
-}
+} \ No newline at end of file
diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx
index f38eeaf41..7cbe5c19d 100644
--- a/src/client/views/collections/CollectionLinearView.tsx
+++ b/src/client/views/collections/CollectionLinearView.tsx
@@ -13,6 +13,8 @@ import { CollectionSubView } from './CollectionSubView';
import { DocumentView } from '../nodes/DocumentView';
import { documentSchema } from '../../../fields/documentSchemas';
import { Id } from '../../../fields/FieldSymbols';
+import { DocumentLinksButton } from '../nodes/DocumentLinksButton';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
type LinearDocument = makeInterface<[typeof documentSchema,]>;
@@ -75,6 +77,18 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
return new Transform(-translateX, -translateY, 1);
}
+ @action
+ exitLongLinks = () => {
+ if (DocumentLinksButton.StartLink) {
+ if (DocumentLinksButton.StartLink.Document) {
+ action((e: React.PointerEvent<HTMLDivElement>) => {
+ Doc.UnBrushDoc(DocumentLinksButton.StartLink?.Document as Doc);
+ });
+ }
+ }
+ DocumentLinksButton.StartLink = undefined;
+ }
+
render() {
const guid = Utils.GenerateGuid();
const flexDir: any = StrCast(this.Document.flexDirection);
@@ -82,7 +96,12 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
const color = StrCast(this.props.Document.color, "white");
return <div className="collectionLinearView-outer">
<div className="collectionLinearView" ref={this.createDashEventsTarget} >
- <label htmlFor={`${guid}`} title="Close Menu" style={{ background: backgroundColor === color ? "black" : backgroundColor }}
+ <label htmlFor={`${guid}`} title="Close Menu" style={{
+ background: backgroundColor === color ? "black" : backgroundColor,
+ // width: "18px", height: "18px", fontSize: "12.5px",
+ // transition: this.props.Document.linearViewIsExpanded ? "transform 0.2s" : "transform 0.5s",
+ // transform: this.props.Document.linearViewIsExpanded ? "" : "rotate(45deg)"
+ }}
onPointerDown={e => e.stopPropagation()} >
<p>+</p>
</label>
@@ -130,6 +149,19 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
</div>;
})}
</div>
+ {DocumentLinksButton.StartLink ? <span className="bottomPopup-background" style={{
+ background: backgroundColor === color ? "black" : backgroundColor
+ }}
+ onPointerDown={e => e.stopPropagation()} >
+ <span className="bottomPopup-text" >
+ Creating link from: {DocumentLinksButton.StartLink.title} </span>
+ <span className="bottomPopup-exit" onClick={this.exitLongLinks}
+ >Exit</span>
+
+ {/* <FontAwesomeIcon icon="times-circle" size="lg" style={{ color: "red" }}
+ onClick={this.exitLongLinks} /> */}
+
+ </span> : null}
</div>
</div>;
}
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 10ebe571b..26abd2529 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -12,26 +12,29 @@ import { AclAddonly, AclReadonly, AclSym, DataSym, Doc, DocListCast, Field, Opt
import { Id } from '../../../fields/FieldSymbols';
import { List } from '../../../fields/List';
import { ObjectField } from '../../../fields/ObjectField';
+import { RichTextField } from '../../../fields/RichTextField';
import { listSpec } from '../../../fields/Schema';
import { ComputedField, ScriptField } from '../../../fields/ScriptField';
import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
import { ImageField } from '../../../fields/URLField';
import { TraceMobx } from '../../../fields/util';
-import { emptyFunction, emptyPath, returnFalse, returnOne, returnZero, setupMoveUpEvents, Utils, returnEmptyFilter } from '../../../Utils';
+import { emptyFunction, emptyPath, returnEmptyFilter, returnFalse, returnOne, returnZero, setupMoveUpEvents, Utils } from '../../../Utils';
import { Docs, DocUtils } from '../../documents/Documents';
import { DocumentType } from '../../documents/DocumentTypes';
import { CurrentUserUtils } from '../../util/CurrentUserUtils';
import { ImageUtils } from '../../util/Import & Export/ImageUtils';
import { InteractionUtils } from '../../util/InteractionUtils';
+import { UndoManager } from '../../util/UndoManager';
import { ContextMenu } from "../ContextMenu";
import { FieldView, FieldViewProps } from '../nodes/FieldView';
import { ScriptBox } from '../ScriptBox';
import { Touchable } from '../Touchable';
-import { CollectionCarouselView } from './CollectionCarouselView';
import { CollectionCarousel3DView } from './CollectionCarousel3DView';
+import { CollectionCarouselView } from './CollectionCarouselView';
import { CollectionDockingView } from "./CollectionDockingView";
import { AddCustomFreeFormLayout } from './collectionFreeForm/CollectionFreeFormLayoutEngines';
import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';
+import { CollectionGridView } from './collectionGrid/CollectionGridView';
import { CollectionLinearView } from './CollectionLinearView';
import CollectionMapView from './CollectionMapView';
import { CollectionMulticolumnView } from './collectionMulticolumn/CollectionMulticolumnView';
@@ -43,12 +46,8 @@ import { CollectionStaffView } from './CollectionStaffView';
import { SubCollectionViewProps } from './CollectionSubView';
import { CollectionTimeView } from './CollectionTimeView';
import { CollectionTreeView } from "./CollectionTreeView";
-import { CollectionGridView } from './collectionGrid/CollectionGridView';
import './CollectionView.scss';
import { CollectionViewBaseChrome } from './CollectionViewChromes';
-import { UndoManager } from '../../util/UndoManager';
-import { RichTextField } from '../../../fields/RichTextField';
-import { TextField } from '../../util/ProsemirrorCopy/prompt';
const higflyout = require("@hig/flyout");
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 21b0473c9..b81e400b3 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1,53 +1,51 @@
import { library } from "@fortawesome/fontawesome-svg-core";
-import { faEye, faEyeSlash } from "@fortawesome/free-regular-svg-icons";
+import { faEye } from "@fortawesome/free-regular-svg-icons";
import { faBraille, faChalkboard, faCompass, faCompressArrowsAlt, faExpandArrowsAlt, faFileUpload, faPaintBrush, faTable, faUpload } from "@fortawesome/free-solid-svg-icons";
-import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction, _allowStateChangesInsideComputed, trace } from "mobx";
+import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from "mobx";
import { observer } from "mobx-react";
import { computedFn } from "mobx-utils";
-import { Doc, HeightSym, Opt, WidthSym, DocListCast } from "../../../../fields/Doc";
-import { documentSchema, collectionSchema } from "../../../../fields/documentSchemas";
+import { Doc, DocListCast, HeightSym, Opt, WidthSym } from "../../../../fields/Doc";
+import { collectionSchema, documentSchema } from "../../../../fields/documentSchemas";
import { Id } from "../../../../fields/FieldSymbols";
-import { InkData, InkField, InkTool, PointData } from "../../../../fields/InkField";
+import { InkData, InkField, InkTool } from "../../../../fields/InkField";
import { List } from "../../../../fields/List";
import { RichTextField } from "../../../../fields/RichTextField";
-import { createSchema, listSpec, makeInterface } from "../../../../fields/Schema";
-import { ScriptField, ComputedField } from "../../../../fields/ScriptField";
+import { createSchema, makeInterface } from "../../../../fields/Schema";
+import { ScriptField } from "../../../../fields/ScriptField";
import { BoolCast, Cast, FieldValue, NumCast, ScriptCast, StrCast } from "../../../../fields/Types";
import { TraceMobx } from "../../../../fields/util";
import { GestureUtils } from "../../../../pen-gestures/GestureUtils";
-import { aggregateBounds, intersectRect, returnOne, Utils, returnZero, returnFalse, numberRange } from "../../../../Utils";
+import { aggregateBounds, intersectRect, returnFalse, returnOne, returnZero, Utils } from "../../../../Utils";
import { CognitiveServices } from "../../../cognitive_services/CognitiveServices";
import { DocServer } from "../../../DocServer";
import { Docs, DocUtils } from "../../../documents/Documents";
+import { DocumentType } from "../../../documents/DocumentTypes";
import { DocumentManager } from "../../../util/DocumentManager";
import { DragManager, dropActionType } from "../../../util/DragManager";
import { HistoryUtil } from "../../../util/History";
import { InteractionUtils } from "../../../util/InteractionUtils";
import { SelectionManager } from "../../../util/SelectionManager";
+import { SnappingManager } from "../../../util/SnappingManager";
import { Transform } from "../../../util/Transform";
import { undoBatch, UndoManager } from "../../../util/UndoManager";
import { COLLECTION_BORDER_WIDTH } from "../../../views/globalCssVariables.scss";
+import { Timeline } from "../../animationtimeline/Timeline";
import { ContextMenu } from "../../ContextMenu";
-import { ContextMenuProps } from "../../ContextMenuItem";
+import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth } from "../../InkingStroke";
import { CollectionFreeFormDocumentView } from "../../nodes/CollectionFreeFormDocumentView";
-import { DocumentViewProps, DocumentView } from "../../nodes/DocumentView";
+import { DocumentLinksButton } from "../../nodes/DocumentLinksButton";
+import { DocumentViewProps } from "../../nodes/DocumentView";
import { FormattedTextBox } from "../../nodes/formattedText/FormattedTextBox";
import { pageSchema } from "../../nodes/ImageBox";
-import PDFMenu from "../../pdf/PDFMenu";
import { CollectionDockingView } from "../CollectionDockingView";
import { CollectionSubView } from "../CollectionSubView";
-import { computePivotLayout, computeTimelineLayout, PoolData, ViewDefBounds, ViewDefResult, computerStarburstLayout, computerPassLayout } from "./CollectionFreeFormLayoutEngines";
+import { CollectionViewType } from "../CollectionView";
+import { computePivotLayout, computerPassLayout, computerStarburstLayout, computeTimelineLayout, PoolData, ViewDefBounds, ViewDefResult } from "./CollectionFreeFormLayoutEngines";
import { CollectionFreeFormRemoteCursors } from "./CollectionFreeFormRemoteCursors";
import "./CollectionFreeFormView.scss";
import MarqueeOptionsMenu from "./MarqueeOptionsMenu";
import { MarqueeView } from "./MarqueeView";
import React = require("react");
-import { CollectionViewType } from "../CollectionView";
-import { Timeline } from "../../animationtimeline/Timeline";
-import { SnappingManager } from "../../../util/SnappingManager";
-import { InkingStroke, ActiveArrowStart, ActiveArrowEnd, ActiveInkColor, ActiveFillColor, ActiveInkWidth, ActiveInkBezierApprox, ActiveDash } from "../../InkingStroke";
-import { DocumentType } from "../../../documents/DocumentTypes";
-import { DocumentLinksButton } from "../../nodes/DocumentLinksButton";
library.add(faEye as any, faTable, faPaintBrush, faExpandArrowsAlt, faCompressArrowsAlt, faCompass, faUpload, faBraille, faChalkboard, faFileUpload);
diff --git a/src/client/views/linking/LinkMenu.scss b/src/client/views/linking/LinkMenu.scss
index c372e7098..6468ccd3d 100644
--- a/src/client/views/linking/LinkMenu.scss
+++ b/src/client/views/linking/LinkMenu.scss
@@ -15,7 +15,7 @@
}
.linkMenu-group {
- border-bottom: 0.5px solid lightgray;
+ border-bottom: 0.5px solid lightgray;
padding: 5px 0;
@@ -30,9 +30,11 @@
p {
background-color: lightgray;
}
+
p.expand-one {
width: calc(100% - 26px);
}
+
.linkEditor-tableButton {
display: block;
}
@@ -50,7 +52,4 @@
display: none;
}
}
-}
-
-
-
+} \ No newline at end of file
diff --git a/src/client/views/linking/LinkMenu.tsx b/src/client/views/linking/LinkMenu.tsx
index de1d60a09..c672511ac 100644
--- a/src/client/views/linking/LinkMenu.tsx
+++ b/src/client/views/linking/LinkMenu.tsx
@@ -10,6 +10,7 @@ import { LinkMenuGroup } from "./LinkMenuGroup";
import { faTrash } from '@fortawesome/free-solid-svg-icons';
import { library } from "@fortawesome/fontawesome-svg-core";
import { DocumentLinksButton } from "../nodes/DocumentLinksButton";
+import { LinkDocPreview } from "../nodes/LinkDocPreview";
library.add(faTrash);
@@ -28,9 +29,16 @@ export class LinkMenu extends React.Component<Props> {
@action
onClick = (e: PointerEvent) => {
+
+ LinkDocPreview.LinkInfo = undefined;
+
if (this._linkMenuRef?.contains(e.target as any)) {
DocumentLinksButton.EditLink = undefined;
}
+
+ if (this._linkMenuRef && !this._linkMenuRef.contains(e.target as any)) {
+ DocumentLinksButton.EditLink = undefined;
+ }
}
@action
componentDidMount() {
@@ -70,7 +78,8 @@ export class LinkMenu extends React.Component<Props> {
render() {
const sourceDoc = this.props.docView.props.Document;
const groups: Map<string, Doc[]> = LinkManager.Instance.getRelatedGroupedLinks(sourceDoc);
- return <div className="linkMenu-list" ref={(r) => this._linkMenuRef = r} style={{ left: this.props.location[0], top: this.props.location[1] }}>
+ return <div className="linkMenu-list"
+ ref={(r) => this._linkMenuRef = r} style={{ left: this.props.location[0], top: this.props.location[1] }}>
{!this._editingLink ?
this.renderAllGroups(groups) :
<LinkEditor sourceDoc={this.props.docView.props.Document} linkDoc={this._editingLink} showLinks={action(() => this._editingLink = undefined)} />
diff --git a/src/client/views/linking/LinkMenuGroup.tsx b/src/client/views/linking/LinkMenuGroup.tsx
index 89deb3a55..7892d381b 100644
--- a/src/client/views/linking/LinkMenuGroup.tsx
+++ b/src/client/views/linking/LinkMenuGroup.tsx
@@ -80,11 +80,11 @@ export class LinkMenuGroup extends React.Component<LinkMenuGroupProps> {
return (
<div className="linkMenu-group">
- <div className="linkMenu-group-name">
+ {/* <div className="linkMenu-group-name">
<p ref={this._drag} onPointerDown={this.onLinkButtonDown}
className={this.props.groupType === "*" || this.props.groupType === "" ? "" : "expand-one"} > {this.props.groupType}:</p>
{this.props.groupType === "*" || this.props.groupType === "" ? <></> : this.viewGroupAsTable(this.props.groupType)}
- </div>
+ </div> */}
<div className="linkMenu-group-wrapper">
{groupItems}
</div>
diff --git a/src/client/views/linking/LinkMenuItem.scss b/src/client/views/linking/LinkMenuItem.scss
index fd0954f65..e3ce69cd7 100644
--- a/src/client/views/linking/LinkMenuItem.scss
+++ b/src/client/views/linking/LinkMenuItem.scss
@@ -5,7 +5,7 @@
position: relative;
display: flex;
font-size: 12px;
-
+
.linkMenu-name {
position: relative;
@@ -22,7 +22,7 @@
.linkMenu-item-content {
width: 100%;
}
-
+
.link-metadata {
padding: 0 10px 0 16px;
margin-bottom: 4px;
@@ -35,11 +35,13 @@
.linkMenu-item-buttons {
display: flex;
}
+
.linkMenu-item-content {
&.expand-two p {
width: calc(100% - 52px);
background-color: lightgray;
}
+
&.expand-three p {
width: calc(100% - 84px);
background-color: lightgray;
@@ -49,11 +51,11 @@
}
.linkMenu-item-buttons {
- display: none;
position: absolute;
top: 50%;
right: 0;
transform: translateY(-50%);
+ display: none;
.button {
width: 20px;
@@ -61,7 +63,6 @@
margin: 0;
margin-right: 6px;
border-radius: 50%;
- cursor: pointer;
pointer-events: auto;
background-color: $dark-color;
color: $light-color;
@@ -80,8 +81,10 @@
&:last-child {
margin-right: 0;
}
+
&:hover {
background: $main-accent;
+ cursor: grab;
}
}
} \ No newline at end of file
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index edc18b6a9..04cd83ee0 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -1,5 +1,5 @@
import { library } from '@fortawesome/fontawesome-svg-core';
-import { faArrowRight, faChevronDown, faChevronUp, faEdit, faEye, faTimes } from '@fortawesome/free-solid-svg-icons';
+import { faArrowRight, faChevronDown, faChevronUp, faEdit, faEye, faTimes, faPencilAlt } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, observable } from 'mobx';
import { observer } from "mobx-react";
@@ -13,7 +13,9 @@ import React = require("react");
import { DocumentManager } from '../../util/DocumentManager';
import { setupMoveUpEvents, emptyFunction } from '../../../Utils';
import { DocumentView } from '../nodes/DocumentView';
-library.add(faEye, faEdit, faTimes, faArrowRight, faChevronDown, faChevronUp);
+import { DocumentLinksButton } from '../nodes/DocumentLinksButton';
+import { LinkDocPreview } from '../nodes/LinkDocPreview';
+library.add(faEye, faEdit, faTimes, faArrowRight, faChevronDown, faChevronUp, faPencilAlt);
interface LinkMenuItemProps {
@@ -69,6 +71,8 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
private _eleClone: any;
_editRef = React.createRef<HTMLDivElement>();
+ _buttonRef = React.createRef<HTMLDivElement>();
+
@observable private _showMore: boolean = false;
@action toggleShowMore(e: React.PointerEvent) { e.stopPropagation(); this._showMore = !this._showMore; }
@@ -95,6 +99,7 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
return (<div className="link-metadata">{mdRows}</div>);
}
+ @action
onLinkButtonDown = (e: React.PointerEvent): void => {
this._downX = e.clientX;
this._downY = e.clientY;
@@ -104,6 +109,10 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
document.addEventListener("pointermove", this.onLinkButtonMoved);
document.removeEventListener("pointerup", this.onLinkButtonUp);
document.addEventListener("pointerup", this.onLinkButtonUp);
+
+ if (this._buttonRef && this._buttonRef.current?.contains(e.target as any)) {
+ LinkDocPreview.LinkInfo = undefined;
+ }
}
onLinkButtonUp = (e: PointerEvent): void => {
@@ -124,7 +133,10 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
e.stopPropagation();
}
+ @action
onContextMenu = (e: React.MouseEvent) => {
+ DocumentLinksButton.EditLink = undefined;
+ LinkDocPreview.LinkInfo = undefined;
e.preventDefault();
ContextMenu.Instance.addItem({ description: "Follow Default Link", event: () => this.followDefault(), icon: "arrow-right" });
ContextMenu.Instance.displayMenu(e.clientX, e.clientY);
@@ -132,9 +144,20 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
@action.bound
async followDefault() {
+ console.log("FOLLOWWW");
+ DocumentLinksButton.EditLink = undefined;
+ LinkDocPreview.LinkInfo = undefined;
DocumentManager.Instance.FollowLink(this.props.linkDoc, this.props.sourceDoc, doc => this.props.addDocTab(doc, "onRight"), false);
}
+ @action
+ deleteLink = (): void => {
+ LinkManager.Instance.deleteLink(this.props.linkDoc);
+ //this.props.showLinks();
+ LinkDocPreview.LinkInfo = undefined;
+ DocumentLinksButton.EditLink = undefined;
+ }
+
render() {
const keys = LinkManager.Instance.getMetadataKeysInGroup(this.props.groupType);//groupMetadataKeys.get(this.props.groupType);
const canExpand = keys ? keys.length > 0 : false;
@@ -142,13 +165,25 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
return (
<div className="linkMenu-item">
<div className={canExpand ? "linkMenu-item-content expand-three" : "linkMenu-item-content expand-two"}>
- <div ref={this._drag} className="linkMenu-name" title="drag to view target. click to customize." onPointerDown={this.onLinkButtonDown}>
+ <div ref={this._drag} className="linkMenu-name" //title="drag to view target. click to customize."
+ onPointerLeave={action(() => LinkDocPreview.LinkInfo = undefined)}
+ onPointerEnter={action(e => this.props.linkDoc && (LinkDocPreview.LinkInfo = {
+ addDocTab: this.props.addDocTab,
+ linkSrc: this.props.sourceDoc,
+ linkDoc: this.props.linkDoc,
+ Location: [e.clientX, e.clientY + 20]
+ }))}
+ onPointerDown={this.onLinkButtonDown}>
<p >{StrCast(this.props.destinationDoc.title)}</p>
- <div className="linkMenu-item-buttons">
+ <div className="linkMenu-item-buttons" ref={this._buttonRef} >
{canExpand ? <div title="Show more" className="button" onPointerDown={e => this.toggleShowMore(e)}>
<FontAwesomeIcon className="fa-icon" icon={this._showMore ? "chevron-up" : "chevron-down"} size="sm" /></div> : <></>}
- <div title="Edit link" className="button" ref={this._editRef} onPointerDown={this.onEdit}><FontAwesomeIcon className="fa-icon" icon="edit" size="sm" /></div>
- <div title="Follow link" className="button" onClick={this.followDefault} onContextMenu={this.onContextMenu}>
+
+ {/* <div title="Edit link" className="button" ref={this._editRef} onPointerDown={this.onEdit}>
+ <FontAwesomeIcon className="fa-icon" icon="pencil-alt" size="sm" /></div> */}
+ <div title="Delete link" className="button" onPointerDown={this.deleteLink}>
+ <FontAwesomeIcon className="fa-icon" icon="trash" size="sm" /></div>
+ <div title="Follow link" className="button" onPointerDown={this.followDefault} onContextMenu={this.onContextMenu}>
<FontAwesomeIcon className="fa-icon" icon="arrow-right" size="sm" />
</div>
</div>
diff --git a/src/client/views/nodes/DocumentLinksButton.scss b/src/client/views/nodes/DocumentLinksButton.scss
index 484f8c469..b58603978 100644
--- a/src/client/views/nodes/DocumentLinksButton.scss
+++ b/src/client/views/nodes/DocumentLinksButton.scss
@@ -23,7 +23,7 @@
&:hover {
background: deepskyblue;
transform: scale(1.05);
- cursor: default;
+ cursor: grab;
}
}
.documentLinksButton {
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index 3940b7a98..bfd860f65 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -10,6 +10,7 @@ import React = require("react");
import { DocUtils } from "../../documents/Documents";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { LinkDocPreview } from "./LinkDocPreview";
+import { LinkCreatedBox } from "./LinkCreatedBox";
const higflyout = require("@hig/flyout");
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
@@ -18,11 +19,14 @@ interface DocumentLinksButtonProps {
View: DocumentView;
Offset?: number[];
AlwaysOn?: boolean;
+ InMenu?: boolean;
}
@observer
export class DocumentLinksButton extends React.Component<DocumentLinksButtonProps, {}> {
private _linkButton = React.createRef<HTMLDivElement>();
+ @observable public static StartLink: DocumentView | undefined;
+
@action
onLinkButtonMoved = (e: PointerEvent) => {
if (this._linkButton.current !== null) {
@@ -50,30 +54,73 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
return false;
}
- @observable static StartLink: DocumentView | undefined;
onLinkButtonDown = (e: React.PointerEvent): void => {
setupMoveUpEvents(this, e, this.onLinkButtonMoved, emptyFunction, action((e, doubleTap) => {
- if (doubleTap) {
+ if (doubleTap && this.props.InMenu) {
+ //action(() => Doc.BrushDoc(this.props.View.Document));
DocumentLinksButton.StartLink = this.props.View;
- } else {
+ } else if (!!!this.props.InMenu) {
DocumentLinksButton.EditLink = this.props.View;
DocumentLinksButton.EditLinkLoc = [e.clientX + 10, e.clientY];
}
}));
}
+
+ @action
+ onLinkClick = (e: React.MouseEvent): void => {
+ if (this.props.InMenu) {
+ DocumentLinksButton.StartLink = this.props.View;
+ //action(() => Doc.BrushDoc(this.props.View.Document));
+ } else if (!!!this.props.InMenu) {
+ DocumentLinksButton.EditLink = this.props.View;
+ DocumentLinksButton.EditLinkLoc = [e.clientX + 10, e.clientY];
+ }
+ }
+
+ @action
completeLink = (e: React.PointerEvent): void => {
setupMoveUpEvents(this, e, returnFalse, emptyFunction, action((e, doubleTap) => {
if (doubleTap) {
if (DocumentLinksButton.StartLink === this.props.View) {
DocumentLinksButton.StartLink = undefined;
+ // action((e: React.PointerEvent<HTMLDivElement>) => {
+ // Doc.UnBrushDoc(this.props.View.Document);
+ // });
} else {
DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View &&
DocUtils.MakeLink({ doc: DocumentLinksButton.StartLink.props.Document }, { doc: this.props.View.props.Document }, "long drag");
+
+ runInAction(() => {
+ LinkCreatedBox.popupX = e.screenX;
+ LinkCreatedBox.popupY = e.screenY - 120;
+ LinkCreatedBox.linkCreated = true;
+ setTimeout(action(() => { LinkCreatedBox.linkCreated = false; }), 2500);
+ });
}
}
}));
}
+ @action
+ finishLinkClick = (e: React.MouseEvent) => {
+ if (DocumentLinksButton.StartLink === this.props.View) {
+ DocumentLinksButton.StartLink = undefined;
+ // action((e: React.PointerEvent<HTMLDivElement>) => {
+ // Doc.UnBrushDoc(this.props.View.Document);
+ // });
+ } else {
+ DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View &&
+ DocUtils.MakeLink({ doc: DocumentLinksButton.StartLink.props.Document }, { doc: this.props.View.props.Document }, "long drag");
+
+ runInAction(() => {
+ LinkCreatedBox.popupX = e.screenX;
+ LinkCreatedBox.popupY = e.screenY - 120;
+ LinkCreatedBox.linkCreated = true;
+ setTimeout(action(() => { LinkCreatedBox.linkCreated = false; }), 2500);
+ });
+ }
+ }
+
@observable
public static EditLink: DocumentView | undefined;
public static EditLinkLoc: number[] = [0, 0];
@@ -83,19 +130,26 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
const links = DocListCast(this.props.View.props.Document.links);
return (!links.length || links[0].hidden) && !this.props.AlwaysOn ? (null) :
<div title="Drag(create link) Tap(view links)" ref={this._linkButton} style={{ minWidth: 20, minHeight: 20, position: "absolute", left: this.props.Offset?.[0] }}>
- <div className={"documentLinksButton"} style={{ backgroundColor: DocumentLinksButton.StartLink ? "transparent" : "" }}
- onPointerDown={this.onLinkButtonDown}
- onPointerLeave={action(() => LinkDocPreview.LinkInfo = undefined)}
- onPointerEnter={action(e => links.length && (LinkDocPreview.LinkInfo = {
- addDocTab: this.props.View.props.addDocTab,
- linkSrc: this.props.View.props.Document,
- linkDoc: links[0],
- Location: [e.clientX, e.clientY + 20]
- }))} >
- {links.length ? links.length : <FontAwesomeIcon className="documentdecorations-icon" icon="link" size="sm" />}
+ <div className={"documentLinksButton"} style={{
+ backgroundColor: DocumentLinksButton.StartLink ? "transparent" : "",
+ width: this.props.InMenu ? "20px" : "30px", height: this.props.InMenu ? "20px" : "30px", fontWeight: "bold"
+ }}
+ onPointerDown={this.onLinkButtonDown} onClick={this.onLinkClick}
+ // onPointerLeave={action(() => LinkDocPreview.LinkInfo = undefined)}
+ // onPointerEnter={action(e => links.length && (LinkDocPreview.LinkInfo = {
+ // addDocTab: this.props.View.props.addDocTab,
+ // linkSrc: this.props.View.props.Document,
+ // linkDoc: links[0],
+ // Location: [e.clientX, e.clientY + 20]
+ // }))}
+ >
+ {links.length && !!!this.props.InMenu ? links.length : <FontAwesomeIcon className="documentdecorations-icon" icon="link" size="sm" />}
</div>
- {DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View ? <div className={"documentLinksButton-endLink"} onPointerDown={this.completeLink} /> : (null)}
- {DocumentLinksButton.StartLink === this.props.View ? <div className={"documentLinksButton-startLink"} /> : (null)}
+ {DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View ? <div className={"documentLinksButton-endLink"}
+ style={{ width: this.props.InMenu ? "20px" : "30px", height: this.props.InMenu ? "20px" : "30px" }}
+ onPointerDown={this.completeLink} onClick={e => this.finishLinkClick(e)} /> : (null)}
+ {DocumentLinksButton.StartLink === this.props.View ? <div className={"documentLinksButton-startLink"}
+ style={{ width: this.props.InMenu ? "20px" : "30px", height: this.props.InMenu ? "20px" : "30px" }} /> : (null)}
</div>;
}
render() {
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 98adab5fa..b38db9a1e 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -42,6 +42,7 @@ import { RadialMenu } from './RadialMenu';
import React = require("react");
import { DocumentLinksButton } from './DocumentLinksButton';
import { MobileInterface } from '../../../mobile/MobileInterface';
+import { LinkCreatedBox } from './LinkCreatedBox';
library.add(fa.faEdit, fa.faTrash, fa.faShare, fa.faDownload, fa.faExpandArrowsAlt, fa.faCompressArrowsAlt, fa.faLayerGroup, fa.faExternalLinkAlt, fa.faAlignCenter, fa.faCaretSquareRight,
fa.faSquare, fa.faConciergeBell, fa.faWindowRestore, fa.faFolder, fa.faMapPin, fa.faLink, fa.faFingerprint, fa.faCrosshairs, fa.faDesktop, fa.faUnlock, fa.faLock, fa.faLaptopCode, fa.faMale,
@@ -116,6 +117,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
protected multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer;
private holdDisposer?: InteractionUtils.MultiTouchEventDisposer;
+ public get title() { return this.props.Document.title; }
public get displayName() { return "DocumentView(" + this.props.Document.title + ")"; } // this makes mobx trace() statements more descriptive
public get ContentDiv() { return this._mainCont.current; }
get active() { return SelectionManager.IsSelected(this, true) || this.props.parentActive(true); }
@@ -640,12 +642,27 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
e.stopPropagation();
de.complete.annoDragData.linkedToDoc = true;
+ runInAction(() => {
+ LinkCreatedBox.popupX = de.x;
+ LinkCreatedBox.popupY = de.y;
+ LinkCreatedBox.linkCreated = true;
+ setTimeout(action(() => { LinkCreatedBox.linkCreated = false; }), 2500);
+ });
+
DocUtils.MakeLink({ doc: de.complete.annoDragData.annotationDocument }, { doc: this.props.Document }, "link");
}
if (de.complete.linkDragData) {
e.stopPropagation();
// const docs = await SearchUtil.Search(`data_l:"${destDoc[Id]}"`, true);
// const views = docs.map(d => DocumentManager.Instance.getDocumentView(d)).filter(d => d).map(d => d as DocumentView);
+
+ runInAction(() => {
+ LinkCreatedBox.popupX = de.x;
+ LinkCreatedBox.popupY = de.y;
+ LinkCreatedBox.linkCreated = true;
+ setTimeout(action(() => { LinkCreatedBox.linkCreated = false; }), 2500);
+ });
+
de.complete.linkDragData.linkSourceDocument !== this.props.Document &&
(de.complete.linkDragData.linkDocument = DocUtils.MakeLink({ doc: de.complete.linkDragData.linkSourceDocument },
{ doc: this.props.Document }, `link`)); // TODODO this is where in text links get passed
@@ -1192,7 +1209,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
id={this.props.Document[Id]}
ref={this._mainCont} onKeyDown={this.onKeyDown}
onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown} onClick={this.onClick}
- onPointerEnter={action(() => Doc.BrushDoc(this.props.Document))}
+ onPointerEnter={action(() => { Doc.BrushDoc(this.props.Document); })}
onPointerLeave={action((e: React.PointerEvent<HTMLDivElement>) => {
let entered = false;
const target = document.elementFromPoint(e.nativeEvent.x, e.nativeEvent.y);
@@ -1201,7 +1218,10 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
entered = true;
}
}
+ // if (this.props.Document !== DocumentLinksButton.StartLink?.Document) {
!entered && Doc.UnBrushDoc(this.props.Document);
+ //}
+
})}
style={{
transformOrigin: this._animateScalingTo ? "center center" : undefined,
diff --git a/src/client/views/nodes/LinkAnchorBox.scss b/src/client/views/nodes/LinkAnchorBox.scss
index 710f2178b..42ef2958e 100644
--- a/src/client/views/nodes/LinkAnchorBox.scss
+++ b/src/client/views/nodes/LinkAnchorBox.scss
@@ -1,4 +1,5 @@
-.linkAnchorBox-cont, .linkAnchorBox-cont-small {
+.linkAnchorBox-cont,
+.linkAnchorBox-cont-small {
cursor: default;
position: absolute;
width: 15;
@@ -24,6 +25,6 @@
}
.linkAnchorBox-cont-small {
- width:5px;
- height:5px;
+ width: 5px;
+ height: 5px;
} \ No newline at end of file
diff --git a/src/client/views/nodes/LinkCreatedBox.scss b/src/client/views/nodes/LinkCreatedBox.scss
new file mode 100644
index 000000000..3cbd38b55
--- /dev/null
+++ b/src/client/views/nodes/LinkCreatedBox.scss
@@ -0,0 +1,21 @@
+.linkCreatedBox-fade {
+ border: 1px solid rgb(100, 100, 100);
+
+
+ width: auto;
+ position: absolute;
+
+ height: auto;
+ z-index: 10000;
+ border-radius: 13px;
+ font-size: 13px;
+ white-space: nowrap;
+
+ color: rgb(100, 100, 100);
+ background-color: rgba(250, 250, 250, 0.85);
+ padding-top: 6.5px;
+ padding-bottom: 6.5px;
+ font-weight: bold;
+ padding-left: 9px;
+ padding-right: 9px;
+} \ No newline at end of file
diff --git a/src/client/views/nodes/LinkCreatedBox.tsx b/src/client/views/nodes/LinkCreatedBox.tsx
new file mode 100644
index 000000000..d157d3fca
--- /dev/null
+++ b/src/client/views/nodes/LinkCreatedBox.tsx
@@ -0,0 +1,31 @@
+import React = require("react");
+import { observer } from "mobx-react";
+import { documentSchema } from "../../../fields/documentSchemas";
+import { makeInterface } from "../../../fields/Schema";
+import "./LinkCreatedBox.scss";
+import { observable, action } from "mobx";
+import { Fade } from "@material-ui/core";
+
+
+@observer
+export class LinkCreatedBox extends React.Component<{}> {
+
+ @observable public static linkCreated: boolean = false;
+ @observable public static popupX: number = 600;
+ @observable public static popupY: number = 250;
+
+ @action
+ public static changeLinkCreated = () => {
+ LinkCreatedBox.linkCreated = !LinkCreatedBox.linkCreated;
+ }
+
+ render() {
+ return <Fade in={LinkCreatedBox.linkCreated}>
+ <div className="linkCreatedBox-fade"
+ style={{
+ left: LinkCreatedBox.popupX ? LinkCreatedBox.popupX : 600,
+ top: LinkCreatedBox.popupY ? LinkCreatedBox.popupY : 250,
+ }}>Link Created</div>
+ </Fade>;
+ }
+} \ No newline at end of file
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index e8a08abb5..197dc8df4 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -10,6 +10,11 @@ import { Transform } from "../../util/Transform";
import { ContentFittingDocumentView } from "./ContentFittingDocumentView";
import React = require("react");
import { DocumentView } from './DocumentView';
+import { sortAndDeduplicateDiagnostics } from 'typescript';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { LinkManager } from '../../util/LinkManager';
+import { DocumentLinksButton } from './DocumentLinksButton';
+import { ContextMenu } from '../ContextMenu';
interface Props {
linkDoc?: Doc;
@@ -24,6 +29,31 @@ export class LinkDocPreview extends React.Component<Props> {
@observable public static LinkInfo: Opt<{ linkDoc?: Doc; addDocTab: (document: Doc, where: string) => boolean, linkSrc: Doc; href?: string; Location: number[] }>;
@observable _targetDoc: Opt<Doc>;
@observable _toolTipText = "";
+ _editRef = React.createRef<HTMLDivElement>();
+
+ @action
+ deleteLink = (): void => {
+ this.props.linkDoc ? LinkManager.Instance.deleteLink(this.props.linkDoc) : null;
+ //this.props.showLinks();
+ LinkDocPreview.LinkInfo = undefined;
+ DocumentLinksButton.EditLink = undefined;
+ }
+
+ @action
+ onContextMenu = (e: React.MouseEvent) => {
+ DocumentLinksButton.EditLink = undefined;
+ LinkDocPreview.LinkInfo = undefined;
+ e.preventDefault();
+ ContextMenu.Instance.addItem({ description: "Follow Default Link", event: () => this.followDefault(), icon: "arrow-right" });
+ ContextMenu.Instance.displayMenu(e.clientX, e.clientY);
+ }
+
+ @action.bound
+ async followDefault() {
+ DocumentLinksButton.EditLink = undefined;
+ LinkDocPreview.LinkInfo = undefined;
+ this._targetDoc ? DocumentManager.Instance.FollowLink(this.props.linkDoc, this._targetDoc, doc => this.props.addDocTab(doc, "onRight"), false) : null;
+ }
componentDidUpdate() { this.updatePreview(); }
componentDidMount() { this.updatePreview(); }
@@ -56,15 +86,30 @@ export class LinkDocPreview extends React.Component<Props> {
this.props.addDocTab(Docs.Create.WebDocument(this.props.href, { title: this.props.href, _width: 200, _height: 400, UseCors: true }), "onRight");
}
}
- width = () => Math.min(350, NumCast(this._targetDoc?.[WidthSym](), 350));
- height = () => Math.min(350, NumCast(this._targetDoc?.[HeightSym](), 350));
+ width = () => Math.min(225, NumCast(this._targetDoc?.[WidthSym](), 225));
+ height = () => Math.min(225, NumCast(this._targetDoc?.[HeightSym](), 225));
@computed get targetDocView() {
return !this._targetDoc ?
- <div style={{ pointerEvents: "all", maxWidth: 350, maxHeight: 250, width: "100%", height: "100%", overflow: "hidden" }}>
+ <div style={{
+ pointerEvents: "all", maxWidth: 225, maxHeight: 225, width: "100%", height: "100%",
+ overflow: "hidden"
+ }}>
<div style={{ width: "100%", height: "100%", textOverflow: "ellipsis", }} onPointerDown={this.pointerDown}>
{this._toolTipText}
</div>
</div> :
+ // <div style={{
+ // border: "6px solid white",
+ // }}>
+ // <div style={{ backgroundColor: "white" }}> {this._targetDoc.title}
+ // <div className="wrapper" style={{ float: "right" }}>
+ // <div title="Delete link" className="button" style={{ display: "inline" }} ref={this._editRef} onPointerDown={this.deleteLink}>
+ // <FontAwesomeIcon className="fa-icon" icon="trash" size="sm" /></div>
+ // <div title="Follow link" className="button" style={{ display: "inline" }} onClick={this.followDefault} onContextMenu={this.onContextMenu}>
+ // <FontAwesomeIcon className="fa-icon" icon="arrow-right" size="sm" />
+ // </div>
+ // </div>
+ // </div>
<ContentFittingDocumentView
Document={this._targetDoc}
LibraryPath={emptyPath}
@@ -92,6 +137,7 @@ export class LinkDocPreview extends React.Component<Props> {
NativeWidth={returnZero}
NativeHeight={returnZero}
/>;
+ //</div>;
}
render() {
@@ -99,7 +145,7 @@ export class LinkDocPreview extends React.Component<Props> {
style={{
position: "absolute", left: this.props.location[0],
top: this.props.location[1], width: this.width(), height: this.height(),
- boxShadow: "black 2px 2px 1em"
+ boxShadow: "black 2px 2px 1em", zIndex: 1000
}}>
{this.targetDocView}
</div>;
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 69708e7a0..167ba782f 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -59,6 +59,7 @@ import { FieldView, FieldViewProps } from "../FieldView";
import "./FormattedTextBox.scss";
import { FormattedTextBoxComment, formattedTextBoxCommentPlugin, findLinkMark } from './FormattedTextBoxComment';
import React = require("react");
+import { DocumentManager } from '../../../util/DocumentManager';
library.add(faEdit);
library.add(faSmile, faTextHeight, faUpload);
@@ -1079,7 +1080,42 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
}
@action
+ onDoubleClick = (e: React.MouseEvent): void => {
+
+ this.doLinkOnDeselect();
+ FormattedTextBox._downEvent = true;
+ FormattedTextBoxComment.textBox = this;
+ if (this.props.onClick && e.button === 0 && !this.props.isSelected(false)) {
+ e.preventDefault();
+ }
+ if (e.button === 0 && this.props.isSelected(true) && !e.altKey && !e.ctrlKey && !e.metaKey) {
+ if (e.clientX < this.ProseRef!.getBoundingClientRect().right) { // stop propagation if not in sidebar
+ e.stopPropagation(); // if the text box is selected, then it consumes all down events
+ }
+ }
+ if (e.button === 2 || (e.button === 0 && e.ctrlKey)) {
+ e.preventDefault();
+ }
+ FormattedTextBoxComment.Hide();
+ if (FormattedTextBoxComment.linkDoc) {
+ if (FormattedTextBoxComment.linkDoc.type !== DocumentType.LINK) {
+ this.props.addDocTab(FormattedTextBoxComment.linkDoc, e.ctrlKey ? "inTab" : "onRight");
+ } else {
+ DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, this.props.Document,
+ (doc: Doc, followLinkLocation: string) => this.props.addDocTab(doc, e.ctrlKey ? "inTab" : followLinkLocation));
+ }
+ }
+
+ (e.nativeEvent as any).formattedHandled = true;
+
+ if (e.buttons === 1 && this.props.isSelected(true) && !e.altKey) {
+ e.stopPropagation();
+ }
+ }
+
+ @action
onFocused = (e: React.FocusEvent): void => {
+ console.log("FOUCSS");
FormattedTextBox.FocusedBox = this;
this.tryUpdateHeight();
@@ -1211,6 +1247,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
}
public static HadSelection: boolean = false;
onBlur = (e: any) => {
+ console.log("BLURRR");
FormattedTextBox.HadSelection = window.getSelection()?.toString() !== "";
//DictationManager.Controls.stop(false);
this.endUndoTypingBatch();
@@ -1347,6 +1384,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
}
}
})}
+ onDoubleClick={this.onDoubleClick}
>
<div className={`formattedTextBox-outer`} ref={this._scrollRef}
style={{ width: `calc(100% - ${this.sidebarWidthPercent})`, pointerEvents: !this.props.isSelected() ? "none" : undefined }}
@@ -1393,7 +1431,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
setTimeout(() => this._editorView!.focus(), 500);
e.stopPropagation();
}} >
- <FontAwesomeIcon className="formattedTExtBox-audioFont"
+ <FontAwesomeIcon className="formattedTextBox-audioFont"
style={{ color: this._recording ? "red" : "blue", opacity: this._recording ? 1 : 0.5, display: this.props.isSelected() ? "" : "none" }} icon={"microphone"} size="sm" />
</div>}
</div>
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss b/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
index 2dd63ec21..9089e7039 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.scss
@@ -8,10 +8,12 @@
margin-bottom: 7px;
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
- }
- .FormattedTextBox-tooltip:before {
+}
+
+.FormattedTextBox-tooltip:before {
content: "";
- height: 0; width: 0;
+ height: 0;
+ width: 0;
position: absolute;
left: 50%;
margin-left: -5px;
@@ -19,10 +21,12 @@
border: 5px solid transparent;
border-bottom-width: 0;
border-top-color: silver;
- }
- .FormattedTextBox-tooltip:after {
+}
+
+.FormattedTextBox-tooltip:after {
content: "";
- height: 0; width: 0;
+ height: 0;
+ width: 0;
position: absolute;
left: 50%;
margin-left: -5px;
@@ -30,4 +34,72 @@
border: 5px solid transparent;
border-bottom-width: 0;
border-top-color: white;
- } \ No newline at end of file
+}
+
+.FormattedTextBoxComment-buttons {
+ display: none;
+ position: absolute;
+ top: 50%;
+ right: 0;
+ transform: translateY(-50%);
+
+ .FormattedTextBoxComment-button {
+ width: 20px;
+ height: 20px;
+ margin: 0;
+ margin-right: 6px;
+ border-radius: 50%;
+ pointer-events: auto;
+ background-color: rgb(38, 40, 41);
+ color: rgb(178, 181, 184);
+ font-size: 65%;
+ transition: transform 0.2s;
+ text-align: center;
+ position: relative;
+
+ // margin-top: "auto";
+ // margin-bottom: "auto";
+ // background: black;
+ // color: white;
+ // display: inline-block;
+ // border-radius: 18px;
+ // font-size: 12.5px;
+ // width: 18px;
+ // height: 18px;
+ // margin-top: auto;
+ // margin-bottom: auto;
+ // margin-right: 3px;
+ // cursor: pointer;
+ // transition: transform 0.2s;
+
+ .FormattedTextBoxComment-fa-icon {
+ margin-top: "auto";
+ margin-bottom: "auto";
+ background: black;
+ color: white;
+ display: inline-block;
+ border-radius: 18px;
+ font-size: 12.5px;
+ width: 18px;
+ height: 18px;
+ margin-top: auto;
+ margin-bottom: auto;
+ margin-right: 3px;
+ cursor: pointer;
+ transition: transform 0.2s;
+ // position: absolute;
+ // top: 50%;
+ // left: 50%;
+ // transform: translate(-50%, -50%);
+ }
+
+ &:last-child {
+ margin-right: 0;
+ }
+
+ &:hover {
+ background: rgb(53, 146, 199);
+ ;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index 4c90b6afd..56826e5c7 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -2,7 +2,7 @@ import { Mark, ResolvedPos } from "prosemirror-model";
import { EditorState, Plugin } from "prosemirror-state";
import { EditorView } from "prosemirror-view";
import * as ReactDOM from 'react-dom';
-import { Doc, DocCastAsync } from "../../../../fields/Doc";
+import { Doc, DocCastAsync, Opt } from "../../../../fields/Doc";
import { Cast, FieldValue, NumCast } from "../../../../fields/Types";
import { emptyFunction, returnEmptyString, returnFalse, Utils, emptyPath, returnZero, returnOne, returnEmptyFilter } from "../../../../Utils";
import { DocServer } from "../../../DocServer";
@@ -16,6 +16,11 @@ import React = require("react");
import { Docs } from "../../../documents/Documents";
import wiki from "wikijs";
import { DocumentType } from "../../../documents/DocumentTypes";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { action } from "mobx";
+import { LinkManager } from "../../../util/LinkManager";
+import { LinkDocPreview } from "../LinkDocPreview";
+import { DocumentLinksButton } from "../DocumentLinksButton";
export let formattedTextBoxCommentPlugin = new Plugin({
view(editorView) { return new FormattedTextBoxComment(editorView); }
@@ -62,6 +67,10 @@ export class FormattedTextBoxComment {
static mark: Mark;
static textBox: FormattedTextBox | undefined;
static linkDoc: Doc | undefined;
+
+ static _deleteRef: Opt<HTMLDivElement | null>;
+ static _followRef: Opt<HTMLDivElement | null>;
+
constructor(view: any) {
if (!FormattedTextBoxComment.tooltip) {
const root = document.getElementById("root");
@@ -75,8 +84,8 @@ export class FormattedTextBoxComment {
FormattedTextBoxComment.tooltip.appendChild(FormattedTextBoxComment.tooltipText);
FormattedTextBoxComment.tooltip.className = "FormattedTextBox-tooltip";
FormattedTextBoxComment.tooltip.style.pointerEvents = "all";
- FormattedTextBoxComment.tooltip.style.maxWidth = "350px";
- FormattedTextBoxComment.tooltip.style.maxHeight = "250px";
+ FormattedTextBoxComment.tooltip.style.maxWidth = "200px";
+ FormattedTextBoxComment.tooltip.style.maxHeight = "206px";
FormattedTextBoxComment.tooltip.style.width = "100%";
FormattedTextBoxComment.tooltip.style.height = "100%";
FormattedTextBoxComment.tooltip.style.overflow = "hidden";
@@ -87,12 +96,25 @@ export class FormattedTextBoxComment {
const textBox = FormattedTextBoxComment.textBox;
if (FormattedTextBoxComment.linkDoc && !keep && textBox) {
if (FormattedTextBoxComment.linkDoc.author) {
- if (FormattedTextBoxComment.linkDoc.type !== DocumentType.LINK) {
- textBox.props.addDocTab(FormattedTextBoxComment.linkDoc, e.ctrlKey ? "inTab" : "onRight");
+
+ if (FormattedTextBoxComment._deleteRef && FormattedTextBoxComment._deleteRef.contains(e.target as any)) {
+ this.deleteLink();
+ } else if (FormattedTextBoxComment._followRef && FormattedTextBoxComment._followRef.contains(e.target as any)) {
+ if (FormattedTextBoxComment.linkDoc.type !== DocumentType.LINK) {
+ textBox.props.addDocTab(FormattedTextBoxComment.linkDoc, e.ctrlKey ? "inTab" : "onRight");
+ } else {
+ DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, textBox.props.Document,
+ (doc: Doc, followLinkLocation: string) => textBox.props.addDocTab(doc, e.ctrlKey ? "inTab" : followLinkLocation));
+ }
} else {
- DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, textBox.props.Document,
- (doc: Doc, followLinkLocation: string) => textBox.props.addDocTab(doc, e.ctrlKey ? "inTab" : followLinkLocation));
+ if (FormattedTextBoxComment.linkDoc.type !== DocumentType.LINK) {
+ textBox.props.addDocTab(FormattedTextBoxComment.linkDoc, e.ctrlKey ? "inTab" : "onRight");
+ } else {
+ DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, textBox.props.Document,
+ (doc: Doc, followLinkLocation: string) => textBox.props.addDocTab(doc, e.ctrlKey ? "inTab" : followLinkLocation));
+ }
}
+
}
} else if (textBox && (FormattedTextBoxComment.tooltipText as any).href) {
textBox.props.addDocTab(Docs.Create.WebDocument((FormattedTextBoxComment.tooltipText as any).href, { title: (FormattedTextBoxComment.tooltipText as any).href, _width: 200, _height: 400, UseCors: true }), "onRight");
@@ -106,6 +128,15 @@ export class FormattedTextBoxComment {
}
}
+ @action
+ deleteLink = () => {
+ FormattedTextBoxComment.linkDoc ? LinkManager.Instance.deleteLink(FormattedTextBoxComment.linkDoc) : null;
+ LinkDocPreview.LinkInfo = undefined;
+ DocumentLinksButton.EditLink = undefined;
+ //FormattedTextBoxComment.tooltipText = undefined;
+ FormattedTextBoxComment.Hide();
+ }
+
public static Hide() {
FormattedTextBoxComment.textBox = undefined;
FormattedTextBoxComment.tooltip && (FormattedTextBoxComment.tooltip.style.display = "none");
@@ -210,32 +241,87 @@ export class FormattedTextBoxComment {
}
if (target?.author) {
FormattedTextBoxComment.showCommentbox("", view, nbef);
- ReactDOM.render(<ContentFittingDocumentView
- Document={target}
- LibraryPath={emptyPath}
- fitToBox={true}
- moveDocument={returnFalse}
- rootSelected={returnFalse}
- ScreenToLocalTransform={Transform.Identity}
- parentActive={returnFalse}
- addDocument={returnFalse}
- removeDocument={returnFalse}
- addDocTab={returnFalse}
- pinToPres={returnFalse}
- dontRegisterView={true}
- docFilters={returnEmptyFilter}
- ContainingCollectionDoc={undefined}
- ContainingCollectionView={undefined}
- renderDepth={0}
- PanelWidth={() => Math.min(350, NumCast(target._width, 350))}
- PanelHeight={() => Math.min(250, NumCast(target._height, 250))}
- focus={emptyFunction}
- whenActiveChanged={returnFalse}
- bringToFront={returnFalse}
- ContentScaling={returnOne}
- NativeWidth={returnZero}
- NativeHeight={returnZero}
- />, FormattedTextBoxComment.tooltipText);
+ const docPreview = <div style={{ backgroundColor: "white", border: "8px solid white" }}>
+ {target.title}
+ <div className="wrapper" style={{ float: "right" }}>
+ <div title="Delete link" className="FormattedTextBoxComment-button" style={{
+ display: "inline",
+ paddingLeft: "6px",
+ paddingRight: "6px",
+ paddingTop: "2.5px",
+ paddingBottom: "2.5px",
+ width: "20px",
+ height: "20px",
+ margin: 0,
+ marginRight: "6px",
+ borderRadius: "50%",
+ pointerEvents: "auto",
+ backgroundColor: "rgb(38, 40, 41)",
+ color: "rgb(178, 181, 184)",
+ transition: "transform 0.2s",
+ textAlign: "center",
+ position: "relative"
+ }} ref={(r) => this._deleteRef = r}>
+ <FontAwesomeIcon className="FormattedTextBox-fa-icon" icon="trash"
+ size="sm" /></div>
+ <div title="Follow link" className="FormattedTextBoxComment-button" style={{
+ display: "inline",
+ paddingLeft: "6px",
+ paddingRight: "6px",
+ paddingTop: "2.5px",
+ paddingBottom: "2.5px",
+ width: "20px",
+ height: "20px",
+ margin: 0,
+ marginRight: "6px",
+ borderRadius: "50%",
+ pointerEvents: "auto",
+ backgroundColor: "rgb(38, 40, 41)",
+ color: "rgb(178, 181, 184)",
+ transition: "transform 0.2s",
+ textAlign: "center",
+ position: "relative"
+ }} ref={(r) => this._followRef = r}>
+ <FontAwesomeIcon className="FormattedTextBox-fa-icon" icon="arrow-right"
+ size="sm" />
+ </div>
+ </div>
+ <div className="wrapper" style={{
+ maxWidth: "180px", maxHeight: "168px", overflow: "hidden",
+ overflowY: "hidden", paddingTop: "5px"
+ }}>
+ <ContentFittingDocumentView
+ Document={target}
+ LibraryPath={emptyPath}
+ fitToBox={true}
+ moveDocument={returnFalse}
+ rootSelected={returnFalse}
+ ScreenToLocalTransform={Transform.Identity}
+ parentActive={returnFalse}
+ addDocument={returnFalse}
+ removeDocument={returnFalse}
+ addDocTab={returnFalse}
+ pinToPres={returnFalse}
+ dontRegisterView={true}
+ docFilters={returnEmptyFilter}
+ ContainingCollectionDoc={undefined}
+ ContainingCollectionView={undefined}
+ renderDepth={0}
+ PanelWidth={() => Math.min(350, NumCast(target._width, 350))}
+ PanelHeight={() => Math.min(250, NumCast(target._height, 250))}
+ focus={emptyFunction}
+ whenActiveChanged={returnFalse}
+ bringToFront={returnFalse}
+ ContentScaling={returnOne}
+ NativeWidth={returnZero}
+ NativeHeight={returnZero}
+ />
+ </div>
+ </div>;
+ FormattedTextBoxComment.showCommentbox("", view, nbef);
+
+ ReactDOM.render(docPreview, FormattedTextBoxComment.tooltipText);
+
FormattedTextBoxComment.tooltip.style.width = NumCast(target._width) ? `${NumCast(target._width)}` : "100%";
FormattedTextBoxComment.tooltip.style.height = NumCast(target._height) ? `${NumCast(target._height)}` : "100%";
}
@@ -249,4 +335,4 @@ export class FormattedTextBoxComment {
}
destroy() { }
-}
+} \ No newline at end of file
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 4a35ef018..7aa1d528d 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -832,12 +832,14 @@ export namespace Doc {
})(doc);
}
export function BrushDoc(doc: Doc) {
+
if (!doc || doc[AclSym] === AclPrivate || Doc.GetProto(doc)[AclSym] === AclPrivate) return doc;
brushManager.BrushedDoc.set(doc, true);
brushManager.BrushedDoc.set(Doc.GetProto(doc), true);
return doc;
}
export function UnBrushDoc(doc: Doc) {
+
if (!doc || doc[AclSym] === AclPrivate || Doc.GetProto(doc)[AclSym] === AclPrivate) return doc;
brushManager.BrushedDoc.delete(doc);
brushManager.BrushedDoc.delete(Doc.GetProto(doc));