From cc1d3df760efef033f5d5f03336cf7769b4dbfbf Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 9 Aug 2020 20:36:39 -0400 Subject: added '*' prefix for matching related families of fields in SchemaView & Search. --- src/client/views/nodes/formattedText/FormattedTextBox.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index b0bf54be6..7d4bd5dd3 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -250,8 +250,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp if (effectiveAcl === AclEdit || effectiveAcl === AclAdmin) { if (!this._applyingChange && json.replace(/"selection":.*/, "") !== curProto?.Data.replace(/"selection":.*/, "")) { this._applyingChange = true; - const lastmodified = "lastmodified"; - (curText !== Cast(this.dataDoc[this.fieldKey], RichTextField)?.Text) && (this.dataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now()))) && (this.dataDoc[lastmodified] = new DateField(new Date(Date.now()))); + (curText !== Cast(this.dataDoc[this.fieldKey], RichTextField)?.Text) && (this.dataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now()))); if ((!curTemp && !curProto) || curText || curLayout?.Data.includes("dash")) { // if no template, or there's text that didn't come from the layout template, write it to the document. (if this is driven by a template, then this overwrites the template text which is intended) if (json.replace(/"selection":.*/, "") !== curLayout?.Data.replace(/"selection":.*/, "")) { if (!this._pause && !this.layoutDoc._timeStampOnEnter) { -- cgit v1.2.3-70-g09d2 From 3ee0b9320fff9910c38bbef04e4866c6746316b8 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 9 Aug 2020 21:45:17 -0400 Subject: more audiobox cleanup. fixed dropping links onto audio box regions/labels. --- src/client/views/nodes/AudioBox.tsx | 125 +++++++++++++++--------------------- 1 file changed, 51 insertions(+), 74 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index bc89cb6f9..709422f35 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -25,6 +25,7 @@ import { List } from "../../../fields/List"; import { Scripting } from "../../util/Scripting"; import Waveform from "react-audio-waveform"; import axios from "axios"; +import { SnappingManager } from "../../util/SnappingManager"; const _global = (window /* browser */ || global /* node */) as any; declare class MediaRecorder { @@ -85,14 +86,21 @@ export class AudioBox extends ViewBoxAnnotatableComponent) { super(props); - // onClick play script - if (!AudioBox.RangeScript) { - AudioBox.RangeScript = ScriptField.MakeScript(`scriptContext.playFrom((this.audioStart), (this.audioEnd))`, { scriptContext: "any" })!; - } + // onClick play scripts + AudioBox.RangeScript = AudioBox.RangeScript || ScriptField.MakeScript(`scriptContext.playFrom((this.audioStart), (this.audioEnd))`, { scriptContext: "any" })!; + AudioBox.LabelScript = AudioBox.LabelScript || ScriptField.MakeScript(`scriptContext.playFrom((this.audioStart))`, { scriptContext: "any" })!; + } - if (!AudioBox.LabelScript) { - AudioBox.LabelScript = ScriptField.MakeScript(`scriptContext.playFrom((this.audioStart))`, { scriptContext: "any" })!; + getLinkData(l: Doc) { + let la1 = l.anchor1 as Doc; + let la2 = l.anchor2 as Doc; + let linkTime = NumCast(l.anchor2_timecode); + if (Doc.AreProtosEqual(la1, this.dataDoc)) { + la1 = l.anchor2 as Doc; + la2 = l.anchor1 as Doc; + linkTime = NumCast(l.anchor1_timecode); } + return { la1, la2, linkTime }; } componentWillUnmount() { @@ -110,7 +118,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent { if (scrollLinkId) { DocListCast(this.dataDoc.links).filter(l => l[Id] === scrollLinkId).map(l => { - const linkTime = Doc.AreProtosEqual(l.anchor1 as Doc, this.dataDoc) ? NumCast(l.anchor1_timecode) : NumCast(l.anchor2_timecode); + const { linkTime } = this.getLinkData(l); setTimeout(() => { this.playFromTime(linkTime); Doc.linkFollowHighlight(l); }, 250); }); Doc.SetInPlace(this.layoutDoc, "scrollToLinkID", undefined, false); @@ -124,17 +132,10 @@ export class AudioBox extends ViewBoxAnnotatableComponent { - let la1 = l.anchor1 as Doc; - let la2 = l.anchor2 as Doc; + DocListCast(this.dataDoc.links).map(l => { + let { la1, la2, linkTime } = this.getLinkData(l); if (la1 === sel || la2 === sel) { // if the selected document is linked to this audio - let linkTime = NumCast(l.anchor2_timecode); let endTime; - if (Doc.AreProtosEqual(la1, this.dataDoc)) { - la1 = l.anchor2 as Doc; - la2 = l.anchor1 as Doc; - linkTime = NumCast(l.anchor1_timecode); - } if (la2.audioStart) linkTime = NumCast(la2.audioStart); if (la1.audioStart) linkTime = NumCast(la1.audioStart); @@ -164,12 +165,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent this.dataDoc.duration = htmlEle.duration); DocListCast(this.dataDoc.links).map(l => { - let la1 = l.anchor1 as Doc; - let linkTime = NumCast(l.anchor2_timecode); - if (Doc.AreProtosEqual(la1, this.dataDoc)) { - linkTime = NumCast(l.anchor1_timecode); - la1 = l.anchor2 as Doc; - } + const { la1, linkTime } = this.getLinkData(l); if (linkTime > NumCast(this.layoutDoc.currentTimecode) && linkTime < htmlEle.currentTime) { Doc.linkFollowHighlight(la1); } @@ -349,47 +345,33 @@ export class AudioBox extends ViewBoxAnnotatableComponent screen_delta / rect.width * this.audioDuration; this._markerStart = this._markerEnd = toTimeline(e.clientX - rect.x); - setupMoveUpEvents(this, e, action((e: PointerEvent) => { - this._visible = true; - this._markerEnd = toTimeline(e.clientX - rect.x); - if (this._markerEnd < this._markerStart) { - const tmp = this._markerStart; - this._markerStart = this._markerEnd; - this._markerEnd = tmp; - } - return false; - }), - action((e: PointerEvent, movement: number[]) => { - if (Math.abs(movement[0]) > 15) { - this.createNewMarker(this._markerStart, toTimeline(e.clientX - rect.x)); + setupMoveUpEvents(this, e, + action((e: PointerEvent) => { + this._visible = true; + this._markerEnd = toTimeline(e.clientX - rect.x); + if (this._markerEnd < this._markerStart) { + const tmp = this._markerStart; + this._markerStart = this._markerEnd; + this._markerEnd = tmp; } + return false; + }), + action((e: PointerEvent, movement: number[]) => { + (Math.abs(movement[0]) > 15) && this.createMarker(this._markerStart, toTimeline(e.clientX - rect.x)); this._visible = false; }), - emptyFunction); - } - // returns the selection container - @computed get container() { - return
; + (e: PointerEvent) => e.shiftKey && this.createMarker(this._ele!.currentTime) + ); } - // creates a new marker @action - createNewMarker(audioStart: number, audioEnd: number) { - const newMarker = Docs.Create.LabelDocument({ - title: ComputedField.MakeFunction(`formatToTime(self.audioStart) + "-" + formatToTime(self.audioEnd)`) as any, isLabel: false, + createMarker(audioStart: number, audioEnd?: number) { + const marker = Docs.Create.LabelDocument({ + title: ComputedField.MakeFunction(`formatToTime(self.audioStart) + "-" + formatToTime(self.audioEnd)`) as any, isLabel: audioEnd === undefined, useLinkSmallAnchor: true, hideLinkButton: true, audioStart, audioEnd, _showSidebar: false, _autoHeight: true, annotationOn: this.props.Document }); - this.addMark(newMarker); - } - - // adds an annotation marker or label - @action - addMark(marker: Doc) { - marker.data = ""; + marker.data = ""; // clears out the label's text so that only its border will display if (this.dataDoc[this.annotationKey]) { this.dataDoc[this.annotationKey].push(marker); } else { @@ -403,10 +385,11 @@ export class AudioBox extends ViewBoxAnnotatableComponent screen_delta / rect.width * this.audioDuration; - setupMoveUpEvents(this, e, () => { - this.changeMarker(this._currMarker, toTimeline(e.clientX - rect.x)); - return false; - }, + setupMoveUpEvents(this, e, + () => { + this.changeMarker(this._currMarker, toTimeline(e.clientX - rect.x)); + return false; + }, () => this._ele!.currentTime = this.layoutDoc.currentTimecode = toTimeline(e.clientX - rect.x), emptyFunction); } @@ -462,6 +445,13 @@ export class AudioBox extends ViewBoxAnnotatableComponent; + } + // returns the audio waveform @computed get waveform() { return AudioBox.LabelScript; render() { - const interactive = this.active() ? "-interactive" : ""; + const interactive = SnappingManager.GetIsDragging() || this.active() ? "-interactive" : ""; this._first = true; // for indicating the first marker that is rendered this.path && this._buckets.length !== 100 ? this.peaks : null; // render waveform if audio is done recording const markerDoc = (mark: Doc, script: undefined | (() => ScriptField)) => { @@ -562,8 +552,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent
{ e.stopPropagation(); e.preventDefault(); }} onPointerDown={e => { - e.stopPropagation(); - e.preventDefault(); if (e.button === 0 && !e.ctrlKey) { const rect = (e.target as any).getBoundingClientRect(); @@ -575,9 +563,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent
{this.waveform} @@ -605,15 +590,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent )} {DocListCast(this.dataDoc.links).map((l, i) => { - let la1 = l.anchor1 as Doc; - let la2 = l.anchor2 as Doc; - let linkTime = NumCast(l.anchor2_timecode); - if (Doc.AreProtosEqual(la1, this.dataDoc)) { - la1 = l.anchor2 as Doc; - la2 = l.anchor1 as Doc; - linkTime = NumCast(l.anchor1_timecode); - } - + let { la1, la2, linkTime } = this.getLinkData(l); if (la2.audioStart && !la2.audioEnd) { linkTime = NumCast(la2.audioStart); } @@ -639,7 +616,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent { if (e.button === 0 && !e.ctrlKey) { this.playFrom(linkTime); e.stopPropagation(); e.preventDefault(); } }} />
; })} - {this._visible ? this.container : null} + {this._visible ? this.selectionContainer : null}
{ e.stopPropagation(); e.preventDefault(); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / this.audioDuration * 100}%`, pointerEvents: "none" }} /> {this.audio} -- cgit v1.2.3-70-g09d2 From dc0ffc050b5b11e345245927f3d8a813937e588d Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 9 Aug 2020 22:48:26 -0400 Subject: starting to fix link following behavior to audio regions. --- src/client/util/DocumentManager.ts | 2 +- src/client/views/linking/LinkEditor.tsx | 6 +- src/client/views/nodes/AudioBox.scss | 5 + src/client/views/nodes/AudioBox.tsx | 256 ++++++++++++++++---------------- 4 files changed, 140 insertions(+), 129 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 523dbfca0..bd57e7f48 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -152,7 +152,7 @@ export class DocumentManager { const first = getFirstDocView(annotatedDoc); if (first) { annotatedDoc = first.props.Document; - docView?.props.focus(annotatedDoc, false); + first.props.focus(annotatedDoc, false); } } if (docView) { // we have a docView already and aren't forced to create a new one ... just focus on the document. TODO move into view if necessary otherwise just highlight? diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx index 5832a2181..3ef391a5d 100644 --- a/src/client/views/linking/LinkEditor.tsx +++ b/src/client/views/linking/LinkEditor.tsx @@ -355,11 +355,11 @@ export class LinkEditor extends React.Component { this.openDropdown = !this.openDropdown; } - @undoBatch @action - changeFollowBehavior = (follow: string) => { + @undoBatch + changeFollowBehavior = action((follow: string) => { this.openDropdown = false; Doc.GetProto(this.props.linkDoc).followLinkLocation = follow; - } + }) @computed get followingDropdown() { diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss index 0d787d9af..c80e3af24 100644 --- a/src/client/views/nodes/AudioBox.scss +++ b/src/client/views/nodes/AudioBox.scss @@ -8,6 +8,11 @@ position: relative; cursor: default; + .audiobox-inner { + width:100%; + height: 100%; + } + .audiobox-buttons { display: flex; width: 100%; diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 709422f35..0ea624edf 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -128,37 +128,41 @@ export class AudioBox extends ViewBoxAnnotatableComponent SelectionManager.SelectedDocuments(), selected => { - const sel = selected.length ? selected[0].props.Document : undefined; - let link; - if (sel) { - // for determining if the link is created after recording (since it will use linkTime rather than creation date) - DocListCast(this.dataDoc.links).map(l => { - let { la1, la2, linkTime } = this.getLinkData(l); - if (la1 === sel || la2 === sel) { // if the selected document is linked to this audio - let endTime; - if (la2.audioStart) linkTime = NumCast(la2.audioStart); - if (la1.audioStart) linkTime = NumCast(la1.audioStart); - - if (la1.audioEnd) endTime = NumCast(la1.audioEnd); - if (la2.audioEnd) endTime = NumCast(la2.audioEnd); - - if (linkTime) { - link = true; - this.layoutDoc.playOnSelect && this.recordingStart && sel && !Doc.AreProtosEqual(sel, this.props.Document) && (endTime ? this.playFrom(linkTime, endTime) : this.playFrom(linkTime)); - } - } - }); - } - - // for links created during recording - if (!link) { - this.layoutDoc.playOnSelect && this.recordingStart && sel && sel.creationDate && !Doc.AreProtosEqual(sel, this.props.Document) && this.playFromTime(DateCast(sel.creationDate).date.getTime()); - this.layoutDoc.playOnSelect && this.recordingStart && !sel && this.pause(); + if (this.layoutDoc.playOnSelect) { + const sel = selected.length ? selected[0].props.Document : undefined; + const link = sel && DocListCast(this.dataDoc.links).forEach(l => (l.anchor1 === sel || l.anchor2 === sel) && this.playLink(l), false); + // for links created during recording + if (!link) { + this.layoutDoc.playOnSelect && this.recordingStart && sel && sel.creationDate && !Doc.AreProtosEqual(sel, this.props.Document) && this.playFromTime(DateCast(sel.creationDate).date.getTime()); + this.layoutDoc.playOnSelect && this.recordingStart && !sel && this.pause(); + } } }); this._scrubbingDisposer = reaction(() => AudioBox._scrubTime, (time) => this.layoutDoc.playOnSelect && this.playFromTime(AudioBox._scrubTime)); } + playLink = (doc: Doc) => { + let link = false; + !Doc.AreProtosEqual(doc, this.props.Document) && DocListCast(this.props.Document.links).forEach(l => { + if (l.anchor1 === doc || l.anchor2 === doc) { + const { la1, la2, linkTime } = this.getLinkData(l); + let startTime = linkTime; + if (la2.audioStart) startTime = NumCast(la2.audioStart); + if (la1.audioStart) startTime = NumCast(la1.audioStart); + + let endTime; + if (la1.audioEnd) endTime = NumCast(la1.audioEnd); + if (la2.audioEnd) endTime = NumCast(la2.audioEnd); + + if (startTime) { + link = true; + this.recordingStart && (endTime ? this.playFrom(startTime, endTime) : this.playFrom(startTime)); + } + } + }); + return link; + } + // for updating the timecode timecodeChanged = () => { const htmlEle = this._ele; @@ -511,6 +515,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent ScriptField)) => { return this.playLink(mark)} pointerEvents={true} NativeHeight={returnZero} NativeWidth={returnZero} @@ -524,112 +529,113 @@ export class AudioBox extends ViewBoxAnnotatableComponent; }; - return
- {!this.path ? -
-
- -
- {this.audioState === "recording" ? -
e.stopPropagation()}> -
- -
-
- -
-
{formatTime(Math.round(NumCast(this.layoutDoc.currentTimecode)))}
+ return
+
+ {!this.path ? +
+
+
- : - } -
: -
-
-
-
-
{ e.stopPropagation(); e.preventDefault(); }} - onPointerDown={e => { - if (e.button === 0 && !e.ctrlKey) { - const rect = (e.target as any).getBoundingClientRect(); - - if (e.target !== this._audioRef.current) { - const wasPaused = this.audioState === "paused"; - this._ele!.currentTime = this.layoutDoc.currentTimecode = (e.clientX - rect.x) / rect.width * this.audioDuration; - wasPaused && this.pause(); +
: +
+
+
+
+
{ e.stopPropagation(); e.preventDefault(); }} + onPointerDown={e => { + if (e.button === 0 && !e.ctrlKey) { + const rect = (e.target as any).getBoundingClientRect(); + + if (e.target !== this._audioRef.current) { + const wasPaused = this.audioState === "paused"; + this._ele!.currentTime = this.layoutDoc.currentTimecode = (e.clientX - rect.x) / rect.width * this.audioDuration; + wasPaused && this.pause(); + } + + this.onPointerDownTimeline(e); + } + }}> +
+ {this.waveform} +
+ {DocListCast(this.dataDoc[this.annotationKey]).map((m, i) => + (!m.isLabel) ? + (this.layoutDoc.hideMarkers) ? (null) : +
{ this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)); e.stopPropagation(); }} > +
this.onPointerDown(e, m, true)}>
+ {markerDoc(m, this.rangeScript)} +
this.onPointerDown(e, m, false)}>
+
+ : + (this.layoutDoc.hideLabels) ? (null) : +
+ {markerDoc(m, this.labelScript)} +
+ )} + {DocListCast(this.dataDoc.links).map((l, i) => { + const { la1, la2, linkTime } = this.getLinkData(l); + let startTime = linkTime; + if (la2.audioStart && !la2.audioEnd) { + startTime = NumCast(la2.audioStart); } - this.onPointerDownTimeline(e); - } - }}> -
- {this.waveform} + return !linkTime ? (null) : +
e.stopPropagation()}> + +
Doc.linkFollowHighlight(la1)} + onPointerDown={e => { if (e.button === 0 && !e.ctrlKey) { this.playFrom(startTime); e.stopPropagation(); e.preventDefault(); } }} /> +
; + })} + {this._visible ? this.selectionContainer : null} + +
{ e.stopPropagation(); e.preventDefault(); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / this.audioDuration * 100}%`, pointerEvents: "none" }} /> + {this.audio} +
+
+ {formatTime(Math.round(NumCast(this.layoutDoc.currentTimecode)))} +
+
+ {formatTime(Math.round(this.audioDuration))}
- {DocListCast(this.dataDoc[this.annotationKey]).map((m, i) => - (!m.isLabel) ? - (this.layoutDoc.hideMarkers) ? (null) : -
{ this.playFrom(NumCast(m.audioStart), NumCast(m.audioEnd)); e.stopPropagation(); }} > -
this.onPointerDown(e, m, true)}>
- {markerDoc(m, this.rangeScript)} -
this.onPointerDown(e, m, false)}>
-
- : - (this.layoutDoc.hideLabels) ? (null) : -
- {markerDoc(m, this.labelScript)} -
- )} - {DocListCast(this.dataDoc.links).map((l, i) => { - let { la1, la2, linkTime } = this.getLinkData(l); - if (la2.audioStart && !la2.audioEnd) { - linkTime = NumCast(la2.audioStart); - } - - return !linkTime ? (null) : -
e.stopPropagation()}> - -
Doc.linkFollowHighlight(la1)} - onPointerDown={e => { if (e.button === 0 && !e.ctrlKey) { this.playFrom(linkTime); e.stopPropagation(); e.preventDefault(); } }} /> -
; - })} - {this._visible ? this.selectionContainer : null} - -
{ e.stopPropagation(); e.preventDefault(); }} style={{ left: `${NumCast(this.layoutDoc.currentTimecode) / this.audioDuration * 100}%`, pointerEvents: "none" }} /> - {this.audio} -
-
- {formatTime(Math.round(NumCast(this.layoutDoc.currentTimecode)))} -
-
- {formatTime(Math.round(this.audioDuration))}
-
- } + }
; } } -- cgit v1.2.3-70-g09d2 From 1d2851b237fd41f8a8726244b095986699f513a5 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 9 Aug 2020 23:09:49 -0400 Subject: fixed playing audio on link follow when audio opens on right or in tab --- src/client/views/linking/LinkMenuItem.tsx | 9 ++++++++- src/client/views/nodes/AudioBox.tsx | 4 +++- 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx index b95fccf2a..21c666a4d 100644 --- a/src/client/views/linking/LinkMenuItem.tsx +++ b/src/client/views/linking/LinkMenuItem.tsx @@ -162,7 +162,14 @@ export class LinkMenuItem extends React.Component { } if (linkDoc.followLinkLocation && linkDoc.followLinkLocation !== "Default") { - this.props.addDocTab(this.props.destinationDoc, StrCast(linkDoc.followLinkLocation)); + const annotationOn = this.props.destinationDoc.annotationOn as Doc; + this.props.addDocTab(annotationOn instanceof Doc ? annotationOn : this.props.destinationDoc, StrCast(linkDoc.followLinkLocation)); + if (annotationOn) { + setTimeout(() => { + const dv = DocumentManager.Instance.getFirstDocumentView(this.props.destinationDoc); + dv?.props.focus(this.props.destinationDoc, false); + }); + } } else { DocumentManager.Instance.FollowLink(this.props.linkDoc, this.props.sourceDoc, doc => this.props.addDocTab(doc, "onRight"), false); } diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 0ea624edf..d689aeadc 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -195,7 +195,9 @@ export class AudioBox extends ViewBoxAnnotatableComponent this.playFrom(seekTimeInSeconds, endTime), 500); + } else if (this._ele && AudioBox.Enabled) { if (seekTimeInSeconds < 0) { if (seekTimeInSeconds > -1) { setTimeout(() => this.playFrom(0), -seekTimeInSeconds * 1000); -- cgit v1.2.3-70-g09d2 From b096129d54238bc4cea735cd2db8e5f3e94613b7 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 9 Aug 2020 23:23:06 -0400 Subject: fixed playing audio links on select. --- src/client/views/nodes/AudioBox.tsx | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index d689aeadc..289388320 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -128,14 +128,12 @@ export class AudioBox extends ViewBoxAnnotatableComponent SelectionManager.SelectedDocuments(), selected => { - if (this.layoutDoc.playOnSelect) { - const sel = selected.length ? selected[0].props.Document : undefined; - const link = sel && DocListCast(this.dataDoc.links).forEach(l => (l.anchor1 === sel || l.anchor2 === sel) && this.playLink(l), false); - // for links created during recording - if (!link) { - this.layoutDoc.playOnSelect && this.recordingStart && sel && sel.creationDate && !Doc.AreProtosEqual(sel, this.props.Document) && this.playFromTime(DateCast(sel.creationDate).date.getTime()); - this.layoutDoc.playOnSelect && this.recordingStart && !sel && this.pause(); - } + const sel = selected.length ? selected[0].props.Document : undefined; + const link = sel && DocListCast(this.dataDoc.links).forEach(l => (l.anchor1 === sel || l.anchor2 === sel) && this.playLink(sel), false); + // for links created during recording + if (!link) { + this.layoutDoc.playOnSelect && this.recordingStart && sel && sel.creationDate && !Doc.AreProtosEqual(sel, this.props.Document) && this.playFromTime(DateCast(sel.creationDate).date.getTime()); + this.layoutDoc.playOnSelect && this.recordingStart && !sel && this.pause(); } }); this._scrubbingDisposer = reaction(() => AudioBox._scrubTime, (time) => this.layoutDoc.playOnSelect && this.playFromTime(AudioBox._scrubTime)); -- cgit v1.2.3-70-g09d2 From 03ae3477dac354eff9178dac701ee40e394434c9 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 10 Aug 2020 10:37:07 -0400 Subject: fixed issues with presentationBox grabbing all keyboard events and preventing title edits among others. fixed runtime errors. fixed groupManager to open again. --- src/client/util/SettingsManager.tsx | 2 +- src/client/views/GlobalKeyHandler.ts | 4 +++- .../views/collections/CollectionDockingView.tsx | 12 +++++++---- .../collectionFreeForm/MarqueeOptionsMenu.tsx | 12 ++++------- src/client/views/nodes/PresBox.tsx | 24 ++++++++++++++++++---- 5 files changed, 36 insertions(+), 18 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx index 513cece40..e3b91925a 100644 --- a/src/client/util/SettingsManager.tsx +++ b/src/client/util/SettingsManager.tsx @@ -146,7 +146,7 @@ export default class SettingsManager extends React.Component<{}> { @computed get accountsContent() { return
- +
; } diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts index 0ea02e3cb..182f6397c 100644 --- a/src/client/views/GlobalKeyHandler.ts +++ b/src/client/views/GlobalKeyHandler.ts @@ -108,7 +108,9 @@ export default class KeyManager { GoogleAuthenticationManager.Instance.cancel(); SharingManager.Instance.close(); GroupManager.Instance.close(); - CollectionFreeFormViewChrome.Instance.clearKeep(); + CollectionFreeFormViewChrome.Instance?.clearKeep(); + window.getSelection()?.empty(); + document.body.focus(); break; case "delete": case "backspace": diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 7e096fa37..0c93b4e63 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -513,7 +513,11 @@ export class CollectionDockingView extends React.Component tab.titleElement[0].focus(); + tab.titleElement[0].onclick = (e: any) => { + if (Date.now() - tab.titleElement[0].lastClick < 1000) tab.titleElement[0].select(); + tab.titleElement[0].lastClick = Date.now(); + tab.titleElement[0].focus(); + } tab.titleElement[0].onchange = (e: any) => { tab.titleElement[0].size = e.currentTarget.value.length + 1; Doc.GetProto(doc).title = e.currentTarget.value, true; @@ -691,8 +695,8 @@ export class DockedFrameRenderer extends React.Component { return (this.props as any).glContainer.parent.parent; } get _tab(): any { - const tab = (this.props as any).glContainer.tab.element[0] as HTMLElement; - return tab.getElementsByClassName("lm_title")?.[0]; + const tab = (this.props as any).glContainer.tab?.element[0] as HTMLElement; + return tab?.getElementsByClassName("lm_title")?.[0]; } constructor(props: any) { super(props); @@ -757,7 +761,7 @@ export class DockedFrameRenderer extends React.Component { this._tabReaction = reaction(() => ({ views: SelectionManager.SelectedDocuments(), color: StrCast(this._document?._backgroundColor, "white") }), (data) => { const selected = data.views.some(v => Doc.AreProtosEqual(v.props.Document, this._document)); - this._tab.style.backgroundColor = selected ? data.color : ""; + this._tab && (this._tab.style.backgroundColor = selected ? data.color : ""); } ); } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx index d27ca7c3a..f1df7998b 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx @@ -25,34 +25,30 @@ export default class MarqueeOptionsMenu extends AntimodeMenu { render() { const buttons = [ -
Create a Collection
} placement="bottom"> +
Create a Collection
} placement="bottom">
, -
Summarize Documents
} placement="bottom"> +
Summarize Documents
} placement="bottom">
, -
Delete Documents
} placement="bottom"> +
Delete Documents
} placement="bottom">
, -
Change to Text
} placement="bottom"> +
Change to Text
} placement="bottom"> diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index b7af4683e..849fc4076 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -83,6 +83,7 @@ export class PresBox extends ViewBoxBaseComponent } @computed get isPres(): boolean { if (this.selectedDoc?.type === DocumentType.PRES) { + document.removeEventListener("keydown", this.keyEvents, true); document.addEventListener("keydown", this.keyEvents, true); return true; } else { @@ -91,6 +92,9 @@ export class PresBox extends ViewBoxBaseComponent } } @computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; } + componentWillUnmount() { + document.removeEventListener("keydown", this.keyEvents, true); + } componentDidMount() { this.rootDoc.presBox = this.rootDoc; @@ -517,29 +521,41 @@ export class PresBox extends ViewBoxBaseComponent // Key for when the presentaiton is active (according to Selection Manager) @action keyEvents = (e: KeyboardEvent) => { - e.stopPropagation(); - e.preventDefault(); - + let handled = false; + const anchorNode = document.activeElement as HTMLDivElement; + if (anchorNode && anchorNode.className?.includes("lm_title")) return; if (e.keyCode === 27) { // Escape key if (this.layoutDoc.presStatus === "edit") this._selectedArray = []; else this.layoutDoc.presStatus = "edit"; + handled = true; } if ((e.metaKey || e.altKey) && e.keyCode === 65) { // Ctrl-A to select all - if (this.layoutDoc.presStatus === "edit") this._selectedArray = this.childDocs; + if (this.layoutDoc.presStatus === "edit") { + this._selectedArray = this.childDocs; + handled = true; + } } if (e.keyCode === 37 || e.keyCode === 38) { // left(37) / a(65) / up(38) to go back this.back(); + handled = true; } if (e.keyCode === 39 || e.keyCode === 40) { // right (39) / d(68) / down(40) to go to next this.next(); + handled = true; } if (e.keyCode === 32) { // spacebar to 'present' or autoplay if (this.layoutDoc.presStatus !== "edit") this.startAutoPres(0); else this.layoutDoc.presStatus = "manual"; + handled = true; } if (e.keyCode === 8) { // delete selected items if (this.layoutDoc.presStatus === "edit") { this._selectedArray.forEach((doc, i) => { this.removeDocument(doc); }); + handled = true; } } + if (handled) { + e.stopPropagation(); + e.preventDefault(); + } } /** -- cgit v1.2.3-70-g09d2