aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
diff options
context:
space:
mode:
authorMelissa Zhang <mzhang19096@gmail.com>2020-08-07 09:40:06 -0700
committerMelissa Zhang <mzhang19096@gmail.com>2020-08-07 09:40:06 -0700
commit9886ed681ff18a33f7acab8f83b475ca9ea60bf7 (patch)
tree0b69d4b0fbfc52eac07c2e38fdbb34f161a2dc98 /src/client/views/collections/collectionFreeForm/PropertiesView.tsx
parentc94a61aa594f77db4c9b08a5f91c1a7e57d5ff9d (diff)
parentb02cfed890d9d95a8f45bbc93d688bd3311dd387 (diff)
merge with master
Diffstat (limited to 'src/client/views/collections/collectionFreeForm/PropertiesView.tsx')
-rw-r--r--src/client/views/collections/collectionFreeForm/PropertiesView.tsx528
1 files changed, 364 insertions, 164 deletions
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index f5e0cd077..15900aa33 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -2,13 +2,11 @@ import React = require("react");
import { observer } from "mobx-react";
import "./PropertiesView.scss";
import { observable, action, computed, runInAction } from "mobx";
-import { Doc, Field, DocListCast, WidthSym, HeightSym, AclSym, AclPrivate, AclReadonly, AclAddonly, AclEdit, AclAdmin, Opt } from "../../../../fields/Doc";
-import { DocumentView } from "../../nodes/DocumentView";
+import { Doc, Field, WidthSym, HeightSym, AclSym, AclPrivate, AclReadonly, AclAddonly, AclEdit, AclAdmin, Opt, DocCastAsync } from "../../../../fields/Doc";
import { ComputedField } from "../../../../fields/ScriptField";
import { EditableView } from "../../EditableView";
import { KeyValueBox } from "../../nodes/KeyValueBox";
import { Cast, NumCast, StrCast } from "../../../../fields/Types";
-import { listSpec } from "../../../../fields/Schema";
import { ContentFittingDocumentView } from "../../nodes/ContentFittingDocumentView";
import { returnFalse, returnOne, emptyFunction, emptyPath, returnTrue, returnZero, returnEmptyFilter, Utils } from "../../../../Utils";
import { Id } from "../../../../fields/FieldSymbols";
@@ -16,18 +14,26 @@ import { Transform } from "../../../util/Transform";
import { PropertiesButtons } from "../../PropertiesButtons";
import { SelectionManager } from "../../../util/SelectionManager";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { Tooltip, Checkbox, Divider } from "@material-ui/core";
+import { Tooltip, Checkbox } from "@material-ui/core";
import SharingManager from "../../../util/SharingManager";
import { DocumentType } from "../../../documents/DocumentTypes";
-import FormatShapePane from "./FormatShapePane";
import { SharingPermissions, GetEffectiveAcl } from "../../../../fields/util";
import { InkField } from "../../../../fields/InkField";
-import { undoBatch } from "../../../util/UndoManager";
+import { undoBatch, UndoManager } from "../../../util/UndoManager";
import { ColorState, SketchPicker } from "react-color";
-import AntimodeMenu from "../../AntimodeMenu";
import "./FormatShapePane.scss";
-import { discovery_v1 } from "googleapis";
+import { PresBox } from "../../nodes/PresBox";
+import { DocumentManager } from "../../../util/DocumentManager";
+import FormatShapePane from "./FormatShapePane";
+const higflyout = require("@hig/flyout");
+export const { anchorPoints } = higflyout;
+export const Flyout = higflyout.default;
+const _global = (window /* browser */ || global /* node */) as any;
+
+// import * as fa from '@fortawesome/free-solid-svg-icons';
+// import { library } from "@fortawesome/fontawesome-svg-core";
+// library.add(fa.faPlus, fa.faMinus, fa.faCog);
interface PropertiesViewProps {
width: number;
@@ -39,14 +45,21 @@ interface PropertiesViewProps {
@observer
export class PropertiesView extends React.Component<PropertiesViewProps> {
+ private _widthUndo?: UndoManager.Batch;
@computed get MAX_EMBED_HEIGHT() { return 200; }
@computed get selectedDocumentView() {
if (SelectionManager.SelectedDocuments().length) {
return SelectionManager.SelectedDocuments()[0];
+ } else if (PresBox.Instance?._selectedArray.length) {
+ return DocumentManager.Instance.getDocumentView(PresBox.Instance.rootDoc);
} else { return undefined; }
}
+ @computed get isPres(): boolean {
+ if (this.selectedDoc?.type === DocumentType.PRES) return true;
+ return false;
+ }
@computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; }
@computed get dataDoc() { return this.selectedDocumentView?.dataDoc; }
@@ -58,6 +71,18 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
@observable openLayout: boolean = true;
@observable openAppearance: boolean = true;
@observable openTransform: boolean = true;
+ // @observable selectedUser: string = "";
+ // @observable addButtonPressed: boolean = false;
+
+ //Pres Trails booleans:
+ @observable openPresTransitions: boolean = false;
+ @observable openPresProgressivize: boolean = false;
+ @observable openAddSlide: boolean = false;
+ @observable openSlideOptions: boolean = false;
+
+ @observable inActions: boolean = false;
+ @observable _controlBtn: boolean = false;
+ @observable _lock: boolean = false;
@computed get isInk() { return this.selectedDoc?.type === DocumentType.INK; }
@@ -156,7 +181,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
doc && Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key));
const rows: JSX.Element[] = [];
for (const key of Object.keys(ids).slice().sort()) {
- if ((key[0] === key[0].toUpperCase() && key.substring(0, 3) !== "ACL")
+ if ((key[0] === key[0].toUpperCase() && key.substring(0, 3) !== "ACL" && key !== "UseCors")
|| key[0] === "#" || key === "author" ||
key === "creationDate" || key.indexOf("lastModified") !== -1) {
@@ -222,12 +247,23 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
return false;
}
+ @observable transform: Transform = Transform.Identity();
+ getTransform = () => { return this.transform; }
+ propertiesDocViewRef = (ref: HTMLDivElement) => {
+ const observer = new _global.ResizeObserver(action((entries: any) => {
+ const cliRect = ref.getBoundingClientRect();
+ this.transform = new Transform(-cliRect.x, -cliRect.y, 1);
+ }));
+ ref && observer.observe(ref);
+ }
+
+ previewBackground = () => "lightgrey";
@computed get layoutPreview() {
if (this.selectedDoc) {
const layoutDoc = Doc.Layout(this.selectedDoc);
const panelHeight = StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfHeight : this.docHeight;
const panelWidth = StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfWidth : this.docWidth;
- return <div style={{ display: "inline-block", height: panelHeight() }} key={this.selectedDoc[Id]}>
+ return <div ref={this.propertiesDocViewRef} style={{ pointerEvents: "none", display: "inline-block", height: panelHeight() }} key={this.selectedDoc[Id]}>
<ContentFittingDocumentView
Document={layoutDoc}
DataDoc={this.dataDoc}
@@ -235,8 +271,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
renderDepth={this.props.renderDepth + 1}
rootSelected={returnFalse}
treeViewDoc={undefined}
- backgroundColor={() => "lightgrey"}
- fitToBox={false}
+ backgroundColor={this.previewBackground}
+ fitToBox={true}
FreezeDimensions={true}
NativeWidth={layoutDoc.type ===
StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfWidth : returnZero}
@@ -245,7 +281,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
PanelWidth={panelWidth}
PanelHeight={panelHeight}
focus={returnFalse}
- ScreenToLocalTransform={this.props.ScreenToLocalTransform}
+ ScreenToLocalTransform={this.getTransform}
docFilters={returnEmptyFilter}
ContainingCollectionDoc={undefined}
ContainingCollectionView={undefined}
@@ -259,6 +295,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
bringToFront={returnFalse}
ContentScaling={returnOne}
dontRegisterView={true}
+ dropAction={undefined}
/>
</div>;
} else {
@@ -266,13 +303,20 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
}
}
+ /**
+ * Handles the changing of a user's permissions from the permissions panel.
+ */
@undoBatch
changePermissions = (e: any, user: string) => {
SharingManager.Instance.shareFromPropertiesSidebar(user, e.currentTarget.value as SharingPermissions, this.selectedDoc!);
}
- getPermissionsSelect(user: string) {
+ /**
+ * @returns the options for the permissions dropdown.
+ */
+ getPermissionsSelect(user: string, permission: string) {
return <select className="permissions-select"
+ defaultValue={permission}
onChange={e => this.changePermissions(e, user)}>
{Object.values(SharingPermissions).map(permission => {
return (
@@ -283,16 +327,22 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
</select>;
}
+ /**
+ * @returns the notification icon. On clicking, it should notify someone of a document been shared with them.
+ */
@computed get notifyIcon() {
- return <Tooltip title={<><div className="dash-tooltip">Notify with message</div></>}>
+ return <Tooltip title={<div className="dash-tooltip">Notify with message</div>}>
<div className="notify-button">
<FontAwesomeIcon className="notify-button-icon" icon="bell" color="white" size="sm" />
</div>
</Tooltip>;
}
+ /**
+ * ... next to the owner that opens the main SharingManager interface on click.
+ */
@computed get expansionIcon() {
- return <Tooltip title={<><div className="dash-tooltip">{"Show more permissions"}</div></>}>
+ return <Tooltip title={<div className="dash-tooltip">{"Show more permissions"}</div>}>
<div className="expansion-button" onPointerDown={() => {
if (this.selectedDocumentView) {
SharingManager.Instance.open(this.selectedDocumentView);
@@ -303,17 +353,26 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
</Tooltip>;
}
- sharingItem(name: string, effectiveAcl: symbol, permission?: string) {
- return <div className="propertiesView-sharingTable-item">
+ /**
+ * @returns a row of the permissions panel
+ */
+ sharingItem(name: string, effectiveAcl: symbol, permission: string) {
+ return <div className="propertiesView-sharingTable-item" key={name + permission}
+ // style={{ backgroundColor: this.selectedUser === name ? "#bcecfc" : "" }}
+ // onPointerDown={action(() => this.selectedUser = this.selectedUser === name ? "" : name)}
+ >
<div className="propertiesView-sharingTable-item-name" style={{ width: name !== "Me" ? "85px" : "80px" }}> {name} </div>
{/* {name !== "Me" ? this.notifyIcon : null} */}
<div className="propertiesView-sharingTable-item-permission">
- {effectiveAcl === AclAdmin && permission !== "Owner" ? this.getPermissionsSelect(name) : permission}
+ {effectiveAcl === AclAdmin && permission !== "Owner" ? this.getPermissionsSelect(name, permission) : permission}
{permission === "Owner" ? this.expansionIcon : null}
</div>
</div>;
}
+ /**
+ * @returns the sharing and permissiosn panel.
+ */
@computed get sharingTable() {
const AclMap = new Map<symbol, string>([
[AclPrivate, SharingPermissions.None],
@@ -326,13 +385,24 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
const effectiveAcl = GetEffectiveAcl(this.selectedDoc!);
const tableEntries = [];
+ // DocCastAsync(Doc.UserDoc().sidebarUsersDisplayed).then(sidebarUsersDisplayed => {
if (this.selectedDoc![AclSym]) {
for (const [key, value] of Object.entries(this.selectedDoc![AclSym])) {
const name = key.substring(4).replace("_", ".");
- if (name !== Doc.CurrentUserEmail && name !== this.selectedDoc!.author) tableEntries.push(this.sharingItem(name, effectiveAcl, AclMap.get(value)!));
+ if (name !== Doc.CurrentUserEmail && name !== this.selectedDoc!.author/* && sidebarUsersDisplayed![name] !== false*/) {
+ tableEntries.push(this.sharingItem(name, effectiveAcl, AclMap.get(value)!));
+ }
}
}
+ // if (Doc.UserDoc().sidebarUsersDisplayed) {
+ // for (const [name, value] of Object.entries(sidebarUsersDisplayed!)) {
+ // if (value === true && !this.selectedDoc![`ACL-${name.substring(8).replace(".", "_")}`]) tableEntries.push(this.sharingItem(name.substring(8), effectiveAcl, SharingPermissions.None));
+ // }
+ // }
+ // })
+
+ // shifts the current user and the owner to the top of the doc.
tableEntries.unshift(this.sharingItem("Me", effectiveAcl, Doc.CurrentUserEmail === this.selectedDoc!.author ? "Owner" : StrCast(this.selectedDoc![`ACL-${Doc.CurrentUserEmail.replace(".", "_")}`])));
if (Doc.CurrentUserEmail !== this.selectedDoc!.author) tableEntries.unshift(this.sharingItem(StrCast(this.selectedDoc!.author), effectiveAcl, "Owner"));
@@ -349,20 +419,19 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
/>;
}
- @undoBatch
@action
toggleCheckbox = () => {
this.layoutFields = !this.layoutFields;
}
@computed get editableTitle() {
- return <EditableView
+ return <div className="editable-title"><EditableView
key="editableView"
contents={StrCast(this.selectedDoc?.title)}
height={25}
fontSize={14}
GetValue={() => StrCast(this.selectedDoc?.title)}
- SetValue={this.setTitle} />;
+ SetValue={this.setTitle} /> </div>;
}
@undoBatch
@@ -399,15 +468,14 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
var index = 0;
if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) {
doc.rotation = Number(doc.rotation) + Number(angle);
- const ink = Cast(doc.data, InkField)?.inkData;
- if (ink) {
-
+ const inks = Cast(doc.data, InkField)?.inkData;
+ if (inks) {
const newPoints: { X: number, Y: number }[] = [];
- for (var i = 0; i < ink.length; i++) {
- const newX = Math.cos(angle) * (ink[i].X - _centerPoints[index].X) - Math.sin(angle) * (ink[i].Y - _centerPoints[index].Y) + _centerPoints[index].X;
- const newY = Math.sin(angle) * (ink[i].X - _centerPoints[index].X) + Math.cos(angle) * (ink[i].Y - _centerPoints[index].Y) + _centerPoints[index].Y;
+ inks.forEach(ink => {
+ const newX = Math.cos(angle) * (ink.X - _centerPoints[index].X) - Math.sin(angle) * (ink.Y - _centerPoints[index].Y) + _centerPoints[index].X;
+ const newY = Math.sin(angle) * (ink.X - _centerPoints[index].X) + Math.cos(angle) * (ink.Y - _centerPoints[index].Y) + _centerPoints[index].Y;
newPoints.push({ X: newX, Y: newY });
- }
+ });
doc.data = new InkField(newPoints);
const xs = newPoints.map(p => p.X);
const ys = newPoints.map(p => p.Y);
@@ -424,23 +492,22 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
}
}
- @observable _controlBtn: boolean = false;
- @observable _lock: boolean = false;
+
@computed
get controlPointsButton() {
return <div className="inking-button">
- <Tooltip title={<><div className="dash-tooltip">{"Edit points"}</div></>}>
- <div className="inking-button-points" onPointerDown={action(() => this._controlBtn = !this._controlBtn)} style={{ backgroundColor: this._controlBtn ? "black" : "" }}>
+ <Tooltip title={<div className="dash-tooltip">{"Edit points"}</div>}>
+ <div className="inking-button-points" onPointerDown={action(() => FormatShapePane.Instance._controlBtn = !FormatShapePane.Instance._controlBtn)} style={{ backgroundColor: FormatShapePane.Instance._controlBtn ? "black" : "" }}>
<FontAwesomeIcon icon="bezier-curve" color="white" size="lg" />
</div>
</Tooltip>
- <Tooltip title={<><div className="dash-tooltip">{this._lock ? "Unlock points" : "Lock points"}</div></>}>
- <div className="inking-button-lock" onPointerDown={action(() => this._lock = !this._lock)} >
- <FontAwesomeIcon icon={this._lock ? "unlock" : "lock"} color="white" size="lg" />
+ <Tooltip title={<div className="dash-tooltip">{FormatShapePane.Instance._lock ? "Unlock ratio" : "Lock ratio"}</div>}>
+ <div className="inking-button-lock" onPointerDown={action(() => FormatShapePane.Instance._lock = !FormatShapePane.Instance._lock)} >
+ <FontAwesomeIcon icon={FormatShapePane.Instance._lock ? "lock" : "unlock"} color="white" size="lg" />
</div>
</Tooltip>
- <Tooltip title={<><div className="dash-tooltip">{"Rotate 90˚"}</div></>}>
+ <Tooltip title={<div className="dash-tooltip">{"Rotate 90˚"}</div>}>
<div className="inking-button-rotate" onPointerDown={action(() => this.rotate(Math.PI / 2))}>
<FontAwesomeIcon icon="undo" color="white" size="lg" />
</div>
@@ -492,12 +559,10 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
const oldX = NumCast(this.selectedDoc?.x);
const oldY = NumCast(this.selectedDoc?.y);
this.selectedDoc && (this.selectedDoc._width = oldWidth + (dirs === "up" ? 10 : - 10));
- this._lock && this.selectedDoc && (this.selectedDoc._height = (NumCast(this.selectedDoc?._width) / oldWidth * NumCast(this.selectedDoc?._height)));
+ FormatShapePane.Instance._lock && this.selectedDoc && (this.selectedDoc._height = (NumCast(this.selectedDoc?._width) / oldWidth * NumCast(this.selectedDoc?._height)));
const doc = this.selectedDoc;
if (doc?.type === DocumentType.INK && doc.x && doc.y && doc._height && doc._width) {
- console.log(doc.x, doc.y, doc._height, doc._width);
const ink = Cast(doc.data, InkField)?.inkData;
- console.log(ink);
if (ink) {
const newPoints: { X: number, Y: number }[] = [];
for (var j = 0; j < ink.length; j++) {
@@ -516,12 +581,10 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
const oX = NumCast(this.selectedDoc?.x);
const oY = NumCast(this.selectedDoc?.y);
this.selectedDoc && (this.selectedDoc._height = oHeight + (dirs === "up" ? 10 : - 10));
- this._lock && this.selectedDoc && (this.selectedDoc._width = (NumCast(this.selectedDoc?._height) / oHeight * NumCast(this.selectedDoc?._width)));
+ FormatShapePane.Instance._lock && this.selectedDoc && (this.selectedDoc._width = (NumCast(this.selectedDoc?._height) / oHeight * NumCast(this.selectedDoc?._width)));
const docu = this.selectedDoc;
if (docu?.type === DocumentType.INK && docu.x && docu.y && docu._height && docu._width) {
- console.log(docu.x, docu.y, docu._height, docu._width);
const ink = Cast(docu.data, InkField)?.inkData;
- console.log(ink);
if (ink) {
const newPoints: { X: number, Y: number }[] = [];
for (var j = 0; j < ink.length; j++) {
@@ -539,7 +602,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
getField(key: string) {
//if (this.selectedDoc) {
- return Field.toString(this.selectedDoc[key] as Field);
+ return Field.toString(this.selectedDoc?.[key] as Field);
// } else {
// return undefined as Opt<string>;
// }
@@ -556,17 +619,18 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
set shapeWid(value) {
const oldWidth = NumCast(this.selectedDoc?._width);
this.selectedDoc && (this.selectedDoc._width = Number(value));
- this._lock && this.selectedDoc && (this.selectedDoc._height = (NumCast(this.selectedDoc?._width) * NumCast(this.selectedDoc?._height)) / oldWidth);
+ FormatShapePane.Instance._lock && this.selectedDoc && (this.selectedDoc._height = (NumCast(this.selectedDoc?._width) * NumCast(this.selectedDoc?._height)) / oldWidth);
}
set shapeHgt(value) {
const oldHeight = NumCast(this.selectedDoc?._height);
this.selectedDoc && (this.selectedDoc._height = Number(value));
- this._lock && this.selectedDoc && (this.selectedDoc._width = (NumCast(this.selectedDoc?._height) * NumCast(this.selectedDoc?._width)) / oldHeight);
+ FormatShapePane.Instance._lock && this.selectedDoc && (this.selectedDoc._width = (NumCast(this.selectedDoc?._height) * NumCast(this.selectedDoc?._width)) / oldHeight);
}
- @computed get hgtInput() { return this.inputBoxDuo("hgt", this.shapeHgt, (val: string) => this.shapeHgt = val, "H:", "wid", this.shapeWid, (val: string) => this.shapeWid = val, "W:"); }
- @computed get XpsInput() { return this.inputBoxDuo("Xps", this.shapeXps, (val: string) => this.shapeXps = val, "X:", "Yps", this.shapeYps, (val: string) => this.shapeYps = val, "Y:"); }
- @computed get rotInput() { return this.inputBoxDuo("rot", this.shapeRot, (val: string) => { this.rotate(Number(val) - Number(this.shapeRot)); this.shapeRot = val; return true; }, "∠:", "rot", this.shapeRot, (val: string) => this.shapeRot = val, ""); }
+ @computed get hgtInput() { return this.inputBoxDuo("hgt", this.shapeHgt, (val: string) => { if (!isNaN(Number(val))) { this.shapeHgt = val; } return true; }, "H:", "wid", this.shapeWid, (val: string) => { if (!isNaN(Number(val))) { this.shapeWid = val; } return true; }, "W:"); }
+ @computed get XpsInput() { return this.inputBoxDuo("Xps", this.shapeXps, (val: string) => { if (val !== "0" && !isNaN(Number(val))) { this.shapeXps = val; } return true; }, "X:", "Yps", this.shapeYps, (val: string) => { if (val !== "0" && !isNaN(Number(val))) { this.shapeYps = val; } return true; }, "Y:"); }
+ @computed get rotInput() { return this.inputBoxDuo("rot", this.shapeRot, (val: string) => { if (!isNaN(Number(val))) { this.rotate(Number(val) - Number(this.shapeRot)); this.shapeRot = val; } return true; }, "∠:", "rot", this.shapeRot, (val: string) => { if (!isNaN(Number(val))) { this.rotate(Number(val) - Number(this.shapeRot)); this.shapeRot = val; } return true; }, ""); }
+
@observable private _fillBtn = false;
@observable private _lineBtn = false;
@@ -580,14 +644,18 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
set colorFil(value) { value && (this._lastFill = value); this.selectedDoc && (this.selectedDoc.fillColor = value ? value : undefined); }
set colorStk(value) { value && (this._lastLine = value); this.selectedDoc && (this.selectedDoc.color = value ? value : undefined); }
- colorButton(value: string, setter: () => {}) {
- return <div className="color-button" key="color" onPointerDown={undoBatch(action(e => setter()))}>
- <div className="color-button-preview" style={{
- backgroundColor: value ?? "121212", width: 15, height: 15,
- display: value === "" || value === "transparent" ? "none" : ""
- }} />
- {value === "" || value === "transparent" ? <p style={{ fontSize: 25, color: "red", marginTop: -14, position: "fixed" }}>☒</p> : ""}
- </div>;
+ colorButton(value: string, type: string, setter: () => {}) {
+ return <Flyout anchorPoint={anchorPoints.LEFT_TOP}
+ content={type === "fill" ? this.fillPicker : this.linePicker}>
+ <div className="color-button" key="color" onPointerDown={undoBatch(action(e => setter()))}>
+ <div className="color-button-preview" style={{
+ backgroundColor: value ?? "121212", width: 15, height: 15,
+ display: value === "" || value === "transparent" ? "none" : ""
+ }} />
+ {value === "" || value === "transparent" ? <p style={{ fontSize: 25, color: "red", marginTop: -14, position: "fixed" }}>☒</p> : ""}
+ </div>
+ </Flyout>;
+
}
@undoBatch
@@ -613,8 +681,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
color={type === "stk" ? this.colorStk : this.colorFil} />;
}
- @computed get fillButton() { return this.colorButton(this.colorFil, () => { this._fillBtn = !this._fillBtn; this._lineBtn = false; return true; }); }
- @computed get lineButton() { return this.colorButton(this.colorStk, () => { this._lineBtn = !this._lineBtn; this._fillBtn = false; return true; }); }
+ @computed get fillButton() { return this.colorButton(this.colorFil, "fill", () => { this._fillBtn = !this._fillBtn; this._lineBtn = false; return true; }); }
+ @computed get lineButton() { return this.colorButton(this.colorStk, "line", () => { this._lineBtn = !this._lineBtn; this._fillBtn = false; return true; }); }
@computed get fillPicker() { return this.colorPicker((color: string) => this.colorFil = color, "fil"); }
@computed get linePicker() { return this.colorPicker((color: string) => this.colorStk = color, "stk"); }
@@ -631,8 +699,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
<div className="stroke-button">{this.lineButton}</div>
</div>
</div>
- {this._fillBtn ? this.fillPicker : ""}
- {this._lineBtn ? this.linePicker : ""}
+ {/* {this._fillBtn ? this.fillPicker : ""}
+ {this._lineBtn ? this.linePicker : ""} */}
</div>;
}
@@ -683,7 +751,10 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
</div>
<input className="width-range" type="range"
defaultValue={Number(this.widthStk)} min={1} max={100}
- onChange={undoBatch(action((e) => this.widthStk = e.target.value))} />
+ onChange={(action((e) => this.widthStk = e.target.value))}
+ onMouseDown={(e) => { this._widthUndo = UndoManager.StartBatch("width undo"); }}
+ onMouseUp={(e) => { this._widthUndo?.end(); this._widthUndo = undefined; }}
+ />
</div>
<div className="arrows">
@@ -701,7 +772,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
</div>
</div>
<div className="dashed">
- <div className="dashed-title">Dash:</div>
+ <div className="dashed-title">Dashed Line:</div>
<input key="markHead" className="dashed-input"
type="checkbox" checked={this.dashdStk === "2"}
onChange={this.changeDash} />
@@ -730,121 +801,250 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
</div>;
}
- render() {
+ /**
+ * Handles adding and removing members from the sharing panel
+ */
+ // handleUserChange = (selectedUser: string, add: boolean) => {
+ // if (!Doc.UserDoc().sidebarUsersDisplayed) Doc.UserDoc().sidebarUsersDisplayed = new Doc;
+ // DocCastAsync(Doc.UserDoc().sidebarUsersDisplayed).then(sidebarUsersDisplayed => {
+ // sidebarUsersDisplayed![`display-${selectedUser}`] = add;
+ // !add && runInAction(() => this.selectedUser = "");
+ // });
+ // }
- if (!this.selectedDoc) {
+ render() {
+ if (!this.selectedDoc && !this.isPres) {
return <div className="propertiesView" style={{ width: this.props.width }}>
<div className="propertiesView-title" style={{ width: this.props.width }}>
No Document Selected
- <div className="propertiesView-title-icon" onPointerDown={this.props.onDown}>
- <FontAwesomeIcon icon="times" color="black" size="xs" />
- </div>
</div>
</div>;
- }
-
- const novice = Doc.UserDoc().noviceMode;
- return <div className="propertiesView" style={{ width: this.props.width }} >
- <div className="propertiesView-title" style={{ width: this.props.width }}>
- Properties
- <div className="propertiesView-title-icon" onPointerDown={this.props.onDown}>
- <FontAwesomeIcon icon="times" color="black" size="sm" />
- </div>
- </div>
- <div className="propertiesView-name">
- {this.editableTitle}
- </div>
- <div className="propertiesView-settings">
- <div className="propertiesView-settings-title"
- onPointerDown={() => runInAction(() => { this.openActions = !this.openActions; })}
- style={{ backgroundColor: this.openActions ? "black" : "" }}>
- Actions
- <div className="propertiesView-settings-title-icon">
- <FontAwesomeIcon icon={this.openActions ? "caret-down" : "caret-right"} size="lg" color="white" />
+ } else {
+ const novice = Doc.UserDoc().noviceMode;
+
+ if (this.selectedDoc && !this.isPres) {
+ return <div className="propertiesView" style={{
+ width: this.props.width,
+ // overflowY: this.inActions ? "visible" : "scroll"
+ }} >
+ <div className="propertiesView-title" style={{ width: this.props.width }}>
+ Properties
+ {/* <div className="propertiesView-title-icon" onPointerDown={this.props.onDown}>
+ <FontAwesomeIcon icon="times" color="black" size="sm" />
+ </div> */}
</div>
- </div>
- {!this.openActions ? (null) :
- <div className="propertiesView-settings-content">
- <PropertiesButtons />
- </div>}
- </div>
- <div className="propertiesView-sharing">
- <div className="propertiesView-sharing-title"
- onPointerDown={() => runInAction(() => { this.openSharing = !this.openSharing; })}
- style={{ backgroundColor: this.openSharing ? "black" : "" }}>
- Sharing {"&"} Permissions
- <div className="propertiesView-sharing-title-icon">
- <FontAwesomeIcon icon={this.openSharing ? "caret-down" : "caret-right"} size="lg" color="white" />
+ <div className="propertiesView-name">
+ {this.editableTitle}
</div>
- </div>
- {!this.openSharing ? (null) :
- <div className="propertiesView-sharing-content">
- {this.sharingTable}
- </div>}
- </div>
-
- {!this.isInk ? (null) :
- <div className="propertiesView-appearance">
- <div className="propertiesView-appearance-title"
- onPointerDown={() => runInAction(() => { this.openAppearance = !this.openAppearance; })}
- style={{ backgroundColor: this.openAppearance ? "black" : "" }}>
- Appearance
- <div className="propertiesView-appearance-title-icon">
- <FontAwesomeIcon icon={this.openAppearance ? "caret-down" : "caret-right"} size="lg" color="white" />
+ <div className="propertiesView-settings" onPointerEnter={() => runInAction(() => { this.inActions = true; })}
+ onPointerLeave={action(() => this.inActions = false)}>
+ <div className="propertiesView-settings-title"
+ onPointerDown={() => runInAction(() => { this.openActions = !this.openActions; })}
+ style={{ backgroundColor: this.openActions ? "black" : "" }}>
+ Actions
+ <div className="propertiesView-settings-title-icon">
+ <FontAwesomeIcon icon={this.openActions ? "caret-down" : "caret-right"} size="lg" color="white" />
+ </div>
+ </div>
+ {!this.openActions ? (null) :
+ <div className="propertiesView-settings-content">
+ <PropertiesButtons />
+ </div>}
+ </div>
+ <div className="propertiesView-sharing">
+ <div className="propertiesView-sharing-title"
+ onPointerDown={() => runInAction(() => { this.openSharing = !this.openSharing; })}
+ style={{ backgroundColor: this.openSharing ? "black" : "" }}>
+ Sharing {"&"} Permissions
+ <div className="propertiesView-sharing-title-icon">
+ <FontAwesomeIcon icon={this.openSharing ? "caret-down" : "caret-right"} size="lg" color="white" />
+ </div>
</div>
+ {!this.openSharing ? (null) :
+ <div className="propertiesView-sharing-content">
+ {this.sharingTable}
+ {/* <div className="change-buttons">
+ <button
+ onPointerDown={action(() => this.addButtonPressed = !this.addButtonPressed)}
+ >
+ <FontAwesomeIcon icon={fa.faPlus} size={"sm"} style={{ marginTop: -3, marginLeft: -3 }} />
+ </button>
+ <button
+ id="sharingProperties-removeUser"
+ onPointerDown={() => this.handleUserChange(this.selectedUser, false)}
+ style={{ backgroundColor: this.selectedUser ? "#121721" : "#777777" }}
+ ><FontAwesomeIcon icon={fa.faMinus} size={"sm"} style={{ marginTop: -3, marginLeft: -3 }} /></button>
+ <button onClick={() => SharingManager.Instance.open(this.selectedDocumentView!)}><FontAwesomeIcon icon={fa.faCog} size={"sm"} style={{ marginTop: -3, marginLeft: -3 }} /></button>
+ {this.addButtonPressed ?
+ // <input type="text" onKeyDown={this.handleKeyPress} /> :
+ <select onChange={e => this.handleUserChange(e.target.value, true)}>
+ <option selected disabled hidden>
+ Add users
+ </option>
+ {SharingManager.Instance.users.map(user =>
+ (<option value={user.user.email}>
+ {user.user.email}
+ </option>)
+ )}
+ {GroupManager.Instance.getAllGroups().map(group =>
+ (<option value={StrCast(group.groupName)}>
+ {StrCast(group.groupName)}
+ </option>))}
+ </select> :
+ null}
+ </div> */}
+ </div>}
</div>
- {!this.openAppearance ? (null) :
- <div className="propertiesView-appearance-content">
- {this.appearanceEditor}
+
+ {!this.isInk ? (null) :
+ <div className="propertiesView-appearance">
+ <div className="propertiesView-appearance-title"
+ onPointerDown={() => runInAction(() => { this.openAppearance = !this.openAppearance; })}
+ style={{ backgroundColor: this.openAppearance ? "black" : "" }}>
+ Appearance
+ <div className="propertiesView-appearance-title-icon">
+ <FontAwesomeIcon icon={this.openAppearance ? "caret-down" : "caret-right"} size="lg" color="white" />
+ </div>
+ </div>
+ {!this.openAppearance ? (null) :
+ <div className="propertiesView-appearance-content">
+ {this.appearanceEditor}
+ </div>}
</div>}
- </div>}
-
- {this.isInk ? <div className="propertiesView-transform">
- <div className="propertiesView-transform-title"
- onPointerDown={() => runInAction(() => { this.openTransform = !this.openTransform; })}
- style={{ backgroundColor: this.openTransform ? "black" : "" }}>
- Transform
- <div className="propertiesView-transform-title-icon">
- <FontAwesomeIcon icon={this.openTransform ? "caret-down" : "caret-right"} size="lg" color="white" />
+
+ {this.isInk ? <div className="propertiesView-transform">
+ <div className="propertiesView-transform-title"
+ onPointerDown={() => runInAction(() => { this.openTransform = !this.openTransform; })}
+ style={{ backgroundColor: this.openTransform ? "black" : "" }}>
+ Transform
+ <div className="propertiesView-transform-title-icon">
+ <FontAwesomeIcon icon={this.openTransform ? "caret-down" : "caret-right"} size="lg" color="white" />
+ </div>
+ </div>
+ {this.openTransform ? <div className="propertiesView-transform-content">
+ {this.transformEditor}
+ </div> : null}
+ </div> : null}
+
+ <div className="propertiesView-fields">
+ <div className="propertiesView-fields-title"
+ onPointerDown={() => runInAction(() => { this.openFields = !this.openFields; })}
+ style={{ backgroundColor: this.openFields ? "black" : "" }}>
+ <div className="propertiesView-fields-title-name">
+ Fields {"&"} Tags
+ <div className="propertiesView-fields-title-icon">
+ <FontAwesomeIcon icon={this.openFields ? "caret-down" : "caret-right"} size="lg" color="white" />
+ </div>
+ </div>
+ </div>
+ {!novice && this.openFields ? <div className="propertiesView-fields-checkbox">
+ {this.fieldsCheckbox}
+ <div className="propertiesView-fields-checkbox-text">Layout</div>
+ </div> : null}
+ {!this.openFields ? (null) :
+ <div className="propertiesView-fields-content">
+ {novice ? this.noviceFields : this.expandedField}
+ </div>}
</div>
- </div>
- {this.openTransform ? <div className="propertiesView-transform-content">
- {this.transformEditor}
- </div> : null}
- </div> : null}
-
- <div className="propertiesView-fields">
- <div className="propertiesView-fields-title"
- onPointerDown={() => runInAction(() => { this.openFields = !this.openFields; })}
- style={{ backgroundColor: this.openFields ? "black" : "" }}>
- <div className="propertiesView-fields-title-name">
- Fields {"&"} Tags
- <div className="propertiesView-fields-title-icon">
- <FontAwesomeIcon icon={this.openFields ? "caret-down" : "caret-right"} size="lg" color="white" />
+ <div className="propertiesView-layout">
+ <div className="propertiesView-layout-title"
+ onPointerDown={() => runInAction(() => { this.openLayout = !this.openLayout; })}
+ style={{ backgroundColor: this.openLayout ? "black" : "" }}>
+ Layout
+ <div className="propertiesView-layout-title-icon" onPointerDown={() => runInAction(() => { this.openLayout = !this.openLayout; })}>
+ <FontAwesomeIcon icon={this.openLayout ? "caret-down" : "caret-right"} size="lg" color="white" />
+ </div>
</div>
+ {this.openLayout ? <div className="propertiesView-layout-content" >{this.layoutPreview}</div> : null}
</div>
- </div>
- {!novice && this.openFields ? <div className="propertiesView-fields-checkbox">
- {this.fieldsCheckbox}
- <div className="propertiesView-fields-checkbox-text">Layout</div>
- </div> : null}
- {!this.openFields ? (null) :
- <div className="propertiesView-fields-content">
- {novice ? this.noviceFields : this.expandedField}
+ </div>;
+ }
+ if (this.isPres) {
+ const selectedItem: boolean = PresBox.Instance?._selectedArray.length > 0;
+ return <div className="propertiesView" style={{ width: this.props.width }} >
+ <div className="propertiesView-title" style={{ width: this.props.width }}>
+ Presentation
+ <div className="propertiesView-title-icon" onPointerDown={this.props.onDown}>
+ <FontAwesomeIcon icon="times" color="black" size="sm" />
+ </div>
+ </div>
+ <div className="propertiesView-name">
+ {this.editableTitle}
+ <div className="propertiesView-presSelected">
+ {PresBox.Instance?._selectedArray.length} selected
+ <div className="propertiesView-selectedList">
+ {PresBox.Instance?.listOfSelected}
+ </div>
+ </div>
+ </div>
+ {!selectedItem ? (null) : <div className="propertiesView-presTrails">
+ <div className="propertiesView-presTrails-title"
+ onPointerDown={() => runInAction(() => { this.openPresTransitions = !this.openPresTransitions; })}
+ style={{ backgroundColor: this.openPresTransitions ? "black" : "" }}>
+ &nbsp; <FontAwesomeIcon icon={"rocket"} /> &nbsp; Transitions
+ <div className="propertiesView-presTrails-title-icon">
+ <FontAwesomeIcon icon={this.openPresTransitions ? "caret-down" : "caret-right"} size="lg" color="white" />
+ </div>
+ </div>
+ {this.openPresTransitions ? <div className="propertiesView-presTrails-content">
+ {PresBox.Instance.transitionDropdown}
+ </div> : null}
</div>}
- </div>
- <div className="propertiesView-layout">
- <div className="propertiesView-layout-title"
- onPointerDown={() => runInAction(() => { this.openLayout = !this.openLayout; })}
- style={{ backgroundColor: this.openLayout ? "black" : "" }}>
- Layout
- <div className="propertiesView-layout-title-icon" onPointerDown={() => runInAction(() => { this.openLayout = !this.openLayout; })}>
- <FontAwesomeIcon icon={this.openLayout ? "caret-down" : "caret-right"} size="lg" color="white" />
+ {!selectedItem ? (null) : <div className="propertiesView-presTrails">
+ <div className="propertiesView-presTrails-title"
+ onPointerDown={() => runInAction(() => { this.openPresProgressivize = !this.openPresProgressivize; })}
+ style={{ backgroundColor: this.openPresProgressivize ? "black" : "" }}>
+ &nbsp; <FontAwesomeIcon icon={"tasks"} /> &nbsp; Progressivize
+ <div className="propertiesView-presTrails-title-icon">
+ <FontAwesomeIcon icon={this.openPresProgressivize ? "caret-down" : "caret-right"} size="lg" color="white" />
+ </div>
+ </div>
+ {this.openPresProgressivize ? <div className="propertiesView-presTrails-content">
+ {PresBox.Instance.progressivizeDropdown}
+ </div> : null}
+ </div>}
+ {!selectedItem ? (null) : <div className="propertiesView-presTrails">
+ <div className="propertiesView-presTrails-title"
+ onPointerDown={() => runInAction(() => { this.openSlideOptions = !this.openSlideOptions; })}
+ style={{ backgroundColor: this.openSlideOptions ? "black" : "" }}>
+ &nbsp; <FontAwesomeIcon icon={"cog"} /> &nbsp; {PresBox.Instance.stringType} options
+ <div className="propertiesView-presTrails-title-icon">
+ <FontAwesomeIcon icon={this.openSlideOptions ? "caret-down" : "caret-right"} size="lg" color="white" />
+ </div>
+ </div>
+ {this.openSlideOptions ? <div className="propertiesView-presTrails-content">
+ {PresBox.Instance.optionsDropdown}
+ </div> : null}
+ </div>}
+ <div className="propertiesView-presTrails">
+ <div className="propertiesView-presTrails-title"
+ onPointerDown={() => runInAction(() => { this.openAddSlide = !this.openAddSlide; })}
+ style={{ backgroundColor: this.openAddSlide ? "black" : "" }}>
+ &nbsp; <FontAwesomeIcon icon={"plus"} /> &nbsp; Add new slide
+ <div className="propertiesView-presTrails-title-icon">
+ <FontAwesomeIcon icon={this.openAddSlide ? "caret-down" : "caret-right"} size="lg" color="white" />
+ </div>
+ </div>
+ {this.openAddSlide ? <div className="propertiesView-presTrails-content">
+ {PresBox.Instance.newDocumentDropdown}
+ </div> : null}
</div>
- </div>
- {this.openLayout ? <div className="propertiesView-layout-content">{this.layoutPreview}</div> : null}
- </div>
- </div>;
+ <div className="propertiesView-sharing">
+ <div className="propertiesView-sharing-title"
+ onPointerDown={() => runInAction(() => { this.openSharing = !this.openSharing; })}
+ style={{ backgroundColor: this.openSharing ? "black" : "" }}>
+ Sharing {"&"} Permissions
+ <div className="propertiesView-sharing-title-icon">
+ <FontAwesomeIcon icon={this.openSharing ? "caret-down" : "caret-right"} size="lg" color="white" />
+ </div>
+ </div>
+ {this.openSharing ? <div className="propertiesView-sharing-content">
+ {this.sharingTable}
+ </div> : null}
+ </div>
+ </div>;
+ }
+ }
}
-} \ No newline at end of file
+} \ No newline at end of file