aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/ScreenshotBox.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/ScreenshotBox.tsx')
-rw-r--r--src/client/views/nodes/ScreenshotBox.tsx104
1 files changed, 48 insertions, 56 deletions
diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx
index ebb8a3374..1e3933ac3 100644
--- a/src/client/views/nodes/ScreenshotBox.tsx
+++ b/src/client/views/nodes/ScreenshotBox.tsx
@@ -1,12 +1,11 @@
-import React = require('react');
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import * as React from 'react';
// import { Canvas } from '@react-three/fiber';
-import { computed, observable, runInAction } from 'mobx';
+import { computed, makeObservable, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
// import { BufferAttribute, Camera, Vector2, Vector3 } from 'three';
import { DateField } from '../../../fields/DateField';
import { Doc } from '../../../fields/Doc';
-import { Height, Width } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { ComputedField } from '../../../fields/ScriptField';
import { Cast, DocCast, NumCast } from '../../../fields/Types';
@@ -18,16 +17,17 @@ import { DocumentType } from '../../documents/DocumentTypes';
import { Networking } from '../../Network';
import { CaptureManager } from '../../util/CaptureManager';
import { SettingsManager } from '../../util/SettingsManager';
+import { TrackMovements } from '../../util/TrackMovements';
import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
import { CollectionStackedTimeline } from '../collections/CollectionStackedTimeline';
import { ContextMenu } from '../ContextMenu';
-import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../DocComponent';
+import { ViewBoxAnnotatableComponent } from '../DocComponent';
+import { media_state } from './AudioBox';
import { FieldView, FieldViewProps } from './FieldView';
import { FormattedTextBox } from './formattedText/FormattedTextBox';
import './ScreenshotBox.scss';
import { VideoBox } from './VideoBox';
-import { TrackMovements } from '../../util/TrackMovements';
-import { media_state } from './AudioBox';
+import { DocData } from '../../../fields/DocSymbols';
declare class MediaRecorder {
constructor(e: any, options?: any); // whatever MediaRecorder has
@@ -38,18 +38,18 @@ declare class MediaRecorder {
// setRaised: (r: { coord: Vector2, off: Vector3 }[]) => void;
// x: number;
// y: number;
-// rootDoc: Doc;
+// doc: Doc;
// color: string;
// }
// @observer
// export class VideoTile extends React.Component<VideoTileProps> {
-// @observable _videoRef: HTMLVideoElement | undefined;
+// @observable _videoRef: HTMLVideoElement | undefined = undefined;
// _mesh: any = undefined;
// render() {
-// const topLeft = [this.props.x, this.props.y];
-// const raised = this.props.raised;
+// const topLeft = [this._props.x, this._props.y];
+// const raised = this._props.raised;
// const find = (raised: { coord: Vector2, off: Vector3 }[], what: Vector2) => raised.find(r => r.coord.x === what.x && r.coord.y === what.y);
// const tl1 = find(raised, new Vector2(topLeft[0], topLeft[1] + 1));
// const tl2 = find(raised, new Vector2(topLeft[0] + 1, topLeft[1] + 1));
@@ -70,11 +70,11 @@ declare class MediaRecorder {
// const normals = new Float32Array(quad_normals);
// const uvs = new Float32Array(quad_uvs); // Each vertex has one uv coordinate for texture mapping
// const indices = new Uint32Array(quad_indices); // Use the four vertices to draw the two triangles that make up the square.
-// const popOut = () => NumCast(this.props.rootDoc.popOut);
-// const popOff = () => NumCast(this.props.rootDoc.popOff);
+// const popOut = () => NumCast(this.Document.popOut);
+// const popOff = () => NumCast(this.Document.popOff);
// return (
// <mesh key={`mesh${topLeft[0]}${topLeft[1]}`} onClick={action(async e => {
-// this.props.setRaised([
+// this._props.setRaised([
// { coord: new Vector2(topLeft[0], topLeft[1]), off: new Vector3(-popOff(), -popOff(), popOut()) },
// { coord: new Vector2(topLeft[0] + 1, topLeft[1]), off: new Vector3(popOff(), -popOff(), popOut()) },
// { coord: new Vector2(topLeft[0], topLeft[1] + 1), off: new Vector3(-popOff(), popOff(), popOut()) },
@@ -100,7 +100,7 @@ declare class MediaRecorder {
// r?.setAttribute('uv', new BufferAttribute(uvs, 2));
// r?.setIndex(new BufferAttribute(indices, 1));
// }} />
-// {!this._videoRef ? <meshStandardMaterial color={this.props.color} /> :
+// {!this._videoRef ? <meshStandardMaterial color={this._props.color} /> :
// <meshBasicMaterial >
// <videoTexture attach="map" args={[this._videoRef]} />
// </meshBasicMaterial>}
@@ -110,7 +110,7 @@ declare class MediaRecorder {
// }
@observer
-export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps & FieldViewProps>() {
+export class ScreenshotBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
public static LayoutString(fieldKey: string) {
return FieldView.LayoutString(ScreenshotBox, fieldKey);
}
@@ -119,23 +119,17 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
@observable private _videoRef: HTMLVideoElement | null = null;
@observable _screenCapture = false;
@computed get recordingStart() {
- return Cast(this.dataDoc[this.props.fieldKey + '_recordingStart'], DateField)?.date.getTime();
+ return Cast(this.dataDoc[this._props.fieldKey + '_recordingStart'], DateField)?.date.getTime();
}
- constructor(props: any) {
+ constructor(props: FieldViewProps) {
super(props);
- if (this.rootDoc.videoWall) {
- this.rootDoc.nativeWidth = undefined;
- this.rootDoc.nativeHeight = undefined;
- this.layoutDoc.popOff = 0;
- this.layoutDoc.popOut = 1;
- } else {
- this.setupDictation();
- }
+ makeObservable(this);
+ this.setupDictation();
}
getAnchor = (addAsAnnotation: boolean) => {
const startTime = Cast(this.layoutDoc._layout_currentTimecode, 'number', null) || (this._videoRec ? (Date.now() - (this.recordingStart || 0)) / 1000 : undefined);
- return CollectionStackedTimeline.createAnchor(this.rootDoc, this.dataDoc, this.annotationKey, startTime, startTime === undefined ? undefined : startTime + 3, undefined, addAsAnnotation) || this.rootDoc;
+ return CollectionStackedTimeline.createAnchor(this.Document, this.dataDoc, this.annotationKey, startTime, startTime === undefined ? undefined : startTime + 3, undefined, addAsAnnotation) || this.Document;
};
videoLoad = () => {
@@ -145,14 +139,14 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
if (!nativeWidth || !nativeHeight) {
if (!nativeWidth) Doc.SetNativeWidth(this.dataDoc, 1200);
Doc.SetNativeHeight(this.dataDoc, (nativeWidth || 1200) / aspect);
- this.layoutDoc._height = (this.layoutDoc[Width]() || 0) / aspect;
+ this.layoutDoc._height = NumCast(this.layoutDoc._width) / aspect;
}
};
componentDidMount() {
this.dataDoc.nativeWidth = this.dataDoc.nativeHeight = 0;
- this.props.setContentView?.(this); // this tells the DocumentView that this ScreenshotBox is the "content" of the document. this allows the DocumentView to indirectly call getAnchor() on the AudioBox when making a link.
- // this.rootDoc.videoWall && reaction(() => ({ width: this.props.PanelWidth(), height: this.props.PanelHeight() }),
+ this._props.setContentViewBox?.(this); // this tells the DocumentView that this ScreenshotBox is the "content" of the document. this allows the DocumentView to indirectly call getAnchor() on the AudioBox when making a link.
+ // this.layoutDoc.videoWall && reaction(() => ({ width: this._props.PanelWidth(), height: this._props.PanelHeight() }),
// ({ width, height }) => {
// if (this._camera) {
// const angle = -Math.abs(1 - width / height);
@@ -174,7 +168,6 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
};
@computed get content() {
- if (this.rootDoc.videoWall) return null;
return (
<video
className={'videoBox-content'}
@@ -182,7 +175,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
ref={r => {
this._videoRef = r;
setTimeout(() => {
- if (this.rootDoc.mediaState === media_state.PendingRecording && this._videoRef) {
+ if (this.layoutDoc.mediaState === media_state.PendingRecording && this._videoRef) {
this.toggleRecording();
}
}, 100);
@@ -203,13 +196,13 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
// @observable _raised = [] as { coord: Vector2, off: Vector3 }[];
// @action setRaised = (r: { coord: Vector2, off: Vector3 }[]) => this._raised = r;
@computed get threed() {
- // if (this.rootDoc.videoWall) {
+ // if (this.layoutDoc.videoWall) {
// const screens: any[] = [];
// const colors = ["yellow", "red", "orange", "brown", "maroon", "gray"];
// let count = 0;
// numberRange(this._numScreens).forEach(x => numberRange(this._numScreens).forEach(y => screens.push(
- // <VideoTile rootDoc={this.rootDoc} color={colors[count++ % colors.length]} x={x} y={y} raised={this._raised} setRaised={this.setRaised} />)));
- // return <Canvas key="canvas" id="CANCAN" style={{ width: this.props.PanelWidth(), height: this.props.PanelHeight() }} gl={{ antialias: false }} colorManagement={false} onCreated={props => {
+ // <VideoTile doc={this.layoutDoc} color={colors[count++ % colors.length]} x={x} y={y} raised={this._raised} setRaised={this.setRaised} />)));
+ // return <Canvas key="canvas" id="CANCAN" style={{ width: this._props.PanelWidth(), height: this._props.PanelHeight() }} gl={{ antialias: false }} colorManagement={false} onCreated={props => {
// this._camera = props.camera;
// props.camera.position.set(this._numScreens / 2, this._numScreens / 2, this._numScreens - 2);
// props.camera.lookAt(this._numScreens / 2, this._numScreens / 2, 0);
@@ -232,15 +225,15 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
this._audioRec.onstop = async (e: any) => {
const [{ result }] = await Networking.UploadFilesToServer(aud_chunks.map((file: any) => ({ file })));
if (!(result instanceof Error)) {
- this.dataDoc[this.props.fieldKey + '_audio'] = new AudioField(result.accessPaths.agnostic.client);
+ this.dataDoc[this._props.fieldKey + '_audio'] = new AudioField(result.accessPaths.agnostic.client);
}
};
this._videoRef!.srcObject = await (navigator.mediaDevices as any).getDisplayMedia({ video: true });
this._videoRec = new MediaRecorder(this._videoRef!.srcObject);
const vid_chunks: any = [];
this._videoRec.onstart = () => {
- if (this.dataDoc[this.props.fieldKey + '_trackScreen']) TrackMovements.Instance.start();
- this.dataDoc[this.props.fieldKey + '_recordingStart'] = new DateField(new Date());
+ if (this.dataDoc[this._props.fieldKey + '_trackScreen']) TrackMovements.Instance.start();
+ this.dataDoc[this._props.fieldKey + '_recordingStart'] = new DateField(new Date());
};
this._videoRec.ondataavailable = (e: any) => vid_chunks.push(e.data);
this._videoRec.onstop = async (e: any) => {
@@ -251,7 +244,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
this.dataDoc[this.fieldKey + '_presentation'] = JSON.stringify(presCopy);
}
TrackMovements.Instance.finish();
- const file = new File(vid_chunks, `${this.rootDoc[Id]}.mkv`, { type: vid_chunks[0].type, lastModified: Date.now() });
+ const file = new File(vid_chunks, `${this.Document[Id]}.mkv`, { type: vid_chunks[0].type, lastModified: Date.now() });
const [{ result }] = await Networking.UploadFilesToServer({ file });
this.dataDoc[this.fieldKey + '_duration'] = (new Date().getTime() - this.recordingStart!) / 1000;
if (!(result instanceof Error)) {
@@ -260,7 +253,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
this.layoutDoc.layout = VideoBox.LayoutString(this.fieldKey);
this.dataDoc.nativeWidth = this.dataDoc.nativeHeight = undefined;
this.layoutDoc._layout_fitWidth = undefined;
- this.dataDoc[this.props.fieldKey] = new VideoField(result.accessPaths.agnostic.client);
+ this.dataDoc[this._props.fieldKey] = new VideoField(result.accessPaths.agnostic.client);
} else alert('video conversion failed');
};
this._audioRec.start();
@@ -280,23 +273,23 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
const ind = DocUtils.ActiveRecordings.indexOf(this);
ind !== -1 && DocUtils.ActiveRecordings.splice(ind, 1);
- CaptureManager.Instance.open(this.rootDoc);
+ CaptureManager.Instance.open(this.Document);
}
};
setupDictation = () => {
if (this.dataDoc[this.fieldKey + '_dictation']) return;
- const dictationText = DocUtils.GetNewTextDoc('dictation', NumCast(this.rootDoc.x), NumCast(this.rootDoc.y) + NumCast(this.layoutDoc._height) + 10, NumCast(this.layoutDoc._width), 2 * NumCast(this.layoutDoc._height));
+ const dictationText = DocUtils.GetNewTextDoc('dictation', NumCast(this.Document.x), NumCast(this.Document.y) + NumCast(this.layoutDoc._height) + 10, NumCast(this.layoutDoc._width), 2 * NumCast(this.layoutDoc._height));
const textField = Doc.LayoutFieldKey(dictationText);
dictationText._layout_autoHeight = false;
- const dictationTextProto = Doc.GetProto(dictationText);
+ const dictationTextProto = dictationText[DocData];
dictationTextProto[`${textField}_recordingSource`] = this.dataDoc;
- dictationTextProto[`${textField}_recordingStart`] = ComputedField.MakeFunction(`self.${textField}_recordingSource.${this.fieldKey}_recordingStart`);
- dictationTextProto.mediaState = ComputedField.MakeFunction(`self.${textField}_recordingSource.mediaState`);
+ dictationTextProto[`${textField}_recordingStart`] = ComputedField.MakeFunction(`this.${textField}_recordingSource.${this.fieldKey}_recordingStart`);
+ dictationTextProto.mediaState = ComputedField.MakeFunction(`this.${textField}_recordingSource.mediaState`);
this.dataDoc[this.fieldKey + '_dictation'] = dictationText;
};
- videoPanelHeight = () => (NumCast(this.dataDoc[this.fieldKey + '_nativeHeight'], this.layoutDoc[Height]()) / NumCast(this.dataDoc[this.fieldKey + '_nativeWidth'], this.layoutDoc[Width]())) * this.props.PanelWidth();
- formattedPanelHeight = () => Math.max(0, this.props.PanelHeight() - this.videoPanelHeight());
+ videoPanelHeight = () => (NumCast(this.dataDoc[this.fieldKey + '_nativeHeight'], NumCast(this.layoutDoc._height)) / NumCast(this.dataDoc[this.fieldKey + '_nativeWidth'], NumCast(this.layoutDoc._width))) * this._props.PanelWidth();
+ formattedPanelHeight = () => Math.max(0, this._props.PanelHeight() - this.videoPanelHeight());
render() {
TraceMobx();
return (
@@ -304,14 +297,14 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
<div className="videoBox-viewer">
<div style={{ position: 'relative', height: this.videoPanelHeight() }}>
<CollectionFreeFormView
- {...this.props}
- setContentView={emptyFunction}
+ {...this._props}
+ setContentViewBox={emptyFunction}
NativeWidth={returnZero}
NativeHeight={returnZero}
PanelHeight={this.videoPanelHeight}
- PanelWidth={this.props.PanelWidth}
- focus={this.props.focus}
- isSelected={this.props.isSelected}
+ PanelWidth={this._props.PanelWidth}
+ focus={this._props.focus}
+ isSelected={this._props.isSelected}
isAnnotationOverlay={true}
select={emptyFunction}
isContentActive={returnFalse}
@@ -321,8 +314,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
removeDocument={returnFalse}
moveDocument={returnFalse}
addDocument={returnFalse}
- ScreenToLocalTransform={this.props.ScreenToLocalTransform}
- renderDepth={this.props.renderDepth + 1}>
+ renderDepth={this._props.renderDepth + 1}>
<>
{this.threed}
{this.content}
@@ -332,7 +324,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
<div style={{ background: SettingsManager.userColor, position: 'relative', height: this.formattedPanelHeight() }}>
{!(this.dataDoc[this.fieldKey + '_dictation'] instanceof Doc) ? null : (
<FormattedTextBox
- {...this.props}
+ {...this._props}
Document={DocCast(this.dataDoc[this.fieldKey + '_dictation'])}
fieldKey={'text'}
PanelHeight={this.formattedPanelHeight}
@@ -345,12 +337,12 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
removeDocument={returnFalse}
moveDocument={returnFalse}
addDocument={returnFalse}
- renderDepth={this.props.renderDepth + 1}
+ renderDepth={this._props.renderDepth + 1}
/>
)}
</div>
</div>
- {!this.props.isSelected() ? null : (
+ {!this._props.isSelected() ? null : (
<div className="screenshotBox-uiButtons" style={{ background: SettingsManager.userColor }}>
<div className="screenshotBox-recorder" style={{ color: SettingsManager.userBackgroundColor, background: SettingsManager.userVariantColor }} key="snap" onPointerDown={this.toggleRecording}>
<FontAwesomeIcon icon="file" size="lg" />