import { action, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, DocListCast } from '../../../../fields/Doc'; import { Id } from '../../../../fields/FieldSymbols'; import { listSpec } from '../../../../fields/Schema'; import { BoolCast, Cast, DocCast, StrCast } from '../../../../fields/Types'; import { VideoField } from '../../../../fields/URLField'; import { Upload } from '../../../../server/SharedMediaTypes'; import { Docs } from '../../../documents/Documents'; import { DocumentType } from '../../../documents/DocumentTypes'; import { DocumentManager } from '../../../util/DocumentManager'; import { DragManager } from '../../../util/DragManager'; import { ScriptingGlobals } from '../../../util/ScriptingGlobals'; import { SelectionManager } from '../../../util/SelectionManager'; import { Presentation } from '../../../util/TrackMovements'; import { undoBatch } from '../../../util/UndoManager'; import { CollectionFreeFormView } from '../../collections/collectionFreeForm/CollectionFreeFormView'; import { ViewBoxBaseComponent } from '../../DocComponent'; import { FieldView, FieldViewProps } from '../FieldView'; import { VideoBox } from '../VideoBox'; import { RecordingView } from './RecordingView'; import { DateField } from '../../../../fields/DateField'; import { media_state } from '../AudioBox'; import { List } from '../../../../fields/List'; @observer export class RecordingBox extends ViewBoxBaseComponent() { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(RecordingBox, fieldKey); } private _ref: React.RefObject = React.createRef(); componentDidMount() { this.props.setContentView?.(this); Doc.SetNativeWidth(this.dataDoc, 1280); Doc.SetNativeHeight(this.dataDoc, 720); } @observable result: Upload.AccessPathInfo | undefined = undefined; @observable videoDuration: number | undefined = undefined; @action setVideoDuration = (duration: number) => (this.videoDuration = duration); @action setResult = (info: Upload.AccessPathInfo, presentation?: Presentation) => { this.result = info; this.dataDoc.type = DocumentType.VID; this.dataDoc[this.fieldKey + '_duration'] = this.videoDuration; this.dataDoc.layout = VideoBox.LayoutString(this.fieldKey); this.dataDoc[this.props.fieldKey] = new VideoField(this.result.accessPaths.client); this.dataDoc[this.fieldKey + '_recorded'] = true; // stringify the presentation and store it if (presentation?.movements) { const presCopy = { ...presentation }; presCopy.movements = presentation.movements.map(movement => ({ ...movement, doc: movement.doc[Id] })) as any; this.dataDoc[this.fieldKey + '_presentation'] = JSON.stringify(presCopy); } }; @undoBatch @action public static WorkspaceStopRecording() { const remDoc = RecordingBox.screengrabber?.rootDoc; if (remDoc) { //if recordingbox is true; when we press the stop button. changed vals temporarily to see if changes happening RecordingBox.screengrabber?.Pause?.(); setTimeout(() => { RecordingBox.screengrabber?.Finish?.(); remDoc.overlayX = 70; //was 100 remDoc.overlayY = 590; RecordingBox.screengrabber = undefined; }, 100); //could break if recording takes too long to turn into videobox. If so, either increase time on setTimeout below or find diff place to do this setTimeout(() => Doc.RemFromMyOverlay(remDoc), 1000); Doc.UserDoc().workspaceRecordingState = media_state.Paused; Doc.AddDocToList(Doc.UserDoc(), 'workspaceRecordings', remDoc); } } /** * This method toggles whether or not we are currently using the RecordingBox to record with the topbar button * @param _readOnly_ * @returns */ @undoBatch @action public static WorkspaceStartRecording() { const screengrabber = Docs.Create.ScreenshotDocument({ title: `${Doc.ActiveDashboard?.title ?? ''} ${new DateField()}`, _width: 205, _height: 115, }); screengrabber.overlayX = 70; //was -400 screengrabber.overlayY = 590; //was 0 screengrabber[Doc.LayoutFieldKey(screengrabber) + '_trackScreen'] = true; Doc.AddToMyOverlay(screengrabber); //just adds doc to overlay DocumentManager.Instance.AddViewRenderedCb(screengrabber, docView => { RecordingBox.screengrabber = docView.ComponentView as RecordingBox; RecordingBox.screengrabber.Record?.(); }); Doc.UserDoc().workspaceRecordingState = media_state.Recording; } /** * This method changes the menu depending on whether or not we are in playback mode * @param value RecordingBox rootdoc */ @undoBatch @action public static replayWorkspace(value: Doc) { Doc.UserDoc().currentRecording = value; value.overlayX = 70; value.overlayY = 590; Doc.AddToMyOverlay(value); DocumentManager.Instance.AddViewRenderedCb(value, docView => { Doc.UserDoc().currentRecording = docView.rootDoc; SelectionManager.SelectSchemaViewDoc(value); RecordingBox.resumeWorkspaceReplaying(value); }); // let recordingIndex = DocListCast(Doc.UserDoc().workspaceRecordings).indexOf(value); // DragManager.StartDropdownDrag([document.createElement('div')], new DragManager.DocumentDragData([value]), 1, 1, recordingIndex); } /** * Adds the recording box to the canvas * @param value current recordingbox */ @undoBatch @action public static addRecToWorkspace(value: RecordingBox) { let ffView = Array.from(DocumentManager.Instance.DocumentViews).find(view => view.ComponentView instanceof CollectionFreeFormView); (ffView?.ComponentView as CollectionFreeFormView).props.addDocument?.(value.rootDoc); Doc.RemoveDocFromList(Doc.UserDoc(), 'workspaceRecordings', value.rootDoc); Doc.RemFromMyOverlay(value.rootDoc); Doc.UserDoc().currentRecording = undefined; Doc.UserDoc().workspaceReplayingState = undefined; Doc.UserDoc().workspaceRecordingState = undefined; } @undoBatch @action public static resumeWorkspaceReplaying(doc: Doc) { const docView = DocumentManager.Instance.getDocumentView(doc); const videoBox = docView?.ComponentView as VideoBox; if (videoBox) { videoBox.Play(); Doc.UserDoc().workspaceReplayingState = media_state.Playing; } } @undoBatch @action public static pauseWorkspaceReplaying(doc: Doc) { const docView = DocumentManager.Instance.getDocumentView(doc); const videoBox = docView?.ComponentView as VideoBox; if (videoBox) { videoBox.Pause(); } Doc.UserDoc().workspaceReplayingState = media_state.Paused; } @undoBatch @action public static stopWorkspaceReplaying(value: Doc) { Doc.RemFromMyOverlay(value); Doc.UserDoc().currentRecording = undefined; Doc.UserDoc().workspaceReplayingState = undefined; Doc.UserDoc().workspaceRecordingState = undefined; Doc.RemFromMyOverlay(value); } @undoBatch @action public static removeWorkspaceReplaying(value: Doc) { Doc.RemoveDocFromList(Doc.UserDoc(), 'workspaceRecordings', value); Doc.RemFromMyOverlay(value); Doc.UserDoc().currentRecording = undefined; Doc.UserDoc().workspaceReplayingState = undefined; Doc.UserDoc().workspaceRecordingState = undefined; } Record: undefined | (() => void); Pause: undefined | (() => void); Finish: undefined | (() => void); getControls = (record: () => void, pause: () => void, finish: () => void) => { this.Record = record; this.Pause = pause; this.Finish = finish; }; render() { return (
{!this.result && ( )}
); } static screengrabber: RecordingBox | undefined; } ScriptingGlobals.add(function startWorkspaceRecording() { RecordingBox.WorkspaceStartRecording(); }); ScriptingGlobals.add(function stopWorkspaceRecording() { RecordingBox.WorkspaceStopRecording(); }); ScriptingGlobals.add(function stopWorkspaceReplaying(value: Doc) { RecordingBox.stopWorkspaceReplaying(value); }); ScriptingGlobals.add(function removeWorkspaceReplaying(value: Doc) { RecordingBox.removeWorkspaceReplaying(value); }); ScriptingGlobals.add(function getCurrentRecording() { return Doc.UserDoc().currentRecording; }); ScriptingGlobals.add(function getWorkspaceRecordings() { return new List(['Record Workspace', ...DocListCast(Doc.UserDoc().workspaceRecordings)]); }); ScriptingGlobals.add(function isWorkspaceRecording() { return Doc.UserDoc().workspaceRecordingState === media_state.Recording; }); ScriptingGlobals.add(function isWorkspaceReplaying() { return Doc.UserDoc().workspaceReplayingState; }); ScriptingGlobals.add(function replayWorkspace(value: Doc | string, _readOnly_: boolean) { if (_readOnly_) return DocCast(Doc.UserDoc().currentRecording) ?? 'Record Workspace'; if (typeof value === 'string') RecordingBox.WorkspaceStartRecording(); else RecordingBox.replayWorkspace(value); }); ScriptingGlobals.add(function pauseWorkspaceReplaying(value: Doc, _readOnly_: boolean) { RecordingBox.pauseWorkspaceReplaying(value); }); ScriptingGlobals.add(function resumeWorkspaceReplaying(value: Doc, _readOnly_: boolean) { RecordingBox.resumeWorkspaceReplaying(value); }); ScriptingGlobals.add(function renderDropdown() { if (!Doc.UserDoc().workspaceRecordings || DocListCast(Doc.UserDoc().workspaceRecordings).length === 0) { return true; } return false; });