aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/util/CaptureManager.scss465
-rw-r--r--src/client/util/CaptureManager.tsx75
-rw-r--r--src/client/views/AntimodeMenu.scss14
-rw-r--r--src/client/views/AntimodeMenu.tsx2
-rw-r--r--src/client/views/MainView.scss3
-rw-r--r--src/client/views/MainView.tsx6
-rw-r--r--src/client/views/collections/CollectionMenu.scss126
-rw-r--r--src/client/views/collections/CollectionMenu.tsx78
-rw-r--r--src/client/views/nodes/ScreenshotBox.tsx121
-rw-r--r--src/client/views/nodes/VideoBox.scss10
-rw-r--r--src/client/views/nodes/formattedText/RichTextMenu.scss7
-rw-r--r--src/client/views/nodes/formattedText/RichTextMenu.tsx2
12 files changed, 790 insertions, 119 deletions
diff --git a/src/client/util/CaptureManager.scss b/src/client/util/CaptureManager.scss
new file mode 100644
index 000000000..5ca54517c
--- /dev/null
+++ b/src/client/util/CaptureManager.scss
@@ -0,0 +1,465 @@
+@import "../views/globalCssVariables";
+
+.settings-interface {
+ //background-color: whitesmoke !important;
+ color: grey;
+ width: 450px;
+
+ button {
+ background: #315a96;
+ outline: none;
+ border-radius: 5px;
+ border: 0px;
+ color: #fcfbf7;
+ text-transform: uppercase;
+ letter-spacing: 2px;
+ font-size: 75%;
+ padding: 10px;
+ margin: 10px;
+ transition: transform 0.2s;
+ margin: 2px;
+ }
+}
+
+.settings-title {
+ font-size: 25px;
+ font-weight: bold;
+ padding-right: 10px;
+ color: black;
+}
+
+.settings-username {
+ font-size: 12px;
+ padding-right: 15px;
+ color: black;
+ margin-top: 10px;
+ margin-bottom: 10px;
+ /* right: 135; */
+ // position: absolute;
+ // left: 243;
+}
+
+.settings-section {
+ display: flex;
+ border-bottom: 1px solid grey;
+ padding-bottom: 8px;
+ padding-top: 6px;
+
+ .settings-section-title {
+ font-size: 16;
+ font-weight: bold;
+ text-align: left;
+ color: black;
+ width: 80;
+ margin-right: 50px;
+ }
+
+ &:last-child {
+ border-bottom: none;
+ }
+}
+
+
+.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 {
+ display: flex;
+}
+
+.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;
+ }
+}
+
+.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
new file mode 100644
index 000000000..f01fcd0d2
--- /dev/null
+++ b/src/client/util/CaptureManager.tsx
@@ -0,0 +1,75 @@
+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");
+export const { anchorPoints } = higflyout;
+export const Flyout = higflyout.default;
+
+@observer
+export class CaptureManager extends React.Component<{}> {
+ public static Instance: CaptureManager;
+ static _settingsStyle = addStyleSheet();
+ @observable isOpen: boolean = false; // whether the CaptureManager is to be displayed or not.
+
+
+ constructor(props: {}) {
+ super(props);
+ CaptureManager.Instance = this;
+ }
+
+ public close = action(() => this.isOpen = false);
+ public open = action(() => this.isOpen = true);
+
+
+ @computed get colorsContent() {
+
+ return <div className="colors-content">
+
+ </div>;
+ }
+
+ @computed get formatsContent() {
+ return <div className="prefs-content">
+
+ </div>;
+ }
+
+
+
+
+
+ private get captureInterface() {
+ return <div className="settings-interface">
+ <div className="settings-panel">
+
+ </div>
+
+ <div className="close-button" onClick={this.close}>
+ <FontAwesomeIcon icon={"times"} color="black" size={"lg"} />
+ </div>
+ </div>;
+
+ }
+
+ render() {
+ return <MainViewModal
+ contents={this.captureInterface}
+ isDisplayed={this.isOpen}
+ interactive={true}
+ closeOnExternalClick={this.close}
+ dialogueBoxStyle={{ width: "500px", height: "300px", background: Cast(Doc.SharingDoc().userColor, "string", null) }} />;
+ }
+} \ No newline at end of file
diff --git a/src/client/views/AntimodeMenu.scss b/src/client/views/AntimodeMenu.scss
index c9b5e7658..a275901be 100644
--- a/src/client/views/AntimodeMenu.scss
+++ b/src/client/views/AntimodeMenu.scss
@@ -7,7 +7,7 @@
height: $antimodemenu-height;
background: #323232;
box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.25);
- border-radius: 0px 6px 6px 6px;
+ // border-radius: 0px 6px 6px 6px;
z-index: 1001;
display: flex;
@@ -24,6 +24,16 @@
background-color: transparent;
width: 35px;
height: 35px;
+ padding: 5;
+ text-align: center;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ position: relative;
+
+ .svg {
+ margin: 0;
+ }
&.active {
background-color: #121212;
@@ -31,7 +41,7 @@
}
.antimodeMenu-button:hover {
- background-color: #121212;
+ background-color: rgba(0, 0, 0, 0.4);
}
.antimodeMenu-dragger {
diff --git a/src/client/views/AntimodeMenu.tsx b/src/client/views/AntimodeMenu.tsx
index 5acb3e4c8..fe6d39ca4 100644
--- a/src/client/views/AntimodeMenu.tsx
+++ b/src/client/views/AntimodeMenu.tsx
@@ -140,7 +140,7 @@ export abstract class AntimodeMenu<T extends AntimodeMenuProps> extends React.Co
left: this._left, top: this._top, opacity: this._opacity, transitionProperty: this._transitionProperty, transitionDuration: this._transitionDuration, transitionDelay: this._transitionDelay,
position: this.Pinned ? "unset" : undefined
}}>
- <div className="antimodeMenu-dragger" onPointerDown={this.dragStart} style={{ width: "20px" }} />
+ {/* {this.getDragger} */}
{buttons}
</div>
);
diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss
index 8ccb64744..3f04a0f3a 100644
--- a/src/client/views/MainView.scss
+++ b/src/client/views/MainView.scss
@@ -358,9 +358,6 @@
.mainView-libraryFlyout-out {
transition: width .25s;
box-shadow: rgb(156, 147, 150) 0.2vw 0.2vw 0.2vw;
- .mainView-docButtons {
- left: 0;
- }
}
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 204ec370f..7d78d74e3 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -17,6 +17,7 @@ import { emptyFunction, emptyPath, returnEmptyDoclist, returnEmptyFilter, return
import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager';
import { DocServer } from '../DocServer';
import { Docs, DocUtils } from '../documents/Documents';
+import { CaptureManager } from '../util/CaptureManager';
import { CurrentUserUtils } from '../util/CurrentUserUtils';
import { DocumentManager } from '../util/DocumentManager';
import { GroupManager } from '../util/GroupManager';
@@ -177,8 +178,8 @@ export class MainView extends React.Component {
const targClass = targets[0].className.toString();
if (SearchBox.Instance._searchbarOpen || SearchBox.Instance.open) {
const check = targets.some((thing) =>
- (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" ||
- thing.className === "collectionSchema-header-menuOptions"));
+ (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" ||
+ thing.className === "collectionSchema-header-menuOptions"));
!check && SearchBox.Instance.resetSearch(true);
}
!targClass.includes("contextMenu") && ContextMenu.Instance.closeMenu();
@@ -619,6 +620,7 @@ export class MainView extends React.Component {
<DictationOverlay />
<SharingManager />
<SettingsManager />
+ <CaptureManager />
<GroupManager />
<GoogleAuthenticationManager />
<DocumentDecorations boundsLeft={this.leftOffset} boundsTop={this.topOffset} />
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<AntimodeMenuProps> {
@@ -388,7 +391,32 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
return !targetDoc ? (null) : <Tooltip key="pin" title={<div className="dash-tooltip">{Doc.isDocPinned(targetDoc) ? "Unpin from presentation" : "Pin to presentation"}</div>} placement="top">
<button className="antimodeMenu-button" style={{ backgroundColor: isPinned ? "121212" : undefined, borderLeft: "1px solid gray" }}
onClick={e => TabDocView.PinDoc(targetDoc, { unpin: isPinned })}>
- <FontAwesomeIcon className="documentdecorations-icon" size="lg" icon="map-pin" />
+ <FontAwesomeIcon className="colMenu-icon" size="lg" icon="map-pin" />
+ </button>
+ </Tooltip>;
+ }
+
+ @undoBatch
+ @action
+ startRecording = () => {
+ const doc = Docs.Create.ScreenshotDocument("", { _fitWidth: true, _width: 400, _height: 200, title: "screen snapshot", system: true, cloneFieldFilter: new List<string>(["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 <Tooltip key="record" title={<div className="dash-tooltip">{"Capture screen"}</div>} placement="top">
+ <button className="antimodeMenu-button"
+ onClick={e => this.startRecording()}>
+ <div className="recordButtonOutline" style={{}}>
+ <div className="recordButtonInner" style={{}}>
+ </div>
+ </div>
</button>
</Tooltip>;
}
@@ -478,7 +506,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
const targetDoc = this.selectedDoc;
return !targetDoc || targetDoc.type === DocumentType.PRES ? (null) : <Tooltip title={<div className="dash-tooltip">{"Tap or Drag to create an alias"}</div>} placement="top">
<button className="antimodeMenu-button" onPointerDown={this.onAliasButtonDown} onClick={this.onAlias} style={{ cursor: "drag" }}>
- <FontAwesomeIcon className="documentdecorations-icon" icon="copy" size="lg" />
+ <FontAwesomeIcon className="colMenu-icon" icon="copy" size="lg" />
</button>
</Tooltip>;
}
@@ -486,38 +514,48 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
@computed get lightboxButton() {
const targetDoc = this.selectedDoc;
return !targetDoc ? (null) : <Tooltip title={<div className="dash-tooltip">{"View in Lightbox"}</div>} placement="top">
- <button className="antimodeMenu-button" style={{ borderRight: "1px solid gray", justifyContent: 'center' }} onPointerDown={() => {
+ <button className="antimodeMenu-button" onPointerDown={() => {
const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]);
LightboxView.SetLightboxDoc(targetDoc, undefined, docs);
}}>
- <FontAwesomeIcon className="documentdecorations-icon" icon="desktop" size="lg" />
+ <FontAwesomeIcon className="colMenu-icon" icon="desktop" size="lg" />
</button>
</Tooltip>;
}
+ @computed get toggleOverlayButton() {
+ return <>
+ <Tooltip title={<div className="dash-tooltip">Toggle Overlay Layer</div>} placement="bottom">
+ <button className={"antimodeMenu-button"} key="float"
+ style={{
+ backgroundColor: this.props.docView.layoutDoc.z ? "121212" : undefined,
+ pointerEvents: this.props.docView.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Freeform ? "none" : undefined,
+ color: this.props.docView.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Freeform ? "dimgrey" : undefined
+ }}
+ onClick={undoBatch(() => this.props.docView.props.CollectionFreeFormDocumentView?.().float())}>
+ <FontAwesomeIcon icon={["fab", "buffer"]} size={"lg"} />
+ </button>
+ </Tooltip>
+ </>
+ }
+
render() {
return (
<div className="collectionMenu-cont" >
<div className="collectionMenu">
<div className="collectionViewBaseChrome">
+ {this.notACollection || this.props.type === CollectionViewType.Invalid ? (null) : this.viewModes}
+ <div className="collectionMenu-divider" key="divider1"></div>
{this.aliasButton}
{/* {this.pinButton} */}
- {this.pinWithViewButton}
- {this.lightboxButton}
- <Tooltip title={<div className="dash-tooltip">Toggle Overlay Layer</div>} placement="bottom">
- <button className={"antimodeMenu-button"} key="float"
- style={{
- backgroundColor: this.props.docView.layoutDoc.z ? "121212" : undefined, borderRight: "1px solid gray",
- pointerEvents: this.props.docView.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Freeform ? "none" : undefined,
- color: this.props.docView.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Freeform ? "dimgrey" : undefined
- }}
- onClick={undoBatch(() => this.props.docView.props.CollectionFreeFormDocumentView?.().float())}>
- <FontAwesomeIcon icon={["fab", "buffer"]} size={"lg"} />
- </button>
- </Tooltip>
+ {/* {this.pinWithViewButton} */}
+ {this.toggleOverlayButton}
+ <div className="collectionMenu-divider" key="divider2"></div>
{this.subChrome}
- {this.notACollection || this.props.type === CollectionViewType.Invalid ? (null) : this.viewModes}
- {!this._buttonizableCommands ? (null) : this.templateChrome}
+ <div className="collectionMenu-divider" key="divider3"></div>
+ {this.lightboxButton}
+ {this.recordButton}
+ {/* {!this._buttonizableCommands ? (null) : this.templateChrome} */}
</div>
</div>
</div>
diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx
index 8163b652c..4c24dc5e1 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, observable } from "mobx";
+import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from "mobx";
import { observer } from "mobx-react";
import { DateField } from "../../../fields/DateField";
import { Doc, WidthSym } from "../../../fields/Doc";
@@ -25,6 +25,7 @@ import "./ScreenshotBox.scss";
import { VideoBox } from "./VideoBox";
import { TraceMobx } from "../../../fields/util";
import { FormattedTextBox } from "./formattedText/FormattedTextBox";
+import { CaptureManager } from "../../util/CaptureManager";
declare class MediaRecorder {
constructor(e: any, options?: any); // whatever MediaRecorder has
}
@@ -40,6 +41,8 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
private _videoRec: any;
@observable _screenCapture = false;
@computed get recordingStart() { return Cast(this.dataDoc[this.props.fieldKey + "-recordingStart"], DateField)?.date.getTime(); }
+ private _disposers: { [name: string]: IReactionDisposer } = {};
+
constructor(props: any) {
super(props);
@@ -66,10 +69,14 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
componentDidMount() {
this.dataDoc.nativeWidth = this.dataDoc.nativeHeight = 0;
this.props.setContentView?.(this); // this tells the DocumentView that this ScreenshotBox is the "content" of the document. this allows the DocumentView to indirectly call getAnchor() on the AudioBox when making a link.
+ this._disposers.rec = reaction(() => this.rootDoc.startRec == true,
+ this.toggleRecording
+ );
}
componentWillUnmount() {
const ind = DocUtils.ActiveRecordings.indexOf(this);
ind !== -1 && (DocUtils.ActiveRecordings.splice(ind, 1));
+ Object.values(this._disposers).forEach(disposer => disposer?.());
}
specificContextMenu = (e: React.MouseEvent): void => {
@@ -91,6 +98,13 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
}
toggleRecording = action(async () => {
+ console.log("toggleRecording");
+ console.log("2:" + this._videoRef.current!.srcObject);
+ if (this._screenCapture) {
+ CaptureManager.Instance.open(this.rootDoc);
+ } else {
+ console.log("opening");
+ }
this._screenCapture = !this._screenCapture;
if (this._screenCapture) {
this._audioRec = new MediaRecorder(await navigator.mediaDevices.getUserMedia({ audio: true }));
@@ -149,57 +163,62 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
formattedPanelHeight = () => Math.max(0, this.props.PanelHeight() - this.videoPanelHeight());
render() {
TraceMobx();
- return <div className="videoBox" onContextMenu={this.specificContextMenu} style={{ width: "100%", height: "100%" }} >
- <div className="videoBox-viewer" >
- <div style={{ position: "relative", height: this.videoPanelHeight() }}>
- <CollectionFreeFormView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit}
- PanelHeight={this.videoPanelHeight}
- PanelWidth={this.props.PanelWidth}
- focus={this.props.focus}
- isSelected={this.props.isSelected}
- isAnnotationOverlay={true}
- select={emptyFunction}
- isContentActive={returnFalse}
- scaling={returnOne}
- whenChildContentsActiveChanged={emptyFunction}
- removeDocument={returnFalse}
- moveDocument={returnFalse}
- addDocument={returnFalse}
- CollectionView={undefined}
- ScreenToLocalTransform={this.props.ScreenToLocalTransform}
- renderDepth={this.props.renderDepth + 1}
- ContainingCollectionDoc={this.props.ContainingCollectionDoc}>
- {this.contentFunc}
- </CollectionFreeFormView></div>
- <div style={{ position: "relative", height: this.formattedPanelHeight() }}>
- <FormattedTextBox {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit}
- Document={this.dataDoc[this.fieldKey + "-dictation"]}
- fieldKey={"text"}
- PanelHeight={this.formattedPanelHeight}
- PanelWidth={this.props.PanelWidth}
- focus={this.props.focus}
- isSelected={this.props.isSelected}
- isAnnotationOverlay={true}
- select={emptyFunction}
- isContentActive={returnFalse}
- scaling={returnOne}
- xMargin={25}
- yMargin={10}
- whenChildContentsActiveChanged={emptyFunction}
- removeDocument={returnFalse}
- moveDocument={returnFalse}
- addDocument={returnFalse}
- CollectionView={undefined}
- ScreenToLocalTransform={this.props.ScreenToLocalTransform}
- renderDepth={this.props.renderDepth + 1}
- ContainingCollectionDoc={this.props.ContainingCollectionDoc}>
- </FormattedTextBox></div>
+ return this.rootDoc.startRec ?
+ <div className="mini-viewer">
+
</div>
- {!this.props.isSelected() ? (null) : <div className="screenshotBox-uiButtons">
- <div className="screenshotBox-recorder" key="snap" onPointerDown={this.toggleRecording} >
- <FontAwesomeIcon icon="file" size="lg" />
+ :
+ <div className="videoBox" onContextMenu={this.specificContextMenu} style={{ width: "100%", height: "100%" }} >
+ <div className="videoBox-viewer" >
+ <div style={{ position: "relative", height: this.videoPanelHeight() }}>
+ <CollectionFreeFormView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit}
+ PanelHeight={this.videoPanelHeight}
+ PanelWidth={this.props.PanelWidth}
+ focus={this.props.focus}
+ isSelected={this.props.isSelected}
+ isAnnotationOverlay={true}
+ select={emptyFunction}
+ isContentActive={returnFalse}
+ scaling={returnOne}
+ whenChildContentsActiveChanged={emptyFunction}
+ removeDocument={returnFalse}
+ moveDocument={returnFalse}
+ addDocument={returnFalse}
+ CollectionView={undefined}
+ ScreenToLocalTransform={this.props.ScreenToLocalTransform}
+ renderDepth={this.props.renderDepth + 1}
+ ContainingCollectionDoc={this.props.ContainingCollectionDoc}>
+ {this.contentFunc}
+ </CollectionFreeFormView></div>
+ <div style={{ position: "relative", height: this.formattedPanelHeight() }}>
+ <FormattedTextBox {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit}
+ Document={this.dataDoc[this.fieldKey + "-dictation"]}
+ fieldKey={"text"}
+ PanelHeight={this.formattedPanelHeight}
+ PanelWidth={this.props.PanelWidth}
+ focus={this.props.focus}
+ isSelected={this.props.isSelected}
+ isAnnotationOverlay={true}
+ select={emptyFunction}
+ isContentActive={returnFalse}
+ scaling={returnOne}
+ xMargin={25}
+ yMargin={10}
+ whenChildContentsActiveChanged={emptyFunction}
+ removeDocument={returnFalse}
+ moveDocument={returnFalse}
+ addDocument={returnFalse}
+ CollectionView={undefined}
+ ScreenToLocalTransform={this.props.ScreenToLocalTransform}
+ renderDepth={this.props.renderDepth + 1}
+ ContainingCollectionDoc={this.props.ContainingCollectionDoc}>
+ </FormattedTextBox></div>
</div>
- </div>}
- </div >;
+ {!this.props.isSelected() ? (null) : <div className="screenshotBox-uiButtons">
+ <div className="screenshotBox-recorder" key="snap" onPointerDown={this.toggleRecording} >
+ <FontAwesomeIcon icon="file" size="lg" />
+ </div>
+ </div>}
+ </div >;
}
} \ No newline at end of file
diff --git a/src/client/views/nodes/VideoBox.scss b/src/client/views/nodes/VideoBox.scss
index dd8d77603..30f0c4393 100644
--- a/src/client/views/nodes/VideoBox.scss
+++ b/src/client/views/nodes/VideoBox.scss
@@ -1,3 +1,13 @@
+.mini-viewer{
+ cursor: grab;
+ position: absolute;
+ right: 10;
+ top: 10;
+ opacity: 0.1;
+ transition: all 0.4s;
+ color: white;
+}
+
.videoBox {
transform-origin: top left;
width: 100%;
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.scss b/src/client/views/nodes/formattedText/RichTextMenu.scss
index fbc468292..1d24d6833 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.scss
+++ b/src/client/views/nodes/formattedText/RichTextMenu.scss
@@ -95,9 +95,10 @@
.color-preview-button {
.color-preview {
- width: 100%;
- height: 3px;
- margin-top: 3px;
+ width: 60%;
+ top: 80%;
+ position: absolute;
+ height: 4px;
}
}
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index 5da868281..071491463 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -976,7 +976,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
const row2 = <div className="antimodeMenu-row row-2" key="row2">
{this.collapsed ? this.getDragger() : (null)}
<div key="row 2" style={{ display: this.collapsed ? "none" : undefined }}>
- <div className="richTextMenu-divider" key="divider 3" />,
+ <div className="richTextMenu-divider" key="divider 3" />
{[this.createMarksDropdown(this.activeFontSize, this.fontSizeOptions, "font size", action((val: string) => {
this.activeFontSize = val;
SelectionManager.Views().map(dv => dv.props.Document._fontSize = val);