From 61ce7b4d434aff7e642d2af17b8643297f99e4a3 Mon Sep 17 00:00:00 2001
From: mehekj <mehek.jethani@gmail.com>
Date: Wed, 15 Mar 2023 18:15:18 -0400
Subject: column drag in progress

---
 .../views/nodes/RecordingBox/RecordingView.tsx     | 177 ++++++++++-----------
 1 file changed, 85 insertions(+), 92 deletions(-)

(limited to 'src/client/views/nodes/RecordingBox/RecordingView.tsx')

diff --git a/src/client/views/nodes/RecordingBox/RecordingView.tsx b/src/client/views/nodes/RecordingBox/RecordingView.tsx
index ec5917b9e..6efe62e0b 100644
--- a/src/client/views/nodes/RecordingBox/RecordingView.tsx
+++ b/src/client/views/nodes/RecordingBox/RecordingView.tsx
@@ -1,32 +1,31 @@
 import * as React from 'react';
-import "./RecordingView.scss";
-import { useEffect, useRef, useState } from "react";
-import { ProgressBar } from "./ProgressBar"
+import './RecordingView.scss';
+import { useEffect, useRef, useState } from 'react';
+import { ProgressBar } from './ProgressBar';
 import { MdBackspace } from 'react-icons/md';
 import { FaCheckCircle } from 'react-icons/fa';
-import { IconContext } from "react-icons";
+import { IconContext } from 'react-icons';
 import { Networking } from '../../../Network';
 import { Upload } from '../../../../server/SharedMediaTypes';
 import { returnFalse, returnTrue, setupMoveUpEvents } from '../../../../Utils';
 import { Presentation, TrackMovements } from '../../../util/TrackMovements';
 
 export interface MediaSegment {
-    videoChunks: any[],
-    endTime: number,
-    startTime: number,
-    presentation?: Presentation,
+    videoChunks: any[];
+    endTime: number;
+    startTime: number;
+    presentation?: Presentation;
 }
 
 interface IRecordingViewProps {
-    setResult: (info: Upload.AccessPathInfo, presentation?: Presentation) => void
-    setDuration: (seconds: number) => void
-    id: string
+    setResult: (info: Upload.AccessPathInfo, presentation?: Presentation) => void;
+    setDuration: (seconds: number) => void;
+    id: string;
 }
 
 const MAXTIME = 100000;
 
 export function RecordingView(props: IRecordingViewProps) {
-
     const [recording, setRecording] = useState(false);
     const recordingTimerRef = useRef<number>(0);
     const [recordingTimer, setRecordingTimer] = useState(0); // unit is 0.01 second
@@ -46,19 +45,16 @@ export function RecordingView(props: IRecordingViewProps) {
     const [finished, setFinished] = useState<boolean>(false);
     const [trackScreen, setTrackScreen] = useState<boolean>(false);
 
-
-
     const DEFAULT_MEDIA_CONSTRAINTS = {
         video: {
             width: 1280,
             height: 720,
-
         },
         audio: {
             echoCancellation: true,
             noiseSuppression: true,
-            sampleRate: 44100
-        }
+            sampleRate: 44100,
+        },
     };
 
     useEffect(() => {
@@ -71,12 +67,11 @@ export function RecordingView(props: IRecordingViewProps) {
                 const videoFiles = videos.map((vid, i) => new File(vid.videoChunks, `segvideo${i}.mkv`, { type: vid.videoChunks[0].type, lastModified: Date.now() }));
 
                 // upload the segments to the server and get their server access paths
-                const serverPaths: string[] = (await Networking.UploadFilesToServer(videoFiles))
-                    .map(res => (res.result instanceof Error) ? '' : res.result.accessPaths.agnostic.server)
+                const serverPaths: string[] = (await Networking.UploadFilesToServer(videoFiles)).map(res => (res.result instanceof Error ? '' : res.result.accessPaths.agnostic.server));
 
                 // concat the segments together using post call
                 const result: Upload.AccessPathInfo | Error = await Networking.PostToServer('/concatVideos', serverPaths);
-                !(result instanceof Error) ? props.setResult(result, concatPres || undefined) : console.error("video conversion failed");
+                !(result instanceof Error) ? props.setResult(result, concatPres || undefined) : console.error('video conversion failed');
             })();
         }
     }, [videos]);
@@ -87,7 +82,9 @@ export function RecordingView(props: IRecordingViewProps) {
     }, [finished]);
 
     // check if the browser supports media devices on first load
-    useEffect(() => { if (!navigator.mediaDevices) alert('This browser does not support getUserMedia.'); }, []);
+    useEffect(() => {
+        if (!navigator.mediaDevices) alert('This browser does not support getUserMedia.');
+    }, []);
 
     useEffect(() => {
         let interval: any = null;
@@ -102,24 +99,24 @@ export function RecordingView(props: IRecordingViewProps) {
     }, [recording]);
 
     useEffect(() => {
-        setVideoProgressHelper(recordingTimer)
+        setVideoProgressHelper(recordingTimer);
         recordingTimerRef.current = recordingTimer;
     }, [recordingTimer]);
 
     const setVideoProgressHelper = (progress: number) => {
         const newProgress = (progress / MAXTIME) * 100;
         setProgress(newProgress);
-    }
+    };
 
     const startShowingStream = async (mediaConstraints = DEFAULT_MEDIA_CONSTRAINTS) => {
         const stream = await navigator.mediaDevices.getUserMedia(mediaConstraints);
 
-        videoElementRef.current!.src = "";
+        videoElementRef.current!.src = '';
         videoElementRef.current!.srcObject = stream;
         videoElementRef.current!.muted = true;
 
         return stream;
-    }
+    };
 
     const record = async () => {
         // don't need to start a new stream every time we start recording a new segment
@@ -145,29 +142,28 @@ export function RecordingView(props: IRecordingViewProps) {
                 const nextVideo = {
                     videoChunks,
                     endTime: recordingTimerRef.current,
-                    startTime: videos?.lastElement()?.endTime || 0
+                    startTime: videos?.lastElement()?.endTime || 0,
                 };
 
                 // depending on if a presenation exists, add it to the video
                 const presentation = TrackMovements.Instance.yieldPresentation();
-                setVideos(videos => [...videos, (presentation != null && trackScreen) ? { ...nextVideo, presentation } : nextVideo]);
+                setVideos(videos => [...videos, presentation != null && trackScreen ? { ...nextVideo, presentation } : nextVideo]);
             }
 
             // reset the temporary chunks
             videoChunks = [];
             setRecording(false);
-        }
+        };
 
         videoRecorder.current.start(200);
-    }
-
+    };
 
     // if this is called, then we're done recording all the segments
     const finish = (e: React.PointerEvent) => {
         e.stopPropagation();
 
         // call stop on the video recorder if active
-        videoRecorder.current?.state !== "inactive" && videoRecorder.current?.stop();
+        videoRecorder.current?.state !== 'inactive' && videoRecorder.current?.stop();
 
         // end the streams (audio/video) to remove recording icon
         const stream = videoElementRef.current!.srcObject;
@@ -178,94 +174,91 @@ export function RecordingView(props: IRecordingViewProps) {
 
         // this will call upon progessbar to update videos to be in the correct order
         setFinished(true);
-    }
+    };
 
     const pause = (e: React.PointerEvent) => {
         e.stopPropagation();
         // if recording, then this is just a new segment
-        videoRecorder.current?.state === "recording" && videoRecorder.current.stop();
-    }
+        videoRecorder.current?.state === 'recording' && videoRecorder.current.stop();
+    };
 
     const start = (e: React.PointerEvent) => {
-        setupMoveUpEvents({}, e, returnTrue, returnFalse, e => {
-            // start recording if not already recording
-            if (!videoRecorder.current || videoRecorder.current.state === "inactive") record();
-
-            return true; // cancels propagation to documentView to avoid selecting it.
-        }, false, false);
-    }
+        setupMoveUpEvents(
+            {},
+            e,
+            returnTrue,
+            returnFalse,
+            e => {
+                // start recording if not already recording
+                if (!videoRecorder.current || videoRecorder.current.state === 'inactive') record();
+
+                return true; // cancels propagation to documentView to avoid selecting it.
+            },
+            false,
+            false
+        );
+    };
 
     const undoPrevious = (e: React.PointerEvent) => {
         e.stopPropagation();
         setDoUndo(prev => !prev);
-    }
+    };
 
-    const handleOnTimeUpdate = () => { playing && setVideoProgressHelper(videoElementRef.current!.currentTime); };
+    const handleOnTimeUpdate = () => {
+        playing && setVideoProgressHelper(videoElementRef.current!.currentTime);
+    };
 
     const millisecondToMinuteSecond = (milliseconds: number) => {
         const toTwoDigit = (digit: number) => {
-            return String(digit).length == 1 ? "0" + digit : digit
-        }
+            return String(digit).length == 1 ? '0' + digit : digit;
+        };
         const minutes = Math.floor((milliseconds % (1000 * 60 * 60)) / (1000 * 60));
         const seconds = Math.floor((milliseconds % (1000 * 60)) / 1000);
-        return toTwoDigit(minutes) + " : " + toTwoDigit(seconds);
-    }
+        return toTwoDigit(minutes) + ' : ' + toTwoDigit(seconds);
+    };
 
     return (
         <div className="recording-container">
             <div className="video-wrapper">
-                <video id={`video-${props.id}`}
-                    autoPlay
-                    muted
-                    onTimeUpdate={() => handleOnTimeUpdate()}
-                    ref={videoElementRef}
-                />
+                <video id={`video-${props.id}`} autoPlay muted onTimeUpdate={() => handleOnTimeUpdate()} ref={videoElementRef} />
                 <div className="recording-sign">
                     <span className="dot" />
                     <p className="timer">{millisecondToMinuteSecond(recordingTimer * 10)}</p>
                 </div>
                 <div className="controls">
-
                     <div className="controls-inner-container">
-                        <div className="record-button-wrapper">
-                            {recording ?
-                                <button className="stop-button" onPointerDown={pause} /> :
-                                <button className="record-button" onPointerDown={start} />
-                            }
-                        </div>
-
-                        {!recording && (videos.length > 0 ?
-
-                            <div className="options-wrapper video-edit-wrapper">
-                                <IconContext.Provider value={{ color: "grey", className: "video-edit-buttons", style: { display: canUndo ? 'inherit' : 'none' } }}>
-                                    <MdBackspace onPointerDown={undoPrevious} />
-                                </IconContext.Provider>
-                                <IconContext.Provider value={{ color: "#cc1c08", className: "video-edit-buttons" }}>
-                                    <FaCheckCircle onPointerDown={finish} />
-                                </IconContext.Provider>
-                            </div>
-
-                            : <div className="options-wrapper track-screen-wrapper">
-                                <label className="track-screen">
-                                    <input type="checkbox" checked={trackScreen} onChange={(e) => { setTrackScreen(e.target.checked) }} />
-                                    <span className="checkmark"></span>
-                                    Track Screen
-                                </label>
-                            </div>)}
-
+                        <div className="record-button-wrapper">{recording ? <button className="stop-button" onPointerDown={pause} /> : <button className="record-button" onPointerDown={start} />}</div>
+
+                        {!recording &&
+                            (videos.length > 0 ? (
+                                <div className="options-wrapper video-edit-wrapper">
+                                    <IconContext.Provider value={{ color: 'grey', className: 'video-edit-buttons', style: { display: canUndo ? 'inherit' : 'none' } }}>
+                                        <MdBackspace onPointerDown={undoPrevious} />
+                                    </IconContext.Provider>
+                                    <IconContext.Provider value={{ color: '#cc1c08', className: 'video-edit-buttons' }}>
+                                        <FaCheckCircle onPointerDown={finish} />
+                                    </IconContext.Provider>
+                                </div>
+                            ) : (
+                                <div className="options-wrapper track-screen-wrapper">
+                                    <label className="track-screen">
+                                        <input
+                                            type="checkbox"
+                                            checked={trackScreen}
+                                            onChange={e => {
+                                                setTrackScreen(e.target.checked);
+                                            }}
+                                        />
+                                        <span className="checkmark"></span>
+                                        Track Screen
+                                    </label>
+                                </div>
+                            ))}
                     </div>
-
                 </div>
 
-                <ProgressBar
-                    videos={videos}
-                    setVideos={setVideos}
-                    orderVideos={orderVideos}
-                    progress={progress}
-                    recording={recording}
-                    doUndo={doUndo}
-                    setCanUndo={setCanUndo}
-                />
+                <ProgressBar videos={videos} setVideos={setVideos} orderVideos={orderVideos} progress={progress} recording={recording} doUndo={doUndo} setCanUndo={setCanUndo} />
             </div>
-        </div>)
-}
\ No newline at end of file
+        </div>
+    );
+}
-- 
cgit v1.2.3-70-g09d2


From 2a584d4827c9ece87f3bd618201f356237ba7fc7 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 1 May 2023 12:49:06 -0400
Subject: fixed RecordingBox/View serialization to save docid, not Doc.

---
 src/client/util/ReplayMovements.ts                 |  27 +++---
 src/client/util/TrackMovements.ts                  |   2 +-
 .../views/nodes/RecordingBox/RecordingBox.tsx      | 106 +++++++++++----------
 .../views/nodes/RecordingBox/RecordingView.tsx     |  10 +-
 src/fields/Doc.ts                                  |   5 +-
 src/server/DashUploadUtils.ts                      |  14 ++-
 src/server/websocket.ts                            |  23 +++--
 7 files changed, 102 insertions(+), 85 deletions(-)

(limited to 'src/client/views/nodes/RecordingBox/RecordingView.tsx')

diff --git a/src/client/util/ReplayMovements.ts b/src/client/util/ReplayMovements.ts
index 40261985a..22cca4a2e 100644
--- a/src/client/util/ReplayMovements.ts
+++ b/src/client/util/ReplayMovements.ts
@@ -1,13 +1,11 @@
+import { IReactionDisposer, observable, reaction } from 'mobx';
+import { Doc, IdToDoc } from '../../fields/Doc';
+import { CollectionDockingView } from '../views/collections/CollectionDockingView';
 import { CollectionFreeFormView } from '../views/collections/collectionFreeForm';
-import { IReactionDisposer, observable, observe, reaction } from 'mobx';
-import { Doc } from '../../fields/Doc';
+import { OpenWhereMod } from '../views/nodes/DocumentView';
 import { VideoBox } from '../views/nodes/VideoBox';
 import { DocumentManager } from './DocumentManager';
-import { CollectionDockingView } from '../views/collections/CollectionDockingView';
-import { DocServer } from '../DocServer';
 import { Movement, Presentation } from './TrackMovements';
-import { OpenWhereMod } from '../views/nodes/DocumentView';
-import { returnTransparent } from '../../Utils';
 
 export class ReplayMovements {
     private timers: NodeJS.Timeout[] | null;
@@ -61,7 +59,7 @@ export class ReplayMovements {
             return;
         }
 
-        const docIdtoDoc = this.loadPresentation(presentation);
+        this.loadPresentation(presentation);
 
         this.videoBoxDisposeFunc = reaction(
             () => ({ playing: videoBox._playing, timeViewed: videoBox.player?.currentTime || 0 }),
@@ -94,13 +92,14 @@ export class ReplayMovements {
             throw '[recordingApi.ts] followMovements() failed: no presentation data';
         }
 
-        // generate a set of all unique docIds
-        const docs = new Set<Doc>();
-        for (const { doc } of movements) {
-            if (!docs.has(doc)) docs.add(doc);
-        }
-
-        return docs;
+        movements.forEach((movement, i) => {
+            if (typeof movement.doc === 'string') {
+                movements[i].doc = IdToDoc(movement.doc);
+                if (!movements[i].doc) {
+                    console.log('ERROR: tracked doc not found');
+                }
+            }
+        });
     };
 
     // returns undefined if the docView isn't open on the screen
diff --git a/src/client/util/TrackMovements.ts b/src/client/util/TrackMovements.ts
index 2f16307b3..cb8225643 100644
--- a/src/client/util/TrackMovements.ts
+++ b/src/client/util/TrackMovements.ts
@@ -234,7 +234,7 @@ export class TrackMovements {
         const movement: Movement = { time, panX, panY, scale, doc };
 
         // add that movement to the current presentation data's movement array
-        this.currentPresentation.movements && this.currentPresentation.movements.push(movement);
+        this.currentPresentation.movements?.push(movement);
     };
 
     // method that concatenates an array of presentatations into one
diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx
index 0ff7c4292..f406ffbea 100644
--- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx
+++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx
@@ -1,58 +1,64 @@
-import { action, observable } from "mobx";
-import { observer } from "mobx-react";
-import * as React from "react";
-import { VideoField } from "../../../../fields/URLField";
-import { Upload } from "../../../../server/SharedMediaTypes";
-import { ViewBoxBaseComponent } from "../../DocComponent";
-import { FieldView } from "../FieldView";
-import { VideoBox } from "../VideoBox";
+import { action, observable } from 'mobx';
+import { observer } from 'mobx-react';
+import * as React from 'react';
+import { VideoField } from '../../../../fields/URLField';
+import { Upload } from '../../../../server/SharedMediaTypes';
+import { ViewBoxBaseComponent } from '../../DocComponent';
+import { FieldView } from '../FieldView';
+import { VideoBox } from '../VideoBox';
 import { RecordingView } from './RecordingView';
-import { DocumentType } from "../../../documents/DocumentTypes";
-import { Presentation } from "../../../util/TrackMovements";
-import { Doc } from "../../../../fields/Doc";
-import { Id } from "../../../../fields/FieldSymbols";
-
+import { DocumentType } from '../../../documents/DocumentTypes';
+import { Presentation } from '../../../util/TrackMovements';
+import { Doc } from '../../../../fields/Doc';
+import { Id } from '../../../../fields/FieldSymbols';
 
 @observer
 export class RecordingBox extends ViewBoxBaseComponent() {
+    public static LayoutString(fieldKey: string) {
+        return FieldView.LayoutString(RecordingBox, fieldKey);
+    }
 
-      public static LayoutString(fieldKey: string) { return FieldView.LayoutString(RecordingBox, fieldKey); }
-
-      private _ref: React.RefObject<HTMLDivElement> = React.createRef();
+    private _ref: React.RefObject<HTMLDivElement> = React.createRef();
 
-      constructor(props: any) {
+    constructor(props: any) {
         super(props);
-      }
-
-      componentDidMount() {
-            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
-            presentation?.movements && (this.dataDoc[this.fieldKey + "-presentation"] = JSON.stringify(presentation));
-      }
-
-      render() {
-            return <div className="recordingBox" ref={this._ref}>
-                  {!this.result && <RecordingView setResult={this.setResult} setDuration={this.setVideoDuration} id={this.rootDoc.proto?.[Id] || ''} />}
-            </div>;
-      }
+    }
+
+    componentDidMount() {
+        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);
+        }
+    };
+
+    render() {
+        return (
+            <div className="recordingBox" ref={this._ref}>
+                {!this.result && <RecordingView setResult={this.setResult} setDuration={this.setVideoDuration} id={this.rootDoc.proto?.[Id] || ''} />}
+            </div>
+        );
+    }
 }
diff --git a/src/client/views/nodes/RecordingBox/RecordingView.tsx b/src/client/views/nodes/RecordingBox/RecordingView.tsx
index 6efe62e0b..424ebc384 100644
--- a/src/client/views/nodes/RecordingBox/RecordingView.tsx
+++ b/src/client/views/nodes/RecordingBox/RecordingView.tsx
@@ -1,14 +1,14 @@
 import * as React from 'react';
-import './RecordingView.scss';
 import { useEffect, useRef, useState } from 'react';
-import { ProgressBar } from './ProgressBar';
-import { MdBackspace } from 'react-icons/md';
-import { FaCheckCircle } from 'react-icons/fa';
 import { IconContext } from 'react-icons';
-import { Networking } from '../../../Network';
+import { FaCheckCircle } from 'react-icons/fa';
+import { MdBackspace } from 'react-icons/md';
 import { Upload } from '../../../../server/SharedMediaTypes';
 import { returnFalse, returnTrue, setupMoveUpEvents } from '../../../../Utils';
+import { Networking } from '../../../Network';
 import { Presentation, TrackMovements } from '../../../util/TrackMovements';
+import { ProgressBar } from './ProgressBar';
+import './RecordingView.scss';
 
 export interface MediaSegment {
     videoChunks: any[];
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 93c28cf08..0ec881c48 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -1703,8 +1703,11 @@ export namespace Doc {
     }
 }
 
+export function IdToDoc(id: string) {
+    return DocCast(DocServer.GetCachedRefField(id));
+}
 ScriptingGlobals.add(function idToDoc(id: string): any {
-    return DocServer.GetCachedRefField(id);
+    return IdToDoc(id);
 });
 ScriptingGlobals.add(function renameAlias(doc: any) {
     return StrCast(Doc.GetProto(doc).title).replace(/\([0-9]*\)/, '') + `(${doc.aliasNumber})`;
diff --git a/src/server/DashUploadUtils.ts b/src/server/DashUploadUtils.ts
index f461cf3fa..070d49ec3 100644
--- a/src/server/DashUploadUtils.ts
+++ b/src/server/DashUploadUtils.ts
@@ -70,7 +70,14 @@ export namespace DashUploadUtils {
         // make a list of paths to create the ordered text file for ffmpeg
         const filePathsText = filePaths.map(filePath => `file '${filePath}'`).join('\n');
         // write the text file to the file system
-        writeFile(textFilePath, filePathsText, err => console.log(err));
+        await new Promise<void>((res, reject) =>
+            writeFile(textFilePath, filePathsText, err => {
+                if (err) {
+                    reject();
+                    console.log(err);
+                } else res();
+            })
+        );
 
         // make output file name based on timestamp
         const outputFileName = `output-${Utils.GenerateGuid()}.mp4`;
@@ -86,7 +93,10 @@ export namespace DashUploadUtils {
                 .outputOptions('-c copy')
                 //.videoCodec("copy")
                 .save(outputFilePath)
-                .on('error', reject)
+                .on('error', (err: any) => {
+                    console.log(err);
+                    reject();
+                })
                 .on('end', resolve);
         });
 
diff --git a/src/server/websocket.ts b/src/server/websocket.ts
index a11d20cfa..2acdaa5a3 100644
--- a/src/server/websocket.ts
+++ b/src/server/websocket.ts
@@ -51,7 +51,7 @@ export namespace WebSocket {
                 next();
             });
 
-            socket.emit(MessageStore.UpdateStats.Message, DashStats.getUpdatedStatsBundle())
+            socket.emit(MessageStore.UpdateStats.Message, DashStats.getUpdatedStatsBundle());
 
             // convenience function to log server messages on the client
             function log(message?: any, ...optionalParams: any[]) {
@@ -104,14 +104,12 @@ export namespace WebSocket {
             socket.on('disconnect', function () {
                 let currentUser = socketMap.get(socket);
                 if (!(currentUser === undefined)) {
-                    let currentUsername = currentUser.split(' ')[0]
+                    let currentUsername = currentUser.split(' ')[0];
                     DashStats.logUserLogout(currentUsername, socket);
-                    delete timeMap[currentUsername]
+                    delete timeMap[currentUsername];
                 }
             });
 
-
-
             Utils.Emit(socket, MessageStore.Foo, 'handshooken');
 
             Utils.AddServerHandler(socket, MessageStore.Bar, guid => barReceived(socket, guid));
@@ -146,10 +144,10 @@ export namespace WebSocket {
             };
         });
 
-        setInterval(function() {
+        setInterval(function () {
             // Utils.Emit(socket, MessageStore.UpdateStats, DashStats.getUpdatedStatsBundle());
 
-            io.emit(MessageStore.UpdateStats.Message, DashStats.getUpdatedStatsBundle())
+            io.emit(MessageStore.UpdateStats.Message, DashStats.getUpdatedStatsBundle());
         }, DashStats.SAMPLING_INTERVAL);
     }
 
@@ -193,7 +191,7 @@ export namespace WebSocket {
     }
 
     function barReceived(socket: SocketIO.Socket, userEmail: string) {
-         clients[userEmail] = new Client(userEmail.toString());
+        clients[userEmail] = new Client(userEmail.toString());
         const currentdate = new Date();
         const datetime = currentdate.getDate() + '/' + (currentdate.getMonth() + 1) + '/' + currentdate.getFullYear() + ' @ ' + currentdate.getHours() + ':' + currentdate.getMinutes() + ':' + currentdate.getSeconds();
         console.log(blue(`user ${userEmail} has connected to the web socket at: ${datetime}`));
@@ -326,8 +324,7 @@ export namespace WebSocket {
         const remListItems = diff.diff.$set[updatefield].fields;
         const curList = (curListItems as any)?.fields?.[updatefield.replace('fields.', '')]?.fields.filter((f: any) => f !== null) || [];
         diff.diff.$set[updatefield].fields = curList?.filter(
-            (curItem: any) => !remListItems.some((remItem: any) => (remItem.fieldId ? remItem.fieldId === curItem.fieldId :
-                 remItem.heading ? remItem.heading === curItem.heading : remItem === curItem))
+            (curItem: any) => !remListItems.some((remItem: any) => (remItem.fieldId ? remItem.fieldId === curItem.fieldId : remItem.heading ? remItem.heading === curItem.heading : remItem === curItem))
         );
         const sendBack = diff.diff.length !== diff.diff.$set[updatefield].fields.length;
         delete diff.diff.length;
@@ -373,9 +370,11 @@ export namespace WebSocket {
     var CurUser: string | undefined = undefined;
 
     function UpdateField(socket: Socket, diff: Diff) {
-        let currentUsername = socketMap.get(socket)!.split(' ')[0];
+        const curUser = socketMap.get(socket);
+        if (!curUser) return;
+        let currentUsername = curUser.split(' ')[0];
         userOperations.set(currentUsername, userOperations.get(currentUsername) !== undefined ? userOperations.get(currentUsername)! + 1 : 0);
-        
+
         if (CurUser !== socketMap.get(socket)) {
             CurUser = socketMap.get(socket);
             console.log('Switch User: ' + CurUser);
-- 
cgit v1.2.3-70-g09d2


From 27f518632c24f69fff360bef36eb0e5426167b83 Mon Sep 17 00:00:00 2001
From: James Hu <51237606+jameshu111@users.noreply.github.com>
Date: Wed, 7 Jun 2023 12:30:53 -0400
Subject: Update other uses

---
 src/client/documents/Documents.ts                      | 4 ++--
 src/client/util/Import & Export/DirectoryImportBox.tsx | 2 +-
 src/client/util/ReportManager.tsx                      | 2 +-
 src/client/views/nodes/AudioBox.tsx                    | 2 +-
 src/client/views/nodes/DocumentView.tsx                | 2 +-
 src/client/views/nodes/RecordingBox/RecordingView.tsx  | 2 +-
 src/client/views/nodes/ScreenshotBox.tsx               | 4 ++--
 src/mobile/ImageUpload.tsx                             | 2 +-
 src/server/ApiManagers/UploadManager.ts                | 2 +-
 9 files changed, 11 insertions(+), 11 deletions(-)

(limited to 'src/client/views/nodes/RecordingBox/RecordingView.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 77f0e1e5e..0030af982 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -1844,7 +1844,7 @@ export namespace DocUtils {
     export async function uploadFilesToDocs(files: File[], options: DocumentOptions) {
         const generatedDocuments: Doc[] = [];
         const fileNoGuidPairs: Networking.FileGuidPair[] = [];
-        files.map(file => fileNoGuidPairs.push({file : file}));
+        files.map(file => fileNoGuidPairs.push({file}));
         const upfiles = await Networking.UploadFilesToServer(fileNoGuidPairs);
         for (const {
             source: { name, type },
@@ -1857,7 +1857,7 @@ export namespace DocUtils {
 
     export function uploadFileToDoc(file: File, options: DocumentOptions, overwriteDoc: Doc) {
         const generatedDocuments: Doc[] = [];
-        Networking.UploadFilesToServer([{file: file, guid: overwriteDoc[Id]}]).then(upfiles => {
+        Networking.UploadFilesToServer([{file, guid: overwriteDoc[Id]}]).then(upfiles => {
             const {
                 source: { name, type },
                 result,
diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx
index b9bb22564..1a4c2450e 100644
--- a/src/client/util/Import & Export/DirectoryImportBox.tsx	
+++ b/src/client/util/Import & Export/DirectoryImportBox.tsx	
@@ -112,7 +112,7 @@ export class DirectoryImportBox extends React.Component<FieldViewProps> {
                 sizes.push(file.size);
                 modifiedDates.push(file.lastModified);
             });
-            collector.push(...(await Networking.UploadFilesToServer<Upload.ImageInformation>(batch)));
+            collector.push(...(await Networking.UploadFilesToServer<Upload.ImageInformation>(batch.map(file =>({file})))));
             runInAction(() => (this.completed += batch.length));
         });
 
diff --git a/src/client/util/ReportManager.tsx b/src/client/util/ReportManager.tsx
index 51742d455..4c1020455 100644
--- a/src/client/util/ReportManager.tsx
+++ b/src/client/util/ReportManager.tsx
@@ -173,7 +173,7 @@ export class ReportManager extends React.Component<{}> {
         // upload the files to the server
         if (input.files && input.files.length !== 0) {
             const fileArray: File[] = Array.from(input.files);
-            (Networking.UploadFilesToServer(fileArray)).then(links => {
+            (Networking.UploadFilesToServer(fileArray.map(file =>({file})))).then(links => {
                 console.log('finshed uploading', links.map(this.getServerPath));
                 this.setFileLinks((links ?? []).map(this.getServerPath));
             })
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 0cb849923..6558d215a 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -233,7 +233,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
         this.dataDoc[this.fieldKey + '-recordingStart'] = new DateField();
         DocUtils.ActiveRecordings.push(this);
         this._recorder.ondataavailable = async (e: any) => {
-            const [{ result }] = await Networking.UploadFilesToServer(e.data);
+            const [{ result }] = await Networking.UploadFilesToServer({file: e.data});
             if (!(result instanceof Error)) {
                 this.props.Document[this.fieldKey] = new AudioField(result.accessPaths.agnostic.client);
             }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 0769e26d0..687683e6e 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1013,7 +1013,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
                 gumStream = stream;
                 recorder = new MediaRecorder(stream);
                 recorder.ondataavailable = async (e: any) => {
-                    const [{ result }] = await Networking.UploadFilesToServer(e.data);
+                    const [{ result }] = await Networking.UploadFilesToServer({file: e.data});
                     if (!(result instanceof Error)) {
                         const audioField = new AudioField(result.accessPaths.agnostic.client);
                         const audioAnnos = Cast(dataDoc[field + '-audioAnnotations'], listSpec(AudioField), null);
diff --git a/src/client/views/nodes/RecordingBox/RecordingView.tsx b/src/client/views/nodes/RecordingBox/RecordingView.tsx
index 424ebc384..51eb774e2 100644
--- a/src/client/views/nodes/RecordingBox/RecordingView.tsx
+++ b/src/client/views/nodes/RecordingBox/RecordingView.tsx
@@ -67,7 +67,7 @@ export function RecordingView(props: IRecordingViewProps) {
                 const videoFiles = videos.map((vid, i) => new File(vid.videoChunks, `segvideo${i}.mkv`, { type: vid.videoChunks[0].type, lastModified: Date.now() }));
 
                 // upload the segments to the server and get their server access paths
-                const serverPaths: string[] = (await Networking.UploadFilesToServer(videoFiles)).map(res => (res.result instanceof Error ? '' : res.result.accessPaths.agnostic.server));
+                const serverPaths: string[] = (await Networking.UploadFilesToServer(videoFiles.map(file => ({file})))).map(res => (res.result instanceof Error ? '' : res.result.accessPaths.agnostic.server));
 
                 // concat the segments together using post call
                 const result: Upload.AccessPathInfo | Error = await Networking.PostToServer('/concatVideos', serverPaths);
diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx
index 1e178b123..312b3c619 100644
--- a/src/client/views/nodes/ScreenshotBox.tsx
+++ b/src/client/views/nodes/ScreenshotBox.tsx
@@ -224,7 +224,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
             const aud_chunks: any = [];
             this._audioRec.ondataavailable = (e: any) => aud_chunks.push(e.data);
             this._audioRec.onstop = async (e: any) => {
-                const [{ result }] = await Networking.UploadFilesToServer(aud_chunks);
+                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);
                 }
@@ -237,7 +237,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
             this._videoRec.onstop = async (e: any) => {
                 console.log('screenshotbox: upload');
                 const file = new File(vid_chunks, `${this.rootDoc[Id]}.mkv`, { type: vid_chunks[0].type, lastModified: Date.now() });
-                const [{ result }] = await Networking.UploadFilesToServer(file);
+                const [{ result }] = await Networking.UploadFilesToServer({file});
                 this.dataDoc[this.fieldKey + '_duration'] = (new Date().getTime() - this.recordingStart!) / 1000;
                 if (!(result instanceof Error)) {
                     // convert this screenshotBox into normal videoBox
diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx
index f910d765e..da38fcaee 100644
--- a/src/mobile/ImageUpload.tsx
+++ b/src/mobile/ImageUpload.tsx
@@ -42,7 +42,7 @@ export class Uploader extends React.Component<ImageUploadProps> {
                     this.process = "Uploading Files";
                     for (let index = 0; index < files.length; ++index) {
                         const file = files[index];
-                        const res = await Networking.UploadFilesToServer(file);
+                        const res = await Networking.UploadFilesToServer({file});
                         this.setOpacity(3, "1"); // Slab 3
                         // For each item that the user has selected
                         res.map(async ({ result }) => {
diff --git a/src/server/ApiManagers/UploadManager.ts b/src/server/ApiManagers/UploadManager.ts
index 74c06b4a6..94f744848 100644
--- a/src/server/ApiManagers/UploadManager.ts
+++ b/src/server/ApiManagers/UploadManager.ts
@@ -75,7 +75,7 @@ export default class UploadManager extends ApiManager {
                         for (const key in files) {
                             const f = files[key];
                             if (!Array.isArray(f)) {
-                                const result = await DashUploadUtils.upload(f);
+                                const result = await DashUploadUtils.upload(f, key);
                                 result && !(result.result instanceof Error) && results.push(result);
                             }
                         }
-- 
cgit v1.2.3-70-g09d2

