From b1ec42d48e5430cdfe8e6397d500af31efc76893 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 21 Sep 2022 18:18:31 -0400 Subject: fixed issues with deleting last stack, or deleting stacks and leaving only row/cols in goldenLayout --- src/client/goldenLayout.js | 13 ++++++++----- src/client/views/collections/CollectionDockingView.tsx | 3 ++- 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/client/goldenLayout.js b/src/client/goldenLayout.js index e5cd50de2..dd11e6466 100644 --- a/src/client/goldenLayout.js +++ b/src/client/goldenLayout.js @@ -3263,11 +3263,6 @@ const canDelete = rowOrCol && !rowOrCol.isRoot && (rowOrCol.contentItems.length > 1 || (parRowOrCol && parRowOrCol.contentItems.length > 1)); // bcz: added test for last stack if (canDelete) { rowOrCol.removeChild(stack); - if (rowOrCol.contentItems.length === 1 && parRowOrCol.contentItems.length === 1 && !parRowOrCol.isRoot) { - saveScrollTops(rowOrCol.contentItems[0].element); - parRowOrCol.replaceChild(rowOrCol, rowOrCol.contentItems[0]); - restoreScrollTops(rowOrCol.contentItems[0].element); - } } } }, @@ -4061,6 +4056,14 @@ lm.items.AbstractContentItem.prototype.removeChild.call(this, contentItem, keepChild); if (this.contentItems.length === 1 && this.config.isClosable === true) { + if (["row","column"].includes(this.contentItems[0].type) || ["row","column"].includes(this.parent.type)) { + let parent = this.parent; + let correctRowOrCol = this.contentItems[0]; + saveScrollTops(correctRowOrCol.element); + parent.replaceChild(this, correctRowOrCol); + restoreScrollTops(correctRowOrCol.element); + } + // bcz: this has the effect of removing children from the DOM and then re-adding them above where they were before. // in the case of things like an iFrame with a YouTube video, the video will reload for now reason. So let's try leaving these "empty" rows alone. // childItem = this.contentItems[0]; diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 25fe5fe43..c6ac5ee0c 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -477,6 +477,7 @@ export class CollectionDockingView extends CollectionSubView() { }; stackCreated = (stack: any) => { + stack = stack.header ? stack : stack.origin; stack.header?.element.on('mousedown', (e: any) => { const dashboard = Doc.ActiveDashboard; if (dashboard && e.target === stack.header?.element[0] && e.button === 2) { @@ -499,7 +500,7 @@ export class CollectionDockingView extends CollectionSubView() { .click( action(() => { //if (confirm('really close this?')) { - if (!stack.parent.parent.isRoot || stack.parent.contentItems.length > 1) { + if ((!stack.parent.isRoot && !stack.parent.parent.isRoot) || stack.parent.contentItems.length > 1) { stack.remove(); } else { alert('cant delete the last stack'); -- cgit v1.2.3-70-g09d2 From 23099cff00b2bc3343cc7e83c4920d465f08b985 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 21 Sep 2022 20:42:04 -0400 Subject: added error message for file upload errors before parsing. --- src/client/documents/Documents.ts | 2 +- src/server/ApiManagers/UploadManager.ts | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 4f652b6e4..029c3033d 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -1864,7 +1864,7 @@ export namespace DocUtils { const { source: { name, type }, result, - } = upfiles.lastElement(); + } = upfiles.lastElement() ?? { source: { name: '', type: '' }, result: { message: 'upload failed' } }; if ((result as any).message) { if (overwriteDoc) { overwriteDoc.isLoading = false; diff --git a/src/server/ApiManagers/UploadManager.ts b/src/server/ApiManagers/UploadManager.ts index 0b6e18743..5077bced2 100644 --- a/src/server/ApiManagers/UploadManager.ts +++ b/src/server/ApiManagers/UploadManager.ts @@ -60,6 +60,18 @@ export default class UploadManager extends ApiManager { return new Promise(resolve => { form.parse(req, async (_err, _fields, files) => { const results: Upload.FileResponse[] = []; + if (_err.message) { + results.push({ + source: { + size: 0, + path: 'none', + name: 'none', + type: 'none', + toJSON: () => ({ name: 'none', path: '' }), + }, + result: { name: 'failed upload', message: `${_err.message}` }, + }); + } for (const key in files) { const f = files[key]; if (!Array.isArray(f)) { -- cgit v1.2.3-70-g09d2 From 05cfb0b626016e3fb77e0f7b4e5b3cca08e4f2f9 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 21 Sep 2022 20:46:16 -0400 Subject: from last --- src/server/ApiManagers/UploadManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/ApiManagers/UploadManager.ts b/src/server/ApiManagers/UploadManager.ts index 5077bced2..76cf36d44 100644 --- a/src/server/ApiManagers/UploadManager.ts +++ b/src/server/ApiManagers/UploadManager.ts @@ -60,7 +60,7 @@ export default class UploadManager extends ApiManager { return new Promise(resolve => { form.parse(req, async (_err, _fields, files) => { const results: Upload.FileResponse[] = []; - if (_err.message) { + if (_err?.message) { results.push({ source: { size: 0, -- cgit v1.2.3-70-g09d2 From dc5d5d318ad4ebc99e7c1302057e1b6e132f5017 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 21 Sep 2022 21:55:27 -0400 Subject: imposed 50MB max file size for uploads --- src/client/Network.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src') diff --git a/src/client/Network.ts b/src/client/Network.ts index a222b320f..996eb35d8 100644 --- a/src/client/Network.ts +++ b/src/client/Network.ts @@ -30,6 +30,17 @@ export namespace Networking { if (!files.length) { return []; } + const maxFileSize = 50000000; + if (files.some(f => f.size > maxFileSize)) { + return new Promise(res => + res([ + { + source: { name: '', type: '', size: 0, toJson: () => ({ name: '', type: '' }) }, + result: { name: '', message: `max file size (${maxFileSize / 1000000}MB) exceeded` }, + }, + ]) + ); + } files.forEach(file => formData.append(Utils.GenerateGuid(), file)); } else { formData.append(Utils.GenerateGuid(), files); -- cgit v1.2.3-70-g09d2 From d40a8e4506672f9d0ad505409f4b181d73762c28 Mon Sep 17 00:00:00 2001 From: mehekj Date: Wed, 21 Sep 2022 23:23:37 -0400 Subject: fixed video duration in presbox media controls --- src/client/views/nodes/VideoBox.tsx | 1 + src/client/views/nodes/trails/PresBox.tsx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 4bcd79641..f7f558bb4 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -405,6 +405,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent() { const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; const clipStart: number = NumCast(activeItem.clipStart); - const clipEnd: number = NumCast(activeItem.clipEnd); + const clipEnd: number = NumCast(activeItem.clipEnd, NumCast(activeItem.duration)); const mediaStopDocInd: number = NumCast(activeItem.mediaStopDoc); if (activeItem && targetDoc) { return ( -- cgit v1.2.3-70-g09d2 From 13a0c0c505edd4b00f9d7b5aed78237c4d23a3d1 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 22 Sep 2022 09:59:00 -0400 Subject: remove overlaydocs when switching dashboards. --- src/client/views/topbar/TopBar.tsx | 87 +++----------------------------------- src/fields/Doc.ts | 2 + 2 files changed, 7 insertions(+), 82 deletions(-) (limited to 'src') diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx index 7bc7ba3ed..7e728306c 100644 --- a/src/client/views/topbar/TopBar.tsx +++ b/src/client/views/topbar/TopBar.tsx @@ -80,8 +80,6 @@ export class TopBar extends React.Component { * - Taking a snapshot of a dashboard */ @computed get topbarCenter() { - const myDashboards = DocListCast(Doc.MyDashboards.data); - const activeDashboard = Doc.ActiveDashboard; // const dashboardItems = myDashboards.map(board => { // const boardTitle = StrCast(board.title); // console.log(boardTitle); @@ -91,10 +89,10 @@ export class TopBar extends React.Component { // val: board, // }; // }); - return activeDashboard ? ( + return Doc.ActiveDashboard ? (
- // ); - // } render() { return ( //TODO:glr Add support for light / dark mode diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 74a3d8cf2..a3c742f28 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -239,6 +239,8 @@ export class Doc extends RefField { return DocCast(Doc.UserDoc().activeDashboard); } public static set ActiveDashboard(val: Doc | undefined) { + const overlays = Cast(Doc.MyOverlayDocs.data, listSpec(Doc), null); + overlays && (overlays.length = 0); Doc.UserDoc().activeDashboard = val; } public static set ActiveTool(tool: InkTool) { -- cgit v1.2.3-70-g09d2 From 0bf2c263c82eb08a8f9545967c5907fc00be9a9f Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 22 Sep 2022 11:32:38 -0400 Subject: fixed presenting backward in presBox. fixed context menu to appear above other widgets --- src/client/views/ContextMenu.scss | 2 +- src/client/views/DocumentDecorations.tsx | 25 +++++++++++++++---------- src/client/views/global/globalCssVariables.scss | 2 +- src/client/views/nodes/trails/PresBox.tsx | 25 +++++++++++++++---------- 4 files changed, 32 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/client/views/ContextMenu.scss b/src/client/views/ContextMenu.scss index 1e6a377de..cbe14060a 100644 --- a/src/client/views/ContextMenu.scss +++ b/src/client/views/ContextMenu.scss @@ -3,7 +3,7 @@ .contextMenu-cont { position: absolute; display: flex; - z-index: 100000; + z-index: $contextMenu-zindex; box-shadow: 0px 3px 4px rgba(0, 0, 0, 30%); flex-direction: column; background: whitesmoke; diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 797730c10..4675571c2 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -31,6 +31,7 @@ import { ImageBox } from './nodes/ImageBox'; import React = require('react'); import { IconButton } from 'browndash-components'; import { FaUndo } from 'react-icons/fa'; +import { VideoBox } from './nodes/VideoBox'; @observer export class DocumentDecorations extends React.Component<{ PanelWidth: number; PanelHeight: number; boundsLeft: number; boundsTop: number }, { value: string }> { @@ -678,7 +679,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P bounds.b = Math.max(bounds.y, Math.max(topBounds, Math.min(window.innerHeight, bounds.b + this._resizeBorderWidth / 2 + this._linkBoxHeight) - this._resizeBorderWidth / 2 - this._linkBoxHeight)); // Rotation constants: Only allow rotation on ink and images - const useRotation = seldoc.ComponentView instanceof InkingStroke || seldoc.ComponentView instanceof ImageBox; + const useRotation = seldoc.ComponentView instanceof InkingStroke || seldoc.ComponentView instanceof ImageBox || seldoc.ComponentView instanceof VideoBox; const rotation = NumCast(seldoc.rootDoc._jitterRotation); const resizerScheme = colorScheme ? 'documentDecorations-resizer' + colorScheme : ''; @@ -721,12 +722,14 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P width: bounds.r - bounds.x + this._resizeBorderWidth + 'px', height: bounds.b - bounds.y + this._resizeBorderWidth + this._titleHeight + 'px', }}> - {hideResizers ? null : (
- {hideDeleteButton ?
: topBtn('close', 'times', undefined, e => this.onCloseClick(true), 'Close')} - {hideDeleteButton ?
: topBtn('minimize', 'window-maximize', undefined, e => this.onCloseClick(undefined), 'Minimize')} - {titleArea} - {hideOpenButton ? null : topBtn('open', 'external-link-alt', this.onMaximizeDown, undefined, 'Open in Tab (ctrl: as alias, shift: in new collection)')} -
)} + {hideResizers ? null : ( +
+ {hideDeleteButton ?
: topBtn('close', 'times', undefined, e => this.onCloseClick(true), 'Close')} + {hideDeleteButton ?
: topBtn('minimize', 'window-maximize', undefined, e => this.onCloseClick(undefined), 'Minimize')} + {titleArea} + {hideOpenButton ? null : topBtn('open', 'external-link-alt', this.onMaximizeDown, undefined, 'Open in Tab (ctrl: as alias, shift: in new collection)')} +
+ )} {hideResizers ? null : ( <>
e.preventDefault()} /> @@ -743,9 +746,11 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P )} - {useRotation &&
e.preventDefault()}> - } isCircle={true} hoverStyle={"lighten"} backgroundColor={Colors.DARK_GRAY} color={Colors.LIGHT_GRAY}/> -
} + {useRotation && ( +
e.preventDefault()}> + } isCircle={true} hoverStyle={'lighten'} backgroundColor={Colors.DARK_GRAY} color={Colors.LIGHT_GRAY} /> +
+ )} {useRounding && (
() { //TODO: al: it seems currently that tempMedia doesn't stop onslidechange after clicking the button; the time the tempmedia stop depends on the start & end time // TODO: to handle child slides (entering into subtrail and exiting), also the next() and back() functions // No more frames in current doc and next slide is defined, therefore move to next slide - nextSlide = (activeNext: Doc) => { - let nextSelected = this.itemIndex + 1; + nextSlide = (slideNum?: number) => { + let nextSelected = slideNum ?? this.itemIndex + 1; this.gotoDocument(nextSelected, this.activeItem); for (nextSelected = nextSelected + 1; nextSelected < this.childDocs.length; nextSelected++) { if (this.childDocs[nextSelected].groupWithUp) { @@ -261,10 +261,12 @@ 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(activeNext); + const slides = DocListCast(this.rootDoc[StrCast(this.presFieldKey, 'data')]); + const curLast = this.selectedArray.size ? Math.max(...Array.from(this.selectedArray).map(d => slides.indexOf(DocCast(d)))) : this.itemIndex; + this.nextSlide(curLast + 1); } 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.activeItem); + this.nextSlide(0); } }; @@ -280,8 +282,8 @@ export class PresBox extends ViewBoxBaseComponent() { 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; + for (; prevSelected > 0 && this.childDocs[Math.max(0, prevSelected - 1)].groupWithUp; prevSelected--) { + didZoom = didZoom === 'none' ? this.childDocs[prevSelected].presMovement : didZoom; } if (lastFrame !== undefined && curFrame >= 1) { // Case 1: There are still other frames and should go through all frames before going to previous slide @@ -289,7 +291,8 @@ 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, activeItem); + this.nextSlide(prevSelected); + this.rootDoc._itemIndex = prevSelected; 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 @@ -2458,12 +2461,13 @@ export class PresBox extends ViewBoxBaseComponent() {
{ + onClick={e => { this.back(); if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } + e.stopPropagation(); }}>
@@ -2475,18 +2479,19 @@ export class PresBox extends ViewBoxBaseComponent() {
{ + onClick={e => { this.next(); if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } + e.stopPropagation(); }}>
{'Click to return to 1st slide'}
}> -
this.gotoDocument(0, this.activeItem)}> +
this.nextSlide(0)}> 1
-- cgit v1.2.3-70-g09d2 From 735e81f31cca1fdc054b9c28c950ceafa04e039a Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 22 Sep 2022 12:02:59 -0400 Subject: minipres opacity bumped up to 0.5 --- src/client/views/nodes/trails/PresBox.scss | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/trails/PresBox.scss b/src/client/views/nodes/trails/PresBox.scss index a0a2dd4f8..7069d2742 100644 --- a/src/client/views/nodes/trails/PresBox.scss +++ b/src/client/views/nodes/trails/PresBox.scss @@ -1,4 +1,4 @@ -@import "../../global/globalCssVariables"; +@import '../../global/globalCssVariables'; .presBox-cont { cursor: auto; @@ -231,8 +231,7 @@ margin-top: 10px; } - @media screen and (-webkit-min-device-pixel-ratio:0) { - + @media screen and (-webkit-min-device-pixel-ratio: 0) { .multiThumb-slider { display: grid; background-color: $white; @@ -330,8 +329,6 @@ } } - - .slider-headers { position: relative; display: grid; @@ -382,7 +379,6 @@ border-bottom: solid 2px $medium-gray; } - .ribbon-textInput { border-radius: 2px; height: 20px; @@ -467,7 +463,6 @@ font-weight: 500; position: relative; - .ribbon-final-button { cursor: pointer; position: relative; @@ -687,7 +682,6 @@ max-width: 200px; overflow: visible; - .presBox-dropdownOption { cursor: pointer; font-size: 11; @@ -716,7 +710,7 @@ width: 85%; min-width: max-content; display: block; - background: #FFFFFF; + background: #ffffff; border: 0.5px solid #979797; box-sizing: border-box; box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); @@ -741,7 +735,7 @@ padding-top: 5px; padding-bottom: 5px; border: solid 1px $black; - // overflow: auto; + // overflow: auto; ::-webkit-scrollbar { -webkit-appearance: none; @@ -953,8 +947,6 @@ min-width: 150px; } - - select { background: $dark-gray; color: $white; @@ -999,8 +991,6 @@ } } - - .collectionViewBaseChrome-viewPicker { min-width: 50; width: 5%; @@ -1080,7 +1070,7 @@ position: absolute; top: 0; left: 0; - opacity: 0.1; + opacity: 0.5; transition: all 0.4s; color: $white; width: 100%; @@ -1165,8 +1155,6 @@ .presPanel-button-text:hover { background-color: $medium-gray; } - - } // .miniPres { @@ -1241,4 +1229,4 @@ // background-color: #5a5a5a; // } // } -// } \ No newline at end of file +// } -- cgit v1.2.3-70-g09d2 From 4f1427343be65fcf00389570107f436cee4c66c5 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 22 Sep 2022 12:11:56 -0400 Subject: fixed creating new dashboards to open them --- src/client/views/DashboardView.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx index 911b53945..11bb0c6a8 100644 --- a/src/client/views/DashboardView.tsx +++ b/src/client/views/DashboardView.tsx @@ -370,11 +370,12 @@ export class DashboardView extends React.Component { system: true, explainer: 'All of the trails that you have created will appear here.', }; - dashboardDoc.myTrails = new PrefetchProxy(DocUtils.AssignScripts(Docs.Create.TreeDocument([], reqdOpts), { treeViewChildDoubleClick: 'openPresentation(documentView.rootDoc)' })); + const myTrails = DocUtils.AssignScripts(Docs.Create.TreeDocument([], reqdOpts), { treeViewChildDoubleClick: 'openPresentation(documentView.rootDoc)' }); + dashboardDoc.myTrails = new PrefetchProxy(myTrails); const contextMenuScripts = [reqdBtnScript.onClick]; - if (Cast(Doc.MyTrails.contextMenuScripts, listSpec(ScriptField), null)?.length !== contextMenuScripts.length) { - Doc.MyTrails.contextMenuScripts = new List(contextMenuScripts.map(script => ScriptField.MakeFunction(script)!)); + if (Cast(myTrails.contextMenuScripts, listSpec(ScriptField), null)?.length !== contextMenuScripts.length) { + myTrails.contextMenuScripts = new List(contextMenuScripts.map(script => ScriptField.MakeFunction(script)!)); } } } -- cgit v1.2.3-70-g09d2 From 40cc7455e853d306ee2750c51308d095dc2970ef Mon Sep 17 00:00:00 2001 From: mehekj Date: Thu, 22 Sep 2022 12:27:54 -0400 Subject: fixed media range sliders in presBox --- src/client/views/nodes/trails/PresBox.scss | 1 + src/client/views/nodes/trails/PresBox.tsx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/views/nodes/trails/PresBox.scss b/src/client/views/nodes/trails/PresBox.scss index 7069d2742..34df415ac 100644 --- a/src/client/views/nodes/trails/PresBox.scss +++ b/src/client/views/nodes/trails/PresBox.scss @@ -288,6 +288,7 @@ height: 10px; -webkit-appearance: none; margin-top: -1px; + background: transparent; } .toolbar-slider::-webkit-slider-thumb { diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 69f817d79..de19f831d 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -1430,7 +1430,7 @@ export class PresBox extends ViewBoxBaseComponent() { const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; const clipStart: number = NumCast(activeItem.clipStart); - const clipEnd: number = NumCast(activeItem.clipEnd, NumCast(activeItem.duration)); + const clipEnd: number = NumCast(activeItem.clipEnd, NumCast(activeItem[Doc.LayoutFieldKey(activeItem) + '-duration'])); const mediaStopDocInd: number = NumCast(activeItem.mediaStopDoc); if (activeItem && targetDoc) { return ( -- cgit v1.2.3-70-g09d2