aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2021-04-11 13:16:51 -0400
committerGitHub <noreply@github.com>2021-04-11 13:16:51 -0400
commit607e219255efbe2961bc23d5bd296c810e39e8d1 (patch)
tree04fec0def75bb4c1264306717de31ebd0a2a2518 /src/client/views/collections
parentf87c528f95912319c4181b3955cad4f1042c021e (diff)
parentb215d4860454fca9050bb96a5f7c222c1eb9a3c7 (diff)
Merge pull request #952 from browngraphicslab/demo_changes
Demo changes
Diffstat (limited to 'src/client/views/collections')
-rw-r--r--src/client/views/collections/CollectionMenu.scss126
-rw-r--r--src/client/views/collections/CollectionMenu.tsx71
-rw-r--r--src/client/views/collections/CollectionPileView.tsx13
-rw-r--r--src/client/views/collections/CollectionStackedTimeline.tsx11
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx2
-rw-r--r--src/client/views/collections/CollectionStackingViewFieldColumn.tsx2
-rw-r--r--src/client/views/collections/CollectionSubView.tsx2
-rw-r--r--src/client/views/collections/CollectionView.tsx1
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx2
9 files changed, 166 insertions, 64 deletions
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..a26953ff6 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -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,29 @@ 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("screen recording", { _fitWidth: true, _width: 400, _height: 200, mediaState: "pendingRecording" });
+ //Doc.AddDocToList((Doc.UserDoc().myOverlayDocs as Doc), undefined, doc);
+ CollectionDockingView.AddSplit(doc, "right");
+ }
+
+ @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 +503,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 +511,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.toggleOverlayButton}
{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>
+ <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/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 <div className="collectionPileView-innards" style={{ pointerEvents: this.layoutEngine() === "starburst" || (SnappingManager.GetIsDragging() && !draggingSelf) ? undefined : "none", zIndex: this.layoutEngine() === "starburst" && !SnappingManager.GetIsDragging() ? -10 : "auto" }} >
- <CollectionFreeFormView {...this.props} layoutEngine={this.layoutEngine}
+ return <div className="collectionPileView-innards"
+ style={{
+ pointerEvents: isStarburst || (SnappingManager.GetIsDragging() && !draggingSelf) ? undefined : "none",
+ zIndex: isStarburst && !SnappingManager.GetIsDragging() ? -10 : "auto"
+ }} >
+ <CollectionFreeFormView {...this.props}
+ layoutEngine={this.layoutEngine}
+ childDocumentsActive={isStarburst ? returnTrue : undefined}
addDocument={undoBatch((doc: Doc | Doc[]) => {
(doc instanceof Doc ? [doc] : doc).map((d) => DocUtils.iconify(d));
return this.props.addDocument?.(doc) || false;
diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx
index 6a1242f20..ab9c4aa2c 100644
--- a/src/client/views/collections/CollectionStackedTimeline.tsx
+++ b/src/client/views/collections/CollectionStackedTimeline.tsx
@@ -234,8 +234,9 @@ export class CollectionStackedTimeline extends CollectionSubView<PanZoomDocument
return level;
}
- dictationHeight = () => this.props.PanelHeight() / 3;
- timelineContentHeight = () => this.props.PanelHeight() * 2 / 3;
+ 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);
@@ -348,7 +349,11 @@ class StackedTimelineAnchor extends React.Component<StackedTimelineAnchorProps>
(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
+ // 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/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<StackingDocument,
@computed get chromeHidden() { return this.props.chromeHidden || BoolCast(this.layoutDoc.chromeHidden); }
@computed get columnHeaders() { return Cast(this.layoutDoc._columnHeaders, listSpec(SchemaHeaderField), null); }
@computed get pivotField() { return StrCast(this.layoutDoc._pivotField); }
- @computed get filteredChildren() { return this.childLayoutPairs.filter(pair => 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/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<CSVFieldC
}
});
const pt = this.props.screenToLocalTransform().inverse().transformPoint(x, y);
- ContextMenu.Instance.displayMenu(x, y);
+ ContextMenu.Instance.displayMenu(x, y, undefined, true);
}
@computed get innards() {
TraceMobx();
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index b998555d8..a5d62acb4 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -74,7 +74,7 @@ export function CollectionSubView<T, X>(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/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 c623ce653..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<PanZoomDocument, P
docRangeFilters={this.freeformRangeDocFilters}
searchFilterDocs={this.searchFilterDocs}
isContentActive={this.isAnnotationOverlay ? this.props.isContentActive : returnFalse}
- isDocumentActive={this.isContentActive}
+ isDocumentActive={this.props.childDocumentsActive ? this.props.isDocumentActive : this.isContentActive}
focus={this.focusDocument}
addDocTab={this.addDocTab}
addDocument={this.props.addDocument}