aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoranika <anika.ahluwalia@gmail.com>2021-01-28 09:21:12 -0500
committeranika <anika.ahluwalia@gmail.com>2021-01-28 09:21:12 -0500
commit35e1b844c23b0f78ead7ab00ffec16c8c6460229 (patch)
treed2d9dcd87ca62cca4a02db0b55a5fe307a2926b9 /src
parent5b0a4a154a6e68139d3d7e462ca421d3fbbdd224 (diff)
parent17bd18fd01d8b1f7fbef11d42651932d251cacc7 (diff)
Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web into filters
Diffstat (limited to 'src')
-rw-r--r--src/client/views/DocComponent.tsx5
-rw-r--r--src/client/views/DocumentDecorations.scss38
-rw-r--r--src/client/views/DocumentDecorations.tsx8
-rw-r--r--src/client/views/MainView.scss2
-rw-r--r--src/client/views/collections/CollectionStackedTimeline.tsx60
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx31
-rw-r--r--src/client/views/nodes/DocumentView.tsx2
-rw-r--r--src/client/views/nodes/PresBox.tsx7
-rw-r--r--src/client/views/nodes/VideoBox.scss7
-rw-r--r--src/client/views/nodes/VideoBox.tsx45
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx1
-rw-r--r--src/client/views/nodes/formattedText/RichTextSchema.tsx3
12 files changed, 132 insertions, 77 deletions
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index 8d545c61b..99f13295d 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -131,7 +131,10 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps, T
const docs = indocs.filter(doc => effectiveAcl === AclEdit || effectiveAcl === AclAdmin || GetEffectiveAcl(doc) === AclAdmin);
if (docs.length) {
const docs = doc instanceof Doc ? [doc] : doc;
- docs.map(doc => doc.isPushpin = doc.annotationOn = undefined);
+ docs.map(doc => {
+ Doc.SetInPlace(doc, "isPushpin", undefined, true);
+ Doc.SetInPlace(doc, "annotationOn", undefined, true);
+ });
const targetDataDoc = this.dataDoc;
const value = DocListCast(targetDataDoc[annotationKey ?? this.annotationKey]);
const toRemove = value.filter(v => docs.includes(v));
diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss
index f9b8c1940..22e120167 100644
--- a/src/client/views/DocumentDecorations.scss
+++ b/src/client/views/DocumentDecorations.scss
@@ -79,7 +79,7 @@ $linkGap : 3px;
grid-column: 5;
grid-row: 4;
border-radius: 100%;
- background: dimgray;
+ background: black;
height: 8;
right: -12;
top: 12;
@@ -145,7 +145,7 @@ $linkGap : 3px;
.documentDecorations-topRightResizer:hover,
.documentDecorations-bottomLeftResizer:hover {
cursor: nesw-resize;
- background: dimGray;
+ background: black;
opacity: 1;
}
@@ -169,6 +169,14 @@ $linkGap : 3px;
cursor: pointer;
}
+ .documentDecorations-titleBackground {
+ background: #ffffffcf;
+ border-radius: 8px;
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ }
+
.documentDecorations-title {
opacity: 1;
grid-column-start: 2;
@@ -177,26 +185,22 @@ $linkGap : 3px;
overflow: hidden;
text-align: center;
display: flex;
- border-bottom: solid 1px;
- margin-left: 10px;
- width: calc(100% - 10px);
+ margin-left: 5px;
+ height: 22px;
+ position: absolute;
+ .documentDecorations-titleSpan {
+ width: 100%;
+ border-radius: 8px;
+ background: #ffffffcf;
+ position: absolute;
+ display: inline-block;
+ cursor: move;
+ }
}
.focus-visible {
margin-left: 0px;
}
-
- .publishBox {
- width: 20px;
- height: 22px;
- grid-column-start: 3;
- grid-column-end: 4;
- pointer-events: all;
- background: darkgray;
- display: inline-block;
- position: absolute;
- right: 0;
- }
}
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index fb85684fb..8d8f4cd3b 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -577,8 +577,8 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b
const titleArea = this._edtingTitle ?
<input ref={this._keyinput} className="documentDecorations-title" type="text" name="dynbox" autoComplete="on" value={this._accumulatedTitle}
onBlur={e => this.titleBlur(true)} onChange={action(e => this._accumulatedTitle = e.target.value)} onKeyPress={this.titleEntered} /> :
- <div className="documentDecorations-title" style={{ gridColumnEnd: 5 }} key="title" onPointerDown={this.onTitleDown} >
- <span style={{ width: "100%", display: "inline-block", cursor: "move" }}>{`${this.selectionTitle}`}</span>
+ <div className="documentDecorations-title" style={{ width: `calc(100% - ${seldoc.props.hideResizeHandles ? 0 : 20}px` }} key="title" onPointerDown={this.onTitleDown} >
+ <span className="documentDecorations-titleSpan">{`${this.selectionTitle}`}</span>
</div>;
let inMainMenuPanel = false;
@@ -612,8 +612,8 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b
top: bounds.y - this._resizeBorderWidth / 2 - this._titleHeight,
}}>
{closeIcon}
- {bounds.r - bounds.x < 100 ? null : titleArea}
- {seldoc.rootDoc.anchorStartTime !== undefined ? (null) :
+ {titleArea}
+ {seldoc.props.hideResizeHandles ? (null) :
<>
{SelectionManager.Views().length !== 1 || seldoc.Document.type === DocumentType.INK ? (null) :
<Tooltip key="i" title={<div className="dash-tooltip">{`${seldoc.finalLayoutKey.includes("icon") ? "De" : ""}Iconify Document`}</div>} placement="top">
diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss
index d6a455a22..8ccb64744 100644
--- a/src/client/views/MainView.scss
+++ b/src/client/views/MainView.scss
@@ -61,7 +61,7 @@
}
.mainView-container {
- color: dimgray;
+ color: black;
.lm_title {
background: #cacaca;
diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx
index 1775250fa..21fbef1ac 100644
--- a/src/client/views/collections/CollectionStackedTimeline.tsx
+++ b/src/client/views/collections/CollectionStackedTimeline.tsx
@@ -16,6 +16,7 @@ import { CollectionSubView } from "../collections/CollectionSubView";
import { DocumentView } from "../nodes/DocumentView";
import { LabelBox } from "../nodes/LabelBox";
import "./CollectionStackedTimeline.scss";
+import { undoBatch } from "../../util/UndoManager";
type PanZoomDocument = makeInterface<[]>;
const PanZoomDocument = makeInterface();
@@ -58,10 +59,10 @@ export class CollectionStackedTimeline extends CollectionSubView<PanZoomDocument
constructor(props: any) {
super(props);
// onClick play scripts
- CollectionStackedTimeline.RangeScript = CollectionStackedTimeline.RangeScript || ScriptField.MakeFunction(`scriptContext.clickAnchor(this)`, { self: Doc.name, scriptContext: "any" })!;
- CollectionStackedTimeline.LabelScript = CollectionStackedTimeline.LabelScript || ScriptField.MakeFunction(`scriptContext.clickAnchor(this)`, { self: Doc.name, scriptContext: "any" })!;
- CollectionStackedTimeline.RangePlayScript = CollectionStackedTimeline.RangePlayScript || ScriptField.MakeFunction(`scriptContext.playOnClick(this)`, { self: Doc.name, scriptContext: "any" })!;
- CollectionStackedTimeline.LabelPlayScript = CollectionStackedTimeline.LabelPlayScript || ScriptField.MakeFunction(`scriptContext.playOnClick(this)`, { self: Doc.name, scriptContext: "any" })!;
+ CollectionStackedTimeline.RangeScript = CollectionStackedTimeline.RangeScript || ScriptField.MakeFunction(`scriptContext.clickAnchor(this, clientX)`, { self: Doc.name, scriptContext: "any", clientX: "number" })!;
+ CollectionStackedTimeline.LabelScript = CollectionStackedTimeline.LabelScript || ScriptField.MakeFunction(`scriptContext.clickAnchor(this, clientX)`, { self: Doc.name, scriptContext: "any", clientX: "number" })!;
+ CollectionStackedTimeline.RangePlayScript = CollectionStackedTimeline.RangePlayScript || ScriptField.MakeFunction(`scriptContext.playOnClick(this, clientX)`, { self: Doc.name, scriptContext: "any", clientX: "number" })!;
+ CollectionStackedTimeline.LabelPlayScript = CollectionStackedTimeline.LabelPlayScript || ScriptField.MakeFunction(`scriptContext.playOnClick(this, clientX)`, { self: Doc.name, scriptContext: "any", clientX: "number" })!;
}
// for creating key anchors with key events
@@ -84,8 +85,8 @@ export class CollectionStackedTimeline extends CollectionSubView<PanZoomDocument
}
}
- anchorStart = (anchor: Doc) => NumCast(anchor.anchorStartTime, NumCast(anchor._timecodeToShow, NumCast(anchor.videoStart)));
- anchorEnd = (anchor: Doc, defaultVal: any = null) => NumCast(anchor.anchorEndTime, NumCast(anchor._timecodeToHide, NumCast(anchor.videoEnd, defaultVal)));
+ anchorStart = (anchor: Doc) => NumCast(anchor.anchorStartTime, NumCast(anchor._timecodeToShow, NumCast(anchor.videoStart, NumCast(anchor.audioStart))));
+ anchorEnd = (anchor: Doc, val: any = null) => NumCast(anchor.anchorEndTime, NumCast(anchor._timecodeToHide, NumCast(anchor.videoEnd, NumCast(anchor.audioEnd, val))));
getLinkData(l: Doc) {
let la1 = l.anchor1 as Doc;
@@ -106,7 +107,11 @@ export class CollectionStackedTimeline extends CollectionSubView<PanZoomDocument
// updates the anchor with the new time
@action
changeAnchor = (anchor: Opt<Doc>, time: number) => {
- anchor && (this._left ? anchor.anchorStartTime = time : anchor.anchorEndTime = time);
+ if (anchor) {
+ const timelineOnly = Cast(anchor.anchorStartTime, "number", null) !== undefined;
+ if (timelineOnly) this._left ? anchor.anchorStartTime = time : anchor.anchorEndTime = time;
+ else this._left ? anchor._timecodeToShow = time : anchor._timecodeToHide = time;
+ }
}
// checks if the two anchors are the same with start and end time
@@ -160,6 +165,7 @@ export class CollectionStackedTimeline extends CollectionSubView<PanZoomDocument
}
}
+ @undoBatch
@action
createAnchor(anchorStartTime?: number, anchorEndTime?: number) {
if (anchorStartTime === undefined) return this.props.Document;
@@ -179,21 +185,46 @@ export class CollectionStackedTimeline extends CollectionSubView<PanZoomDocument
return anchor;
}
- // play back the audio from time
@action
- playOnClick = (anchorDoc: Doc) => {
- this.props.playFrom(this.anchorStart(anchorDoc), this.anchorEnd(anchorDoc, this.props.duration));
+ playOnClick = (anchorDoc: Doc, clientX: number) => {
+ const seekTimeInSeconds = this.anchorStart(anchorDoc);
+ const endTime = this.anchorEnd(anchorDoc);
+ if (this.layoutDoc.autoPlay) {
+ if (this.props.playing()) this.props.Pause();
+ else this.props.playFrom(seekTimeInSeconds, endTime);
+ } else {
+ if (seekTimeInSeconds < NumCast(this.layoutDoc._currentTimecode) && endTime > NumCast(this.layoutDoc._currentTimecode)) {
+ if (!this.layoutDoc.autoPlay && this.props.playing()) {
+ this.props.Pause();
+ } else {
+ this.props.Play();
+ }
+ } else {
+ this.props.playFrom(seekTimeInSeconds, endTime);
+ }
+ }
return { select: true };
}
- // play back the audio from time
@action
- clickAnchor = (anchorDoc: Doc) => {
- if (this.props.Document.autoPlay) return this.playOnClick(anchorDoc);
- this.props.setTime(this.anchorStart(anchorDoc));
+ clickAnchor = (anchorDoc: Doc, clientX: number) => {
+ const seekTimeInSeconds = this.anchorStart(anchorDoc);
+ const endTime = this.anchorEnd(anchorDoc);
+ if (seekTimeInSeconds < NumCast(this.layoutDoc._currentTimecode) + 1e-4 && endTime > NumCast(this.layoutDoc._currentTimecode) - 1e-4) {
+ if (this.props.playing()) this.props.Pause();
+ else if (this.layoutDoc.autoPlay) this.props.Play();
+ else if (!this.layoutDoc.autoPlay) {
+ const rect = this._timeline?.getBoundingClientRect();
+ rect && this.props.setTime(this.toTimeline(clientX - rect.x, rect.width));
+ }
+ } else {
+ if (this.layoutDoc.autoPlay) this.props.playFrom(seekTimeInSeconds, endTime);
+ else this.props.setTime(seekTimeInSeconds);
+ }
return { select: true };
}
+
toTimeline = (screen_delta: number, width: number) => Math.max(0, Math.min(this.props.duration, screen_delta / width * this.props.duration));
// starting the drag event for anchor resizing
onPointerDown = (e: React.PointerEvent, m: Doc, left: boolean): void => {
@@ -263,6 +294,7 @@ export class CollectionStackedTimeline extends CollectionSubView<PanZoomDocument
onClick={script}
onDoubleClick={this.props.Document.autoPlay ? undefined : doublescript}
ignoreAutoHeight={false}
+ hideResizeHandles={true}
bringToFront={emptyFunction}
scriptContext={this} />
};
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 6619205af..8c3f0997f 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -931,11 +931,13 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
const layoutdoc = Doc.Layout(doc);
const savedState = { px: this.Document._panX, py: this.Document._panY, s: this.Document[this.scaleFieldKey], pt: this.Document._viewTransition };
- willZoom && this.setScaleToZoom(layoutdoc, scale);
- const newPanX = (NumCast(doc.x) + doc[WidthSym]() / 2) - (this.isAnnotationOverlay ? (Doc.NativeWidth(this.props.Document)) / 2 / this.zoomScaling() : 0);
- const newPanY = (NumCast(doc.y) + doc[HeightSym]() / 2) - (this.isAnnotationOverlay ? (Doc.NativeHeight(this.props.Document)) / 2 / this.zoomScaling() : 0);
const newState = HistoryUtil.getState();
- newState.initializers![this.Document[Id]] = { panX: newPanX, panY: newPanY };
+ if (!layoutdoc.annotationOn) {
+ willZoom && this.setScaleToZoom(layoutdoc, scale);
+ const newPanX = (NumCast(doc.x) + doc[WidthSym]() / 2) - (this.isAnnotationOverlay ? (Doc.NativeWidth(this.props.Document)) / 2 / this.zoomScaling() : 0);
+ const newPanY = (NumCast(doc.y) + doc[HeightSym]() / 2) - (this.isAnnotationOverlay ? (Doc.NativeHeight(this.props.Document)) / 2 / this.zoomScaling() : 0);
+ newState.initializers![this.Document[Id]] = { panX: newPanX, panY: newPanY };
+ }
HistoryUtil.pushState(newState);
if (DocListCast(this.dataDoc[this.props.fieldKey]).includes(doc)) {
@@ -1651,18 +1653,15 @@ class CollectionFreeFormViewPannableContents extends React.Component<CollectionF
const vfTop: number = NumCast(activeItem.presPinViewY);
const vfWidth: number = 100;
const vfHeight: number = 100;
- return (
- <>
- {!this.props.presPinView ? (null) : <div id="resizable" className="resizable" onPointerDown={this.onPointerDown} style={{ width: vfWidth, height: vfHeight, top: vfTop, left: vfLeft, position: 'absolute' }}>
- <div className='resizers' key={'resizer' + activeItem.id}>
- <div id="resizer-tl" className='resizer top-left' onPointerDown={this.onPointerDown}></div>
- <div id="resizer-tr" className='resizer top-right' onPointerDown={this.onPointerDown}></div>
- <div id="resizer-bl" className='resizer bottom-left' onPointerDown={this.onPointerDown}></div>
- <div id="resizer-br" className='resizer bottom-right' onPointerDown={this.onPointerDown}></div>
- </div>
- </div>}
- </>
- );
+ return !this.props.presPinView ? (null) :
+ <div key="resizable" className="resizable" onPointerDown={this.onPointerDown} style={{ width: vfWidth, height: vfHeight, top: vfTop, left: vfLeft, position: 'absolute' }}>
+ <div className='resizers' key={'resizer' + activeItem.id}>
+ <div className='resizer top-left' onPointerDown={this.onPointerDown}></div>
+ <div className='resizer top-right' onPointerDown={this.onPointerDown}></div>
+ <div className='resizer bottom-left' onPointerDown={this.onPointerDown}></div>
+ <div className='resizer bottom-right' onPointerDown={this.onPointerDown}></div>
+ </div>
+ </div>;
}
}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 6dc7a822c..b653b35bc 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -30,7 +30,6 @@ import { ContextMenuProps } from '../ContextMenuItem';
import { DocComponent } from "../DocComponent";
import { EditableView } from '../EditableView';
import { InkingStroke } from "../InkingStroke";
-import { InkStrokeProperties } from '../InkStrokeProperties';
import { StyleLayers, StyleProp } from "../StyleProvider";
import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView";
import { DocumentContentsView } from "./DocumentContentsView";
@@ -86,6 +85,7 @@ export interface DocumentViewSharedProps {
export interface DocumentViewProps extends DocumentViewSharedProps {
// properties specific to DocumentViews but not to FieldView
freezeDimensions?: boolean;
+ hideResizeHandles?: boolean; // whether to suppress DocumentDecorations when this document is selected
hideTitle?: boolean; // forces suppression of title. e.g, treeView document labels suppress titles in case they are globally active via settings
treeViewDoc?: Doc;
contentPointerEvents?: string; // pointer events allowed for content of a document view. eg. set to "none" in menuSidebar for sharedDocs so that you can select a document, but not interact with its contents
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 62e497e18..8d0283a12 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -417,15 +417,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
self._dragArray.splice(0, self._dragArray.length, ...dragViewCache);
self._eleArray.splice(0, self._eleArray.length, ...eleViewCache);
});
- const openInTab = () => {
- collectionDocView ? collectionDocView.props.addDocTab(targetDoc, "") : this.props.addDocTab(targetDoc, ":left");
+ const openInTab = (doc: Doc, finished?: () => void) => {
+ collectionDocView ? collectionDocView.props.addDocTab(doc, "") : this.props.addDocTab(doc, ":left");
this.layoutDoc.presCollection = targetDoc;
// this still needs some fixing
setTimeout(resetSelection, 500);
+ doc !== targetDoc && setTimeout(() => finished?.(), 100); /// give it some time to create the targetDoc if we're opening up its context
};
// If openDocument is selected then it should open the document for the user
if (activeItem.openDocument) {
- openInTab();
+ openInTab(targetDoc);
} else if (curDoc.presMovement === PresMovement.Pan && targetDoc) {
await DocumentManager.Instance.jumpToDocument(targetDoc, false, openInTab, srcContext, undefined, undefined, undefined, includesDoc || tab ? undefined : resetSelection); // documents open in new tab instead of on right
} else if ((curDoc.presMovement === PresMovement.Zoom || curDoc.presMovement === PresMovement.Jump) && targetDoc) {
diff --git a/src/client/views/nodes/VideoBox.scss b/src/client/views/nodes/VideoBox.scss
index 19f605278..ac4d64f12 100644
--- a/src/client/views/nodes/VideoBox.scss
+++ b/src/client/views/nodes/VideoBox.scss
@@ -183,14 +183,15 @@
pointer-events:all;
}
-.timeline-button {
+.videoBox-timelineButton {
position: absolute;
display: flex;
align-items: center;
z-index: 1010;
- bottom: 35px;
- right: 235px;
+ bottom: 5px;
+ right: 5px;
color: white;
+ cursor: pointer;
background: dimgrey;
width: 20px;
height: 20px;
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index bfac7dc1c..506ba8c49 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -55,16 +55,17 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
@observable _marqueeing: number[] | undefined;
@observable _savedAnnotations: Dictionary<number, HTMLDivElement[]> = new Dictionary<number, HTMLDivElement[]>();
@observable _screenCapture = false;
- @observable _visible: boolean = false;
+ @observable _clicking = false;
@observable _forceCreateYouTubeIFrame = false;
@observable _playTimer?: NodeJS.Timeout = undefined;
@observable _fullScreen = false;
@observable _playing = false;
@computed get links() { return DocListCast(this.dataDoc.links); }
- @computed get heightPercent() { return this.layoutDoc._timelineShow ? NumCast(this.layoutDoc._videoTimelineHeightPercent, VideoBox.heightPercent) : 100; }
+ @computed get heightPercent() { return NumCast(this.layoutDoc._timelineHeightPercent, 100); }
@computed get duration() { return NumCast(this.dataDoc[this.fieldKey + "-duration"]); }
@computed get anchorDocs() { return DocListCast(this.dataDoc[this.annotationKey + "-timeline"]).concat(DocListCast(this.dataDoc[this.annotationKey])); }
+ private get transition() { return this._clicking ? "left 0.5s, width 0.5s, height 0.5s" : ""; }
public get player(): HTMLVideoElement | null { return this._videoRef; }
constructor(props: Readonly<FieldViewProps>) {
@@ -310,8 +311,8 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
const field = Cast(this.dataDoc[this.fieldKey], VideoField);
const interactive = Doc.GetSelectedTool() !== InkTool.None || !this.props.isSelected() ? "" : "-interactive";
const style = "videoBox-content" + (this._fullScreen ? "-fullScreen" : "") + interactive;
- return !field ? <div>Loading</div> :
- <div className="container" style={{ pointerEvents: this._isChildActive || this.active() ? "all" : "none" }}>
+ return !field ? <div key="loading">Loading</div> :
+ <div className="container" key="container" style={{ pointerEvents: this._isChildActive || this.active() ? "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" }}
@@ -380,16 +381,11 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
<span>{"" + formatTime(curTime)}</span>
<span style={{ fontSize: 8 }}>{" " + Math.round((curTime - Math.trunc(curTime)) * 100)}</span>
</div>,
- <div className="videoBox-snapshot" key="snap" onPointerDown={this.onSnapshot} >
+ <div className="videoBox-snapshot" key="snap" onClick={this.onSnapshot} >
<FontAwesomeIcon icon="camera" size="lg" />
</div>,
- <div className="timeline-button" key="timeline-button" onPointerDown={action(e => this.layoutDoc._timelineShow = !this.layoutDoc._timelineShow)}
- style={{
- transform: `scale(${this.scaling()})`,
- right: this.scaling() * 10 - 10,
- bottom: this.scaling() * 10 - 10
- }}>
- <FontAwesomeIcon icon={this.layoutDoc._timelineShow ? "eye-slash" : "eye"} style={{ width: "100%" }} />
+ <div className="videoBox-timelineButton" key="timeline" onPointerDown={this.onTimelineHdlDown} style={{ bottom: `${100 - this.heightPercent}%` }}>
+ <FontAwesomeIcon icon={"eye"} size="lg" />
</div>,
VideoBox._showControls ? (null) : [
// <div className="control-background">
@@ -411,12 +407,29 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
e.preventDefault();
}
- onSnapshot = (e: React.PointerEvent) => {
+ onSnapshot = (e: React.MouseEvent) => {
this.Snapshot();
e.stopPropagation();
e.preventDefault();
}
+ onTimelineHdlDown = action((e: React.PointerEvent) => {
+ this._clicking = true;
+ setupMoveUpEvents(this, e,
+ action((e: PointerEvent) => {
+ this._clicking = false;
+ if (this.active()) {
+ const local = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY);
+ this.layoutDoc._timelineHeightPercent = Math.max(0, Math.min(100, local[1] / this.props.PanelHeight() * 100));
+ }
+ return false;
+ }), emptyFunction,
+ () => {
+ this.layoutDoc._timelineHeightPercent = this.heightPercent !== 100 ? 100 : VideoBox.heightPercent;
+ setTimeout(action(() => this._clicking = false), 500);
+ }, this.active(), this.active());
+ });
+
onResetDown = (e: React.PointerEvent) => {
setupMoveUpEvents(this, e, (e: PointerEvent) => {
this.Seek(Math.max(0, (this.layoutDoc._currentTimecode || 0) + Math.sign(e.movementX) * 0.0333));
@@ -483,7 +496,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
// returns the timeline
@computed get renderTimeline() {
- return <div style={{ width: "100%", height: `${100 - this.heightPercent}%`, position: "absolute" }}>
+ return <div style={{ width: "100%", transition: this.transition, height: `${100 - this.heightPercent}%`, position: "absolute" }}>
<CollectionStackedTimeline ref={this._stackedTimeline}
Document={this.props.Document}
fieldKey={this.annotationKey}
@@ -524,7 +537,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
contentFunc = () => [this.youtubeVideoId ? this.youtubeContent : this.content];
@computed get annotationLayer() {
- return <div className="imageBox-annotationLayer" style={{ height: `${this.heightPercent}%` }} ref={this._annotationLayer} />;
+ return <div className="imageBox-annotationLayer" style={{ transition: this.transition, height: `${this.heightPercent}%` }} ref={this._annotationLayer} />;
}
marqueeDown = action((e: React.PointerEvent) => {
@@ -553,7 +566,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
borderRadius
}} >
<div className="videoBox-viewer" onPointerDown={this.marqueeDown} >
- <div style={{ position: "absolute", width: this.panelWidth(), height: this.panelHeight(), top: 0, left: `${(100 - this.heightPercent) / 2}%` }}>
+ <div style={{ position: "absolute", transition: this.transition, width: this.panelWidth(), height: this.panelHeight(), top: 0, left: `${(100 - this.heightPercent) / 2}%` }}>
<CollectionFreeFormView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit}
fieldKey={this.annotationKey}
isAnnotationOverlay={true}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index e06a324d2..36d268fe9 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1302,6 +1302,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
this.endUndoTypingBatch();
this.unhighlightSearchTerms();
this._editorView?.destroy();
+ RichTextMenu.Instance?.TextView === this && RichTextMenu.Instance.updateMenu(undefined, undefined, undefined);
FormattedTextBoxComment.tooltip && (FormattedTextBoxComment.tooltip.style.display = "none");
}
diff --git a/src/client/views/nodes/formattedText/RichTextSchema.tsx b/src/client/views/nodes/formattedText/RichTextSchema.tsx
index d272b6b8c..abbb89780 100644
--- a/src/client/views/nodes/formattedText/RichTextSchema.tsx
+++ b/src/client/views/nodes/formattedText/RichTextSchema.tsx
@@ -136,6 +136,8 @@ export class DashDocView {
addDocument={returnFalse}
rootSelected={this._textBox.props.isSelected}
removeDocument={removeDoc}
+ layerProvider={this._textBox.props.layerProvider}
+ styleProvider={this._textBox.props.styleProvider}
ScreenToLocalTransform={this.getDocTransform}
addDocTab={this._textBox.props.addDocTab}
pinToPres={returnFalse}
@@ -143,7 +145,6 @@ export class DashDocView {
PanelWidth={finalLayout[WidthSym]}
PanelHeight={finalLayout[HeightSym]}
focus={this.outerFocus}
- styleProvider={DefaultStyleProvider}
parentActive={returnFalse}
whenActiveChanged={returnFalse}
bringToFront={emptyFunction}