aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2021-08-30 10:23:13 -0400
committerbobzel <zzzman@gmail.com>2021-08-30 10:23:13 -0400
commit962a1a3f1ae9a55c5aea630d3252cecb740fa15c (patch)
tree9f5f234786af112a475ea5be962e2e2907fb2dfe /src
parent584926578067f023b52c7754e65bc289f2a745e6 (diff)
parent2d2e027f11253834a337680bbfd1ac549bb2a1f0 (diff)
merged with master - fixed warnings and errors.
Diffstat (limited to 'src')
-rw-r--r--src/Utils.ts2
-rw-r--r--src/client/documents/Documents.ts10
-rw-r--r--src/client/util/CurrentUserUtils.ts2
-rw-r--r--src/client/util/SelectionManager.ts2
-rw-r--r--src/client/views/AudioWaveform.tsx24
-rw-r--r--src/client/views/DocComponent.tsx23
-rw-r--r--src/client/views/GestureOverlay.tsx4
-rw-r--r--src/client/views/MainView.tsx1
-rw-r--r--src/client/views/MarqueeAnnotator.tsx2
-rw-r--r--src/client/views/StyleProvider.tsx2
-rw-r--r--src/client/views/TemplateMenu.tsx1
-rw-r--r--src/client/views/collections/CollectionMenu.tsx3
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx2
-rw-r--r--src/client/views/collections/CollectionStackedTimeline.tsx79
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx2
-rw-r--r--src/client/views/collections/CollectionSubView.tsx3
-rw-r--r--src/client/views/collections/CollectionTreeView.scss8
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx48
-rw-r--r--src/client/views/collections/CollectionView.tsx8
-rw-r--r--src/client/views/collections/TabDocView.tsx3
-rw-r--r--src/client/views/collections/TreeView.tsx11
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx8
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx10
-rw-r--r--src/client/views/collections/collectionSchema/SchemaTable.tsx4
-rw-r--r--src/client/views/linking/LinkEditor.tsx6
-rw-r--r--src/client/views/linking/LinkRelationshipSearch.tsx12
-rw-r--r--src/client/views/nodes/AudioBox.tsx199
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx6
-rw-r--r--src/client/views/nodes/ComparisonBox.tsx17
-rw-r--r--src/client/views/nodes/DocumentView.tsx17
-rw-r--r--src/client/views/nodes/FilterBox.tsx1
-rw-r--r--src/client/views/nodes/ImageBox.tsx5
-rw-r--r--src/client/views/nodes/LabelBox.tsx2
-rw-r--r--src/client/views/nodes/LinkBox.tsx1
-rw-r--r--src/client/views/nodes/PDFBox.tsx12
-rw-r--r--src/client/views/nodes/VideoBox.tsx27
-rw-r--r--src/client/views/nodes/WebBox.tsx26
-rw-r--r--src/client/views/nodes/button/FontIconBox.tsx6
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx10
-rw-r--r--src/client/views/pdf/AnchorMenu.tsx6
-rw-r--r--src/client/views/pdf/PDFViewer.tsx13
-rw-r--r--src/client/views/search/SearchBox.tsx56
-rw-r--r--src/fields/Doc.ts3
43 files changed, 373 insertions, 314 deletions
diff --git a/src/Utils.ts b/src/Utils.ts
index b7e6b83a0..8054245f5 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -118,7 +118,7 @@ export namespace Utils {
}
const isTransparentFunctionHack = "isTransparent(__value__)";
- const noRecursionHack = "__noRecursion";
+ export const noRecursionHack = "__noRecursion";
export function IsRecursiveFilter(val: string) {
return !val.includes(noRecursionHack);
}
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 007262f9c..ec856e748 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -729,10 +729,20 @@ export namespace Docs {
}
export function PdfDocument(url: string, options: DocumentOptions = {}) {
+ const width = options._width || undefined;
+ const height = options._height || undefined;
+ const nwid = options._nativeWidth || undefined;
+ const nhght = options._nativeHeight || undefined;
+ if (!nhght && width && height && nwid) options._nativeHeight = Number(nwid) * Number(height) / Number(width);
return InstanceFromProto(Prototypes.get(DocumentType.PDF), new PdfField(url), options);
}
export function WebDocument(url: string, options: DocumentOptions = {}) {
+ const width = options._width || undefined;
+ const height = options._height || undefined;
+ const nwid = options._nativeWidth || undefined;
+ const nhght = options._nativeHeight || undefined;
+ if (!nhght && width && height && nwid) options._nativeHeight = Number(nwid) * Number(height) / Number(width);
return InstanceFromProto(Prototypes.get(DocumentType.WEB), url ? new WebField(url) : undefined, options);
}
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 66799d62f..bba7616e8 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -420,7 +420,7 @@ export class CurrentUserUtils {
((doc.emptyPane as Doc).proto as Doc)["dragFactory-count"] = 0;
}
if (doc.emptySlide === undefined) {
- const textDoc = Docs.Create.TreeDocument([], { title: "Slide", _viewType: CollectionViewType.Tree, _fontSize: "20px", treeViewType: "outline", _xMargin: 0, _yMargin: 0, _width: 300, _height: 200, _singleLine: true, backgroundColor: "transparent", system: true, cloneFieldFilter: new List<string>(["system"]) });
+ const textDoc = Docs.Create.TreeDocument([], { title: "Slide", _viewType: CollectionViewType.Tree, _fontSize: "20px", _autoHeight: true, treeViewType: "outline", _xMargin: 0, _yMargin: 0, _width: 300, _height: 200, _singleLine: true, backgroundColor: "transparent", system: true, cloneFieldFilter: new List<string>(["system"]) });
Doc.GetProto(textDoc).title = ComputedField.MakeFunction('self.text?.Text');
FormattedTextBox.SelectOnLoad = textDoc[Id];
doc.emptySlide = textDoc;
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index dbcc49f3d..0cfaebbf2 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -1,10 +1,10 @@
import { action, observable, ObservableMap } from "mobx";
import { computedFn } from "mobx-utils";
import { Doc, Opt } from "../../fields/Doc";
+import { DocumentType } from "../documents/DocumentTypes";
import { CollectionSchemaView } from "../views/collections/collectionSchema/CollectionSchemaView";
import { CollectionViewType } from "../views/collections/CollectionView";
import { DocumentView } from "../views/nodes/DocumentView";
-import { DocumentType } from "../documents/DocumentTypes";
export namespace SelectionManager {
diff --git a/src/client/views/AudioWaveform.tsx b/src/client/views/AudioWaveform.tsx
index f519f9ef0..8f3b7c2cd 100644
--- a/src/client/views/AudioWaveform.tsx
+++ b/src/client/views/AudioWaveform.tsx
@@ -67,7 +67,7 @@ export class AudioWaveform extends React.Component<AudioWaveformProps> {
);
}
);
- };
+ }
@action
createTrimBuckets = () => {
@@ -84,7 +84,7 @@ export class AudioWaveform extends React.Component<AudioWaveformProps> {
(NumCast(this.props.layoutDoc.clipEnd) / this.props.duration) * 100
);
return audioBuckets.slice(start, end);
- };
+ }
render() {
const audioBuckets = Cast(
@@ -110,16 +110,16 @@ export class AudioWaveform extends React.Component<AudioWaveformProps> {
progressColor={Colors.MEDIUM_BLUE}
/>
) : (
- <Waveform
- color={Colors.MEDIUM_BLUE}
- height={this._waveHeight}
- barWidth={0.1}
- pos={this.props.duration}
- duration={this.props.duration}
- peaks={this.createTrimBuckets()}
- progressColor={Colors.MEDIUM_BLUE}
- />
- )}
+ <Waveform
+ color={Colors.MEDIUM_BLUE}
+ height={this._waveHeight}
+ barWidth={0.1}
+ pos={this.props.duration}
+ duration={this.props.duration}
+ peaks={this.createTrimBuckets()}
+ progressColor={Colors.MEDIUM_BLUE}
+ />
+ )}
</div>
);
}
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index d9cc29bed..33dff9da5 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -1,17 +1,17 @@
-import { Doc, Opt, DataSym, AclReadonly, AclAugment, AclPrivate, AclEdit, AclSym, DocListCast, AclAdmin, AclSelfEdit } from '../../fields/Doc';
-import { Touchable } from './Touchable';
-import { computed, action, observable } from 'mobx';
-import { Cast, BoolCast, ScriptCast } from '../../fields/Types';
+import { action, computed, observable } from 'mobx';
+import { DateField } from '../../fields/DateField';
+import { AclAdmin, AclAugment, AclEdit, AclPrivate, AclReadonly, AclSym, DataSym, Doc, DocListCast, Opt } from '../../fields/Doc';
import { InkTool } from '../../fields/InkField';
-import { InteractionUtils } from '../util/InteractionUtils';
import { List } from '../../fields/List';
-import { DateField } from '../../fields/DateField';
import { ScriptField } from '../../fields/ScriptField';
-import { GetEffectiveAcl, SharingPermissions, distributeAcls, denormalizeEmail, inheritParentAcls } from '../../fields/util';
-import { CurrentUserUtils } from '../util/CurrentUserUtils';
-import { DocUtils } from '../documents/Documents';
+import { Cast, ScriptCast } from '../../fields/Types';
+import { denormalizeEmail, distributeAcls, GetEffectiveAcl, inheritParentAcls, SharingPermissions } from '../../fields/util';
import { returnFalse } from '../../Utils';
+import { DocUtils } from '../documents/Documents';
+import { CurrentUserUtils } from '../util/CurrentUserUtils';
+import { InteractionUtils } from '../util/InteractionUtils';
import { UndoManager } from '../util/UndoManager';
+import { Touchable } from './Touchable';
/// DocComponent returns a generic React base class used by views that don't have 'fieldKey' props (e.g.,CollectionFreeFormDocumentView, DocumentView)
@@ -107,6 +107,7 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps, T
// key where data is stored
@computed get fieldKey() { return this.props.fieldKey; }
+ isAnyChildContentActive = () => this._isAnyChildContentActive;
lookupField = (field: string) => ScriptCast((this.layoutDoc as any).lookupField)?.script.run({ self: this.layoutDoc, data: this.rootDoc, field: field }).result;
@@ -229,10 +230,6 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps, T
}
whenChildContentsActiveChanged = action((isActive: boolean) => this.props.whenChildContentsActiveChanged(this._isAnyChildContentActive = isActive));
- isContentActive = (outsideReaction?: boolean) => (CurrentUserUtils.SelectedTool !== InkTool.None ||
- (this.props.isContentActive?.() || this.props.Document.forceActive ||
- this.props.isSelected(outsideReaction) || this._isAnyChildContentActive ||
- this.props.rootSelected(outsideReaction)) ? true : false)
}
return Component;
} \ No newline at end of file
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 24f9501ce..b401a7f03 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -31,7 +31,7 @@ export class GestureOverlay extends Touchable {
@observable public InkShape: string = "";
@observable public SavedColor?: string;
- @observable public SavedWidth?: string;
+ @observable public SavedWidth?: number;
@observable public Tool: ToolglassTools = ToolglassTools.None;
@observable private _thumbX?: number;
@@ -953,7 +953,7 @@ Scripting.addGlobal(function setPen(width: any, color: any, fill: any, arrowStar
Scripting.addGlobal(function resetPen() {
runInAction(() => {
SetActiveInkColor(GestureOverlay.Instance.SavedColor ?? "rgb(0, 0, 0)");
- SetActiveInkWidth(GestureOverlay.Instance.SavedWidth ?? "2");
+ SetActiveInkWidth(GestureOverlay.Instance.SavedWidth?.toString() ?? "2");
});
}, "resets the pen tool");
Scripting.addGlobal(function createText(text: any, x: any, y: any) {
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index c95e56584..f082ba2c0 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -475,6 +475,7 @@ export class MainView extends React.Component {
bringToFront={emptyFunction}
select={emptyFunction}
isContentActive={returnFalse}
+ isAnyChildContentActive={returnFalse}
isSelected={returnFalse}
docViewPath={returnEmptyDoclist}
moveDocument={this.moveButtonDoc}
diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx
index 1897572f8..eee365ed8 100644
--- a/src/client/views/MarqueeAnnotator.tsx
+++ b/src/client/views/MarqueeAnnotator.tsx
@@ -77,7 +77,7 @@ export class MarqueeAnnotator extends React.Component<MarqueeAnnotatorProps> {
e.stopPropagation();
const sourceAnchorCreator = () => {
const annoDoc = this.highlight("rgba(173, 216, 230, 0.75)", true); // hyperlink color
- this.props.addDocument(annoDoc);
+ annoDoc && this.props.addDocument(annoDoc);
return annoDoc;
};
const targetCreator = (annotationOn: Doc | undefined) => {
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 470ae7c77..fa35081bc 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -102,7 +102,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
if (docColor) return docColor;
const backColor = backgroundCol();
if (!backColor) return undefined;
- return lightOrDark(backColor)
+ return lightOrDark(backColor);
case StyleProp.Hidden: return BoolCast(doc?._hidden);
case StyleProp.BorderRounding: return StrCast(doc?.[fieldKey + "borderRounding"], doc?._viewType === CollectionViewType.Pile ? "50%" : "");
case StyleProp.TitleHeight: return 15;
diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx
index 5491a81e6..ff3f92364 100644
--- a/src/client/views/TemplateMenu.tsx
+++ b/src/client/views/TemplateMenu.tsx
@@ -141,6 +141,7 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
onCheckedClick={this.scriptField}
onChildClick={this.scriptField}
dropAction={undefined}
+ isAnyChildContentActive={returnFalse}
isContentActive={returnTrue}
bringToFront={emptyFunction}
focus={emptyFunction}
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 77e5132fc..cbfe47338 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -108,6 +108,7 @@ export class CollectionMenu extends AntimodeMenu<AntimodeMenuProps> {
bringToFront={emptyFunction}
select={emptyFunction}
isContentActive={returnFalse}
+ isAnyChildContentActive={returnFalse}
isSelected={returnFalse}
docViewPath={returnEmptyDoclist}
moveDocument={returnFalse}
@@ -120,7 +121,7 @@ export class CollectionMenu extends AntimodeMenu<AntimodeMenuProps> {
PanelWidth={() => 100}
PanelHeight={() => 35}
renderDepth={0}
- focus={() => undefined}
+ focus={emptyFunction}
whenChildContentsActiveChanged={emptyFunction}
docFilters={returnEmptyFilter}
docRangeFilters={returnEmptyFilter}
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 1efea96be..6bdeaf722 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -18,6 +18,7 @@ import { SnappingManager } from "../../util/SnappingManager";
import { Transform } from "../../util/Transform";
import { undoBatch } from "../../util/UndoManager";
import { COLLECTION_BORDER_WIDTH, SCHEMA_DIVIDER_WIDTH } from '../../views/global/globalCssVariables.scss';
+import { SchemaTable } from "../collections/collectionSchema/SchemaTable";
import { ContextMenu } from "../ContextMenu";
import { ContextMenuProps } from "../ContextMenuItem";
import '../DocumentDecorations.scss';
@@ -25,7 +26,6 @@ import { DocumentView } from "../nodes/DocumentView";
import { DefaultStyleProvider } from "../StyleProvider";
import "./CollectionSchemaView.scss";
import { CollectionSubView } from "./CollectionSubView";
-import { SchemaTable } from "../collections/collectionSchema/SchemaTable";
// bcz: need to add drag and drop of rows and columns. This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657
export enum ColumnType {
diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx
index 51e05e278..d98d966d8 100644
--- a/src/client/views/collections/CollectionStackedTimeline.tsx
+++ b/src/client/views/collections/CollectionStackedTimeline.tsx
@@ -141,25 +141,26 @@ export class CollectionStackedTimeline extends CollectionSubView<
}
componentWillUnmount() {
document.removeEventListener("keydown", this.keyEvents, true);
- if (CollectionStackedTimeline.SelectingRegion === this)
+ if (CollectionStackedTimeline.SelectingRegion === this) {
runInAction(
() => (CollectionStackedTimeline.SelectingRegion = undefined)
);
+ }
}
anchorStart = (anchor: Doc) =>
- NumCast(anchor._timecodeToShow, NumCast(anchor[this.props.startTag]));
+ NumCast(anchor._timecodeToShow, NumCast(anchor[this.props.startTag]))
anchorEnd = (anchor: Doc, val: any = null) => {
const endVal = NumCast(anchor[this.props.endTag], val);
return NumCast(
anchor._timecodeToHide,
endVal === undefined ? null : endVal
);
- };
+ }
toTimeline = (screen_delta: number, width: number) => {
return Math.max(
this.trimStart,
- Math.min(this.trimEnd, (screen_delta / width) * this.props.trimDuration + this.trimStart))
+ Math.min(this.trimEnd, (screen_delta / width) * this.props.trimDuration + this.trimStart));
}
rangeClickScript = () => CollectionStackedTimeline.RangeScript;
@@ -190,7 +191,7 @@ export class CollectionStackedTimeline extends CollectionSubView<
}
}
}
- };
+ }
getLinkData(l: Doc) {
let la1 = l.anchor1 as Doc;
@@ -279,12 +280,12 @@ export class CollectionStackedTimeline extends CollectionSubView<
this.props.setTime(((clientX - rect.x) / rect.width) * this.duration)
:
this.props.setTime(((clientX - rect.x) / rect.width) * this.props.trimDuration + this.trimStart)
- )
+ );
}
);
}
- };
+ }
@action
trimLeft = (e: React.PointerEvent): void => {
@@ -312,7 +313,7 @@ export class CollectionStackedTimeline extends CollectionSubView<
}
})
);
- };
+ }
@action
trimRight = (e: React.PointerEvent): void => {
@@ -340,7 +341,7 @@ export class CollectionStackedTimeline extends CollectionSubView<
}
})
);
- };
+ }
@undoBatch
@action
@@ -395,12 +396,13 @@ export class CollectionStackedTimeline extends CollectionSubView<
}
}
return { select: true };
- };
+ }
@action
clickAnchor = (anchorDoc: Doc, clientX: number) => {
- if (anchorDoc.isLinkButton)
+ if (anchorDoc.isLinkButton) {
LinkManager.FollowLink(undefined, anchorDoc, this.props, false);
+ }
const seekTimeInSeconds = this.anchorStart(anchorDoc) - 0.25;
const endTime = this.anchorEnd(anchorDoc);
if (
@@ -415,14 +417,15 @@ export class CollectionStackedTimeline extends CollectionSubView<
this.props.setTime(this.toTimeline(clientX - rect.x, rect.width));
}
} else {
- if (this.layoutDoc.autoPlayAnchors)
+ if (this.layoutDoc.autoPlayAnchors) {
this.props.playFrom(seekTimeInSeconds, endTime);
+ }
else {
this.props.setTime(seekTimeInSeconds);
}
}
return { select: true };
- };
+ }
// makes sure no anchors overlaps each other by setting the correct position and width
getLevel = (
@@ -456,17 +459,17 @@ export class CollectionStackedTimeline extends CollectionSubView<
placed.push({ anchorStartTime: x1, anchorEndTime: x2, level });
return level;
- };
+ }
dictationHeightPercent = 50;
dictationHeight = () =>
- (this.props.PanelHeight() * (100 - this.dictationHeightPercent)) / 100;
+ (this.props.PanelHeight() * (100 - this.dictationHeightPercent)) / 100
timelineContentHeight = () =>
- (this.props.PanelHeight() * this.dictationHeightPercent) / 100;
+ (this.props.PanelHeight() * this.dictationHeightPercent) / 100
dictationScreenToLocalTransform = () =>
this.props
.ScreenToLocalTransform()
- .translate(0, -this.timelineContentHeight());
+ .translate(0, -this.timelineContentHeight())
@computed get renderDictation() {
const dictation = Cast(this.dataDoc[this.props.dictationKey], Doc, null);
return !dictation ? null : (
@@ -552,7 +555,7 @@ export class CollectionStackedTimeline extends CollectionSubView<
const top = (d.level / maxLevel) * this.timelineContentHeight();
const timespan = end - start;
const width = (timespan / this.props.trimDuration) * timelineContentWidth;
- const height = this.timelineContentHeight() / maxLevel
+ const height = this.timelineContentHeight() / maxLevel;
return this.props.Document.hideAnchors ? null : (
<div
className={"collectionStackedTimeline-marker-timeline"}
@@ -723,17 +726,19 @@ class StackedTimelineAnchor extends React.Component<StackedTimelineAnchorProps>
const changeAnchor = (anchor: Doc, left: boolean, time: number) => {
const timelineOnly =
Cast(anchor[this.props.startTag], "number", null) !== undefined;
- if (timelineOnly)
+ if (timelineOnly) {
Doc.SetInPlace(
anchor,
left ? this.props.startTag : this.props.endTag,
time,
true
);
- else
+ }
+ else {
left
? (anchor._timecodeToShow = time)
: (anchor._timecodeToHide = time);
+ }
return false;
};
setupMoveUpEvents(
@@ -746,13 +751,13 @@ class StackedTimelineAnchor extends React.Component<StackedTimelineAnchorProps>
},
emptyFunction
);
- };
+ }
@action
computeTitle = () => {
const start = Math.max(NumCast(this.props.mark[this.props.startTag]), this.props.trimStart) - this.props.trimStart;
const end = Math.min(NumCast(this.props.mark[this.props.endTag]), this.props.trimEnd) - this.props.trimStart;
- return `#${formatTime(start)}-${formatTime(end)}`
+ return `#${formatTime(start)}-${formatTime(end)}`;
}
renderInner = computedFn(function (
@@ -824,21 +829,21 @@ class StackedTimelineAnchor extends React.Component<StackedTimelineAnchorProps>
{inner.view}
{!inner.anchor.view ||
!SelectionManager.IsSelected(inner.anchor.view) ? null : (
- <>
- <div
- key="left"
- className="collectionStackedTimeline-left-resizer"
- onPointerDown={(e) => this.onAnchorDown(e, this.props.mark, true)}
- />
- <div
- key="right"
- className="collectionStackedTimeline-resizer"
- onPointerDown={(e) =>
- this.onAnchorDown(e, this.props.mark, false)
- }
- />
- </>
- )}
+ <>
+ <div
+ key="left"
+ className="collectionStackedTimeline-left-resizer"
+ onPointerDown={(e) => this.onAnchorDown(e, this.props.mark, true)}
+ />
+ <div
+ key="right"
+ className="collectionStackedTimeline-resizer"
+ onPointerDown={(e) =>
+ this.onAnchorDown(e, this.props.mark, false)
+ }
+ />
+ </>
+ )}
</>
);
}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index b9bc83d49..4fedda1bd 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -144,7 +144,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
() => this.layoutDoc._columnHeaders = new List()
);
this._autoHeightDisposer = reaction(() => this.layoutDoc._autoHeight,
- () => this.props.setHeight(Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER),
+ autoHeight => autoHeight && this.props.setHeight(Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER),
this.headerMargin + (this.isStackingView ?
Math.max(...this.refList.map(r => Number(getComputedStyle(r).height.replace("px", "")))) :
this.refList.reduce((p, r) => p + Number(getComputedStyle(r).height.replace("px", "")), 0)))));
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 1f4c35daa..b70df93da 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -23,6 +23,7 @@ import ReactLoading from 'react-loading';
export interface SubCollectionViewProps extends CollectionViewProps {
CollectionView: Opt<CollectionView>;
SetSubView?: (subView: any) => void;
+ isAnyChildContentActive: () => boolean;
}
export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?: X) {
@@ -490,7 +491,5 @@ import { FormattedTextBox, GoogleRef } from "../nodes/formattedText/FormattedTex
import { CollectionView, CollectionViewType, CollectionViewProps } from "./CollectionView";
import { SelectionManager } from "../../util/SelectionManager";
import { OverlayView } from "../OverlayView";
-import { Hypothesis } from "../../util/HypothesisUtils";
import { GetEffectiveAcl, TraceMobx } from "../../../fields/util";
-import { FilterBox } from "../nodes/FilterBox";
diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss
index ec461ab94..d370d21ab 100644
--- a/src/client/views/collections/CollectionTreeView.scss
+++ b/src/client/views/collections/CollectionTreeView.scss
@@ -1,5 +1,8 @@
@import "../global/globalCssVariables";
+.collectionTreeView-container {
+ transform-origin: top left;
+}
.collectionTreeView-dropTarget {
border-width: $COLLECTION_BORDER_WIDTH;
border-color: transparent;
@@ -35,6 +38,11 @@
width: max-content;
}
+ .no-indent-outline {
+ padding-left: 0;
+ width: 100%;
+ }
+
.editableView-container {
font-weight: bold;
}
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index a78034dca..89d42439e 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -1,15 +1,16 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, reaction, IReactionDisposer, observable } from "mobx";
+import { action, computed, IReactionDisposer, observable, reaction } from "mobx";
import { observer } from "mobx-react";
-import { DataSym, Doc, DocListCast, HeightSym, Opt, WidthSym, StrListCast } from '../../../fields/Doc';
+import { DataSym, Doc, DocListCast, HeightSym, Opt, StrListCast, WidthSym } from '../../../fields/Doc';
import { Id } from '../../../fields/FieldSymbols';
-import { List } from '../../../fields/List';
+import { InkTool } from '../../../fields/InkField';
import { Document, listSpec } from '../../../fields/Schema';
import { ScriptField } from '../../../fields/ScriptField';
import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../../../Utils';
import { DocUtils } from '../../documents/Documents';
+import { CurrentUserUtils } from '../../util/CurrentUserUtils';
import { DocumentManager } from '../../util/DocumentManager';
import { DragManager, dropActionType } from "../../util/DragManager";
import { SelectionManager } from '../../util/SelectionManager';
@@ -25,9 +26,6 @@ import { CollectionSubView } from "./CollectionSubView";
import "./CollectionTreeView.scss";
import { TreeView } from "./TreeView";
import React = require("react");
-import { InkTool } from '../../../fields/InkField';
-import { CurrentUserUtils } from '../../util/CurrentUserUtils';
-import { CollectionView, CollectionViewType } from './CollectionView';
const _global = (window /* browser */ || global /* node */) as any;
export type collectionTreeViewProps = {
@@ -63,7 +61,9 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
this.props.isSelected(outsideReaction) || this._isAnyChildContentActive ||
this.props.rootSelected(outsideReaction)) ? true : false)
+ isDisposing = false;
componentWillUnmount() {
+ this.isDisposing = true;
super.componentWillUnmount();
this.treedropDisposer?.();
Object.values(this._disposers).forEach(disposer => disposer?.());
@@ -78,15 +78,16 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
refList: Set<any> = new Set();
observer: any;
computeHeight = () => {
- const hgt = this.paddingTop() + 26/* bcz: ugh: title bar height hack ... get ref and compute instead */ +
- Array.from(this.refList).reduce((p, r) => p + Number(getComputedStyle(r).height.replace("px", "")), 0);
- this.props.setHeight(hgt);
+ if (this.isDisposing) return;
+ const bodyHeight = Array.from(this.refList).reduce((p, r) => p + Number(getComputedStyle(r).height.replace("px", "")), this.paddingTop() + this.paddingBot());
+ this.layoutDoc._autoHeightMargins = bodyHeight;
+ this.props.setHeight(this.documentTitleHeight() + bodyHeight);
}
unobserveHeight = (ref: any) => {
this.refList.delete(ref);
this.rootDoc.autoHeight && this.computeHeight();
}
- observerHeight = (ref: any) => {
+ observeHeight = (ref: any) => {
if (ref) {
this.refList.add(ref);
this.observer = new _global.ResizeObserver(action((entries: any) => {
@@ -201,6 +202,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
NativeWidth={this.documentTitleWidth}
NativeHeight={this.documentTitleHeight}
focus={this.props.focus}
+ treeViewDoc={this.props.Document}
ScreenToLocalTransform={this.titleTransform}
docFilters={returnEmptyFilter}
docRangeFilters={returnEmptyFilter}
@@ -253,14 +255,14 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
true,
this.whenChildContentsActiveChanged,
this.props.dontRegisterView || Cast(this.props.Document.childDontRegisterViews, "boolean", null),
- this.observerHeight,
+ this.observeHeight,
this.unobserveHeight,
this.childContextMenuItems()
);
}
@computed get titleBar() {
const hideTitle = this.props.treeViewHideTitle || this.doc.treeViewHideTitle;
- return hideTitle ? (null) : (this.doc.treeViewType === "outline" ? this.documentTitle : this.editableTitle)(this.treeChildren);
+ return hideTitle ? (null) : (this.outlineMode ? this.documentTitle : this.editableTitle)(this.treeChildren);
}
@computed get renderClearButton() {
@@ -270,30 +272,42 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
</button>
</div >;
}
+ @computed get nativeWidth() { return Doc.NativeWidth(this.Document, undefined, true); }
+ @computed get nativeHeight() { return Doc.NativeHeight(this.Document, undefined, true); }
+ @computed get contentScaling() {
+ const nw = this.nativeWidth;
+ const nh = this.nativeHeight;
+ const hscale = nh ? this.props.PanelHeight() / nh : 1;
+ const wscale = nw ? this.props.PanelWidth() / nw : 1;
+ return wscale < hscale ? wscale : hscale;
+ }
paddingX = () => NumCast(this.doc._xPadding, 15);
paddingTop = () => NumCast(this.doc._yPadding, 20);
+ paddingBot = () => NumCast(this.doc._yPadding, 20);
documentTitleWidth = () => Math.min(this.layoutDoc?.[WidthSym](), this.panelWidth());
- documentTitleHeight = () => Math.min(this.layoutDoc?.[HeightSym](), (StrCast(this.layoutDoc?._fontSize) ? Number(StrCast(this.layoutDoc?._fontSize, "32px").replace("px", "")) : NumCast(this.layoutDoc?._fontSize)) * 2);
+ documentTitleHeight = () => (this.layoutDoc?.[HeightSym]() || 0) - NumCast(this.layoutDoc.autoHeightMargins);
titleTransform = () => this.props.ScreenToLocalTransform().translate(-NumCast(this.doc._xPadding, 10), -NumCast(this.doc._yPadding, 20));
truncateTitleWidth = () => this.treeViewtruncateTitleWidth;
onChildClick = () => this.props.onChildClick?.() || ScriptCast(this.doc.onChildClick);
- panelWidth = () => this.props.PanelWidth() - 2 * this.paddingX();
+ panelWidth = () => (this.props.PanelWidth() - 2 * this.paddingX()) * (this.props.scaling?.() || 1);
render() {
TraceMobx();
const background = () => this.props.styleProvider?.(this.doc, this.props, StyleProp.BackgroundColor);
const pointerEvents = () => !this.props.isContentActive() && !SnappingManager.GetIsDragging() ? "none" : undefined;
return !(this.doc instanceof Doc) || !this.treeChildren ? (null) :
- <div className="collectionTreeView-container" onContextMenu={this.onContextMenu}>
+ <div className="collectionTreeView-container"
+ style={this.outlineMode ? { transform: `scale(${this.contentScaling})`, width: `calc(${100 / this.contentScaling}%)` } : {}}
+ onContextMenu={this.onContextMenu}>
<div className="collectionTreeView-dropTarget"
- style={{ background: background(), paddingLeft: `${this.paddingX()}px`, paddingRight: `${this.paddingX()}px`, paddingTop: `${this.paddingTop()}px`, pointerEvents: pointerEvents() }}
+ style={{ background: background(), paddingLeft: `${this.paddingX()}px`, paddingRight: `${this.paddingX()}px`, paddingBottom: `${this.paddingBot()}px`, paddingTop: `${this.paddingTop()}px`, pointerEvents: pointerEvents() }}
onWheel={e => e.stopPropagation()}
onDrop={this.onTreeDrop}
ref={this.createTreeDropTarget}>
{this.titleBar}
{this.renderClearButton}
- <ul className="no-indent">
+ <ul className={`no-indent${this.outlineMode ? "-outline" : ""}`} >
{this.treeViewElements}
</ul>
</div >
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index a821aeeea..229e93b9e 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -37,6 +37,7 @@ import { CollectionTreeView } from "./CollectionTreeView";
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import './CollectionView.scss';
import { returnEmptyString } from '../../../Utils';
+import { InkTool } from '../../../fields/InkField';
export const COLLECTION_BORDER_WIDTH = 2;
const path = require('path');
@@ -119,7 +120,7 @@ export class CollectionView extends ViewBoxAnnotatableComponent<ViewBoxAnnotatab
// const imageProtos = children.filter(doc => Cast(doc.data, ImageField)).map(Doc.GetProto);
// const allTagged = imageProtos.length > 0 && imageProtos.every(image => image.googlePhotosTags);
// return !allTagged ? (null) : <img id={"google-tags"} src={"/assets/google_tags.png"} />;
- this.isContentActive();
+ //this.isContentActive();
}
screenToLocalTransform = () => this.props.renderDepth ? this.props.ScreenToLocalTransform() : this.props.ScreenToLocalTransform().scale(this.props.PanelWidth() / this.bodyPanelWidth());
@@ -253,6 +254,9 @@ export class CollectionView extends ViewBoxAnnotatableComponent<ViewBoxAnnotatab
@observable _subView: any = undefined;
+ isContentActive = (outsideReaction?: boolean) => {
+ return this.props.isContentActive() ? true : false;
+ }
render() {
TraceMobx();
const props: SubCollectionViewProps = {
@@ -262,6 +266,8 @@ export class CollectionView extends ViewBoxAnnotatableComponent<ViewBoxAnnotatab
moveDocument: this.moveDocument,
removeDocument: this.removeDocument,
isContentActive: this.isContentActive,
+ isAnyChildContentActive: this.isAnyChildContentActive,
+ whenChildContentsActiveChanged: this.whenChildContentsActiveChanged,
PanelWidth: this.bodyPanelWidth,
PanelHeight: this.props.PanelHeight,
ScreenToLocalTransform: this.screenToLocalTransform,
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index f80a2d8b5..28b074d35 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -490,7 +490,8 @@ export class TabMinimapView extends React.Component<TabMinimapViewProps> {
childLayoutTemplate={this.childLayoutTemplate} // bcz: Ugh .. should probably be rendering a CollectionView or the minimap should be part of the collectionFreeFormView to avoid having to set stuff like this.
noOverlay={true} // don't render overlay Docs since they won't scale
setHeight={returnFalse}
- isContentActive={returnTrue}
+ isContentActive={returnFalse}
+ isAnyChildContentActive={returnFalse}
select={emptyFunction}
dropAction={undefined}
isSelected={returnFalse}
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 3ee9dbf59..86fd21677 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -9,7 +9,7 @@ import { listSpec } from '../../../fields/Schema';
import { ComputedField, ScriptField } from '../../../fields/ScriptField';
import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
-import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, simulateMouseClick, Utils } from '../../../Utils';
+import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, simulateMouseClick, Utils, returnOne } from '../../../Utils';
import { Docs, DocUtils } from '../../documents/Documents';
import { DocumentType } from "../../documents/DocumentTypes";
import { CurrentUserUtils } from '../../util/CurrentUserUtils';
@@ -296,7 +296,7 @@ export class TreeView extends React.Component<TreeViewProps> {
const aspect = Doc.NativeAspect(layoutDoc);
if (layoutDoc._fitWidth) return Math.min(this.props.panelWidth() - treeBulletWidth(), layoutDoc[WidthSym]());
if (aspect) return Math.min(layoutDoc[WidthSym](), Math.min(this.MAX_EMBED_HEIGHT * aspect, this.props.panelWidth() - treeBulletWidth()));
- return Math.min(this.props.panelWidth() - treeBulletWidth(), Doc.NativeWidth(layoutDoc) ? layoutDoc[WidthSym]() : this.layoutDoc[WidthSym]());
+ return Math.min((this.props.panelWidth() - treeBulletWidth()) / (this.props.treeView.props.scaling?.() || 1), Doc.NativeWidth(layoutDoc) ? layoutDoc[WidthSym]() : this.layoutDoc[WidthSym]());
}
docHeight = () => {
const layoutDoc = this.layoutDoc;
@@ -365,7 +365,7 @@ export class TreeView extends React.Component<TreeViewProps> {
return rows;
}
- rtfWidth = () => Math.min(this.layoutDoc?.[WidthSym](), this.props.panelWidth() - treeBulletWidth());
+ rtfWidth = () => Math.min(this.layoutDoc?.[WidthSym](), (this.props.panelWidth() - treeBulletWidth())) / (this.props.treeView.props.scaling?.() || 1);
rtfHeight = () => this.rtfWidth() <= this.layoutDoc?.[WidthSym]() ? Math.min(this.layoutDoc?.[HeightSym](), this.MAX_EMBED_HEIGHT) : this.MAX_EMBED_HEIGHT;
rtfOutlineHeight = () => Math.max(this.layoutDoc?.[HeightSym](), treeBulletWidth());
expandPanelHeight = () => {
@@ -544,7 +544,7 @@ export class TreeView extends React.Component<TreeViewProps> {
switch (property.split(":")[0]) {
case StyleProp.Opacity: return this.props.treeView.outlineMode ? undefined : 1;
case StyleProp.BackgroundColor: return this.selected ? "#7089bb" : StrCast(doc._backgroundColor, StrCast(doc.backgroundColor));
- case StyleProp.DocContents: return testDocProps(props) && !props?.treeViewDoc ? (null) :
+ case StyleProp.DocContents: return this.props.treeView.outlineMode ? (null) :
<div className="treeView-label" style={{ // just render a title for a tree view label (identified by treeViewDoc being set in 'props')
maxWidth: props?.PanelWidth() || undefined,
background: props?.styleProvider?.(doc, props, StyleProp.BackgroundColor),
@@ -646,6 +646,7 @@ export class TreeView extends React.Component<TreeViewProps> {
searchFilterDocs={returnEmptyDoclist}
ContainingCollectionView={undefined}
ContainingCollectionDoc={this.props.treeView.props.Document}
+ ContentScaling={returnOne}
/>;
const buttons = this.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.Decorations + (Doc.IsSystem(this.props.containerCollection) ? ":afterHeader" : ""));
@@ -702,10 +703,12 @@ export class TreeView extends React.Component<TreeViewProps> {
hideDecorationTitle={this.props.treeView.outlineMode}
hideResizeHandles={this.props.treeView.outlineMode}
focus={this.refocus}
+ ContentScaling={returnOne}
hideLinkButton={BoolCast(this.props.treeView.props.Document.childHideLinkButton)}
dontRegisterView={BoolCast(this.props.treeView.props.Document.childDontRegisterViews, this.props.dontRegisterView)}
ScreenToLocalTransform={this.docTransform}
renderDepth={this.props.renderDepth + 1}
+ treeViewDoc={this.props.treeView?.props.Document}
rootSelected={returnTrue}
layerProvider={returnTrue}
docViewPath={this.props.treeView.props.docViewPath}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
index 59891b7a1..16258404d 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
@@ -2,15 +2,15 @@ import { action, computed, IReactionDisposer, observable, reaction } from "mobx"
import { observer } from "mobx-react";
import { Doc } from "../../../../fields/Doc";
import { Id } from "../../../../fields/FieldSymbols";
+import { List } from "../../../../fields/List";
import { NumCast, StrCast } from "../../../../fields/Types";
import { emptyFunction, setupMoveUpEvents, Utils } from '../../../../Utils';
import { DocumentType } from "../../../documents/DocumentTypes";
+import { LinkManager } from "../../../util/LinkManager";
import { SnappingManager } from "../../../util/SnappingManager";
import { DocumentView } from "../../nodes/DocumentView";
import "./CollectionFreeFormLinkView.scss";
import React = require("react");
-import { LinkManager } from "../../../util/LinkManager";
-import { List } from "../../../fields/List";
export interface CollectionFreeFormLinkViewProps {
@@ -177,11 +177,11 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
if (!this.renderData) return (null);
const { a, b, pt1norm, pt2norm, aActive, bActive, textX, textY, pt1, pt2 } = this.renderData;
LinkManager.currentLink = this.props.LinkDocs[0];
- const linkRelationship = LinkManager.currentLink?.linkRelationship; //get string representing relationship
+ const linkRelationship = StrCast(LinkManager.currentLink?.linkRelationship); //get string representing relationship
const linkRelationshipList = Doc.UserDoc().linkRelationshipList as List<string>;
const linkColorList = Doc.UserDoc().linkColorList as List<string>;
//access stroke color using index of the relationship in the color list (default black)
- const strokeColor = linkRelationshipList.indexOf(linkRelationship) == -1 ? "black" : linkColorList[linkRelationshipList.indexOf(linkRelationship)];
+ const strokeColor = linkRelationshipList.indexOf(linkRelationship) === -1 ? "black" : linkColorList[linkRelationshipList.indexOf(linkRelationship)];
return !a.width || !b.width || ((!this.props.LinkDocs[0].linkDisplay) && !aActive && !bActive) ? (null) : (<>
<path className="collectionfreeformlinkview-linkLine" style={{ opacity: this._opacity, strokeDasharray: "2 2", stroke: strokeColor }}
d={`M ${pt1[0]} ${pt1[1]} C ${pt1[0] + pt1norm[0]} ${pt1[1] + pt1norm[1]}, ${pt2[0] + pt2norm[0]} ${pt2[1] + pt2norm[1]}, ${pt2[0]} ${pt2[1]}`} />
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 985d162f9..1c54467c5 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1,6 +1,7 @@
import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx";
import { observer } from "mobx-react";
import { computedFn } from "mobx-utils";
+import { DateField } from "../../../../fields/DateField";
import { Doc, HeightSym, Opt, StrListCast, WidthSym } from "../../../../fields/Doc";
import { collectionSchema, documentSchema } from "../../../../fields/documentSchemas";
import { Id } from "../../../../fields/FieldSymbols";
@@ -17,6 +18,7 @@ import { aggregateBounds, emptyFunction, intersectRect, returnFalse, setupMoveUp
import { CognitiveServices } from "../../../cognitive_services/CognitiveServices";
import { DocServer } from "../../../DocServer";
import { Docs, DocUtils } from "../../../documents/Documents";
+import { DocumentType } from "../../../documents/DocumentTypes";
import { CurrentUserUtils } from "../../../util/CurrentUserUtils";
import { DocumentManager } from "../../../util/DocumentManager";
import { DragManager, dropActionType } from "../../../util/DragManager";
@@ -48,8 +50,7 @@ import { CollectionFreeFormRemoteCursors } from "./CollectionFreeFormRemoteCurso
import "./CollectionFreeFormView.scss";
import { MarqueeView } from "./MarqueeView";
import React = require("react");
-import { DocumentType } from "../../../documents/DocumentTypes";
-import { DateField } from "../../../../fields/DateField";
+import Color = require("color");
export const panZoomSchema = createSchema({
_panX: "number",
@@ -117,7 +118,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
@computed get views() { return this._layoutElements.filter(ele => ele.bounds && !ele.bounds.z).map(ele => ele.ele); }
@computed get backgroundEvents() { return this.props.layerProvider?.(this.layoutDoc) === false && SnappingManager.GetIsDragging(); }
- @computed get backgroundActive() { return this.props.layerProvider?.(this.layoutDoc) === false && (this.props.ContainingCollectionView?.isContentActive() || this.props.isContentActive()); }
+ @computed get backgroundActive() { return this.props.layerProvider?.(this.layoutDoc) === false && this.props.isContentActive(); }
@computed get fitToContentVals() {
return {
bounds: { ...this.contentBounds, cx: (this.contentBounds.x + this.contentBounds.r) / 2, cy: (this.contentBounds.y + this.contentBounds.b) / 2 },
@@ -170,6 +171,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
getContainerTransform = () => this.cachedGetContainerTransform.copy();
getTransformOverlay = () => this.getContainerTransform().translate(1, 1);
getActiveDocuments = () => this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map(pair => pair.layout);
+ isAnyChildContentActive = () => this.props.isAnyChildContentActive();
addLiveTextBox = (newBox: Doc) => {
FormattedTextBox.SelectOnLoad = newBox[Id];// track the new text box so we can give it a prop that tells it to focus itself when it's displayed
this.addDocument(newBox);
@@ -1033,7 +1035,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
docFilters={this.childDocFilters}
docRangeFilters={this.childDocRangeFilters}
searchFilterDocs={this.searchFilterDocs}
- isContentActive={this.isAnnotationOverlay ? this.props.isContentActive : returnFalse}
+ isContentActive={returnFalse}
isDocumentActive={this.props.childDocumentsActive ? this.props.isDocumentActive : this.isContentActive}
focus={this.focusDocument}
addDocTab={this.addDocTab}
diff --git a/src/client/views/collections/collectionSchema/SchemaTable.tsx b/src/client/views/collections/collectionSchema/SchemaTable.tsx
index 1cf466cba..3833f968b 100644
--- a/src/client/views/collections/collectionSchema/SchemaTable.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaTable.tsx
@@ -194,7 +194,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
const sortIcon = col.desc === undefined ? "caret-right" : col.desc === true ? "caret-down" : "caret-up";
const header = <div className="collectionSchemaView-menuOptions-wrapper" style={{ background: col.color, padding: "2px", display: "flex", cursor: "default", height: "100%", }}>
{keysDropdown}
- <div onClick={e => this.changeSorting(col)} style={{ width: 21, padding: 1, display: "inline", zIndex: 1, background: "inherit", cursor: "pointer" }}>
+ <div onClick={e => this.changeSorting(col)} style={{ width: 21, padding: 1, display: "inline", zIndex: 1, background: "inherit", cursor: "pointer" }}>
<FontAwesomeIcon icon={sortIcon} size="lg" />
</div>
{/* {this.props.Document._chromeHidden || this.props.addDocument == returnFalse ? undefined : <div className="collectionSchemaView-addRow" onClick={this.createRow}>+ new</div>} */}
@@ -562,7 +562,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
onPointerDown={this.props.onPointerDown} onClick={this.props.onClick} onWheel={e => this.props.active(true) && e.stopPropagation()}
onDrop={e => this.props.onDrop(e, {})} onContextMenu={this.onContextMenu} >
{this.reactTable}
- {this.props.Document._chromeHidden || this.props.addDocument == returnFalse ? undefined : <div className="collectionSchemaView-addRow" onClick={this.createRow}>+ new</div>}
+ {this.props.Document._chromeHidden || this.props.addDocument === returnFalse ? undefined : <div className="collectionSchemaView-addRow" onClick={this.createRow}>+ new</div>}
{!this._showDoc ? (null) :
<div className="collectionSchemaView-documentPreview" ref="overlay"
style={{
diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx
index fba95cad2..240a71c3e 100644
--- a/src/client/views/linking/LinkEditor.tsx
+++ b/src/client/views/linking/LinkEditor.tsx
@@ -48,7 +48,7 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
if (linkRelationshipList && !linkRelationshipList.includes(value)) {
linkRelationshipList.push(value);
const randColor = "rgb(" + Math.floor(Math.random() * 255) + "," + Math.floor(Math.random() * 255) + "," + Math.floor(Math.random() * 255) + ")";
- linkColorList.push(randColor)
+ linkColorList.push(randColor);
}
this.relationshipButtonColor = "rgb(62, 133, 55)";
setTimeout(action(() => this.relationshipButtonColor = ""), 750);
@@ -62,7 +62,7 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
@action
getRelationshipResults = () => {
const query = this.relationship; //current content in input box
- const linkRelationshipList = StrListCast(Doc.UserDoc().linkRelationshipList)
+ const linkRelationshipList = StrListCast(Doc.UserDoc().linkRelationshipList);
if (linkRelationshipList) {
return linkRelationshipList.filter(rel => rel.includes(query));
}
@@ -73,7 +73,7 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
*/
@action
toggleRelationshipResults = () => {
- this.relationshipSearchVisibility = this.relationshipSearchVisibility == "none" ? "block" : "none";
+ this.relationshipSearchVisibility = this.relationshipSearchVisibility === "none" ? "block" : "none";
}
@undoBatch
diff --git a/src/client/views/linking/LinkRelationshipSearch.tsx b/src/client/views/linking/LinkRelationshipSearch.tsx
index 8f83f0e6e..53da880e4 100644
--- a/src/client/views/linking/LinkRelationshipSearch.tsx
+++ b/src/client/views/linking/LinkRelationshipSearch.tsx
@@ -15,7 +15,7 @@ export class LinkRelationshipSearch extends React.Component<LinkRelationshipSear
handleResultClick = (e: React.MouseEvent) => {
const relationship = (e.target as HTMLParagraphElement).textContent;
if (relationship) {
- this.props.handleRelationshipSearchChange(relationship)
+ this.props.handleRelationshipSearchChange(relationship);
}
}
@@ -31,8 +31,8 @@ export class LinkRelationshipSearch extends React.Component<LinkRelationshipSear
* Render an empty div to increase the height of LinkEditor to accommodate 2+ results
*/
emptyDiv = () => {
- if (this.props.results && this.props.results.length > 2 && this.props.display == "block") {
- return <div style={{ height: "50px" }}></div>
+ if (this.props.results && this.props.results.length > 2 && this.props.display === "block") {
+ return <div style={{ height: "50px" }} />;
}
}
@@ -47,9 +47,9 @@ export class LinkRelationshipSearch extends React.Component<LinkRelationshipSear
{ // return a dropdown of relationship results if there exist results
this.props.results
? this.props.results.map(result => {
- return (<p key={result} onClick={this.handleResultClick}>
+ return <p key={result} onClick={this.handleResultClick}>
{result}
- </p>)
+ </p>;
})
: <p>No matching relationships</p>
}
@@ -58,6 +58,6 @@ export class LinkRelationshipSearch extends React.Component<LinkRelationshipSear
{/*Render an empty div to increase the height of LinkEditor to accommodate 2+ results */}
{this.emptyDiv()}
</div>
- )
+ );
}
} \ No newline at end of file
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index a3f03fc4b..f5a7e61aa 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -163,7 +163,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
: undefined)
) || this.rootDoc
);
- };
+ }
componentWillUnmount() {
Object.values(this._disposers).forEach((disposer) => disposer?.());
@@ -240,7 +240,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
this.layoutDoc._currentTimecode = htmlEle.currentTime;
}
- };
+ }
// pause play back
Pause = action(() => {
@@ -252,7 +252,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
playFromTime = (absoluteTime: number) => {
this.recordingStart &&
this.playFrom((absoluteTime - this.recordingStart) / 1000);
- };
+ }
// play back the audio from time
@action
@@ -277,7 +277,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
this._play = setTimeout(
() => {
this._ended = fullPlay ? true : this._ended;
- this.Pause()
+ this.Pause();
},
(end - start) * 1000
); // use setTimeout to play a specific duration
@@ -286,7 +286,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
this.Pause();
}
}
- };
+ }
// update the recording time
updateRecordTime = () => {
@@ -299,7 +299,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
(new Date().getTime() - this._recordStart - this.pauseTime) / 1000;
}
}
- };
+ }
// starts recording
recordAudioAnnotation = async () => {
@@ -320,7 +320,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
setTimeout(this.updateRecordTime, 0);
this._recorder.start();
setTimeout(() => this._recorder && this.stopRecording(), 60 * 60 * 1000); // stop after an hour
- };
+ }
// context menu
specificContextMenu = (e: React.MouseEvent): void => {
@@ -336,8 +336,8 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
(this.layoutDoc.dontAutoPlayFollowedLinks ? "" : "Don't") +
" play when link is selected",
event: () =>
- (this.layoutDoc.dontAutoPlayFollowedLinks =
- !this.layoutDoc.dontAutoPlayFollowedLinks),
+ (this.layoutDoc.dontAutoPlayFollowedLinks =
+ !this.layoutDoc.dontAutoPlayFollowedLinks),
icon: "expand-arrows-alt",
});
funcs.push({
@@ -353,7 +353,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
subitems: funcs,
icon: "asterisk",
});
- };
+ }
// stops the recording
stopRecording = action(() => {
@@ -376,12 +376,12 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
this._recorder ? this.stopRecording() : this.recordAudioAnnotation();
e.stopPropagation();
}
- };
+ }
// for play button
Play = (e?: any) => {
let start;
- if (this._ended || this._ele!.currentTime == this.duration) {
+ if (this._ended || this._ele!.currentTime === this.duration) {
start = this._trimStart;
this._ended = false;
}
@@ -391,7 +391,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
this.playFrom(start, this._trimEnd, true);
e?.stopPropagation?.();
- };
+ }
// creates a text document for dictation
onFile = (e: any) => {
@@ -413,14 +413,14 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
);
this.props.addDocument?.(newDoc);
e.stopPropagation();
- };
+ }
// ref for updating time
setRef = (e: HTMLAudioElement | null) => {
e?.addEventListener("timeupdate", this.timecodeChanged);
e?.addEventListener("ended", this.Pause);
this._ele = e;
- };
+ }
// returns the path of the audio file
@computed get path() {
@@ -431,16 +431,10 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
// returns the html audio element
@computed get audio() {
- return (
- <audio
- ref={this.setRef}
- className={`audiobox-control${this.isContentActive() ? "-interactive" : ""
- }`}
- >
- <source src={this.path} type="audio/mpeg" />
- Not supported.
- </audio>
- );
+ return <audio ref={this.setRef} className={`audiobox-control${this.props.isContentActive() ? "-interactive" : ""}`}>
+ <source src={this.path} type="audio/mpeg" />
+ Not supported.
+ </audio>;
}
// pause the time during recording phase
@@ -450,7 +444,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
this._paused = true;
this._recorder.pause();
e.stopPropagation();
- };
+ }
// continue the recording
@action
@@ -459,17 +453,18 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
this._paused = false;
this._recorder.resume();
e.stopPropagation();
- };
+ }
playing = () => this.mediaState === "playing";
playLink = (link: Doc) => {
const stack = this._stackedTimeline.current;
if (link.annotationOn === this.rootDoc) {
- if (!this.layoutDoc.dontAutoPlayFollowedLinks)
+ if (!this.layoutDoc.dontAutoPlayFollowedLinks) {
this.playFrom(stack?.anchorStart(link) || 0, stack?.anchorEnd(link));
- else
+ } else {
this._ele!.currentTime = this.layoutDoc._currentTimecode =
stack?.anchorStart(link) || 0;
+ }
} else {
this.links
.filter((l) => l.anchor1 === link || l.anchor2 === link)
@@ -478,17 +473,18 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
const startTime = stack?.anchorStart(la1) || stack?.anchorStart(la2);
const endTime = stack?.anchorEnd(la1) || stack?.anchorEnd(la2);
if (startTime !== undefined) {
- if (!this.layoutDoc.dontAutoPlayFollowedLinks)
+ if (!this.layoutDoc.dontAutoPlayFollowedLinks) {
endTime
? this.playFrom(startTime, endTime)
: this.playFrom(startTime);
- else
+ } else {
this._ele!.currentTime = this.layoutDoc._currentTimecode =
startTime;
+ }
}
});
}
- };
+ }
// shows trim controls
@action
@@ -500,7 +496,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
this.Pause();
}
this._trimming = true;
- };
+ }
// hides trim controls and displays new clip
@action
@@ -512,7 +508,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
this.layoutDoc.clipEnd = this._trimEnd;
this._trimming = false;
this.setAnchorTime(Math.max(Math.min(this._trimEnd, this._ele!.currentTime), this._trimStart));
- };
+ }
@action
setStartTrim = (newStart: number) => {
@@ -528,14 +524,14 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
timelineWhenChildContentsActiveChanged = (isActive: boolean) =>
this.props.whenChildContentsActiveChanged(
runInAction(() => (this._isAnyChildContentActive = isActive))
- );
+ )
timelineScreenToLocal = () =>
this.props
.ScreenToLocalTransform()
.translate(
-AudioBox.playheadWidth,
(-(100 - this.heightPercent) / 200) * this.props.PanelHeight()
- );
+ )
setAnchorTime = (time: number) => {
(this._ele!.currentTime = this.layoutDoc._currentTimecode = time);
}
@@ -543,7 +539,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
timelineHeight = () =>
(((this.props.PanelHeight() * this.heightPercent) / 100) *
this.heightPercent) /
- 100; // panelHeight * heightPercent is player height. * heightPercent is timeline height (as per css inline)
+ 100 // panelHeight * heightPercent is player height. * heightPercent is timeline height (as per css inline)
timelineWidth = () => this.props.PanelWidth() - AudioBox.playheadWidth;
@computed get renderTimeline() {
return (
@@ -570,7 +566,8 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
ScreenToLocalTransform={this.timelineScreenToLocal}
Play={this.Play}
Pause={this.Pause}
- isContentActive={this.isContentActive}
+ isContentActive={this.props.isContentActive}
+ isAnyChildContentActive={this.isAnyChildContentActive}
playLink={this.playLink}
PanelWidth={this.timelineWidth}
PanelHeight={this.timelineHeight}
@@ -586,7 +583,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
render() {
const interactive =
- SnappingManager.GetIsDragging() || this.isContentActive()
+ SnappingManager.GetIsDragging() || this.props.isContentActive()
? "-interactive"
: "";
return (
@@ -641,76 +638,76 @@ export class AudioBox extends ViewBoxAnnotatableComponent<
</div>
</div>
) : (
- <button
- className={`audiobox-record${interactive}`}
- style={{ backgroundColor: Colors.DARK_GRAY }}
- >
- RECORD
- </button>
- )}
+ <button
+ className={`audiobox-record${interactive}`}
+ style={{ backgroundColor: Colors.DARK_GRAY }}
+ >
+ RECORD
+ </button>
+ )}
</div>
) : (
- <div
- className="audiobox-controls"
- style={{
- pointerEvents:
- this._isAnyChildContentActive || this.isContentActive()
- ? "all"
- : "none",
- }}
- >
- <div className="audiobox-dictation" />
<div
- className="audiobox-player"
- style={{ height: `${AudioBox.heightPercent}%` }}
+ className="audiobox-controls"
+ style={{
+ pointerEvents:
+ this._isAnyChildContentActive || this.props.isContentActive()
+ ? "all"
+ : "none",
+ }}
>
+ <div className="audiobox-dictation" />
<div
- className="audiobox-buttons"
- title={this.mediaState === "paused" ? "play" : "pause"}
- onClick={this.mediaState === "paused" ? this.Play : this.Pause}
+ className="audiobox-player"
+ style={{ height: `${AudioBox.heightPercent}%` }}
>
- {" "}
- <FontAwesomeIcon
- icon={this.mediaState === "paused" ? "play" : "pause"}
- size={"1x"}
- />
- </div>
- <div
- className="audiobox-buttons"
- title={this._trimming ? "finish" : "trim"}
- onClick={this._trimming ? this.finishTrim : this.startTrim}
- >
- <FontAwesomeIcon
- icon={this._trimming ? "check" : "cut"}
- size={"1x"}
- />
- </div>
- <div
- className="audiobox-timeline"
- style={{
- top: 0,
- height: `100%`,
- left: AudioBox.playheadWidth,
- width: `calc(100% - ${AudioBox.playheadWidth}px)`,
- background: "white",
- }}
- >
- {this.renderTimeline}
- </div>
- {this.audio}
- <div className="audioBox-current-time">
- {this._trimming ?
- formatTime(Math.round(NumCast(this.layoutDoc._currentTimecode)))
- : formatTime(Math.round(NumCast(this.layoutDoc._currentTimecode) - NumCast(this._trimStart)))}
- </div>
- <div className="audioBox-total-time">
- {this._trimming || !this._trimEnd ?
- formatTime(Math.round(NumCast(this.duration)))
- : formatTime(Math.round(NumCast(this.trimDuration)))}
+ <div
+ className="audiobox-buttons"
+ title={this.mediaState === "paused" ? "play" : "pause"}
+ onClick={this.mediaState === "paused" ? this.Play : this.Pause}
+ >
+ {" "}
+ <FontAwesomeIcon
+ icon={this.mediaState === "paused" ? "play" : "pause"}
+ size={"1x"}
+ />
+ </div>
+ <div
+ className="audiobox-buttons"
+ title={this._trimming ? "finish" : "trim"}
+ onClick={this._trimming ? this.finishTrim : this.startTrim}
+ >
+ <FontAwesomeIcon
+ icon={this._trimming ? "check" : "cut"}
+ size={"1x"}
+ />
+ </div>
+ <div
+ className="audiobox-timeline"
+ style={{
+ top: 0,
+ height: `100%`,
+ left: AudioBox.playheadWidth,
+ width: `calc(100% - ${AudioBox.playheadWidth}px)`,
+ background: "white",
+ }}
+ >
+ {this.renderTimeline}
+ </div>
+ {this.audio}
+ <div className="audioBox-current-time">
+ {this._trimming ?
+ formatTime(Math.round(NumCast(this.layoutDoc._currentTimecode)))
+ : formatTime(Math.round(NumCast(this.layoutDoc._currentTimecode) - NumCast(this._trimStart)))}
+ </div>
+ <div className="audioBox-total-time">
+ {this._trimming || !this._trimEnd ?
+ formatTime(Math.round(NumCast(this.duration)))
+ : formatTime(Math.round(NumCast(this.trimDuration)))}
+ </div>
</div>
</div>
- </div>
- )}
+ )}
</div>
);
}
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 092823603..9cc4b1f9a 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -17,8 +17,8 @@ import { InkingStroke } from "../InkingStroke";
import { StyleProp } from "../StyleProvider";
import "./CollectionFreeFormDocumentView.scss";
import { DocumentView, DocumentViewProps } from "./DocumentView";
-import { FieldViewProps } from "./FieldView";
import React = require("react");
+import Color = require("color");
export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
dataProvider?: (doc: Doc, replica: string) => { x: number, y: number, zIndex?: number, opacity?: number, highlight?: boolean, z: number, transition?: string } | undefined;
@@ -164,6 +164,8 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
PanelWidth: this.panelWidth,
PanelHeight: this.panelHeight,
};
+ const background = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
+ const mixBlendMode = StrCast(this.layoutDoc.mixBlendMode) as any || (background && Color(background).alpha() !== 1 ? "multiply" : undefined);
return <div className={"collectionFreeFormDocumentView-container"}
style={{
outline: this.Highlight ? "orange solid 2px" : "",
@@ -172,7 +174,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
transform: this.transform,
transition: this.props.dataTransition ? this.props.dataTransition : this.dataProvider ? this.dataProvider.transition : StrCast(this.layoutDoc.dataTransition),
zIndex: this.ZInd,
- mixBlendMode: StrCast(this.layoutDoc.mixBlendMode) as any,
+ mixBlendMode,
display: this.ZInd === -99 ? "none" : undefined
}} >
<DocumentView {...divProps} ref={action((r: DocumentView | null) => this._contentView = r)} />
diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx
index 153176afc..6708a08ee 100644
--- a/src/client/views/nodes/ComparisonBox.tsx
+++ b/src/client/views/nodes/ComparisonBox.tsx
@@ -1,17 +1,18 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, observable } from 'mobx';
import { observer } from "mobx-react";
-import { Doc } from '../../../fields/Doc';
+import { Doc, Opt } from '../../../fields/Doc';
import { documentSchema } from '../../../fields/documentSchemas';
import { createSchema, makeInterface } from '../../../fields/Schema';
import { Cast, NumCast, StrCast } from '../../../fields/Types';
-import { emptyFunction, OmitKeys, setupMoveUpEvents } from '../../../Utils';
+import { emptyFunction, OmitKeys, returnFalse, setupMoveUpEvents } from '../../../Utils';
import { DragManager } from '../../util/DragManager';
import { SnappingManager } from '../../util/SnappingManager';
import { undoBatch } from '../../util/UndoManager';
import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../DocComponent';
+import { StyleProp } from '../StyleProvider';
import "./ComparisonBox.scss";
-import { DocumentView } from './DocumentView';
+import { DocumentView, DocumentViewProps } from './DocumentView';
import { FieldView, FieldViewProps } from './FieldView';
import React = require("react");
@@ -71,6 +72,11 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
delete this.dataDoc[fieldKey];
}
+ docStyleProvider = (doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string): any => {
+ if (property === StyleProp.PointerEvents) return "none";
+ return this.props.styleProvider?.(doc, props, property);
+ }
+
render() {
const clipWidth = NumCast(this.layoutDoc._clipWidth) + "%";
const clearButton = (which: string) => {
@@ -84,6 +90,9 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
const whichDoc = Cast(this.dataDoc[`compareBox-${which}`], Doc, null);
return whichDoc ? <>
<DocumentView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit}
+ isContentActive={returnFalse}
+ isDocumentActive={returnFalse}
+ styleProvider={this.docStyleProvider}
Document={whichDoc}
DataDoc={undefined}
pointerEvents={"none"} />
@@ -102,7 +111,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
};
return (
- <div className={`comparisonBox${this.isContentActive() || SnappingManager.GetIsDragging() ? "-interactive" : ""}` /* change className to easily disable/enable pointer events in CSS */}>
+ <div className={`comparisonBox${this.props.isContentActive() || SnappingManager.GetIsDragging() ? "-interactive" : ""}` /* change className to easily disable/enable pointer events in CSS */}>
{displayBox("after", 1, this.props.PanelWidth() - 3)}
<div className="clip-div" style={{ width: clipWidth, transition: this._animating, background: StrCast(this.layoutDoc._backgroundColor, "gray") }}>
{displayBox("before", 0, 0)}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 2bd79df64..fda84dd2d 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -85,6 +85,7 @@ export interface DocComponentView {
reverseNativeScaling?: () => boolean; // DocumentView's setup screenToLocal based on the doc having a nativeWidth/Height. However, some content views (e.g., FreeFormView w/ fitToBox set) may ignore the native dimensions so this flags the DocumentView to not do Nativre scaling.
shrinkWrap?: () => void; // requests a document to display all of its contents with no white space. currently only implemented (needed?) for freeform views
menuControls?: () => JSX.Element; // controls to display in the top menu bar when the document is selected.
+ isAnyChildContentActive?: () => boolean; // is any child content of the document active
getKeyFrameEditing?: () => boolean; // whether the document is in keyframe editing mode (if it is, then all hidden documents that are not active at the keyframe time will still be shown)
setKeyFrameEditing?: (set: boolean) => void; // whether the document is in keyframe editing mode (if it is, then all hidden documents that are not active at the keyframe time will still be shown)
playFrom?: (time: number, endTime?: number) => void;
@@ -184,7 +185,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
private _dropDisposer?: DragManager.DragDropDisposer;
private _holdDisposer?: InteractionUtils.MultiTouchEventDisposer;
protected _multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer;
- _componentView: Opt<DocComponentView>; // needs to be accessed from DocumentView wrapper class
+ @observable _componentView: Opt<DocComponentView>; // needs to be accessed from DocumentView wrapper class
private get topMost() { return this.props.renderDepth === 0 && !LightboxView.LightboxDoc; }
public get displayName() { return "DocumentView(" + this.props.Document.title + ")"; } // this makes mobx trace() statements more descriptive
@@ -780,8 +781,14 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
contentScaling = () => this.ContentScale;
onClickFunc = () => this.onClickHandler;
setHeight = (height: number) => this.layoutDoc._height = height;
- setContentView = (view: { getAnchor?: () => Doc, forward?: () => boolean, back?: () => boolean }) => this._componentView = view;
- isContentActive = (outsideReaction?: boolean) => this.props.isSelected(outsideReaction) || this.props.Document.forceActive || this.props.isContentActive() ? true : false;
+ setContentView = action((view: { getAnchor?: () => Doc, forward?: () => boolean, back?: () => boolean }) => this._componentView = view);
+ isContentActive = (outsideReaction?: boolean) => {
+ return CurrentUserUtils.SelectedTool !== InkTool.None ||
+ this.props.Document.forceActive ||
+ this.props.isSelected(outsideReaction) ||
+ this._componentView?.isAnyChildContentActive?.() ||
+ this.props.isContentActive() ? true : false;
+ }
@computed get contents() {
TraceMobx();
const audioView = !this.layoutDoc._showAudio ? (null) :
@@ -796,7 +803,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
</div>;
return <div className="documentView-contentsView"
style={{
- pointerEvents: (this.props.contentPointerEvents as any),// || (CurrentUserUtils.SelectedTool !== InkTool.None || SnappingManager.GetIsDragging() || this.isContentActive() ? "all" : "none"),
+ pointerEvents: (this.props.contentPointerEvents as any) || (this.isContentActive() ? "all" : "none"),
height: this.headerMargin ? `calc(100% - ${this.headerMargin}px)` : undefined,
}}>
<DocumentContentsView key={1} {...this.props}
@@ -1053,7 +1060,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
return this.docView?._componentView?.reverseNativeScaling?.() ? 0 :
returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.layoutDoc, this.props.DataDoc, this.props.freezeDimensions));
}
- @computed get shouldNotScale() { return (this.fitWidth && !this.nativeWidth) || [CollectionViewType.Docking, CollectionViewType.Tree].includes(this.Document._viewType as any); }
+ @computed get shouldNotScale() { return (this.fitWidth && !this.nativeWidth) || this.props.treeViewDoc || [CollectionViewType.Docking].includes(this.Document._viewType as any); }
@computed get effectiveNativeWidth() { return this.shouldNotScale ? 0 : (this.nativeWidth || NumCast(this.layoutDoc.width)); }
@computed get effectiveNativeHeight() { return this.shouldNotScale ? 0 : (this.nativeHeight || NumCast(this.layoutDoc.height)); }
@computed get nativeScaling() {
diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx
index 1e13d1b5a..7ad03e055 100644
--- a/src/client/views/nodes/FilterBox.tsx
+++ b/src/client/views/nodes/FilterBox.tsx
@@ -417,6 +417,7 @@ export class FilterBox extends ViewBoxBaseComponent<FieldViewProps, FilterBoxDoc
renderDepth={1}
dropAction={this.props.dropAction}
ScreenToLocalTransform={this.props.ScreenToLocalTransform}
+ isAnyChildContentActive={returnFalse}
addDocTab={returnFalse}
pinToPres={returnFalse}
isSelected={returnFalse}
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index c4e74ebd2..38deb4a73 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -332,9 +332,9 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
return <div className="imageBox-annotationLayer" style={{ height: this.props.PanelHeight() }} ref={this._annotationLayer} />;
}
marqueeDown = (e: React.PointerEvent) => {
- if (!e.altKey && e.button === 0 && this.layoutDoc._viewScale === 1 && this.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen].includes(CurrentUserUtils.SelectedTool)) {
+ if (!e.altKey && e.button === 0 && this.layoutDoc._viewScale === 1 && this.props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen].includes(CurrentUserUtils.SelectedTool)) {
setupMoveUpEvents(this, e, action(e => {
- MarqueeAnnotator.clearAnnotations(this._savedAnnotations)
+ MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
this._marqueeing = [e.clientX, e.clientY];
return true;
}), returnFalse, () => MarqueeAnnotator.clearAnnotations(this._savedAnnotations), false);
@@ -368,7 +368,6 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
ScreenToLocalTransform={this.screenToLocalTransform}
scaling={returnOne}
select={emptyFunction}
- isContentActive={this.isContentActive}
whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
removeDocument={this.removeDocument}
moveDocument={this.moveDocument}
diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx
index 8d665b8a6..db1ae0537 100644
--- a/src/client/views/nodes/LabelBox.tsx
+++ b/src/client/views/nodes/LabelBox.tsx
@@ -21,7 +21,7 @@ type LabelDocument = makeInterface<[typeof LabelSchema, typeof documentSchema]>;
const LabelDocument = makeInterface(LabelSchema, documentSchema);
export interface LabelBoxProps {
- label?: string
+ label?: string;
}
@observer
diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx
index c65ba9c69..55ea45bb8 100644
--- a/src/client/views/nodes/LinkBox.tsx
+++ b/src/client/views/nodes/LinkBox.tsx
@@ -30,6 +30,7 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps, LinkDocument>(
dontRegisterView={true}
renderDepth={this.props.renderDepth + 1}
CollectionView={undefined}
+ isAnyChildContentActive={returnFalse}
isContentActive={this.isContentActiveFunc}
addDocument={returnFalse}
removeDocument={returnFalse}
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 23236cf20..5e07229c1 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -177,9 +177,9 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
</>;
const searchTitle = `${!this._searching ? "Open" : "Close"} Search Bar`;
const curPage = this.Document._curPage || 1;
- return !this.isContentActive() ? (null) :
+ return !this.props.isContentActive() ? (null) :
<div className="pdfBox-ui" onKeyDown={e => [KeyCodes.BACKSPACE, KeyCodes.DELETE].includes(e.keyCode) ? e.stopPropagation() : true}
- onPointerDown={e => e.stopPropagation()} style={{ display: this.isContentActive() ? "flex" : "none" }}>
+ onPointerDown={e => e.stopPropagation()} style={{ display: this.props.isContentActive() ? "flex" : "none" }}>
<div className="pdfBox-overlayCont" onPointerDown={(e) => e.stopPropagation()} style={{ left: `${this._searching ? 0 : 100}%` }}>
<button className="pdfBox-overlayButton" title={searchTitle} />
<input className="pdfBox-searchBar" placeholder="Search" ref={this._searchRef} onChange={this.searchStringChanged}
@@ -209,7 +209,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
{this._pageControls ? pageBtns : (null)}
</div>
<button className="pdfBox-sidebarBtn" title="Toggle Sidebar"
- style={{ display: !this.isContentActive() ? "none" : undefined }}
+ style={{ display: !this.props.isContentActive() ? "none" : undefined }}
onPointerDown={this.sidebarBtnDown} >
<FontAwesomeIcon icon={"chevron-left"} size="sm" />
</button>
@@ -229,7 +229,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
}
@computed get renderTitleBox() {
- const classname = "pdfBox" + (this.isContentActive() ? "-interactive" : "");
+ const classname = "pdfBox" + (this.props.isContentActive() ? "-interactive" : "");
return <div className={classname} >
<div className="pdfBox-title-outer">
<strong className="pdfBox-title" >{this.props.Document.title}</strong>
@@ -268,7 +268,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
dataDoc={this.dataDoc}
pdf={this._pdf!}
url={this.pdfUrl!.url.pathname}
- isContentActive={this.isContentActive}
+ isContentActive={this.props.isContentActive}
anchorMenuClick={this.anchorMenuClick}
loaded={!Doc.NativeAspect(this.dataDoc) ? this.loaded : undefined}
setPdfViewer={this.setPdfViewer}
@@ -285,13 +285,13 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
rootDoc={this.rootDoc}
layoutDoc={this.layoutDoc}
dataDoc={this.dataDoc}
+ setHeight={emptyFunction}
nativeWidth={this._previewNativeWidth ?? NumCast(this.layoutDoc._nativeWidth)}
showSidebar={this.SidebarShown}
whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
sidebarAddDocument={this.sidebarAddDocument}
moveDocument={this.moveDocument}
removeDocument={this.removeDocument}
- isContentActive={this.isContentActive}
/>
{this.settingsPanel()}
</div>;
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index d16b28f32..90de3227f 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -307,7 +307,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
const interactive = CurrentUserUtils.SelectedTool !== InkTool.None || !this.props.isSelected() ? "" : "-interactive";
const style = "videoBox-content" + (this._fullScreen ? "-fullScreen" : "") + interactive;
return !field ? <div key="loading">Loading</div> :
- <div className="container" key="container" style={{ pointerEvents: this._isAnyChildContentActive || this.isContentActive() ? "all" : "none" }}>
+ <div className="container" key="container" style={{ mixBlendMode: "multiply", pointerEvents: this.props.isContentActive() ? "all" : "none" }}>
<div className={`${style}`} style={{ width: "100%", height: "100%", left: "0px" }}>
<video key="video" autoPlay={this._screenCapture} ref={this.setVideoRef}
style={{ height: "100%", width: "auto", display: "flex", margin: "auto" }}
@@ -321,7 +321,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
Not supported.
</video>
{!this.audiopath || this.audiopath === field.url.href ? (null) :
- <audio ref={this.setAudioRef} className={`audiobox-control${this.isContentActive() ? "-interactive" : ""}`}>
+ <audio ref={this.setAudioRef} className={`audiobox-control${this.props.isContentActive() ? "-interactive" : ""}`}>
<source src={this.audiopath} type="audio/mpeg" />
Not supported.
</audio>}
@@ -378,30 +378,30 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
private get uIButtons() {
const curTime = (this.layoutDoc._currentTimecode || 0);
const nonNativeControls = [
- <Tooltip title={<div className="dash-tooltip">{"playback"}</div>} placement="bottom">
- <div className="videoBox-play" key="play" onPointerDown={this.onPlayDown} >
+ <Tooltip title={<div className="dash-tooltip">{"playback"}</div>} key="play" placement="bottom">
+ <div className="videoBox-play" onPointerDown={this.onPlayDown} >
<FontAwesomeIcon icon={this._playing ? "pause" : "play"} size="lg" />
</div>
</Tooltip>,
- <Tooltip title={<div className="dash-tooltip">{"timecode"}</div>} placement="bottom">
+ <Tooltip title={<div className="dash-tooltip">{"timecode"}</div>} key="time" placement="bottom">
<div className="videoBox-time" onPointerDown={this.onResetDown} >
<span>{formatTime(curTime)}</span>
<span style={{ fontSize: 8 }}>{" " + Math.floor((curTime - Math.trunc(curTime)) * 100).toString().padStart(2, "0")}</span>
</div>
</Tooltip>,
- <Tooltip title={<div className="dash-tooltip">{"view full screen"}</div>} placement="bottom">
+ <Tooltip title={<div className="dash-tooltip">{"view full screen"}</div>} key="full" placement="bottom">
<div className="videoBox-full" onPointerDown={this.FullScreen}>
<FontAwesomeIcon icon="expand" size="lg" />
</div>
</Tooltip>];
return <div className="videoBox-ui">
{[...(VideoBox._nativeControls ? [] : nonNativeControls),
- <Tooltip title={<div className="dash-tooltip">{"snapshot current frame"}</div>} placement="bottom">
+ <Tooltip title={<div className="dash-tooltip">{"snapshot current frame"}</div>} key="snap" placement="bottom">
<div className="videoBox-snapshot" onPointerDown={this.onSnapshotDown} >
<FontAwesomeIcon icon="camera" size="lg" />
</div>
</Tooltip>,
- <Tooltip title={<div className="dash-tooltip">{"show annotation timeline"}</div>} placement="bottom">
+ <Tooltip title={<div className="dash-tooltip">{"show annotation timeline"}</div>} key="timeline" placement="bottom">
<div className="videoBox-timelineButton" onPointerDown={this.onTimelineHdlDown}>
<FontAwesomeIcon icon="eye" size="lg" />
</div>
@@ -429,7 +429,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
setupMoveUpEvents(this, e,
action((e: PointerEvent) => {
this._clicking = false;
- if (this.isContentActive()) {
+ if (this.props.isContentActive()) {
const local = this.props.ScreenToLocalTransform().scale(this.props.scaling?.() || 1).transformPoint(e.clientX, e.clientY);
this.layoutDoc._timelineHeightPercent = Math.max(0, Math.min(100, local[1] / this.props.PanelHeight() * 100));
}
@@ -438,7 +438,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
() => {
this.layoutDoc._timelineHeightPercent = this.heightPercent !== 100 ? 100 : VideoBox.heightPercent;
setTimeout(action(() => this._clicking = false), 500);
- }, this.isContentActive(), this.isContentActive());
+ }, this.props.isContentActive(), this.props.isContentActive());
});
onResetDown = (e: React.PointerEvent) => {
@@ -529,12 +529,12 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
playFrom={this.playFrom}
setTime={this.setAnchorTime}
playing={this.playing}
+ isAnyChildContentActive={this.isAnyChildContentActive}
whenChildContentsActiveChanged={this.timelineWhenChildContentsActiveChanged}
removeDocument={this.removeDocument}
ScreenToLocalTransform={this.timelineScreenToLocal}
Play={this.Play}
Pause={this.Pause}
- isContentActive={this.isContentActive}
playLink={this.playLink}
PanelHeight={this.timelineHeight}
trimming={false}
@@ -552,7 +552,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
}
marqueeDown = (e: React.PointerEvent) => {
- if (!e.altKey && e.button === 0 && this.layoutDoc._viewScale === 1 && this.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen].includes(CurrentUserUtils.SelectedTool)) {
+ if (!e.altKey && e.button === 0 && this.layoutDoc._viewScale === 1 && this.props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen].includes(CurrentUserUtils.SelectedTool)) {
setupMoveUpEvents(this, e, action(e => {
MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
this._marqueeing = [e.clientX, e.clientY];
@@ -576,7 +576,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
}
marqueeFitScaling = () => (this.props.scaling?.() || 1) * this.heightPercent / 100;
marqueeOffset = () => [this.panelWidth() / 2 * (1 - this.heightPercent / 100) / (this.heightPercent / 100), 0];
- timelineDocFilter = () => ["_timelineLabel:true:x"];
+ timelineDocFilter = () => [`_timelineLabel:true,${Utils.noRecursionHack}:x`];
render() {
const borderRad = this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BorderRounding);
const borderRadius = borderRad?.includes("px") ? `${Number(borderRad.split("px")[0]) / this.scaling()}px` : borderRad;
@@ -598,7 +598,6 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
ScreenToLocalTransform={this.screenToLocalTransform}
docFilters={this.timelineDocFilter}
select={emptyFunction}
- isContentActive={this.isContentActive}
scaling={returnOne}
whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
removeDocument={this.removeDocument}
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index ae6b90e41..e4d4557af 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -88,12 +88,13 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
this.dataDoc[this.fieldKey + "-sidebar"] = ComputedField.MakeFunction(`copyField(this["${this.fieldKey}-"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"-sidebar"`);
});
- this._disposers.selection = reaction(() => this.props.isSelected(),
- selected => !selected && setTimeout(() => {
- // Array.from(this._savedAnnotations.values()).forEach(v => v.forEach(a => a.remove()));
- // this._savedAnnotations.clear();
- })
- );
+ this._disposers.autoHeight = reaction(() => this.layoutDoc._autoHeight,
+ autoHeight => {
+ if (autoHeight) {
+ this.layoutDoc._nativeHeight = NumCast(this.props.Document[this.props.fieldKey + "-nativeHeight"]);
+ this.props.setHeight(NumCast(this.props.Document[this.props.fieldKey + "-nativeHeight"]) * (this.props.scaling?.() || 1));
+ }
+ });
if (this.webField?.href.indexOf("youtube") !== -1) {
const youtubeaspect = 400 / 315;
@@ -401,7 +402,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
@action
onMarqueeDown = (e: React.PointerEvent) => {
- if (!e.altKey && e.button === 0 && this.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen].includes(CurrentUserUtils.SelectedTool)) {
+ if (!e.altKey && e.button === 0 && this.props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen].includes(CurrentUserUtils.SelectedTool)) {
setupMoveUpEvents(this, e, action(e => {
MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
this._marqueeing = [e.clientX, e.clientY];
@@ -484,7 +485,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
NumCast(this.layoutDoc.nativeWidth)
@computed get content() {
- return <div className={"webBox-cont" + (!this.props.docViewPath().lastElement()?.docView?._pendingDoubleClick && this.isContentActive() && CurrentUserUtils.SelectedTool === InkTool.None && !DocumentDecorations.Instance?.Interacting ? "-interactive" : "")}
+ return <div className={"webBox-cont" + (!this.props.docViewPath().lastElement()?.docView?._pendingDoubleClick && this.props.isContentActive() && CurrentUserUtils.SelectedTool === InkTool.None && !DocumentDecorations.Instance?.Interacting ? "-interactive" : "")}
style={{ width: NumCast(this.layoutDoc[this.fieldKey + "-contentWidth"]) || `${100 / (this.props.scaling?.() || 1)}%`, }}>
{this.urlContent}
</div>;
@@ -529,7 +530,6 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
docFilters={docFilters || this.props.docFilters}
dontRenderDocuments={docFilters ? false : true}
select={emptyFunction}
- isContentActive={returnFalse}
ContentScaling={returnOne}
bringToFront={emptyFunction}
whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
@@ -539,7 +539,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
childPointerEvents={true}
pointerEvents={CurrentUserUtils.SelectedTool !== InkTool.None || this._isAnnotating || SnappingManager.GetIsDragging() ? "all" : "none"} />;
return (
- <div className="webBox" ref={this._mainCont} style={{ pointerEvents: this.isContentActive() ? "all" : this.isContentActive() || SnappingManager.GetIsDragging() ? undefined : "none" }} >
+ <div className="webBox" ref={this._mainCont} style={{ pointerEvents: this.props.isContentActive() ? "all" : this.props.isContentActive() || SnappingManager.GetIsDragging() ? undefined : "none" }} >
<div className={`webBox-container`} style={{ pointerEvents }} onContextMenu={this.specificContextMenu}>
<base target="_blank" />
<div className={"webBox-outerContent"} ref={this._outerRef}
@@ -559,7 +559,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
{renderAnnotations(this.transparentFilter)}
</div>
{renderAnnotations(this.opaqueFilter)}
- {renderAnnotations()}
+ {SnappingManager.GetIsDragging() ? (null) : renderAnnotations()}
{this.annotationLayer}
</div>
</div>
@@ -583,15 +583,15 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
rootDoc={this.rootDoc}
layoutDoc={this.layoutDoc}
dataDoc={this.dataDoc}
+ setHeight={emptyFunction}
nativeWidth={this._previewNativeWidth ?? NumCast(this.layoutDoc._nativeWidth)}
showSidebar={this.SidebarShown}
sidebarAddDocument={this.sidebarAddDocument}
moveDocument={this.moveDocument}
removeDocument={this.removeDocument}
- isContentActive={this.isContentActive}
/>
<button className="webBox-overlayButton-sidebar" key="sidebar" title="Toggle Sidebar"
- style={{ display: !this.isContentActive() ? "none" : undefined }}
+ style={{ display: !this.props.isContentActive() ? "none" : undefined }}
onPointerDown={this.sidebarBtnDown} >
<FontAwesomeIcon style={{ color: "white" }} icon={"chevron-left"} size="sm" />
</button>
diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx
index 040e8f0f4..a6887cbba 100644
--- a/src/client/views/nodes/button/FontIconBox.tsx
+++ b/src/client/views/nodes/button/FontIconBox.tsx
@@ -336,7 +336,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
const checkWidth = ScriptField.MakeScript("setStrokeWidth(0, true)")?.script.run().result;
const width = 20 + (checkWidth / 100) * 70;
const height = 20 + (checkWidth / 100) * 70;
- strokeIcon = (<div style={{ borderRadius: "100%", width: width + '%', height: height + '%', backgroundColor: boolResult ? boolResult : "#FFFFFF" }} />)
+ strokeIcon = (<div style={{ borderRadius: "100%", width: width + '%', height: height + '%', backgroundColor: boolResult ? boolResult : "#FFFFFF" }} />);
}
const colorOptions: string[] = ['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505',
@@ -451,7 +451,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
const script: string = StrCast(this.rootDoc.script);
// Script for checking the outcome of the toggle
- let checkScript: string = StrCast(this.rootDoc.script) + "('', true)";
+ const checkScript: string = StrCast(this.rootDoc.script) + "('', true)";
// Function to run the script
const checkResult = ScriptField.MakeScript(checkScript)?.script.run().result;
@@ -609,7 +609,7 @@ Scripting.addGlobal(function getActiveTextInfo(info: "family" | "size" | "color"
case "color": return style?.activeColors[0];
case "highlight": return style?.activeHighlights[0];
}
-})
+});
Scripting.addGlobal(function setAlignment(align: "left" | "right" | "center", checkResult?: boolean) {
const editorView = RichTextMenu.Instance?.TextView?.EditorView;
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index f4053d69f..a9beb67de 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1211,7 +1211,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
if ((e.nativeEvent as any).formattedHandled) {
console.log("handled");
}
- if (!(e.nativeEvent as any).formattedHandled && this.isContentActive(true)) {
+ if (!(e.nativeEvent as any).formattedHandled && this.props.isContentActive(true)) {
const editor = this._editorView!;
const pcords = editor.posAtCoords({ left: e.clientX, top: e.clientY });
!this.props.isSelected(true) && editor.dispatch(editor.state.tr.setSelection(new TextSelection(editor.state.doc.resolve(pcords?.pos || 0))));
@@ -1481,7 +1481,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
@computed get sidebarHandle() {
TraceMobx();
const annotated = DocListCast(this.dataDoc[this.SidebarKey]).filter(d => d?.author).length;
- return (!annotated && !this.isContentActive()) ? (null) : <div className="formattedTextBox-sidebar-handle" onPointerDown={this.sidebarDown}
+ return (!annotated && !this.props.isContentActive()) ? (null) : <div className="formattedTextBox-sidebar-handle" onPointerDown={this.sidebarDown}
style={{
left: `max(0px, calc(100% - ${this.sidebarWidthPercent} ${this.sidebarWidth() ? "- 5px" : "- 10px"}))`,
background: this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.WidgetColor + (annotated ? ":annotated" : ""))
@@ -1504,7 +1504,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
sidebarAddDocument={this.sidebarAddDocument}
moveDocument={this.moveDocument}
removeDocument={this.removeDocument}
- isContentActive={this.isContentActive}
/> :
<ComponentTag
{...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit}
@@ -1517,7 +1516,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
scaleField={this.SidebarKey + "-scale"}
isAnnotationOverlay={false}
select={emptyFunction}
- isContentActive={this.isContentActive}
scaling={this.sidebarContentScaling}
whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
removeDocument={this.sidebarRemDocument}
@@ -1539,7 +1537,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
render() {
TraceMobx();
const selected = this.props.isSelected();
- const active = this.isContentActive();
+ const active = this.props.isContentActive();
const scale = this.props.hideOnLeave ? 1 : (this.props.scaling?.() || 1) * NumCast(this.layoutDoc._viewScale, 1);
const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : "";
const interactive = (CurrentUserUtils.SelectedTool === InkTool.None || SnappingManager.GetIsDragging()) && (this.layoutDoc.z || this.props.layerProvider?.(this.layoutDoc) !== false);
@@ -1551,7 +1549,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
const selPaddingClass = selected && !this.layoutDoc._singleLine && margins >= 10 ? "-selected" : "";
return (
<div className="formattedTextBox-cont"
- onWheel={e => this.isContentActive() && e.stopPropagation()}
+ onWheel={e => this.props.isContentActive() && e.stopPropagation()}
style={{
transform: this.props.dontScale ? undefined : `scale(${scale})`,
transformOrigin: this.props.dontScale ? undefined : "top left",
diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx
index 75e3f81fb..3bf1f0828 100644
--- a/src/client/views/pdf/AnchorMenu.tsx
+++ b/src/client/views/pdf/AnchorMenu.tsx
@@ -69,8 +69,7 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
this._disposer = reaction(() => SelectionManager.Views(),
selected => {
this._showLinkPopup = false;
- console.log("unmount");
- AnchorMenu.Instance.fadeOut(true)
+ AnchorMenu.Instance.fadeOut(true);
});
}
@@ -86,6 +85,7 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
if (!this.Highlight(this.highlightColor, false) && this.Pinned) {
this.Highlighting = !this.Highlighting;
}
+ AnchorMenu.Instance.fadeOut(true);
}
@action
@@ -157,7 +157,7 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
<FontAwesomeIcon icon="link" size="lg" />
</button>
</Tooltip>,
- <LinkPopup showPopup={this._showLinkPopup} linkFrom={this.onMakeAnchor} />
+ <LinkPopup key="popup" showPopup={this._showLinkPopup} linkFrom={this.onMakeAnchor} />
] : [
<Tooltip key="trash" title={<div className="dash-tooltip">{"Remove Link Anchor"}</div>}>
<button className="antimodeMenu-button" onPointerDown={this.Delete}>
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 734d9127c..02010e123 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -119,9 +119,11 @@ export class PDFViewer extends React.Component<IViewerProps> {
this._mainCont.current?.addEventListener("scroll", e => (e.target as any).scrollLeft = 0);
this._disposers.autoHeight = reaction(() => this.props.layoutDoc._autoHeight,
- () => {
- this.props.layoutDoc._nativeHeight = NumCast(this.props.Document[this.props.fieldKey + "-nativeHeight"]);
- this.props.setHeight(NumCast(this.props.Document[this.props.fieldKey + "-nativeHeight"]) * (this.props.scaling?.() || 1));
+ autoHeight => {
+ if (autoHeight) {
+ this.props.layoutDoc._nativeHeight = NumCast(this.props.Document[this.props.fieldKey + "-nativeHeight"]);
+ this.props.setHeight(NumCast(this.props.Document[this.props.fieldKey + "-nativeHeight"]) * (this.props.scaling?.() || 1));
+ }
});
this._disposers.searchMatch = reaction(() => Doc.IsSearchMatch(this.props.rootDoc),
@@ -512,7 +514,6 @@ export class PDFViewer extends React.Component<IViewerProps> {
const renderAnnotations = (docFilters?: () => string[]) =>
<CollectionFreeFormView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit}
isAnnotationOverlay={true}
- isContentActive={returnFalse}
fieldKey={this.props.fieldKey + "-annotations"}
setPreviewCursor={this.setPreviewCursor}
PanelHeight={this.panelHeight}
@@ -526,7 +527,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
CollectionView={undefined}
ScreenToLocalTransform={this.overlayTransform}
renderDepth={this.props.renderDepth + 1}
- childPointerEvents={true} />
+ childPointerEvents={true} />;
return <div>
<div className={`pdfViewerDash-overlay${CurrentUserUtils.SelectedTool !== InkTool.None || SnappingManager.GetIsDragging() ? "-inking" : ""}`}
style={{
@@ -543,7 +544,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
transform: `scale(${this._zoomed})`
}}>
{renderAnnotations(this.opaqueFilter)}
- {renderAnnotations()}
+ {SnappingManager.GetIsDragging() ? (null) : renderAnnotations()}
</div>
</div>;
}
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 07186fe8d..260ddfc90 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -14,7 +14,7 @@ import "./SearchBox.scss";
import { DocumentManager } from '../../util/DocumentManager';
import { DocUtils } from '../../documents/Documents';
-export const searchSchema = createSchema({
+export const searchSchema = createSchema({
Document: Doc
});
@@ -109,13 +109,12 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps, SearchBoxDoc
});
makeLink = action((linkTo: Doc) => {
- console.log("[makeLink-1] got here!")
console.log(linkTo.title);
- if (this.props.linkFrom){
+ if (this.props.linkFrom) {
const linkFrom = this.props.linkFrom();
- if (linkFrom){
+ if (linkFrom) {
console.log(linkFrom.title);
- DocUtils.MakeLink({doc: linkFrom}, {doc:linkTo});
+ DocUtils.MakeLink({ doc: linkFrom }, { doc: linkTo });
}
}
});
@@ -177,10 +176,10 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps, SearchBoxDoc
* right side of each search result.
*/
static formatType(type: String): String {
- if (type == "pdf") {
+ if (type === "pdf") {
return "PDF";
}
- else if (type == "image") {
+ else if (type === "image") {
return "Img";
}
@@ -200,28 +199,25 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps, SearchBoxDoc
const blockedTypes = [DocumentType.PRESELEMENT, DocumentType.KVP, DocumentType.FILTER, DocumentType.SEARCH, DocumentType.SEARCHITEM, DocumentType.FONTICON, DocumentType.BUTTON, DocumentType.SCRIPTING];
const blockedKeys = ["x", "y", "proto", "width", "autoHeight", "acl-Override", "acl-Public", "context", "zIndex", "height", "text-scrollHeight", "text-height", "cloneFieldFilter", "isPrototype", "text-annotations",
"dragFactory-count", "text-noTemplate", "aliases", "system", "layoutKey", "baseProto", "xMargin", "yMargin", "links", "layout", "layout_keyValue", "fitWidth", "viewType", "title-custom",
- "panX", "panY", "viewScale"]
+ "panX", "panY", "viewScale"];
const collection = CollectionDockingView.Instance;
query = query.toLowerCase();
- this._results = []
- this._selectedResult = undefined
+ this._results = [];
+ this._selectedResult = undefined;
if (collection !== undefined) {
const docs = DocListCast(collection.rootDoc[Doc.LayoutFieldKey(collection.rootDoc)]);
- const docIDs: String[] = []
- console.log(docs.length)
+ const docIDs: String[] = [];
SearchBox.foreachRecursiveDoc(docs, (depth: number, doc: Doc) => {
const dtype = StrCast(doc.type, "string") as DocumentType;
if (dtype && !blockedTypes.includes(dtype) && !docIDs.includes(doc[Id]) && depth > 0) {
const hlights = new Set<string>();
SearchBox.documentKeys(doc).forEach(key => Field.toString(doc[key] as Field).toLowerCase().includes(query) && hlights.add(key));
- blockedKeys.forEach(key => {
- hlights.delete(key);
- })
+ blockedKeys.forEach(key => hlights.delete(key));
Array.from(hlights.keys()).length > 0 && this._results.push([doc, Array.from(hlights.keys())]);
}
- docIDs.push(doc[Id])
+ docIDs.push(doc[Id]);
});
}
}
@@ -245,7 +241,7 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps, SearchBoxDoc
submitSearch = async () => {
this.resetSearch();
- let query = StrCast(this._searchString);
+ const query = StrCast(this._searchString);
Doc.SetSearchQuery(query);
this._results = [];
@@ -282,11 +278,9 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps, SearchBoxDoc
*/
@computed
public get selectOptions() {
- const selectValues = ["all", "rtf", "image", "pdf", "web", "video", "audio", "collection"]
+ const selectValues = ["all", "rtf", "image", "pdf", "web", "video", "audio", "collection"];
- return selectValues.map(value => {
- return <option key={value} value={value}>{SearchBox.formatType(value)}</option>
- })
+ return selectValues.map(value => <option key={value} value={value}>{SearchBox.formatType(value)}</option>);
}
/**
@@ -295,17 +289,17 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps, SearchBoxDoc
render() {
var validResults = 0;
- const isLinkSearch:boolean = this.props.linkSearch;
+ const isLinkSearch: boolean = this.props.linkSearch;
const results = this._results.map(result => {
var className = "searchBox-results-scroll-view-result";
- if (this._selectedResult == result[0]) {
- className += " searchBox-results-scroll-view-result-selected"
+ if (this._selectedResult === result[0]) {
+ className += " searchBox-results-scroll-view-result-selected";
}
- if (this._docTypeString == "all" || this._docTypeString == result[0].type) {
+ if (this._docTypeString === "all" || this._docTypeString === result[0].type) {
validResults++;
return (
<div key={result[0][Id]} onClick={isLinkSearch ? () => this.makeLink(result[0]) : () => this.onResultClick(result[0])} className={className}>
@@ -319,25 +313,25 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps, SearchBoxDoc
{result[1].join(", ")}
</div>
</div>
- )
+ );
}
return null;
- })
+ });
results.filter(result => result);
return (
<div style={{ pointerEvents: "all" }} className="searchBox-container">
- <div className="searchBox-bar" >
- {isLinkSearch ? (null) : <select name="type" id="searchBox-type" className="searchBox-type" onChange={this.onSelectChange}>
+ <div className="searchBox-bar" >
+ {isLinkSearch ? (null) : <select name="type" id="searchBox-type" className="searchBox-type" onChange={this.onSelectChange}>
{this.selectOptions}
</select>}
- <input defaultValue={""} autoComplete="off" onChange={this.onInputChange} type="text" placeholder="Search..." id="search-input" className="searchBox-input" style={{width: isLinkSearch ? "100%" : undefined, borderRadius: isLinkSearch ? "5px" : undefined}} ref={this._inputRef} />
+ <input defaultValue={""} autoComplete="off" onChange={this.onInputChange} type="text" placeholder="Search..." id="search-input" className="searchBox-input" style={{ width: isLinkSearch ? "100%" : undefined, borderRadius: isLinkSearch ? "5px" : undefined }} ref={this._inputRef} />
</div >
<div className="searchBox-results-container">
<div className="searchBox-results-count">
- {`${validResults}` + " result" + (validResults == 1 ? "" : "s")}
+ {`${validResults}` + " result" + (validResults === 1 ? "" : "s")}
</div>
<div className="searchBox-results-scroll-view">
{results}
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 17f41fac8..b09ff93d0 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -1092,6 +1092,9 @@ export namespace Doc {
const isTransparent = (color: string) => color !== "" && (Color(color).alpha() !== 1);
return isTransparent(StrCast(doc[key]));
}
+ if (typeof value === "string") {
+ value = value.replace(`,${Utils.noRecursionHack}`, "");
+ }
const fieldVal = doc[key];
if (Cast(fieldVal, listSpec("string"), []).length) {
const vals = Cast(fieldVal, listSpec("string"), []);