aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/Documents.ts3
-rw-r--r--src/client/util/CurrentUserUtils.ts56
-rw-r--r--src/client/util/DragManager.ts2
-rw-r--r--src/client/util/SearchUtil.ts2
-rw-r--r--src/client/util/SettingsManager.scss6
-rw-r--r--src/client/views/.DS_Storebin10244 -> 10244 bytes
-rw-r--r--src/client/views/DocumentDecorations.tsx2
-rw-r--r--src/client/views/GestureOverlay.tsx14
-rw-r--r--src/client/views/InkingStroke.tsx2
-rw-r--r--src/client/views/MainView.tsx102
-rw-r--r--src/client/views/MainViewNotifs.scss20
-rw-r--r--src/client/views/MainViewNotifs.tsx38
-rw-r--r--src/client/views/OverlayView.scss2
-rw-r--r--src/client/views/OverlayView.tsx2
-rw-r--r--src/client/views/PropertiesButtons.tsx8
-rw-r--r--src/client/views/ScriptingRepl.tsx2
-rw-r--r--src/client/views/collections/CollectionDockingView.scss76
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx83
-rw-r--r--src/client/views/collections/CollectionMenu.tsx6
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx6
-rw-r--r--src/client/views/collections/CollectionView.tsx2
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx119
-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.tsx19
-rw-r--r--src/client/views/nodes/DocumentView.tsx10
-rw-r--r--src/client/views/nodes/FontIconBox.scss21
-rw-r--r--src/client/views/nodes/FontIconBox.tsx39
-rw-r--r--src/client/views/nodes/ImageBox.tsx4
-rw-r--r--src/client/views/nodes/PresBox.scss224
-rw-r--r--src/client/views/nodes/PresBox.tsx870
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx3
-rw-r--r--src/client/views/presentationview/PresElementBox.scss4
-rw-r--r--src/client/views/presentationview/PresElementBox.tsx145
-rw-r--r--src/fields/ScriptField.ts4
-rw-r--r--src/fields/documentSchemas.ts2
-rw-r--r--src/server/ApiManagers/SearchManager.ts5
-rw-r--r--src/server/ApiManagers/UploadManager.ts2
38 files changed, 1016 insertions, 898 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 5e83645ec..42ba4d2c4 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -112,6 +112,7 @@ export interface DocumentOptions {
_columnsHideIfEmpty?: boolean; // whether stacking view column headings should be hidden
isTemplateForField?: string; // the field key for which the containing document is a rendering template
isTemplateDoc?: boolean;
+ watchedDocuments?: Doc; // list of documents to "watch" in an icon doc to display a badge
targetScriptKey?: string; // where to write a template script (used by collections with click templates which need to target onClick, onDoubleClick, etc)
templates?: List<string>;
hero?: ImageField; // primary image that best represents a compound document (e.g., for a buxton device document that has multiple images)
@@ -184,7 +185,7 @@ export interface DocumentOptions {
targetContainer?: Doc; // document whose proto will be set to 'panel' as the result of a onClick click script
searchFileTypes?: List<string>; // file types allowed in a search query
strokeWidth?: number;
- stayInCollection?: boolean;// whether the document should remain in its collection when someone tries to drag and drop it elsewhere
+ _stayInCollection?: boolean;// whether the document should remain in its collection when someone tries to drag and drop it elsewhere
treeViewPreventOpen?: boolean; // ignores the treeViewOpen Doc flag which allows a treeViewItem's expand/collapse state to be independent of other views of the same document in the tree view
treeViewHideTitle?: boolean; // whether to hide the title of a tree view
treeViewHideHeaderFields?: boolean; // whether to hide the drop down options for tree view items.
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index e06dec663..2d988d322 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -23,6 +23,7 @@ import { SchemaHeaderField } from "../../fields/SchemaHeaderField";
import { DimUnit } from "../views/collections/collectionMulticolumn/CollectionMulticolumnView";
import { LabelBox } from "../views/nodes/LabelBox";
import { LinkManager } from "./LinkManager";
+import { Id } from "../../fields/FieldSymbols";
export class CurrentUserUtils {
private static curr_id: string;
@@ -457,6 +458,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[] = [];
@@ -475,7 +478,7 @@ export class CurrentUserUtils {
title,
toolTip,
ignoreClick,
- dropAction: "copy",
+ dropAction: "alias",
onDragStart: drag ? ScriptField.MakeFunction(drag) : undefined,
onClick: click ? ScriptField.MakeScript(click) : undefined,
ischecked: ischecked ? ComputedField.MakeFunction(ischecked) : undefined,
@@ -500,19 +503,20 @@ export class CurrentUserUtils {
return doc.myItemCreators as Doc;
}
- static menuBtnDescriptions(): {
- title: string, icon: string, click: string,
+ static menuBtnDescriptions(doc: Doc): {
+ title: string, icon: string, click: string, watchedDocuments?: Doc
}[] {
+ this.setupSharingSidebar(doc); // sets up the right sidebar collection for mobile upload documents and sharing
return [
- { title: "Sharing", icon: "users", click: 'scriptContext.selectMenu(self, "Sharing")' },
- { title: "Workspace", icon: "desktop", click: 'scriptContext.selectMenu(self, "Workspace")' },
- { title: "Catalog", icon: "file", click: 'scriptContext.selectMenu(self, "Catalog")' },
- { title: "Archive", icon: "archive", click: 'scriptContext.selectMenu(self, "Archive")' },
- { title: "Import", icon: "upload", click: 'scriptContext.selectMenu(self, "Import")' },
- { title: "Tools", icon: "wrench", click: 'scriptContext.selectMenu(self, "Tools")' },
- { title: "Help", icon: "question-circle", click: 'scriptContext.selectMenu(self, "Help")' },
- { title: "Settings", icon: "cog", click: 'scriptContext.selectMenu(self, "Settings")' },
- { title: "User Doc", icon: "address-card", click: 'scriptContext.selectMenu(self, "UserDoc")' },
+ { title: "Sharing", icon: "users", click: 'selectMainMenu(self)', watchedDocuments: doc["sidebar-sharing"] as Doc },
+ { title: "Workspace", icon: "desktop", click: 'selectMainMenu(self)' },
+ { title: "Catalog", icon: "file", click: 'selectMainMenu(self)' },
+ { title: "Archive", icon: "archive", click: 'selectMainMenu(self)' },
+ { title: "Import", icon: "upload", click: 'selectMainMenu(self)' },
+ { title: "Tools", icon: "wrench", click: 'selectMainMenu(self)' },
+ { title: "Help", icon: "question-circle", click: 'selectMainMenu(self)' },
+ { title: "Settings", icon: "cog", click: 'selectMainMenu(self)' },
+ { title: "User Doc", icon: "address-card", click: 'selectMainMenu(self)' },
];
}
@@ -526,16 +530,17 @@ export class CurrentUserUtils {
}
static setupMenuPanel(doc: Doc) {
if (doc.menuStack === undefined) {
- const menuBtns = CurrentUserUtils.menuBtnDescriptions().map(({ title, icon, click }) =>
+ const menuBtns = CurrentUserUtils.menuBtnDescriptions(doc).map(({ title, icon, click, watchedDocuments }) =>
Docs.Create.FontIconDocument({
icon,
iconShape: "square",
title,
_backgroundColor: "black",
- stayInCollection: true,
+ _stayInCollection: true,
childDropAction: "same",
_width: 60,
_height: 60,
+ watchedDocuments,
onClick: ScriptField.MakeScript(click, { scriptContext: "any" }), system: true
}));
const userDoc = menuBtns[menuBtns.length - 1];
@@ -722,7 +727,7 @@ export class CurrentUserUtils {
if (doc.myCatalog === undefined) {
doc.myCatalog = new PrefetchProxy(Docs.Create.SchemaDocument([], [], {
title: "CATALOG", _height: 1000, _fitWidth: true, forceActive: true, boxShadow: "0 0", treeViewPreventOpen: false,
- childDropAction: "alias", targetDropAction: "same", stayInCollection: true, treeViewOpen: true, system: true
+ childDropAction: "alias", targetDropAction: "same", _stayInCollection: true, treeViewOpen: true, system: true
}));
}
@@ -742,7 +747,7 @@ export class CurrentUserUtils {
doc.myRecentlyClosed === undefined;
if (doc.myRecentlyClosed === undefined) {
doc.myRecentlyClosed = new PrefetchProxy(Docs.Create.TreeDocument([], {
- title: "RECENTLY CLOSED", _height: 75, forceActive: true, boxShadow: "0 0", treeViewPreventOpen: false, treeViewOpen: true, stayInCollection: true, system: true
+ title: "RECENTLY CLOSED", _height: 75, forceActive: true, boxShadow: "0 0", treeViewPreventOpen: false, treeViewOpen: true, _stayInCollection: true, system: true
}));
}
// this is equivalent to using PrefetchProxies to make sure the recentlyClosed doc is ready
@@ -838,13 +843,25 @@ export class CurrentUserUtils {
}
}
- // Right sidebar is where mobile uploads are contained
+ // Sharing sidebar is where shared documents are contained
static setupSharingSidebar(doc: Doc) {
if (doc["sidebar-sharing"] === undefined) {
doc["sidebar-sharing"] = new PrefetchProxy(Docs.Create.StackingDocument([], { title: "Shared Documents", childDropAction: "alias", system: true }));
}
}
+ // 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", forceActive: true, _showTitle: "title", childDropAction: "alias", _autoHeight: true, _yMargin: 30, lockedPosition: true, _chromeStatus: "disabled" }));
+ }
+ if (doc["sidebar-import"] === undefined) {
+ 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: 20, ignoreClick: true, lockedPosition: true }));
+ }
+ }
+
static setupClickEditorTemplates(doc: Doc) {
if (doc["clickFuncs-child"] === undefined) {
@@ -909,6 +926,7 @@ export class CurrentUserUtils {
doc.fontFamily = StrCast(doc.fontFamily, "Arial");
doc.fontColor = StrCast(doc.fontColor, "black");
doc.fontHighlight = StrCast(doc.fontHighlight, "");
+ doc.defaultAclPrivate = BoolCast(doc.defaultAclPrivate, true);
doc.activeCollectionBackground = StrCast(doc.activeCollectionBackground, "white");
doc.activeCollectionNestedBackground = Cast(doc.activeCollectionNestedBackground, "string", null);
doc.noviceMode = BoolCast(doc.noviceMode, true);
@@ -917,7 +935,7 @@ export class CurrentUserUtils {
Utils.DRAG_THRESHOLD = NumCast(doc["constants-dragThreshold"]);
this.setupDefaultIconTemplates(doc); // creates a set of icon templates triggered by the document deoration icon
this.setupDocTemplates(doc); // sets up the template menu of templates
- this.setupSharingSidebar(doc); // sets up the right sidebar collection for mobile upload documents and sharing
+ this.setupImportSidebar(doc);
this.setupActiveMobileMenu(doc); // sets up the current mobile menu for Dash Mobile
this.setupMenuPanel(doc);
this.setupSearchPanel(doc);
@@ -967,4 +985,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/util/DragManager.ts b/src/client/util/DragManager.ts
index 4b1860b5c..0cca61841 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -210,7 +210,7 @@ export namespace DragManager {
docDragData.droppedDocuments =
dragData.draggedDocuments.map(d => !dragData.isSelectionMove && !dragData.userDropAction && ScriptCast(d.onDragStart) ? addAudioTag(ScriptCast(d.onDragStart).script.run({ this: d }).result) :
docDragData.dropAction === "alias" ? Doc.MakeAlias(d) :
- docDragData.dropAction === "copy" ? Doc.MakeDelegate(d) : d);
+ docDragData.dropAction === "copy" ? Doc.MakeClone(d) : d);
docDragData.dropAction !== "same" && docDragData.droppedDocuments.forEach((drop: Doc, i: number) => {
const dragProps = Cast(dragData.draggedDocuments[i].removeDropProperties, listSpec("string"), []);
const remProps = (dragData?.removeDropProperties || []).concat(Array.from(dragProps));
diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts
index 286544222..f916ac44a 100644
--- a/src/client/util/SearchUtil.ts
+++ b/src/client/util/SearchUtil.ts
@@ -38,7 +38,7 @@ export namespace SearchUtil {
query = query || "*"; //If we just have a filter query, search for * as the query
const rpquery = Utils.prepend("/dashsearch");
const replacedQuery = query.replace(/type_t:([^ )])/, (substring, arg) => `{!join from=id to=proto_i}type_t:${arg}`);
- const gotten = await rp.get(rpquery, { qs: { ...options, q: replacedQuery } });
+ const gotten = await rp.get(rpquery, { qs: { ...options, /* sort: "lastModified_d desc", */ q: replacedQuery } });
const result: IdSearchResult = gotten.startsWith("<") ? { ids: [], docs: [], numFound: 0, lines: [] } : JSON.parse(gotten);
if (!returnDocs) {
return result;
diff --git a/src/client/util/SettingsManager.scss b/src/client/util/SettingsManager.scss
index 560786400..ec513e5d5 100644
--- a/src/client/util/SettingsManager.scss
+++ b/src/client/util/SettingsManager.scss
@@ -97,6 +97,8 @@
.modes-content {
display: flex;
+ margin-left: 10px;
+ font-size: 12;
.modes-select {
// width: 170px;
@@ -112,6 +114,8 @@
.modes-playground,
.default-acl {
display: flex;
+ margin-left: 10px;
+ font-size: 12;
.playground-check,
.acl-check {
@@ -125,10 +129,12 @@
.playground-text {
color: black;
margin-right: 10px;
+ margin-top: 2;
}
.acl-text {
color: black;
+ margin-top: 2;
}
}
diff --git a/src/client/views/.DS_Store b/src/client/views/.DS_Store
index c379549d0..c6f3afa14 100644
--- a/src/client/views/.DS_Store
+++ b/src/client/views/.DS_Store
Binary files differ
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index fdf802c6a..c5e3e6752 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -616,7 +616,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
<div className="documentDecorations-contextMenu" onPointerDown={this.onSettingsDown}>
<FontAwesomeIcon size="lg" icon="cog" />
</div></Tooltip>) : canDelete ? (
- <Tooltip title={<><div className="dash-tooltip">Delete</div></>} placement="top">
+ <Tooltip title={<><div className="dash-tooltip">Close</div></>} placement="top">
<div className="documentDecorations-closeButton" onClick={this.onCloseClick}>
{/* Currently, this is set to be enabled if there is no ink selected. It might be interesting to think about minimizing ink if it's useful? -syip2*/}
<FontAwesomeIcon className="documentdecorations-times" icon={faTimes} size="lg" />
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 81bb542dd..76e786257 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -678,8 +678,8 @@ export default class GestureOverlay extends Touchable {
var top = Math.min(...ys);
const firstx = this._points[0].X;
const firsty = this._points[0].Y;
- const lastx = this._points[this._points.length - 2].X;
- const lasty = this._points[this._points.length - 2].Y;
+ var lastx = this._points[this._points.length - 2].X;
+ var lasty = this._points[this._points.length - 2].Y;
var fourth = (lastx - firstx) / 4;
if (isNaN(fourth) || fourth === 0) { fourth = 0.01; }
var m = (lasty - firsty) / (lastx - firstx);
@@ -771,11 +771,17 @@ export default class GestureOverlay extends Touchable {
break;
case "line":
+ if (Math.abs(firstx - lastx) < 20) {
+ lastx = firstx;
+ }
+ if (Math.abs(firsty - lasty) < 20) {
+ lasty = firsty;
+ }
this._points.push({ X: firstx, Y: firsty });
this._points.push({ X: firstx, Y: firsty });
- this._points.push({ X: firstx + 4 * fourth, Y: m * (firstx + 4 * fourth) + b });
- this._points.push({ X: firstx + 4 * fourth, Y: m * (firstx + 4 * fourth) + b });
+ this._points.push({ X: lastx, Y: lasty });
+ this._points.push({ X: lastx, Y: lasty });
break;
case "arrow":
const x1 = left;
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index e3390426b..41311ed86 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -43,7 +43,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
this.props.Document._backgroundColor = "rgba(0,0,0,0.7)";
this.props.Document.mixBlendMode = "hard-light";
this.props.Document.color = "#9b9b9bff";
- this.props.Document.stayInCollection = true;
+ this.props.Document._stayInCollection = true;
this.props.Document.isInkMask = true;
}
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 88777aafa..d0f543d16 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -61,6 +61,10 @@ import { Hypothesis } from '../util/HypothesisUtils';
import { WebBox } from './nodes/WebBox';
import * as ReactDOM from 'react-dom';
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';
import RichTextMenu from './nodes/formattedText/RichTextMenu';
@observer
@@ -306,11 +310,7 @@ export class MainView extends React.Component {
DocServer.Control.makeEditable();
}
}
- // if there is a pending doc, and it has new data, show it (syip: we use a timeout to prevent collection docking view from being uninitialized)
- setTimeout(async () => {
- const col = this.userDoc && await Cast(this.userDoc["sidebar-sharing"], Doc);
- col && Cast(col.data, listSpec(Doc)) && runInAction(() => MainViewNotifs.NotifsCol = col);
- }, 100);
+
return true;
}
@@ -528,22 +528,24 @@ export class MainView extends React.Component {
_lastButton: Doc | undefined;
@action
- selectMenu = (button: Doc, str: string) => {
+ selectMenu = (button: Doc) => {
+ const title = StrCast(Doc.GetProto(button).title);
this._lastButton && (this._lastButton.color = "white");
this._lastButton && (this._lastButton._backgroundColor = "");
- if (this.panelContent === str && this.flyoutWidth !== 0) {
+ if (this.panelContent === title && this.flyoutWidth !== 0) {
this.panelContent = "none";
this.flyoutWidth = 0;
} else {
let panelDoc: Doc | undefined;
- switch (this.panelContent = str) {
+ switch (this.panelContent = title) {
case "Tools": panelDoc = Doc.UserDoc()["sidebar-tools"] as Doc ?? undefined; break;
case "Workspace": panelDoc = Doc.UserDoc()["sidebar-workspaces"] as Doc ?? undefined; break;
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; break;
case "Sharing": panelDoc = Doc.UserDoc()["sidebar-sharing"] as Doc ?? undefined; break;
- case "UserDoc": panelDoc = Doc.UserDoc()["sidebar-userDoc"] as Doc ?? undefined; break;
+ case "User Doc": panelDoc = Doc.UserDoc()["sidebar-userDoc"] as Doc ?? undefined; break;
}
this.sidebarContent.proto = panelDoc;
if (panelDoc) {
@@ -607,7 +609,6 @@ export class MainView extends React.Component {
</div>
</div>
{this.dockingContent}
- <MainViewNotifs />
{this.showProperties ? (null) :
<div className="mainView-propertiesDragger" title="Properties View Dragger" onPointerDown={this.onPropertiesPointerDown}
style={{ right: rightFlyout, top: "50%" }}>
@@ -892,7 +893,84 @@ 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.multiple = true;
+ 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 selectMainMenu(doc: Doc, title: string) { MainView.Instance.selectMenu(doc); });
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"; });
Scripting.addGlobal(function copyWorkspace() {
@@ -901,4 +979,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/MainViewNotifs.scss b/src/client/views/MainViewNotifs.scss
deleted file mode 100644
index 92d7d6ee3..000000000
--- a/src/client/views/MainViewNotifs.scss
+++ /dev/null
@@ -1,20 +0,0 @@
-.mainNotifs-container {
- position:absolute;
- z-index: 1000;
- top: 12px;
-
- .mainNotifs-badge {
- position: absolute;
- top: -10px;
- right: -10px;
- color: white;
- background: #f44b42;
- font-weight: 300;
- border-radius: 100%;
- width: 25px;
- height: 25px;
- text-align: center;
- padding-top: 4px;
- font-size: 12px;
- }
-} \ No newline at end of file
diff --git a/src/client/views/MainViewNotifs.tsx b/src/client/views/MainViewNotifs.tsx
deleted file mode 100644
index 89006ebc8..000000000
--- a/src/client/views/MainViewNotifs.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import { observable } from 'mobx';
-import { observer } from 'mobx-react';
-import "normalize.css";
-import * as React from 'react';
-import { Doc, DocListCast, Opt } from '../../fields/Doc';
-import { returnFalse, setupMoveUpEvents } from '../../Utils';
-import { DragManager } from '../util/DragManager';
-import "./MainViewNotifs.scss";
-import { MainView } from './MainView';
-import { NumCast } from '../../fields/Types';
-
-
-@observer
-export class MainViewNotifs extends React.Component {
- @observable static NotifsCol: Opt<Doc>;
- _notifsRef = React.createRef<HTMLDivElement>();
-
- onPointerDown = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e,
- (e: PointerEvent) => {
- const dragData = new DragManager.DocumentDragData([MainViewNotifs.NotifsCol!]);
- DragManager.StartDocumentDrag([this._notifsRef.current!], dragData, e.x, e.y);
- return true;
- },
- returnFalse,
- () => MainViewNotifs.NotifsCol && MainView.Instance.selectMenu(MainViewNotifs.NotifsCol, "Sharing"));
- }
-
- render() {
- const length = MainViewNotifs.NotifsCol ? DocListCast(MainViewNotifs.NotifsCol.data).length : 0;
- return <div className="mainNotifs-container" style={{ width: 15, height: 15, top: 12 + NumCast(MainViewNotifs.NotifsCol?.position) * 60 }} ref={this._notifsRef}>
- <button className="mainNotifs-badge" style={length > 0 ? { "display": "initial" } : { "display": "none" }}
- onPointerDown={this.onPointerDown} >
- {length}
- </button>
- </div>;
- }
-}
diff --git a/src/client/views/OverlayView.scss b/src/client/views/OverlayView.scss
index 09a349012..555f4298d 100644
--- a/src/client/views/OverlayView.scss
+++ b/src/client/views/OverlayView.scss
@@ -44,6 +44,6 @@
}
.overlayView-doc {
- z-index: 1;
+ z-index: 9002; //so that it appears above chroma
position: absolute;
} \ No newline at end of file
diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx
index 5c3a8185c..49580cde4 100644
--- a/src/client/views/OverlayView.tsx
+++ b/src/client/views/OverlayView.tsx
@@ -182,7 +182,7 @@ export class OverlayView extends React.Component {
offsetx = NumCast(d.x) - e.clientX;
offsety = NumCast(d.y) - e.clientY;
};
- return <div className="overlayView-doc" ref={dref} key={d[Id]} onPointerDown={onPointerDown} style={{ width: NumCast(d._width), height: NumCast(d._height), transform: `translate(${d.x}px, ${d.y}px)` }}>
+ return <div className="overlayView-doc" ref={dref} key={d[Id]} onPointerDown={onPointerDown} style={{ top: d.type === 'presentation' ? 0 : undefined, width: NumCast(d._width), height: NumCast(d._height), transform: `translate(${d.x}px, ${d.y}px)` }}>
<DocumentView
Document={d}
LibraryPath={emptyPath}
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 2451ff55a..35d4f7f6e 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -416,14 +416,14 @@ export class PropertiesButtons extends React.Component<{}, {}> {
get deleteButton() {
const targetDoc = this.selectedDoc;
return !targetDoc ? (null) : <Tooltip
- title={<><div className="dash-tooltip">{"Delete Document"}</div></>} placement="top">
+ title={<><div className="dash-tooltip">Close Document</div></>} placement="top">
<div>
<div className={"propertiesButtons-linkButton-empty"}
onPointerDown={this.deleteDocument}>
{<FontAwesomeIcon className="propertiesButtons-icon"
- icon="trash-alt" size="lg" />}
+ icon="times" size="lg" />}
</div>
- <div className="propertiesButtons-title"> delete </div>
+ <div className="propertiesButtons-title"> close </div>
</div>
</Tooltip>;
}
@@ -639,7 +639,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
this.selectedDoc._backgroundColor = "rgba(0,0,0,0.7)";
this.selectedDoc.mixBlendMode = "hard-light";
this.selectedDoc.color = "#9b9b9bff";
- this.selectedDoc.stayInCollection = true;
+ this.selectedDoc._stayInCollection = true;
this.selectedDoc.isInkMask = true;
}
}
diff --git a/src/client/views/ScriptingRepl.tsx b/src/client/views/ScriptingRepl.tsx
index 1eb380e0b..db087fb23 100644
--- a/src/client/views/ScriptingRepl.tsx
+++ b/src/client/views/ScriptingRepl.tsx
@@ -104,7 +104,7 @@ export class ScriptingRepl extends React.Component {
if (ts.isParameter(node.parent)) {
// delete knownVars[node.text];
} else if (isntPropAccess && isntPropAssign && !(node.text in knownVars) && !(node.text in globalThis)) {
- const match = node.text.match(/\d([0-9]+)/);
+ const match = node.text.match(/d([0-9]+)/);
if (match) {
const m = parseInt(match[1]);
usedDocuments.push(m);
diff --git a/src/client/views/collections/CollectionDockingView.scss b/src/client/views/collections/CollectionDockingView.scss
index 4204ef5bb..6ebd5103b 100644
--- a/src/client/views/collections/CollectionDockingView.scss
+++ b/src/client/views/collections/CollectionDockingView.scss
@@ -20,82 +20,6 @@
}
}
-.miniPres:hover {
- opacity: 1;
-}
-
-.miniPres {
- position: absolute;
- overflow: hidden;
- right: 10;
- top: 10;
- opacity: 0.1;
- transition: all 0.4s;
- /* border: solid 1px; */
- color: white;
- /* box-shadow: black 0.4vw 0.4vw 0.8vw; */
-
- .miniPresOverlay {
- display: grid;
- grid-template-columns: auto auto auto auto auto auto auto auto;
- grid-template-rows: 100%;
- height: 100%;
- justify-items: center;
- align-items: center;
-
- .miniPres-button-text {
- display: flex;
- height: 20;
- font-weight: 400;
- min-width: 100%;
- border-radius: 5px;
- align-items: center;
- justify-content: center;
- transition: all 0.3s;
- }
-
- .miniPres-button-frame {
- justify-self: center;
- align-self: center;
- align-items: center;
- display: grid;
- grid-template-columns: auto auto auto;
- justify-content: space-around;
- font-size: 11;
- margin-left: 7;
- width: 30;
- height: 85%;
- background-color: rgba(91, 157, 221, 0.4);
- border-radius: 5px;
- }
-
- .miniPres-divider {
- width: 0.5px;
- height: 80%;
- border-right: solid 2px #5a5a5a;
- }
-
- .miniPres-button {
- display: flex;
- height: 20;
- min-width: 20;
- border-radius: 100%;
- align-items: center;
- justify-content: center;
- transition: all 0.3s;
- }
-
- .miniPres-button:hover {
- background-color: #5a5a5a;
- }
-
- .miniPres-button-text:hover {
- background-color: #5a5a5a;
- }
- }
-}
-
-
.lm_title {
margin-top: 3px;
border-radius: 5px;
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 22bb6e59a..43da0d3cf 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -191,31 +191,6 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
return retVal;
}
- @undoBatch
- @action
- public static ReplaceTab(document: Doc, stack: any): Opt<Doc> {
- if (!CollectionDockingView.Instance) return undefined;
- const instance = CollectionDockingView.Instance;
- const replaceTab = (doc: Doc, child: any): Opt<Doc> => {
- for (const contentItem of child.contentItems) {
- const { config, isStack, isRow, isColumn } = contentItem;
- if (isRow || isColumn || isStack) {
- const val = replaceTab(doc, contentItem);
- if (val) return val;
- } else if (config.component === "DocumentFrameRenderer" &&
- config.props.documentId === doc[Id]) {
- const alias = Doc.MakeAlias(doc);
- config.props.documentId = alias[Id];
- config.title = alias.title;
- instance.stateChanged();
- return alias;
- }
- }
- return undefined;
- };
- return replaceTab(document, instance._goldenLayout.root);
- }
-
//
// Creates a vertical split on the right side of the docking view, and then adds the Document to the right of that split
//
@@ -358,6 +333,32 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
return true;
}
+ @undoBatch
+ @action
+ public ReplaceTab = (stack: any, document: Doc, libraryPath?: Doc[]) => {
+ Doc.GetProto(document).lastOpened = new DateField;
+ const docContentConfig = CollectionDockingView.makeDocumentConfig(document, undefined, libraryPath);
+ if (stack === undefined) {
+ let stack: any = this._goldenLayout.root;
+ while (!stack.isStack) {
+ if (stack.contentItems.length) {
+ stack = stack.contentItems[0];
+ } else {
+ stack.addChild({ type: 'stack', content: [docContentConfig] });
+ stack = undefined;
+ break;
+ }
+ }
+ if (stack) {
+ stack.addChild(docContentConfig);
+ }
+ } else {
+ stack.addChild(docContentConfig, undefined);
+ }
+ this.layoutChanged();
+ return true;
+ }
+
setupGoldenLayout() {
const config = StrCast(this.props.Document.dockingConfig);
if (config) {
@@ -727,9 +728,11 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
pinDoc.presZoomButton = true;
pinDoc.context = curPres;
Doc.AddDocToList(curPres, "data", pinDoc);
+ if (curPres.expandBoolean) pinDoc.presExpandInlineButton = true;
if (!DocumentManager.Instance.getDocumentView(curPres)) {
CollectionDockingView.AddRightSplit(curPres);
}
+ DocumentManager.Instance.jumpToDocument(doc, false, undefined, Cast(doc.context, Doc, null));
}
}
}
@@ -837,12 +840,8 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
} else if (location === "close") {
return CollectionDockingView.CloseRightSplit(doc);
} else if (location === "replace") {
- const alias = CollectionDockingView.ReplaceTab(doc, this._stack);
- if (alias) {
- runInAction(() => this._document = alias);
- return true;
- }
- return false;
+ CollectionDockingView.UseRightSplit(doc);
+ return true;
} else {// if (location === "inPlace") {
return CollectionDockingView.Instance.AddTab(this._stack, doc, libraryPath);
}
@@ -873,26 +872,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
const currentFrame = Cast(presTargetDoc.currentFrame, "number", null);
return currentFrame;
}
- renderMiniPres() {
- return (
- <div className="miniPres"
- style={{ width: 250, height: 30, background: '#323232' }}
- >
- {<div className="miniPresOverlay">
- <div className="miniPres-button" onClick={PresBox.Instance.back}><FontAwesomeIcon icon={"arrow-left"} /></div>
- <div className="miniPres-button" onClick={() => PresBox.Instance.startAutoPres(PresBox.Instance.itemIndex)}><FontAwesomeIcon icon={PresBox.Instance.layoutDoc.presStatus === "auto" ? "pause" : "play"} /></div>
- <div className="miniPres-button" onClick={PresBox.Instance.next}><FontAwesomeIcon icon={"arrow-right"} /></div>
- <div className="miniPres-divider"></div>
- <div className="miniPres-button-text">
- Slide {PresBox.Instance.itemIndex + 1} / {PresBox.Instance.childDocs.length}
- {PresBox.Instance.playButtonFrames}
- </div>
- <div className="miniPres-divider"></div>
- <div className="miniPres-button-text" onClick={PresBox.Instance.updateMinimize}>EXIT</div>
- </div>}
- </div>
- );
- }
+
renderMiniMap() {
return <div className="miniMap" style={{
width: this.returnMiniSize(), height: this.returnMiniSize(), background: StrCast(this._document!._backgroundColor,
@@ -975,7 +955,6 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
ContainingCollectionView={undefined}
ContainingCollectionDoc={undefined} />
{document._viewType === CollectionViewType.Freeform && !this._document?.hideMinimap ? this.renderMiniMap() : (null)}
- {document._viewType === CollectionViewType.Freeform && this._document?.miniPres ? this.renderMiniPres() : (null)}
</>;
}
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 823c2f9b0..5119ff6c9 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -623,7 +623,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>
@@ -736,8 +736,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/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index b27af66ba..2b7ae4338 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -4,7 +4,7 @@ import { CursorProperty } from "csstype";
import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx";
import { observer } from "mobx-react";
import Switch from 'rc-switch';
-import { DataSym, Doc, HeightSym, WidthSym, DocListCastAsync } from "../../../fields/Doc";
+import { DataSym, Doc, HeightSym, WidthSym } from "../../../fields/Doc";
import { collectionSchema, documentSchema } from "../../../fields/documentSchemas";
import { Id } from "../../../fields/FieldSymbols";
import { List } from "../../../fields/List";
@@ -299,10 +299,6 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument)
const srcInd = docs.indexOf(doc);
docs.splice(srcInd, 1);
docs.splice((targInd > srcInd ? targInd - 1 : targInd) + plusOne, 0, doc);
- DocListCastAsync(docs).then(resolvedDocs => {
- const pos = resolvedDocs?.findIndex(shareDoc => shareDoc.icon === "users") || 0; // hopefully find out if the sharing doc has been moved
- if (MainViewNotifs.NotifsCol && pos !== -1) MainViewNotifs.NotifsCol.position = pos;
- });
} else if (i < (newDocs.length / 2)) { //glr: for some reason dragged documents are duplicated
if (targInd === -1) targInd = docs.length;
else targInd = docs.indexOf(newDocs[0]) + 1;
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 7562d7e9c..6dd21ef7f 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -222,7 +222,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
return true;
}
const first = doc instanceof Doc ? doc : doc[0];
- if (!first?.stayInCollection && addDocument !== returnFalse) {
+ if (!first?._stayInCollection && addDocument !== returnFalse) {
if (UndoManager.RunInTempBatch(() => this.removeDocument(doc))) {
const added = addDocument(doc);
if (!added) UndoManager.UndoTempBatch();
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index d521c70f2..b15bda87d 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -15,7 +15,7 @@ import { ScriptField } from "../../../../fields/ScriptField";
import { BoolCast, Cast, FieldValue, NumCast, ScriptCast, StrCast } from "../../../../fields/Types";
import { TraceMobx } from "../../../../fields/util";
import { GestureUtils } from "../../../../pen-gestures/GestureUtils";
-import { aggregateBounds, intersectRect, returnFalse, returnOne, returnZero, Utils } from "../../../../Utils";
+import { aggregateBounds, intersectRect, returnFalse, returnOne, returnZero, Utils, setupMoveUpEvents } from "../../../../Utils";
import { CognitiveServices } from "../../../cognitive_services/CognitiveServices";
import { DocServer } from "../../../DocServer";
import { Docs, DocUtils } from "../../../documents/Documents";
@@ -1496,8 +1496,123 @@ interface CollectionFreeFormViewPannableContentsProps {
@observer
class CollectionFreeFormViewPannableContents extends React.Component<CollectionFreeFormViewPannableContentsProps>{
+ @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 = 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) => { });
+ }
+ }
+
+ //Removes all event listeners
+ onPointerUp = (e: PointerEvent): void => {
+ e.stopPropagation();
+ e.preventDefault();
+ this._drag = "";
+ document.removeEventListener("pointermove", this.onPointerMove);
+ document.removeEventListener("pointerup", this.onPointerUp);
+ }
+
+ //Adjusts the value in NodeStore
+ @action
+ onPointerMove = (e: PointerEvent) => {
+ const doc = document.getElementById('resizable');
+ const rect = doc!.getBoundingClientRect();
+ const toNumber = (original: number, delta: number): number => {
+ return original + (delta * this.props.zoomScaling());
+ };
+ if (doc) {
+ 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.width = toNumber(width, e.movementX) + 'px';
+ doc.style.height = toNumber(height, e.movementY) + 'px';
+ break;
+ case "resizer-bl":
+ 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(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(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(top, e.movementY) + 'px';
+ doc.style.left = toNumber(left, e.movementX) + 'px';
+ }
+ this.updateAll(height, width, top, left);
+ return false;
+ }
+ return true;
+ }
+
+ @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
+ updateList = (doc: Doc, list: any, val: number) => {
+ const x: List<number> = list;
+ if (x && x.length >= NumCast(doc.currentFrame) + 1) {
+ x[NumCast(doc.currentFrame)] = val;
+ list = x;
+ } else if (doc && x) {
+ x.length = NumCast(doc.currentFrame) + 1;
+ x[NumCast(doc.currentFrame)] = val;
+ list = x;
+ }
+ }
+
+ // scale: NumCast(targetDoc._viewScale),
+ @computed get zoomProgressivizeContainer() {
+ 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 = 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' }}>
+ <div className='resizers'>
+ <div id="resizer-tl" className='resizer top-left' onPointerDown={this.onPointerDown}></div>
+ <div id="resizer-tr" className='resizer top-right' onPointerDown={this.onPointerDown}></div>
+ <div id="resizer-bl" className='resizer bottom-left' onPointerDown={this.onPointerDown}></div>
+ <div id="resizer-br" className='resizer bottom-right' onPointerDown={this.onPointerDown}></div>
+ </div>
+ </div>}
+ </>
+ );
+ }
+ }
+
@computed get zoomProgressivize() {
- return PresBox.Instance && this.props.zoomProgressivize ? PresBox.Instance.zoomProgressivizeContainer : (null);
+ return PresBox.Instance && this.props.zoomProgressivize ? this.zoomProgressivizeContainer : (null);
}
@computed get progressivize() {
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index 850324cc3..57e968aa7 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 289388320..900963eb0 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -85,6 +85,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps, AudioD
constructor(props: Readonly<FieldViewProps>) {
super(props);
+ AudioBox.Instance = this;
// onClick play scripts
AudioBox.RangeScript = AudioBox.RangeScript || ScriptField.MakeScript(`scriptContext.playFrom((this.audioStart), (this.audioEnd))`, { scriptContext: "any" })!;
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 63869bd50..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";
@@ -164,15 +164,16 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
setTimeout(() => docs.forEach(doc => doc.dataTransition = "inherit"), 1010);
}
- public static setupZoom(doc: Doc, zoomProgressivize: boolean = false) {
+
+ public static setupZoom(doc: Doc, targDoc: Doc, zoomProgressivize: boolean = false) {
const width = new List<number>();
const height = new List<number>();
const top = new List<number>();
const left = new List<number>();
- width.push(NumCast(doc.width));
- height.push(NumCast(doc.height));
- top.push(NumCast(doc.height) / -2);
- left.push(NumCast(doc.width) / -2);
+ width.push(NumCast(targDoc._width));
+ height.push(NumCast(targDoc._height));
+ top.push(NumCast(targDoc._height) / -2);
+ left.push(NumCast(targDoc._width) / -2);
doc["viewfinder-width-indexed"] = width;
doc["viewfinder-height-indexed"] = height;
doc["viewfinder-top-indexed"] = top;
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index a1c934e81..d92dc0ec2 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -6,15 +6,13 @@ import { Document } from '../../../fields/documentSchemas';
import { Id } from '../../../fields/FieldSymbols';
import { InkTool } from '../../../fields/InkField';
import { listSpec } from "../../../fields/Schema";
-import { SchemaHeaderField } from '../../../fields/SchemaHeaderField';
import { ScriptField } from '../../../fields/ScriptField';
import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Types";
import { GetEffectiveAcl, TraceMobx } from '../../../fields/util';
import { MobileInterface } from '../../../mobile/MobileInterface';
import { GestureUtils } from '../../../pen-gestures/GestureUtils';
-import { emptyFunction, emptyPath, OmitKeys, returnOne, returnTransparent, Utils } from "../../../Utils";
+import { emptyFunction, OmitKeys, returnOne, returnTransparent, Utils } from "../../../Utils";
import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils';
-import { ClientRecommender } from '../../ClientRecommender';
import { Docs, DocUtils } from "../../documents/Documents";
import { DocumentType } from '../../documents/DocumentTypes';
import { DocumentManager } from "../../util/DocumentManager";
@@ -22,7 +20,6 @@ import { DragManager, dropActionType } from "../../util/DragManager";
import { InteractionUtils } from '../../util/InteractionUtils';
import { LinkManager } from '../../util/LinkManager';
import { Scripting } from '../../util/Scripting';
-import { SearchUtil } from '../../util/SearchUtil';
import { SelectionManager } from "../../util/SelectionManager";
import SharingManager from '../../util/SharingManager';
import { SnappingManager } from '../../util/SnappingManager';
@@ -33,7 +30,6 @@ import { ContextMenu } from "../ContextMenu";
import { ContextMenuProps } from '../ContextMenuItem';
import { DocComponent } from "../DocComponent";
import { EditableView } from '../EditableView';
-import { KeyphraseQueryView } from '../KeyphraseQueryView';
import { DocumentContentsView } from "./DocumentContentsView";
import { DocumentLinksButton } from './DocumentLinksButton';
import "./DocumentView.scss";
@@ -767,7 +763,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
Doc.AreProtosEqual(this.props.Document, Doc.UserDoc()) && moreItems.push({ description: "Toggle Always Show Link End", event: () => Doc.UserDoc()["documentLinksButton-hideEnd"] = !Doc.UserDoc()["documentLinksButton-hideEnd"], icon: "eye" });
}
- moreItems.push({ description: "Close", event: this.deleteClicked, icon: "trash" });
+ moreItems.push({ description: "Close", event: this.deleteClicked, icon: "times" });
!more && cm.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" });
cm.moveAfter(cm.findByDescription("More...")!, cm.findByDescription("OnClick...")!);
@@ -819,7 +815,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
@computed get contents() {
const pos = this.props.relative ? "relative " : "absolute";
TraceMobx();
- return (<div style={{ width: "100%", height: "100%" }}>
+ return (<div className="documentView-contentsView" style={{ borderRadius: "inherit", width: "100%", height: "100%" }}>
<DocumentContentsView key={1}
docFilters={this.props.docFilters}
ContainingCollectionView={this.props.ContainingCollectionView}
diff --git a/src/client/views/nodes/FontIconBox.scss b/src/client/views/nodes/FontIconBox.scss
index 6a540269e..75bc90d7a 100644
--- a/src/client/views/nodes/FontIconBox.scss
+++ b/src/client/views/nodes/FontIconBox.scss
@@ -13,6 +13,27 @@
width: 100%;
}
+.fontIconBadge-container {
+ position:absolute;
+ z-index: 1000;
+ top: 12px;
+
+ .fontIconBadge {
+ position: absolute;
+ top: -10px;
+ right: -10px;
+ color: white;
+ background: #f44b42;
+ font-weight: 300;
+ border-radius: 100%;
+ width: 25px;
+ height: 25px;
+ text-align: center;
+ padding-top: 4px;
+ font-size: 12px;
+ }
+}
+
.menuButton-round {
border-radius: 100%;
background-color: black;
diff --git a/src/client/views/nodes/FontIconBox.tsx b/src/client/views/nodes/FontIconBox.tsx
index 168d640e9..fa21a8594 100644
--- a/src/client/views/nodes/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox.tsx
@@ -5,13 +5,15 @@ import { createSchema, makeInterface } from '../../../fields/Schema';
import { DocComponent } from '../DocComponent';
import './FontIconBox.scss';
import { FieldView, FieldViewProps } from './FieldView';
-import { StrCast, Cast } from '../../../fields/Types';
-import { Utils } from "../../../Utils";
+import { StrCast, Cast, ScriptCast } from '../../../fields/Types';
+import { Utils, setupMoveUpEvents, returnFalse, emptyFunction } from "../../../Utils";
import { runInAction, observable, reaction, IReactionDisposer } from 'mobx';
-import { Doc } from '../../../fields/Doc';
+import { Doc, DocListCast } from '../../../fields/Doc';
import { ContextMenu } from '../ContextMenu';
import { ScriptField } from '../../../fields/ScriptField';
import { Tooltip } from '@material-ui/core';
+import { MainViewNotifs } from '../MainViewNotifs';
+import { DragManager } from '../../util/DragManager';
const FontIconSchema = createSchema({
icon: "string",
});
@@ -73,6 +75,7 @@ export class FontIconBox extends DocComponent<FieldViewProps, FontIconDocument>(
{<FontAwesomeIcon className={`menuButton-icon-${shape}`} icon={StrCast(this.dataDoc.icon, "user") as any} color={color}
size={this.layoutDoc.iconShape === "square" ? "sm" : "lg"} />}
{!label ? (null) : <div className="fontIconBox-label" style={{ color, backgroundColor }}> {label} </div>}
+ {this.props.Document.watchedDocuments ? <FontIconBadge collection={Cast(this.props.Document.watchedDocuments, Doc, null)} /> : (null)}
</div>
</button>;
return !this.layoutDoc.toolTip ? button :
@@ -80,4 +83,34 @@ export class FontIconBox extends DocComponent<FieldViewProps, FontIconDocument>(
{button}
</Tooltip>;
}
+}
+
+interface FontIconBadgeProps {
+ collection: Doc;
+}
+
+@observer
+export class FontIconBadge extends React.Component<FontIconBadgeProps> {
+ _notifsRef = React.createRef<HTMLDivElement>();
+
+ onPointerDown = (e: React.PointerEvent) => {
+ setupMoveUpEvents(this, e,
+ (e: PointerEvent) => {
+ const dragData = new DragManager.DocumentDragData([this.props.collection]);
+ DragManager.StartDocumentDrag([this._notifsRef.current!], dragData, e.x, e.y);
+ return true;
+ },
+ returnFalse, emptyFunction, false);
+ }
+
+ render() {
+ if (!(this.props.collection instanceof Doc)) return (null);
+ const length = DocListCast(this.props.collection.data).length;
+ return <div className="fontIconBadge-container" style={{ width: 15, height: 15, top: 12 }} ref={this._notifsRef}>
+ <div className="fontIconBadge" style={length > 0 ? { "display": "initial" } : { "display": "none" }}
+ onPointerDown={this.onPointerDown} >
+ {length}
+ </div>
+ </div>;
+ }
} \ No newline at end of file
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index d668d332b..216c5f39e 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -158,7 +158,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD
if (field) {
const funcs: ContextMenuProps[] = [];
funcs.push({ description: "Rotate Clockwise 90", event: this.rotate, icon: "expand-arrows-alt" });
- funcs.push({ description: "Make Background", event: () => this.layoutDoc.isBackground = true, icon: "expand-arrows-alt" });
+ funcs.push({ description: "Make Background", event: () => { this.layoutDoc.isBackground = true; this.props.bringToFront?.(this.rootDoc); }, icon: "expand-arrows-alt" });
if (!Doc.UserDoc().noviceMode) {
funcs.push({ description: "Export to Google Photos", event: () => GooglePhotos.Transactions.UploadImages([this.props.Document]), icon: "caret-square-right" });
funcs.push({ description: "Copy path", event: () => Utils.CopyText(field.url.href), icon: "expand-arrows-alt" });
@@ -466,7 +466,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD
width: this.props.PanelWidth() ? undefined : `${100 / this.props.ContentScaling()}%`,
height: this.props.PanelWidth() ? undefined : `${100 / this.props.ContentScaling()}%`,
pointerEvents: this.layoutDoc.isBackground ? "none" : undefined,
- borderRadius: `${Number(StrCast(this.layoutDoc.borderRoundisng).replace("px", "")) / this.props.ContentScaling()}px`
+ borderRadius: `${Number(StrCast(this.layoutDoc.borderRounding).replace("px", "")) / this.props.ContentScaling()}px`
}} >
<CollectionFreeFormView {...this.props}
forceScaling={true}
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
index 8ee7f1e0e..c4d8f1a4f 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;
@@ -12,7 +13,7 @@ $light-background: #ececec;
width: 100%;
min-width: 20px;
height: 100%;
- min-height: 41px;
+ min-height: 35px;
letter-spacing: 2px;
overflow: hidden;
transition: 0.7s opacity ease;
@@ -50,6 +51,7 @@ $light-background: #ececec;
background-color: #323232;
.toolbar-button {
+ cursor: pointer;
margin-left: 10px;
margin-right: 10px;
letter-spacing: 0;
@@ -153,7 +155,6 @@ $light-background: #ececec;
margin-left: 5px;
margin-top: 5px;
margin-bottom: 5px;
- margin-right: 5px;
width: max-content;
justify-content: center;
align-items: center;
@@ -161,6 +162,30 @@ $light-background: #ececec;
padding-left: 10px;
}
+ .ribbon-propertyUpDown {
+ height: 20;
+ width: 20;
+ margin-top: 5px;
+ display: grid;
+ grid-template-rows: 10px 10px;
+
+ .ribbon-propertyUpDownItem {
+ cursor: pointer;
+ color: white;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 100%;
+ width: 100%;
+ background: black;
+ }
+
+ .ribbon-propertyUpDownItem:hover {
+ background: darkgrey;
+ transform: scale(1.05);
+ }
+ }
+
.presBox-subheading {
font-size: 11;
font-weight: 400;
@@ -254,6 +279,18 @@ $light-background: #ececec;
width: 100%;
}
+ .presBox-input {
+ width: 30;
+ height: 100%;
+ background: none;
+ border: none;
+ text-align: right;
+ }
+
+ .presBox-input:focus {
+ outline: none;
+ }
+
.ribbon-frameSelector {
border: black solid 1px;
width: 60px;
@@ -281,6 +318,7 @@ $light-background: #ececec;
}
.numKeyframe {
+ cursor: pointer;
font-size: 10;
font-weight: 600;
position: relative;
@@ -311,6 +349,7 @@ $light-background: #ececec;
.ribbon-final-button {
+ cursor: pointer;
position: relative;
font-size: 11;
font-weight: normal;
@@ -329,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;
@@ -347,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 {
@@ -363,6 +413,7 @@ $light-background: #ececec;
}
.ribbon-button {
+ cursor: pointer;
font-size: 10.5;
font-weight: 200;
height: 20;
@@ -399,11 +450,9 @@ $light-background: #ececec;
grid-template-rows: max-content auto;
justify-self: center;
margin-top: 10px;
- /* padding-left: 10px; */
padding-right: 10px;
letter-spacing: normal;
width: 100%;
- /* max-width: 100%; */
height: max-content;
font-weight: 500;
position: relative;
@@ -412,10 +461,36 @@ $light-background: #ececec;
border-bottom: solid 1px darkgrey;
.presBox-dropdown:hover {
- border: solid 1px #378AD8;
- border-bottom-left-radius: 0px;
+ border: solid 1px $dark-blue;
+
+ .presBox-dropdownIcon {
+ color: $dark-blue;
+ }
+ }
+
+ .presBox-dropdown {
+ cursor: pointer;
+ display: grid;
+ grid-template-columns: auto 20%;
+ position: relative;
+ border: solid 1px black;
+ background-color: $light-background;
+ border-radius: 5px;
+ font-size: 10;
+ height: 25;
+ padding-left: 5px;
+ align-items: center;
+ margin-top: 5px;
+ margin-bottom: 5px;
+ font-weight: 200;
+ width: 100%;
+ min-width: max-content;
+ max-width: 200px;
+ overflow: visible;
+
.presBox-dropdownOption {
+ cursor: pointer;
font-size: 11;
display: block;
padding-left: 10px;
@@ -431,13 +506,13 @@ $light-background: #ececec;
.presBox-dropdownOption.active {
position: relative;
- background-color: #aedef8;
+ background-color: $light-blue;
}
.presBox-dropdownOptions {
position: absolute;
- top: 24px;
- left: -1px;
+ top: 23px;
+ left: -2px;
z-index: 200;
width: 85%;
min-width: max-content;
@@ -449,34 +524,6 @@ $light-background: #ececec;
}
.presBox-dropdownIcon {
- color: #378AD8;
- }
- }
-
- .presBox-dropdown {
- display: grid;
- grid-template-columns: auto 20%;
- position: relative;
- border: solid 1px black;
- background-color: $light-background;
- border-radius: 5px;
- font-size: 10;
- height: 25;
- padding-left: 5px;
- align-items: center;
- margin-top: 5px;
- margin-bottom: 5px;
- font-weight: 200;
- width: 100%;
- min-width: max-content;
- max-width: 200px;
- overflow: visible;
-
- .presBox-dropdownOptions {
- display: none;
- }
-
- .presBox-dropdownIcon {
position: relative;
color: black;
align-self: center;
@@ -509,6 +556,7 @@ $light-background: #ececec;
}
.dropdown-play-button {
+ cursor: pointer;
font-size: 12;
padding-left: 5px;
padding-right: 5px;
@@ -523,6 +571,7 @@ $light-background: #ececec;
}
.presBox-button-left {
+ cursor: pointer;
position: relative;
align-self: flex-start;
justify-self: flex-start;
@@ -539,6 +588,7 @@ $light-background: #ececec;
}
.presBox-button-right {
+ cursor: pointer;
position: relative;
text-align: center;
border-left: solid 1px darkgrey;
@@ -561,6 +611,7 @@ $light-background: #ececec;
}
.dropdown-play {
+ cursor: pointer;
right: 0px;
top: calc(100% + 2px);
display: none;
@@ -581,6 +632,7 @@ $light-background: #ececec;
}
.open-layout {
+ cursor: pointer;
position: relative;
display: flex;
align-items: center;
@@ -612,6 +664,7 @@ $light-background: #ececec;
}
.layout {
+ cursor: pointer;
align-self: center;
justify-self: center;
margin-top: 5;
@@ -682,6 +735,7 @@ $light-background: #ececec;
grid-template-columns: auto auto;
.presBox-viewPicker {
+ cursor: pointer;
height: 25;
position: relative;
display: inline-block;
@@ -708,6 +762,7 @@ $light-background: #ececec;
}
.presBox-button {
+ cursor: pointer;
height: 25px;
border-radius: 5px;
display: none;
@@ -746,7 +801,7 @@ $light-background: #ececec;
}
- .miniPresOverlay {
+ .presPanelOverlay {
background-color: #323232;
color: white;
border-radius: 5px;
@@ -761,7 +816,7 @@ $light-background: #ececec;
right: 10px;
transition: all 0.2s;
- .miniPres-button-text {
+ .presPanel-button-text {
display: flex;
height: 20;
width: max-content;
@@ -778,13 +833,13 @@ $light-background: #ececec;
transition: all 0.3s;
}
- .miniPres-divider {
+ .presPanel-divider {
width: 0.5px;
height: 80%;
border-right: solid 1px #5a5a5a;
}
- .miniPres-button-frame {
+ .presPanel-button-frame {
justify-self: center;
align-self: center;
align-items: center;
@@ -799,7 +854,8 @@ $light-background: #ececec;
border-radius: 5px;
}
- .miniPres-button {
+ .presPanel-button {
+ cursor: pointer;
display: flex;
height: 20;
min-width: 20;
@@ -811,11 +867,11 @@ $light-background: #ececec;
transition: all 0.3s;
}
- .miniPres-button:hover {
+ .presPanel-button:hover {
background-color: #5a5a5a;
}
- .miniPres-button-text:hover {
+ .presPanel-button-text:hover {
background-color: #5a5a5a;
}
}
@@ -894,4 +950,82 @@ $light-background: #ececec;
.select {
font-size: 100%;
}
-} \ No newline at end of file
+}
+
+.miniPres:hover {
+ opacity: 1;
+}
+
+.miniPres {
+ cursor: grab;
+ position: absolute;
+ overflow: hidden;
+ right: 10;
+ top: 10;
+ opacity: 0.1;
+ transition: all 0.4s;
+ /* border: solid 1px; */
+ color: white;
+ /* box-shadow: black 0.4vw 0.4vw 0.8vw; */
+
+ .miniPresOverlay {
+ display: grid;
+ grid-template-columns: auto auto auto auto auto auto auto auto;
+ grid-template-rows: 100%;
+ height: 100%;
+ justify-items: center;
+ align-items: center;
+
+ .miniPres-button-text {
+ cursor: pointer;
+ display: flex;
+ height: 20;
+ font-weight: 400;
+ min-width: 100%;
+ border-radius: 5px;
+ align-items: center;
+ justify-content: center;
+ transition: all 0.3s;
+ }
+
+ .miniPres-button-frame {
+ justify-self: center;
+ align-self: center;
+ align-items: center;
+ display: grid;
+ grid-template-columns: auto auto auto;
+ justify-content: space-around;
+ font-size: 11;
+ margin-left: 7;
+ width: 30;
+ height: 85%;
+ background-color: rgba(91, 157, 221, 0.4);
+ border-radius: 5px;
+ }
+
+ .miniPres-divider {
+ width: 0.5px;
+ height: 80%;
+ border-right: solid 2px #5a5a5a;
+ }
+
+ .miniPres-button {
+ cursor: pointer;
+ display: flex;
+ height: 20;
+ min-width: 20;
+ border-radius: 100%;
+ align-items: center;
+ justify-content: center;
+ transition: all 0.3s;
+ }
+
+ .miniPres-button:hover {
+ background-color: #5a5a5a;
+ }
+
+ .miniPres-button-text:hover {
+ background-color: #5a5a5a;
+ }
+ }
+}
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 849fc4076..dd4c103c4 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -23,10 +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);
@@ -54,13 +56,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
@observable private presentTools: boolean = false;
@observable private pathBoolean: boolean = false;
@observable private expandBoolean: boolean = false;
+ @observable private openMovementDropdown: boolean = false;
+ @observable private openEffectDropdown: boolean = false;
@computed get childDocs() { return DocListCast(this.dataDoc[this.fieldKey]); }
@computed get itemIndex() { return NumCast(this.rootDoc._itemIndex); }
@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"
@@ -92,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() {
@@ -106,6 +112,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
updateCurrentPresentation = () => {
Doc.UserDoc().activePresentation = this.rootDoc;
+ PresBox.Instance = this;
}
/**
@@ -123,25 +130,29 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
const lastFrame = Cast(presTargetDoc.lastFrame, "number", null);
const curFrame = NumCast(presTargetDoc.currentFrame);
let internalFrames: boolean = false;
- if (presTargetDoc.presProgressivize || presTargetDoc.zoomProgressivize || presTargetDoc.scrollProgressivize) internalFrames = true;
+ if (presTargetDoc.presProgressivize || activeItem.zoomProgressivize || presTargetDoc.scrollProgressivize) internalFrames = true;
// Case 1: There are still other frames and should go through all frames before going to next slide
if (internalFrames && lastFrame !== undefined && curFrame < lastFrame) {
presTargetDoc._viewTransition = "all 1s";
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.zoomProgressivize) this.zoomProgressivizeNext(presTargetDoc);
+ 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) {
+ } else if ((presTargetDoc.type === DocumentType.AUDIO) && !this._moveOnFromAudio && this.layoutDoc.presStatus !== 'auto') {
AudioBox.Instance.playFrom(0);
this._moveOnFromAudio = true;
// Case 3: No more frames in current doc and next slide is defined, therefore move to next slide
} else if (this.childDocs[this.itemIndex + 1] !== undefined) {
const nextSelected = this.itemIndex + 1;
+ if (presTargetDoc.type === DocumentType.AUDIO) AudioBox.Instance.pause();
this.gotoDocument(nextSelected, this.itemIndex);
const targetNext = Cast(activeNext.presentationTargetDoc, Doc, null);
if (activeNext && targetNext.type === DocumentType.AUDIO && activeNext.playAuto) {
+ AudioBox.Instance.playFrom(0);
+ this._moveOnFromAudio = true;
} else this._moveOnFromAudio = false;
}
}
@@ -156,10 +167,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)
}
}
@@ -174,8 +193,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
if (presTargetDoc?.lastFrame !== undefined) {
presTargetDoc.currentFrame = 0;
}
- this.navigateToElement(this.childDocs[index]); //Handles movement to element
this._selectedArray = [this.childDocs[index]]; //Update selected array
+ //Handles movement to element
+ if (this.layoutDoc._viewType === "stacking") this.navigateToElement(this.childDocs[index]);
this.onHideDocument(); //Handles hide after/before
}
});
@@ -197,8 +217,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
this.turnOffEdit();
if (this.itemIndex >= 0) {
- if (targetDoc) {
- if (srcContext) this.layoutDoc.presCollection = srcContext;
+ if (srcContext && targetDoc) {
+ this.layoutDoc.presCollection = srcContext;
} else if (targetDoc) this.layoutDoc.presCollection = targetDoc;
}
if (collectionDocView) {
@@ -211,21 +231,25 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
const docToJump = curDoc;
const willZoom = false;
- //docToJump stayed same meaning, it was not in the group or was the last element in the group
- if (targetDoc.zoomProgressivize && this.rootDoc.presStatus !== 'edit') {
- this.zoomProgressivizeNext(targetDoc);
- } else if (docToJump === curDoc) {
- //checking if curDoc has navigation open
- if (curDoc.presNavButton && targetDoc) {
- await DocumentManager.Instance.jumpToDocument(targetDoc, false, undefined, srcContext);
- } else if (curDoc.presZoomButton && targetDoc) {
+ // If openDocument is selected then it should open the document for the user
+ if (activeItem.openDocument) {
+ this.props.addDocTab(activeItem, "replace");
+ } else
+ //docToJump stayed same meaning, it was not in the group or was the last element in the group
+ if (activeItem.zoomProgressivize && this.rootDoc.presStatus !== 'edit') {
+ this.zoomProgressivizeNext(targetDoc);
+ } else if (docToJump === curDoc) {
+ //checking if curDoc has navigation open
+ if (curDoc.presNavButton && targetDoc) {
+ await DocumentManager.Instance.jumpToDocument(targetDoc, false, undefined, srcContext);
+ } else if (curDoc.presZoomButton && targetDoc) {
+ //awaiting jump so that new scale can be found, since jumping is async
+ await DocumentManager.Instance.jumpToDocument(targetDoc, true, undefined, srcContext);
+ }
+ } else {
//awaiting jump so that new scale can be found, since jumping is async
- await DocumentManager.Instance.jumpToDocument(targetDoc, true, undefined, srcContext);
+ targetDoc && await DocumentManager.Instance.jumpToDocument(targetDoc, willZoom, undefined, srcContext);
}
- } else {
- //awaiting jump so that new scale can be found, since jumping is async
- targetDoc && await DocumentManager.Instance.jumpToDocument(targetDoc, willZoom, undefined, srcContext);
- }
// After navigating to the document, if it is added as a presPinView then it will
// adjust the pan and scale to that of the pinView when it was added.
// TODO: Add option to remove presPinView
@@ -234,10 +258,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
targetDoc._panY = activeItem.presPinViewY;
targetDoc._viewScale = activeItem.presPinViewScale;
}
- // If openDocument is selected then it should open the document for the user
- if (collectionDocView && activeItem.openDocument) {
- collectionDocView.props.addDocTab(activeItem, "inPlace");
- }
// If website and has presWebsite data associated then on click it should
// go back to that specific website
// TODO: Add progressivize for navigating web (storing websites for given frames)
@@ -250,22 +270,23 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
* Uses the viewfinder to progressivize through the different views of a single collection.
* @param presTargetDoc: document for which internal zoom is used
*/
- zoomProgressivizeNext = (presTargetDoc: Doc) => {
- const srcContext = Cast(presTargetDoc.context, Doc, null);
- const docView = DocumentManager.Instance.getDocumentView(presTargetDoc);
- const vfLeft: number = this.checkList(presTargetDoc, presTargetDoc["viewfinder-left-indexed"]);
- const vfWidth: number = this.checkList(presTargetDoc, presTargetDoc["viewfinder-width-indexed"]);
- const vfTop: number = this.checkList(presTargetDoc, presTargetDoc["viewfinder-top-indexed"]);
- const vfHeight: number = this.checkList(presTargetDoc, presTargetDoc["viewfinder-height-indexed"]);
+ zoomProgressivizeNext = (activeItem: Doc) => {
+ const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
+ const srcContext = Cast(targetDoc?.context, Doc, null);
+ const docView = DocumentManager.Instance.getDocumentView(targetDoc);
+ 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);
if (srcDocView) {
- const layoutdoc = Doc.Layout(presTargetDoc);
+ const layoutdoc = Doc.Layout(targetDoc);
const panelWidth: number = srcDocView.props.PanelWidth();
const panelHeight: number = srcDocView.props.PanelHeight();
- const newPanX = NumCast(presTargetDoc.x) + NumCast(layoutdoc._width) / 2;
- const newPanY = NumCast(presTargetDoc.y) + NumCast(layoutdoc._height) / 2;
+ const newPanX = NumCast(targetDoc.x) + NumCast(layoutdoc._width) / 2;
+ const newPanY = NumCast(targetDoc.y) + NumCast(layoutdoc._height) / 2;
const newScale = 0.9 * Math.min(Number(panelWidth) / vfWidth, Number(panelHeight) / vfHeight);
srcContext._panX = newPanX + (vfLeft + (vfWidth / 2));
srcContext._panY = newPanY + (vfTop + (vfHeight / 2));
@@ -277,9 +298,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
const panelWidth: number = docView.props.PanelWidth();
const panelHeight: number = docView.props.PanelHeight();
const newScale = 0.9 * Math.min(Number(panelWidth) / vfWidth, Number(panelHeight) / vfHeight);
- presTargetDoc._panX = vfLeft + (vfWidth / 2);
- presTargetDoc._panY = vfTop + (vfWidth / 2);
- presTargetDoc._viewScale = newScale;
+ targetDoc._panX = vfLeft + (vfWidth / 2);
+ targetDoc._panY = vfTop + (vfWidth / 2);
+ targetDoc._viewScale = newScale;
}
const resize = document.getElementById('resizable');
if (resize) {
@@ -299,7 +320,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) {
@@ -319,40 +340,60 @@ 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);
+ duration = NumCast(targetDoc.presDuration) + NumCast(targetDoc.presTransition);
+ if (duration <= 100) { 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;
}
@action togglePath = () => this.pathBoolean = !this.pathBoolean;
- @action toggleExpand = () => this.expandBoolean = !this.expandBoolean;
+ @action toggleExpandMode = () => {
+ this.rootDoc.expandBoolean = !this.rootDoc.expandBoolean;
+ this.childDocs.forEach((doc) => {
+ if (this.rootDoc.expandBoolean) doc.presExpandInlineButton = true;
+ else if (!this.rootDoc.expandBoolean) doc.presExpandInlineButton = false;
+ });
+ };
/**
* The function that starts the presentation at the given index, also checking if actions should be applied
@@ -376,17 +417,23 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
* The method called to open the presentation as a minimized view
* TODO: Look at old updateMinimize and compare...
*/
+ @undoBatch
+ @action
updateMinimize = () => {
- const srcContext = Cast(this.rootDoc.presCollection, Doc, null);
- this.turnOffEdit();
- if (srcContext) {
- if (srcContext.miniPres) {
- srcContext.miniPres = false;
- CollectionDockingView.AddRightSplit(this.rootDoc);
- } else {
- srcContext.miniPres = true;
- this.props.addDocTab?.(this.rootDoc, "close");
- }
+ if (this.layoutDoc.inOverlay) {
+ this.layoutDoc.presStatus = 'edit';
+ Doc.RemoveDocFromList((Doc.UserDoc().myOverlayDocuments as Doc), undefined, this.rootDoc);
+ CollectionDockingView.AddRightSplit(this.rootDoc);
+ this.layoutDoc.inOverlay = false;
+ } else {
+ this.layoutDoc.presStatus = 'manual';
+ const pt = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
+ this.rootDoc.x = pt[0] + (this.props.PanelWidth() - 250);
+ this.rootDoc.y = pt[1] + 10;
+ this.rootDoc._height = 35;
+ this.rootDoc._width = 250;
+ this.props.addDocTab?.(this.rootDoc, "close");
+ Doc.AddDocToList((Doc.UserDoc().myOverlayDocuments as Doc), undefined, this.rootDoc);
}
}
@@ -426,6 +473,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
break;
case 'jump': //Jump Cut
targetDoc.presTransition = 0;
+ activeItem.presZoomButton = true;
activeItem.presSwitchButton = !activeItem.presSwitchButton;
if (activeItem.presSwitchButton) activeItem.presMovement = 'Jump cut';
else activeItem.presMovement = 'None';
@@ -449,6 +497,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
} else {
doc.aliasOf instanceof Doc && (doc.presentationTargetDoc = doc.aliasOf);
!this.childDocs.includes(doc) && (doc.presZoomButton = true);
+ if (this.rootDoc.expandBoolean) doc.presExpandInlineButton = true;
}
});
return true;
@@ -488,20 +537,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
@@ -516,17 +573,20 @@ 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 = [];
+ if (this.layoutDoc.inOverlay) { this.updateMinimize(); }
+ else 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") {
@@ -534,14 +594,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
@@ -565,23 +625,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
@@ -589,7 +639,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(
@@ -619,7 +669,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);
@@ -669,16 +719,22 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
}
// Converts seconds to ms and updates presTransition
- setTransitionTime = (number: String) => {
- const timeInMS = Number(number) * 1000;
+ setTransitionTime = (number: String, change?: number) => {
+ let timeInMS = Number(number) * 1000;
+ if (change) timeInMS += change;
+ 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);
if (targetDoc) targetDoc.presTransition = timeInMS;
}
// Converts seconds to ms and updates presDuration
- setDurationTime = (number: String) => {
- const timeInMS = Number(number) * 1000;
+ setDurationTime = (number: String, change?: number) => {
+ let timeInMS = Number(number) * 1000;
+ if (change) timeInMS += change;
+ 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);
if (targetDoc) targetDoc.presDuration = timeInMS;
@@ -689,19 +745,19 @@ 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) {
- const 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';
return (
- <div className={`presBox-ribbon ${this.transitionTools && this.layoutDoc.presStatus === "edit" ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
+ <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" onPointerDown={e => e.stopPropagation()}>
+ <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"} />
- <div className={'presBox-dropdownOptions'} id={'presBoxMovementDropdown'} onClick={e => e.stopPropagation()}>
+ <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>
<div className={`presBox-dropdownOption ${activeItem.presMovement === 'Pan' ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.movementChanged('pan')}>Pan</div>
@@ -709,8 +765,21 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
</div>
</div>
<div className="ribbon-doubleButton" style={{ display: activeItem.presMovement === 'Pan' || activeItem.presMovement === 'Zoom' ? "inline-flex" : "none" }}>
- <div className="presBox-subheading" >Transition Speed</div>
- <div className="ribbon-property"> {transitionSpeed} s </div>
+ <div className="presBox-subheading">Transition Speed</div>
+ <div className="ribbon-property">
+ <input className="presBox-input"
+ type="number" value={transitionSpeed}
+ onFocus={() => { document.removeEventListener("keydown", this.keyEvents, true); }}
+ 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(transitionSpeed), 1000)}>
+ <FontAwesomeIcon icon={"caret-up"} />
+ </div>
+ <div className="ribbon-propertyUpDownItem" onClick={() => this.setTransitionTime(String(transitionSpeed), -1000)}>
+ <FontAwesomeIcon icon={"caret-down"} />
+ </div>
+ </div>
</div>
<input type="range" step="0.1" min="0.1" max="10" value={transitionSpeed} className={`toolbar-slider ${activeItem.presMovement === 'Pan' || activeItem.presMovement === 'Zoom' ? "" : "none"}`} id="toolbar-slider" onChange={(e: React.ChangeEvent<HTMLInputElement>) => { e.stopPropagation(); this.setTransitionTime(e.target.value); }} />
<div className={`slider-headers ${activeItem.presMovement === 'Pan' || activeItem.presMovement === 'Zoom' ? "" : "none"}`}>
@@ -727,9 +796,22 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
</div>
<div className="ribbon-doubleButton" >
<div className="presBox-subheading">Slide Duration</div>
- <div className="ribbon-property"> {duration} s </div>
+ <div className="ribbon-property">
+ <input className="presBox-input"
+ type="number" value={duration}
+ onFocus={() => { document.removeEventListener("keydown", this.keyEvents, true); }}
+ 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)}>
+ <FontAwesomeIcon icon={"caret-up"} />
+ </div>
+ <div className="ribbon-propertyUpDownItem" onClick={() => this.setDurationTime(String(duration), -1000)}>
+ <FontAwesomeIcon icon={"caret-down"} />
+ </div>
+ </div>
</div>
- <input type="range" step="0.1" min="0.1" max="10" value={duration} style={{ display: targetDoc.type === DocumentType.AUDIO ? "none" : "block" }} className={"toolbar-slider"} id="duration-slider" onChange={(e: React.ChangeEvent<HTMLInputElement>) => { e.stopPropagation(); this.setDurationTime(e.target.value); }} />
+ <input type="range" step="0.1" min="0.1" max="20" value={duration} style={{ display: targetDoc.type === DocumentType.AUDIO ? "none" : "block" }} className={"toolbar-slider"} id="duration-slider" onChange={(e: React.ChangeEvent<HTMLInputElement>) => { e.stopPropagation(); this.setDurationTime(e.target.value); }} />
<div className={"slider-headers"} style={{ display: targetDoc.type === DocumentType.AUDIO ? "none" : "grid" }}>
<div className="slider-text">Short</div>
<div className="slider-text">Medium</div>
@@ -738,12 +820,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
</div>
<div className="ribbon-box">
Effects
- <div className="presBox-dropdown"
- onPointerDown={e => e.stopPropagation()}
- >
+ <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"} />
- <div className={'presBox-dropdownOptions'} id={'presBoxMovementDropdown'} onClick={e => e.stopPropagation()}>
+ <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>
<div className={'presBox-dropdownOption'} onPointerDown={e => e.stopPropagation()} onClick={() => targetDoc.presEffect = 'Flip'}>Flip</div>
@@ -774,7 +854,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
Apply to all
</div>
</div>
- </div>
+ </div >
);
}
}
@@ -793,6 +873,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
return effect;
}
+ @undoBatch
+ @action
applyTo = (array: Doc[]) => {
const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
@@ -803,12 +885,13 @@ 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;
}
});
}
-
- private inputRef = React.createRef<HTMLInputElement>();
-
@computed get optionsDropdown() {
const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
@@ -838,9 +921,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 >
@@ -865,11 +980,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 >
@@ -884,13 +994,18 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
@computed get newDocumentDropdown() {
return (
<div>
- <div className={"presBox-ribbon"} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
+ <div className={"presBox-ribbon"} onClick={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
<div className="ribbon-box">
Slide Title: <br></br>
- <input className="ribbon-textInput" placeholder="..." type="text" name="fname" ref={this.inputRef} onChange={(e) => {
- e.stopPropagation();
- runInAction(() => this.title = e.target.value);
- }}></input>
+ <input className="ribbon-textInput" placeholder="..." type="text" name="fname"
+ onFocus={() => {
+ document.removeEventListener("keydown", this.keyEvents, true);
+ }}
+ onChange={(e) => {
+ e.stopPropagation();
+ e.preventDefault();
+ runInAction(() => this.title = e.target.value);
+ }}></input>
</div>
<div className="ribbon-box">
Choose type:
@@ -1007,7 +1122,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
// Case in which the document has keyframes to navigate to next key frame
@undoBatch
@action
- nextKeyframe = (tagDoc: Doc): void => {
+ nextKeyframe = (tagDoc: Doc, activeItem: Doc): void => {
const childDocs = DocListCast(tagDoc[Doc.LayoutFieldKey(tagDoc)]);
const currentFrame = Cast(tagDoc.currentFrame, "number", null);
if (currentFrame === undefined) {
@@ -1016,23 +1131,23 @@ 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 (tagDoc.zoomProgressivize) {
+ if (activeItem.zoomProgressivize) {
const resize = document.getElementById('resizable');
if (resize) {
- resize.style.width = this.checkList(tagDoc, tagDoc["viewfinder-width-indexed"]) + 'px';
- resize.style.height = this.checkList(tagDoc, tagDoc["viewfinder-height-indexed"]) + 'px';
- resize.style.top = this.checkList(tagDoc, tagDoc["viewfinder-top-indexed"]) + 'px';
- resize.style.left = this.checkList(tagDoc, tagDoc["viewfinder-left-indexed"]) + 'px';
+ resize.style.width = this.checkList(tagDoc, activeItem["viewfinder-width-indexed"]) + 'px';
+ resize.style.height = this.checkList(tagDoc, activeItem["viewfinder-height-indexed"]) + 'px';
+ resize.style.top = this.checkList(tagDoc, activeItem["viewfinder-top-indexed"]) + 'px';
+ resize.style.left = this.checkList(tagDoc, activeItem["viewfinder-left-indexed"]) + 'px';
}
}
}
@undoBatch
@action
- prevKeyframe = (tagDoc: Doc): void => {
+ prevKeyframe = (tagDoc: Doc, activeItem: Doc): void => {
const childDocs = DocListCast(tagDoc[Doc.LayoutFieldKey(tagDoc)]);
const currentFrame = Cast(tagDoc.currentFrame, "number", null);
if (currentFrame === undefined) {
@@ -1041,13 +1156,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
}
CollectionFreeFormDocumentView.gotoKeyframe(childDocs.slice());
tagDoc.currentFrame = Math.max(0, (currentFrame || 0) - 1);
- if (tagDoc.zoomProgressivize) {
+ if (activeItem.zoomProgressivize) {
const resize = document.getElementById('resizable');
if (resize) {
- resize.style.width = this.checkList(tagDoc, tagDoc["viewfinder-width-indexed"]) + 'px';
- resize.style.height = this.checkList(tagDoc, tagDoc["viewfinder-height-indexed"]) + 'px';
- resize.style.top = this.checkList(tagDoc, tagDoc["viewfinder-top-indexed"]) + 'px';
- resize.style.left = this.checkList(tagDoc, tagDoc["viewfinder-left-indexed"]) + 'px';
+ resize.style.width = this.checkList(tagDoc, activeItem["viewfinder-width-indexed"]) + 'px';
+ resize.style.height = this.checkList(tagDoc, activeItem["viewfinder-height-indexed"]) + 'px';
+ resize.style.top = this.checkList(tagDoc, activeItem["viewfinder-top-indexed"]) + 'px';
+ resize.style.left = this.checkList(tagDoc, activeItem["viewfinder-left-indexed"]) + 'px';
}
}
}
@@ -1067,58 +1182,72 @@ 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: (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: targetDoc.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> */}
+ <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' ? "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.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>
+ {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" }}>
Frames
<div className="ribbon-doubleButton">
<div className="ribbon-frameSelector">
- <div key="back" title="back frame" className="backKeyframe" onClick={e => { e.stopPropagation(); this.prevKeyframe(targetDoc); }}>
+ <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>
- <div key="fwd" title="forward frame" className="fwdKeyframe" onClick={e => { e.stopPropagation(); this.nextKeyframe(targetDoc); }}>
+ <div key="fwd" title="forward frame" className="fwdKeyframe" onClick={e => { e.stopPropagation(); this.nextKeyframe(targetDoc, activeItem); }}>
<FontAwesomeIcon icon={"caret-right"} size={"lg"} />
</div>
</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>
@@ -1126,43 +1255,70 @@ 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;
doc.editZoomProgressivize = false;
doc.editScrollProgressivize = false;
const targetDoc = Cast(doc.presentationTargetDoc, Doc, null);
- targetDoc.editSnapZoomProgressivize = false;
- targetDoc.editZoomProgressivize = false;
- targetDoc.editScrollProgressivize = false;
- if (doc.type === DocumentType.WEB) {
- doc.presWebsite = doc.data;
+ if (targetDoc) {
+ targetDoc.editZoomProgressivize = false;
+ targetDoc.editScrollProgressivize = false;
}
});
}
//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 {
targetDoc.editZoomProgressivize = false;
+ activeItem.editZoomProgressivize = false;
}
}
@@ -1172,6 +1328,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;
@@ -1185,7 +1342,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
activeItem.scrollProgressivize = !activeItem.scrollProgressivize;
const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
- targetDoc.scrollProgressivize = !targetDoc.zoomProgressivize;
+ targetDoc.scrollProgressivize = !targetDoc.scrollProgressivize;
CollectionFreeFormDocumentView.setupScroll(targetDoc, NumCast(targetDoc.currentFrame), true);
if (targetDoc.editScrollProgressivize) {
targetDoc.editScrollProgressivize = false;
@@ -1202,52 +1359,25 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
activeItem.zoomProgressivize = !activeItem.zoomProgressivize;
const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
targetDoc.zoomProgressivize = !targetDoc.zoomProgressivize;
- CollectionFreeFormDocumentView.setupZoom(targetDoc, true);
- if (targetDoc.editZoomProgressivize) {
- targetDoc.editZoomProgressivize = false;
+ CollectionFreeFormDocumentView.setupZoom(activeItem, targetDoc, true);
+ if (activeItem.editZoomProgressivize) {
+ activeItem.editZoomProgressivize = false;
targetDoc.currentFrame = 0;
targetDoc.lastFrame = 0;
}
}
- //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;
}
}
@@ -1258,6 +1388,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;
@@ -1267,11 +1398,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;
}
}
@@ -1308,236 +1437,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
else doc.displayMovement = true;
}
- 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;
- 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
- onPointerBR = (e: React.PointerEvent): void => {
- e.stopPropagation();
- e.preventDefault();
- this._isDraggingBR = 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
- 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();
- e.preventDefault();
- this._isDraggingTL = false;
- this._isDraggingTR = false;
- this._isDraggingBL = false;
- this._isDraggingBR = false;
- this._isDragging = false;
- document.removeEventListener("pointermove", this.onPointerMove);
- document.removeEventListener("pointerup", this.onPointerUp);
- }
-
- //Adjusts the value in NodeStore
- onPointerMove = (e: PointerEvent): void => {
- const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
- const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
- const tagDocView = DocumentManager.Instance.getDocumentView(targetDoc);
- e.stopPropagation();
- e.preventDefault();
- const doc = document.getElementById('resizable');
- if (doc && tagDocView) {
-
- const scale2 = tagDocView.childScaling();
- const scale3 = tagDocView.props.ScreenToLocalTransform().Scale;
- const scale = NumCast(targetDoc._viewScale);
- console.log("scale: " + NumCast(targetDoc._viewScale));
- let height = doc.offsetHeight;
- let width = doc.offsetWidth;
- let top = doc.offsetTop;
- let left = doc.offsetLeft;
- // const newHeightB = height += (e.movementY * NumCast(targetDoc._viewScale));
- // const newHeightT = height -= (e.movementY * NumCast(targetDoc._viewScale));
- // const newWidthR = width += (e.movementX * NumCast(targetDoc._viewScale));
- // const newWidthL = width -= (e.movementX * NumCast(targetDoc._viewScale));
- // const newLeft = left += (e.movementX * NumCast(targetDoc._viewScale));
- // const newTop = top += (e.movementY * NumCast(targetDoc._viewScale));
- // 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';
- // }
- //Bottom right
- if (this._isDraggingBR) {
- const newHeight = height += (e.movementY * scale);
- doc.style.height = newHeight + 'px';
- const newWidth = width += (e.movementX * scale);
- doc.style.width = newWidth + 'px';
- // Bottom left
- } else if (this._isDraggingBL) {
- const newHeight = height += (e.movementY * scale);
- doc.style.height = newHeight + 'px';
- const newWidth = width -= (e.movementX * scale);
- doc.style.width = newWidth + 'px';
- const newLeft = left += (e.movementX * scale);
- doc.style.left = newLeft + 'px';
- // Top right
- } else if (this._isDraggingTR) {
- const newWidth = width += (e.movementX * scale);
- doc.style.width = newWidth + 'px';
- const newHeight = height -= (e.movementY * scale);
- doc.style.height = newHeight + 'px';
- const newTop = top += (e.movementY * scale);
- doc.style.top = newTop + 'px';
- // Top left
- } else if (this._isDraggingTL) {
- const newWidth = width -= (e.movementX * scale);
- doc.style.width = newWidth + 'px';
- const newHeight = height -= (e.movementY * scale);
- doc.style.height = newHeight + 'px';
- const newTop = top += (e.movementY * scale);
- doc.style.top = newTop + 'px';
- const newLeft = left += (e.movementX * scale);
- doc.style.left = newLeft + 'px';
- } else if (this._isDragging) {
- const newTop = top += (e.movementY * scale);
- doc.style.top = newTop + 'px';
- const newLeft = left += (e.movementX * scale);
- doc.style.left = newLeft + 'px';
- }
- this.updateList(targetDoc, targetDoc["viewfinder-width-indexed"], width);
- this.updateList(targetDoc, targetDoc["viewfinder-height-indexed"], height);
- this.updateList(targetDoc, targetDoc["viewfinder-top-indexed"], top);
- this.updateList(targetDoc, targetDoc["viewfinder-left-indexed"], left);
- }
- }
-
@action
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 {
+ } else if (x) {
x.length = NumCast(doc.currentFrame) + 1;
x[NumCast(doc.currentFrame)] = x[NumCast(doc.currentFrame) - 1];
return x[NumCast(doc.currentFrame)];
- }
-
- }
-
- @action
- updateList = (doc: Doc, list: any, val: number) => {
- const x: List<number> = list;
- if (x && x.length >= NumCast(doc.currentFrame) + 1) {
- x[NumCast(doc.currentFrame)] = val;
- list = x;
- } else {
- x.length = NumCast(doc.currentFrame) + 1;
- x[NumCast(doc.currentFrame)] = val;
- list = x;
- }
- }
-
- // scale: NumCast(targetDoc._viewScale),
- @computed get zoomProgressivizeContainer() {
- const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
- const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
- if (targetDoc) {
- const vfLeft: number = this.checkList(targetDoc, targetDoc["viewfinder-left-indexed"]);
- const vfWidth: number = this.checkList(targetDoc, targetDoc["viewfinder-width-indexed"]);
- const vfTop: number = this.checkList(targetDoc, targetDoc["viewfinder-top-indexed"]);
- const vfHeight: number = this.checkList(targetDoc, targetDoc["viewfinder-height-indexed"]);
- return (
- <>
- {!targetDoc.editZoomProgressivize ? (null) : <div id="resizable" className="resizable" onPointerDown={this.onPointerMid} style={{ width: vfWidth, height: vfHeight, top: vfTop, left: vfLeft, position: 'absolute' }}>
- <div className='resizers'>
- <div id="resizer-tl" className='resizer top-left' onPointerDown={this.onPointerTL}></div>
- <div id="resizer-tr" className='resizer top-right' onPointerDown={this.onPointerTR}></div>
- <div id="resizer-bl" className='resizer bottom-left' onPointerDown={this.onPointerBL}></div>
- <div id="resizer-br" className='resizer bottom-right' onPointerDown={this.onPointerBR}></div>
- </div>
- </div>}
- </>
- );
- }
+ } else return 100;
}
@computed get progressivizeChildDocs() {
@@ -1620,8 +1529,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)}>
@@ -1634,12 +1553,17 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
<FontAwesomeIcon icon={"exchange-alt"} />
</div>
</Tooltip>
- <Tooltip title={<><div className="dash-tooltip">{this.expandBoolean ? "Minimize all" : "Expand all"}</div></>}>
- <div style={{ opacity: this.childDocs.length > 0 ? 1 : 0.3 }} className={`toolbar-button ${this.expandBoolean ? "active" : ""}`} onClick={() => { if (this.childDocs.length > 0) this.toggleExpand(); this.childDocs.forEach((doc, ind) => { if (this.expandBoolean) doc.presExpandInlineButton = true; else doc.presExpandInlineButton = false; }); }}>
+ <Tooltip title={<><div className="dash-tooltip">{this.rootDoc.expandBoolean ? "Minimize all" : "Expand all"}</div></>}>
+ <div className={`toolbar-button ${this.rootDoc.expandBoolean ? "active" : ""}`} onClick={this.toggleExpandMode}>
<FontAwesomeIcon icon={"eye"} />
</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>
);
}
@@ -1697,18 +1621,18 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
@computed get playButtons() {
// Case 1: There are still other frames and should go through all frames before going to next slide
- return (<div className="miniPresOverlay" style={{ display: this.layoutDoc.presStatus !== "edit" ? "inline-flex" : "none" }}>
- <div className="miniPres-button" onClick={this.back}><FontAwesomeIcon icon={"arrow-left"} /></div>
- <div className="miniPres-button" onClick={() => this.startAutoPres(this.itemIndex)}><FontAwesomeIcon icon={this.layoutDoc.presStatus === "auto" ? "pause" : "play"} /></div>
- <div className="miniPres-button" onClick={this.next}><FontAwesomeIcon icon={"arrow-right"} /></div>
- <div className="miniPres-divider"></div>
- <div className="miniPres-button-text" style={{ display: this.props.PanelWidth() > 250 ? "inline-flex" : "none" }}>
+ return (<div className="presPanelOverlay" style={{ display: this.layoutDoc.presStatus !== "edit" ? "inline-flex" : "none" }}>
+ <div className="presPanel-button" onClick={this.back}><FontAwesomeIcon icon={"arrow-left"} /></div>
+ <div className="presPanel-button" onClick={() => this.startAutoPres(this.itemIndex)}><FontAwesomeIcon icon={this.layoutDoc.presStatus === "auto" ? "pause" : "play"} /></div>
+ <div className="presPanel-button" onClick={this.next}><FontAwesomeIcon icon={"arrow-right"} /></div>
+ <div className="presPanel-divider"></div>
+ <div className="presPanel-button-text" style={{ display: this.props.PanelWidth() > 250 ? "inline-flex" : "none" }}>
Slide {this.itemIndex + 1} / {this.childDocs.length}
{this.playButtonFrames}
</div>
- <div className="miniPres-divider"></div>
- {this.props.PanelWidth() > 250 ? <div className="miniPres-button-text" onClick={() => this.layoutDoc.presStatus = "edit"}>EXIT</div>
- : <div className="miniPres-button" onClick={() => this.layoutDoc.presStatus = "edit"}>
+ <div className="presPanel-divider"></div>
+ {this.props.PanelWidth() > 250 ? <div className="presPanel-button-text" onClick={() => this.layoutDoc.presStatus = "edit"}>EXIT</div>
+ : <div className="presPanel-button" onClick={() => this.layoutDoc.presStatus = "edit"}>
<FontAwesomeIcon icon={"times"} />
</div>}
</div>);
@@ -1720,28 +1644,44 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
// needed to ensure that the childDocs are loaded for looking up fields
this.childDocs.slice();
const mode = StrCast(this.rootDoc._viewType) as CollectionViewType;
- return <div className="presBox-cont" style={{ minWidth: this.layoutDoc.inOverlay ? 240 : undefined }} >
- {this.topPanel}
- {this.toolbar}
- {this.newDocumentToolbarDropdown}
- <div className="presBox-listCont">
- {mode !== CollectionViewType.Invalid ?
- <CollectionView {...this.props}
- ContainingCollectionDoc={this.props.Document}
- PanelWidth={this.props.PanelWidth}
- PanelHeight={this.panelHeight}
- moveDocument={returnFalse}
- childOpacity={returnOne}
- childLayoutTemplate={this.childLayoutTemplate}
- filterAddDocument={this.addDocumentFilter}
- removeDocument={returnFalse}
- dontRegisterView={true}
- focus={this.selectElement}
- ScreenToLocalTransform={this.getTransform} />
- : (null)
- }
+ return this.layoutDoc.inOverlay ?
+ <div className="miniPres" style={{ width: 250, height: 35, background: '#323232', top: 0, zIndex: 3000000 }}>
+ {<div className="miniPresOverlay">
+ <div className="miniPres-button" onClick={this.back}><FontAwesomeIcon icon={"arrow-left"} /></div>
+ <div className="miniPres-button" onClick={() => this.startAutoPres(this.itemIndex)}><FontAwesomeIcon icon={this.layoutDoc.presStatus === "auto" ? "pause" : "play"} /></div>
+ <div className="miniPres-button" onClick={this.next}><FontAwesomeIcon icon={"arrow-right"} /></div>
+ <div className="miniPres-divider"></div>
+ <div className="miniPres-button-text">
+ Slide {this.itemIndex + 1} / {this.childDocs.length}
+ {this.playButtonFrames}
+ </div>
+ <div className="miniPres-divider"></div>
+ <div className="miniPres-button-text" onClick={this.updateMinimize}>EXIT</div>
+ </div>}
</div>
- </div>;
+ :
+ <div className="presBox-cont" style={{ minWidth: this.layoutDoc.inOverlay ? 240 : undefined }} >
+ {this.topPanel}
+ {this.toolbar}
+ {this.newDocumentToolbarDropdown}
+ <div className="presBox-listCont">
+ {mode !== CollectionViewType.Invalid ?
+ <CollectionView {...this.props}
+ ContainingCollectionDoc={this.props.Document}
+ PanelWidth={this.props.PanelWidth}
+ PanelHeight={this.panelHeight}
+ moveDocument={returnFalse}
+ childOpacity={returnOne}
+ childLayoutTemplate={this.childLayoutTemplate}
+ filterAddDocument={this.addDocumentFilter}
+ removeDocument={returnFalse}
+ dontRegisterView={true}
+ focus={this.selectElement}
+ ScreenToLocalTransform={this.getTransform} />
+ : (null)
+ }
+ </div>
+ </div>;
}
}
Scripting.addGlobal(function lookupPresBoxField(container: Doc, field: string, data: Doc) {
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index f1eb5ef09..8c05d3603 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -648,7 +648,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
const options = cm.findByDescription("Options...");
const optionItems = options && "subitems" in options ? options.subitems : [];
- !Doc.UserDoc().noviceMode && optionItems.push({ description: this.Document._singleLine ? "Make Single Line" : "Make Multi Line", event: () => this.layoutDoc._singleLine = !this.layoutDoc._singleLine, icon: "expand-arrows-alt" });
+ !Doc.UserDoc().noviceMode && optionItems.push({ description: !this.Document._singleLine ? "Make Single Line" : "Make Multi Line", event: () => this.layoutDoc._singleLine = !this.layoutDoc._singleLine, icon: "expand-arrows-alt" });
optionItems.push({ description: `${this.Document._autoHeight ? "Lock" : "Auto"} Height`, event: () => this.layoutDoc._autoHeight = !this.layoutDoc._autoHeight, icon: "plus" });
optionItems.push({ description: `${!this.layoutDoc._nativeWidth || !this.layoutDoc._nativeHeight ? "Lock" : "Unlock"} Aspect`, event: this.toggleNativeDimensions, icon: "snowflake" });
!options && cm.addItem({ description: "Options...", subitems: optionItems, icon: "eye" });
@@ -1580,6 +1580,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
onScroll={this.onscrolled} onDrop={this.ondrop} >
<div className={`formattedTextBox-inner${rounded}${selclass}`} ref={this.createDropTarget}
style={{
+ overflow: this.layoutDoc._singleLine ? "hidden" : undefined,
padding: this.layoutDoc._textBoxPadding ? StrCast(this.layoutDoc._textBoxPadding) : `${Math.max(0, NumCast(this.layoutDoc._yMargin, this.props.yMargin || 0) + selPad)}px ${NumCast(this.layoutDoc._xMargin, this.props.xMargin || 0) + selPad}px`,
pointerEvents: !this.props.active() ? ((this.layoutDoc.isLinkButton || this.props.onClick) ? "none" : undefined) : undefined
}}
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 a6dbb76ef..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];
@@ -233,12 +129,21 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
private _itemRef: React.RefObject<HTMLDivElement> = React.createRef();
private _dragRef: React.RefObject<HTMLDivElement> = React.createRef();
+ @action
headerDown = (e: React.PointerEvent<HTMLDivElement>) => {
- const element = 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 = [];
+ PresBox.Instance._selectedArray.push(this.rootDoc);
+ PresBox.Instance._eleArray = [];
+ PresBox.Instance._eleArray.push(this._itemRef.current!);
+ PresBox.Instance._dragArray = [];
+ PresBox.Instance._dragArray.push(this._dragRef.current!);
setupMoveUpEvents(this, e, this.startDrag, emptyFunction, emptyFunction);
}
}
@@ -293,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) : (
@@ -319,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}
>
@@ -347,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/fields/ScriptField.ts b/src/fields/ScriptField.ts
index 4cc3a7cc7..9391f56ac 100644
--- a/src/fields/ScriptField.ts
+++ b/src/fields/ScriptField.ts
@@ -56,6 +56,9 @@ async function deserializeScript(script: ScriptField) {
if (script.script.originalScript === 'self.userDoc.noviceMode') {
return (script as any).script = (ScriptField.NoviceMode ?? (ScriptField.NoviceMode = ComputedField.MakeFunction('self.userDoc.noviceMode')))?.script;
}
+ if (script.script.originalScript === `selectMainMenu(self)`) {
+ return (script as any).script = (ScriptField.SelectMenu ?? (ScriptField.SelectMenu = ComputedField.MakeFunction('selectMainMenu(self)')))?.script;
+ }
const captures: ProxyField<Doc> = (script as any).captures;
if (captures) {
const doc = (await captures.value())!;
@@ -89,6 +92,7 @@ export class ScriptField extends ObjectField {
public static DeiconifyView: Opt<ScriptField>;
public static ConvertToButtons: Opt<ScriptField>;
public static NoviceMode: Opt<ScriptField>;
+ public static SelectMenu: Opt<ScriptField>;
constructor(script: CompiledScript, setterscript?: CompiledScript) {
super();
diff --git a/src/fields/documentSchemas.ts b/src/fields/documentSchemas.ts
index ada13226e..848a648e1 100644
--- a/src/fields/documentSchemas.ts
+++ b/src/fields/documentSchemas.ts
@@ -102,7 +102,7 @@ export const documentSchema = createSchema({
_lockedTransform: "boolean",// whether a freeformview can pan/zoom
// drag drop properties
- stayInCollection: "boolean",// whether document can be dropped into a different collection
+ _stayInCollection: "boolean",// whether document can be dropped into a different collection
dragFactory: Doc, // the document that serves as the "template" for the onDragStart script. ie, to drag out copies of the dragFactory document.
dropAction: "string", // override specifying what should happen when this document is dropped (can be "alias", "copy", "move")
targetDropAction: "string", // allows the target of a drop event to specify the dropAction ("alias", "copy", "move") NOTE: if the document is dropped within the same collection, the dropAction is coerced to 'move'
diff --git a/src/server/ApiManagers/SearchManager.ts b/src/server/ApiManagers/SearchManager.ts
index 99f227b28..a5aaab63e 100644
--- a/src/server/ApiManagers/SearchManager.ts
+++ b/src/server/ApiManagers/SearchManager.ts
@@ -62,7 +62,7 @@ export class SearchManager extends ApiManager {
subscription: "/dashsearch",
secureHandler: async ({ req, res }) => {
const solrQuery: any = {};
- ["q", "fq", "start", "rows", "hl", "hl.fl"].forEach(key => solrQuery[key] = req.query[key]);
+ ["q", "fq", "start", "rows", "sort", "hl", "hl.fl"].forEach(key => solrQuery[key] = req.query[key]);
if (solrQuery.q === undefined) {
res.send([]);
return;
@@ -136,6 +136,9 @@ export namespace SolrManager {
const term = ToSearchTerm(value);
if (term !== undefined) {
const { suffix, value } = term;
+ if (key.endsWith('lastModified')) {
+ update["lastModified" + suffix] = value;
+ }
update[key + suffix] = value;
dynfield = true;
}
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 });