aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/util/CurrentUserUtils.ts11
-rw-r--r--src/client/views/MainView.tsx142
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx1
-rw-r--r--src/client/views/collections/CollectionMenu.tsx6
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx188
-rw-r--r--src/client/views/collections/collectionFreeForm/PropertiesView.tsx8
-rw-r--r--src/client/views/nodes/AudioBox.tsx1
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx8
-rw-r--r--src/client/views/nodes/PresBox.scss32
-rw-r--r--src/client/views/nodes/PresBox.tsx369
-rw-r--r--src/client/views/presentationview/PresElementBox.scss4
-rw-r--r--src/client/views/presentationview/PresElementBox.tsx135
-rw-r--r--src/server/ApiManagers/UploadManager.ts2
13 files changed, 416 insertions, 491 deletions
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 6681b4260..c4702cafa 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -457,6 +457,8 @@ export class CurrentUserUtils {
}
+
+
// setup the "creator" buttons for the sidebar-- eg. the default set of draggable document creation tools
static async setupCreatorButtons(doc: Doc) {
let alreadyCreatedButtons: string[] = [];
@@ -847,8 +849,13 @@ export class CurrentUserUtils {
// Import sidebar is where shared documents are contained
static setupImportSidebar(doc: Doc) {
+ if (doc["sidebar-import-documents"] === undefined) {
+ doc["sidebar-import-documents"] = new PrefetchProxy(Docs.Create.StackingDocument([], { title: "Imported Documents", _showTitle: "title", _height: 300, _yMargin: 30, childDropAction: "alias" }));
+ }
if (doc["sidebar-import"] === undefined) {
- doc["sidebar-import"] = new PrefetchProxy(Docs.Create.StackingDocument([], { title: "Imported Documents", childDropAction: "alias" }));
+ const uploads = Cast(doc["sidebar-import-documents"], Doc, null) as Doc;
+ const newUpload = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("importDocument()"), toolTip: "Import external document", _backgroundColor: "black", title: "Import", icon: "upload", system: true });
+ doc["sidebar-import"] = new PrefetchProxy(Docs.Create.StackingDocument([newUpload, uploads], { title: "Imported Documents", _yMargin: 30, childDropAction: "alias" }));
}
}
@@ -975,4 +982,4 @@ Scripting.addGlobal(function createNewWorkspace() { return MainView.Instance.cre
Scripting.addGlobal(function links(doc: any) { return new List(LinkManager.Instance.getAllRelatedLinks(doc)); },
"returns all the links to the document or its annotations", "(doc: any)");
Scripting.addGlobal(function directLinks(doc: any) { return new List(LinkManager.Instance.getAllDirectLinks(doc)); },
- "returns all the links directly to the document", "(doc: any)"); \ No newline at end of file
+ "returns all the links directly to the document", "(doc: any)");
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index f13acd9a7..43afb17bf 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -66,6 +66,7 @@ import { SearchBox } from './search/SearchBox';
import { SearchUtil } from '../util/SearchUtil';
import { Networking } from '../Network';
import * as rp from 'request-promise';
+import { LinkManager } from '../util/LinkManager';
@observer
export class MainView extends React.Component {
@@ -548,7 +549,7 @@ export class MainView extends React.Component {
case "Catalog": panelDoc = Doc.UserDoc()["sidebar-catalog"] as Doc ?? undefined; break;
case "Archive": panelDoc = Doc.UserDoc()["sidebar-recentlyClosed"] as Doc ?? undefined; break;
case "Settings": SettingsManager.Instance.open(); break;
- case "Import": panelDoc = Doc.UserDoc()["sidebar-import"] as Doc ?? undefined; this.importDocument(); break;
+ case "Import": panelDoc = Doc.UserDoc()["sidebar-import"] as Doc ?? undefined; break;
case "Sharing": panelDoc = Doc.UserDoc()["sidebar-sharing"] as Doc ?? undefined; break;
case "UserDoc": panelDoc = Doc.UserDoc()["sidebar-userDoc"] as Doc ?? undefined; break;
}
@@ -563,66 +564,6 @@ export class MainView extends React.Component {
return true;
}
-
- importDocument = async () => {
- const inputRef = React.createRef<HTMLInputElement>();
- const sidebar = Cast(Doc.UserDoc()["sidebar-import"], Doc) as Doc;
- let process = '';
- let error = '';
- try {
- const col = sidebar;
- await Docs.Prototypes.initialize();
- const imgPrev = document.getElementById("img_preview");
- if (imgPrev) {
- const files: FileList | null = inputRef.current!.files;
- if (files && files.length !== 0) {
- for (let index = 0; index < files.length; ++index) {
- const file = files[index];
- const res = await Networking.UploadFilesToServer(file);
- // For each item that the user has selected
- res.map(async ({ result }) => {
- const name = file.name;
- if (result instanceof Error) {
- return;
- }
- const path = Utils.prepend(result.accessPaths.agnostic.client);
- let doc = null;
- // Case 1: File is a video
- if (file.type === "video/mp4") {
- doc = Docs.Create.VideoDocument(path, { _nativeWidth: 400, _width: 400, title: name });
- // Case 2: File is a PDF document
- } else if (file.type === "application/pdf") {
- doc = Docs.Create.PdfDocument(path, { _nativeWidth: 400, _width: 400, _fitWidth: true, title: name });
- // Case 3: File is another document type (most likely Image)
- } else {
- doc = Docs.Create.ImageDocument(path, { _nativeWidth: 400, _width: 400, title: name });
- }
- const res = await rp.get(Utils.prepend("/getUserDocumentId"));
- if (!res) {
- throw new Error("No user id returned");
- }
- const field = await DocServer.GetRefField(res);
- let pending: Opt<Doc>;
- if (field instanceof Doc) {
- pending = col;
- }
- if (pending) {
- const data = await Cast(pending.data, listSpec(Doc));
- if (data) data.push(doc);
- else pending.data = new List([doc]);
- }
- });
- }
- // Case in which the user pressed upload and no files were selected
- } else {
- process = "No file selected";
- }
- }
- } catch (error) {
- error = JSON.stringify(error);
- }
- }
-
@action
closeProperties = () => {
CurrentUserUtils.propertiesWidth = 0;
@@ -959,6 +900,81 @@ export class MainView extends React.Component {
document.addEventListener("editSuccess", onSuccess);
});
}
+
+ importDocument = () => {
+ const sidebar = Cast(Doc.UserDoc()["sidebar-import-documents"], Doc, null) as Doc;
+ const sidebarDocView = DocumentManager.Instance.getDocumentView(sidebar);
+ const input = document.createElement("input");
+ input.type = "file";
+ input.accept = ".zip, application/pdf, video/*, image/*, audio/*";
+ input.onchange = async _e => {
+ const upload = Utils.prepend("/uploadDoc");
+ const formData = new FormData();
+ const file = input.files && input.files[0];
+ if (file && file.type === 'application/zip') {
+ formData.append('file', file);
+ formData.append('remap', "true");
+ const response = await fetch(upload, { method: "POST", body: formData });
+ const json = await response.json();
+ if (json !== "error") {
+ const doc = await DocServer.GetRefField(json);
+ if (doc instanceof Doc && sidebarDocView) {
+ sidebarDocView.props.addDocument?.(doc);
+ setTimeout(() => {
+ SearchUtil.Search(`{!join from=id to=proto_i}id:link*`, true, {}).then(docs => {
+ docs.docs.forEach(d => LinkManager.Instance.addLink(d));
+ });
+ }, 2000); // need to give solr some time to update so that this query will find any link docs we've added.
+
+ }
+ }
+ } else if (input.files && input.files.length !== 0) {
+ const files: FileList | null = input.files;
+ for (let i = 0; i < files.length; i++) {
+ const file = files[i];
+ const res = await Networking.UploadFilesToServer(file);
+ res.map(async ({ result }) => {
+ const name = file.name;
+ if (result instanceof Error) {
+ return;
+ }
+ const path = Utils.prepend(result.accessPaths.agnostic.client);
+ let doc: Doc;
+ // Case 1: File is a video
+ if (file.type.includes("video")) {
+ doc = Docs.Create.VideoDocument(path, { _height: 100, title: name });
+ // Case 2: File is a PDF document
+ } else if (file.type === "application/pdf") {
+ doc = Docs.Create.PdfDocument(path, { _height: 100, _fitWidth: true, title: name });
+ // Case 3: File is an image
+ } else if (file.type.includes("image")) {
+ doc = Docs.Create.ImageDocument(path, { _height: 100, title: name });
+ // Case 4: File is an audio document
+ } else {
+ doc = Docs.Create.AudioDocument(path, { title: name });
+ }
+ const res = await rp.get(Utils.prepend("/getUserDocumentId"));
+ if (!res) {
+ throw new Error("No user id returned");
+ }
+ const field = await DocServer.GetRefField(res);
+ let pending: Opt<Doc>;
+ if (field instanceof Doc) {
+ pending = sidebar;
+ }
+ if (pending) {
+ const data = await Cast(pending.data, listSpec(Doc));
+ if (data) data.push(doc);
+ else pending.data = new List([doc]);
+ }
+ });
+ }
+ } else {
+ console.log("No file selected");
+ }
+ };
+ input.click();
+ }
}
Scripting.addGlobal(function freezeSidebar() { MainView.expandFlyout(); });
Scripting.addGlobal(function toggleComicMode() { Doc.UserDoc().fontFamily = "Comic Sans MS"; Doc.UserDoc().renderStyle = Doc.UserDoc().renderStyle === "comic" ? undefined : "comic"; });
@@ -968,4 +984,6 @@ Scripting.addGlobal(function copyWorkspace() {
Doc.AddDocToList(workspaces, "data", copiedWorkspace);
// bcz: strangely, we need a timeout to prevent exceptions/issues initializing GoldenLayout (the rendering engine for Main Container)
setTimeout(() => MainView.Instance.openWorkspace(copiedWorkspace), 0);
-}); \ No newline at end of file
+});
+Scripting.addGlobal(function importDocument() { return MainView.Instance.importDocument(); },
+ "imports files from device directly into the import sidebar");
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 754d9257a..998e41bd2 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -731,6 +731,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
if (!DocumentManager.Instance.getDocumentView(curPres)) {
CollectionDockingView.AddRightSplit(curPres);
}
+ DocumentManager.Instance.jumpToDocument(doc, false, undefined, Cast(doc.context, Doc, null));
}
}
}
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 0377944b7..33617c7ba 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -622,7 +622,7 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu
</div>
</Tooltip> : null}
{!this.isText && !this.props.isDoc ? <Tooltip key="num" title={<div className="dash-tooltip">Toggle View All</div>} placement="bottom">
- <div className="numKeyframe" style={{ backgroundColor: this.document.editing ? "#759c75" : "#c56565" }}
+ <div className="numKeyframe" style={{ color: this.document.editing ? "white" : "black", backgroundColor: this.document.editing ? "#5B9FDD" : "#AEDDF8" }}
onClick={action(() => this.document.editing = !this.document.editing)} >
{NumCast(this.document.currentFrame)}
</div>
@@ -735,8 +735,10 @@ export class CollectionStackingViewChrome extends React.Component<CollectionMenu
@action resetValue = () => { this._currentKey = this.pivotField; };
render() {
+ const doctype = this.props.docView.Document.type;
+ const isPres: boolean = (doctype === DocumentType.PRES);
return (
- <div className="collectionStackingViewChrome-cont">
+ isPres ? (null) : <div className="collectionStackingViewChrome-cont">
<div className="collectionStackingViewChrome-pivotField-cont">
<div className="collectionStackingViewChrome-pivotField-label">
GROUP BY:
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 162713c3b..b15bda87d 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1496,82 +1496,22 @@ interface CollectionFreeFormViewPannableContentsProps {
@observer
class CollectionFreeFormViewPannableContents extends React.Component<CollectionFreeFormViewPannableContentsProps>{
- private _isDraggingTL = false;
- private _isDraggingTR = false;
- private _isDraggingBR = false;
- private _isDraggingBL = false;
- private _isDragging = false;
- // private _drag = "";
-
- // onPointerDown = (e: React.PointerEvent): void => {
- // e.stopPropagation();
- // e.preventDefault();
- // if (e.button === 0) {
- // this._drag = e.currentTarget.id;
- // console.log(this._drag);
- // }
- // document.removeEventListener("pointermove", this.onPointerMove);
- // document.addEventListener("pointermove", this.onPointerMove);
- // document.removeEventListener("pointerup", this.onPointerUp);
- // document.addEventListener("pointerup", this.onPointerUp);
- // }
-
-
- // //Adds event listener so knows pointer is down and moving
- // onPointerMid = (e: React.PointerEvent): void => {
- // e.stopPropagation();
- // e.preventDefault();
- // this._isDragging = true;
- // const dragData = new DragManager.DocumentDragData([]);
- // console.log(DragManager.StartDocumentDrag([], dragData, e.clientX, e.clientY));
- // }
+ @observable private _drag: string = '';
//Adds event listener so knows pointer is down and moving
onPointerDown = (e: React.PointerEvent): void => {
e.stopPropagation();
e.preventDefault();
- const corner = document.elementFromPoint(e.clientX, e.clientY)?.id;
- if (corner) this._drag = corner;
- const rect = document.getElementById('resizable');
+ const corner = e.target as any;
+ console.log(corner.id);
+ if (corner) this._drag = corner.id;
+ const rect = document.getElementById(this._drag);
if (rect) {
console.log(this._drag);
setupMoveUpEvents(e.target, e, this.onPointerMove, (e) => { }, (e) => { });
}
}
- // //Adds event listener so knows pointer is down and moving
- // onPointerBL = (e: React.PointerEvent): void => {
- // e.stopPropagation();
- // e.preventDefault();
- // this._isDraggingBL = true;
- // document.removeEventListener("pointermove", this.onPointerMove);
- // document.addEventListener("pointermove", this.onPointerMove);
- // document.removeEventListener("pointerup", this.onPointerUp);
- // document.addEventListener("pointerup", this.onPointerUp);
- // }
-
- // //Adds event listener so knows pointer is down and moving
- // onPointerTR = (e: React.PointerEvent): void => {
- // e.stopPropagation();
- // e.preventDefault();
- // this._isDraggingTR = true;
- // document.removeEventListener("pointermove", this.onPointerMove);
- // document.addEventListener("pointermove", this.onPointerMove);
- // document.removeEventListener("pointerup", this.onPointerUp);
- // document.addEventListener("pointerup", this.onPointerUp);
- // }
-
- // //Adds event listener so knows pointer is down and moving
- // onPointerTL = (e: React.PointerEvent): void => {
- // e.stopPropagation();
- // e.preventDefault();
- // this._isDraggingTL = true;
- // document.removeEventListener("pointermove", this.onPointerMove);
- // document.addEventListener("pointermove", this.onPointerMove);
- // document.removeEventListener("pointerup", this.onPointerUp);
- // document.addEventListener("pointerup", this.onPointerUp);
- // }
-
//Removes all event listeners
onPointerUp = (e: PointerEvent): void => {
e.stopPropagation();
@@ -1581,26 +1521,13 @@ class CollectionFreeFormViewPannableContents extends React.Component<CollectionF
document.removeEventListener("pointerup", this.onPointerUp);
}
- // @action
- // pan = (e: PointerEvent | React.Touch | { moveX: number, moveY: number }): void => {
- // const scale = this.props.getLocalTransform().inverse().Scale;
- // const newPanX = Math.min((1 - 1 / scale) * this.props.nativeWidth, Math.max(0, moveX));
- // const newPanY = Math.min((1 - 1 / scale) * this.nativeHeight), Math.max(0, panY));
- // }
-
- @observable private _drag: string = '';
-
//Adjusts the value in NodeStore
@action
onPointerMove = (e: PointerEvent) => {
- const activeItem = Cast(PresBox.Instance.childDocs[PresBox.Instance.itemIndex], Doc, null);
- const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
const doc = document.getElementById('resizable');
- const rect = (e.target as any).getBoundingClientRect();
- const toNumber = (screen_delta: number, wh: number): number => {
- // console.log(screen_delta);
- // console.log(wh);
- return screen_delta + wh;
+ const rect = doc!.getBoundingClientRect();
+ const toNumber = (original: number, delta: number): number => {
+ return original + (delta * this.props.zoomScaling());
};
if (doc) {
let height = doc.offsetHeight;
@@ -1610,84 +1537,41 @@ class CollectionFreeFormViewPannableContents extends React.Component<CollectionF
switch (this._drag) {
case "": break;
case "resizer-br":
- doc.style.width = toNumber(e.clientX - rect.x, width) + 'px';
- doc.style.height = toNumber(e.clientY - rect.y, height) + 'px';
+ doc.style.width = toNumber(width, e.movementX) + 'px';
+ doc.style.height = toNumber(height, e.movementY) + 'px';
break;
case "resizer-bl":
- doc.style.width = toNumber(e.clientX - rect.x, width) + 'px';
- doc.style.height = toNumber(e.clientY - rect.y, height) + 'px';
- doc.style.left = toNumber(e.clientY - rect.y, height) + 'px';
+ doc.style.width = toNumber(width, -e.movementX) + 'px';
+ doc.style.height = toNumber(height, e.movementY) + 'px';
+ doc.style.left = toNumber(left, e.movementX) + 'px';
break;
case "resizer-tr":
- doc.style.width = toNumber(e.clientX - rect.x, width) + 'px';
- doc.style.height = toNumber(e.clientY - rect.y, height) + 'px';
- doc.style.top = toNumber(e.clientY - rect.y, top) + 'px';
+ doc.style.width = toNumber(width, -e.movementX) + 'px';
+ doc.style.height = toNumber(height, -e.movementY) + 'px';
+ doc.style.top = toNumber(top, e.movementY) + 'px';
case "resizer-tl":
- doc.style.width = toNumber(e.clientX - rect.x, width) + 'px';
- doc.style.height = toNumber(e.clientY - rect.y, height) + 'px';
- doc.style.top = toNumber(e.clientY - rect.x, top) + 'px';
- doc.style.left = toNumber(e.clientX - rect.y, left) + 'px';
+ doc.style.width = toNumber(width, -e.movementX) + 'px';
+ doc.style.height = toNumber(height, -e.movementY) + 'px';
+ doc.style.top = toNumber(top, e.movementY) + 'px';
+ doc.style.left = toNumber(left, e.movementX) + 'px';
case "resizable":
- doc.style.top = toNumber(e.clientY - rect.x, top) + 'px';
- doc.style.left = toNumber(e.clientX - rect.y, left) + 'px';
+ doc.style.top = toNumber(top, e.movementY) + 'px';
+ doc.style.left = toNumber(left, e.movementX) + 'px';
}
- this.updateList(targetDoc, activeItem["viewfinder-width-indexed"], width);
- this.updateList(targetDoc, activeItem["viewfinder-height-indexed"], height);
- this.updateList(targetDoc, activeItem["viewfinder-top-indexed"], top);
- this.updateList(targetDoc, activeItem["viewfinder-left-indexed"], left);
+ this.updateAll(height, width, top, left);
return false;
}
return true;
+ }
-
- // const activeItem = Cast(PresBox.Instance.childDocs[PresBox.Instance.itemIndex], Doc, null);
- // const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
- // const tagDocView = DocumentManager.Instance.getDocumentView(targetDoc);
- // e.stopPropagation();
- // e.preventDefault();
- // if (doc && tagDocView) {
-
- // const scale = this.props.zoomScaling();
- // const scale2 = tagDocView.childScaling();
- // const scale3 = tagDocView.props.ScreenToLocalTransform().Scale;
- // const scale1 = NumCast(targetDoc._viewScale);
- // // const scale = this.props.zoomScaling();
- // console.log("_viewScale: " + scale1);
- // console.log("_StLT: " + scale3);
- // console.log("zoomScaling: " + scale);
- // console.log("movementX: " + e.movementX);
- // console.log("movementX * scale: " + e.movementX * scale);
- // let height = doc.offsetHeight;
- // let width = doc.offsetWidth;
- // let top = doc.offsetTop;
- // let left = doc.offsetLeft;
- // switch (this._drag) {
- // case "": break;
- // case "resizer-br":
- // doc.style.height = newHeightB + 'px';
- // doc.style.width = newWidthR + 'px';
- // break;
- // case "resizer-bl":
- // doc.style.height = newHeightB + 'px';
- // doc.style.width = newWidthL + 'px';
- // doc.style.left = newLeft + 'px';
- // break;
- // case "resizer-tr":
- // doc.style.width = newWidthR + 'px';
- // doc.style.height = newHeightT + 'px';
- // doc.style.top = newTop + 'px';
- // case "resizer-tl":
- // doc.style.width = newWidthL + 'px';
- // doc.style.height = newHeightT + 'px';
- // doc.style.top = newTop + 'px';
- // doc.style.left = newLeft + 'px';
- // case "resizable":
- // doc.style.top = newTop + 'px';
- // doc.style.left = newLeft + 'px';
- // }
-
-
- // }
+ @action
+ updateAll = (width: number, height: number, top: number, left: number) => {
+ const activeItem = Cast(PresBox.Instance.childDocs[PresBox.Instance.itemIndex], Doc, null);
+ const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
+ this.updateList(targetDoc, activeItem["viewfinder-width-indexed"], width);
+ this.updateList(targetDoc, activeItem["viewfinder-height-indexed"], height);
+ this.updateList(targetDoc, activeItem["viewfinder-top-indexed"], top);
+ this.updateList(targetDoc, activeItem["viewfinder-left-indexed"], left);
}
@action
@@ -1708,10 +1592,10 @@ class CollectionFreeFormViewPannableContents extends React.Component<CollectionF
const activeItem = Cast(PresBox.Instance.childDocs[PresBox.Instance.itemIndex], Doc, null);
const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
if (activeItem && activeItem.zoomProgressivize) {
- const vfLeft: number = !activeItem ? 0 : PresBox.Instance.checkList(targetDoc, activeItem["viewfinder-left-indexed"]);
- const vfWidth: number = !activeItem ? 0 : PresBox.Instance.checkList(targetDoc, activeItem["viewfinder-width-indexed"]);
- const vfTop: number = !activeItem ? 0 : PresBox.Instance.checkList(targetDoc, activeItem["viewfinder-top-indexed"]);
- const vfHeight: number = !activeItem ? 0 : PresBox.Instance.checkList(targetDoc, activeItem["viewfinder-height-indexed"]);
+ const vfLeft: number = PresBox.Instance.checkList(targetDoc, activeItem["viewfinder-left-indexed"]);
+ const vfWidth: number = PresBox.Instance.checkList(targetDoc, activeItem["viewfinder-width-indexed"]);
+ const vfTop: number = PresBox.Instance.checkList(targetDoc, activeItem["viewfinder-top-indexed"]);
+ const vfHeight: number = PresBox.Instance.checkList(targetDoc, activeItem["viewfinder-height-indexed"]);
return (
<>
{!activeItem.editZoomProgressivize ? (null) : <div id="resizable" className="resizable" onPointerDown={this.onPointerDown} style={{ width: vfWidth, height: vfHeight, top: vfTop, left: vfLeft, position: 'absolute' }}>
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index c7edd67b3..a945ae2ba 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -963,8 +963,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
}
if (this.isPres) {
const selectedItem: boolean = PresBox.Instance?._selectedArray.length > 0;
- return <div className="propertiesView">
- <div className="propertiesView-title">
+ return <div className="propertiesView" style={{ width: this.props.width }}>
+ <div className="propertiesView-title" style={{ width: this.props.width }}>
Presentation
</div>
<div className="propertiesView-name">
@@ -1028,7 +1028,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
{PresBox.Instance.newDocumentDropdown}
</div> : null}
</div>
- <div className="propertiesView-sharing">
+ {/* <div className="propertiesView-sharing">
<div className="propertiesView-sharing-title"
onPointerDown={() => runInAction(() => { this.openSharing = !this.openSharing; })}
style={{ backgroundColor: this.openSharing ? "black" : "" }}>
@@ -1040,7 +1040,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
{this.openSharing ? <div className="propertiesView-sharing-content">
{this.sharingTable}
</div> : null}
- </div>
+ </div> */}
</div>;
}
}
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 900963eb0..011b6ff87 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -510,6 +510,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
labelScript = () => AudioBox.LabelScript;
render() {
+ AudioBox.Instance = this;
const interactive = SnappingManager.GetIsDragging() || this.active() ? "-interactive" : "";
this._first = true; // for indicating the first marker that is rendered
this.path && this._buckets.length !== 100 ? this.peaks : null; // render waveform if audio is done recording
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index d11a10df8..52f6a66c8 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -132,7 +132,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
}
- public static updateKeyframe(docs: Doc[], time: number) {
+ public static updateKeyframe(docs: Doc[], time: number, targetDoc?: Doc) {
const timecode = Math.round(time);
docs.forEach(doc => {
const xindexed = Cast(doc['x-indexed'], listSpec("number"), null);
@@ -145,11 +145,11 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
xindexed?.length <= timecode + 1 && xindexed.push(undefined as any as number);
yindexed?.length <= timecode + 1 && yindexed.push(undefined as any as number);
opacityindexed?.length <= timecode + 1 && opacityindexed.push(undefined as any as number);
- if (doc.appearFrame) {
+ if (doc.appearFrame && targetDoc) {
if (doc.appearFrame === timecode + 1) {
- doc["text-color"] = "red";
+ doc["text-color"] = StrCast(targetDoc["pres-text-color"]);
} else if (doc.appearFrame < timecode + 1) {
- doc["text-color"] = "grey";
+ doc["text-color"] = StrCast(targetDoc["pres-text-viewed-color"]);
} else { doc["text-color"] = "black"; }
} else if (doc.appearFrame === 0) {
doc["text-color"] = "black";
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
index 951044c71..54accb012 100644
--- a/src/client/views/nodes/PresBox.scss
+++ b/src/client/views/nodes/PresBox.scss
@@ -3,6 +3,7 @@ $dark-blue: #5B9FDD;
$light-background: #ececec;
.presBox-cont {
+ cursor: auto;
position: absolute;
display: block;
pointer-events: inherit;
@@ -50,6 +51,7 @@ $light-background: #ececec;
background-color: #323232;
.toolbar-button {
+ cursor: pointer;
margin-left: 10px;
margin-right: 10px;
letter-spacing: 0;
@@ -168,6 +170,7 @@ $light-background: #ececec;
grid-template-rows: 10px 10px;
.ribbon-propertyUpDownItem {
+ cursor: pointer;
color: white;
display: flex;
justify-content: center;
@@ -315,6 +318,7 @@ $light-background: #ececec;
}
.numKeyframe {
+ cursor: pointer;
font-size: 10;
font-weight: 600;
position: relative;
@@ -345,6 +349,7 @@ $light-background: #ececec;
.ribbon-final-button {
+ cursor: pointer;
position: relative;
font-size: 11;
font-weight: normal;
@@ -363,7 +368,13 @@ $light-background: #ececec;
background-color: #979797;
}
+ .ribbon-final-button:hover {
+ transform: scale(1.05);
+ transition: all 0.4s;
+ }
+
.ribbon-final-button-hidden {
+ cursor: pointer;
position: relative;
font-size: 11;
font-weight: normal;
@@ -381,6 +392,11 @@ $light-background: #ececec;
border-radius: 10px;
background-color: black;
}
+
+ .ribbon-final-button-hidden:hover {
+ transform: scale(1.05);
+ transition: all 0.4s;
+ }
}
.selectedList {
@@ -397,6 +413,7 @@ $light-background: #ececec;
}
.ribbon-button {
+ cursor: pointer;
font-size: 10.5;
font-weight: 200;
height: 20;
@@ -452,6 +469,7 @@ $light-background: #ececec;
}
.presBox-dropdown {
+ cursor: pointer;
display: grid;
grid-template-columns: auto 20%;
position: relative;
@@ -472,6 +490,7 @@ $light-background: #ececec;
.presBox-dropdownOption {
+ cursor: pointer;
font-size: 11;
display: block;
padding-left: 10px;
@@ -492,8 +511,8 @@ $light-background: #ececec;
.presBox-dropdownOptions {
position: absolute;
- top: 24px;
- left: -1px;
+ top: 23px;
+ left: -2px;
z-index: 200;
width: 85%;
min-width: max-content;
@@ -537,6 +556,7 @@ $light-background: #ececec;
}
.dropdown-play-button {
+ cursor: pointer;
font-size: 12;
padding-left: 5px;
padding-right: 5px;
@@ -551,6 +571,7 @@ $light-background: #ececec;
}
.presBox-button-left {
+ cursor: pointer;
position: relative;
align-self: flex-start;
justify-self: flex-start;
@@ -567,6 +588,7 @@ $light-background: #ececec;
}
.presBox-button-right {
+ cursor: pointer;
position: relative;
text-align: center;
border-left: solid 1px darkgrey;
@@ -589,6 +611,7 @@ $light-background: #ececec;
}
.dropdown-play {
+ cursor: pointer;
right: 0px;
top: calc(100% + 2px);
display: none;
@@ -609,6 +632,7 @@ $light-background: #ececec;
}
.open-layout {
+ cursor: pointer;
position: relative;
display: flex;
align-items: center;
@@ -640,6 +664,7 @@ $light-background: #ececec;
}
.layout {
+ cursor: pointer;
align-self: center;
justify-self: center;
margin-top: 5;
@@ -710,6 +735,7 @@ $light-background: #ececec;
grid-template-columns: auto auto;
.presBox-viewPicker {
+ cursor: pointer;
height: 25;
position: relative;
display: inline-block;
@@ -736,6 +762,7 @@ $light-background: #ececec;
}
.presBox-button {
+ cursor: pointer;
height: 25px;
border-radius: 5px;
display: none;
@@ -828,6 +855,7 @@ $light-background: #ececec;
}
.miniPres-button {
+ cursor: pointer;
display: flex;
height: 20;
min-width: 20;
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index eb657ab02..f6f6a2333 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -23,11 +23,12 @@ import { Scripting } from "../../util/Scripting";
import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView";
import { List } from "../../../fields/List";
import { Tooltip } from "@material-ui/core";
-import { CollectionFreeFormViewChrome } from "../collections/CollectionMenu";
import { actionAsync } from "mobx-utils";
import { SelectionManager } from "../../util/SelectionManager";
import { AudioBox } from "./AudioBox";
import { DocumentView } from "./DocumentView";
+import { SketchPicker, ColorState } from "react-color";
+import { CurrentUserUtils } from "../../util/CurrentUserUtils";
type PresBoxSchema = makeInterface<[typeof documentSchema]>;
const PresBoxDocument = makeInterface(documentSchema);
@@ -63,7 +64,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
@computed get presElement() { return Cast(Doc.UserDoc().presElement, Doc, null); }
constructor(props: any) {
super(props);
- PresBox.Instance = this;
+ if (Doc.UserDoc().activePresentation = this.rootDoc) PresBox.Instance = this;
if (!this.presElement) { // create exactly one presElmentBox template to use by any and all presentations.
Doc.UserDoc().presElement = new PrefetchProxy(Docs.Create.PresElementBoxDocument({
title: "pres element template", backgroundColor: "transparent", _xMargin: 0, isTemplateDoc: true, isTemplateForField: "data"
@@ -95,8 +96,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
}
}
@computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; }
+
componentWillUnmount() {
document.removeEventListener("keydown", this.keyEvents, true);
+ this.turnOffEdit();
}
componentDidMount() {
@@ -107,13 +110,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
this.layoutDoc._gridGap = 5;
}
- onComponentUnmount() {
- document.removeEventListener("keydown", this.keyEvents, true);
- console.log("when does this happen?");
- }
-
updateCurrentPresentation = () => {
Doc.UserDoc().activePresentation = this.rootDoc;
+ PresBox.Instance = this;
}
/**
@@ -138,7 +137,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
setTimeout(() => presTargetDoc._viewTransition = undefined, 1010);
presTargetDoc.currentFrame = curFrame + 1;
if (presTargetDoc.scrollProgressivize) CollectionFreeFormDocumentView.updateScrollframe(presTargetDoc, currentFrame);
- if (presTargetDoc.presProgressivize) CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0);
+ if (presTargetDoc.presProgressivize) CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0, presTargetDoc);
+ else presTargetDoc.editing = true;
if (activeItem.zoomProgressivize) this.zoomProgressivizeNext(presTargetDoc);
// Case 2: Audio or video therefore wait to play the audio or video before moving on
} else if ((presTargetDoc.type === DocumentType.AUDIO) && !this._moveOnFromAudio && this.layoutDoc.presStatus !== 'auto') {
@@ -164,10 +164,18 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
back = () => {
this.updateCurrentPresentation();
const docAtCurrent = this.childDocs[this.itemIndex];
- if (docAtCurrent) {
+ const targetDoc = Cast(docAtCurrent.presentationTargetDoc, Doc, null);
+ const prevItem = Cast(this.childDocs[Math.max(0, this.itemIndex - 1)], Doc, null);
+ const prevTargetDoc = Cast(prevItem.presentationTargetDoc, Doc, null);
+ const lastFrame = Cast(targetDoc.lastFrame, "number", null);
+ const curFrame = NumCast(targetDoc.currentFrame);
+ if (lastFrame !== undefined && curFrame >= 1) {
+ this.prevKeyframe(targetDoc, docAtCurrent);
+ } else if (docAtCurrent) {
let prevSelected = this.itemIndex;
prevSelected = Math.max(0, prevSelected - 1);
this.gotoDocument(prevSelected, this.itemIndex);
+ if (NumCast(prevTargetDoc.lastFrame) > 0) prevTargetDoc.currentFrame = NumCast(prevTargetDoc.lastFrame)
}
}
@@ -261,12 +269,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
*/
zoomProgressivizeNext = (activeItem: Doc) => {
const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
- const srcContext = Cast(targetDoc.context, Doc, null);
+ const srcContext = Cast(targetDoc?.context, Doc, null);
const docView = DocumentManager.Instance.getDocumentView(targetDoc);
- const vfLeft: number = !activeItem ? 0 : this.checkList(targetDoc, activeItem["viewfinder-left-indexed"]);
- const vfWidth: number = !activeItem ? 0 : this.checkList(targetDoc, activeItem["viewfinder-width-indexed"]);
- const vfTop: number = !activeItem ? 0 : this.checkList(targetDoc, activeItem["viewfinder-top-indexed"]);
- const vfHeight: number = !activeItem ? 0 : this.checkList(targetDoc, activeItem["viewfinder-height-indexed"]);
+ const vfLeft = this.checkList(targetDoc, activeItem["viewfinder-left-indexed"]);
+ const vfWidth = this.checkList(targetDoc, activeItem["viewfinder-width-indexed"]);
+ const vfTop = this.checkList(targetDoc, activeItem["viewfinder-top-indexed"]);
+ const vfHeight = this.checkList(targetDoc, activeItem["viewfinder-height-indexed"]);
// Case 1: document that is not a Golden Layout tab
if (srcContext) {
const srcDocView = DocumentManager.Instance.getDocumentView(srcContext);
@@ -309,7 +317,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
onHideDocument = () => {
this.childDocs.forEach((doc, index) => {
const curDoc = Cast(doc, Doc, null);
- const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null);
+ const tagDoc = Cast(curDoc.presentationTargetDoc!, Doc, null);
if (tagDoc) tagDoc.opacity = 1;
if (curDoc.presHideTillShownButton) {
if (index > this.itemIndex) {
@@ -329,33 +337,48 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
}
+
//The function that starts or resets presentaton functionally, depending on presStatus of the layoutDoc
@undoBatch
@action
startAutoPres = (startSlide: number) => {
this.updateCurrentPresentation();
- const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
- const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
+ let activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+ let targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
+ let duration = NumCast(targetDoc.presDuration) + NumCast(targetDoc.presTransition);
+ const timer = (ms: number) => {
+ return new Promise(res => this._presTimer = setTimeout(res, ms));
+ }
+ const load = async () => { // Wrap the loop into an async function for this to work
+ for (var i = startSlide; i < this.childDocs.length; i++) {
+ activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+ targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
+ if (targetDoc.presDuration && targetDoc.presTransition) {
+ duration = NumCast(targetDoc.presDuration) + NumCast(targetDoc.presTransition);
+ } else duration = 2500;
+ if (NumCast(targetDoc.lastFrame) > 0) {
+ for (var f = 0; f < NumCast(targetDoc.lastFrame); f++) {
+ await timer(duration / NumCast(targetDoc.lastFrame));
+ this.next();
+ }
+ }
+ await timer(duration); this.next(); // then the created Promise can be awaited
+ if (i === this.childDocs.length - 1) setTimeout(() => { clearTimeout(this._presTimer); if (this.layoutDoc.presStatus === 'auto') this.layoutDoc.presStatus = "manual"; }, duration);
+ }
+ }
if (this.layoutDoc.presStatus === "auto") {
- if (this._presTimer) clearInterval(this._presTimer);
+ if (this._presTimer) clearTimeout(this._presTimer);
this.layoutDoc.presStatus = "manual";
} else {
this.layoutDoc.presStatus = "auto";
this.startPresentation(startSlide);
this.gotoDocument(startSlide, this.itemIndex);
- this._presTimer = setInterval(() => {
- if (this.itemIndex + 1 < this.childDocs.length) this.next();
- else {
- clearInterval(this._presTimer);
- this.layoutDoc.presStatus = "manual";
- }
- }, targetDoc.presDuration ? NumCast(targetDoc.presDuration) + NumCast(targetDoc.presTransition) : 2000);
+ load();
}
}
//The function that resets the presentation by removing every action done by it. It also
//stops the presentaton.
- // TODO: Ensure resetPresentation is called when the presentation is closed
resetPresentation = () => {
this.updateCurrentPresentation();
this.rootDoc._itemIndex = 0;
@@ -505,20 +528,28 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
return list;
}
+ @action
+ selectPres = () => {
+ const presDocView = DocumentManager.Instance.getDocumentView(PresBox.Instance.rootDoc)!;
+ SelectionManager.SelectDoc(presDocView, false);
+ }
+
//Regular click
@action
selectElement = (doc: Doc) => {
this.gotoDocument(this.childDocs.indexOf(doc), NumCast(this.itemIndex));
+ this.selectPres();
}
//Command click
@action
multiSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement) => {
if (!this._selectedArray.includes(doc)) {
- this._selectedArray.push(this.childDocs[this.childDocs.indexOf(doc)]);
+ this._selectedArray.push(doc);
this._eleArray.push(ref);
this._dragArray.push(drag);
}
+ this.selectPres();
}
//Shift click
@@ -533,17 +564,18 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
this._dragArray.push(drag);
}
}
+ this.selectPres();
}
- // Key for when the presentaiton is active (according to Selection Manager)
+ // Key for when the presentaiton is active
@action
keyEvents = (e: KeyboardEvent) => {
let handled = false;
const anchorNode = document.activeElement as HTMLDivElement;
if (anchorNode && anchorNode.className?.includes("lm_title")) return;
if (e.keyCode === 27) { // Escape key
- if (this.layoutDoc.presStatus === "edit") this._selectedArray = [];
- else this.layoutDoc.presStatus = "edit";
+ if (this.layoutDoc.presStatus === "edit") { this._selectedArray = []; this._eleArray = []; this._dragArray = []; }
+ else this.layoutDoc.presStatus = "edit"; if (this._presTimer) clearTimeout(this._presTimer);
handled = true;
} if ((e.metaKey || e.altKey) && e.keyCode === 65) { // Ctrl-A to select all
if (this.layoutDoc.presStatus === "edit") {
@@ -551,14 +583,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
handled = true;
}
} if (e.keyCode === 37 || e.keyCode === 38) { // left(37) / a(65) / up(38) to go back
- this.back();
+ this.back(); if (this._presTimer) clearTimeout(this._presTimer);
handled = true;
} if (e.keyCode === 39 || e.keyCode === 40) { // right (39) / d(68) / down(40) to go to next
- this.next();
+ this.next(); if (this._presTimer) clearTimeout(this._presTimer);
handled = true;
} if (e.keyCode === 32) { // spacebar to 'present' or autoplay
if (this.layoutDoc.presStatus !== "edit") this.startAutoPres(0);
- else this.layoutDoc.presStatus = "manual";
+ else this.layoutDoc.presStatus = "manual"; if (this._presTimer) clearTimeout(this._presTimer);
handled = true;
}
if (e.keyCode === 8) { // delete selected items
@@ -582,23 +614,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
@action
viewPaths = async () => {
const srcContext = Cast(this.rootDoc.presCollection, Doc, null);
- if (this.pathBoolean) {
- if (srcContext) {
- this.togglePath();
- srcContext._fitToBox = false;
- srcContext._viewType = "freeform";
- srcContext.presPathView = false;
- }
- } else {
- if (srcContext) {
- this.togglePath();
- srcContext._fitToBox = true;
- srcContext._viewType = "freeform";
- srcContext.presPathView = true;
- }
+ if (this.pathBoolean && srcContext) {
+ this.togglePath();
+ srcContext.presPathView = false;
+ } else if (srcContext) {
+ this.togglePath();
+ srcContext.presPathView = true;
}
- const viewType = srcContext?._viewType;
- const fit = srcContext?._fitToBox;
}
// Adds the index in the pres path graphically
@@ -606,7 +628,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
const order: JSX.Element[] = [];
this.childDocs.forEach((doc, index) => {
const targetDoc = Cast(doc.presentationTargetDoc, Doc, null);
- const srcContext = Cast(targetDoc.context, Doc, null);
+ const srcContext = Cast(targetDoc?.context, Doc, null);
// Case A: Document is contained within the colleciton
if (this.rootDoc.presCollection === srcContext) {
order.push(
@@ -636,7 +658,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
let pathPoints = "";
this.childDocs.forEach((doc, index) => {
const targetDoc = Cast(doc.presentationTargetDoc, Doc, null);
- const srcContext = Cast(targetDoc.context, Doc, null);
+ const srcContext = Cast(targetDoc?.context, Doc, null);
if (targetDoc && this.rootDoc.presCollection === srcContext) {
const n1x = NumCast(targetDoc.x) + (NumCast(targetDoc._width) / 2);
const n1y = NumCast(targetDoc.y) + (NumCast(targetDoc._height) / 2);
@@ -689,7 +711,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
setTransitionTime = (number: String, change?: number) => {
let timeInMS = Number(number) * 1000;
if (change) timeInMS += change;
- if (timeInMS < 0) timeInMS = 100;
+ if (timeInMS < 100) timeInMS = 100;
if (timeInMS > 10000) timeInMS = 10000;
const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
@@ -700,7 +722,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
setDurationTime = (number: String, change?: number) => {
let timeInMS = Number(number) * 1000;
if (change) timeInMS += change;
- if (timeInMS < 0) timeInMS = 100;
+ if (timeInMS < 100) timeInMS = 100;
if (timeInMS > 20000) timeInMS = 20000;
const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
@@ -712,8 +734,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
if (activeItem && targetDoc) {
- let transitionSpeed = targetDoc.presTransition ? String(Number(targetDoc.presTransition) / 1000) : 0.5;
- let duration = targetDoc.presDuration ? String(Number(targetDoc.presDuration) / 1000) : 2;
+ let transitionSpeed = targetDoc.presTransition ? NumCast(targetDoc.presTransition) / 1000 : 0.5;
+ let duration = targetDoc.presDuration ? NumCast(targetDoc.presDuration) / 1000 : 2;
if (targetDoc.type === DocumentType.AUDIO) duration = NumCast(targetDoc.duration);
const effect = targetDoc.presEffect ? targetDoc.presEffect : 'None';
activeItem.presMovement = activeItem.presMovement ? activeItem.presMovement : 'Zoom';
@@ -721,9 +743,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
<div className={`presBox-ribbon ${this.transitionTools && this.layoutDoc.presStatus === "edit" ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onClick={action(e => { e.stopPropagation(); this.openMovementDropdown = false; this.openEffectDropdown = false; })}>
<div className="ribbon-box">
Movement
- <div className="presBox-dropdown" onClick={action(e => { e.stopPropagation(); this.openMovementDropdown = !this.openMovementDropdown })} style={{ borderBottomLeftRadius: this.openMovementDropdown ? 0 : 5 }}>
+ <div className="presBox-dropdown" onClick={action(e => { e.stopPropagation(); this.openMovementDropdown = !this.openMovementDropdown })} style={{ borderBottomLeftRadius: this.openMovementDropdown ? 0 : 5, border: this.openMovementDropdown ? 'solid 2px #5B9FDD' : 'solid 1px black' }}>
{activeItem.presMovement}
- <FontAwesomeIcon className='presBox-dropdownIcon' style={{ gridColumn: 2 }} icon={"angle-down"} />
+ <FontAwesomeIcon className='presBox-dropdownIcon' style={{ gridColumn: 2, color: this.openMovementDropdown ? '#5B9FDD' : 'black' }} icon={"angle-down"} />
<div className={'presBox-dropdownOptions'} id={'presBoxMovementDropdown'} onPointerDown={e => e.stopPropagation()} style={{ display: this.openMovementDropdown ? "grid" : "none" }}>
<div className={`presBox-dropdownOption ${activeItem.presMovement === 'None' ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('none')}>None</div>
<div className={`presBox-dropdownOption ${activeItem.presMovement === 'Zoom' ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('zoom')}>Pan and Zoom</div>
@@ -735,15 +757,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
<div className="presBox-subheading">Transition Speed</div>
<div className="ribbon-property">
<input className="presBox-input"
- type="text" value={transitionSpeed}
+ type="number" value={transitionSpeed}
onFocus={() => { document.removeEventListener("keydown", this.keyEvents, true); }}
- onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { if (Number(e.target.value) >= 0 && Number(e.target.value) <= 10 && !isNaN(Number(e.target.value)) || e.target.value === '') this.setTransitionTime(e.target.value) })} /> s
+ onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { this.setTransitionTime(e.target.value) })} /> s
</div>
<div className="ribbon-propertyUpDown">
- <div className="ribbon-propertyUpDownItem" onClick={() => this.setTransitionTime(String(duration), 1000)}>
+ <div className="ribbon-propertyUpDownItem" onClick={() => this.setTransitionTime(String(transitionSpeed), 1000)}>
<FontAwesomeIcon icon={"caret-up"} />
</div>
- <div className="ribbon-propertyUpDownItem" onClick={() => this.setTransitionTime(String(duration), -1000)}>
+ <div className="ribbon-propertyUpDownItem" onClick={() => this.setTransitionTime(String(transitionSpeed), -1000)}>
<FontAwesomeIcon icon={"caret-down"} />
</div>
</div>
@@ -765,9 +787,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
<div className="presBox-subheading">Slide Duration</div>
<div className="ribbon-property">
<input className="presBox-input"
- type="text" value={duration}
+ type="number" value={duration}
onFocus={() => { document.removeEventListener("keydown", this.keyEvents, true); }}
- onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { if (Number(e.target.value) >= 0 && Number(e.target.value) <= 20 && !isNaN(Number(e.target.value)) || e.target.value === '') this.setDurationTime(e.target.value) })} /> s
+ onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { this.setDurationTime(e.target.value) })} /> s
</div>
<div className="ribbon-propertyUpDown">
<div className="ribbon-propertyUpDownItem" onClick={() => this.setDurationTime(String(duration), 1000)}>
@@ -787,9 +809,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
</div>
<div className="ribbon-box">
Effects
- <div className="presBox-dropdown" onClick={action(e => { e.stopPropagation(); this.openEffectDropdown = !this.openEffectDropdown })} style={{ borderBottomLeftRadius: this.openMovementDropdown ? 0 : 5 }}>
+ <div className="presBox-dropdown" onClick={action(e => { e.stopPropagation(); this.openEffectDropdown = !this.openEffectDropdown })} style={{ borderBottomLeftRadius: this.openEffectDropdown ? 0 : 5, border: this.openEffectDropdown ? 'solid 2px #5B9FDD' : 'solid 1px black' }}>
{effect}
- <FontAwesomeIcon className='presBox-dropdownIcon' style={{ gridColumn: 2 }} icon={"angle-down"} />
+ <FontAwesomeIcon className='presBox-dropdownIcon' style={{ gridColumn: 2, color: this.openEffectDropdown ? '#5B9FDD' : 'black' }} icon={"angle-down"} />
<div className={'presBox-dropdownOptions'} id={'presBoxMovementDropdown'} style={{ display: this.openEffectDropdown ? "grid" : "none" }} onPointerDown={e => e.stopPropagation()}>
<div className={'presBox-dropdownOption'} onPointerDown={e => e.stopPropagation()} onClick={() => targetDoc.presEffect = 'None'}>None</div>
<div className={'presBox-dropdownOption'} onPointerDown={e => e.stopPropagation()} onClick={() => targetDoc.presEffect = 'Fade'}>Fade In</div>
@@ -850,6 +872,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
tagDoc.presTransition = targetDoc.presTransition;
tagDoc.presDuration = targetDoc.presDuration;
tagDoc.presEffect = targetDoc.presEffect;
+ tagDoc.presEffectDirection = targetDoc.presEffectDirection;
+ curDoc.presMovement = activeItem.presMovement;
+ curDoc.presHideTillShownButton = activeItem.presHideTillShownButton;
+ curDoc.presHideAfterButton = activeItem.presHideAfterButton;
}
});
}
@@ -882,9 +908,41 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
}
}}>Presentation pin view</div>
</div>
- <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.WEB ? "inline-flex" : "none" }}>
- <div className="ribbon-button" onClick={this.progressivizeText}>Store original website</div>
+ <div style={{ display: activeItem.presPinView ? "block" : "none" }}>
+ <div className="ribbon-doubleButton" style={{ marginRight: 10 }}>
+ <div className="presBox-subheading">Pan X</div>
+ <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}>
+ <input className="presBox-input"
+ style={{ textAlign: 'left', width: 50 }}
+ type="number" value={NumCast(activeItem.presPinViewX)}
+ onFocus={() => { document.removeEventListener("keydown", this.keyEvents, true); }}
+ onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { let val = e.target.value; activeItem.presPinViewX = Number(val); })} />
+ </div>
+ </div>
+ <div className="ribbon-doubleButton" style={{ marginRight: 10 }}>
+ <div className="presBox-subheading">Pan Y</div>
+ <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}>
+ <input className="presBox-input"
+ style={{ textAlign: 'left', width: 50 }}
+ type="number" value={NumCast(activeItem.presPinViewY)}
+ onFocus={() => { document.removeEventListener("keydown", this.keyEvents, true); }}
+ onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { let val = e.target.value; activeItem.presPinViewY = Number(val) })} />
+ </div>
+ </div>
+ <div className="ribbon-doubleButton" style={{ marginRight: 10 }}>
+ <div className="presBox-subheading">Scale</div>
+ <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}>
+ <input className="presBox-input"
+ style={{ textAlign: 'left', width: 50 }}
+ type="number" value={NumCast(activeItem.presPinViewScale)}
+ onFocus={() => { document.removeEventListener("keydown", this.keyEvents, true); }}
+ onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { let val = e.target.value; activeItem.presPinViewScale = Number(val) })} />
+ </div>
+ </div>
</div>
+ {/* <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.WEB ? "inline-flex" : "none" }}>
+ <div className="ribbon-button" onClick={this.progressivizeText}>Store original website</div>
+ </div> */}
</div>
</div>
</div >
@@ -909,11 +967,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
<div className="title" style={{ alignSelf: 'center' }}>Title</div>
<div className="content">Text goes here</div>
</div>
- {/* <div className="layout" style={{ border: this.layout === 'twoColumns' ? 'solid 2px #5b9ddd' : '' }} onClick={() => runInAction(() => { this.layout = 'twoColumns'; this.createNewSlide(this.layout); })}>
- <div className="title" style={{ alignSelf: 'center', gridColumn: '1/3' }}>Title</div>
- <div className="content" style={{ gridColumn: 1, gridRow: 2 }}>Column one text</div>
- <div className="content" style={{ gridColumn: 2, gridRow: 2 }}>Column two text</div>
- </div> */}
</div>
</div>
</div >
@@ -1043,7 +1096,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
@computed get presentDropdown() {
return (
<div className={`dropdown-play ${this.presentTools ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
- <div className="dropdown-play-button" onClick={this.updateMinimize}>
+ <div className="dropdown-play-button" onClick={() => this.updateMinimize()}>
Minimize
</div>
<div className="dropdown-play-button" onClick={(action(() => { this.layoutDoc.presStatus = "manual"; this.turnOffEdit(); }))}>
@@ -1065,7 +1118,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0);
}
CollectionFreeFormDocumentView.updateScrollframe(tagDoc, currentFrame);
- CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0);
+ CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0, tagDoc);
tagDoc.currentFrame = Math.max(0, (currentFrame || 0) + 1);
tagDoc.lastFrame = Math.max(NumCast(tagDoc.currentFrame), NumCast(tagDoc.lastFrame));
if (activeItem.zoomProgressivize) {
@@ -1116,38 +1169,52 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
case DocumentType.AUDIO: type = "Audio"; break;
case DocumentType.VID: type = "Video"; break;
case DocumentType.IMG: type = "Image"; break;
+ case DocumentType.WEB: type = "Web page"; break;
default: type = "Other node"; break;
}
}
return type;
}
+ @observable private openActiveColorPicker: boolean = false;
+ @observable private openViewedColorPicker: boolean = false;
+
+
+
@computed get progressivizeDropdown() {
const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
-
+ const activeFontColor = targetDoc["pres-text-color"] ? StrCast(targetDoc["pres-text-color"]) : "Black";
+ const viewedFontColor = targetDoc["pres-text-viewed-color"] ? StrCast(targetDoc["pres-text-viewed-color"]) : "Black";
if (activeItem && targetDoc) {
return (
<div>
<div className={`presBox-ribbon ${this.progressivizeTools && this.layoutDoc.presStatus === "edit" ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
<div className="ribbon-box">
{this.stringType} selected
- <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.COL && targetDoc._viewType === 'freeform' ? "inline-flex" : "none" }}>
- <div className="ribbon-button" style={{ backgroundColor: activeItem.presProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeChild}>Child documents</div>
- <div className="ribbon-button" style={{ display: activeItem.presProgressivize ? "flex" : "none", backgroundColor: targetDoc.editProgressivize ? "#aedef8" : "" }} onClick={this.editProgressivize}>Edit</div>
+ <div className="ribbon-doubleButton" style={{ borderTop: 'solid 1px darkgrey', display: targetDoc.type === DocumentType.COL && targetDoc._viewType === 'freeform' ? "inline-flex" : "none" }}>
+ <div className="ribbon-button" style={{ backgroundColor: activeItem.presProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeChild}>Contents</div>
+ <div className="ribbon-button" style={{ opacity: activeItem.presProgressivize ? 1 : 0.4, backgroundColor: targetDoc.editProgressivize ? "#aedef8" : "" }} onClick={this.editProgressivize}>Edit</div>
+ </div>
+ <div className="ribbon-doubleButton" style={{ display: activeItem.presProgressivize ? "inline-flex" : "none" }}>
+ <div className="presBox-subheading">Active text color</div>
+ <div className="ribbon-property" style={{ backgroundColor: activeFontColor }} onClick={action(() => { console.log("hi"); this.openActiveColorPicker = !this.openActiveColorPicker })}>
+ </div>
</div>
- <div className="ribbon-doubleButton" style={{ display: (targetDoc.type === DocumentType.COL && targetDoc._viewType === 'freeform') || targetDoc.type === DocumentType.IMG ? "inline-flex" : "none" }}>
- <div className="ribbon-button" style={{ backgroundColor: activeItem.zoomProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeZoom}>Internal zoom</div>
- <div className="ribbon-button" style={{ display: activeItem.zoomProgressivize ? "flex" : "none", backgroundColor: activeItem.editZoomProgressivize ? "#aedef8" : "" }} onClick={this.editZoomProgressivize}>Viewfinder</div>
- {/* <div className="ribbon-button" style={{ display: activeItem.zoomProgressivize ? "flex" : "none", backgroundColor: targetDoc.editSnapZoomProgressivize ? "#aedef8" : "" }} onClick={this.editSnapZoomProgressivize}>Snapshot</div> */}
+ {this.activeColorPicker}
+ <div className="ribbon-doubleButton" style={{ display: activeItem.presProgressivize ? "inline-flex" : "none" }}>
+ <div className="presBox-subheading">Viewed font color</div>
+ <div className="ribbon-property" style={{ backgroundColor: viewedFontColor }} onClick={action(() => this.openViewedColorPicker = !this.openViewedColorPicker)}>
+ </div>
</div>
- {/* <div className="ribbon-doubleButton" style={{ display: targetDoc.type === DocumentType.COL && targetDoc._viewType === 'freeform' ? "inline-flex" : "none" }}>
- <div className="ribbon-button" onClick={this.progressivizeText}>Text progressivize</div>
- <div className="ribbon-button" style={{ display: activeItem.textProgressivize ? "flex" : "none", backgroundColor: targetDoc.editTextProgressivize ? "#aedef8" : "" }} onClick={this.editTextProgressivize}>Edit</div>
+ {this.viewedColorPicker}
+ {/* <div className="ribbon-doubleButton" style={{ borderTop: 'solid 1px darkgrey', display: (targetDoc.type === DocumentType.COL && targetDoc._viewType === 'freeform') || targetDoc.type === DocumentType.IMG ? "inline-flex" : "none" }}>
+ <div className="ribbon-button" style={{ backgroundColor: activeItem.zoomProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeZoom}>Zoom</div>
+ <div className="ribbon-button" style={{ opacity: activeItem.zoomProgressivize ? 1 : 0.4, backgroundColor: activeItem.editZoomProgressivize ? "#aedef8" : "" }} onClick={this.editZoomProgressivize}>Edit</div>
</div> */}
- <div className="ribbon-doubleButton" style={{ display: targetDoc._viewType === "stacking" || targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF ? "inline-flex" : "none" }}>
- <div className="ribbon-button" style={{ backgroundColor: activeItem.scrollProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeScroll}>Scroll progressivize</div>
- <div className="ribbon-button" style={{ display: activeItem.scrollProgressivize ? "flex" : "none", backgroundColor: targetDoc.editScrollProgressivize ? "#aedef8" : "" }} onClick={this.editScrollProgressivize}>Edit</div>
+ <div className="ribbon-doubleButton" style={{ borderTop: 'solid 1px darkgrey', display: targetDoc._viewType === "stacking" || targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF ? "inline-flex" : "none" }}>
+ <div className="ribbon-button" style={{ backgroundColor: activeItem.scrollProgressivize ? "#aedef8" : "" }} onClick={this.progressivizeScroll}>Scroll</div>
+ <div className="ribbon-button" style={{ opacity: activeItem.scrollProgressivize ? 1 : 0.4, backgroundColor: targetDoc.editScrollProgressivize ? "#aedef8" : "" }} onClick={this.editScrollProgressivize}>Edit</div>
</div>
</div>
<div className="ribbon-final-box" style={{ display: activeItem.zoomProgressivize || activeItem.scrollProgressivize || activeItem.presProgressivize || activeItem.textProgressivize ? "grid" : "none" }}>
@@ -1157,7 +1224,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
<div key="back" title="back frame" className="backKeyframe" onClick={e => { e.stopPropagation(); this.prevKeyframe(targetDoc, activeItem); }}>
<FontAwesomeIcon icon={"caret-left"} size={"lg"} />
</div>
- <div key="num" title="toggle view all" className="numKeyframe" style={{ backgroundColor: targetDoc.editing ? "#5a9edd" : "#5a9edd" }}
+ <div key="num" title="toggle view all" className="numKeyframe" style={{ color: targetDoc.editing ? "white" : "black", backgroundColor: targetDoc.editing ? "#5B9FDD" : "#AEDDF8" }}
onClick={action(() => targetDoc.editing = !targetDoc.editing)} >
{NumCast(targetDoc.currentFrame)}
</div>
@@ -1167,7 +1234,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
</div>
<Tooltip title={<><div className="dash-tooltip">{"Last frame"}</div></>}><div className="ribbon-property">{NumCast(targetDoc.lastFrame)}</div></Tooltip>
</div>
- <div className="ribbon-button" style={{ height: 20, backgroundColor: "#5a9edd" }} onClick={() => console.log(" TODO: play frames")}>Play</div>
+ <div className="ribbon-button" style={{ height: 20, backgroundColor: "#AEDDF8" }} onClick={() => console.log(" TODO: play frames")}>Play</div>
</div>
</div>
</div>
@@ -1175,6 +1242,45 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
}
}
+ @undoBatch
+ @action
+ switchActive = (color: ColorState) => {
+ const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+ const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
+ const val = String(color.hex);
+ targetDoc["pres-text-color"] = val;
+ return true;
+ }
+ @undoBatch
+ @action
+ switchPresented = (color: ColorState) => {
+ const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+ const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
+ const val = String(color.hex);
+ targetDoc["pres-text-viewed-color"] = val;
+ return true;
+ }
+
+ @computed get activeColorPicker() {
+ const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+ const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
+ if (this.openActiveColorPicker) return <SketchPicker onChange={this.switchActive}
+ presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505',
+ '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B',
+ '#FFFFFF', '#f1efeb', 'transparent']}
+ color={StrCast(targetDoc["pres-text-color"])} />;
+ }
+
+ @computed get viewedColorPicker() {
+ const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+ const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
+ if (this.openViewedColorPicker) return <SketchPicker onChange={this.switchPresented}
+ presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505',
+ '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B',
+ '#FFFFFF', '#f1efeb', 'transparent']}
+ color={StrCast(targetDoc["pres-text-viewed-color"])} />;
+ }
+
turnOffEdit = () => {
this.childDocs.forEach((doc) => {
doc.editSnapZoomProgressivize = false;
@@ -1184,31 +1290,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
targetDoc.editSnapZoomProgressivize = false;
targetDoc.editZoomProgressivize = false;
targetDoc.editScrollProgressivize = false;
- if (doc.type === DocumentType.WEB) {
- doc.presWebsite = doc.data;
- }
});
}
//Toggle whether the user edits or not
@action
- editSnapZoomProgressivize = (e: React.MouseEvent) => {
- const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
- const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
- if (!targetDoc.editSnapZoomProgressivize) {
- targetDoc.editSnapZoomProgressivize = true;
- } else {
- targetDoc.editSnapZoomProgressivize = false;
- }
-
- }
-
- //Toggle whether the user edits or not
- @action
editZoomProgressivize = (e: React.MouseEvent) => {
const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
if (!targetDoc.editZoomProgressivize) {
+ if (!activeItem.zoomProgressivize) activeItem.zoomProgressivize = true; targetDoc.zoomProgressivize = true;
targetDoc.editZoomProgressivize = true;
activeItem.editZoomProgressivize = true;
} else {
@@ -1223,6 +1314,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
if (!targetDoc.editScrollProgressivize) {
+ if (!targetDoc.scrollProgressivize) { targetDoc.scrollProgressivize = true; activeItem.scrollProgressivize = true; }
targetDoc.editScrollProgressivize = true;
} else {
targetDoc.editScrollProgressivize = false;
@@ -1261,44 +1353,17 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
}
}
- //Progressivize Text nodes
- @action
- editTextProgressivize = (e: React.MouseEvent) => {
- const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
- const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
- targetDoc.currentFrame = targetDoc.lastFrame;
- if (targetDoc?.editTextProgressivize) {
- targetDoc.editTextProgressivize = false;
- } else {
- targetDoc.editTextProgressivize = true;
- }
- }
-
- @action
- progressivizeText = (e: React.MouseEvent) => {
- e.stopPropagation();
- const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
- activeItem.presProgressivize = !activeItem.presProgressivize;
- const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
- const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]);
- targetDoc.presProgressivize = !targetDoc.presProgressivize;
- if (activeItem.presProgressivize) {
- targetDoc.currentFrame = 0;
- CollectionFreeFormDocumentView.setupKeyframes(docs, docs.length, true);
- targetDoc.lastFrame = docs.length - 1;
- }
- }
-
//Progressivize Child Docs
@action
editProgressivize = (e: React.MouseEvent) => {
const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
targetDoc.currentFrame = targetDoc.lastFrame;
- if (targetDoc?.editProgressivize) {
- targetDoc.editProgressivize = false;
- } else {
+ if (!targetDoc.editProgressivize) {
+ if (!activeItem.presProgressivize) { activeItem.presProgressivize = true; targetDoc.presProgressivize = true; }
targetDoc.editProgressivize = true;
+ } else {
+ targetDoc.editProgressivize = false;
}
}
@@ -1309,6 +1374,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]);
if (!activeItem.presProgressivize) {
+ targetDoc.editing = false;
activeItem.presProgressivize = true;
targetDoc.presProgressivize = true;
targetDoc.currentFrame = 0;
@@ -1318,11 +1384,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
targetDoc.editProgressivize = false;
activeItem.presProgressivize = false;
targetDoc.presProgressivize = false;
- // docs.forEach((doc, index) => {
- // doc.appearFrame = 0;
- // });
targetDoc.currentFrame = 0;
targetDoc.lastFrame = 0;
+ targetDoc.editing = true;
}
}
@@ -1360,15 +1424,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
}
@action
- checkList = (doc: Doc, list: any) => {
+ checkList = (doc: Doc, list: any): number => {
const x: List<number> = list;
- if (x && x.length >= NumCast(doc.currentFrame) + 1) {
+ if (x && x.length >= NumCast(doc!.currentFrame) + 1) {
return x[NumCast(doc.currentFrame)];
- } else if (doc && x) {
+ } else if (x) {
x.length = NumCast(doc.currentFrame) + 1;
x[NumCast(doc.currentFrame)] = x[NumCast(doc.currentFrame) - 1];
return x[NumCast(doc.currentFrame)];
- }
+ } else return 100;
}
@computed get progressivizeChildDocs() {
@@ -1451,8 +1515,18 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
return width;
}
+ @action
+ toggleProperties = () => {
+ if (CurrentUserUtils.propertiesWidth > 0) {
+ CurrentUserUtils.propertiesWidth = 0;
+ } else {
+ CurrentUserUtils.propertiesWidth = 250;
+ }
+ }
+
@computed get toolbar() {
- const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+ const propIcon = CurrentUserUtils.propertiesWidth > 0 ? "angle-double-right" : "angle-double-left";
+ const propTitle = CurrentUserUtils.propertiesWidth > 0 ? "Close Presentation Panel" : "Open Presentation Panel";
return (
<div id="toolbarContainer" className={'presBox-toolbar'} style={{ display: this.layoutDoc.presStatus === "edit" ? "inline-flex" : "none" }}>
<Tooltip title={<><div className="dash-tooltip">{"Add new slide"}</div></>}><div className={`toolbar-button ${this.newDocumentTools ? "active" : ""}`} onClick={action(() => this.newDocumentTools = !this.newDocumentTools)}>
@@ -1471,6 +1545,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
</div>
</Tooltip>
<div className="toolbar-divider" />
+ <Tooltip title={<><div className="dash-tooltip">{propTitle}</div></>}>
+ <div className="toolbar-button" style={{ position: 'absolute', right: 4, fontSize: 16 }} onClick={this.toggleProperties}>
+ <FontAwesomeIcon className={"toolbar-thumbtack"} icon={propIcon} style={{ color: CurrentUserUtils.propertiesWidth > 0 ? '#AEDDF8' : 'white' }} />
+ </div>
+ </Tooltip>
</div>
);
}
diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss
index 1e776384a..6ee190b82 100644
--- a/src/client/views/presentationview/PresElementBox.scss
+++ b/src/client/views/presentationview/PresElementBox.scss
@@ -3,6 +3,7 @@ $dark-blue: #5B9FDD;
$light-background: #ececec;
.presElementBox-item {
+ cursor: grab;
display: grid;
grid-template-columns: max-content max-content max-content max-content;
background-color: #d5dce2;
@@ -161,6 +162,7 @@ $light-background: #ececec;
}
.presElementBox-closeIcon {
+ cursor: pointer;
position: absolute;
border-radius: 100%;
z-index: 300;
@@ -177,6 +179,7 @@ $light-background: #ececec;
}
.presElementBox-expand {
+ cursor: pointer;
position: absolute;
border-radius: 100%;
z-index: 300;
@@ -193,6 +196,7 @@ $light-background: #ececec;
}
.presElementBox-expand-selected {
+ cursor: pointer;
position: absolute;
border-radius: 100%;
right: 3px;
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index 42b43b402..a25a8ee33 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -19,6 +19,7 @@ import { PresBox } from "../nodes/PresBox";
import { DocumentType } from "../../documents/DocumentTypes";
import { Tooltip } from "@material-ui/core";
import { DragManager } from "../../util/DragManager";
+import { CurrentUserUtils } from "../../util/CurrentUserUtils";
export const presSchema = createSchema({
presentationTargetDoc: Doc,
@@ -59,111 +60,6 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
}
/**
- * The function that is called on click to turn Hiding document till press option on/off.
- * It also sets the beginning and end opacitys.
- */
- @action
- onHideDocumentUntilPressClick = (e: React.MouseEvent) => {
- e.stopPropagation();
- this.rootDoc.presHideTillShownButton = !this.rootDoc.presHideTillShownButton;
- if (!this.rootDoc.presHideTillShownButton) {
- if (this.indexInPres >= this.itemIndex && this.targetDoc) {
- this.targetDoc.opacity = 1;
- }
- } else {
- if (this.presStatus !== "edit" && this.indexInPres > this.itemIndex && this.targetDoc) {
- this.targetDoc.opacity = 0;
- }
- }
- }
-
- /**
- * The function that is called on click to turn Hiding document after presented option on/off.
- * It also makes sure that the option swithches from fade-after to this one, since both
- * can't coexist.
- */
- @action
- onHideDocumentAfterPresentedClick = (e: React.MouseEvent) => {
- e.stopPropagation();
- this.rootDoc.presHideAfterButton = !this.rootDoc.presHideAfterButton;
- if (!this.rootDoc.presHideAfterButton) {
- if (this.indexInPres <= this.itemIndex && this.targetDoc) {
- this.targetDoc.opacity = 1;
- }
- } else {
- if (this.rootDoc.presFadeButton) this.rootDoc.presFadeButton = false;
- if (this.presStatus !== "edit" && this.indexInPres < this.itemIndex && this.targetDoc) {
- this.targetDoc.opacity = 0;
- }
- }
- }
-
- @action
- progressivize = (e: React.MouseEvent) => {
- e.stopPropagation();
- this.rootDoc.presProgressivize = !this.rootDoc.presProgressivize;
- const rootTarget = Cast(this.rootDoc.presentationTargetDoc, Doc, null);
- const docs = rootTarget.type === DocumentType.COL ? DocListCast(rootTarget[Doc.LayoutFieldKey(rootTarget)]) :
- DocListCast(rootTarget[Doc.LayoutFieldKey(rootTarget) + "-annotations"]);
- if (this.rootDoc.presProgressivize) {
- rootTarget.currentFrame = 0;
- CollectionFreeFormDocumentView.setupKeyframes(docs, docs.length, true);
- rootTarget.lastFrame = docs.length - 1;
- }
- }
-
- /**
- * The function that is called on click to turn fading document after presented option on/off.
- * It also makes sure that the option swithches from hide-after to this one, since both
- * can't coexist.
- */
- @action
- onFadeDocumentAfterPresentedClick = (e: React.MouseEvent) => {
- e.stopPropagation();
- this.rootDoc.presFadeButton = !this.rootDoc.presFadeButton;
- if (!this.rootDoc.presFadeButton) {
- if (this.indexInPres <= this.itemIndex && this.targetDoc) {
- this.targetDoc.opacity = 1;
- }
- } else {
- this.rootDoc.presHideAfterButton = false;
- if (this.presStatus !== "edit" && (this.indexInPres < this.itemIndex) && this.targetDoc) {
- this.targetDoc.opacity = 0.5;
- }
- }
- }
-
- /**
- * The function that is called on click to turn navigation option of docs on/off.
- */
- @action
- onNavigateDocumentClick = (e: React.MouseEvent) => {
- e.stopPropagation();
- this.rootDoc.presNavButton = !this.rootDoc.presNavButton;
- if (this.rootDoc.presNavButton) {
- this.rootDoc.presZoomButton = false;
- if (this.itemIndex === this.indexInPres) {
- this.props.focus(this.rootDoc);
- }
- }
- }
-
- /**
- * The function that is called on click to turn zoom option of docs on/off.
- */
- @action
- onZoomDocumentClick = (e: React.MouseEvent) => {
- e.stopPropagation();
-
- this.rootDoc.presZoomButton = !this.rootDoc.presZoomButton;
- if (this.rootDoc.presZoomButton) {
- this.rootDoc.presNavButton = false;
- if (this.itemIndex === this.indexInPres) {
- this.props.focus(this.rootDoc);
- }
- }
- }
- /**
* Returns a local transformed coordinate array for given coordinates.
*/
ScreenToLocalListTransform = (xCord: number, yCord: number) => [xCord, yCord];
@@ -235,12 +131,11 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
@action
headerDown = (e: React.PointerEvent<HTMLDivElement>) => {
- const element1 = document.elementFromPoint(e.clientX, e.clientY)?.parentElement;
const element = e.target as any;
e.stopPropagation();
e.preventDefault();
- if (element) {
- if (PresBox.Instance._eleArray.includes(element)) {
+ if (element && !(e.ctrlKey || e.metaKey)) {
+ if (PresBox.Instance._eleArray.includes(this._itemRef.current!)) {
setupMoveUpEvents(this, e, this.startDrag, emptyFunction, emptyFunction);
} else {
PresBox.Instance._selectedArray = [];
@@ -303,8 +198,14 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
}
}
+ @action
+ toggleProperties = () => {
+ if (CurrentUserUtils.propertiesWidth === 0) {
+ CurrentUserUtils.propertiesWidth = 250;
+ }
+ }
+
render() {
- const treecontainer = this.props.ContainingCollectionDoc?._viewType === CollectionViewType.Tree;
const className = "presElementBox-item" + (PresBox.Instance._selectedArray.includes(this.rootDoc) ? " presElementBox-active" : "");
const pbi = "presElementBox-interaction";
return !(this.rootDoc instanceof Doc) || this.targetDoc instanceof Promise ? (null) : (
@@ -329,6 +230,14 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
PresBox.Instance._dragArray.push(this._dragRef.current!);
}
}}
+ onDoubleClick={e => {
+ this.toggleProperties();
+ this.props.focus(this.rootDoc);
+ PresBox.Instance._eleArray = [];
+ PresBox.Instance._eleArray.push(this._itemRef.current!);
+ PresBox.Instance._dragArray = [];
+ PresBox.Instance._dragArray.push(this._dragRef.current!);
+ }}
onPointerDown={this.headerDown}
onPointerUp={this.headerUp}
>
@@ -357,14 +266,6 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
<div ref={this._highlightTopRef} onPointerOver={this.onPointerTop} onPointerLeave={this.onPointerLeave} className="presElementBox-highlightTop" style={{ zIndex: 299, backgroundColor: "rgba(0,0,0,0)" }} />
<div ref={this._highlightBottomRef} onPointerOver={this.onPointerBottom} onPointerLeave={this.onPointerLeave} className="presElementBox-highlightBottom" style={{ zIndex: 299, backgroundColor: "rgba(0,0,0,0)" }} />
<div className="presElementBox-highlight" style={{ backgroundColor: PresBox.Instance._selectedArray.includes(this.rootDoc) ? "#AEDDF8" : "rgba(0,0,0,0)" }} />
- <div className="presElementBox-buttons" style={{ display: this.rootDoc.presExpandInlineButton ? "grid" : "none" }}>
- <button title="Zoom" className={pbi + (this.rootDoc.presZoomButton ? "-selected" : "")} onClick={this.onZoomDocumentClick}><FontAwesomeIcon icon={"search"} onPointerDown={e => e.stopPropagation()} /></button>
- <button title="Navigate" className={pbi + (this.rootDoc.presNavButton ? "-selected" : "")} onClick={this.onNavigateDocumentClick}><FontAwesomeIcon icon={"location-arrow"} onPointerDown={e => e.stopPropagation()} /></button>
- <button title="Hide Before" className={pbi + (this.rootDoc.presHideTillShownButton ? "-selected" : "")} onClick={this.onHideDocumentUntilPressClick}><FontAwesomeIcon icon={"file"} onPointerDown={e => e.stopPropagation()} /></button>
- <button title="Hide After" className={pbi + (this.rootDoc.presHideAfterButton ? "-selected" : "")} onClick={this.onHideDocumentAfterPresentedClick}><FontAwesomeIcon icon={"file-download"} onPointerDown={e => e.stopPropagation()} /></button>
- <button title="Progressivize" className={pbi + (this.rootDoc.presProgressivize ? "-selected" : "")} onClick={this.progressivize}><FontAwesomeIcon icon={"tasks"} onPointerDown={e => e.stopPropagation()} /></button>
- <button title="Effect" className={pbi + (this.rootDoc.presEffect ? "-selected" : "")}>E</button>
- </div>
{this.renderEmbeddedInline}
</div>
);
diff --git a/src/server/ApiManagers/UploadManager.ts b/src/server/ApiManagers/UploadManager.ts
index bd8fe97eb..e088cd2c4 100644
--- a/src/server/ApiManagers/UploadManager.ts
+++ b/src/server/ApiManagers/UploadManager.ts
@@ -279,7 +279,7 @@ function delay(ms: number) {
*
* On failure, returns undefined.
*/
-async function captureYoutubeScreenshot(targetUrl: string){
+async function captureYoutubeScreenshot(targetUrl: string) {
// const browser = await launch({ args: ['--no-sandbox', '--disable-setuid-sandbox'] });
// const page = await browser.newPage();
// // await page.setViewport({ width: 1920, height: 1080 });