From a14e2da6130ac3c0c55b03cbc8a5fa3723be45bc Mon Sep 17 00:00:00 2001 From: Geireann <60007097+geireann@users.noreply.github.com> Date: Tue, 6 Apr 2021 20:31:25 -0400 Subject: updates --- src/client/views/collections/CollectionMenu.scss | 126 ++++++++++++++++------- src/client/views/collections/CollectionMenu.tsx | 78 ++++++++++---- 2 files changed, 148 insertions(+), 56 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss index 2c81d727e..9eac75f4b 100644 --- a/src/client/views/collections/CollectionMenu.scss +++ b/src/client/views/collections/CollectionMenu.scss @@ -14,35 +14,53 @@ top: 0; width: 100%; - .antimodeMenu-button { - padding: 0; - width: 30px; + .recordButtonOutline { + border-radius: 100%; + width: 18px; + height: 18px; + border: solid 1px #f5f5f5; display: flex; + align-items: center; + justify-content: center; + } - svg { - margin: auto; - } + .recordButtonInner { + border-radius: 100%; + width: 70%; + height: 70%; + background: white; } .collectionMenu { display: flex; - padding-bottom: 1px; - height: 32px; - border-bottom: .5px solid rgb(180, 180, 180); + height: 100%; overflow: visible; z-index: 901; border: unset; + .collectionMenu-divider { + height: 85%; + margin-left: 3px; + margin-right: 3px; + width: 1.5px; + background-color: #656060; + } + .collectionViewBaseChrome { display: flex; + align-items: center; .collectionViewBaseChrome-viewPicker { font-size: 75%; - background: #323232; outline-color: black; color: white; border: none; - border-right: solid gray 1px; + background: #323232; + } + + .collectionViewBaseChrome-viewPicker:focus { + outline: none; + border: none; } .collectionViewBaseChrome-viewPicker:active { @@ -65,18 +83,26 @@ margin-left: 3px; margin-right: 0px; font-size: 75%; - background: #323232; + text-transform: capitalize; color: white; border: none; - border-right: solid gray 1px; + background: #323232; + } + + .collectionViewBaseChrome-cmdPicker:focus { + border: none; + outline: none; } .commandEntry-outerDiv { pointer-events: all; - background-color: #323232; + background-color: transparent; display: flex; flex-direction: row; - height: 30px; + align-items: center; + justify-content: center; + height: 100%; + overflow: hidden; .commandEntry-drop { color: white; @@ -86,6 +112,15 @@ } } + .commandEntry-outerDiv:hover{ + background-color: rgba(0,0,0,0.2); + + .collectionViewBaseChrome-viewPicker, + .collectionViewBaseChrome-cmdPicker{ + background: rgb(41,41,41); + } + } + .collectionViewBaseChrome-collapse { transition: all .5s, opacity 0.3s; position: absolute; @@ -103,11 +138,12 @@ .collectionViewBaseChrome-template, .collectionViewBaseChrome-viewModes { - display: grid; - background: rgb(238, 238, 238); + align-items: center; + height: 100%; + display: flex; + background: transparent; color: grey; - margin-top: auto; - margin-bottom: auto; + justify-content: center; } .collectionViewBaseChrome-viewSpecs { @@ -263,27 +299,52 @@ .collectionTreeViewChrome-pivotField-cont, .collection3DCarouselViewChrome-scrollSpeed-cont { justify-self: right; - display: flex; + align-items: center; + display: grid; + grid-auto-columns: auto; font-size: 75%; letter-spacing: 2px; .collectionStackingViewChrome-pivotField-label, .collectionTreeViewChrome-pivotField-label, .collection3DCarouselViewChrome-scrollSpeed-label { - vertical-align: center; - padding-left: 10px; - margin: auto; + grid-column: 1; + margin-right: 7px; + user-select: none; + font-family: 'Roboto'; + letter-spacing: normal; + } + + .collectionStackingViewChrome-sortIcon { + transition: transform .5s; + grid-column: 3; + text-align: center; + display: flex; + justify-content: center; + align-items: center; + cursor: pointer; + width: 25px; + height: 25px; + border-radius: 100%; + } + + .collectionStackingViewChrome-sortIcon:hover { + background-color: rgba(0,0,0,0.2); } .collectionStackingViewChrome-pivotField, .collectionTreeViewChrome-pivotField, .collection3DCarouselViewChrome-scrollSpeed { color: white; - width: 100%; + grid-column: 2; + grid-row: 1; + width: 90%; min-width: 100px; display: flex; + height: 80%; + border-radius: 7px; align-items: center; - background: rgb(238, 238, 238); + background: #eeeeee; .editable-view-input, input, @@ -378,20 +439,13 @@ display: inline-flex; position: relative; align-items: center; - margin-left: 10px; - - .antimodeMenu-button { - text-align: center; - display: block; - position: relative; - } + height: 100%; .color-previewI { - width: 80%; - height: 20%; - bottom: 0; + width: 60%; + top: 80%; position: absolute; - margin-left: 2px; + height: 4px; } .color-previewII { diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 623e05b33..3321a8d8f 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -15,7 +15,7 @@ import { RichTextField } from "../../../fields/RichTextField"; import { listSpec } from "../../../fields/Schema"; import { ScriptField } from "../../../fields/ScriptField"; import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types"; -import { emptyFunction, setupMoveUpEvents, Utils } from "../../../Utils"; +import { DeepCopy, emptyFunction, setupMoveUpEvents, Utils } from "../../../Utils"; import { DocumentType } from "../../documents/DocumentTypes"; import { CurrentUserUtils } from "../../util/CurrentUserUtils"; import { DragManager } from "../../util/DragManager"; @@ -34,6 +34,9 @@ import "./CollectionMenu.scss"; import { CollectionViewType, COLLECTION_BORDER_WIDTH } from "./CollectionView"; import { TabDocView } from "./TabDocView"; import { LightboxView } from "../LightboxView"; +import { Docs } from "../../documents/Documents"; +import { DocumentManager } from "../../util/DocumentManager"; +import { CollectionDockingView } from "./CollectionDockingView"; @observer export class CollectionMenu extends AntimodeMenu { @@ -388,7 +391,32 @@ export class CollectionViewBaseChrome extends React.Component{Doc.isDocPinned(targetDoc) ? "Unpin from presentation" : "Pin to presentation"}} placement="top"> + ; + } + + @undoBatch + @action + startRecording = () => { + const doc = Docs.Create.ScreenshotDocument("", { _fitWidth: true, _width: 400, _height: 200, title: "screen snapshot", system: true, cloneFieldFilter: new List(["system"]) }); + doc.x = 0; + doc.y = 0; + Doc.AddDocToList((Doc.UserDoc().myOverlayDocs as Doc), undefined, doc); + CollectionDockingView.AddSplit(doc, "right"); + // doc.startRec = true; + } + + @computed + get recordButton() { + const targetDoc = this.selectedDoc; + return {"Capture screen"}} placement="top"> + ; } @@ -478,7 +506,7 @@ export class CollectionViewBaseChrome extends React.Component{"Tap or Drag to create an alias"}} placement="top"> ; } @@ -486,38 +514,48 @@ export class CollectionViewBaseChrome extends React.Component{"View in Lightbox"}} placement="top"> - ; } + @computed get toggleOverlayButton() { + return <> + Toggle Overlay Layer} placement="bottom"> + + + + } + render() { return (
+ {this.notACollection || this.props.type === CollectionViewType.Invalid ? (null) : this.viewModes} +
{this.aliasButton} {/* {this.pinButton} */} - {this.pinWithViewButton} - {this.lightboxButton} - Toggle Overlay Layer
} placement="bottom"> - - + {/* {this.pinWithViewButton} */} + {this.toggleOverlayButton} +
{this.subChrome} - {this.notACollection || this.props.type === CollectionViewType.Invalid ? (null) : this.viewModes} - {!this._buttonizableCommands ? (null) : this.templateChrome} +
+ {this.lightboxButton} + {this.recordButton} + {/* {!this._buttonizableCommands ? (null) : this.templateChrome} */}
-- cgit v1.2.3-70-g09d2 From 6a73699a10edb842b2b5eba4ef05731772859f13 Mon Sep 17 00:00:00 2001 From: Geireann <60007097+geireann@users.noreply.github.com> Date: Wed, 7 Apr 2021 14:45:14 -0400 Subject: bug fixes --- src/client/util/CaptureManager.scss | 450 ++------------------- src/client/util/CaptureManager.tsx | 47 ++- src/client/views/LightboxView.tsx | 7 +- src/client/views/MainViewModal.tsx | 2 +- src/client/views/collections/CollectionMenu.tsx | 2 +- src/client/views/nodes/ScreenshotBox.tsx | 150 +++---- .../views/presentationview/PresElementBox.tsx | 2 + 7 files changed, 160 insertions(+), 500 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/util/CaptureManager.scss b/src/client/util/CaptureManager.scss index 5ca54517c..8447bd2d5 100644 --- a/src/client/util/CaptureManager.scss +++ b/src/client/util/CaptureManager.scss @@ -1,8 +1,7 @@ @import "../views/globalCssVariables"; -.settings-interface { +.capture-interface { //background-color: whitesmoke !important; - color: grey; width: 450px; button { @@ -21,14 +20,35 @@ } } -.settings-title { - font-size: 25px; - font-weight: bold; - padding-right: 10px; +.capture-t1 { + display: flex; + justify-content: left; + align-items: center; + font-size: 20px; + font-family: 'Roboto'; + font-weight: 600; color: black; + + .recordButtonOutline { + border-radius: 100%; + width: 25px; + height: 25px; + margin-right: 10px; + border: solid 1px #a94442; + display: flex; + align-items: center; + justify-content: center; + } + + .recordButtonInner { + border-radius: 100%; + width: 70%; + height: 70%; + background: #a94442; + } } -.settings-username { +.capture-t2 { font-size: 12px; padding-right: 15px; color: black; @@ -39,13 +59,13 @@ // left: 243; } -.settings-section { +.capture-block { display: flex; border-bottom: 1px solid grey; padding-bottom: 8px; padding-top: 6px; - .settings-section-title { + .capture-block-title { font-size: 16; font-weight: bold; text-align: left; @@ -59,407 +79,21 @@ } } - -.password-content { - display: flex; - flex-direction: column; - - .password-content-inputs { - width: 100; - // margin-bottom: 10px; - font-size: 10px; - - .password-inputs { - border: 1px solid rgb(160, 160, 160); - margin-bottom: 8px; - width: 130; - color: black; - border-radius: 5px; - padding:7px; - - } - } - - .password-content-buttons { - //margin-left: 84px; - //width: 100; - padding: 7px; - - .password-submit { - //margin-left: 85px; - margin-top: 5px; - } - - .password-forgot { - //margin-left: 65px; - //margin-top: -20px; - font-size: 12px; - white-space: nowrap; - } - } -} - -.accounts-content { +.close-button { + position: absolute; + top: 10; + right: 10; + background:transparent; + border-radius:100%; + width: 25px; + height: 25px; display: flex; + align-items: center; + justify-content: center; + transition: 0.2s; } -.modes-content { - display: flex; - margin-left: 10px; - font-size: 12px; - - .modes-select { - // width: 170px; - width: 80%; - height: 35px; - margin-right: 10px; - color: black; - border-radius: 5px; - - &:hover { - cursor: pointer; - } - } - - .modes-playground, - .default-acl { - display: flex; - margin-left: 10px; - margin-top: 10px; - font-size: 10px; - - .playground-check, - .acl-check { - margin-right: 5px; - - &:hover { - cursor: pointer; - } - } - - .playground-text { - color: black; - margin-right: 10px; - margin-top: 2; - } - - .acl-text { - color: black; - margin-top: 2; - text-align: left; - } - - } -} - -.colorFlyout { - margin-top: 2px; - //margin-right: 18px; - - &:hover { - cursor: pointer; - } - - .colorFlyout-button { - width: 20px; - height: 20px; - border: 0.5px solid black; - border-radius: 5px; - padding-top: 3px; - } -} - -.prefs-content{ - text-align: left; -} - -.appearances-content { - display: flex; - margin-top: 4px; - color: black; - font-size: 10px; - - .preferences-color { - display: flex; - margin-top: 2px; - - .preferences-color-text { - margin-top: 3px; - margin-right: 4; - flex: 1 1 auto; - text-align: left; - } - - .colorFlyout { - align-self: flex-end; - } - } - - .preferences-font { - //height: 23px; - margin-top: 2px; - - .preferences-font-text { - color: black; - margin-top: 4; - margin-right: 4; - margin-bottom: 2px; - text-align: left; - } - - .preferences-font-controls { - display: flex; - justify-content: space-between; - } - - .font-select { - height: 35px; - color: black; - font-size: 9; - margin-right: 6; - border-radius: 5px; - width: 65%; - - &:hover { - cursor: pointer; - } - } - - .size-select { - height: 35px; - color: black; - font-size: 9; - border-radius: 5px; - width: 30%; - - &:hover { - cursor: pointer; - } - } - } - - .preferences-check { - color: black; - margin-right: 4; - margin-bottom: -3; - margin-left: 5; - margin-top: -1px; - display: inline-block; - padding-left: 5px; - text-align: left; - } +.close-button:hover { + background: rgba(0,0,0,0.1); } -.settings-interface { - display: flex; - flex-direction: column; - - button { - width: auto; - align-self: center; - background: #252b33; - margin-right: 15px; - - //margin-top: 4px; - - &:hover { - background: $main-accent; - } - } - - // .delete-button { - // background: rgb(227, 86, 86); - // } - - .close-button { - position: absolute; - right: 1em; - top: 1em; - cursor: pointer; - } - - // .logout-button { - // right: 355; - // position: absolute; - // } - - .settings-content { - background: #e4e4e4; - //border-radius: 6px; - padding: 10px; - //width: 560px; - flex: 1 1 auto; - } - - .settings-top { - display: flex; - margin-bottom: 10px; - } - - - .error-text { - color: #C40233; - width: 300; - margin-left: -20; - font-size: 10; - margin-bottom: 4; - margin-top: -3; - } - - .success-text { - width: 300; - margin-left: -20; - font-size: 10; - margin-bottom: 4; - margin-top: -3; - color: #009F6B; - } - - .focus-span { - text-decoration: underline; - } - - h1 { - color: #121721; - text-transform: uppercase; - letter-spacing: 2px; - font-size: 19; - margin-top: 0; - font-weight: bold; - } - - .container { - display: block; - position: relative; - margin-top: 10px; - margin-bottom: 10px; - font-size: 22px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - width: 700px; - min-width: 700px; - max-width: 700px; - text-align: left; - font-style: normal; - font-size: 15; - font-weight: normal; - padding: 0; - - .padding { - padding: 0 0 0 20px; - color: black; - } - - } -} - -.settings-interface { - flex-direction: row; - position: relative; - min-height: 250px; - width: 100%; - - .settings-content { - background-color: #fdfdfd; - } -} - -.settings-panel { - position: relative; - min-width: 150px; - background-color: #e4e4e4; - - .settings-user { - position: absolute; - bottom: 10px; - text-align: center; - left: 0; - right: 0; - - .settings-username { - padding-right: 0px; - } - - .logout-button { - margin-right: 2px; - } - } -} - -.settings-tabs { - // font-size: 16px; - font-weight: 600; - color: black; - - .tab-control { - padding: 10px; - border-bottom: 1px solid #9f9e9e; - cursor: pointer; - - &.active { - background-color: #fdfdfd; - } - } -} - -.settings-section-context { - width: 100%; -} - -.tab-section { - display: none; - height: 200px; - - &.active { - display: block; - } -} - -.tab-content { - display: flex; - margin: 20px 0; - - .tab-column { - flex: 0 0 50%; - - .tab-column-title { - color: black; - font-size: 16px; - font-weight: bold; - margin-bottom: 16px; - } - - .tab-column-title, .tab-column-content { - padding-left: 16px; - } - - } - -} - -.tab-column button { - font-size: 9px; -} - -@media only screen and (max-device-width: 480px) { - .settings-interface { - width: 80vw; - height: 400px; - } - - .settings-interface .settings-body .settings-content input { - font-size: 30; - } - - .settings-interface button { - width: 100%; - font-size: 30px; - background: #315a96; - } - - .settings-interface .settings-heading { - font-size: 25; - } -} diff --git a/src/client/util/CaptureManager.tsx b/src/client/util/CaptureManager.tsx index f01fcd0d2..cea0c182f 100644 --- a/src/client/util/CaptureManager.tsx +++ b/src/client/util/CaptureManager.tsx @@ -2,16 +2,10 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { action, computed, observable, runInAction } from "mobx"; import { observer } from "mobx-react"; import * as React from "react"; -import { ColorState, SketchPicker } from "react-color"; import { Doc } from "../../fields/Doc"; import { BoolCast, StrCast, Cast } from "../../fields/Types"; import { addStyleSheet, addStyleSheetRule, Utils } from "../../Utils"; -import { GoogleAuthenticationManager } from "../apis/GoogleAuthenticationManager"; -import { DocServer } from "../DocServer"; -import { Networking } from "../Network"; import { MainViewModal } from "../views/MainViewModal"; -import { CurrentUserUtils } from "./CurrentUserUtils"; -import { GroupManager } from "./GroupManager"; import "./CaptureManager.scss"; import { undoBatch } from "./UndoManager"; const higflyout = require("@hig/flyout"); @@ -22,6 +16,7 @@ export const Flyout = higflyout.default; export class CaptureManager extends React.Component<{}> { public static Instance: CaptureManager; static _settingsStyle = addStyleSheet(); + @observable _document: any; @observable isOpen: boolean = false; // whether the CaptureManager is to be displayed or not. @@ -31,18 +26,27 @@ export class CaptureManager extends React.Component<{}> { } public close = action(() => this.isOpen = false); - public open = action(() => this.isOpen = true); + public open = action((doc: Doc) => { + this.isOpen = true; + this._document = doc; + }); - @computed get colorsContent() { - - return
+ @computed get visibilityContent() { + return
+
Visibility +
+ Private + Public +
+
; } - @computed get formatsContent() { - return
+ @computed get linksContent() { + return
+
Links
; } @@ -52,11 +56,19 @@ export class CaptureManager extends React.Component<{}> { private get captureInterface() { - return
-
- + return
+
+
+
+
+
+ Conversation Capture
+
+
+ {this.visibilityContent} + {this.linksContent}
@@ -70,6 +82,9 @@ export class CaptureManager extends React.Component<{}> { isDisplayed={this.isOpen} interactive={true} closeOnExternalClick={this.close} - dialogueBoxStyle={{ width: "500px", height: "300px", background: Cast(Doc.SharingDoc().userColor, "string", null) }} />; + dialogueBoxStyle={{ width: "500px", height: "300px", border: "none", background: Cast(Doc.SharingDoc().userColor, "string", null) }} + overlayStyle={{ background: "black" }} + overlayDisplayedOpacity={0.6} + /> } } \ No newline at end of file diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index 2fd9cb854..efd3d733f 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -188,10 +188,13 @@ export class LightboxView extends React.Component { LightboxView._future?.push(...DocListCast(tours[0][fieldKey]).reverse()); } else { const coll = LightboxView._docTarget; - if (coll) { + const doc = LightboxView.LightboxDoc; + if (coll && doc) { console.log('test'); + console.log('target: ' + coll.title); + console.log('doc: ' + doc.title); const fieldKey = Doc.LayoutFieldKey(coll); - LightboxView.SetLightboxDoc(coll, undefined); + LightboxView.SetLightboxDoc(doc); // LightboxView.SetLightboxDoc(coll, undefined, [...DocListCast(coll[fieldKey]), ...DocListCast(coll[fieldKey + "-annotations"])]); TabDocView.PinDoc(coll, { hidePresBox: true }); } diff --git a/src/client/views/MainViewModal.tsx b/src/client/views/MainViewModal.tsx index 7f91c0079..55dee005d 100644 --- a/src/client/views/MainViewModal.tsx +++ b/src/client/views/MainViewModal.tsx @@ -34,7 +34,7 @@ export class MainViewModal extends React.Component {
(["system"]) }); doc.x = 0; doc.y = 0; + doc.startRec = true; Doc.AddDocToList((Doc.UserDoc().myOverlayDocs as Doc), undefined, doc); CollectionDockingView.AddSplit(doc, "right"); - // doc.startRec = true; } @computed diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx index 4c24dc5e1..cecc593f0 100644 --- a/src/client/views/nodes/ScreenshotBox.tsx +++ b/src/client/views/nodes/ScreenshotBox.tsx @@ -1,6 +1,6 @@ import React = require("react"); import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from "mobx"; +import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction, trace } from "mobx"; import { observer } from "mobx-react"; import { DateField } from "../../../fields/DateField"; import { Doc, WidthSym } from "../../../fields/Doc"; @@ -36,7 +36,7 @@ const ScreenshotDocument = makeInterface(documentSchema); @observer export class ScreenshotBox extends ViewBoxAnnotatableComponent(ScreenshotDocument) { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(ScreenshotBox, fieldKey); } - private _videoRef = React.createRef(); + private _videoRef: HTMLVideoElement | undefined | null; private _audioRec: any; private _videoRec: any; @observable _screenCapture = false; @@ -56,7 +56,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent { - const aspect = this._videoRef.current!.videoWidth / this._videoRef.current!.videoHeight; + const aspect = this._videoRef!.videoWidth / this._videoRef!.videoHeight; const nativeWidth = Doc.NativeWidth(this.layoutDoc); const nativeHeight = Doc.NativeHeight(this.layoutDoc); if (!nativeWidth || !nativeHeight) { @@ -69,9 +69,6 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent this.rootDoc.startRec == true, - this.toggleRecording - ); } componentWillUnmount() { const ind = DocUtils.ActiveRecordings.indexOf(this); @@ -85,10 +82,22 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent { + console.log('ref: ', r); + this._videoRef = r; + setTimeout(() => { + if (this.rootDoc.startRec && this._videoRef) { // TODO glr: use mediaState + this.toggleRecording(); + this.rootDoc.startRec = undefined; + } + }, 1000); + }} + autoPlay={true} + style={{ width: "100%", height: "100%" }} onCanPlay={this.videoLoad} controls={true} onClick={e => e.preventDefault()}> @@ -99,14 +108,11 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent { console.log("toggleRecording"); - console.log("2:" + this._videoRef.current!.srcObject); - if (this._screenCapture) { - CaptureManager.Instance.open(this.rootDoc); - } else { - console.log("opening"); - } + console.log("2:" + this._videoRef!.srcObject); + this._screenCapture = !this._screenCapture; if (this._screenCapture) { + console.log("opening"); this._audioRec = new MediaRecorder(await navigator.mediaDevices.getUserMedia({ audio: true })); const aud_chunks: any = []; this._audioRec.ondataavailable = (e: any) => aud_chunks.push(e.data); @@ -116,12 +122,13 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent 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) => { + console.log("onStop: video end"); const file = new File(vid_chunks, `${this.rootDoc[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; @@ -143,6 +150,9 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent Math.max(0, this.props.PanelHeight() - this.videoPanelHeight()); render() { TraceMobx(); - return this.rootDoc.startRec ? -
- + console.log('rendering'); + return
+
+
+ + {this.contentFunc} +
+
+ +
- : -
-
-
- - {this.contentFunc} -
-
- -
+ {!this.props.isSelected() ? (null) :
+
+
- {!this.props.isSelected() ? (null) :
-
- -
-
} -
; +
} +
; } } \ No newline at end of file diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index a1fc77a92..f15d51764 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -57,6 +57,7 @@ export class PresElementBox extends ViewBoxBaseComponent [this.rootDoc.presExpandInlineButton, this.collapsedHeight], params => this.layoutDoc._height = NumCast(params[1]) + (Number(params[0]) ? 100 : 0), { fireImmediately: true }); } @@ -114,6 +115,7 @@ export class PresElementBox extends ViewBoxBaseComponent
; -- cgit v1.2.3-70-g09d2 From 821f1395198e4fe4cb06192ce1ba1a2864914159 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 7 Apr 2021 15:44:17 -0400 Subject: can't make two different views of a recording. --- src/client/views/collections/CollectionMenu.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/collections') diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 3299ea3a9..e0c68e51c 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -403,7 +403,7 @@ export class CollectionViewBaseChrome extends React.Component Date: Thu, 8 Apr 2021 04:07:42 -0400 Subject: changes --- src/client/util/CaptureManager.scss | 84 ++++++++++++++++++++-- src/client/util/CaptureManager.tsx | 66 ++++++++++++++--- src/client/views/collections/CollectionMenu.tsx | 3 +- .../collections/CollectionStackedTimeline.tsx | 8 +-- src/client/views/nodes/DocumentView.tsx | 2 +- src/client/views/nodes/VideoBox.tsx | 3 +- 6 files changed, 146 insertions(+), 20 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/util/CaptureManager.scss b/src/client/util/CaptureManager.scss index 8447bd2d5..71539ee1e 100644 --- a/src/client/util/CaptureManager.scss +++ b/src/client/util/CaptureManager.scss @@ -60,8 +60,7 @@ } .capture-block { - display: flex; - border-bottom: 1px solid grey; + display: block; padding-bottom: 8px; padding-top: 6px; @@ -72,10 +71,87 @@ color: black; width: 80; margin-right: 50px; + margin-bottom: 5px; + } + + .capture-block-list { + height: 135px; + width: calc(100% + 15px); + overflow: scroll; + } + + .capture-block-radio { + font-size: 12; + display: block; + font-weight: normal; + + .radio-container { + display: flex; + justify-content: left; + align-items: center; + font-size: 13px; + font-family: 'Roboto'; + } } - &:last-child { - border-bottom: none; + .list-item { + display: flex; + height: 25px; + font-family: 'Roboto'; + font-size: 13px; + + .number { + width: 20px; + height: 20px; + display: flex; + justify-content: center; + align-items: center; + background-color: #BDDBE8; + border-radius: 100%; + font-weight: 800; + margin-right: 5px; + } + } + + .buttons { + display: flex; + position: absolute; + bottom: 0; + right: 15; + justify-content: flex-end; + align-items: center; + height: 60px; + + .save { + cursor: pointer; + width: 80px; + height: 40px; + font-size: 14px; + display: flex; + font-weight: bold; + justify-content: center; + align-items: center; + background: #337ab7; + color: whitesmoke; + border-radius: 5px; + text-transform: uppercase; + } + + .cancel { + cursor: pointer; + width: 80px; + height: 40px; + font-size: 14px; + display: flex; + font-weight: 100; + justify-content: center; + align-items: center; + background: #ccc; + color: black; + border-radius: 5px; + text-transform: uppercase; + margin-left: 10px; + } } } diff --git a/src/client/util/CaptureManager.tsx b/src/client/util/CaptureManager.tsx index cea0c182f..c38337c91 100644 --- a/src/client/util/CaptureManager.tsx +++ b/src/client/util/CaptureManager.tsx @@ -2,11 +2,14 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { action, computed, observable, runInAction } from "mobx"; import { observer } from "mobx-react"; import * as React from "react"; -import { Doc } from "../../fields/Doc"; +import { convertToObject } from "typescript"; +import { Doc, DocListCast } from "../../fields/Doc"; import { BoolCast, StrCast, Cast } from "../../fields/Types"; import { addStyleSheet, addStyleSheetRule, Utils } from "../../Utils"; +import { LightboxView } from "../views/LightboxView"; import { MainViewModal } from "../views/MainViewModal"; import "./CaptureManager.scss"; +import { SelectionManager } from "./SelectionManager"; import { undoBatch } from "./UndoManager"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; @@ -35,23 +38,69 @@ export class CaptureManager extends React.Component<{}> { @computed get visibilityContent() { return
-
Visibility -
- Private - Public +
Visibility
+
+
+ Private +
+
+ Public
; } @computed get linksContent() { + const doc = this._document; + const order: JSX.Element[] = []; + if (doc) { + console.log('title', doc.title); + console.log('links', doc.links); + const linkDocs = DocListCast(doc.links); + const firstDocs = linkDocs.filter(linkDoc => Doc.AreProtosEqual(linkDoc.anchor1 as Doc, doc) || Doc.AreProtosEqual((linkDoc.anchor1 as Doc).annotationOn as Doc, doc)); // link docs where 'doc' is anchor1 + const secondDocs = linkDocs.filter(linkDoc => Doc.AreProtosEqual(linkDoc.anchor2 as Doc, doc) || Doc.AreProtosEqual((linkDoc.anchor2 as Doc).annotationOn as Doc, doc)); // link docs where 'doc' is anchor2 + linkDocs.forEach((l, i) => { + if (l) { + console.log(i, (l.anchor1 as Doc).title); + console.log(i, (l.anchor2 as Doc).title); + order.push( +
+
{i}
+ {(l.anchor1 as Doc).title} +
+ ); + } + }); + } + return
Links
- +
+ {order} +
; } - + @computed get closeButtons() { + return
+
+
{ + LightboxView.SetLightboxDoc(this._document); + this.close(); + }}> + Save +
+
{ + const selected = SelectionManager.Views().slice(); + SelectionManager.DeselectAll(); + selected.map(dv => dv.props.removeDocument?.(dv.props.Document)); + this.close(); + }}> + Cancel +
+
+
+ } @@ -72,6 +121,7 @@ export class CaptureManager extends React.Component<{}> {
+ {this.closeButtons}
; } @@ -82,7 +132,7 @@ export class CaptureManager extends React.Component<{}> { isDisplayed={this.isOpen} interactive={true} closeOnExternalClick={this.close} - dialogueBoxStyle={{ width: "500px", height: "300px", border: "none", background: Cast(Doc.SharingDoc().userColor, "string", null) }} + dialogueBoxStyle={{ width: "500px", height: "350px", border: "none", background: "whitesmoke" }} overlayStyle={{ background: "black" }} overlayDisplayedOpacity={0.6} /> diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 3299ea3a9..6816b4739 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -403,7 +403,6 @@ export class CollectionViewBaseChrome extends React.Component
{this.aliasButton} {/* {this.pinButton} */} - {/* {this.pinWithViewButton} */} {this.toggleOverlayButton} + {this.pinWithViewButton}
{this.subChrome}
diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx index 6a1242f20..4f9f297a2 100644 --- a/src/client/views/collections/CollectionStackedTimeline.tsx +++ b/src/client/views/collections/CollectionStackedTimeline.tsx @@ -234,15 +234,15 @@ export class CollectionStackedTimeline extends CollectionSubView this.props.PanelHeight() / 3; - timelineContentHeight = () => this.props.PanelHeight() * 2 / 3; + dictationHeight = () => "50%"; + timelineContentHeight = () => this.props.PanelHeight() / 2; dictationScreenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(0, -this.timelineContentHeight()); @computed get renderDictation() { const dictation = Cast(this.dataDoc[this.props.dictationKey], Doc, null); - return !dictation ? (null) :
+ return !dictation ? (null) :
"100%"} isAnnotationOverlay={true} isDocumentActive={returnFalse} select={emptyFunction} diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 26cf52f17..153603c3c 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -1105,7 +1105,7 @@ export class DocumentView extends React.Component { position: this.props.Document.isInkMask ? "absolute" : undefined, transform: `translate(${this.centeringX}px, ${this.centeringY}px)`, width: xshift() ?? `${100 * (this.props.PanelWidth() - this.Xshift * 2) / this.props.PanelWidth()}%`, - height: yshift() ?? (this.fitWidth ? `${this.panelHeight}px` : + height: this.props.Document.type === DocumentType.VID ? "100%" : yshift() ?? (this.fitWidth ? `${this.panelHeight}px` : `${100 * this.effectiveNativeHeight / this.effectiveNativeWidth * this.props.PanelWidth() / this.props.PanelHeight()}%`), }}> { this._clicking = true; + console.log('timeline click'); setupMoveUpEvents(this, e, action((e: PointerEvent) => { this._clicking = false; if (this.isContentActive()) { const local = this.props.ScreenToLocalTransform().scale(this.props.scaling?.() || 1).transformPoint(e.clientX, e.clientY); - this.layoutDoc._timelineHeightPercent = Math.max(0, Math.min(100, local[1] / this.props.PanelHeight() * 100)); + this.layoutDoc._timelineHeightPercent = 50; } return false; }), emptyFunction, -- cgit v1.2.3-70-g09d2 From 742cd3d9e76f188e0a78b2c4288e0d7e6af14fe8 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 8 Apr 2021 15:42:09 -0400 Subject: fixed pushpins to be created only when removed from a collection. fixed webbox links which weren't showing up in link menu. --- src/client/documents/Documents.ts | 4 ++-- src/client/views/DocComponent.tsx | 4 ++-- src/client/views/collections/CollectionSubView.tsx | 2 +- src/client/views/nodes/WebBox.tsx | 9 +++++++-- 4 files changed, 12 insertions(+), 7 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 90db8644d..38a9bd0e1 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -1317,7 +1317,7 @@ export namespace DocUtils { } } - export function LeavePushpin(doc: Doc) { + export function LeavePushpin(doc: Doc, annotationField: string) { if (doc.isPushpin) return undefined; const context = Cast(doc.context, Doc, null) ?? Cast(doc.annotationOn, Doc, null); const hasContextAnchor = DocListCast(doc.links). @@ -1330,7 +1330,7 @@ export namespace DocUtils { icon: "map-pin", x: Cast(doc.x, "number", null), y: Cast(doc.y, "number", null), backgroundColor: "#ACCEF7", _width: 15, _height: 15, _xPadding: 0, _isLinkButton: true, _timecodeToShow: Cast(doc._timecodeToShow, "number", null) }); - Doc.AddDocToList(context, Doc.LayoutFieldKey(context) + "-annotations", pushpin); + Doc.AddDocToList(context, annotationField, pushpin); const pushpinLink = DocUtils.MakeLink({ doc: pushpin }, { doc: doc }, "pushpin", ""); doc._timecodeToShow = undefined; return pushpin; diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index 5ff96ac8d..c017b7015 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -151,7 +151,7 @@ export function ViewBoxAnnotatableComponent

{ - leavePushpin && DocUtils.LeavePushpin(doc); + leavePushpin && DocUtils.LeavePushpin(doc, annotationKey ?? this.annotationKey); Doc.RemoveDocFromList(targetDataDoc, annotationKey ?? this.annotationKey, doc); doc.context = undefined; recent && Doc.AddDocToList(recent, "data", doc, undefined, true, true); @@ -216,7 +216,7 @@ export function ViewBoxAnnotatableComponent

[AclAdmin, AclEdit].includes(GetEffectiveAcl(doc))).map(doc => { // only make a pushpin if we have acl's to edit the document this.props.layerProvider?.(doc, true); - DocUtils.LeavePushpin(doc); + //DocUtils.LeavePushpin(doc); doc._stayInCollection = undefined; doc.context = this.props.Document; if (annotationKey ?? this._annotationKey) Doc.GetProto(doc).annotationOn = this.props.Document; diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index a5d679df0..071422131 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -74,7 +74,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: const { Document, DataDoc } = this.props; const validPairs = this.childDocs.map(doc => Doc.GetLayoutDataDocPair(Document, !this.props.isAnnotationOverlay ? DataDoc : undefined, doc)). filter(pair => { // filter out any documents that have a proto that we don't have permissions to (which we determine by not having any keys - return pair.layout && !pair.layout.hidden && (!pair.layout.proto || (pair.layout.proto instanceof Doc && GetEffectiveAcl(pair.layout.proto) !== AclPrivate));// Object.keys(pair.layout.proto).length)); + return pair.layout && /*!pair.layout.hidden &&*/ (!pair.layout.proto || (pair.layout.proto instanceof Doc && GetEffectiveAcl(pair.layout.proto) !== AclPrivate));// Object.keys(pair.layout.proto).length)); }); return validPairs.map(({ data, layout }) => ({ data: data as Doc, layout: layout! })); // this mapping is a bit of a hack to coerce types } diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index ab178c60b..cea3833bb 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -12,7 +12,7 @@ import { makeInterface, listSpec } from "../../../fields/Schema"; import { Cast, NumCast, StrCast } from "../../../fields/Types"; import { WebField } from "../../../fields/URLField"; import { TraceMobx } from "../../../fields/util"; -import { emptyFunction, getWordAtPoint, OmitKeys, returnOne, smoothScroll, Utils, setupMoveUpEvents } from "../../../Utils"; +import { emptyFunction, getWordAtPoint, OmitKeys, returnOne, smoothScroll, Utils, setupMoveUpEvents, returnFalse } from "../../../Utils"; import { Docs } from "../../documents/Documents"; import { DocumentType } from '../../documents/DocumentTypes'; import { CurrentUserUtils } from "../../util/CurrentUserUtils"; @@ -32,6 +32,7 @@ import { FieldView, FieldViewProps } from './FieldView'; import { LinkDocPreview } from "./LinkDocPreview"; import "./WebBox.scss"; import React = require("react"); +import { ComputedField } from "../../../fields/ScriptField"; const _global = (window /* browser */ || global /* node */) as any; const htmlToText = require("html-to-text"); @@ -80,6 +81,7 @@ export class WebBox extends ViewBoxAnnotatableComponent { this._url = this.webField?.toString() || ""; this._annotationKey = "annotations-" + this.urlHash(this._url); + this.dataDoc[this.fieldKey + "-annotations"] = ComputedField.MakeFunction(`copyField(this["${this.annotationKey}"])`); }); this._disposers.selection = reaction(() => this.props.isSelected(), @@ -290,6 +292,7 @@ export class WebBox extends ViewBoxAnnotatableComponent Date: Fri, 9 Apr 2021 11:18:59 -0400 Subject: fix for removing documents from pdfs/web boxes. fixes for making objects draggable again in PDFs. fixes for lightboxview to allow stepping into collecitons. fix for stacking view to skip hidden documents --- src/client/views/LightboxView.tsx | 6 +----- src/client/views/collections/CollectionStackedTimeline.tsx | 3 ++- src/client/views/collections/CollectionStackingView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 2 +- src/client/views/nodes/PDFBox.tsx | 2 ++ src/client/views/nodes/VideoBox.tsx | 2 +- src/client/views/nodes/WebBox.tsx | 5 ----- src/client/views/pdf/PDFViewer.tsx | 3 ++- 8 files changed, 10 insertions(+), 15 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index 098c40df4..9444446b1 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -190,12 +190,8 @@ export class LightboxView extends React.Component { const coll = LightboxView._docTarget; const doc = LightboxView.LightboxDoc; if (coll && doc) { - console.log('test'); - console.log('target: ' + coll.title); - console.log('doc: ' + doc.title); const fieldKey = Doc.LayoutFieldKey(coll); - LightboxView.SetLightboxDoc(doc); - // LightboxView.SetLightboxDoc(coll, undefined, [...DocListCast(coll[fieldKey]), ...DocListCast(coll[fieldKey + "-annotations"])]); + LightboxView.SetLightboxDoc(coll, undefined, [...DocListCast(coll[fieldKey]), ...DocListCast(coll[fieldKey + "-annotations"])]); TabDocView.PinDoc(coll, { hidePresBox: true }); } } diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx index 4f9f297a2..5b5d05681 100644 --- a/src/client/views/collections/CollectionStackedTimeline.tsx +++ b/src/client/views/collections/CollectionStackedTimeline.tsx @@ -235,6 +235,7 @@ export class CollectionStackedTimeline extends CollectionSubView "50%"; + documentHeight = () => "100%"; timelineContentHeight = () => this.props.PanelHeight() / 2; dictationScreenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(0, -this.timelineContentHeight()); @computed get renderDictation() { @@ -242,7 +243,7 @@ export class CollectionStackedTimeline extends CollectionSubView "100%"} + PanelHeight={this.documentHeight} isAnnotationOverlay={true} isDocumentActive={returnFalse} select={emptyFunction} diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 8d8c69fd5..1aed40bc3 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -55,7 +55,7 @@ export class CollectionStackingView extends CollectionSubView pair.layout instanceof Doc).map(pair => pair.layout); } + @computed get filteredChildren() { return this.childLayoutPairs.filter(pair => (pair.layout instanceof Doc) && !pair.layout.hidden).map(pair => pair.layout); } @computed get headerMargin() { return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.HeaderMargin); } @computed get xMargin() { return NumCast(this.layoutDoc._xMargin, 2 * Math.min(this.gridGap, .05 * this.props.PanelWidth())); } @computed get yMargin() { return this.props.yMargin || NumCast(this.layoutDoc._yMargin, 5); } // 2 * this.gridGap)); } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 859aff2e8..22543cc8a 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -1106,7 +1106,7 @@ export class DocumentView extends React.Component { position: this.props.Document.isInkMask ? "absolute" : undefined, transform: `translate(${this.centeringX}px, ${this.centeringY}px)`, width: xshift() ?? `${100 * (this.props.PanelWidth() - this.Xshift * 2) / this.props.PanelWidth()}%`, - height: this.props.Document.type === DocumentType.VID ? "100%" : yshift() ?? (this.fitWidth ? `${this.panelHeight}px` : + height: yshift() ?? (this.fitWidth ? `${this.panelHeight}px` : `${100 * this.effectiveNativeHeight / this.effectiveNativeWidth * this.props.PanelWidth() / this.props.PanelHeight()}%`), }}> { this._url = this.webField?.toString() || ""; this._annotationKey = "annotations-" + this.urlHash(this._url); - this.dataDoc[this.fieldKey + "-annotations"] = ComputedField.MakeFunction(`copyField(this["${this.annotationKey}"])`); }); this._disposers.selection = reaction(() => this.props.isSelected(), @@ -292,7 +290,6 @@ export class WebBox extends ViewBoxAnnotatableComponent { }}> Date: Fri, 9 Apr 2021 12:22:37 -0400 Subject: fixed not following links on video in lightbox --- src/client/views/collections/CollectionStackedTimeline.tsx | 3 ++- .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 2 +- src/client/views/nodes/FieldView.tsx | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx index 5b5d05681..782726456 100644 --- a/src/client/views/collections/CollectionStackedTimeline.tsx +++ b/src/client/views/collections/CollectionStackedTimeline.tsx @@ -349,7 +349,8 @@ class StackedTimelineAnchor extends React.Component (time) => { const dictationDoc = Cast(this.props.layoutDoc["data-dictation"], Doc, null); const isDictation = dictationDoc && DocListCast(this.props.mark.links).some(link => Cast(link.anchor1, Doc, null)?.annotationOn === dictationDoc); - if ((isDictation || !Doc.AreProtosEqual(LightboxView.LightboxDoc, this.props.layoutDoc)) && DocListCast(this.props.mark.links).length && + if ((!LightboxView.LightboxDoc + /*isDictation || !Doc.AreProtosEqual(LightboxView.LightboxDoc, this.props.layoutDoc)*/) && DocListCast(this.props.mark.links).length && time > NumCast(this.props.mark[this.props.startTag]) && time < NumCast(this.props.mark[this.props.endTag]) && this._lastTimecode < NumCast(this.props.mark[this.props.startTag])) { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index c623ce653..004d29127 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1032,7 +1032,7 @@ export class CollectionFreeFormView extends CollectionSubView void; isContentActive: (outsideReaction?: boolean) => boolean; + isDocumentActive?: () => boolean; isSelected: (outsideReaction?: boolean) => boolean; scaling?: () => number; setHeight: (height: number) => void; -- cgit v1.2.3-70-g09d2 From f7879dfb8086fc9819861b69a34127d6237f407b Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 9 Apr 2021 14:28:36 -0400 Subject: fixed : in lightbox view from creating a document --- src/client/views/collections/CollectionStackingViewFieldColumn.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/collections') diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index bee7aeb87..47733994b 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -235,7 +235,7 @@ export class CollectionStackingViewFieldColumn extends React.Component Date: Sun, 11 Apr 2021 12:07:10 -0400 Subject: some cleanup of demo_changes --- src/client/views/collections/CollectionMenu.tsx | 2 +- .../collections/CollectionStackedTimeline.tsx | 17 ++++++++------- src/client/views/nodes/PresBox.tsx | 24 +++++++++------------- src/client/views/nodes/ScreenshotBox.tsx | 12 +---------- src/client/views/nodes/VideoBox.tsx | 1 - src/client/views/nodes/WebBox.tsx | 5 +++++ 6 files changed, 27 insertions(+), 34 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index f56f12c67..337595f1c 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -15,7 +15,7 @@ import { RichTextField } from "../../../fields/RichTextField"; import { listSpec } from "../../../fields/Schema"; import { ScriptField } from "../../../fields/ScriptField"; import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types"; -import { DeepCopy, emptyFunction, setupMoveUpEvents, Utils } from "../../../Utils"; +import { emptyFunction, setupMoveUpEvents, Utils } from "../../../Utils"; import { DocumentType } from "../../documents/DocumentTypes"; import { CurrentUserUtils } from "../../util/CurrentUserUtils"; import { DragManager } from "../../util/DragManager"; diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx index 782726456..ab9c4aa2c 100644 --- a/src/client/views/collections/CollectionStackedTimeline.tsx +++ b/src/client/views/collections/CollectionStackedTimeline.tsx @@ -234,16 +234,16 @@ export class CollectionStackedTimeline extends CollectionSubView "50%"; - documentHeight = () => "100%"; - timelineContentHeight = () => this.props.PanelHeight() / 2; + dictationHeightPercent = 50; + dictationHeight = () => `${this.dictationHeightPercent}%`; + timelineContentHeight = () => this.props.PanelHeight() * this.dictationHeightPercent / 100; dictationScreenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(0, -this.timelineContentHeight()); @computed get renderDictation() { const dictation = Cast(this.dataDoc[this.props.dictationKey], Doc, null); - return !dictation ? (null) :

+ return !dictation ? (null) :
(time) => { const dictationDoc = Cast(this.props.layoutDoc["data-dictation"], Doc, null); const isDictation = dictationDoc && DocListCast(this.props.mark.links).some(link => Cast(link.anchor1, Doc, null)?.annotationOn === dictationDoc); - if ((!LightboxView.LightboxDoc - /*isDictation || !Doc.AreProtosEqual(LightboxView.LightboxDoc, this.props.layoutDoc)*/) && DocListCast(this.props.mark.links).length && + if (!LightboxView.LightboxDoc + // bcz: when should links be followed? we don't want to move away from the video to follow a link but we can open it in a sidebar/etc. But we don't know that upfront. + // for now, we won't follow any links when the lightbox is oepn to avoid "losing" the video. + /*(isDictation || !Doc.AreProtosEqual(LightboxView.LightboxDoc, this.props.layoutDoc))*/ + && DocListCast(this.props.mark.links).length && time > NumCast(this.props.mark[this.props.startTag]) && time < NumCast(this.props.mark[this.props.endTag]) && this._lastTimecode < NumCast(this.props.mark[this.props.startTag])) { diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 446db3549..f3fb6ff17 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -5,7 +5,7 @@ import { action, computed, IReactionDisposer, observable, ObservableMap, reactio import { observer } from "mobx-react"; import { ColorState, SketchPicker } from "react-color"; import { Bounce, Fade, Flip, LightSpeed, Roll, Rotate, Zoom } from 'react-reveal'; -import { Doc, DocListCast, DocListCastAsync } from "../../../fields/Doc"; +import { Doc, DocListCast, DocListCastAsync, FieldResult } from "../../../fields/Doc"; import { documentSchema } from "../../../fields/documentSchemas"; import { InkTool } from "../../../fields/InkField"; import { List } from "../../../fields/List"; @@ -247,11 +247,12 @@ export class PresBox extends ViewBoxBaseComponent // } } - stopTempMedia = (targetDoc: Doc) => { - if (targetDoc.type === DocumentType.AUDIO) { + stopTempMedia = (targetDocField: FieldResult) => { + const targetDoc = Cast(targetDocField, Doc, null); + 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) { + } else if (targetDoc?.type === DocumentType.VID) { if (this._mediaTimer && this._mediaTimer[1] === targetDoc) clearTimeout(this._mediaTimer[0]); targetDoc._triggerVideoStop = true; } @@ -331,14 +332,11 @@ 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?.mediaStopTriggerList && this.layoutDoc.presStatus !== PresStatus.Edit) { + DocListCast(from.mediaStopTriggerList).forEach(this.stopTempMedia); } - if (from && from.mediaStop === "auto" && this.layoutDoc.presStatus !== PresStatus.Edit) { - this.stopTempMedia(Cast(from.presentationTargetDoc, Doc, null)); + if (from?.mediaStop === "auto" && this.layoutDoc.presStatus !== PresStatus.Edit) { + this.stopTempMedia(from.presentationTargetDoc); } // 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")) { @@ -577,9 +575,7 @@ export class PresBox extends ViewBoxBaseComponent if (this._presTimer) clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; this.layoutDoc.presLoop = false; - this.childDocs.forEach((doc) => { - this.stopTempMedia(Cast(doc.presentationTargetDoc, Doc, null)); - }); + this.childDocs.forEach(this.stopTempMedia); } } diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx index cecc593f0..6449c99a1 100644 --- a/src/client/views/nodes/ScreenshotBox.tsx +++ b/src/client/views/nodes/ScreenshotBox.tsx @@ -36,7 +36,7 @@ const ScreenshotDocument = makeInterface(documentSchema); @observer export class ScreenshotBox extends ViewBoxAnnotatableComponent(ScreenshotDocument) { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(ScreenshotBox, fieldKey); } - private _videoRef: HTMLVideoElement | undefined | null; + private _videoRef: HTMLVideoElement | null = null; private _audioRec: any; private _videoRec: any; @observable _screenCapture = false; @@ -82,12 +82,9 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent { - console.log('ref: ', r); this._videoRef = r; setTimeout(() => { if (this.rootDoc.startRec && this._videoRef) { // TODO glr: use mediaState @@ -107,12 +104,8 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent { - console.log("toggleRecording"); - console.log("2:" + this._videoRef!.srcObject); - this._screenCapture = !this._screenCapture; if (this._screenCapture) { - console.log("opening"); this._audioRec = new MediaRecorder(await navigator.mediaDevices.getUserMedia({ audio: true })); const aud_chunks: any = []; this._audioRec.ondataavailable = (e: any) => aud_chunks.push(e.data); @@ -128,7 +121,6 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent 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) => { - console.log("onStop: video end"); const file = new File(vid_chunks, `${this.rootDoc[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; @@ -152,7 +144,6 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent Math.max(0, this.props.PanelHeight() - this.videoPanelHeight()); render() { TraceMobx(); - console.log('rendering'); return
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 3b0fb4091..fb58ddefc 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -417,7 +417,6 @@ export class VideoBox extends ViewBoxAnnotatableComponent { this._clicking = true; - console.log('timeline click'); setupMoveUpEvents(this, e, action((e: PointerEvent) => { this._clicking = false; diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 2f2b242f5..a632d1fcc 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -81,7 +81,12 @@ export class WebBox extends ViewBoxAnnotatableComponent { this._url = this.webField?.toString() || ""; this._annotationKey = "annotations-" + this.urlHash(this._url); + // bcz: this is messy. logically, setting the url alone should direct where annotations should go. But + // right now we need to set doc.annotation-active to be the field suffix for the annotations + // and we need to set a computed field to copy the annotations to where everyone else expects them in doc.field-annotations + // TODO: always write annotations to doc.field-anotations and then copy them to doc.field-annotaitons-hash only when the page is changed. this.dataDoc["annotation-active"] = this._annotationKey; + // bcz: need to make sure that doc.data-annotations points to the currently active web page's annotations (this could/should be in the constructor) this.dataDoc[this.fieldKey + "-annotations"] = ComputedField.MakeFunction(`copyField(this["${this.fieldKey}-"+this["annotation-active"]])`); }); -- cgit v1.2.3-70-g09d2 From 6accc320ae70c6607e67a1befe37f5712b092c02 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 11 Apr 2021 12:18:18 -0400 Subject: added childDocumentsActive prop to avoid hardwiring reference to "starburst" in freeformview. --- src/client/views/collections/CollectionPileView.tsx | 13 ++++++++++--- src/client/views/collections/CollectionView.tsx | 1 + .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/views/collections/CollectionPileView.tsx b/src/client/views/collections/CollectionPileView.tsx index 6f6cdd5d2..6baf633dd 100644 --- a/src/client/views/collections/CollectionPileView.tsx +++ b/src/client/views/collections/CollectionPileView.tsx @@ -2,7 +2,7 @@ import { action, computed } from "mobx"; import { observer } from "mobx-react"; import { Doc, HeightSym, WidthSym } from "../../../fields/Doc"; import { NumCast, StrCast } from "../../../fields/Types"; -import { emptyFunction, setupMoveUpEvents } from "../../../Utils"; +import { emptyFunction, setupMoveUpEvents, returnTrue } from "../../../Utils"; import { DocUtils } from "../../documents/Documents"; import { SelectionManager } from "../../util/SelectionManager"; import { SnappingManager } from "../../util/SnappingManager"; @@ -31,9 +31,16 @@ export class CollectionPileView extends CollectionSubView(doc => doc) { // returns the contents of the pileup in a CollectionFreeFormView @computed get contents() { + const isStarburst = this.layoutEngine() === "starburst"; const draggingSelf = this.props.isSelected(); - return
- + { (doc instanceof Doc ? [doc] : doc).map((d) => DocUtils.iconify(d)); return this.props.addDocument?.(doc) || false; diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 4dc0ee3e6..85ae66fdc 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -66,6 +66,7 @@ export interface CollectionViewProps extends FieldViewProps { // property overrides for child documents children?: never | (() => JSX.Element[]) | React.ReactNode; childDocuments?: Doc[]; // used to override the documents shown by the sub collection to an explicit list (see LinkBox) + childDocumentsActive?: () => boolean;// whether child documents can be dragged if collection can be dragged (eg., in a when a Pile document is in startburst mode) childFitWidth?: () => boolean; childOpacity?: () => number; childHideTitle?: () => boolean; // whether to hide the documentdecorations title for children diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 004d29127..7a879ecde 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1032,7 +1032,7 @@ export class CollectionFreeFormView extends CollectionSubView Date: Sun, 11 Apr 2021 12:34:51 -0400 Subject: updated startRect to use mediaState and added pendingRecording as an option. --- src/client/documents/Documents.ts | 5 +++-- src/client/util/CurrentUserUtils.ts | 2 +- src/client/views/collections/CollectionMenu.tsx | 5 +---- src/client/views/nodes/AudioBox.tsx | 2 +- src/client/views/nodes/ScreenshotBox.tsx | 3 +-- 5 files changed, 7 insertions(+), 10 deletions(-) (limited to 'src/client/views/collections') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 96aa43c79..219890945 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -164,6 +164,7 @@ export class DocumentOptions { version?: string; // version identifier for a document label?: string; hidden?: boolean; + mediaState?: string; // status of media document: "pendingRecording", "recording", "paused", "playing" autoPlayAnchors?: boolean; // whether to play audio/video when an anchor is clicked in a stackedTimeline. dontPlayLinkOnSelect?: boolean; // whether an audio/video should start playing when a link is followed to it. toolTip?: string; // tooltip to display on hover @@ -703,8 +704,8 @@ export namespace Docs { return InstanceFromProto(Prototypes.get(DocumentType.WEBCAM), "", options); } - export function ScreenshotDocument(url: string, options: DocumentOptions = {}) { - return InstanceFromProto(Prototypes.get(DocumentType.SCREENSHOT), "", options); + export function ScreenshotDocument(title: string, options: DocumentOptions = {}) { + return InstanceFromProto(Prototypes.get(DocumentType.SCREENSHOT), "", { ...options, title }); } export function ComparisonDocument(options: DocumentOptions = { title: "Comparison Box" }) { diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 0875d9be7..cb8bf5a7f 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -423,7 +423,7 @@ export class CurrentUserUtils { ((doc.emptyScript as Doc).proto as Doc)["dragFactory-count"] = 0; } if (doc.emptyScreenshot === undefined) { - doc.emptyScreenshot = Docs.Create.ScreenshotDocument("", { _fitWidth: true, _width: 400, _height: 200, title: "screen snapshot", system: true, cloneFieldFilter: new List(["system"]) }); + doc.emptyScreenshot = Docs.Create.ScreenshotDocument("empty screenshot", { _fitWidth: true, _width: 400, _height: 200, system: true, cloneFieldFilter: new List(["system"]) }); } if (doc.emptyAudio === undefined) { doc.emptyAudio = Docs.Create.AudioDocument(nullAudio, { _width: 200, title: "audio recording", system: true, cloneFieldFilter: new List(["system"]) }); diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 337595f1c..a26953ff6 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -399,10 +399,7 @@ export class CollectionViewBaseChrome extends React.Component { - const doc = Docs.Create.ScreenshotDocument("", { _fitWidth: true, _width: 400, _height: 200, title: "screen snapshot", system: true, cloneFieldFilter: new List(["system"]) }); - doc.x = 0; - doc.y = 0; - doc.startRec = true; + const doc = Docs.Create.ScreenshotDocument("screen recording", { _fitWidth: true, _width: 400, _height: 200, mediaState: "pendingRecording" }); //Doc.AddDocToList((Doc.UserDoc().myOverlayDocs as Doc), undefined, doc); CollectionDockingView.AddSplit(doc, "right"); } diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 85899578c..a2e36f12e 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -53,7 +53,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent = this.layoutDoc._height; @observable _paused: boolean = false; - @computed get mediaState(): undefined | "recording" | "paused" | "playing" { return this.dataDoc.mediaState as (undefined | "recording" | "paused" | "playing"); } + @computed get mediaState(): undefined | "pendingRecording" | "recording" | "paused" | "playing" { return this.dataDoc.mediaState as (undefined | "pendingRecording" | "recording" | "paused" | "playing"); } set mediaState(value) { this.dataDoc.mediaState = value; } public static SetScrubTime = action((timeInMillisFrom1970: number) => { AudioBox._scrubTime = 0; AudioBox._scrubTime = timeInMillisFrom1970; }); @computed get recordingStart() { return Cast(this.dataDoc[this.props.fieldKey + "-recordingStart"], DateField)?.date.getTime(); } diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx index 73fe8d68a..c4f8d1143 100644 --- a/src/client/views/nodes/ScreenshotBox.tsx +++ b/src/client/views/nodes/ScreenshotBox.tsx @@ -84,9 +84,8 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent { this._videoRef = r; setTimeout(() => { - if (this.rootDoc.startRec && this._videoRef) { // TODO glr: use mediaState + if (this.rootDoc.mediaState === "pendingRecording" && this._videoRef) { // TODO glr: use mediaState this.toggleRecording(); - this.rootDoc.startRec = undefined; } }, 1000); }} -- cgit v1.2.3-70-g09d2