From 6efc3545ccca2bcb0aaf219b2a9ff1c4f06e9e91 Mon Sep 17 00:00:00 2001 From: geireann <60007097+geireann@users.noreply.github.com> Date: Wed, 25 Nov 2020 00:10:33 +0800 Subject: loader --- src/client/views/MainView.tsx | 7 +++++++ src/client/views/collections/CollectionStackingView.tsx | 6 +++--- src/client/views/nodes/PresBox.scss | 10 +++++----- src/client/views/nodes/PresBox.tsx | 1 + 4 files changed, 16 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 452ce61ff..2100f1458 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -85,6 +85,13 @@ export class MainView extends React.Component { componentDidMount() { document.getElementById("root")?.addEventListener("scroll", e => ((ele) => ele.scrollLeft = ele.scrollTop = 0)(document.getElementById("root")!)); + const ele = document.getElementById("loader"); + if (ele) { + setTimeout(() => { + // remove from DOM + ele.outerHTML = ''; + }, 0); + } new InkStrokeProperties(); this._sidebarContent.proto = undefined; DocServer.setPlaygroundFields(["x", "y", "dataTransition", "_delayAutoHeight", "_autoHeight", "_showSidebar", "_sidebarWidthPercent", "_width", "_height", "_viewTransition", "_panX", "_panY", "_viewScale", "_scrollY", "_scrollTop", "hidden", "_curPage", "_viewType", "_chromeStatus"]); // can play with these fields on someone else's diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 97eacaeab..d86a6816d 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -290,11 +290,11 @@ export class CollectionStackingView extends CollectionSubView (pos[axis] + pos1[axis]) / 2 ? 1 : 0; } }); - const oldDocs = this.childDocs.length; + // const oldDocs = this.childDocs.length; if (super.onInternalDrop(e, de)) { - const newDocs = this.childDocs.slice().filter((d: Doc, ind: number) => ind >= oldDocs); + // const newDocs = this.childDocs.slice().filter((d: Doc, ind: number) => ind >= oldDocs); - //de.complete.docDragData.droppedDocuments; + const newDocs = de.complete.docDragData.droppedDocuments; const docs = this.childDocList; DragManager.docsBeingDragged = []; if (docs && newDocs.length) { diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss index de2aee8fa..56b3b0593 100644 --- a/src/client/views/nodes/PresBox.scss +++ b/src/client/views/nodes/PresBox.scss @@ -420,20 +420,20 @@ $light-background: #ececec; background-color: #ececec; border: 1px solid #9f9f9f; grid-template-rows: max-content; - + .frameList-header { display: grid; width: 100%; height: 20px; background-color: #9f9f9f; - + .frameList-headerButtons { display: flex; grid-column: 7; width: 60px; justify-self: right; justify-content: flex-end; - + .headerButton { cursor: pointer; position: relative; @@ -452,7 +452,7 @@ $light-background: #ececec; transition: 0.2s; margin-right: 3px; } - + .headerButton:hover { background-color: rgba(0, 0, 0, 1); transform: scale(1.15); @@ -1061,7 +1061,7 @@ $light-background: #ececec; background-color: #5a5a5a; } - + } // .miniPres { diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 683cb938a..e1f93c991 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -610,6 +610,7 @@ export class PresBox extends ViewBoxBaseComponent addDocumentFilter = (doc: Doc | Doc[]) => { const docs = doc instanceof Doc ? [doc] : doc; docs.forEach((doc, i) => { + if (doc.presentationTargetDoc) return true; if (doc.type === DocumentType.LABEL) { const audio = Cast(doc.annotationOn, Doc, null); if (audio) { -- cgit v1.2.3-70-g09d2 From e58f51695864c4d3069d8aae25582b9a9a518799 Mon Sep 17 00:00:00 2001 From: geireann <60007097+geireann@users.noreply.github.com> Date: Sat, 28 Nov 2020 05:02:01 +0800 Subject: audio in pres updates + pre-loader --- deploy/index.html | 75 +++++++++++++++++----- src/client/util/CurrentUserUtils.ts | 2 +- src/client/views/PropertiesView.tsx | 6 +- src/client/views/collections/TabDocView.tsx | 4 +- src/client/views/nodes/AudioBox.tsx | 31 +++++++-- src/client/views/nodes/PresBox.tsx | 26 ++++---- .../views/presentationview/PresElementBox.tsx | 2 + 7 files changed, 106 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/deploy/index.html b/deploy/index.html index 7b68af2ef..af67ac301 100644 --- a/deploy/index.html +++ b/deploy/index.html @@ -4,29 +4,74 @@ Dash Web - - +
- - - - - + +
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 202cd7b1f..4b046bb1a 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -63,7 +63,7 @@ export class CurrentUserUtils { [this.ficon({ ignoreClick: true, icon: "mobile", - backgroundColor: "rgba(0,0,0,0)" + backgroundColor: "transparent" }), this.mobileTextContainer({}, [this.mobileButtonText({}, "NEW MOBILE BUTTON"), this.mobileButtonInfo({}, "You can customize this button and make it your own.")])]); diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 245e612b3..97bca110b 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -992,7 +992,7 @@ export class PropertiesView extends React.Component {
Presentation
-
+
{this.editableTitle}
@@ -1029,7 +1029,7 @@ export class PropertiesView extends React.Component { {PresBox.Instance.progressivizeDropdown}
: null}
} */} - {/* {!selectedItem || (!scrollable && !pannable) ? (null) :
+ {!selectedItem ? (null) :
{ this.openSlideOptions = !this.openSlideOptions; })} style={{ backgroundColor: this.openSlideOptions ? "black" : "" }}> @@ -1041,7 +1041,7 @@ export class PropertiesView extends React.Component { {this.openSlideOptions ?
{PresBox.Instance.optionsDropdown}
: null} -
} */} +
} {/*
{ this.openAddSlide = !this.openAddSlide; })} diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 7f8f57088..4c0073dcc 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -442,8 +442,8 @@ export class TabDocView extends React.Component { let docColor = StrCast(doc?._backgroundColor, StrCast(doc?.backgroundColor)); if (!docColor) { switch (doc?.type) { - case DocumentType.PRESELEMENT: docColor = TabDocView.darkScheme ? "dimgrey" : ""; break; - case DocumentType.PRES: docColor = TabDocView.darkScheme ? "#3e3e3e" : "black"; break; + case DocumentType.PRESELEMENT: docColor = TabDocView.darkScheme ? "" : ""; break; + case DocumentType.PRES: docColor = TabDocView.darkScheme ? "#3e3e3e" : "white"; break; case DocumentType.FONTICON: docColor = "black"; break; case DocumentType.RTF: docColor = TabDocView.darkScheme ? "#2d2d2d" : "#f1efeb"; case DocumentType.LABEL: diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 4f6c5cebe..1bdba7f9e 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -27,6 +27,8 @@ import Waveform from "react-audio-waveform"; import axios from "axios"; import { SnappingManager } from "../../util/SnappingManager"; import { CurrentUserUtils } from "../../util/CurrentUserUtils"; +import { LinkDocPreview } from "./LinkDocPreview"; +import { FormattedTextBoxComment } from "./formattedText/FormattedTextBoxComment"; declare class MediaRecorder { // whatever MediaRecorder has @@ -49,6 +51,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent this.layoutDoc.scrollToLinkID, + this._disposers.linkPlay = reaction(() => this.layoutDoc.scrollToLinkID, scrollLinkId => { if (scrollLinkId) { DocListCast(this.dataDoc.links).filter(l => l[Id] === scrollLinkId).map(l => { @@ -130,7 +134,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent SelectionManager.SelectedDocuments(), + this._disposers.reaction = reaction(() => SelectionManager.SelectedDocuments(), selected => { const sel = selected.length ? selected[0].props.Document : undefined; let link; @@ -145,7 +149,22 @@ export class AudioBox extends ViewBoxAnnotatableComponent AudioBox._scrubTime, (time) => this.layoutDoc.playOnSelect && this.playFromTime(AudioBox._scrubTime)); + this._disposers.scrubbing = reaction(() => AudioBox._scrubTime, (time) => this.layoutDoc.playOnSelect && this.playFromTime(AudioBox._scrubTime)); + + this._disposers._audioStart = reaction( + () => this.Document._audioStart, + (audioStart) => { + if (audioStart !== undefined) { + if (this.props.renderDepth !== -1 && !LinkDocPreview.TargetDoc && !FormattedTextBoxComment.linkDoc) { + const delay = this._audioRef.current ? 0 : 250; // wait for mainCont and try again to play + const startTime: number = NumCast(this.Document._audioStart); + setTimeout(() => this._audioRef.current && this.playFrom(startTime), delay); + setTimeout(() => { this.Document._currentTimecode = startTime; this.Document._audioStart = undefined; }, 10 + delay); + } + } + }, + { fireImmediately: true } + ); } playLink = (doc: Doc) => { diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index fa58a67b6..dd6e368e8 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -117,7 +117,7 @@ export class PresBox extends ViewBoxBaseComponent if (Doc.UserDoc().activePresentation = this.rootDoc) runInAction(() => PresBox.Instance = this); if (!this.presElement) { // create exactly one presElmentBox template to use by any and all presentations. Doc.UserDoc().presElement = new PrefetchProxy(Docs.Create.PresElementBoxDocument({ - title: "pres element template", type: DocumentType.PRESELEMENT, backgroundColor: "transparent", _xMargin: 0, isTemplateDoc: true, isTemplateForField: "data" + title: "pres element template", type: DocumentType.PRESELEMENT, _xMargin: 0, isTemplateDoc: true, isTemplateForField: "data" })); // this script will be called by each presElement to get rendering-specific info that the PresBox knows about but which isn't written to the PresElement // this is a design choice -- we could write this data to the presElements which would require a reaction to keep it up to date, and it would prevent @@ -191,7 +191,9 @@ export class PresBox extends ViewBoxBaseComponent // 'Play on next' for audio or video therefore first navigate to the audio/video before it should be played nextAudioVideo = (targetDoc: Doc, activeItem: Doc) => { - if (targetDoc.type === DocumentType.AUDIO) AudioBox.Instance.playFrom(NumCast(activeItem.presStartTime)); + if (targetDoc.type === DocumentType.AUDIO) { + targetDoc._audioStart = NumCast(activeItem.presStartTime); + } // if (targetDoc.type === DocumentType.VID) { VideoBox.Instance.Play() }; activeItem.playNow = false; } @@ -201,13 +203,12 @@ export class PresBox extends ViewBoxBaseComponent const nextSelected = this.itemIndex + 1; this.gotoDocument(nextSelected); - // const targetNext = Cast(activeNext.presentationTargetDoc, Doc, null); + const targetNext = Cast(activeNext.presentationTargetDoc, Doc, null); // If next slide is audio / video 'Play automatically' then the next slide should be played - // if (activeNext && (targetNext.type === DocumentType.AUDIO || targetNext.type === DocumentType.VID) && activeNext.playAuto) { - // console.log('play next automatically'); - // if (targetNext.type === DocumentType.AUDIO) AudioBox.Instance.playFrom(NumCast(activeNext.presStartTime)); - // // if (targetNext.type === DocumentType.VID) { VideoBox.Instance.Play() }; - // } else if (targetNext.type === DocumentType.AUDIO || targetNext.type === DocumentType.VID) { activeNext.playNow = true; console.log('play next after it is navigated to'); } + if (activeNext && (targetNext.type === DocumentType.AUDIO || targetNext.type === DocumentType.VID) && activeNext.playAuto) { + if (targetNext.type === DocumentType.AUDIO) targetNext._audioStart = NumCast(activeNext.presStartTime); + // if (targetNext.type === DocumentType.VID) { VideoBox.Instance.Play() }; + } else if (targetNext.type === DocumentType.AUDIO || targetNext.type === DocumentType.VID) { activeNext.playNow = true; console.log('play next after it is navigated to'); } } // Called when the user activates 'next' - to move to the next part of the pres. trail @@ -229,11 +230,10 @@ export class PresBox extends ViewBoxBaseComponent } else if (this.childDocs[this.itemIndex + 1] === undefined && this.layoutDoc.presLoop) { // Case 4: Last slide and presLoop is toggled ON this.gotoDocument(0); + } else if ((targetDoc.type === DocumentType.AUDIO || targetDoc.type === DocumentType.VID) && !activeItem.playAuto && activeItem.playNow && this.layoutDoc.presStatus !== PresStatus.Autoplay) { + // Case 2: 'Play on next' for audio or video therefore first navigate to the audio/video before it should be played + this.nextAudioVideo(targetDoc, activeItem); } - // else if ((targetDoc.type === DocumentType.AUDIO || targetDoc.type === DocumentType.VID) && !activeItem.playAuto && activeItem.playNow && this.layoutDoc.presStatus !== PresStatus.Autoplay) { - // // Case 2: 'Play on next' for audio or video therefore first navigate to the audio/video before it should be played - // this.nextAudioVideo(targetDoc, activeItem); - // } } // Called when the user activates 'back' - to move to the previous part of the pres. trail @@ -1927,7 +1927,7 @@ export class PresBox extends ViewBoxBaseComponent
*/}
{"View paths"}
}> -
1 ? 1 : 0.3, color: this._pathBoolean ? PresColor.DarkBlue : 'white', width: isMini ? "100%" : undefined }} className={"toolbar-button"} onClick={this.childDocs.length > 1 ? this.viewPaths : undefined}> +
1 && this.layoutDoc.presCollection ? 1 : 0.3, color: this._pathBoolean ? PresColor.DarkBlue : 'white', width: isMini ? "100%" : undefined }} className={"toolbar-button"} onClick={this.childDocs.length > 1 && this.layoutDoc.presCollection ? this.viewPaths : undefined}>
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index 8d4bd4b8b..49049b805 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -305,10 +305,12 @@ export class PresElementBox extends ViewBoxBaseComponent {miniView ? + // when width is LESS than 110 px
{`${this.indexInPres + 1}.`}
: + // when width is MORE than 110 px
{`${this.indexInPres + 1}.`}
} -- cgit v1.2.3-70-g09d2 From c4016e01b48367f45bed0ba2041e955c8c009464 Mon Sep 17 00:00:00 2001 From: geireann <60007097+geireann@users.noreply.github.com> Date: Sat, 28 Nov 2020 06:05:44 +0800 Subject: pres trail colors + group with up --- src/Utils.ts | 43 ++++++++++++++++++++++ src/client/views/collections/TabDocView.tsx | 1 + .../collections/collectionFreeForm/MarqueeView.tsx | 1 + src/client/views/nodes/PresBox.tsx | 2 +- .../views/presentationview/PresElementBox.scss | 10 +++-- .../views/presentationview/PresElementBox.tsx | 29 ++++++++++----- 6 files changed, 73 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/Utils.ts b/src/Utils.ts index daacca51d..1a00c0bfb 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -549,6 +549,49 @@ export function simulateMouseClick(element: Element | null | undefined, x: numbe })); } +export function lightOrDark(color: any) { + + // Variables for red, green, blue values + var r, g, b, hsp; + + // Check the format of the color, HEX or RGB? + if (color.match(/^rgb/)) { + + // If RGB --> store the red, green, blue values in separate variables + color = color.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+(?:\.\d+)?))?\)$/); + + r = color[1]; + g = color[2]; + b = color[3]; + } + else { + + // If hex --> Convert it to RGB: http://gist.github.com/983661 + color = +("0x" + color.slice(1).replace( + color.length < 5 && /./g, '$&$&')); + + r = color >> 16; + g = color >> 8 & 255; + b = color & 255; + } + + // HSP (Highly Sensitive Poo) equation from http://alienryderflex.com/hsp.html + hsp = Math.sqrt( + 0.299 * (r * r) + + 0.587 * (g * g) + + 0.114 * (b * b) + ); + + // Using the HSP value, determine whether the color is light or dark + if (hsp > 127.5) { + return 'light'; + } + else { + + return 'dark'; + } +} + export function setupMoveUpEvents( target: object, e: React.PointerEvent, diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 4c0073dcc..45fab480c 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -166,6 +166,7 @@ export class TabDocView extends React.Component { pinDoc.presentationTargetDoc = doc; pinDoc.title = doc.title + " - Slide"; pinDoc.presMovement = PresMovement.Zoom; + pinDoc.groupWithUp = false; pinDoc.context = curPres; const presArray: Doc[] = PresBox.Instance?.sortArray(); const size: number = PresBox.Instance?._selectedArray.size; diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 0eb05500c..c4d51f986 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -404,6 +404,7 @@ export class MarqueeView extends React.Component= 300; const miniView: boolean = this.toolbarWidth <= 110; + const presBox: Doc = this.presBox; //presBox + const presBoxColor: string = StrCast(presBox._backgroundColor); + const lightPresBoxColor: boolean = lightOrDark(presBoxColor) === 'light'; const targetDoc: Doc = this.targetDoc; const activeItem: Doc = this.rootDoc; return ( -
{ e.stopPropagation(); e.preventDefault(); @@ -314,7 +321,11 @@ export class PresElementBox extends ViewBoxBaseComponent {`${this.indexInPres + 1}.`}
} - {miniView ? (null) :
+ {miniView ? (null) :
this.updateView(targetDoc, activeItem)} style={{ fontWeight: 700, display: activeItem.presPinView ? "flex" : "none" }}>V
- {/*
{"Group with up"}
}> +
{"Group with up"}
}>
activeItem.groupWithUp = !activeItem.groupWithUp} - style={{ fontWeight: 700, display: activeItem.presPinView ? "flex" : "none" }}> - e.stopPropagation()} /> + style={{ fontWeight: 700, backgroundColor: activeItem.groupWithUp ? PresColor.DarkBlue : "none" }}> + e.stopPropagation()} />
-
*/} +
{this.rootDoc.presExpandInlineButton ? "Minimize" : "Expand"}
}>
{ e.stopPropagation(); this.presExpandDocumentClick(); }}> e.stopPropagation()} />
-- cgit v1.2.3-70-g09d2 From c15513601495e70c8e4161308814e72972d51367 Mon Sep 17 00:00:00 2001 From: geireann <60007097+geireann@users.noreply.github.com> Date: Sun, 29 Nov 2020 03:08:30 +0800 Subject: group with up functionality --- src/client/views/nodes/PresBox.tsx | 16 ++++++++++++++-- src/client/views/presentationview/PresElementBox.scss | 2 +- src/client/views/presentationview/PresElementBox.tsx | 19 +++++++++++++------ 3 files changed, 28 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 19c553189..1405016ae 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -200,9 +200,16 @@ export class PresBox extends ViewBoxBaseComponent // No more frames in current doc and next slide is defined, therefore move to next slide nextSlide = (targetDoc: Doc, activeNext: Doc) => { - const nextSelected = this.itemIndex + 1; + let nextSelected = this.itemIndex + 1; this.gotoDocument(nextSelected); - + for (nextSelected = nextSelected + 1; nextSelected < this.childDocs.length; nextSelected++) { + if (!this.childDocs[nextSelected].groupWithUp) { + break; + } else { + console.log("Title: " + this.childDocs[nextSelected].title); + this.gotoDocument(nextSelected); + } + } const targetNext = Cast(activeNext.presentationTargetDoc, Doc, null); // If next slide is audio / video 'Play automatically' then the next slide should be played if (activeNext && (targetNext.type === DocumentType.AUDIO || targetNext.type === DocumentType.VID) && activeNext.playAuto) { @@ -246,6 +253,11 @@ export class PresBox extends ViewBoxBaseComponent const lastFrame = Cast(targetDoc.lastFrame, "number", null); const curFrame = NumCast(targetDoc._currentFrame); let prevSelected = this.itemIndex; + // Functionality for group with up + let didZoom = activeItem.presMovement; + for (; !didZoom && prevSelected > 0 && this.childDocs[prevSelected].groupButton; prevSelected--) { + didZoom = this.childDocs[prevSelected].presMovement; + } if (lastFrame !== undefined && curFrame >= 1) { // Case 1: There are still other frames and should go through all frames before going to previous slide this.prevKeyframe(targetDoc, activeItem); diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss index 2c2c195d6..ed1aa9a1e 100644 --- a/src/client/views/presentationview/PresElementBox.scss +++ b/src/client/views/presentationview/PresElementBox.scss @@ -139,7 +139,7 @@ $slide-active: #5B9FDD; .slideButton { cursor: pointer; position: relative; - border-radius: 100%; + border-radius: 100px; z-index: 300; width: 18px; height: 18px; diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index c2d9faba9..463249ab8 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -286,7 +286,7 @@ export class PresElementBox extends ViewBoxBaseComponent { @@ -344,13 +344,20 @@ export class PresElementBox extends ViewBoxBaseComponent this.updateView(targetDoc, activeItem)} style={{ fontWeight: 700, display: activeItem.presPinView ? "flex" : "none" }}>V
-
{"Group with up"}
}> + {this.indexInPres === 0 ? (null) :
{"Group with up"}
}>
activeItem.groupWithUp = !activeItem.groupWithUp} - style={{ fontWeight: 700, backgroundColor: activeItem.groupWithUp ? PresColor.DarkBlue : "none" }}> - e.stopPropagation()} /> + style={{ + fontWeight: 700, + backgroundColor: activeItem.groupWithUp ? presColorBool ? presBoxColor : PresColor.DarkBlue : undefined, + height: activeItem.groupWithUp ? 53 : 18, + transform: activeItem.groupWithUp ? "translate(0, -17px)" : undefined + }}> +
+ e.stopPropagation()} /> +
-
+
}
{this.rootDoc.presExpandInlineButton ? "Minimize" : "Expand"}
}>
{ e.stopPropagation(); this.presExpandDocumentClick(); }}> e.stopPropagation()} />
-- cgit v1.2.3-70-g09d2 From 534a4e81e84adbd46b629731ac3ca7d3ea41a670 Mon Sep 17 00:00:00 2001 From: geireann <60007097+geireann@users.noreply.github.com> Date: Sun, 29 Nov 2020 11:15:30 +0800 Subject: temporal media updates for pres. trails --- deploy/index.html | 4 +- src/client/views/MainView.tsx | 8 +- src/client/views/PropertiesView.tsx | 8 +- src/client/views/nodes/AudioBox.tsx | 22 +- src/client/views/nodes/PresBox.scss | 83 +++- src/client/views/nodes/PresBox.tsx | 323 +++++++++----- src/client/views/nodes/VideoBox.tsx | 51 ++- .../views/presentationview/PresElementBox.scss | 41 +- .../views/presentationview/PresElementBox.tsx | 3 +- .../views/presentationview/PresProperties.tsx | 492 +++++++++++++++++++++ 10 files changed, 901 insertions(+), 134 deletions(-) create mode 100644 src/client/views/presentationview/PresProperties.tsx (limited to 'src') diff --git a/deploy/index.html b/deploy/index.html index af67ac301..beb7dd205 100644 --- a/deploy/index.html +++ b/deploy/index.html @@ -14,8 +14,8 @@ justify-content: center; background-color: #AEDDF8; z-index: 10; - width: 100%; - height: 100%; + width: 100vw; + height: 100vh; } .dash-loader-container { diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 03d2e33df..b1e008dad 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -87,11 +87,11 @@ export class MainView extends React.Component { componentDidMount() { document.getElementById("root")?.addEventListener("scroll", e => ((ele) => ele.scrollLeft = ele.scrollTop = 0)(document.getElementById("root")!)); const ele = document.getElementById("loader"); + if (ele) { - setTimeout(() => { - // remove from DOM - ele.outerHTML = ''; - }, 0); + // remove from DOM + setTimeout(() => { ele.style.opacity = "0"; }, 0); + setTimeout(() => ele.outerHTML = '', 10000); } new InkStrokeProperties(); this._sidebarContent.proto = undefined; diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 97bca110b..c656a020e 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -1007,7 +1007,7 @@ export class PropertiesView extends React.Component {
{ this.openPresTransitions = !this.openPresTransitions; })} style={{ backgroundColor: this.openPresTransitions ? "black" : "" }}> -     Transitions +     Transitions
@@ -1029,17 +1029,17 @@ export class PropertiesView extends React.Component { {PresBox.Instance.progressivizeDropdown}
: null}
} */} - {!selectedItem ? (null) :
+ {!selectedItem || (type !== DocumentType.VID && type !== DocumentType.AUDIO) ? (null) :
{ this.openSlideOptions = !this.openSlideOptions; })} style={{ backgroundColor: this.openSlideOptions ? "black" : "" }}> -     {scrollable ? "Scroll options" : "Pan options"} +     {type === DocumentType.AUDIO ? "Audio Options" : "Video Options"}
{this.openSlideOptions ?
- {PresBox.Instance.optionsDropdown} + {PresBox.Instance.mediaOptionsDropdown}
: null}
} {/*
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 1bdba7f9e..2527a2db1 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -48,9 +48,9 @@ export class AudioBox extends ViewBoxAnnotatableComponent AudioBox._scrubTime, (time) => this.layoutDoc.playOnSelect && this.playFromTime(AudioBox._scrubTime)); - this._disposers._audioStart = reaction( + this._disposers.audioStart = reaction( () => this.Document._audioStart, (audioStart) => { if (audioStart !== undefined) { @@ -165,6 +165,20 @@ export class AudioBox extends ViewBoxAnnotatableComponent this.Document._audioStop, + (audioStop) => { + if (audioStop !== undefined) { + if (this.props.renderDepth !== -1 && !LinkDocPreview.TargetDoc && !FormattedTextBoxComment.linkDoc) { + const delay = this._audioRef.current ? 0 : 250; // wait for mainCont and try again to play + setTimeout(() => this._audioRef.current && this.pause(), delay); + setTimeout(() => { this.Document._audioStop = undefined; }, 10 + delay); + } + } + }, + { fireImmediately: true } + ); } playLink = (doc: Doc) => { diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss index 56b3b0593..6579dbf41 100644 --- a/src/client/views/nodes/PresBox.scss +++ b/src/client/views/nodes/PresBox.scss @@ -127,6 +127,17 @@ $light-background: #ececec; opacity: 0.8; } +.presBox-radioButtons { + background-color: rgba(0, 0, 0, 0.1); + + .checkbox-container { + margin-left: 10px; + display: inline-flex; + height: 20px; + align-items: center; + } +} + .presBox-ribbon { position: relative; display: inline; @@ -209,6 +220,42 @@ $light-background: #ececec; } @media screen and (-webkit-min-device-pixel-ratio:0) { + + .multiThumb-slider { + display: grid; + background-color: $light-background; + height: 10px; + border-radius: 10px; + overflow: hidden; + + .toolbar-slider { + margin-top: 0px; + background: none; + -webkit-appearance: none; + pointer-events: none; + } + + .toolbar-slider.start::-webkit-slider-thumb { + width: 10px; + pointer-events: auto; + -webkit-appearance: none; + height: 10px; + cursor: ew-resize; + background: $dark-blue; + box-shadow: -100vw 0 0 100vw $light-background; + } + + .toolbar-slider.end::-webkit-slider-thumb { + width: 10px; + pointer-events: auto; + -webkit-appearance: none; + height: 10px; + cursor: ew-resize; + background: $dark-blue; + box-shadow: -100vw 0 0 100vw $light-blue; + } + } + .toolbar-slider { margin-top: 5px; position: relative; @@ -219,7 +266,7 @@ $light-background: #ececec; height: 10px; border-radius: 10px; -webkit-appearance: none; - background-color: #ececec; + background-color: $light-background; } .toolbar-slider:focus { @@ -234,14 +281,44 @@ $light-background: #ececec; .toolbar-slider::-webkit-slider-thumb { width: 10px; + pointer-events: auto; -webkit-appearance: none; height: 10px; cursor: ew-resize; - background: #5b9ddd; - box-shadow: -100vw 0 0 100vw #aedef8; + background: $dark-blue; + box-shadow: -100vw 0 0 100vw $light-blue; + } + + .presBox-checkbox { + -webkit-appearance: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + margin: 0; + margin-right: 3px; + border-radius: 100%; + height: 15px; + width: 15px; + cursor: pointer; + background: $light-background; + } + + .presBox-checkbox:focus { + outline: none; + } + + .presBox-checkbox:hover { + background: #c0c0c0; + } + + .presBox-checkbox:checked { + background: $light-blue; } } + + .slider-headers { position: relative; display: grid; diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 1405016ae..9fb07040d 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -24,7 +24,6 @@ import { CollectionDockingView } from "../collections/CollectionDockingView"; import { CollectionView, CollectionViewType } from "../collections/CollectionView"; import { TabDocView } from "../collections/TabDocView"; import { ViewBoxBaseComponent } from "../DocComponent"; -import { AudioBox } from "./AudioBox"; import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView"; import { FieldView, FieldViewProps } from './FieldView'; import "./PresBox.scss"; @@ -193,6 +192,10 @@ export class PresBox extends ViewBoxBaseComponent nextAudioVideo = (targetDoc: Doc, activeItem: Doc) => { if (targetDoc.type === DocumentType.AUDIO) { targetDoc._audioStart = NumCast(activeItem.presStartTime); + + } else if (targetDoc.type === DocumentType.VID) { + targetDoc._currentTimecode = NumCast(activeItem.presStartTime); + setTimeout(() => targetDoc._videoStart = true, 0); } // if (targetDoc.type === DocumentType.VID) { VideoBox.Instance.Play() }; activeItem.playNow = false; @@ -214,7 +217,6 @@ export class PresBox extends ViewBoxBaseComponent // If next slide is audio / video 'Play automatically' then the next slide should be played if (activeNext && (targetNext.type === DocumentType.AUDIO || targetNext.type === DocumentType.VID) && activeNext.playAuto) { if (targetNext.type === DocumentType.AUDIO) targetNext._audioStart = NumCast(activeNext.presStartTime); - // if (targetNext.type === DocumentType.VID) { VideoBox.Instance.Play() }; } else if (targetNext.type === DocumentType.AUDIO || targetNext.type === DocumentType.VID) { activeNext.playNow = true; console.log('play next after it is navigated to'); } } @@ -1071,6 +1073,7 @@ export class PresBox extends ViewBoxBaseComponent @computed get transitionDropdown() { const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; + const type: DocumentType = targetDoc.type; const isPresCollection: boolean = (targetDoc === this.layoutDoc.presCollection); const isPinWithView: boolean = BoolCast(activeItem.presPinView); if (activeItem && targetDoc) { @@ -1137,7 +1140,7 @@ export class PresBox extends ViewBoxBaseComponent {isPresCollection ? (null) :
{"Hide after presented"}
}>
this.updateHideAfter(activeItem)}>Hide after
}
{"Open document in a new tab"}
}>
this.updateOpenDoc(activeItem)}>Open
-
+ {(type === DocumentType.AUDIO || type === DocumentType.VID) ? (null) :
Slide Duration
-
+
} } }); } - @computed get optionsDropdown() { + + @computed get presPinViewOptionsDropdown() { const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; const presPinWithViewIcon = ; + return ( + <> + {this.panable || this.scrollable || this.targetDoc.type === DocumentType.COMPARISON ? 'Pinned view' : (null)} +
+
{activeItem.presPinView ? "Turn off pin with view" : "Turn on pin with view"}
}>
{ + activeItem.presPinView = !activeItem.presPinView; + targetDoc.presPinView = activeItem.presPinView; + if (activeItem.presPinView) { + if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.WEB || targetDoc._viewType === CollectionViewType.Stacking) { + const scroll = targetDoc._scrollTop; + activeItem.presPinView = true; + activeItem.presPinViewScroll = scroll; + } else if (targetDoc.type === DocumentType.VID) { + activeItem.presPinTimecode = targetDoc._currentTimecode; + } else if ((targetDoc.type === DocumentType.COL && targetDoc._viewType === CollectionViewType.Freeform) || targetDoc.type === DocumentType.IMG) { + const x = targetDoc._panX; + const y = targetDoc._panY; + const scale = targetDoc._viewScale; + activeItem.presPinView = true; + activeItem.presPinViewX = x; + activeItem.presPinViewY = y; + activeItem.presPinViewScale = scale; + } else if (targetDoc.type === DocumentType.COMPARISON) { + const width = targetDoc._clipWidth; + activeItem.presPinClipWidth = width; + activeItem.presPinView = true; + } + } + }}>{presPinWithViewIcon}
+ {activeItem.presPinView ?
{"Update the pinned view with the view of the selected document"}
}>
{ + if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF) { + const scroll = targetDoc._scrollTop; + activeItem.presPinViewScroll = scroll; + } else if (targetDoc.type === DocumentType.VID) { + activeItem.presPinTimecode = targetDoc._currentTimecode; + } else if (targetDoc.type === DocumentType.COMPARISON) { + const clipWidth = targetDoc._clipWidth; + activeItem.presPinClipWidth = clipWidth; + } else { + const x = targetDoc._panX; + const y = targetDoc._panY; + const scale = targetDoc._viewScale; + activeItem.presPinViewX = x; + activeItem.presPinViewY = y; + activeItem.presPinViewScale = scale; + } + }}>Update
: (null)} +
+ + ); + } + + @computed get panOptionsDropdown() { + const activeItem: Doc = this.activeItem; + const targetDoc: Doc = this.targetDoc; + return ( + <> + {this.panable ?
+
+
Pan X
+
+ ) => { const val = e.target.value; activeItem.presPinViewX = Number(val); })} /> +
+
+
+
Pan Y
+
+ ) => { const val = e.target.value; activeItem.presPinViewY = Number(val); })} /> +
+
+
+
Scale
+
+ ) => { const val = e.target.value; activeItem.presPinViewScale = Number(val); })} /> +
+
+
: (null)} + + ); + } + + @computed get scrollOptionsDropdown() { + const activeItem: Doc = this.activeItem; + const targetDoc: Doc = this.targetDoc; + return ( + <> + {this.scrollable ?
+
+
Scroll
+
+ ) => { const val = e.target.value; activeItem.presPinViewScroll = Number(val); })} /> +
+
+
: (null)} + + ); + } + + @computed get mediaOptionsDropdown() { + const activeItem: Doc = this.activeItem; + const targetDoc: Doc = this.targetDoc; if (activeItem && targetDoc) { return (
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}> -
+
+
Start playing:
+
+
+ activeItem.mediaPlay = "manual"} + checked={activeItem.mediaPlay === "manual"} + /> +
Start manually
+
+
+ activeItem.mediaPlay = "auto"} + checked={activeItem.mediaPlay === "auto"} + /> +
Play with slide
+
+
+ activeItem.mediaPlay = "onClick"} + checked={activeItem.mediaPlay === "onClick"} + /> +
Play on click
+
+
+
Stop playing:
+
+
+ activeItem.mediaStop = "manual"} + checked={activeItem.mediaStop === "manual"} + /> +
Stop manually
+
+
+ activeItem.mediaStop = "afterCurrent"} + checked={activeItem.mediaStop === "afterCurrent"} + /> +
After current slide
+
+
+ activeItem.mediaStop = "afterSlide"} + checked={activeItem.mediaStop === "afterSlide"} + /> +
After slide + {activeItem.mediaStop !== "afterSlide" ? + (null) + : +
{ e.stopPropagation(); this.openMovementDropdown = !this.openMovementDropdown; })} style={{ borderBottomLeftRadius: this.openMovementDropdown ? 0 : 5, border: this.openMovementDropdown ? `solid 2px ${PresColor.DarkBlue}` : 'solid 1px black' }}> + {this.setMovementName(activeItem.presMovement, activeItem)} + +
e.stopPropagation()} style={{ display: this.openMovementDropdown ? "grid" : "none" }}> +
e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.None)}>None
+
e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Zoom)}>Pan {"&"} Zoom
+
e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Pan)}>Pan
+
e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Jump)}>Jump cut
+
+
} +
+
+
+
Range:
+
+ this._batch = UndoManager.StartBatch("presEndTime")} + onPointerUp={() => this._batch?.end()} + onChange={(e: React.ChangeEvent) => { + e.stopPropagation(); + activeItem.presEndTime = Number(e.target.value); + }} /> + this._batch = UndoManager.StartBatch("presEndTime")} + onPointerUp={() => this._batch?.end()} + onChange={(e: React.ChangeEvent) => { + e.stopPropagation(); + activeItem.presStartTime = Number(e.target.value); + }} /> +
+
+
0 s
+
+
{Math.round(NumCast(activeItem.duration))} s
+
+
+ {/*
activeItem.playAuto = !activeItem.playAuto}>Play automatically
activeItem.playAuto = !activeItem.playAuto}>Play on next
- {/* {targetDoc.type === DocumentType.VID ?
activeItem.presVidFullScreen = !activeItem.presVidFullScreen}>Full screen
: (null)} */} {targetDoc.type === DocumentType.AUDIO ?
Start time
@@ -1267,98 +1483,7 @@ export class PresBox extends ViewBoxBaseComponent onChange={action((e: React.ChangeEvent) => { const val = e.target.value; activeItem.presEndTime = Number(val); })} />
: (null)} - {this.panable || this.scrollable || this.targetDoc.type === DocumentType.COMPARISON ? 'Pinned view' : (null)} -
-
{activeItem.presPinView ? "Turn off pin with view" : "Turn on pin with view"}
}>
{ - activeItem.presPinView = !activeItem.presPinView; - targetDoc.presPinView = activeItem.presPinView; - if (activeItem.presPinView) { - if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.WEB || targetDoc._viewType === CollectionViewType.Stacking) { - const scroll = targetDoc._scrollTop; - activeItem.presPinView = true; - activeItem.presPinViewScroll = scroll; - } else if (targetDoc.type === DocumentType.VID) { - activeItem.presPinTimecode = targetDoc._currentTimecode; - } else if ((targetDoc.type === DocumentType.COL && targetDoc._viewType === CollectionViewType.Freeform) || targetDoc.type === DocumentType.IMG) { - const x = targetDoc._panX; - const y = targetDoc._panY; - const scale = targetDoc._viewScale; - activeItem.presPinView = true; - activeItem.presPinViewX = x; - activeItem.presPinViewY = y; - activeItem.presPinViewScale = scale; - } else if (targetDoc.type === DocumentType.COMPARISON) { - const width = targetDoc._clipWidth; - activeItem.presPinClipWidth = width; - activeItem.presPinView = true; - } - } - }}>{presPinWithViewIcon}
- {activeItem.presPinView ?
{"Update the pinned view with the view of the selected document"}
}>
{ - if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF) { - const scroll = targetDoc._scrollTop; - activeItem.presPinViewScroll = scroll; - } else if (targetDoc.type === DocumentType.VID) { - activeItem.presPinTimecode = targetDoc._currentTimecode; - } else if (targetDoc.type === DocumentType.COMPARISON) { - const clipWidth = targetDoc._clipWidth; - activeItem.presPinClipWidth = clipWidth; - } else { - const x = targetDoc._panX; - const y = targetDoc._panY; - const scale = targetDoc._viewScale; - activeItem.presPinViewX = x; - activeItem.presPinViewY = y; - activeItem.presPinViewScale = scale; - } - }}>Update
: (null)} -
- {this.panable ?
-
-
Pan X
-
- ) => { const val = e.target.value; activeItem.presPinViewX = Number(val); })} /> -
-
-
-
Pan Y
-
- ) => { const val = e.target.value; activeItem.presPinViewY = Number(val); })} /> -
-
-
-
Scale
-
- ) => { const val = e.target.value; activeItem.presPinViewScale = Number(val); })} /> -
-
-
: (null)} - {this.scrollable ?
-
-
Scroll
-
- ) => { const val = e.target.value; activeItem.presPinViewScroll = Number(val); })} /> -
-
-
: (null)} - {/*
-
Store original website
-
*/} -
+
*/}
); diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 8ce76a347..998ca839d 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -21,6 +21,8 @@ import { documentSchema } from "../../../fields/documentSchemas"; import { Networking } from "../../Network"; import { SnappingManager } from "../../util/SnappingManager"; import { SelectionManager } from "../../util/SelectionManager"; +import { LinkDocPreview } from "./LinkDocPreview"; +import { FormattedTextBoxComment } from "./formattedText/FormattedTextBoxComment"; const path = require('path'); export const timeSchema = createSchema({ @@ -32,8 +34,9 @@ const VideoDocument = makeInterface(documentSchema, timeSchema); @observer export class VideoBox extends ViewBoxAnnotatableComponent(VideoDocument) { static _youtubeIframeCounter: number = 0; - private _reactionDisposer?: IReactionDisposer; - private _youtubeReactionDisposer?: IReactionDisposer; + // private _reactionDisposer?: IReactionDisposer; + // private _youtubeReactionDisposer?: IReactionDisposer; + private _disposers: { [name: string]: IReactionDisposer } = {}; private _youtubePlayer: YT.Player | undefined = undefined; private _videoRef: HTMLVideoElement | null = null; private _youtubeIframeId: number = -1; @@ -181,7 +184,32 @@ export class VideoBox extends ViewBoxAnnotatableComponent this.Document._videoStart, + (videoStart) => { + if (videoStart !== undefined) { + if (this.props.renderDepth !== -1 && !LinkDocPreview.TargetDoc && !FormattedTextBoxComment.linkDoc) { + const delay = this.player ? 0 : 250; // wait for mainCont and try again to play + setTimeout(() => this.player && this.Play(), delay); + setTimeout(() => { this.Document._videoStart = undefined; }, 10 + delay); + } + } + }, + { fireImmediately: true } + ); + this._disposers.videoStop = reaction( + () => this.Document._videoStop, + (videoStop) => { + if (videoStop !== undefined) { + if (this.props.renderDepth !== -1 && !LinkDocPreview.TargetDoc && !FormattedTextBoxComment.linkDoc) { + const delay = this.player ? 0 : 250; // wait for mainCont and try again to play + setTimeout(() => this.player && this.Pause(), delay); + setTimeout(() => { this.Document._videoStop = undefined; }, 10 + delay); + } + } + }, + { fireImmediately: true } + ); if (this.youtubeVideoId) { const youtubeaspect = 400 / 315; const nativeWidth = Doc.NativeWidth(this.layoutDoc); @@ -196,8 +224,9 @@ export class VideoBox extends ViewBoxAnnotatableComponent this._fullScreen = vref.webkitDisplayingFullscreen); - this._reactionDisposer?.(); - this._reactionDisposer = reaction(() => (this.layoutDoc._currentTimecode || 0), + this._disposers.reactionDisposer?.(); + this._disposers.reactionDisposer = reaction(() => (this.layoutDoc._currentTimecode || 0), time => !this._playing && (vref.currentTime = time), { fireImmediately: true }); } } @@ -293,10 +322,10 @@ export class VideoBox extends ViewBoxAnnotatableComponent { - this._reactionDisposer?.(); - this._youtubeReactionDisposer?.(); - this._reactionDisposer = reaction(() => this.layoutDoc._currentTimecode, () => !this._playing && this.Seek((this.layoutDoc._currentTimecode || 0))); - this._youtubeReactionDisposer = reaction( + this._disposers.reactionDisposer?.(); + this._disposers.youtubeReactionDisposer?.(); + this._disposers.reactionDisposer = reaction(() => this.layoutDoc._currentTimecode, () => !this._playing && this.Seek((this.layoutDoc._currentTimecode || 0))); + this._disposers.youtubeReactionDisposer = reaction( () => !this.props.Document.isAnnotating && Doc.GetSelectedTool() === InkTool.None && this.props.isSelected(true) && !SnappingManager.GetIsDragging() && !DocumentDecorations.Instance.Interacting, (interactive) => iframe.style.pointerEvents = interactive ? "all" : "none", { fireImmediately: true }); }; diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss index ed1aa9a1e..e1eeefc30 100644 --- a/src/client/views/presentationview/PresElementBox.scss +++ b/src/client/views/presentationview/PresElementBox.scss @@ -122,12 +122,6 @@ $slide-active: #5B9FDD; } - .presItem-slideButtons { - display: none; - } -} - -.presItem-slide:hover { .presItem-slideButtons { display: flex; grid-column: 7; @@ -162,6 +156,41 @@ $slide-active: #5B9FDD; } } +// .presItem-slide:hover { + // .presItem-slideButtons { + // display: flex; + // grid-column: 7; + // grid-row: 1/3; + // width: max-content; + // justify-self: right; + // justify-content: flex-end; + + // .slideButton { + // cursor: pointer; + // position: relative; + // border-radius: 100px; + // z-index: 300; + // width: 18px; + // height: 18px; + // display: flex; + // font-size: 12px; + // justify-self: center; + // align-self: center; + // background-color: rgba(0, 0, 0, 0.5); + // color: white; + // justify-content: center; + // align-items: center; + // transition: 0.2s; + // margin-right: 3px; + // } + + // .slideButton:hover { + // background-color: rgba(0, 0, 0, 1); + // transform: scale(1.2); + // } + // } + // } + .presItem-slide.active { box-shadow: 0 0 0px 1.5px $dark-blue; } diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index 463249ab8..9ec39b792 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -348,6 +348,7 @@ export class PresElementBox extends ViewBoxBaseComponent activeItem.groupWithUp = !activeItem.groupWithUp} style={{ + zIndex: 1000 - this.indexInPres, fontWeight: 700, backgroundColor: activeItem.groupWithUp ? presColorBool ? presBoxColor : PresColor.DarkBlue : undefined, height: activeItem.groupWithUp ? 53 : 18, @@ -367,7 +368,7 @@ export class PresElementBox extends ViewBoxBaseComponent e.stopPropagation()} />
-
{activeItem.presPinView ? (<>View of {targetDoc.title}) : targetDoc.title}
+
{activeItem.presPinView ? (<>View of {targetDoc.title}) : targetDoc.title}
{this.renderEmbeddedInline}
}
); diff --git a/src/client/views/presentationview/PresProperties.tsx b/src/client/views/presentationview/PresProperties.tsx new file mode 100644 index 000000000..edad41861 --- /dev/null +++ b/src/client/views/presentationview/PresProperties.tsx @@ -0,0 +1,492 @@ +import React from "react"; +import { action, computed, observable, reaction } from "mobx"; +import { Doc } from "../../../fields/Doc"; +import { BoolCast, Cast, NumCast } from "../../../fields/Types"; +import { undoBatch, UndoManager } from "../../util/UndoManager"; +import { PresBox, PresColor, PresEffect, PresMovement } from "../nodes/PresBox"; +import { DocumentType } from "../../documents/DocumentTypes"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { CollectionViewType } from "../collections/CollectionView"; +import { Tooltip } from "@material-ui/core"; + + +export class PresProperties { + + @observable public static Instance: PresProperties; + + @computed get pres(): PresBox { return PresBox.Instance; } + + @computed get activeItem() { return Cast(this.pres.childDocs[NumCast(PresBox.Instance.rootDoc._itemIndex)], Doc, null); } + @computed get targetDoc() { return Cast(this.pres.activeItem?.presentationTargetDoc, Doc, null); } + + @computed get scrollable(): boolean { + if (this.targetDoc.type === DocumentType.PDF || this.targetDoc.type === DocumentType.WEB || this.targetDoc.type === DocumentType.RTF || this.targetDoc._viewType === CollectionViewType.Stacking) return true; + else return false; + } + @computed get panable(): boolean { + if ((this.targetDoc.type === DocumentType.COL && this.targetDoc._viewType === CollectionViewType.Freeform) || this.targetDoc.type === DocumentType.IMG) return true; + else return false; + } + + + @observable private openMovementDropdown: boolean = false; + @observable private openEffectDropdown: boolean = false; + + _batch: UndoManager.Batch | undefined = undefined; + + + @computed get effectDirection(): string { + let effect = ''; + switch (this.targetDoc.presEffectDirection) { + case 'left': effect = "Enter from left"; break; + case 'right': effect = "Enter from right"; break; + case 'top': effect = "Enter from top"; break; + case 'bottom': effect = "Enter from bottom"; break; + default: effect = "Enter from center"; break; + } + return effect; + } + + @undoBatch + @action + updateHideBefore = (activeItem: Doc) => { + activeItem.presHideBefore = !activeItem.presHideBefore; + Array.from(this.pres._selectedArray.keys()).forEach((doc) => doc.presHideBefore = activeItem.presHideBefore); + } + + @undoBatch + @action + updateHideAfter = (activeItem: Doc) => { + activeItem.presHideAfter = !activeItem.presHideAfter; + Array.from(this.pres._selectedArray.keys()).forEach((doc) => doc.presHideAfter = activeItem.presHideAfter); + } + + @undoBatch + @action + updateOpenDoc = (activeItem: Doc) => { + activeItem.openDocument = !activeItem.openDocument; + Array.from(this.pres._selectedArray.keys()).forEach((doc) => { + doc.openDocument = activeItem.openDocument; + }); + } + + /** + * When the movement dropdown is changes + */ + @undoBatch + updateMovement = action((movement: any, all?: boolean) => { + const array: any[] = all ? this.pres.childDocs : Array.from(this.pres._selectedArray.keys()); + array.forEach((doc) => { + switch (movement) { + case PresMovement.Zoom: //Pan and zoom + doc.presMovement = PresMovement.Zoom; + break; + case PresMovement.Pan: //Pan + doc.presMovement = PresMovement.Pan; + break; + case PresMovement.Jump: //Jump Cut + doc.presJump = true; + doc.presMovement = PresMovement.Jump; + break; + case PresMovement.None: default: + doc.presMovement = PresMovement.None; + break; + } + }); + }); + + @undoBatch + @action + updateEffect = (effect: any, all?: boolean) => { + const array: any[] = all ? this.pres.childDocs : Array.from(this.pres._selectedArray.keys()); + array.forEach((doc) => { + const tagDoc = Cast(doc.presentationTargetDoc, Doc, null); + switch (effect) { + case PresEffect.Bounce: + tagDoc.presEffect = PresEffect.Bounce; + break; + case PresEffect.Fade: + tagDoc.presEffect = PresEffect.Fade; + break; + case PresEffect.Flip: + tagDoc.presEffect = PresEffect.Flip; + break; + case PresEffect.Roll: + tagDoc.presEffect = PresEffect.Roll; + break; + case PresEffect.Rotate: + tagDoc.presEffect = PresEffect.Rotate; + break; + case PresEffect.None: default: + tagDoc.presEffect = PresEffect.None; + break; + } + }); + } + + @undoBatch + @action + updateEffectDirection = (effect: any, all?: boolean) => { + const array: any[] = all ? this.pres.childDocs : Array.from(this.pres._selectedArray.keys()); + array.forEach((doc) => { + const tagDoc = Cast(doc.presentationTargetDoc, Doc, null); + switch (effect) { + case PresEffect.Left: + tagDoc.presEffectDirection = PresEffect.Left; + break; + case PresEffect.Right: + tagDoc.presEffectDirection = PresEffect.Right; + break; + case PresEffect.Top: + tagDoc.presEffectDirection = PresEffect.Top; + break; + case PresEffect.Bottom: + tagDoc.presEffectDirection = PresEffect.Bottom; + break; + case PresEffect.Center: default: + tagDoc.presEffectDirection = PresEffect.Center; + break; + } + }); + } + + // Converts seconds to ms and updates presTransition + setTransitionTime = (number: String, change?: number) => { + let timeInMS = Number(number) * 1000; + if (change) timeInMS += change; + if (timeInMS < 100) timeInMS = 100; + if (timeInMS > 10000) timeInMS = 10000; + Array.from(PresBox.Instance._selectedArray.keys()).forEach((doc) => doc.presTransition = timeInMS); + } + + // Converts seconds to ms and updates presDuration + setDurationTime = (number: String, change?: number) => { + let timeInMS = Number(number) * 1000; + if (change) timeInMS += change; + if (timeInMS < 100) timeInMS = 100; + if (timeInMS > 20000) timeInMS = 20000; + Array.from(PresBox.Instance._selectedArray.keys()).forEach((doc) => doc.presDuration = timeInMS); + } + + setMovementName = action((movement: any, activeItem: Doc): string => { + let output: string = 'none'; + switch (movement) { + case PresMovement.Zoom: output = 'Pan & Zoom'; break; //Pan and zoom + case PresMovement.Pan: output = 'Pan'; break; //Pan + case PresMovement.Jump: output = 'Jump cut'; break; //Jump Cut + case PresMovement.None: output = 'No Movement'; break; //None + default: output = 'Zoom'; activeItem.presMovement = 'zoom'; break; //default set as zoom + } + return output; + }); + + @computed get transitionDropdown() { + const activeItem: Doc = this.activeItem; + const targetDoc: Doc = this.targetDoc; + const isPresCollection: boolean = (targetDoc === this.pres.layoutDoc.presCollection); + const isPinWithView: boolean = BoolCast(activeItem.presPinView); + if (activeItem && targetDoc) { + const transitionSpeed = activeItem.presTransition ? NumCast(activeItem.presTransition) / 1000 : 0.5; + let duration = activeItem.presDuration ? NumCast(activeItem.presDuration) / 1000 : 2; + if (activeItem.type === DocumentType.AUDIO) duration = NumCast(activeItem.duration); + const effect = targetDoc.presEffect ? targetDoc.presEffect : 'None'; + activeItem.presMovement = activeItem.presMovement ? activeItem.presMovement : 'Zoom'; + return ( +
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onClick={action(e => { e.stopPropagation(); this.openMovementDropdown = false; this.openEffectDropdown = false; })}> +
+ Movement + {isPresCollection || (isPresCollection && isPinWithView) ? +
+ {this.scrollable ? "Scroll to pinned view" : !isPinWithView ? "No movement" : "Pan & Zoom to pinned view"} +
+ : +
{ e.stopPropagation(); this.openMovementDropdown = !this.openMovementDropdown; })} style={{ borderBottomLeftRadius: this.openMovementDropdown ? 0 : 5, border: this.openMovementDropdown ? `solid 2px ${PresColor.DarkBlue}` : 'solid 1px black' }}> + {this.setMovementName(activeItem.presMovement, activeItem)} + +
e.stopPropagation()} style={{ display: this.openMovementDropdown ? "grid" : "none" }}> +
e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.None)}>None
+
e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Zoom)}>Pan {"&"} Zoom
+
e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Pan)}>Pan
+
e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Jump)}>Jump cut
+
+
+ } +
+
Transition Speed
+
+ this.setTransitionTime(e.target.value))} /> s +
+
+
this.setTransitionTime(String(transitionSpeed), 1000))}> + +
+
this.setTransitionTime(String(transitionSpeed), -1000))}> + +
+
+
+ this._batch = UndoManager.StartBatch("presTransition")} + onPointerUp={() => this._batch?.end()} + onChange={(e: React.ChangeEvent) => { + e.stopPropagation(); + this.setTransitionTime(e.target.value); + }} /> +
+
Fast
+
Medium
+
Slow
+
+
+
+ Visibility {"&"} Duration +
+ {isPresCollection ? (null) :
{"Hide before presented"}
}>
this.updateHideBefore(activeItem)}>Hide before
} + {isPresCollection ? (null) :
{"Hide after presented"}
}>
this.updateHideAfter(activeItem)}>Hide after
} +
{"Open document in a new tab"}
}>
this.updateOpenDoc(activeItem)}>Open
+
+
+
Slide Duration
+
+ this.setDurationTime(e.target.value))} /> s +
+
+
this.setDurationTime(String(duration), 1000))}> + +
+
this.setDurationTime(String(duration), -1000))}> + +
+
+
+ { this._batch = UndoManager.StartBatch("presDuration"); }} + onPointerUp={() => { if (this._batch) this._batch.end(); }} + onChange={(e: React.ChangeEvent) => { e.stopPropagation(); this.setDurationTime(e.target.value); }} + /> +
+
Short
+
Medium
+
Long
+
+
+ {isPresCollection ? (null) :
+ Effects +
{ e.stopPropagation(); this.openEffectDropdown = !this.openEffectDropdown; })} style={{ borderBottomLeftRadius: this.openEffectDropdown ? 0 : 5, border: this.openEffectDropdown ? `solid 2px ${PresColor.DarkBlue}` : 'solid 1px black' }}> + {effect} + +
e.stopPropagation()}> +
e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.None)}>None
+
e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Fade)}>Fade In
+
e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Flip)}>Flip
+
e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Rotate)}>Rotate
+
e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Bounce)}>Bounce
+
e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Roll)}>Roll
+
+
+
+
Effect direction
+
+ {this.effectDirection} +
+
+
+
{"Enter from left"}
}>
this.updateEffectDirection(PresEffect.Left)}>
+
{"Enter from right"}
}>
this.updateEffectDirection(PresEffect.Right)}>
+
{"Enter from top"}
}>
this.updateEffectDirection(PresEffect.Top)}>
+
{"Enter from bottom"}
}>
this.updateEffectDirection(PresEffect.Bottom)}>
+
{"Enter from center"}
}>
this.updateEffectDirection(PresEffect.Center)}>
+
+
} +
+
this.applyTo(this.pres.childDocs)}> + Apply to all +
+
+
+ ); + } + } + + @undoBatch + @action + applyTo = (array: Doc[]) => { + const activeItem: Doc = this.activeItem; + const targetDoc: Doc = this.targetDoc; + this.updateMovement(activeItem.presMovement, true); + this.updateEffect(targetDoc.presEffect, true); + this.updateEffectDirection(targetDoc.presEffectDirection, true); + array.forEach((doc) => { + const curDoc = Cast(doc, Doc, null); + const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null); + if (tagDoc && targetDoc) { + curDoc.presTransition = activeItem.presTransition; + curDoc.presDuration = activeItem.presDuration; + curDoc.presHideBefore = activeItem.presHideBefore; + curDoc.presHideAfter = activeItem.presHideAfter; + } + }); + } + + @computed get mediaOptionsDropdown() { + const activeItem: Doc = this.activeItem; + const targetDoc: Doc = this.targetDoc; + if (activeItem && targetDoc) { + return ( +
+
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}> +
+
+
activeItem.playAuto = !activeItem.playAuto}>Play automatically
+
activeItem.playAuto = !activeItem.playAuto}>Play on next
+
+ {/* {targetDoc.type === DocumentType.VID ?
activeItem.presVidFullScreen = !activeItem.presVidFullScreen}>Full screen
: (null)} */} + {targetDoc.type === DocumentType.AUDIO ?
+
Start time
+
+ ) => { activeItem.presStartTime = Number(e.target.value); })} /> +
+
: (null)} + {targetDoc.type === DocumentType.AUDIO ?
+
End time
+
+ ) => { const val = e.target.value; activeItem.presEndTime = Number(val); })} /> +
+
: (null)} +
+
+
+ ); + } + } + + @computed get presPinViewOptionsDropdown() { + const activeItem: Doc = this.activeItem; + const targetDoc: Doc = this.targetDoc; + const presPinWithViewIcon = ; + return ( + <> + {this.panable || this.scrollable || this.targetDoc.type === DocumentType.COMPARISON ? 'Pinned view' : (null)} +
+
{activeItem.presPinView ? "Turn off pin with view" : "Turn on pin with view"}
}>
{ + activeItem.presPinView = !activeItem.presPinView; + targetDoc.presPinView = activeItem.presPinView; + if (activeItem.presPinView) { + if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.WEB || targetDoc._viewType === CollectionViewType.Stacking) { + const scroll = targetDoc._scrollTop; + activeItem.presPinView = true; + activeItem.presPinViewScroll = scroll; + } else if (targetDoc.type === DocumentType.VID) { + activeItem.presPinTimecode = targetDoc._currentTimecode; + } else if ((targetDoc.type === DocumentType.COL && targetDoc._viewType === CollectionViewType.Freeform) || targetDoc.type === DocumentType.IMG) { + const x = targetDoc._panX; + const y = targetDoc._panY; + const scale = targetDoc._viewScale; + activeItem.presPinView = true; + activeItem.presPinViewX = x; + activeItem.presPinViewY = y; + activeItem.presPinViewScale = scale; + } else if (targetDoc.type === DocumentType.COMPARISON) { + const width = targetDoc._clipWidth; + activeItem.presPinClipWidth = width; + activeItem.presPinView = true; + } + } + }}>{presPinWithViewIcon}
+ {activeItem.presPinView ?
{"Update the pinned view with the view of the selected document"}
}>
{ + if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF) { + const scroll = targetDoc._scrollTop; + activeItem.presPinViewScroll = scroll; + } else if (targetDoc.type === DocumentType.VID) { + activeItem.presPinTimecode = targetDoc._currentTimecode; + } else if (targetDoc.type === DocumentType.COMPARISON) { + const clipWidth = targetDoc._clipWidth; + activeItem.presPinClipWidth = clipWidth; + } else { + const x = targetDoc._panX; + const y = targetDoc._panY; + const scale = targetDoc._viewScale; + activeItem.presPinViewX = x; + activeItem.presPinViewY = y; + activeItem.presPinViewScale = scale; + } + }}>Update
: (null)} +
+ + ); + } + + @computed get panOptionsDropdown() { + const activeItem: Doc = this.activeItem; + const targetDoc: Doc = this.targetDoc; + return ( + <> + {this.panable ?
+
+
Pan X
+
+ ) => { const val = e.target.value; activeItem.presPinViewX = Number(val); })} /> +
+
+
+
Pan Y
+
+ ) => { const val = e.target.value; activeItem.presPinViewY = Number(val); })} /> +
+
+
+
Scale
+
+ ) => { const val = e.target.value; activeItem.presPinViewScale = Number(val); })} /> +
+
+
: (null)} + + ); + } + + @computed get scrollOptionsDropdown() { + const activeItem: Doc = this.activeItem; + const targetDoc: Doc = this.targetDoc; + return ( + <> + {this.scrollable ?
+
+
Scroll
+
+ ) => { const val = e.target.value; activeItem.presPinViewScroll = Number(val); })} /> +
+
+
: (null)} + + ); + } +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From e72068df41088f2bd842733f0e45cdfb4d28e6de Mon Sep 17 00:00:00 2001 From: geireann <60007097+geireann@users.noreply.github.com> Date: Sun, 29 Nov 2020 13:24:34 +0800 Subject: pres trails temporal media and fixing group with up --- src/client/views/MainView.tsx | 2 +- .../views/collections/CollectionStackingView.tsx | 2 +- src/client/views/collections/TabDocView.tsx | 6 +- src/client/views/nodes/PresBox.tsx | 116 ++++++++++++++------- .../views/presentationview/PresElementBox.tsx | 2 +- 5 files changed, 83 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index b1e008dad..3c46e0f89 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -148,7 +148,7 @@ export class MainView extends React.Component { fa.faSearch, fa.faFileDownload, fa.faFileUpload, fa.faStop, fa.faCalculator, fa.faWindowMaximize, fa.faAddressCard, fa.faQuestionCircle, fa.faArrowLeft, fa.faArrowRight, fa.faArrowDown, fa.faArrowUp, fa.faBolt, fa.faBullseye, fa.faCaretUp, fa.faCat, fa.faCheck, fa.faChevronRight, fa.faChevronLeft, fa.faChevronDown, fa.faChevronUp, fa.faClone, fa.faCloudUploadAlt, fa.faCommentAlt, fa.faCompressArrowsAlt, fa.faCut, fa.faEllipsisV, fa.faEraser, fa.faExclamation, fa.faFileAlt, - fa.faFileAudio, fa.faFilePdf, fa.faFilm, fa.faFilter, fa.faFont, fa.faGlobeAmericas, fa.faGlobeAsia, fa.faHighlighter, fa.faLongArrowAltRight, fa.faMousePointer, + fa.faFileAudio, fa.faFileVideo, fa.faFilePdf, fa.faFilm, fa.faFilter, fa.faFont, fa.faGlobeAmericas, fa.faGlobeAsia, fa.faHighlighter, fa.faLongArrowAltRight, fa.faMousePointer, fa.faMusic, fa.faObjectGroup, fa.faPause, fa.faPen, fa.faPenNib, fa.faPhone, fa.faPlay, fa.faPortrait, fa.faRedoAlt, fa.faStamp, fa.faStickyNote, fa.faTimesCircle, fa.faThumbtack, fa.faTree, fa.faTv, fa.faUndoAlt, fa.faVideo, fa.faAsterisk, fa.faBrain, fa.faImage, fa.faPaintBrush, fa.faTimes, fa.faEye, fa.faArrowsAlt, fa.faQuoteLeft, fa.faSortAmountDown, fa.faAlignLeft, fa.faAlignCenter, fa.faAlignRight, fa.faHeading, fa.faRulerCombined, diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 35331cc15..4b3393e14 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -290,7 +290,7 @@ export class CollectionStackingView extends CollectionSubView (pos[axis] + pos1[axis]) / 2 ? 1 : 0; } }); - // const oldDocs = this.childDocs.length; + const oldDocs = this.childDocs.length; if (super.onInternalDrop(e, de)) { const droppedDocs = this.childDocs.slice().filter((d: Doc, ind: number) => ind >= oldDocs); // if the drop operation adds something to the end of the list, then use that as the new document (may be different than what was dropped e.g., in the case of a button which is dropped but which creates say, a note). const newDocs = droppedDocs.length ? droppedDocs : de.complete.docDragData.droppedDocuments; // if nothing was added to the end of the list, then presumably the dropped documents were already in the list, but possibly got reordered so we use them. diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 45fab480c..0f228bc06 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -172,9 +172,11 @@ export class TabDocView extends React.Component { const size: number = PresBox.Instance?._selectedArray.size; const presSelected: Doc | undefined = presArray && size ? presArray[size - 1] : undefined; Doc.AddDocToList(curPres, "data", pinDoc, presSelected); - if (pinDoc.type === "audio" && !audioRange) { + if (pinDoc.type === DocumentType.AUDIO || pinDoc.type === DocumentType.VID && !audioRange) { + pinDoc.mediaStart = "manual"; + pinDoc.mediaStop = "manual"; pinDoc.presStartTime = 0; - pinDoc.presEndTime = doc.duration; + pinDoc.presEndTime = pinDoc.type === DocumentType.AUDIO ? doc.duration : NumCast(doc["data-duration"]); } if (curPres.expandBoolean) pinDoc.presExpandInlineButton = true; const dview = CollectionDockingView.Instance.props.Document; diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 9fb07040d..ed2cb9fa1 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -210,7 +210,7 @@ export class PresBox extends ViewBoxBaseComponent break; } else { console.log("Title: " + this.childDocs[nextSelected].title); - this.gotoDocument(nextSelected); + this.gotoDocument(nextSelected, true); } } const targetNext = Cast(activeNext.presentationTargetDoc, Doc, null); @@ -276,7 +276,7 @@ export class PresBox extends ViewBoxBaseComponent //The function that is called when a document is clicked or reached through next or back. //it'll also execute the necessary actions if presentation is playing. - public gotoDocument = action((index: number) => { + public gotoDocument = action((index: number, group?: boolean) => { Doc.UnBrushAllDocs(); if (index >= 0 && index < this.childDocs.length) { this.rootDoc._itemIndex = index; @@ -292,9 +292,9 @@ export class PresBox extends ViewBoxBaseComponent if (presTargetDoc?.lastFrame !== undefined) { presTargetDoc._currentFrame = 0; } - this._selectedArray.clear(); + if (!group) this._selectedArray.clear(); this.childDocs[index] && this._selectedArray.set(this.childDocs[index], undefined); //Update selected array - if (this.layoutDoc._viewType === "stacking") this.navigateToElement(this.childDocs[index]); //Handles movement to element only when presTrail is list + if (this.layoutDoc._viewType === "stacking" && !group) this.navigateToElement(this.childDocs[index]); //Handles movement to element only when presTrail is list this.onHideDocument(); //Handles hide after/before } }); @@ -1073,7 +1073,7 @@ export class PresBox extends ViewBoxBaseComponent @computed get transitionDropdown() { const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; - const type: DocumentType = targetDoc.type; + const type = targetDoc.type; const isPresCollection: boolean = (targetDoc === this.layoutDoc.presCollection); const isPinWithView: boolean = BoolCast(activeItem.presPinView); if (activeItem && targetDoc) { @@ -1103,7 +1103,7 @@ export class PresBox extends ViewBoxBaseComponent
}
-
Transition Speed
+
Movement Speed
{isPresCollection ? (null) :
{"Hide after presented"}
}>
this.updateHideAfter(activeItem)}>Hide after
}
{"Open document in a new tab"}
}>
this.updateOpenDoc(activeItem)}>Open
- {(type === DocumentType.AUDIO || type === DocumentType.VID) ? (null) :
-
Slide Duration
-
- this.setDurationTime(e.target.value))} /> s + {(type === DocumentType.AUDIO || type === DocumentType.VID) ? (null) : <> +
+
Slide Duration
+
+ this.setDurationTime(e.target.value))} /> s
-
-
this.setDurationTime(String(duration), 1000))}> - -
-
this.setDurationTime(String(duration), -1000))}> - +
+
this.setDurationTime(String(duration), 1000))}> + +
+
this.setDurationTime(String(duration), -1000))}> + +
-
} - { this._batch = UndoManager.StartBatch("presDuration"); }} - onPointerUp={() => { if (this._batch) this._batch.end(); }} - onChange={(e: React.ChangeEvent) => { e.stopPropagation(); this.setDurationTime(e.target.value); }} - /> -
-
Short
-
Medium
-
Long
-
+ { this._batch = UndoManager.StartBatch("presDuration"); }} + onPointerUp={() => { if (this._batch) this._batch.end(); }} + onChange={(e: React.ChangeEvent) => { e.stopPropagation(); this.setDurationTime(e.target.value); }} + /> +
+
Short
+
Medium
+
Long
+
+ }
{isPresCollection ? (null) :
Effects @@ -1368,24 +1370,24 @@ export class PresBox extends ViewBoxBaseComponent
activeItem.mediaPlay = "manual"} - checked={activeItem.mediaPlay === "manual"} + onChange={() => activeItem.mediaStart = "manual"} + checked={activeItem.mediaStart === "manual"} />
Start manually
activeItem.mediaPlay = "auto"} - checked={activeItem.mediaPlay === "auto"} + onChange={() => activeItem.mediaStart = "auto"} + checked={activeItem.mediaStart === "auto"} />
Play with slide
activeItem.mediaPlay = "onClick"} - checked={activeItem.mediaPlay === "onClick"} + onChange={() => activeItem.mediaStart = "onClick"} + checked={activeItem.mediaStart === "onClick"} />
Play on click
@@ -1432,8 +1434,42 @@ export class PresBox extends ViewBoxBaseComponent
Range:
+
+
+ Start time: +
+
+ Duration: +
+
+ End time: +
+
+
+
+
+ ) => { activeItem.presStartTime = Number(e.target.value); })} + /> s +
+
+
+ {Math.round((NumCast(activeItem.presEndTime) - NumCast(activeItem.presStartTime)) * 10) / 10} s +
+
+
+ ) => { activeItem.presEndTime = Number(e.target.value); })} + /> s +
+
+
- e.stopPropagation(); activeItem.presEndTime = Number(e.target.value); }} /> -
0 s
-
{Math.round(NumCast(activeItem.duration))} s
+
{activeItem.type === DocumentType.AUDIO ? Math.round(NumCast(activeItem.duration) * 10) / 10 : Math.round(NumCast(activeItem["data-duration"]) * 10) / 10} s
{/*
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index 9ec39b792..23f0dbdee 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -117,7 +117,7 @@ export class PresElementBox extends ViewBoxBaseComponent Date: Mon, 30 Nov 2020 11:10:23 +0800 Subject: Audio updates --- src/client/views/PropertiesView.tsx | 4 +- src/client/views/collections/TabDocView.tsx | 2 +- src/client/views/nodes/PresBox.tsx | 83 ++++++++++------------ .../views/presentationview/PresElementBox.tsx | 2 +- 4 files changed, 42 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index c656a020e..bdba625f8 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -1016,7 +1016,7 @@ export class PropertiesView extends React.Component { {PresBox.Instance.transitionDropdown}
: null}
} - {/* {!selectedItem || type === DocumentType.VID || type === DocumentType.AUDIO ? (null) :
+ {!selectedItem || type === DocumentType.VID || type === DocumentType.AUDIO ? (null) :
this.openPresProgressivize = !this.openPresProgressivize)} style={{ backgroundColor: this.openPresProgressivize ? "black" : "" }}> @@ -1028,7 +1028,7 @@ export class PropertiesView extends React.Component { {this.openPresProgressivize ?
{PresBox.Instance.progressivizeDropdown}
: null} -
} */} +
} {!selectedItem || (type !== DocumentType.VID && type !== DocumentType.AUDIO) ? (null) :
{ this.openSlideOptions = !this.openSlideOptions; })} diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 0f228bc06..258cdc4f7 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -172,7 +172,7 @@ export class TabDocView extends React.Component { const size: number = PresBox.Instance?._selectedArray.size; const presSelected: Doc | undefined = presArray && size ? presArray[size - 1] : undefined; Doc.AddDocToList(curPres, "data", pinDoc, presSelected); - if (pinDoc.type === DocumentType.AUDIO || pinDoc.type === DocumentType.VID && !audioRange) { + if (!audioRange && (pinDoc.type === DocumentType.AUDIO || pinDoc.type === DocumentType.VID)) { pinDoc.mediaStart = "manual"; pinDoc.mediaStop = "manual"; pinDoc.presStartTime = 0; diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index ed2cb9fa1..54818f67e 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -191,18 +191,20 @@ export class PresBox extends ViewBoxBaseComponent // 'Play on next' for audio or video therefore first navigate to the audio/video before it should be played nextAudioVideo = (targetDoc: Doc, activeItem: Doc) => { if (targetDoc.type === DocumentType.AUDIO) { + console.log("play audio"); targetDoc._audioStart = NumCast(activeItem.presStartTime); - } else if (targetDoc.type === DocumentType.VID) { - targetDoc._currentTimecode = NumCast(activeItem.presStartTime); - setTimeout(() => targetDoc._videoStart = true, 0); + console.log("play video"); + targetDoc._videoStop = true; + setTimeout(() => targetDoc._currentTimecode = NumCast(activeItem.presStartTime), 10); + setTimeout(() => targetDoc._videoStart = true, 20); } - // if (targetDoc.type === DocumentType.VID) { VideoBox.Instance.Play() }; activeItem.playNow = false; } // No more frames in current doc and next slide is defined, therefore move to next slide nextSlide = (targetDoc: Doc, activeNext: Doc) => { + const targetNext = Cast(activeNext.presentationTargetDoc, Doc, null); let nextSelected = this.itemIndex + 1; this.gotoDocument(nextSelected); for (nextSelected = nextSelected + 1; nextSelected < this.childDocs.length; nextSelected++) { @@ -213,11 +215,12 @@ export class PresBox extends ViewBoxBaseComponent this.gotoDocument(nextSelected, true); } } - const targetNext = Cast(activeNext.presentationTargetDoc, Doc, null); // If next slide is audio / video 'Play automatically' then the next slide should be played - if (activeNext && (targetNext.type === DocumentType.AUDIO || targetNext.type === DocumentType.VID) && activeNext.playAuto) { - if (targetNext.type === DocumentType.AUDIO) targetNext._audioStart = NumCast(activeNext.presStartTime); - } else if (targetNext.type === DocumentType.AUDIO || targetNext.type === DocumentType.VID) { activeNext.playNow = true; console.log('play next after it is navigated to'); } + if ((targetDoc.type === DocumentType.AUDIO || targetDoc.type === DocumentType.VID) && (activeNext.mediaStart === "auto" || activeNext.playNow)) { + this.nextAudioVideo(targetNext, activeNext); + } else if ((targetDoc.type === DocumentType.AUDIO || targetDoc.type === DocumentType.VID) && !activeNext.playNow && activeNext.mediaStart === "onClick") { + activeNext.playNow = true; + } } // Called when the user activates 'next' - to move to the next part of the pres. trail @@ -234,14 +237,11 @@ export class PresBox extends ViewBoxBaseComponent // Case 1: There are still other frames and should go through all frames before going to next slide this.nextInternalFrame(targetDoc, activeItem); } else if (this.childDocs[this.itemIndex + 1] !== undefined) { - // Case 3: No more frames in current doc and next slide is defined, therefore move to next slide + // Case 2: No more frames in current doc and next slide is defined, therefore move to next slide this.nextSlide(targetDoc, activeNext); - } else if (this.childDocs[this.itemIndex + 1] === undefined && this.layoutDoc.presLoop) { - // Case 4: Last slide and presLoop is toggled ON + } else if (this.childDocs[this.itemIndex + 1] === undefined && (this.layoutDoc.presLoop || this.layoutDoc.presStatus === PresStatus.Edit)) { + // Case 3: Last slide and presLoop is toggled ON or it is in Edit mode this.gotoDocument(0); - } else if ((targetDoc.type === DocumentType.AUDIO || targetDoc.type === DocumentType.VID) && !activeItem.playAuto && activeItem.playNow && this.layoutDoc.presStatus !== PresStatus.Autoplay) { - // Case 2: 'Play on next' for audio or video therefore first navigate to the audio/video before it should be played - this.nextAudioVideo(targetDoc, activeItem); } } @@ -517,10 +517,9 @@ export class PresBox extends ViewBoxBaseComponent try { doc.opacity = 1; } catch (e) { - console.log("REset presentation error: ", e); + console.log("Reset presentation error: ", e); } }); - ///for (const doc of this.childDocs) Cast(doc.presentationTargetDoc, Doc, null).opacity = 1; } @action togglePath = (srcContext: Doc, off?: boolean) => { @@ -628,6 +627,8 @@ export class PresBox extends ViewBoxBaseComponent if (doc.type === DocumentType.LABEL) { const audio = Cast(doc.annotationOn, Doc, null); if (audio) { + audio.mediaStart = "manual"; + audio.mediaStop = "manual"; audio.presStartTime = NumCast(doc.audioStart); audio.presEndTime = NumCast(doc.audioEnd); audio.presDuration = NumCast(doc.audioEnd) - NumCast(doc.audioStart); @@ -1365,6 +1366,18 @@ export class PresBox extends ViewBoxBaseComponent
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
+
Range:
+
+
+ Start time: +
+
+ Duration: +
+
+ End time: +
+
Start playing:
@@ -1373,7 +1386,7 @@ export class PresBox extends ViewBoxBaseComponent onChange={() => activeItem.mediaStart = "manual"} checked={activeItem.mediaStart === "manual"} /> -
Start manually
+
Play manually
onChange={() => activeItem.mediaStart = "auto"} checked={activeItem.mediaStart === "auto"} /> -
Play with slide
-
-
- activeItem.mediaStart = "onClick"} - checked={activeItem.mediaStart === "onClick"} - /> -
Play on click
+
Play automatically (with slide)
Stop playing:
@@ -1400,7 +1405,7 @@ export class PresBox extends ViewBoxBaseComponent onChange={() => activeItem.mediaStop = "manual"} checked={activeItem.mediaStop === "manual"} /> -
Stop manually
+
Stop at end time
onChange={() => activeItem.mediaStop = "afterCurrent"} checked={activeItem.mediaStop === "afterCurrent"} /> -
After current slide
+
Stop automatically (current slide)
onChange={() => activeItem.mediaStop = "afterSlide"} checked={activeItem.mediaStop === "afterSlide"} /> -
After slide +
Stop after slide {activeItem.mediaStop !== "afterSlide" ? (null) : @@ -1433,18 +1438,6 @@ export class PresBox extends ViewBoxBaseComponent
-
Range:
-
-
- Start time: -
-
- Duration: -
-
- End time: -
-
@@ -1673,10 +1666,10 @@ export class PresBox extends ViewBoxBaseComponent return (
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
{ this.updateMinimize(); this.turnOffEdit(true); }))}> - Minimize + Mini-player
{ this.layoutDoc.presStatus = "manual"; this.turnOffEdit(true); }))}> - Sidebar view + Sidebar player
); @@ -1746,7 +1739,7 @@ export class PresBox extends ViewBoxBaseComponent return (
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}> - {/*
+
{this.stringType} selected
Contents
@@ -1772,7 +1765,7 @@ export class PresBox extends ViewBoxBaseComponent
Scroll
Edit
-
*/} +
Frames
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index 23f0dbdee..0d1defbfe 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -326,7 +326,7 @@ export class PresElementBox extends ViewBoxBaseComponent -
+
Date: Mon, 30 Nov 2020 16:21:56 +0800 Subject: fixes and minor changes to temporal media settings in pres. trails --- src/client/views/.DS_Store | Bin 10244 -> 10244 bytes src/client/views/PropertiesView.tsx | 2 +- src/client/views/nodes/PresBox.scss | 3 +- src/client/views/nodes/PresBox.tsx | 117 ++++++++++----------- .../views/presentationview/PresElementBox.scss | 66 ++++++------ 5 files changed, 92 insertions(+), 96 deletions(-) (limited to 'src') diff --git a/src/client/views/.DS_Store b/src/client/views/.DS_Store index c6f3afa14..60b336584 100644 Binary files a/src/client/views/.DS_Store and b/src/client/views/.DS_Store differ diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index bdba625f8..a9076fea7 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -1020,7 +1020,7 @@ export class PropertiesView extends React.Component {
this.openPresProgressivize = !this.openPresProgressivize)} style={{ backgroundColor: this.openPresProgressivize ? "black" : "" }}> -     Progressivize +     Progressivize
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss index 6579dbf41..7cb304f13 100644 --- a/src/client/views/nodes/PresBox.scss +++ b/src/client/views/nodes/PresBox.scss @@ -1,6 +1,7 @@ $light-blue: #AEDDF8; $dark-blue: #5B9FDD; $light-background: #ececec; +$dark-grey: #656565; .presBox-cont { cursor: auto; @@ -629,7 +630,7 @@ $light-background: #ececec; position: relative; font-size: 13; padding-bottom: 10px; - border-bottom: solid 1px darkgrey; + border-bottom: solid 1px $dark-grey; .presBox-dropdown:hover { border: solid 1px $dark-blue; diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 54818f67e..b1434f149 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -1367,7 +1367,7 @@ export class PresBox extends ViewBoxBaseComponent
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
Range:
-
+
Start time:
@@ -1378,6 +1378,52 @@ export class PresBox extends ViewBoxBaseComponent End time:
+
+
+ ) => { activeItem.presStartTime = Number(e.target.value); })} + /> s +
+
+ {Math.round((NumCast(activeItem.presEndTime) - NumCast(activeItem.presStartTime)) * 10) / 10} s +
+
+ ) => { activeItem.presEndTime = Number(e.target.value); })} + /> s +
+
+
+ this._batch = UndoManager.StartBatch("presEndTime")} + onPointerUp={() => this._batch?.end()} + onChange={(e: React.ChangeEvent) => { + e.stopPropagation(); + activeItem.presEndTime = Number(e.target.value); + }} /> + this._batch = UndoManager.StartBatch("presEndTime")} + onPointerUp={() => this._batch?.end()} + onChange={(e: React.ChangeEvent) => { + e.stopPropagation(); + activeItem.presStartTime = Number(e.target.value); + }} /> +
+
+
0 s
+
+
{activeItem.type === DocumentType.AUDIO ? Math.round(NumCast(activeItem.duration) * 10) / 10 : Math.round(NumCast(activeItem["data-duration"]) * 10) / 10} s
+
Start playing:
@@ -1425,69 +1471,18 @@ export class PresBox extends ViewBoxBaseComponent {activeItem.mediaStop !== "afterSlide" ? (null) : -
{ e.stopPropagation(); this.openMovementDropdown = !this.openMovementDropdown; })} style={{ borderBottomLeftRadius: this.openMovementDropdown ? 0 : 5, border: this.openMovementDropdown ? `solid 2px ${PresColor.DarkBlue}` : 'solid 1px black' }}> - {this.setMovementName(activeItem.presMovement, activeItem)} - -
e.stopPropagation()} style={{ display: this.openMovementDropdown ? "grid" : "none" }}> -
e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.None)}>None
-
e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Zoom)}>Pan {"&"} Zoom
-
e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Pan)}>Pan
-
e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Jump)}>Jump cut
-
-
} -
-
-
-
-
-
- ) => { activeItem.presStartTime = Number(e.target.value); })} - /> s -
-
-
- {Math.round((NumCast(activeItem.presEndTime) - NumCast(activeItem.presStartTime)) * 10) / 10} s -
-
-
- ) => { activeItem.presEndTime = Number(e.target.value); })} - /> s + <> + // } + }
-
- this._batch = UndoManager.StartBatch("presEndTime")} - onPointerUp={() => this._batch?.end()} - onChange={(e: React.ChangeEvent) => { - e.stopPropagation(); - activeItem.presEndTime = Number(e.target.value); - }} /> - this._batch = UndoManager.StartBatch("presEndTime")} - onPointerUp={() => this._batch?.end()} - onChange={(e: React.ChangeEvent) => { - e.stopPropagation(); - activeItem.presStartTime = Number(e.target.value); - }} /> -
-
-
0 s
-
-
{activeItem.type === DocumentType.AUDIO ? Math.round(NumCast(activeItem.duration) * 10) / 10 : Math.round(NumCast(activeItem["data-duration"]) * 10) / 10} s
-
{/*
diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss index e1eeefc30..1ad4b820e 100644 --- a/src/client/views/presentationview/PresElementBox.scss +++ b/src/client/views/presentationview/PresElementBox.scss @@ -157,39 +157,39 @@ $slide-active: #5B9FDD; } // .presItem-slide:hover { - // .presItem-slideButtons { - // display: flex; - // grid-column: 7; - // grid-row: 1/3; - // width: max-content; - // justify-self: right; - // justify-content: flex-end; - - // .slideButton { - // cursor: pointer; - // position: relative; - // border-radius: 100px; - // z-index: 300; - // width: 18px; - // height: 18px; - // display: flex; - // font-size: 12px; - // justify-self: center; - // align-self: center; - // background-color: rgba(0, 0, 0, 0.5); - // color: white; - // justify-content: center; - // align-items: center; - // transition: 0.2s; - // margin-right: 3px; - // } - - // .slideButton:hover { - // background-color: rgba(0, 0, 0, 1); - // transform: scale(1.2); - // } - // } - // } +// .presItem-slideButtons { +// display: flex; +// grid-column: 7; +// grid-row: 1/3; +// width: max-content; +// justify-self: right; +// justify-content: flex-end; + +// .slideButton { +// cursor: pointer; +// position: relative; +// border-radius: 100px; +// z-index: 300; +// width: 18px; +// height: 18px; +// display: flex; +// font-size: 12px; +// justify-self: center; +// align-self: center; +// background-color: rgba(0, 0, 0, 0.5); +// color: white; +// justify-content: center; +// align-items: center; +// transition: 0.2s; +// margin-right: 3px; +// } + +// .slideButton:hover { +// background-color: rgba(0, 0, 0, 1); +// transform: scale(1.2); +// } +// } +// } .presItem-slide.active { box-shadow: 0 0 0px 1.5px $dark-blue; -- cgit v1.2.3-70-g09d2 From d48c388ac906f9e91f4e91321398be7eb4d8d2fb Mon Sep 17 00:00:00 2001 From: geireann <60007097+geireann@users.noreply.github.com> Date: Tue, 1 Dec 2020 00:23:04 +0800 Subject: UI mini changes --- src/client/views/nodes/PresBox.scss | 7 +++ src/client/views/nodes/PresBox.tsx | 61 +++++++++++++++------- .../views/presentationview/PresElementBox.tsx | 2 +- 3 files changed, 49 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss index 7cb304f13..d0d80e012 100644 --- a/src/client/views/nodes/PresBox.scss +++ b/src/client/views/nodes/PresBox.scss @@ -137,6 +137,13 @@ $dark-grey: #656565; height: 20px; align-items: center; } + + .checkbox-dropdown { + display: flex; + width: 100%; + align-items: flex-end; + gap: 5px; + } } .presBox-ribbon { diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index b1434f149..1e9916689 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -28,6 +28,7 @@ import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView import { FieldView, FieldViewProps } from './FieldView'; import "./PresBox.scss"; import Color = require("color"); +import { clear } from "console"; export enum PresMovement { Zoom = "zoom", @@ -190,20 +191,21 @@ export class PresBox extends ViewBoxBaseComponent // 'Play on next' for audio or video therefore first navigate to the audio/video before it should be played nextAudioVideo = (targetDoc: Doc, activeItem: Doc) => { + const duration: number = NumCast(activeItem.presEndTime) - NumCast(activeItem.presStartTime); if (targetDoc.type === DocumentType.AUDIO) { console.log("play audio"); targetDoc._audioStart = NumCast(activeItem.presStartTime); + setTimeout(() => targetDoc._audioStop = true, duration * 1000); } else if (targetDoc.type === DocumentType.VID) { - console.log("play video"); targetDoc._videoStop = true; setTimeout(() => targetDoc._currentTimecode = NumCast(activeItem.presStartTime), 10); setTimeout(() => targetDoc._videoStart = true, 20); + setTimeout(() => targetDoc._videoStop = true, (duration * 1000) + 20); } - activeItem.playNow = false; } // No more frames in current doc and next slide is defined, therefore move to next slide - nextSlide = (targetDoc: Doc, activeNext: Doc) => { + nextSlide = (activeNext: Doc) => { const targetNext = Cast(activeNext.presentationTargetDoc, Doc, null); let nextSelected = this.itemIndex + 1; this.gotoDocument(nextSelected); @@ -216,10 +218,8 @@ export class PresBox extends ViewBoxBaseComponent } } // If next slide is audio / video 'Play automatically' then the next slide should be played - if ((targetDoc.type === DocumentType.AUDIO || targetDoc.type === DocumentType.VID) && (activeNext.mediaStart === "auto" || activeNext.playNow)) { + if ((targetNext.type === DocumentType.AUDIO || targetNext.type === DocumentType.VID) && (activeNext.mediaStart === "auto")) { this.nextAudioVideo(targetNext, activeNext); - } else if ((targetDoc.type === DocumentType.AUDIO || targetDoc.type === DocumentType.VID) && !activeNext.playNow && activeNext.mediaStart === "onClick") { - activeNext.playNow = true; } } @@ -238,7 +238,7 @@ export class PresBox extends ViewBoxBaseComponent this.nextInternalFrame(targetDoc, activeItem); } else if (this.childDocs[this.itemIndex + 1] !== undefined) { // Case 2: No more frames in current doc and next slide is defined, therefore move to next slide - this.nextSlide(targetDoc, activeNext); + this.nextSlide(activeNext); } else if (this.childDocs[this.itemIndex + 1] === undefined && (this.layoutDoc.presLoop || this.layoutDoc.presStatus === PresStatus.Edit)) { // Case 3: Last slide and presLoop is toggled ON or it is in Edit mode this.gotoDocument(0); @@ -605,6 +605,17 @@ export class PresBox extends ViewBoxBaseComponent if (viewType === CollectionViewType.Stacking) this.layoutDoc._gridGap = 0; }); + /** + * Called when the user changes the view type + * Either 'List' (stacking) or 'Slides' (carousel) + */ + // @undoBatch + mediaStopChanged = action((e: React.ChangeEvent) => { + const activeItem: Doc = this.activeItem; + //@ts-ignore + activeItem.mediaStopDoc = e.target.selectedOptions[0].value as Doc; + }); + setMovementName = action((movement: any, activeItem: Doc): string => { let output: string = 'none'; @@ -1358,6 +1369,18 @@ export class PresBox extends ViewBoxBaseComponent ); } + @computed get mediaStopSlides() { + const activeItem: Doc = this.activeItem; + const list = this.childDocs.map((doc) => { + return ( + + ); + }) + return ( + list + ); + } + @computed get mediaOptionsDropdown() { const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; @@ -1432,7 +1455,7 @@ export class PresBox extends ViewBoxBaseComponent onChange={() => activeItem.mediaStart = "manual"} checked={activeItem.mediaStart === "manual"} /> -
Play manually
+
On click
onChange={() => activeItem.mediaStart = "auto"} checked={activeItem.mediaStart === "auto"} /> -
Play automatically (with slide)
+
Automatically
Stop playing:
@@ -1459,7 +1482,7 @@ export class PresBox extends ViewBoxBaseComponent onChange={() => activeItem.mediaStop = "afterCurrent"} checked={activeItem.mediaStop === "afterCurrent"} /> -
Stop automatically (current slide)
+
Stop on slide change
onChange={() => activeItem.mediaStop = "afterSlide"} checked={activeItem.mediaStop === "afterSlide"} /> -
Stop after slide +
Stop after chosen slide {activeItem.mediaStop !== "afterSlide" ? (null) : - <> - // } - } + }
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index 0d1defbfe..950ef77a1 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -75,7 +75,7 @@ export class PresElementBox extends ViewBoxBaseComponent 97; // embedWidth = () => this.props.PanelWidth(); // embedHeight = () => Math.min(this.props.PanelWidth() - 20, this.props.PanelHeight() - this.collapsedHeight); - embedWidth = (): number => this.props.PanelWidth() - 30; + embedWidth = (): number => this.props.PanelWidth() - 35; /** * The function that is responsible for rendering a preview or not for this * presentation element. -- cgit v1.2.3-70-g09d2 From 1a17c43b652916961216882286398641031a5a5e Mon Sep 17 00:00:00 2001 From: geireann <60007097+geireann@users.noreply.github.com> Date: Tue, 1 Dec 2020 17:08:26 +0800 Subject: temp media stop on change slide --- src/client/views/nodes/PresBox.scss | 7 ++ src/client/views/nodes/PresBox.tsx | 139 +++++++++++++-------- .../views/presentationview/PresElementBox.tsx | 2 +- 3 files changed, 95 insertions(+), 53 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss index d0d80e012..ba21cef42 100644 --- a/src/client/views/nodes/PresBox.scss +++ b/src/client/views/nodes/PresBox.scss @@ -134,6 +134,7 @@ $dark-grey: #656565; .checkbox-container { margin-left: 10px; display: inline-flex; + width: 100%; height: 20px; align-items: center; } @@ -143,6 +144,11 @@ $dark-grey: #656565; width: 100%; align-items: flex-end; gap: 5px; + + .presBox-viewPicker { + width: calc(100% - 120px); + min-width: 30px; + } } } @@ -308,6 +314,7 @@ $dark-grey: #656565; border-radius: 100%; height: 15px; width: 15px; + min-width: 15px; cursor: pointer; background: $light-background; } diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 1e9916689..e559b6ca3 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -189,18 +189,30 @@ export class PresBox extends ViewBoxBaseComponent else targetDoc.editing = true; } + _mediaTimer!: [NodeJS.Timeout, Doc]; // 'Play on next' for audio or video therefore first navigate to the audio/video before it should be played - nextAudioVideo = (targetDoc: Doc, activeItem: Doc) => { + startTempMedia = (targetDoc: Doc, activeItem: Doc) => { const duration: number = NumCast(activeItem.presEndTime) - NumCast(activeItem.presStartTime); if (targetDoc.type === DocumentType.AUDIO) { - console.log("play audio"); + if (this._mediaTimer && this._mediaTimer[1] === targetDoc) clearTimeout(this._mediaTimer[0]); targetDoc._audioStart = NumCast(activeItem.presStartTime); - setTimeout(() => targetDoc._audioStop = true, duration * 1000); + this._mediaTimer = [setTimeout(() => targetDoc._audioStop = true, duration * 1000), targetDoc]; } else if (targetDoc.type === DocumentType.VID) { + if (this._mediaTimer && this._mediaTimer[1] === targetDoc) clearTimeout(this._mediaTimer[0]); targetDoc._videoStop = true; setTimeout(() => targetDoc._currentTimecode = NumCast(activeItem.presStartTime), 10); setTimeout(() => targetDoc._videoStart = true, 20); - setTimeout(() => targetDoc._videoStop = true, (duration * 1000) + 20); + this._mediaTimer = [setTimeout(() => targetDoc._videoStop = true, (duration * 1000) + 20), targetDoc]; + } + } + + stopTempMedia = (targetDoc: Doc) => { + if (targetDoc.type === DocumentType.AUDIO) { + if (this._mediaTimer && this._mediaTimer[1] === targetDoc) clearTimeout(this._mediaTimer[0]); + targetDoc._audioStop = true; + } else if (targetDoc.type === DocumentType.VID) { + if (this._mediaTimer && this._mediaTimer[1] === targetDoc) clearTimeout(this._mediaTimer[0]); + targetDoc._videoStop = true; } } @@ -208,19 +220,15 @@ export class PresBox extends ViewBoxBaseComponent nextSlide = (activeNext: Doc) => { const targetNext = Cast(activeNext.presentationTargetDoc, Doc, null); let nextSelected = this.itemIndex + 1; - this.gotoDocument(nextSelected); + this.gotoDocument(nextSelected, this.activeItem); for (nextSelected = nextSelected + 1; nextSelected < this.childDocs.length; nextSelected++) { if (!this.childDocs[nextSelected].groupWithUp) { break; } else { console.log("Title: " + this.childDocs[nextSelected].title); - this.gotoDocument(nextSelected, true); + this.gotoDocument(nextSelected, this.activeItem, true); } } - // If next slide is audio / video 'Play automatically' then the next slide should be played - if ((targetNext.type === DocumentType.AUDIO || targetNext.type === DocumentType.VID) && (activeNext.mediaStart === "auto")) { - this.nextAudioVideo(targetNext, activeNext); - } } // Called when the user activates 'next' - to move to the next part of the pres. trail @@ -241,7 +249,7 @@ export class PresBox extends ViewBoxBaseComponent this.nextSlide(activeNext); } else if (this.childDocs[this.itemIndex + 1] === undefined && (this.layoutDoc.presLoop || this.layoutDoc.presStatus === PresStatus.Edit)) { // Case 3: Last slide and presLoop is toggled ON or it is in Edit mode - this.gotoDocument(0); + this.gotoDocument(0, this.activeItem); } } @@ -266,31 +274,38 @@ export class PresBox extends ViewBoxBaseComponent } else if (activeItem && this.childDocs[this.itemIndex - 1] !== undefined) { // Case 2: There are no other frames so it should go to the previous slide prevSelected = Math.max(0, prevSelected - 1); - this.gotoDocument(prevSelected); + this.gotoDocument(prevSelected, activeItem); if (NumCast(prevTargetDoc.lastFrame) > 0) prevTargetDoc._currentFrame = NumCast(prevTargetDoc.lastFrame); } else if (this.childDocs[this.itemIndex - 1] === undefined && this.layoutDoc.presLoop) { // Case 3: Pres loop is on so it should go to the last slide - this.gotoDocument(this.childDocs.length - 1); + this.gotoDocument(this.childDocs.length - 1, activeItem); } } //The function that is called when a document is clicked or reached through next or back. //it'll also execute the necessary actions if presentation is playing. - public gotoDocument = action((index: number, group?: boolean) => { + public gotoDocument = action((index: number, from?: Doc, group?: boolean) => { Doc.UnBrushAllDocs(); if (index >= 0 && index < this.childDocs.length) { this.rootDoc._itemIndex = index; const activeItem: Doc = this.activeItem; - const presTargetDoc = Cast(this.childDocs[this.itemIndex].presentationTargetDoc, Doc, null); - if (presTargetDoc) { - presTargetDoc && runInAction(() => { - if (activeItem.presMovement === PresMovement.Jump) presTargetDoc.focusSpeed = 0; - else presTargetDoc.focusSpeed = activeItem.presTransition ? activeItem.presTransition : 500; + const targetDoc: Doc = this.targetDoc; + if (from && from.mediaStop === "auto" && this.layoutDoc.presStatus !== PresStatus.Edit) { + this.stopTempMedia(Cast(from.presentationTargetDoc, Doc, null)); + } + // If next slide is audio / video 'Play automatically' then the next slide should be played + if (this.layoutDoc.presStatus !== PresStatus.Edit && (targetDoc.type === DocumentType.AUDIO || targetDoc.type === DocumentType.VID) && (activeItem.mediaStart === "auto")) { + this.startTempMedia(targetDoc, activeItem); + } + if (targetDoc) { + targetDoc && runInAction(() => { + if (activeItem.presMovement === PresMovement.Jump) targetDoc.focusSpeed = 0; + else targetDoc.focusSpeed = activeItem.presTransition ? activeItem.presTransition : 500; }); - setTimeout(() => presTargetDoc.focusSpeed = 500, this.activeItem.presTransition ? NumCast(this.activeItem.presTransition) + 10 : 510); + setTimeout(() => targetDoc.focusSpeed = 500, this.activeItem.presTransition ? NumCast(this.activeItem.presTransition) + 10 : 510); } - if (presTargetDoc?.lastFrame !== undefined) { - presTargetDoc._currentFrame = 0; + if (targetDoc?.lastFrame !== undefined) { + targetDoc._currentFrame = 0; } if (!group) this._selectedArray.clear(); this.childDocs[index] && this._selectedArray.set(this.childDocs[index], undefined); //Update selected array @@ -496,7 +511,7 @@ export class PresBox extends ViewBoxBaseComponent }; this.layoutDoc.presStatus = PresStatus.Autoplay; this.startPresentation(startSlide); - this.gotoDocument(startSlide); + this.gotoDocument(startSlide, activeItem); load(); } @@ -605,6 +620,14 @@ export class PresBox extends ViewBoxBaseComponent if (viewType === CollectionViewType.Stacking) this.layoutDoc._gridGap = 0; }); + + @action + updateMediaStopTriggerList = (list: any, activeItem: Doc): List => { + const x: List = list; + x.push(activeItem); + return x; + } + /** * Called when the user changes the view type * Either 'List' (stacking) or 'Slides' (carousel) @@ -613,7 +636,11 @@ export class PresBox extends ViewBoxBaseComponent mediaStopChanged = action((e: React.ChangeEvent) => { const activeItem: Doc = this.activeItem; //@ts-ignore - activeItem.mediaStopDoc = e.target.selectedOptions[0].value as Doc; + const stopDoc = e.target.selectedOptions[0].value as string; + const stopDocIndex: number = Number(stopDoc[0]); + activeItem.mediaStopDoc = stopDocIndex; + const newList = this.updateMediaStopTriggerList(this.childDocs[stopDocIndex].mediaStopTriggerList, activeItem) + this.childDocs[stopDocIndex].mediaStopTriggerList = newList; }); @@ -702,7 +729,7 @@ export class PresBox extends ViewBoxBaseComponent @action selectElement = (doc: Doc) => { const context = Cast(doc.context, Doc, null); - this.gotoDocument(this.childDocs.indexOf(doc)); + this.gotoDocument(this.childDocs.indexOf(doc), this.activeItem); if (doc.presPinView || doc.presentationTargetDoc === this.layoutDoc.presCollection) setTimeout(() => this.updateCurrentPresentation(context), 0); else this.updateCurrentPresentation(context); } @@ -1371,11 +1398,13 @@ export class PresBox extends ViewBoxBaseComponent @computed get mediaStopSlides() { const activeItem: Doc = this.activeItem; - const list = this.childDocs.map((doc) => { - return ( - - ); - }) + const list = this.childDocs.map((doc, i) => { + if (i > this.itemIndex) { + return ( + + ); + } + }); return ( list ); @@ -1384,6 +1413,8 @@ export class PresBox extends ViewBoxBaseComponent @computed get mediaOptionsDropdown() { const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; + const mediaStopDocInd: number = NumCast(activeItem.mediaStopDoc); + const mediaStopDocStr: string = mediaStopDocInd ? mediaStopDocInd + ". " + this.childDocs[mediaStopDocInd - 1].title : ""; if (activeItem && targetDoc) { return (
@@ -1474,15 +1505,15 @@ export class PresBox extends ViewBoxBaseComponent onChange={() => activeItem.mediaStop = "manual"} checked={activeItem.mediaStop === "manual"} /> -
Stop at end time
+
At audio end time
activeItem.mediaStop = "afterCurrent"} - checked={activeItem.mediaStop === "afterCurrent"} + onChange={() => activeItem.mediaStop = "auto"} + checked={activeItem.mediaStop === "auto"} /> -
Stop on slide change
+
On slide change
onChange={() => activeItem.mediaStop = "afterSlide"} checked={activeItem.mediaStop === "afterSlide"} /> -
Stop after chosen slide - {activeItem.mediaStop !== "afterSlide" ? - (null) - : - } +
+ After chosen slide +
@@ -1631,7 +1660,7 @@ export class PresBox extends ViewBoxBaseComponent if (data && presData) { data.push(doc); TabDocView.PinDoc(doc, false); - this.gotoDocument(this.childDocs.length); + this.gotoDocument(this.childDocs.length, this.activeItem); } else { this.props.addDocTab(doc, "add:right"); } @@ -1681,10 +1710,10 @@ export class PresBox extends ViewBoxBaseComponent @computed get presentDropdown() { return (
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}> -
{ this.updateMinimize(); this.turnOffEdit(true); }))}> +
{ this.updateMinimize(); this.turnOffEdit(true); this.gotoDocument(this.itemIndex, this.activeItem); }))}> Mini-player
-
{ this.layoutDoc.presStatus = "manual"; this.turnOffEdit(true); }))}> +
{ this.layoutDoc.presStatus = "manual"; this.turnOffEdit(true); this.gotoDocument(this.itemIndex, this.activeItem); }))}> Sidebar player
@@ -2160,7 +2189,13 @@ export class PresBox extends ViewBoxBaseComponent }
-
(this.childDocs.length) && (this.layoutDoc.presStatus = "manual"))}> +
{ + if (this.childDocs.length) { + this.layoutDoc.presStatus = "manual"; + this.gotoDocument(this.itemIndex, this.activeItem); + } + })}>
200 ? "inline-flex" : "none" }}>  Present
@@ -2268,10 +2303,10 @@ export class PresBox extends ViewBoxBaseComponent
{this.layoutDoc.presStatus === PresStatus.Autoplay ? "Pause" : "Autoplay"}
}>
{ this.next(); if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } }}>
-
{"Click to return to 1st slide"}
}>
this.gotoDocument(0)}>1
+
{"Click to return to 1st slide"}
}>
this.gotoDocument(0, this.activeItem)}>1
this.gotoDocument(0)} + onClick={() => this.gotoDocument(0, this.activeItem)} style={{ display: this.props.PanelWidth() > 250 ? "inline-flex" : "none" }}> Slide {this.itemIndex + 1} / {this.childDocs.length} {this.playButtonFrames} @@ -2308,7 +2343,7 @@ export class PresBox extends ViewBoxBaseComponent
{this.layoutDoc.presStatus === PresStatus.Autoplay ? "Pause" : "Autoplay"}
}>
{ this.next(); if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } }}>
-
{"Click to return to 1st slide"}
}>
this.gotoDocument(0)}>1
+
{"Click to return to 1st slide"}
}>
this.gotoDocument(0, this.activeItem)}>1
Slide {this.itemIndex + 1} / {this.childDocs.length} {this.playButtonFrames} diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index 950ef77a1..80faf1a69 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -344,7 +344,7 @@ export class PresElementBox extends ViewBoxBaseComponent this.updateView(targetDoc, activeItem)} style={{ fontWeight: 700, display: activeItem.presPinView ? "flex" : "none" }}>V
- {this.indexInPres === 0 ? (null) :
{"Group with up"}
}> + {this.indexInPres === 0 ? (null) :
{activeItem.groupWithUp ? "Ungroup" : "Group with up"}
}>
activeItem.groupWithUp = !activeItem.groupWithUp} style={{ -- cgit v1.2.3-70-g09d2 From d8c644b1e219042cd15b1ac05df899d74c5c926f Mon Sep 17 00:00:00 2001 From: geireann <60007097+geireann@users.noreply.github.com> Date: Tue, 1 Dec 2020 20:31:17 +0800 Subject: small changes to temp audio stopping (not final) --- src/client/views/nodes/PresBox.tsx | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index e559b6ca3..d21e1603d 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -290,6 +290,12 @@ export class PresBox extends ViewBoxBaseComponent this.rootDoc._itemIndex = index; const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; + if (from && from.mediaStopTriggerList && this.layoutDoc.presStatus !== PresStatus.Edit) { + const mediaDocList = DocListCast(from.mediaStopTriggerList); + mediaDocList.forEach((doc) => { + this.stopTempMedia(Cast(doc.presentationTargetDoc, Doc, null)); + }); + } if (from && from.mediaStop === "auto" && this.layoutDoc.presStatus !== PresStatus.Edit) { this.stopTempMedia(Cast(from.presentationTargetDoc, Doc, null)); } @@ -620,14 +626,6 @@ export class PresBox extends ViewBoxBaseComponent if (viewType === CollectionViewType.Stacking) this.layoutDoc._gridGap = 0; }); - - @action - updateMediaStopTriggerList = (list: any, activeItem: Doc): List => { - const x: List = list; - x.push(activeItem); - return x; - } - /** * Called when the user changes the view type * Either 'List' (stacking) or 'Slides' (carousel) @@ -639,8 +637,14 @@ export class PresBox extends ViewBoxBaseComponent const stopDoc = e.target.selectedOptions[0].value as string; const stopDocIndex: number = Number(stopDoc[0]); activeItem.mediaStopDoc = stopDocIndex; - const newList = this.updateMediaStopTriggerList(this.childDocs[stopDocIndex].mediaStopTriggerList, activeItem) - this.childDocs[stopDocIndex].mediaStopTriggerList = newList; + if (this.childDocs[stopDocIndex - 1].mediaStopTriggerList) { + const list = DocListCast(this.childDocs[stopDocIndex - 1].mediaStopTriggerList); + list.push(activeItem); + } else { + this.childDocs[stopDocIndex - 1].mediaStopTriggerList = new List(); + const list = DocListCast(this.childDocs[stopDocIndex - 1].mediaStopTriggerList); + list.push(activeItem); + } }); -- cgit v1.2.3-70-g09d2 From e8f23ca09b04870ae8b265526d912c2244176bb0 Mon Sep 17 00:00:00 2001 From: geireann <60007097+geireann@users.noreply.github.com> Date: Tue, 1 Dec 2020 22:11:26 +0800 Subject: Removed temp presProperties --- .../views/presentationview/PresProperties.tsx | 492 --------------------- 1 file changed, 492 deletions(-) delete mode 100644 src/client/views/presentationview/PresProperties.tsx (limited to 'src') diff --git a/src/client/views/presentationview/PresProperties.tsx b/src/client/views/presentationview/PresProperties.tsx deleted file mode 100644 index edad41861..000000000 --- a/src/client/views/presentationview/PresProperties.tsx +++ /dev/null @@ -1,492 +0,0 @@ -import React from "react"; -import { action, computed, observable, reaction } from "mobx"; -import { Doc } from "../../../fields/Doc"; -import { BoolCast, Cast, NumCast } from "../../../fields/Types"; -import { undoBatch, UndoManager } from "../../util/UndoManager"; -import { PresBox, PresColor, PresEffect, PresMovement } from "../nodes/PresBox"; -import { DocumentType } from "../../documents/DocumentTypes"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { CollectionViewType } from "../collections/CollectionView"; -import { Tooltip } from "@material-ui/core"; - - -export class PresProperties { - - @observable public static Instance: PresProperties; - - @computed get pres(): PresBox { return PresBox.Instance; } - - @computed get activeItem() { return Cast(this.pres.childDocs[NumCast(PresBox.Instance.rootDoc._itemIndex)], Doc, null); } - @computed get targetDoc() { return Cast(this.pres.activeItem?.presentationTargetDoc, Doc, null); } - - @computed get scrollable(): boolean { - if (this.targetDoc.type === DocumentType.PDF || this.targetDoc.type === DocumentType.WEB || this.targetDoc.type === DocumentType.RTF || this.targetDoc._viewType === CollectionViewType.Stacking) return true; - else return false; - } - @computed get panable(): boolean { - if ((this.targetDoc.type === DocumentType.COL && this.targetDoc._viewType === CollectionViewType.Freeform) || this.targetDoc.type === DocumentType.IMG) return true; - else return false; - } - - - @observable private openMovementDropdown: boolean = false; - @observable private openEffectDropdown: boolean = false; - - _batch: UndoManager.Batch | undefined = undefined; - - - @computed get effectDirection(): string { - let effect = ''; - switch (this.targetDoc.presEffectDirection) { - case 'left': effect = "Enter from left"; break; - case 'right': effect = "Enter from right"; break; - case 'top': effect = "Enter from top"; break; - case 'bottom': effect = "Enter from bottom"; break; - default: effect = "Enter from center"; break; - } - return effect; - } - - @undoBatch - @action - updateHideBefore = (activeItem: Doc) => { - activeItem.presHideBefore = !activeItem.presHideBefore; - Array.from(this.pres._selectedArray.keys()).forEach((doc) => doc.presHideBefore = activeItem.presHideBefore); - } - - @undoBatch - @action - updateHideAfter = (activeItem: Doc) => { - activeItem.presHideAfter = !activeItem.presHideAfter; - Array.from(this.pres._selectedArray.keys()).forEach((doc) => doc.presHideAfter = activeItem.presHideAfter); - } - - @undoBatch - @action - updateOpenDoc = (activeItem: Doc) => { - activeItem.openDocument = !activeItem.openDocument; - Array.from(this.pres._selectedArray.keys()).forEach((doc) => { - doc.openDocument = activeItem.openDocument; - }); - } - - /** - * When the movement dropdown is changes - */ - @undoBatch - updateMovement = action((movement: any, all?: boolean) => { - const array: any[] = all ? this.pres.childDocs : Array.from(this.pres._selectedArray.keys()); - array.forEach((doc) => { - switch (movement) { - case PresMovement.Zoom: //Pan and zoom - doc.presMovement = PresMovement.Zoom; - break; - case PresMovement.Pan: //Pan - doc.presMovement = PresMovement.Pan; - break; - case PresMovement.Jump: //Jump Cut - doc.presJump = true; - doc.presMovement = PresMovement.Jump; - break; - case PresMovement.None: default: - doc.presMovement = PresMovement.None; - break; - } - }); - }); - - @undoBatch - @action - updateEffect = (effect: any, all?: boolean) => { - const array: any[] = all ? this.pres.childDocs : Array.from(this.pres._selectedArray.keys()); - array.forEach((doc) => { - const tagDoc = Cast(doc.presentationTargetDoc, Doc, null); - switch (effect) { - case PresEffect.Bounce: - tagDoc.presEffect = PresEffect.Bounce; - break; - case PresEffect.Fade: - tagDoc.presEffect = PresEffect.Fade; - break; - case PresEffect.Flip: - tagDoc.presEffect = PresEffect.Flip; - break; - case PresEffect.Roll: - tagDoc.presEffect = PresEffect.Roll; - break; - case PresEffect.Rotate: - tagDoc.presEffect = PresEffect.Rotate; - break; - case PresEffect.None: default: - tagDoc.presEffect = PresEffect.None; - break; - } - }); - } - - @undoBatch - @action - updateEffectDirection = (effect: any, all?: boolean) => { - const array: any[] = all ? this.pres.childDocs : Array.from(this.pres._selectedArray.keys()); - array.forEach((doc) => { - const tagDoc = Cast(doc.presentationTargetDoc, Doc, null); - switch (effect) { - case PresEffect.Left: - tagDoc.presEffectDirection = PresEffect.Left; - break; - case PresEffect.Right: - tagDoc.presEffectDirection = PresEffect.Right; - break; - case PresEffect.Top: - tagDoc.presEffectDirection = PresEffect.Top; - break; - case PresEffect.Bottom: - tagDoc.presEffectDirection = PresEffect.Bottom; - break; - case PresEffect.Center: default: - tagDoc.presEffectDirection = PresEffect.Center; - break; - } - }); - } - - // Converts seconds to ms and updates presTransition - setTransitionTime = (number: String, change?: number) => { - let timeInMS = Number(number) * 1000; - if (change) timeInMS += change; - if (timeInMS < 100) timeInMS = 100; - if (timeInMS > 10000) timeInMS = 10000; - Array.from(PresBox.Instance._selectedArray.keys()).forEach((doc) => doc.presTransition = timeInMS); - } - - // Converts seconds to ms and updates presDuration - setDurationTime = (number: String, change?: number) => { - let timeInMS = Number(number) * 1000; - if (change) timeInMS += change; - if (timeInMS < 100) timeInMS = 100; - if (timeInMS > 20000) timeInMS = 20000; - Array.from(PresBox.Instance._selectedArray.keys()).forEach((doc) => doc.presDuration = timeInMS); - } - - setMovementName = action((movement: any, activeItem: Doc): string => { - let output: string = 'none'; - switch (movement) { - case PresMovement.Zoom: output = 'Pan & Zoom'; break; //Pan and zoom - case PresMovement.Pan: output = 'Pan'; break; //Pan - case PresMovement.Jump: output = 'Jump cut'; break; //Jump Cut - case PresMovement.None: output = 'No Movement'; break; //None - default: output = 'Zoom'; activeItem.presMovement = 'zoom'; break; //default set as zoom - } - return output; - }); - - @computed get transitionDropdown() { - const activeItem: Doc = this.activeItem; - const targetDoc: Doc = this.targetDoc; - const isPresCollection: boolean = (targetDoc === this.pres.layoutDoc.presCollection); - const isPinWithView: boolean = BoolCast(activeItem.presPinView); - if (activeItem && targetDoc) { - const transitionSpeed = activeItem.presTransition ? NumCast(activeItem.presTransition) / 1000 : 0.5; - let duration = activeItem.presDuration ? NumCast(activeItem.presDuration) / 1000 : 2; - if (activeItem.type === DocumentType.AUDIO) duration = NumCast(activeItem.duration); - const effect = targetDoc.presEffect ? targetDoc.presEffect : 'None'; - activeItem.presMovement = activeItem.presMovement ? activeItem.presMovement : 'Zoom'; - return ( -
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onClick={action(e => { e.stopPropagation(); this.openMovementDropdown = false; this.openEffectDropdown = false; })}> -
- Movement - {isPresCollection || (isPresCollection && isPinWithView) ? -
- {this.scrollable ? "Scroll to pinned view" : !isPinWithView ? "No movement" : "Pan & Zoom to pinned view"} -
- : -
{ e.stopPropagation(); this.openMovementDropdown = !this.openMovementDropdown; })} style={{ borderBottomLeftRadius: this.openMovementDropdown ? 0 : 5, border: this.openMovementDropdown ? `solid 2px ${PresColor.DarkBlue}` : 'solid 1px black' }}> - {this.setMovementName(activeItem.presMovement, activeItem)} - -
e.stopPropagation()} style={{ display: this.openMovementDropdown ? "grid" : "none" }}> -
e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.None)}>None
-
e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Zoom)}>Pan {"&"} Zoom
-
e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Pan)}>Pan
-
e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Jump)}>Jump cut
-
-
- } -
-
Transition Speed
-
- this.setTransitionTime(e.target.value))} /> s -
-
-
this.setTransitionTime(String(transitionSpeed), 1000))}> - -
-
this.setTransitionTime(String(transitionSpeed), -1000))}> - -
-
-
- this._batch = UndoManager.StartBatch("presTransition")} - onPointerUp={() => this._batch?.end()} - onChange={(e: React.ChangeEvent) => { - e.stopPropagation(); - this.setTransitionTime(e.target.value); - }} /> -
-
Fast
-
Medium
-
Slow
-
-
-
- Visibility {"&"} Duration -
- {isPresCollection ? (null) :
{"Hide before presented"}
}>
this.updateHideBefore(activeItem)}>Hide before
} - {isPresCollection ? (null) :
{"Hide after presented"}
}>
this.updateHideAfter(activeItem)}>Hide after
} -
{"Open document in a new tab"}
}>
this.updateOpenDoc(activeItem)}>Open
-
-
-
Slide Duration
-
- this.setDurationTime(e.target.value))} /> s -
-
-
this.setDurationTime(String(duration), 1000))}> - -
-
this.setDurationTime(String(duration), -1000))}> - -
-
-
- { this._batch = UndoManager.StartBatch("presDuration"); }} - onPointerUp={() => { if (this._batch) this._batch.end(); }} - onChange={(e: React.ChangeEvent) => { e.stopPropagation(); this.setDurationTime(e.target.value); }} - /> -
-
Short
-
Medium
-
Long
-
-
- {isPresCollection ? (null) :
- Effects -
{ e.stopPropagation(); this.openEffectDropdown = !this.openEffectDropdown; })} style={{ borderBottomLeftRadius: this.openEffectDropdown ? 0 : 5, border: this.openEffectDropdown ? `solid 2px ${PresColor.DarkBlue}` : 'solid 1px black' }}> - {effect} - -
e.stopPropagation()}> -
e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.None)}>None
-
e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Fade)}>Fade In
-
e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Flip)}>Flip
-
e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Rotate)}>Rotate
-
e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Bounce)}>Bounce
-
e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Roll)}>Roll
-
-
-
-
Effect direction
-
- {this.effectDirection} -
-
-
-
{"Enter from left"}
}>
this.updateEffectDirection(PresEffect.Left)}>
-
{"Enter from right"}
}>
this.updateEffectDirection(PresEffect.Right)}>
-
{"Enter from top"}
}>
this.updateEffectDirection(PresEffect.Top)}>
-
{"Enter from bottom"}
}>
this.updateEffectDirection(PresEffect.Bottom)}>
-
{"Enter from center"}
}>
this.updateEffectDirection(PresEffect.Center)}>
-
-
} -
-
this.applyTo(this.pres.childDocs)}> - Apply to all -
-
-
- ); - } - } - - @undoBatch - @action - applyTo = (array: Doc[]) => { - const activeItem: Doc = this.activeItem; - const targetDoc: Doc = this.targetDoc; - this.updateMovement(activeItem.presMovement, true); - this.updateEffect(targetDoc.presEffect, true); - this.updateEffectDirection(targetDoc.presEffectDirection, true); - array.forEach((doc) => { - const curDoc = Cast(doc, Doc, null); - const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null); - if (tagDoc && targetDoc) { - curDoc.presTransition = activeItem.presTransition; - curDoc.presDuration = activeItem.presDuration; - curDoc.presHideBefore = activeItem.presHideBefore; - curDoc.presHideAfter = activeItem.presHideAfter; - } - }); - } - - @computed get mediaOptionsDropdown() { - const activeItem: Doc = this.activeItem; - const targetDoc: Doc = this.targetDoc; - if (activeItem && targetDoc) { - return ( -
-
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}> -
-
-
activeItem.playAuto = !activeItem.playAuto}>Play automatically
-
activeItem.playAuto = !activeItem.playAuto}>Play on next
-
- {/* {targetDoc.type === DocumentType.VID ?
activeItem.presVidFullScreen = !activeItem.presVidFullScreen}>Full screen
: (null)} */} - {targetDoc.type === DocumentType.AUDIO ?
-
Start time
-
- ) => { activeItem.presStartTime = Number(e.target.value); })} /> -
-
: (null)} - {targetDoc.type === DocumentType.AUDIO ?
-
End time
-
- ) => { const val = e.target.value; activeItem.presEndTime = Number(val); })} /> -
-
: (null)} -
-
-
- ); - } - } - - @computed get presPinViewOptionsDropdown() { - const activeItem: Doc = this.activeItem; - const targetDoc: Doc = this.targetDoc; - const presPinWithViewIcon = ; - return ( - <> - {this.panable || this.scrollable || this.targetDoc.type === DocumentType.COMPARISON ? 'Pinned view' : (null)} -
-
{activeItem.presPinView ? "Turn off pin with view" : "Turn on pin with view"}
}>
{ - activeItem.presPinView = !activeItem.presPinView; - targetDoc.presPinView = activeItem.presPinView; - if (activeItem.presPinView) { - if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.WEB || targetDoc._viewType === CollectionViewType.Stacking) { - const scroll = targetDoc._scrollTop; - activeItem.presPinView = true; - activeItem.presPinViewScroll = scroll; - } else if (targetDoc.type === DocumentType.VID) { - activeItem.presPinTimecode = targetDoc._currentTimecode; - } else if ((targetDoc.type === DocumentType.COL && targetDoc._viewType === CollectionViewType.Freeform) || targetDoc.type === DocumentType.IMG) { - const x = targetDoc._panX; - const y = targetDoc._panY; - const scale = targetDoc._viewScale; - activeItem.presPinView = true; - activeItem.presPinViewX = x; - activeItem.presPinViewY = y; - activeItem.presPinViewScale = scale; - } else if (targetDoc.type === DocumentType.COMPARISON) { - const width = targetDoc._clipWidth; - activeItem.presPinClipWidth = width; - activeItem.presPinView = true; - } - } - }}>{presPinWithViewIcon}
- {activeItem.presPinView ?
{"Update the pinned view with the view of the selected document"}
}>
{ - if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF) { - const scroll = targetDoc._scrollTop; - activeItem.presPinViewScroll = scroll; - } else if (targetDoc.type === DocumentType.VID) { - activeItem.presPinTimecode = targetDoc._currentTimecode; - } else if (targetDoc.type === DocumentType.COMPARISON) { - const clipWidth = targetDoc._clipWidth; - activeItem.presPinClipWidth = clipWidth; - } else { - const x = targetDoc._panX; - const y = targetDoc._panY; - const scale = targetDoc._viewScale; - activeItem.presPinViewX = x; - activeItem.presPinViewY = y; - activeItem.presPinViewScale = scale; - } - }}>Update
: (null)} -
- - ); - } - - @computed get panOptionsDropdown() { - const activeItem: Doc = this.activeItem; - const targetDoc: Doc = this.targetDoc; - return ( - <> - {this.panable ?
-
-
Pan X
-
- ) => { const val = e.target.value; activeItem.presPinViewX = Number(val); })} /> -
-
-
-
Pan Y
-
- ) => { const val = e.target.value; activeItem.presPinViewY = Number(val); })} /> -
-
-
-
Scale
-
- ) => { const val = e.target.value; activeItem.presPinViewScale = Number(val); })} /> -
-
-
: (null)} - - ); - } - - @computed get scrollOptionsDropdown() { - const activeItem: Doc = this.activeItem; - const targetDoc: Doc = this.targetDoc; - return ( - <> - {this.scrollable ?
-
-
Scroll
-
- ) => { const val = e.target.value; activeItem.presPinViewScroll = Number(val); })} /> -
-
-
: (null)} - - ); - } -} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 69f247903d289aeac6383ba3a6912504a6172873 Mon Sep 17 00:00:00 2001 From: geireann <60007097+geireann@users.noreply.github.com> Date: Wed, 2 Dec 2020 18:34:23 +0800 Subject: loader progress bar (superficial) - temp media changes --- deploy/index.html | 83 +++++++++--- deploy/loader.css | 141 --------------------- src/client/views/MainView.tsx | 12 +- src/client/views/PropertiesView.tsx | 4 +- src/client/views/nodes/PresBox.scss | 18 ++- src/client/views/nodes/PresBox.tsx | 245 +++++++++++++++++++----------------- 6 files changed, 226 insertions(+), 277 deletions(-) delete mode 100644 deploy/loader.css (limited to 'src') diff --git a/deploy/index.html b/deploy/index.html index beb7dd205..4e0c2dfa4 100644 --- a/deploy/index.html +++ b/deploy/index.html @@ -13,20 +13,51 @@ align-content: center; justify-content: center; background-color: #AEDDF8; + transition: 3s; z-index: 10; width: 100vw; height: 100vh; } .dash-loader-container { - width: 20vw; - height: 20vw; + display: grid; + grid-auto-rows: auto 30px auto; + } + + .dash-progress-bar { + width: 200px; + height: 5px; + align-self: center; + margin-top: 20px; + background-color: #ececec; + border-radius: 5px; + overflow: hidden; + } + + .dash-progress { + width: 0%; + height: 20px; + background-color: #5b9fdd; + transition: 0.1s; + } + + .dash-animation-container { + width: 10vw; + height: 10vw; display: flex; align-items: center; justify-content: center; border-radius: 100%; background-color: #5B9FDD; - align-self: center; + justify-self: center; + align-self: flex-end; + } + + .dash-loader-text { + font-size: 15px; + font-family: "Roboto"; + text-align: center; + color: #5B9FDD; } .dash-d-path { @@ -38,41 +69,63 @@ @keyframes dash-d-path { 0% { stroke-dashoffset: 1000; - /* stroke-width: 0px; */ } 20% { stroke-dashoffset: 0; - /* stroke-width: 20px; */ } 70% { stroke-dashoffset: 0; - /* stroke-width: 20px; */ } 90% { stroke-dashoffset: 1000; - /* stroke-width: 0px; */ } 100% { stroke-dashoffset: 1000; - /* stroke-width: 0px; */ } } -
+
- - - +
+ + + +
+
+
+
+ +
+
+ Loading Dash... +
diff --git a/deploy/loader.css b/deploy/loader.css deleted file mode 100644 index 065862013..000000000 --- a/deploy/loader.css +++ /dev/null @@ -1,141 +0,0 @@ -.dash-loader { - display: flex; - align-content: center; - justify-content: center; - background-color: lightcyan; - z-index: 10; - width: 100%; - height: 100%; -} - -.dash-loader-container { - width: 100; - align-self: center; -} - -.dash-d-path { - stroke-dasharray: 1000; - stroke-dashoffset: 1000; - animation: dash-d-path 10s linear infinite; -} - -@keyframes dash-d-path { - 0% { - stroke-dashoffset: 1000; - /* stroke-width: 0px; */ - } - - 10% { - stroke-dashoffset: 0; - /* stroke-width: 20px; */ - } - - 90% { - stroke-dashoffset: 0; - /* stroke-width: 20px; */ - } - - 100% { - stroke-dashoffset: 1000; - /* stroke-width: 0px; */ - } -} - -.dash-a-path { - stroke-dasharray: 1000; - stroke-dashoffset: 1000; - animation: dash-a-path 10s linear infinite; -} - -@keyframes dash-a-path { - 0% { - stroke-dashoffset: 1000; - /* stroke-width: 0px; */ - } - - 7% { - stroke-dashoffset: 1000; - /* stroke-width: 0px; */ - } - - 17% { - stroke-dashoffset: 0; - /* stroke-width: 20px; */ - } - - 90% { - stroke-dashoffset: 0; - /* stroke-width: 20px; */ - } - - 100% { - stroke-dashoffset: 1000; - /* stroke-width: 0px; */ - } -} - -.dash-s-path { - stroke-dasharray: 1000; - stroke-dashoffset: 1000; - animation: dash-s-path 10s linear infinite; -} - -@keyframes dash-s-path { - 0% { - stroke-dashoffset: 1000; - /* stroke-width: 0px; */ - } - - 14% { - stroke-dashoffset: 1000; - /* stroke-width: 0px; */ - } - - 20% { - stroke-dashoffset: 0; - /* stroke-width: 20px; */ - } - - 90% { - stroke-dashoffset: 0; - /* stroke-width: 20px; */ - } - - 100% { - stroke-dashoffset: 1000; - /* stroke-width: 0px; */ - } -} - -.dash-h-path { - stroke-dasharray: 1000; - stroke-dashoffset: 1000; - animation: dash-h-path 10s linear infinite; -} - -@keyframes dash-h-path { - 0% { - stroke-dashoffset: 1000; - /* stroke-width: 0px; */ - } - - 18% { - stroke-dashoffset: 1000; - /* stroke-width: 0px; */ - } - - 28% { - stroke-dashoffset: 0; - /* stroke-width: 20px; */ - } - - 90% { - stroke-dashoffset: 0; - /* stroke-width: 20px; */ - } - - 100% { - stroke-dashoffset: 1000; - /* stroke-width: 0px; */ - } -} \ No newline at end of file diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 12e361dc1..747bde64d 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -87,11 +87,15 @@ export class MainView extends React.Component { componentDidMount() { document.getElementById("root")?.addEventListener("scroll", e => ((ele) => ele.scrollLeft = ele.scrollTop = 0)(document.getElementById("root")!)); const ele = document.getElementById("loader"); - - if (ele) { + const prog = document.getElementById("dash-progress"); + if (ele && prog) { // remove from DOM - setTimeout(() => { ele.style.opacity = "0"; }, 0); - setTimeout(() => ele.outerHTML = '', 10000); + setTimeout(() => { + clearTimeout(); + prog.style.transition = "1s"; + prog.style.width = "100%"; + }, 0); + setTimeout(() => ele.outerHTML = '', 1000); } new InkStrokeProperties(); this._sidebarContent.proto = undefined; diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index a9076fea7..3c77bc309 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -1016,7 +1016,7 @@ export class PropertiesView extends React.Component { {PresBox.Instance.transitionDropdown}
: null}
} - {!selectedItem || type === DocumentType.VID || type === DocumentType.AUDIO ? (null) :
+ {/* {!selectedItem || type === DocumentType.VID || type === DocumentType.AUDIO ? (null) :
this.openPresProgressivize = !this.openPresProgressivize)} style={{ backgroundColor: this.openPresProgressivize ? "black" : "" }}> @@ -1028,7 +1028,7 @@ export class PropertiesView extends React.Component { {this.openPresProgressivize ?
{PresBox.Instance.progressivizeDropdown}
: null} -
} +
} */} {!selectedItem || (type !== DocumentType.VID && type !== DocumentType.AUDIO) ? (null) :
{ this.openSlideOptions = !this.openSlideOptions; })} diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss index ba21cef42..1ba86232b 100644 --- a/src/client/views/nodes/PresBox.scss +++ b/src/client/views/nodes/PresBox.scss @@ -129,7 +129,9 @@ $dark-grey: #656565; } .presBox-radioButtons { - background-color: rgba(0, 0, 0, 0.1); + font-size: 10px; + font-weight: 200; + // background-color: rgba(0, 0, 0, 0.1); .checkbox-container { margin-left: 10px; @@ -345,6 +347,20 @@ $dark-grey: #656565; font-weight: 100; margin-top: 3px; font-size: 10px; + + .slider-block { + width: 63px; + border-radius: 5px; + text-align: center; + margin-bottom: 8px; + margin-top: 8px; + } + + .slider-number { + border-radius: 3px; + width: 30px; + margin: auto; + } } .slider-value { diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index d21e1603d..a4f79571e 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -640,10 +640,14 @@ export class PresBox extends ViewBoxBaseComponent if (this.childDocs[stopDocIndex - 1].mediaStopTriggerList) { const list = DocListCast(this.childDocs[stopDocIndex - 1].mediaStopTriggerList); list.push(activeItem); + // this.childDocs[stopDocIndex - 1].mediaStopTriggerList = list; + console.log(list); } else { this.childDocs[stopDocIndex - 1].mediaStopTriggerList = new List(); const list = DocListCast(this.childDocs[stopDocIndex - 1].mediaStopTriggerList); list.push(activeItem); + // this.childDocs[stopDocIndex - 1].mediaStopTriggerList = list; + console.log(list); } }); @@ -1424,102 +1428,138 @@ export class PresBox extends ViewBoxBaseComponent
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
-
Range:
-
-
- Start time: -
-
- Duration: -
-
- End time: -
-
-
-
- ) => { activeItem.presStartTime = Number(e.target.value); })} - /> s +
+ Start {"&"} End Time +
+
+
+ Start time (s) +
+
+ ) => { activeItem.presStartTime = Number(e.target.value); })} + /> +
+
+
+
+ Duration (s) +
+
+ {Math.round((NumCast(activeItem.presEndTime) - NumCast(activeItem.presStartTime)) * 10) / 10} +
+
+
+
+ End time (s) +
+
+ ) => { activeItem.presEndTime = Number(e.target.value); })} + /> +
-
- {Math.round((NumCast(activeItem.presEndTime) - NumCast(activeItem.presStartTime)) * 10) / 10} s
-
- ) => { activeItem.presEndTime = Number(e.target.value); })} - /> s +
+ { + this._batch = UndoManager.StartBatch("presEndTime"); + const endBlock = document.getElementById("endTime"); + if (endBlock) { + endBlock.style.color = PresColor.LightBackground; + endBlock.style.backgroundColor = PresColor.DarkBlue; + } + }} + onPointerUp={() => { + this._batch?.end(); + const endBlock = document.getElementById("endTime"); + if (endBlock) { + endBlock.style.color = "black"; + endBlock.style.backgroundColor = PresColor.LightBackground; + } + }} + onChange={(e: React.ChangeEvent) => { + e.stopPropagation(); + activeItem.presEndTime = Number(e.target.value); + }} /> + { + this._batch = UndoManager.StartBatch("presStartTime"); + const startBlock = document.getElementById("startTime"); + if (startBlock) { + startBlock.style.color = PresColor.LightBackground; + startBlock.style.backgroundColor = PresColor.DarkBlue; + } + }} + onPointerUp={() => { + this._batch?.end(); + const startBlock = document.getElementById("startTime"); + if (startBlock) { + startBlock.style.color = "black"; + startBlock.style.backgroundColor = PresColor.LightBackground; + } + }} + onChange={(e: React.ChangeEvent) => { + e.stopPropagation(); + activeItem.presStartTime = Number(e.target.value); + }} />
-
-
- this._batch = UndoManager.StartBatch("presEndTime")} - onPointerUp={() => this._batch?.end()} - onChange={(e: React.ChangeEvent) => { - e.stopPropagation(); - activeItem.presEndTime = Number(e.target.value); - }} /> - this._batch = UndoManager.StartBatch("presEndTime")} - onPointerUp={() => this._batch?.end()} - onChange={(e: React.ChangeEvent) => { - e.stopPropagation(); - activeItem.presStartTime = Number(e.target.value); - }} /> -
-
-
0 s
-
-
{activeItem.type === DocumentType.AUDIO ? Math.round(NumCast(activeItem.duration) * 10) / 10 : Math.round(NumCast(activeItem["data-duration"]) * 10) / 10} s
-
-
Start playing:
-
-
- activeItem.mediaStart = "manual"} - checked={activeItem.mediaStart === "manual"} - /> -
On click
-
-
- activeItem.mediaStart = "auto"} - checked={activeItem.mediaStart === "auto"} - /> -
Automatically
+
+
0 s
+
+
{activeItem.type === DocumentType.AUDIO ? Math.round(NumCast(activeItem.duration) * 10) / 10 : Math.round(NumCast(activeItem["data-duration"]) * 10) / 10} s
-
Stop playing:
-
-
- activeItem.mediaStop = "manual"} - checked={activeItem.mediaStop === "manual"} - /> -
At audio end time
-
-
- activeItem.mediaStop = "auto"} - checked={activeItem.mediaStop === "auto"} - /> -
On slide change
+
+ Playback +
Start playing:
+
+
+ activeItem.mediaStart = "manual"} + checked={activeItem.mediaStart === "manual"} + /> +
On click
+
+
+ activeItem.mediaStart = "auto"} + checked={activeItem.mediaStart === "auto"} + /> +
Automatically
+
-
+
Stop playing:
+
+
+ activeItem.mediaStop = "manual"} + checked={activeItem.mediaStop === "manual"} + /> +
At audio end time
+
+
+ activeItem.mediaStop = "auto"} + checked={activeItem.mediaStop === "auto"} + /> +
On slide change
+
+ {/*
activeItem.mediaStop = "afterSlide"} @@ -1535,33 +1575,10 @@ export class PresBox extends ViewBoxBaseComponent {this.mediaStopSlides}
+
*/}
- {/*
-
-
activeItem.playAuto = !activeItem.playAuto}>Play automatically
-
activeItem.playAuto = !activeItem.playAuto}>Play on next
-
- {targetDoc.type === DocumentType.AUDIO ?
-
Start time
-
- ) => { activeItem.presStartTime = Number(e.target.value); })} /> -
-
: (null)} - {targetDoc.type === DocumentType.AUDIO ?
-
End time
-
- ) => { const val = e.target.value; activeItem.presEndTime = Number(val); })} /> -
-
: (null)} -
*/}
); -- cgit v1.2.3-70-g09d2 From 22372bb12fdc29167f9c93bbf11a8d192f9b6c92 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 2 Dec 2020 09:18:57 -0500 Subject: added a loadtime cookie to keep track of last load time. --- deploy/index.html | 36 ++++++++++++++++++++++++++++++------ src/client/views/Main.tsx | 7 +++++++ 2 files changed, 37 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/deploy/index.html b/deploy/index.html index 4e0c2dfa4..f2eb5e2aa 100644 --- a/deploy/index.html +++ b/deploy/index.html @@ -7,6 +7,23 @@ + +