From ee45bc1c3001b3e6feff5b43735f5d179f5e87e9 Mon Sep 17 00:00:00 2001 From: anika-ahluwalia Date: Fri, 14 Aug 2020 13:44:09 -0500 Subject: fixed marque offset --- src/client/views/collections/collectionFreeForm/MarqueeView.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index c0b19fcd2..4e8c26e5d 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -719,14 +719,14 @@ export class MarqueeView extends React.Component; } else { - //subtracted 250 for offset + //subtracted for offset var str: string = ""; for (var i = 0; i < this._pointsX.length; i++) { var x = 0; - x = this._pointsX[i] - 250; + x = this._pointsX[i] - 64; str += x.toString(); str += ","; - str += this._pointsY[i].toString(); + str += (this._pointsY[i] - 85).toString(); str += (" "); } -- cgit v1.2.3-70-g09d2 From 5b4b916b2700da746c12754ba3238eb1f3bbf5f7 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Sat, 15 Aug 2020 01:42:57 +0530 Subject: many changes to acls, aliases, sharing sidebar etc --- src/client/documents/Documents.ts | 2 +- src/client/util/CurrentUserUtils.ts | 2 +- src/client/util/SharingManager.tsx | 20 ++++++------ src/client/views/PropertiesButtons.tsx | 12 ++++--- .../collectionFreeForm/PropertiesView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 3 +- src/fields/util.ts | 37 ++++++++++++---------- 7 files changed, 42 insertions(+), 36 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 42ba4d2c4..c424c2bef 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -575,7 +575,7 @@ export namespace Docs { // without this, if a doc has no annotations but the user has AddOnly privileges, they won't be able to add an annotation because they would have needed to create the field's list which they don't have permissions to do. dataDoc[fieldKey + "-annotations"] = new List(); - dataDoc.aliases = new List(); + dataDoc.aliases = new List([viewDoc]); proto.links = ComputedField.MakeFunction("links(self)"); diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 68d02cd94..907b42327 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -846,7 +846,7 @@ export class CurrentUserUtils { // 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 })); + doc["sidebar-sharing"] = new PrefetchProxy(Docs.Create.StackingDocument([], { title: "Shared Documents", childDropAction: "alias", system: true, _yMargin: 30, _showTitle: "title", ignoreClick: true, lockedPosition: true })); } } diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index 48a3c023f..9d79188a3 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -155,16 +155,17 @@ export default class SharingManager extends React.Component<{}> { const users: ValidatedUser[] = this.users.filter(({ user: { email } }) => members.includes(email)); const target = targetDoc || this.targetDoc!; - const ACL = `ACL-${StrCast(group.groupName)}`; + const key = StrCast(group.groupName).replace(".", "_"); + const ACL = `ACL-${key}`; - target.author === Doc.CurrentUserEmail && distributeAcls(ACL, permission as SharingPermissions, target); + GetEffectiveAcl(target) === AclAdmin && distributeAcls(ACL, permission as SharingPermissions, target); // if documents have been shared, add the target to that list if it doesn't already exist, otherwise create a new list with the target group.docsShared ? Doc.IndexOf(target, DocListCast(group.docsShared)) === -1 && (group.docsShared as List).push(target) : group.docsShared = new List([target]); - users.forEach(({ notificationDoc }) => { + users.forEach(({ user, notificationDoc }) => { if (permission !== SharingPermissions.None) Doc.IndexOf(target, DocListCast(notificationDoc[storage])) === -1 && Doc.AddDocToList(notificationDoc, storage, target); // add the target to the notificationDoc if it hasn't already been added - else Doc.IndexOf(target, DocListCast(notificationDoc[storage])) !== -1 && Doc.RemoveDocFromList(notificationDoc, storage, target); // remove the target from the list if it already exists + else GetEffectiveAcl(target, undefined, user.email) === AclPrivate && Doc.IndexOf(target, DocListCast(notificationDoc[storage])) !== -1 && Doc.RemoveDocFromList(notificationDoc, storage, target); // remove the target from the list if it already exists }); } @@ -231,14 +232,11 @@ export default class SharingManager extends React.Component<{}> { const key = user.email.replace('.', '_'); const ACL = `ACL-${key}`; - target.author === Doc.CurrentUserEmail && distributeAcls(ACL, permission as SharingPermissions, target); + GetEffectiveAcl(target) === AclAdmin && distributeAcls(ACL, permission as SharingPermissions, target); + + if (permission !== SharingPermissions.None) Doc.IndexOf(target, DocListCast(notificationDoc[storage])) === -1 && Doc.AddDocToList(notificationDoc, storage, target); + else GetEffectiveAcl(target, undefined, user.email) === AclPrivate && Doc.IndexOf(target, DocListCast(notificationDoc[storage])) !== -1 && Doc.RemoveDocFromList(notificationDoc, storage, target); - if (permission !== SharingPermissions.None) { - Doc.IndexOf(target, DocListCast(notificationDoc[storage])) === -1 && Doc.AddDocToList(notificationDoc, storage, target); - } - else { - Doc.IndexOf(target, DocListCast(notificationDoc[storage])) !== -1 && Doc.RemoveDocFromList(notificationDoc, storage, target); - } } diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index 35d4f7f6e..dfedc9ccc 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -3,7 +3,7 @@ import { faArrowAltCircleDown, faArrowAltCircleRight, faArrowAltCircleUp, faChec import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { action, computed, observable, runInAction } from "mobx"; import { observer } from "mobx-react"; -import { Doc } from "../../fields/Doc"; +import { Doc, DataSym, AclEdit, AclAdmin } from "../../fields/Doc"; import { RichTextField } from '../../fields/RichTextField'; import { Cast, NumCast, BoolCast } from "../../fields/Types"; import { emptyFunction, setupMoveUpEvents, Utils } from "../../Utils"; @@ -30,6 +30,7 @@ import { undoBatch, UndoManager } from '../util/UndoManager'; import { DocumentType } from '../documents/DocumentTypes'; import { InkField } from '../../fields/InkField'; import { PresBox } from './nodes/PresBox'; +import { GetEffectiveAcl } from '../../fields/util'; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -710,6 +711,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { const isCollection = this.selectedDoc.type === DocumentType.COL ? true : false; const isFreeForm = this.selectedDoc._viewType === "freeform" ? true : false; const hasContext = this.selectedDoc.context ? true : false; + const collectionAcl = GetEffectiveAcl(this.selectedDocumentView?.props.ContainingCollectionDoc?.[DataSym]); return
@@ -733,9 +735,11 @@ export class PropertiesButtons extends React.Component<{}, {}> {
{this.downloadButton}
-
- {this.deleteButton} -
+ {collectionAcl === AclAdmin || collectionAcl === AclEdit ? +
+ {this.deleteButton} +
+ : (null)}
{this.onClickButton}
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx index 57e968aa7..b38eed495 100644 --- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx +++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx @@ -403,7 +403,7 @@ export class PropertiesView extends React.Component { // }) // shifts the current user and the owner to the top of the doc. - tableEntries.unshift(this.sharingItem("Me", effectiveAcl, Doc.CurrentUserEmail === this.selectedDoc!.author ? "Owner" : StrCast(this.selectedDoc![`ACL-${Doc.CurrentUserEmail.replace(".", "_")}`]))); + tableEntries.unshift(this.sharingItem("Me", effectiveAcl, Doc.CurrentUserEmail === this.selectedDoc!.author ? "Owner" : AclMap.get(effectiveAcl)!)); if (Doc.CurrentUserEmail !== this.selectedDoc!.author) tableEntries.unshift(this.sharingItem(StrCast(this.selectedDoc!.author), effectiveAcl, "Owner")); return
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index d92dc0ec2..3986a21e8 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -763,7 +763,8 @@ export class DocumentView extends DocComponent(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: "times" }); + const collectionAcl = GetEffectiveAcl(this.props.ContainingCollectionDoc?.[DataSym]); + if (collectionAcl === AclAdmin || collectionAcl === AclEdit) 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...")!); diff --git a/src/fields/util.ts b/src/fields/util.ts index 3d832636f..561d505e3 100644 --- a/src/fields/util.ts +++ b/src/fields/util.ts @@ -154,14 +154,16 @@ export enum SharingPermissions { /** * Calculates the effective access right to a document for the current user. */ -export function GetEffectiveAcl(target: any, in_prop?: string | symbol | number): symbol { +export function GetEffectiveAcl(target: any, in_prop?: string | symbol | number, user?: string): symbol { if (!target) return AclPrivate; if (in_prop === UpdatingFromServer || target[UpdatingFromServer]) return AclAdmin; if (target[AclSym] && Object.keys(target[AclSym]).length) { + const userChecked = user || Doc.CurrentUserEmail; + // if the current user is the author of the document / the current user is a member of the admin group - if (Doc.CurrentUserEmail === (target.__fields?.author || target.author) || currentUserGroups.includes("admin")) return AclAdmin; + if (userChecked === (target.__fields?.author || target.author) || currentUserGroups.includes("admin")) return AclAdmin; // if the ACL is being overriden or the property being modified is one of the playground fields (which can be freely modified) if (_overrideAcl || (in_prop && DocServer.PlaygroundFields?.includes(in_prop.toString()))) return AclEdit; @@ -178,7 +180,7 @@ export function GetEffectiveAcl(target: any, in_prop?: string | symbol | number) for (const [key, value] of Object.entries(target[AclSym])) { // there are issues with storing fields with . in the name, so they are replaced with _ during creation // as a result we need to restore them again during this comparison. - if (currentUserGroups.includes(key.substring(4)) || Doc.CurrentUserEmail === key.substring(4).replace("_", ".")) { + if (currentUserGroups.includes(key.substring(4).replace("_", ".")) || userChecked === key.substring(4).replace("_", ".")) { if (HierarchyMapping.get(value as symbol)! > HierarchyMapping.get(effectiveAcl)!) { effectiveAcl = value as symbol; if (effectiveAcl === AclAdmin) break; @@ -208,52 +210,53 @@ export function distributeAcls(key: string, acl: SharingPermissions, target: Doc ["Admin", 4] ]); - let changed = false; // determines whether fetchProto should be called or not (i.e. is there a change that should be reflected in target[AclSym]) + let layoutDocChanged = false; // determines whether fetchProto should be called or not (i.e. is there a change that should be reflected in target[AclSym]) + let dataDocChanged = false; const dataDoc = target[DataSym]; // if it is inheriting from a collection, it only inherits if A) the key doesn't already exist or B) the right being inherited is more restrictive if (!inheritingFromCollection || !target[key] || HierarchyMapping.get(StrCast(target[key]))! > HierarchyMapping.get(acl)!) { target[key] = acl; - changed = true; + layoutDocChanged = true; + } + + if (dataDoc && (!inheritingFromCollection || !dataDoc[key] || HierarchyMapping.get(StrCast(dataDoc[key]))! > HierarchyMapping.get(acl)!)) { + dataDoc[key] = acl; + dataDocChanged = true; // maps over the aliases of the document - const aliases = DocListCast(target.aliases); + const aliases = DocListCast(dataDoc.aliases); if (aliases.length) { aliases.map(alias => { alias !== target && distributeAcls(key, acl, alias, inheritingFromCollection); }); } - } - - if (dataDoc && (!inheritingFromCollection || !dataDoc[key] || HierarchyMapping.get(StrCast(dataDoc[key]))! > HierarchyMapping.get(acl)!)) { - dataDoc[key] = acl; - changed = true; - // maps over the children of the document DocListCast(dataDoc[Doc.LayoutFieldKey(dataDoc)]).map(d => { - if (d.author === Doc.CurrentUserEmail && (!inheritingFromCollection || !d[key] || HierarchyMapping.get(StrCast(d[key]))! > HierarchyMapping.get(acl)!)) { + if (GetEffectiveAcl(d) === AclAdmin && (!inheritingFromCollection || !d[key] || HierarchyMapping.get(StrCast(d[key]))! > HierarchyMapping.get(acl)!)) { distributeAcls(key, acl, d, inheritingFromCollection); } const data = d[DataSym]; - if (data && data.author === Doc.CurrentUserEmail && (!inheritingFromCollection || !data[key] || HierarchyMapping.get(StrCast(data[key]))! > HierarchyMapping.get(acl)!)) { + if (data && GetEffectiveAcl(data) === AclAdmin && (!inheritingFromCollection || !data[key] || HierarchyMapping.get(StrCast(data[key]))! > HierarchyMapping.get(acl)!)) { distributeAcls(key, acl, data, inheritingFromCollection); } }); // maps over the annotations of the document DocListCast(dataDoc[Doc.LayoutFieldKey(dataDoc) + "-annotations"]).map(d => { - if (d.author === Doc.CurrentUserEmail && (!inheritingFromCollection || !d[key] || HierarchyMapping.get(StrCast(d[key]))! > HierarchyMapping.get(acl)!)) { + if (GetEffectiveAcl(d) === AclAdmin && (!inheritingFromCollection || !d[key] || HierarchyMapping.get(StrCast(d[key]))! > HierarchyMapping.get(acl)!)) { distributeAcls(key, acl, d, inheritingFromCollection); } const data = d[DataSym]; - if (data && data.author === Doc.CurrentUserEmail && (!inheritingFromCollection || !data[key] || HierarchyMapping.get(StrCast(data[key]))! > HierarchyMapping.get(acl)!)) { + if (data && GetEffectiveAcl(data) === AclAdmin && (!inheritingFromCollection || !data[key] || HierarchyMapping.get(StrCast(data[key]))! > HierarchyMapping.get(acl)!)) { distributeAcls(key, acl, data, inheritingFromCollection); } }); } - changed && fetchProto(target); // updates target[AclSym] when changes to acls have been made + layoutDocChanged && fetchProto(target); // updates target[AclSym] when changes to acls have been made + dataDocChanged && fetchProto(dataDoc); } const layoutProps = ["panX", "panY", "width", "height", "nativeWidth", "nativeHeight", "fitWidth", "fitToBox", -- cgit v1.2.3-70-g09d2 From 291d2fb28fa878eff190daf813854d9c0477ccb6 Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 14 Aug 2020 17:29:55 -0400 Subject: cleaned up invocation of RichTextMenu --- src/client/util/CurrentUserUtils.ts | 2 +- src/client/views/AntimodeMenu.tsx | 4 ++- src/client/views/DocumentDecorations.tsx | 4 +-- src/client/views/MainView.tsx | 1 - src/client/views/collections/CollectionMenu.tsx | 8 ++--- .../views/collections/CollectionSchemaCells.tsx | 5 ++-- .../collectionFreeForm/FormatShapePane.tsx | 4 +-- .../collectionFreeForm/MarqueeOptionsMenu.tsx | 4 +-- .../views/nodes/formattedText/FormattedTextBox.tsx | 13 +++++---- .../views/nodes/formattedText/RichTextMenu.tsx | 34 +++++++++------------- src/client/views/pdf/PDFMenu.tsx | 4 +-- 11 files changed, 40 insertions(+), 43 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 68d02cd94..bd22b8e9d 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -451,7 +451,7 @@ export class CurrentUserUtils { // { title: "use stamp", icon: "stamp", click: 'activateStamp(this.activeInkPen = sameDocs(this.activeInkPen, this) ? undefined : this)', backgroundColor: "orange", ischecked: `sameDocs(this.activeInkPen, this)`, activeInkPen: doc }, // { title: "use eraser", icon: "eraser", click: 'activateEraser(this.activeInkPen = sameDocs(this.activeInkPen, this) ? undefined : this);', ischecked: `sameDocs(this.activeInkPen, this)`, backgroundColor: "pink", activeInkPen: doc }, // { title: "use drag", icon: "mouse-pointer", click: 'deactivateInk();this.activeInkPen = this;', ischecked: `sameDocs(this.activeInkPen, this)`, backgroundColor: "white", activeInkPen: doc }, - { toolTip: "Tap to create a document previewer in a new pane, drag for a document previewer", title: "Prev", icon: "expand", click: 'openOnRight(getCopy(this.dragFactory, true))', drag: 'getCopy(this.dragFactory,true)', dragFactory: doc.emptyDocHolder as Doc }, + { toolTip: "Tap to create a document previewer in a new pane, drag for a document previewer", title: "Prev", icon: "expand", click: 'openOnRight(getCopy(this.dragFactory, true))', drag: 'getCopy(this.dragFactory, true)', dragFactory: doc.emptyDocHolder as Doc }, { toolTip: "Toggle a Calculator REPL", title: "repl", icon: "calculator", click: 'addOverlayWindow("ScriptingRepl", { x: 300, y: 100, width: 200, height: 200, title: "Scripting REPL" })' }, { toolTip: "Connect a Google Account", title: "Google Account", icon: "external-link-alt", click: 'GoogleAuthenticationManager.Instance.fetchOrGenerateAccessToken(true)' }, ]; diff --git a/src/client/views/AntimodeMenu.tsx b/src/client/views/AntimodeMenu.tsx index 68ccefcb5..9f16d0fe1 100644 --- a/src/client/views/AntimodeMenu.tsx +++ b/src/client/views/AntimodeMenu.tsx @@ -1,12 +1,14 @@ import React = require("react"); import { observable, action } from "mobx"; import "./AntimodeMenu.scss"; +export interface AntimodeMenuProps { +} /** * This is an abstract class that serves as the base for a PDF-style or Marquee-style * menu. To use this class, look at PDFMenu.tsx or MarqueeOptionsMenu.tsx for an example. */ -export default abstract class AntimodeMenu extends React.Component { +export default abstract class AntimodeMenu extends React.Component { protected _offsetY: number = 0; protected _offsetX: number = 0; protected _mainCont: React.RefObject = React.createRef(); diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 03746a1d2..3f16dd7e7 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -659,8 +659,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> if (bounds.y > bounds.b) { bounds.y = bounds.b - (this._resizeBorderWidth + this._linkBoxHeight + this._titleHeight); } - var offset = 0; - let useRotation = seldoc.rootDoc.type === DocumentType.INK; + let offset = 0; + const useRotation = seldoc.rootDoc.type === DocumentType.INK; return (
{this.search} -
{LinkDescriptionPopup.descriptionPopup ? : null} {DocumentLinksButton.EditLink ? : (null)} diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 5119ff6c9..0b3be8739 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -21,7 +21,7 @@ import { CurrentUserUtils } from "../../util/CurrentUserUtils"; import { DragManager } from "../../util/DragManager"; import { SelectionManager } from "../../util/SelectionManager"; import { undoBatch } from "../../util/UndoManager"; -import AntimodeMenu from "../AntimodeMenu"; +import AntimodeMenu, { AntimodeMenuProps } from "../AntimodeMenu"; import { EditableView } from "../EditableView"; import GestureOverlay from "../GestureOverlay"; import { ActiveFillColor, ActiveInkColor, SetActiveArrowEnd, SetActiveArrowStart, SetActiveBezierApprox, SetActiveFillColor, SetActiveInkColor, SetActiveInkWidth } from "../InkingStroke"; @@ -32,13 +32,13 @@ import "./CollectionMenu.scss"; import { CollectionViewType, COLLECTION_BORDER_WIDTH } from "./CollectionView"; @observer -export default class CollectionMenu extends AntimodeMenu { +export default class CollectionMenu extends AntimodeMenu { static Instance: CollectionMenu; @observable SelectedCollection: DocumentView | undefined; @observable FieldKey: string; - constructor(props: Readonly<{}>) { + constructor(props: any) { super(props); this.FieldKey = ""; CollectionMenu.Instance = this; @@ -655,7 +655,7 @@ export class CollectionFreeFormViewChrome extends React.Component : (null) } - {this.isText ? : null} + {this.isText ? : null}
; } } diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index 20ce6b76d..11470e940 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -82,9 +82,8 @@ export class CollectionSchemaCell extends React.Component { const doc = Doc.GetProto(this.props.rowProps.original); const aliasdoc = await SearchUtil.GetAliasesOfDocument(doc); if (aliasdoc.length > 0) { - const targetContext = Cast(aliasdoc[0].context, Doc) as Doc; - console.log(StrCast(targetContext.title)); - runInAction(() => this.contents = StrCast(targetContext.title)); + const targetContext = Cast(aliasdoc[0].context, Doc, null); + targetContext && runInAction(() => this.contents = StrCast(targetContext.title)); } } diff --git a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx index 1ffa2fbed..a7f44bbbf 100644 --- a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx +++ b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx @@ -9,13 +9,13 @@ import { InkField } from "../../../../fields/InkField"; import { BoolCast, Cast, NumCast } from "../../../../fields/Types"; import { DocumentType } from "../../../documents/DocumentTypes"; import { SelectionManager } from "../../../util/SelectionManager"; -import AntimodeMenu from "../../AntimodeMenu"; +import AntimodeMenu, { AntimodeMenuProps } from "../../AntimodeMenu"; import "./FormatShapePane.scss"; import { undoBatch } from "../../../util/UndoManager"; import { ColorState, SketchPicker } from 'react-color'; @observer -export default class FormatShapePane extends AntimodeMenu { +export default class FormatShapePane extends AntimodeMenu { static Instance: FormatShapePane; private _lastFill = "#D0021B"; diff --git a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx index f1df7998b..2cfe0183c 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx @@ -1,5 +1,5 @@ import React = require("react"); -import AntimodeMenu from "../../AntimodeMenu"; +import AntimodeMenu, { AntimodeMenuProps } from "../../AntimodeMenu"; import { observer } from "mobx-react"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { unimplementedFunction } from "../../../../Utils"; @@ -7,7 +7,7 @@ import { undoBatch } from "../../../util/UndoManager"; import { Tooltip } from "@material-ui/core"; @observer -export default class MarqueeOptionsMenu extends AntimodeMenu { +export default class MarqueeOptionsMenu extends AntimodeMenu { static Instance: MarqueeOptionsMenu; public createCollection: (e: KeyboardEvent | React.PointerEvent | undefined) => void = unimplementedFunction; diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 8c05d3603..c31e7469f 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -34,7 +34,7 @@ import { DictationManager } from '../../../util/DictationManager'; import { DragManager } from "../../../util/DragManager"; import { makeTemplate } from '../../../util/DropConverter'; import buildKeymap, { updateBullets } from "./ProsemirrorExampleTransfer"; -import RichTextMenu from './RichTextMenu'; +import RichTextMenu, { RichTextMenuPlugin } from './RichTextMenu'; import { RichTextRules } from "./RichTextRules"; //import { DashDocView } from "./DashDocView"; @@ -1306,7 +1306,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp // jump rich text menu to this textbox const bounds = this._ref.current?.getBoundingClientRect(); - if (bounds && this.layoutDoc._chromeStatus !== "disabled") { + if (bounds && this.layoutDoc._chromeStatus !== "disabled" && RichTextMenu.Instance) { const x = Math.min(Math.max(bounds.left, 0), window.innerWidth - RichTextMenu.Instance.width); let y = Math.min(Math.max(0, bounds.top - RichTextMenu.Instance.height - 50), window.innerHeight - RichTextMenu.Instance.height); if (coords && coords.left > x && coords.left < x + RichTextMenu.Instance.width && coords.top > y && coords.top < y + RichTextMenu.Instance.height + 50) { @@ -1410,11 +1410,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } } + menuPlugin: any; + richTextMenuPlugin() { + const self = this; return new Plugin({ view(newView) { - RichTextMenu.Instance?.changeView(newView); - return RichTextMenu.Instance; + self.props.isSelected(true) && (RichTextMenu.Instance.view = newView); + return self.menuPlugin = new RichTextMenuPlugin({ editorProps: this.props }); } }); } @@ -1524,7 +1527,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const scale = this.props.hideOnLeave ? 1 : this.props.ContentScaling() * NumCast(this.layoutDoc._viewScale, 1); const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : ""; const interactive = Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc.isBackground; - setTimeout(() => this._editorView && RichTextMenu.Instance.updateFromDash(this._editorView, undefined, this.props), this.props.isSelected() ? 10 : 0); // need to make sure that we update a text box that is selected after updating the one that was deselected + setTimeout(() => this._editorView && RichTextMenu.Instance?.updateMenu(this._editorView, undefined, this.props), this.props.isSelected() ? 10 : 0); // need to make sure that we update a text box that is selected after updating the one that was deselected if (!this.props.isSelected() && FormattedTextBoxComment.textBox === this) { setTimeout(() => FormattedTextBoxComment.Hide(), 0); } diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx index b683fb25d..25b0279ba 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.tsx +++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx @@ -16,7 +16,7 @@ import { unimplementedFunction, Utils } from "../../../../Utils"; import { DocServer } from "../../../DocServer"; import { LinkManager } from "../../../util/LinkManager"; import { SelectionManager } from "../../../util/SelectionManager"; -import AntimodeMenu from "../../AntimodeMenu"; +import AntimodeMenu, { AntimodeMenuProps } from "../../AntimodeMenu"; import { FieldViewProps } from "../FieldView"; import { FormattedTextBox, FormattedTextBoxProps } from "./FormattedTextBox"; import { updateBullets } from "./ProsemirrorExampleTransfer"; @@ -31,11 +31,11 @@ library.add(faBold, faItalic, faChevronLeft, faUnderline, faStrikethrough, faSup @observer -export default class RichTextMenu extends AntimodeMenu { +export default class RichTextMenu extends AntimodeMenu { static Instance: RichTextMenu; public overMenu: boolean = false; // kind of hacky way to prevent selects not being selectable - private view?: EditorView; + public view?: EditorView; public editorProps: FieldViewProps & FormattedTextBoxProps | undefined; public _brushMap: Map> = new Map(); @@ -156,21 +156,7 @@ export default class RichTextMenu extends AntimodeMenu { public delayHide = () => this._delayHide = true; @action - changeView(view: EditorView) { - if ((view as any)?.TextView?.props.isSelected(true)) { - this.view = view; - } - } - - update(view: EditorView, lastState: EditorState | undefined) { - RichTextMenu.Instance.updateFromDash(view, lastState, this.editorProps); - } - - @action - public async updateFromDash(view: EditorView, lastState: EditorState | undefined, props: any) { - RichTextMenu.Instance.finalUpdateFromDash(view, lastState, props); - } - public async finalUpdateFromDash(view: EditorView, lastState: EditorState | undefined, props: any) { + public updateMenu(view: EditorView, lastState: EditorState | undefined, props: any) { if (!view || !(view as any).TextView?.props.isSelected(true)) { return; } @@ -199,8 +185,7 @@ export default class RichTextMenu extends AntimodeMenu { this.activeHighlightColor = !activeHighlights.length ? "" : activeHighlights.length === 1 ? String(activeHighlights[0]) : "..."; // update link in current selection - const targetTitle = await this.getTextLinkTargetTitle(); - this.setCurrentLink(targetTitle); + this.getTextLinkTargetTitle().then(targetTitle => this.setCurrentLink(targetTitle)); } setMark = (mark: Mark, state: EditorState, dispatch: any, dontToggle: boolean = false) => { @@ -1070,4 +1055,13 @@ export class ButtonDropdown extends React.Component {
); } +} + + +interface RichTextMenuPluginProps { + editorProps: any; +} +export class RichTextMenuPlugin extends React.Component { + render() { return null; } + update(view: EditorView, lastState: EditorState | undefined) { RichTextMenu.Instance?.updateMenu(view, lastState, this.props.editorProps); } } \ No newline at end of file diff --git a/src/client/views/pdf/PDFMenu.tsx b/src/client/views/pdf/PDFMenu.tsx index 7bea8d01b..bee282d9b 100644 --- a/src/client/views/pdf/PDFMenu.tsx +++ b/src/client/views/pdf/PDFMenu.tsx @@ -4,14 +4,14 @@ import { observable, action, computed, } from "mobx"; import { observer } from "mobx-react"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { unimplementedFunction, returnFalse, Utils } from "../../../Utils"; -import AntimodeMenu from "../AntimodeMenu"; +import AntimodeMenu, { AntimodeMenuProps } from "../AntimodeMenu"; import { Doc, Opt } from "../../../fields/Doc"; import { ColorState } from "react-color"; import { ButtonDropdown } from "../nodes/formattedText/RichTextMenu"; @observer -export default class PDFMenu extends AntimodeMenu { +export default class PDFMenu extends AntimodeMenu { static Instance: PDFMenu; private _commentCont = React.createRef(); -- cgit v1.2.3-70-g09d2 From 624de3234c8daccdeb0d759c407cbd72880d3b35 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Sat, 15 Aug 2020 16:51:30 +0530 Subject: mainly ui --- src/client/views/collections/collectionFreeForm/PropertiesView.scss | 1 - src/client/views/collections/collectionFreeForm/PropertiesView.tsx | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.scss b/src/client/views/collections/collectionFreeForm/PropertiesView.scss index aee28366a..ddaca7d42 100644 --- a/src/client/views/collections/collectionFreeForm/PropertiesView.scss +++ b/src/client/views/collections/collectionFreeForm/PropertiesView.scss @@ -267,7 +267,6 @@ padding: 3px; align-items: center; border-bottom: 0.5px solid grey; - cursor: pointer; &:hover .propertiesView-sharingTable-item-name { overflow-x: unset; diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx index b38eed495..5c1ec1280 100644 --- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx +++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx @@ -389,7 +389,7 @@ export class PropertiesView extends React.Component { if (this.selectedDoc![AclSym]) { for (const [key, value] of Object.entries(this.selectedDoc![AclSym])) { const name = key.substring(4).replace("_", "."); - if (name !== Doc.CurrentUserEmail && name !== this.selectedDoc!.author/* && sidebarUsersDisplayed![name] !== false*/) { + if (name !== Doc.CurrentUserEmail && name !== this.selectedDoc!.author && name !== "Public"/* && sidebarUsersDisplayed![name] !== false*/) { tableEntries.push(this.sharingItem(name, effectiveAcl, AclMap.get(value)!)); } } @@ -402,7 +402,8 @@ export class PropertiesView extends React.Component { // } // }) - // shifts the current user and the owner to the top of the doc. + // shifts the current user, owner, public to the top of the doc. + tableEntries.unshift(this.sharingItem("Public", effectiveAcl, AclMap.get(this.selectedDoc![AclSym]["ACL-Public"])!)) tableEntries.unshift(this.sharingItem("Me", effectiveAcl, Doc.CurrentUserEmail === this.selectedDoc!.author ? "Owner" : AclMap.get(effectiveAcl)!)); if (Doc.CurrentUserEmail !== this.selectedDoc!.author) tableEntries.unshift(this.sharingItem(StrCast(this.selectedDoc!.author), effectiveAcl, "Owner")); -- cgit v1.2.3-70-g09d2 From e7fd28e27e7389c67c22410ed1a3ff313556a153 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Sat, 15 Aug 2020 19:20:52 +0530 Subject: more alias stuff --- src/client/util/SharingManager.tsx | 4 ++-- src/client/views/collections/collectionFreeForm/PropertiesView.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index 9d79188a3..30935c5dd 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -165,7 +165,7 @@ export default class SharingManager extends React.Component<{}> { users.forEach(({ user, notificationDoc }) => { if (permission !== SharingPermissions.None) Doc.IndexOf(target, DocListCast(notificationDoc[storage])) === -1 && Doc.AddDocToList(notificationDoc, storage, target); // add the target to the notificationDoc if it hasn't already been added - else GetEffectiveAcl(target, undefined, user.email) === AclPrivate && Doc.IndexOf(target, DocListCast(notificationDoc[storage])) !== -1 && Doc.RemoveDocFromList(notificationDoc, storage, target); // remove the target from the list if it already exists + else GetEffectiveAcl(target, undefined, user.email) === AclPrivate && Doc.IndexOf((target.aliasOf as Doc || target), DocListCast(notificationDoc[storage])) !== -1 && Doc.RemoveDocFromList(notificationDoc, storage, (target.aliasOf as Doc || target)); // remove the target from the list if it already exists }); } @@ -235,7 +235,7 @@ export default class SharingManager extends React.Component<{}> { GetEffectiveAcl(target) === AclAdmin && distributeAcls(ACL, permission as SharingPermissions, target); if (permission !== SharingPermissions.None) Doc.IndexOf(target, DocListCast(notificationDoc[storage])) === -1 && Doc.AddDocToList(notificationDoc, storage, target); - else GetEffectiveAcl(target, undefined, user.email) === AclPrivate && Doc.IndexOf(target, DocListCast(notificationDoc[storage])) !== -1 && Doc.RemoveDocFromList(notificationDoc, storage, target); + else GetEffectiveAcl(target, undefined, user.email) === AclPrivate && Doc.IndexOf((target.aliasOf as Doc || target), DocListCast(notificationDoc[storage])) !== -1 && Doc.RemoveDocFromList(notificationDoc, storage, (target.aliasOf as Doc || target)); } diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx index 5c1ec1280..5b58d0ef4 100644 --- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx +++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx @@ -403,7 +403,7 @@ export class PropertiesView extends React.Component { // }) // shifts the current user, owner, public to the top of the doc. - tableEntries.unshift(this.sharingItem("Public", effectiveAcl, AclMap.get(this.selectedDoc![AclSym]["ACL-Public"])!)) + tableEntries.unshift(this.sharingItem("Public", effectiveAcl, (AclMap.get(this.selectedDoc![AclSym]?.["ACL-Public"]) || SharingPermissions.None))); tableEntries.unshift(this.sharingItem("Me", effectiveAcl, Doc.CurrentUserEmail === this.selectedDoc!.author ? "Owner" : AclMap.get(effectiveAcl)!)); if (Doc.CurrentUserEmail !== this.selectedDoc!.author) tableEntries.unshift(this.sharingItem(StrCast(this.selectedDoc!.author), effectiveAcl, "Owner")); -- cgit v1.2.3-70-g09d2 From a248e49ddbabe1947a3883bba47e786e22e1158a Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Mon, 17 Aug 2020 16:21:12 +0530 Subject: added layoutdoc toggles --- src/client/util/SharingManager.scss | 21 +++++++++- src/client/util/SharingManager.tsx | 46 +++++++++++++--------- .../collectionFreeForm/PropertiesView.scss | 14 +++++++ .../collectionFreeForm/PropertiesView.tsx | 26 ++++++++---- 4 files changed, 79 insertions(+), 28 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/util/SharingManager.scss b/src/client/util/SharingManager.scss index 7912db74d..42c300712 100644 --- a/src/client/util/SharingManager.scss +++ b/src/client/util/SharingManager.scss @@ -62,6 +62,7 @@ input { height: 10px; + cursor: pointer; } label { @@ -69,11 +70,29 @@ font-style: italic; } } + + .layoutDoc-acls { + display: flex; + flex-direction: column; + float: right; + margin-right: 12; + margin-top: -15; + align-items: center; + + label { + font-weight: normal; + font-style: italic; + } + + input { + cursor: pointer; + } + } } .main-container { display: flex; - margin-top: -10px; + margin-top: -25px; .individual-container, .group-container { diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index 30935c5dd..5a863c813 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -1,7 +1,7 @@ import { observable, runInAction, action } from "mobx"; import * as React from "react"; import MainViewModal from "../views/MainViewModal"; -import { Doc, Opt, AclAdmin, AclPrivate, DocListCast } from "../../fields/Doc"; +import { Doc, Opt, AclAdmin, AclPrivate, DocListCast, DataSym } from "../../fields/Doc"; import { DocServer } from "../DocServer"; import { Cast, StrCast } from "../../fields/Types"; import * as RequestPromise from "request-promise"; @@ -25,7 +25,6 @@ import { library } from "@fortawesome/fontawesome-svg-core"; library.add(fa.faInfoCircle, fa.faCaretUp, fa.faCaretRight, fa.faCaretDown); - export interface User { email: string; userDocumentId: string; @@ -47,6 +46,8 @@ interface GroupedOptions { const indType = "!indType/"; const groupType = "!groupType/"; +const storage = "data"; + /** * A user who also has a notificationDoc. */ @@ -55,7 +56,6 @@ interface ValidatedUser { notificationDoc: Doc; } -const storage = "data"; @observer export default class SharingManager extends React.Component<{}> { @@ -75,7 +75,8 @@ export default class SharingManager extends React.Component<{}> { // if both showUserOptions and showGroupOptions are false then both are displayed @observable private showUserOptions: boolean = false; // whether to show individuals as options when sharing (in the react-select component) @observable private showGroupOptions: boolean = false; // // whether to show groups as options when sharing (in the react-select component) - private populating: boolean = false; + private populating: boolean = false; // whether the list of users is populating or not + @observable private layoutDocAcls: boolean = false; // whether the layout doc or data doc's acls are to be used // private get linkVisible() { // return this.sharingDoc ? this.sharingDoc[PublicKey] !== SharingPermissions.None : false; @@ -176,7 +177,6 @@ export default class SharingManager extends React.Component<{}> { */ shareWithAddedMember = (group: Doc, emailId: string) => { const user: ValidatedUser = this.users.find(({ user: { email } }) => email === emailId)!; - if (group.docsShared) DocListCast(group.docsShared).forEach(doc => Doc.IndexOf(doc, DocListCast(user.notificationDoc[storage])) === -1 && Doc.AddDocToList(user.notificationDoc, storage, doc)); } @@ -184,9 +184,12 @@ export default class SharingManager extends React.Component<{}> { * Called from the properties sidebar to change permissions of a user. */ shareFromPropertiesSidebar = (shareWith: string, permission: SharingPermissions, target: Doc) => { - const user = this.users.find(({ user: { email } }) => email === (shareWith === "Me" ? Doc.CurrentUserEmail : shareWith)); - if (user) this.setInternalSharing(user, permission, target); - else this.setInternalGroupSharing(GroupManager.Instance.getGroup(shareWith)!, permission, target); + if (shareWith !== "Public") { + const user = this.users.find(({ user: { email } }) => email === (shareWith === "Me" ? Doc.CurrentUserEmail : shareWith)); + if (user) this.setInternalSharing(user, permission, target); + else this.setInternalGroupSharing(GroupManager.Instance.getGroup(shareWith)!, permission, target); + } + else if (GetEffectiveAcl(target) === AclAdmin) distributeAcls("ACL-Public", permission, target); } /** @@ -370,8 +373,8 @@ export default class SharingManager extends React.Component<{}> { * @returns the main interface of the SharingManager. */ private get sharingInterface() { - const groupList = GroupManager.Instance?.getAllGroups() || []; + const groupList = GroupManager.Instance?.getAllGroups() || []; const sortedUsers = this.users.slice().sort(this.sortUsers) .map(({ user: { email } }) => ({ label: email, value: indType + email })); const sortedGroups = groupList.slice().sort(this.sortGroups) @@ -404,17 +407,19 @@ export default class SharingManager extends React.Component<{}> { } } - const users = this.individualSort === "ascending" ? this.users.sort(this.sortUsers) : this.individualSort === "descending" ? this.users.sort(this.sortUsers).reverse() : this.users; - const groups = this.groupSort === "ascending" ? groupList.sort(this.sortGroups) : this.groupSort === "descending" ? groupList.sort(this.sortGroups).reverse() : groupList; + const users = this.individualSort === "ascending" ? this.users.slice().sort(this.sortUsers) : this.individualSort === "descending" ? this.users.slice().sort(this.sortUsers).reverse() : this.users; + const groups = this.groupSort === "ascending" ? groupList.slice().sort(this.sortGroups) : this.groupSort === "descending" ? groupList.slice().sort(this.sortGroups).reverse() : groupList; - const effectiveAcl = this.targetDoc ? GetEffectiveAcl(this.targetDoc) : AclPrivate; + const targetDoc = this.layoutDocAcls ? this.targetDoc : this.targetDoc?.[DataSym]; + + const effectiveAcl = targetDoc ? GetEffectiveAcl(targetDoc) : AclPrivate; // the list of users shared with const userListContents: (JSX.Element | null)[] = users.map(({ user, notificationDoc }) => { const userKey = user.email.replace('.', '_'); - const permissions = StrCast(this.targetDoc?.[`ACL-${userKey}`]); + const permissions = StrCast(targetDoc?.[`ACL-${userKey}`]); - return !permissions || user.email === this.targetDoc?.author ? null : ( + return !permissions || user.email === targetDoc?.author ? (null) : (
{ key={"owner"} className={"container"} > - {this.targetDoc?.author === Doc.CurrentUserEmail ? "Me" : this.targetDoc?.author} + {targetDoc?.author === Doc.CurrentUserEmail ? "Me" : targetDoc?.author}
Owner @@ -454,7 +459,7 @@ export default class SharingManager extends React.Component<{}> {
), - this.targetDoc?.author !== Doc.CurrentUserEmail ? + targetDoc?.author !== Doc.CurrentUserEmail ? (
{ Me
- {this.targetDoc?.[`ACL-${Doc.CurrentUserEmail.replace(".", "_")}`]} + {targetDoc?.[`ACL-${Doc.CurrentUserEmail.replace(".", "_")}`]}
@@ -472,7 +477,7 @@ export default class SharingManager extends React.Component<{}> { // the list of groups shared with const groupListContents = groups.map(group => { - const permissions = StrCast(this.targetDoc?.[`ACL-${StrCast(group.groupName)}`]); + const permissions = StrCast(targetDoc?.[`ACL-${StrCast(group.groupName)}`]); return !permissions ? null : (
{
*/}
-

Share {this.focusOn(StrCast(this.targetDoc?.title, "this document"))}

+

Share {this.focusOn(StrCast(targetDoc?.title, "this document"))}

@@ -569,6 +574,9 @@ export default class SharingManager extends React.Component<{}> { this.showUserOptions = !this.showUserOptions)} /> this.showGroupOptions = !this.showGroupOptions)} />
+
+ this.layoutDocAcls = !this.layoutDocAcls)} checked={this.layoutDocAcls} /> +
}
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.scss b/src/client/views/collections/collectionFreeForm/PropertiesView.scss index ddaca7d42..535581f2e 100644 --- a/src/client/views/collections/collectionFreeForm/PropertiesView.scss +++ b/src/client/views/collections/collectionFreeForm/PropertiesView.scss @@ -121,6 +121,19 @@ padding: 10px; margin-left: 5px; + .propertiesView-acls-checkbox { + float: right; + height: 20px; + margin-top: -20px; + margin-right: -15; + + .propertiesView-acls-checkbox-text { + font-size: 7px; + margin-top: -10px; + margin-left: 6px; + } + } + .change-buttons { display: flex; @@ -259,6 +272,7 @@ background-color: #ececec; max-height: 130px; overflow-y: scroll; + width: 92%; .propertiesView-sharingTable-item { diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx index 5b58d0ef4..85a1d7137 100644 --- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx +++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx @@ -2,7 +2,7 @@ import React = require("react"); import { observer } from "mobx-react"; import "./PropertiesView.scss"; import { observable, action, computed, runInAction } from "mobx"; -import { Doc, Field, WidthSym, HeightSym, AclSym, AclPrivate, AclReadonly, AclAddonly, AclEdit, AclAdmin, Opt, DocCastAsync } from "../../../../fields/Doc"; +import { Doc, Field, WidthSym, HeightSym, AclSym, AclPrivate, AclReadonly, AclAddonly, AclEdit, AclAdmin, Opt, DocCastAsync, DataSym } from "../../../../fields/Doc"; import { ComputedField } from "../../../../fields/ScriptField"; import { EditableView } from "../../EditableView"; import { KeyValueBox } from "../../nodes/KeyValueBox"; @@ -73,6 +73,7 @@ export class PropertiesView extends React.Component { @observable openTransform: boolean = true; // @observable selectedUser: string = ""; // @observable addButtonPressed: boolean = false; + @observable layoutDocAcls: boolean = false; //Pres Trails booleans: @observable openPresTransitions: boolean = false; @@ -386,11 +387,12 @@ export class PropertiesView extends React.Component { const tableEntries = []; // DocCastAsync(Doc.UserDoc().sidebarUsersDisplayed).then(sidebarUsersDisplayed => { - if (this.selectedDoc![AclSym]) { - for (const [key, value] of Object.entries(this.selectedDoc![AclSym])) { + const target = this.layoutDocAcls ? this.selectedDoc! : this.selectedDoc![DataSym]; + if (target[AclSym]) { + for (const [key, value] of Object.entries(target[AclSym])) { const name = key.substring(4).replace("_", "."); - if (name !== Doc.CurrentUserEmail && name !== this.selectedDoc!.author && name !== "Public"/* && sidebarUsersDisplayed![name] !== false*/) { - tableEntries.push(this.sharingItem(name, effectiveAcl, AclMap.get(value)!)); + if (name !== Doc.CurrentUserEmail && name !== target.author && name !== "Public"/* && sidebarUsersDisplayed![name] !== false*/) { + tableEntries.push(this.sharingItem(name, effectiveAcl, AclMap.get(value as symbol)!)); } } } @@ -403,9 +405,9 @@ export class PropertiesView extends React.Component { // }) // shifts the current user, owner, public to the top of the doc. - tableEntries.unshift(this.sharingItem("Public", effectiveAcl, (AclMap.get(this.selectedDoc![AclSym]?.["ACL-Public"]) || SharingPermissions.None))); - tableEntries.unshift(this.sharingItem("Me", effectiveAcl, Doc.CurrentUserEmail === this.selectedDoc!.author ? "Owner" : AclMap.get(effectiveAcl)!)); - if (Doc.CurrentUserEmail !== this.selectedDoc!.author) tableEntries.unshift(this.sharingItem(StrCast(this.selectedDoc!.author), effectiveAcl, "Owner")); + tableEntries.unshift(this.sharingItem("Public", effectiveAcl, (AclMap.get(target[AclSym]?.["ACL-Public"]) || SharingPermissions.None))); + tableEntries.unshift(this.sharingItem("Me", effectiveAcl, Doc.CurrentUserEmail === target.author ? "Owner" : AclMap.get(effectiveAcl)!)); + if (Doc.CurrentUserEmail !== target.author) tableEntries.unshift(this.sharingItem(StrCast(target.author), effectiveAcl, "Owner")); return
{tableEntries} @@ -867,6 +869,14 @@ export class PropertiesView extends React.Component {
{!this.openSharing ? (null) :
+
+ this.layoutDocAcls = !this.layoutDocAcls)} + checked={this.layoutDocAcls} + />; +
Layout
+
{this.sharingTable} {/*
, +
Pin to presentation with selected view
} placement="bottom"> + +
, ]; return this.getElement(buttons); } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index c0b19fcd2..29982212f 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -22,6 +22,8 @@ import MarqueeOptionsMenu from "./MarqueeOptionsMenu"; import "./MarqueeView.scss"; import React = require("react"); import { ContextMenuItem } from "../../ContextMenuItem"; +import { CollectionDockingView } from "../CollectionDockingView"; +import { DocumentManager } from "../../../util/DocumentManager"; interface MarqueeViewProps { getContainerTransform: () => Transform; @@ -250,6 +252,7 @@ export class MarqueeView extends React.Component { + const doc = this.props.Document; + const bounds = this.Bounds; + const selected = this.marqueeSelect(false); + const curPres = Cast(Doc.UserDoc().activePresentation, Doc) as Doc; + if (curPres) { + const pinDoc = Doc.MakeAlias(doc); + pinDoc.presentationTargetDoc = doc; + 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); + } + if (e instanceof KeyboardEvent ? e.key === "c" : true) { + const x = this.Bounds.left + this.Bounds.width / 2; + const y = this.Bounds.top + this.Bounds.height / 2; + const panelWidth: number = this.props.PanelWidth(); + const panelHeight: number = this.props.PanelHeight(); + const scale = Math.min(Number(panelWidth) / this.Bounds.width, Number(panelHeight) / this.Bounds.height); + pinDoc.presPinView = true; + pinDoc.presPinViewX = x; + pinDoc.presPinViewY = y; + pinDoc.presPinViewScale = scale; + } + } + MarqueeOptionsMenu.Instance.fadeOut(true); + this.hideMarquee(); + } + @undoBatch @action collection = (e: KeyboardEvent | React.PointerEvent | undefined) => { const bounds = this.Bounds; diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 5fc76223d..5d6ad25bb 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -58,9 +58,10 @@ export class PresBox extends ViewBoxBaseComponent @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 activeItem() { return Cast(this.childDocs[this.itemIndex], Doc, null); } + @computed get targetDoc() { return Cast(this.activeItem?.presentationTargetDoc, Doc, null); } @computed get presElement() { return Cast(Doc.UserDoc().presElement, Doc, null); } constructor(props: any) { super(props); @@ -123,31 +124,31 @@ export class PresBox extends ViewBoxBaseComponent next = () => { this.updateCurrentPresentation(); const activeNext = Cast(this.childDocs[this.itemIndex + 1], Doc, null); - const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - const presTargetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); - const childDocs = DocListCast(presTargetDoc[Doc.LayoutFieldKey(presTargetDoc)]); - const currentFrame = Cast(presTargetDoc.currentFrame, "number", null); - const lastFrame = Cast(presTargetDoc.lastFrame, "number", null); - const curFrame = NumCast(presTargetDoc.currentFrame); + const activeItem: Doc = this.activeItem; + const targetDoc: Doc = this.targetDoc; + const childDocs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]); + const currentFrame = Cast(targetDoc.currentFrame, "number", null); + const lastFrame = Cast(targetDoc.lastFrame, "number", null); + const curFrame = NumCast(targetDoc.currentFrame); let internalFrames: boolean = false; - if (presTargetDoc.presProgressivize || activeItem.zoomProgressivize || presTargetDoc.scrollProgressivize) internalFrames = true; + if (targetDoc.presProgressivize || activeItem.zoomProgressivize || targetDoc.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, presTargetDoc); - else presTargetDoc.editing = true; - if (activeItem.zoomProgressivize) this.zoomProgressivizeNext(presTargetDoc); + targetDoc._viewTransition = "all 1s"; + setTimeout(() => targetDoc._viewTransition = undefined, 1010); + targetDoc.currentFrame = curFrame + 1; + if (targetDoc.scrollProgressivize) CollectionFreeFormDocumentView.updateScrollframe(targetDoc, currentFrame); + if (targetDoc.presProgressivize) CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0, targetDoc); + else targetDoc.editing = true; + if (activeItem.zoomProgressivize) this.zoomProgressivizeNext(targetDoc); // Case 2: Audio or video therefore wait to play the audio or video before moving on - } else if ((presTargetDoc.type === DocumentType.AUDIO) && !this._moveOnFromAudio && this.layoutDoc.presStatus !== 'auto') { + } else if ((targetDoc.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(); + if (targetDoc.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) { @@ -166,15 +167,15 @@ export class PresBox extends ViewBoxBaseComponent @action back = () => { this.updateCurrentPresentation(); - const docAtCurrent = this.childDocs[this.itemIndex]; - const targetDoc = Cast(docAtCurrent.presentationTargetDoc, Doc, null); + const activeItem: Doc = this.activeItem; + const targetDoc: Doc = this.targetDoc; 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) { + this.prevKeyframe(targetDoc, activeItem); + } else if (activeItem) { let prevSelected = this.itemIndex; prevSelected = Math.max(0, prevSelected - 1); this.gotoDocument(prevSelected, this.itemIndex); @@ -209,8 +210,8 @@ export class PresBox extends ViewBoxBaseComponent * on the right. */ navigateToElement = async (curDoc: Doc) => { - const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); + const activeItem: Doc = this.activeItem; + const targetDoc: Doc = this.targetDoc; const srcContext = await DocCastAsync(targetDoc.context); const presCollection = Cast(this.layoutDoc.presCollection, Doc, null); const collectionDocView = presCollection ? await DocumentManager.Instance.getDocumentView(presCollection) : undefined; @@ -271,7 +272,7 @@ export class PresBox extends ViewBoxBaseComponent * @param presTargetDoc: document for which internal zoom is used */ zoomProgressivizeNext = (activeItem: Doc) => { - const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); + const targetDoc: Doc = this.targetDoc; const srcContext = Cast(targetDoc?.context, Doc, null); const docView = DocumentManager.Instance.getDocumentView(targetDoc); const vfLeft = this.checkList(targetDoc, activeItem["viewfinder-left-indexed"]); @@ -346,8 +347,8 @@ export class PresBox extends ViewBoxBaseComponent @action startAutoPres = (startSlide: number) => { this.updateCurrentPresentation(); - let activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - let targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); + let activeItem: Doc = this.activeItem; + let targetDoc: Doc = this.targetDoc; let duration = NumCast(targetDoc.presDuration) + NumCast(targetDoc.presTransition); const timer = (ms: number) => new Promise(res => this._presTimer = setTimeout(res, ms)); const load = async () => { // Wrap the loop into an async function for this to work @@ -401,12 +402,12 @@ export class PresBox extends ViewBoxBaseComponent startPresentation = (startIndex: number) => { this.updateCurrentPresentation(); this.childDocs.map(doc => { - const presTargetDoc = doc.presentationTargetDoc as Doc; + const tagDoc = doc.presentationTargetDoc as Doc; if (doc.presHideTillShownButton && this.childDocs.indexOf(doc) > startIndex) { - presTargetDoc.opacity = 0; + tagDoc.opacity = 0; } if (doc.presHideAfterButton && this.childDocs.indexOf(doc) < startIndex) { - presTargetDoc.opacity = 0; + tagDoc.opacity = 0; } }); } @@ -418,11 +419,21 @@ export class PresBox extends ViewBoxBaseComponent @undoBatch @action updateMinimize = () => { + const docView = DocumentManager.Instance.getDocumentView(this.layoutDoc); 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 if (this.layoutDoc.context && docView) { + 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; + docView.props.removeDocument?.(this.layoutDoc); + Doc.AddDocToList((Doc.UserDoc().myOverlayDocuments as Doc), undefined, this.rootDoc); } else { this.layoutDoc.presStatus = 'manual'; const pt = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); @@ -453,31 +464,34 @@ export class PresBox extends ViewBoxBaseComponent * When the movement dropdown is changes */ @undoBatch - movementChanged = action((movement: string) => { - const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); + updateMovement = action((movement: any, activeItem: Doc, targetDoc: Doc) => { + console.log(movement); switch (movement) { case 'zoom': //Pan and zoom - activeItem.presZoomButton = !activeItem.presZoomButton; - if (activeItem.presZoomButton) activeItem.presMovement = 'Zoom'; - else activeItem.presMovement = 'None'; + console.log('zoom'); activeItem.presNavButton = false; + activeItem.presZoomButton = !activeItem.presZoomButton; + targetDoc.presTransition = activeItem.presTransition; + if (activeItem.presZoomButton) activeItem.presMovement = 'zoom'; + else activeItem.presMovement = 'none'; break; case 'pan': //Pan activeItem.presZoomButton = false; activeItem.presNavButton = !activeItem.presNavButton; - if (activeItem.presNavButton) activeItem.presMovement = 'Pan'; - else activeItem.presMovement = 'None'; + targetDoc.presTransition = activeItem.presTransition; + if (activeItem.presNavButton) activeItem.presMovement = 'pan'; + else activeItem.presMovement = 'none'; break; case 'jump': //Jump Cut + activeItem.presTransition = targetDoc.presTransition; targetDoc.presTransition = 0; activeItem.presZoomButton = true; activeItem.presSwitchButton = !activeItem.presSwitchButton; - if (activeItem.presSwitchButton) activeItem.presMovement = 'Jump cut'; - else activeItem.presMovement = 'None'; + if (activeItem.presSwitchButton) activeItem.presMovement = 'jump'; + else activeItem.presMovement = 'none'; break; case 'none': default: - activeItem.presMovement = 'None'; + activeItem.presMovement = 'none'; activeItem.presZoomButton = false; activeItem.presNavButton = false; activeItem.presSwitchButton = false; @@ -485,6 +499,18 @@ export class PresBox extends ViewBoxBaseComponent } }); + setMovementName = action((movement: any): string => { + let output: string = 'none'; + console.log(movement); + switch (movement) { + case 'zoom': output = 'Zoom'; break; //Pan and zoom + case 'pan': output = 'Pan'; break; //Pan + case 'jump': output = 'Jump cut'; break; //Jump Cut + case 'none': default: output = 'None'; break; //None + } + return output; + }) + whenActiveChanged = action((isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive)); // For dragging documents into the presentation trail addDocumentFilter = (doc: Doc | Doc[]) => { @@ -501,7 +527,9 @@ export class PresBox extends ViewBoxBaseComponent return true; } childLayoutTemplate = () => this.rootDoc._viewType !== CollectionViewType.Stacking ? undefined : this.presElement; - removeDocument = (doc: Doc) => Doc.RemoveDocFromList(this.dataDoc, this.fieldKey, doc); + removeDocument = (doc: Doc) => { + Doc.RemoveDocFromList(this.dataDoc, this.fieldKey, doc); + }; getTransform = () => this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight panelHeight = () => this.props.PanelHeight() - 40; active = (outsideReaction?: boolean) => ((Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc.isBackground) && @@ -526,10 +554,10 @@ export class PresBox extends ViewBoxBaseComponent */ @computed get listOfSelected() { const list = this._selectedArray.map((doc: Doc, index: any) => { - const activeItem = Cast(doc, Doc, null); - const targetDoc = Cast(activeItem.presentationTargetDoc!, Doc, null); + const curDoc = Cast(doc, Doc, null); + const tagDoc = Cast(curDoc.presentationTargetDoc!, Doc, null); return ( -
{index + 1}. {targetDoc.title}
+
{index + 1}. {tagDoc.title}
); }); return list; @@ -563,8 +591,8 @@ export class PresBox extends ViewBoxBaseComponent @action shiftSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement) => { this._selectedArray = []; - const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - if (activeItem) { + // const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); + if (this.activeItem) { for (let i = Math.min(this.itemIndex, this.childDocs.indexOf(doc)); i <= Math.max(this.itemIndex, this.childDocs.indexOf(doc)); i++) { this._selectedArray.push(this.childDocs[i]); this._eleArray.push(ref); @@ -601,18 +629,33 @@ export class PresBox extends ViewBoxBaseComponent if (this.layoutDoc.presStatus !== "edit") this.startAutoPres(0); else this.layoutDoc.presStatus = "manual"; if (this._presTimer) clearTimeout(this._presTimer); handled = true; - } - if (e.keyCode === 8) { // delete selected items + } if (e.keyCode === 8) { // delete selected items if (this.layoutDoc.presStatus === "edit") { this._selectedArray.forEach((doc, i) => { this.removeDocument(doc); }); + this._selectedArray = []; + this._eleArray = []; + this._dragArray = []; handled = true; } - } - if (handled) { + } if (handled) { e.stopPropagation(); e.preventDefault(); + } if ((e.keyCode === 37 || e.keyCode === 38) && e.shiftKey) { // left(37) / a(65) / up(38) to go back + if (this.layoutDoc.presStatus === "edit" && this._selectedArray.length > 0) { + const index = this.childDocs.indexOf(this._selectedArray[this._selectedArray.length]); + if ((index - 1) > 0) this._selectedArray.push(this.childDocs[index - 1]); + } + handled = true; + } if ((e.keyCode === 39 || e.keyCode === 40) && e.shiftKey) { // left(37) / a(65) / up(38) to go back + if (this.layoutDoc.presStatus === "edit" && this._selectedArray.length > 0) { + const index = this.childDocs.indexOf(this._selectedArray[this._selectedArray.length]); + if ((index - 1) > 0) { + this._selectedArray.push(this.childDocs[index - 1]); + } + } + handled = true; } } @@ -636,12 +679,12 @@ export class PresBox extends ViewBoxBaseComponent @computed get order() { const order: JSX.Element[] = []; this.childDocs.forEach((doc, index) => { - const targetDoc = Cast(doc.presentationTargetDoc, Doc, null); - const srcContext = Cast(targetDoc?.context, Doc, null); + const tagDoc = Cast(doc.presentationTargetDoc, Doc, null); + const srcContext = Cast(tagDoc?.context, Doc, null); // Case A: Document is contained within the colleciton if (this.rootDoc.presCollection === srcContext) { order.push( -
+
{index + 1}
); // Case B: Document is not inside of the collection @@ -666,11 +709,11 @@ export class PresBox extends ViewBoxBaseComponent @computed get paths() { let pathPoints = ""; this.childDocs.forEach((doc, index) => { - const targetDoc = Cast(doc.presentationTargetDoc, 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); + const tagDoc = Cast(doc.presentationTargetDoc, Doc, null); + const srcContext = Cast(tagDoc?.context, Doc, null); + if (tagDoc && this.rootDoc.presCollection === srcContext) { + const n1x = NumCast(tagDoc.x) + (NumCast(tagDoc._width) / 2); + const n1y = NumCast(tagDoc.y) + (NumCast(tagDoc._height) / 2); if (index = 0) pathPoints = n1x + "," + n1y; else pathPoints = pathPoints + " " + n1x + "," + n1y; } else { @@ -701,8 +744,8 @@ export class PresBox extends ViewBoxBaseComponent @action onFadeDocumentAfterPresentedClick = (e: React.MouseEvent) => { e.stopPropagation(); - const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); + const activeItem: Doc = this.activeItem; + const targetDoc: Doc = this.targetDoc; activeItem.presFadeButton = !activeItem.presFadeButton; if (!activeItem.presFadeButton) { if (targetDoc) { @@ -722,9 +765,7 @@ export class PresBox extends ViewBoxBaseComponent 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; + if (this.targetDoc) this.targetDoc.presTransition = timeInMS; } // Converts seconds to ms and updates presDuration @@ -733,15 +774,13 @@ export class PresBox extends ViewBoxBaseComponent 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; + if (this.targetDoc) this.targetDoc.presDuration = timeInMS; } @computed get transitionDropdown() { - const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); + const activeItem: Doc = this.activeItem; + const targetDoc: Doc = this.targetDoc; if (activeItem && targetDoc) { const transitionSpeed = targetDoc.presTransition ? NumCast(targetDoc.presTransition) / 1000 : 0.5; let duration = targetDoc.presDuration ? NumCast(targetDoc.presDuration) / 1000 : 2; @@ -753,16 +792,16 @@ export class PresBox extends ViewBoxBaseComponent
Movement
{ e.stopPropagation(); this.openMovementDropdown = !this.openMovementDropdown; })} style={{ borderBottomLeftRadius: this.openMovementDropdown ? 0 : 5, border: this.openMovementDropdown ? 'solid 2px #5B9FDD' : 'solid 1px black' }}> - {activeItem.presMovement} + {this.setMovementName(activeItem.presMovement)}
e.stopPropagation()} style={{ display: this.openMovementDropdown ? "grid" : "none" }}> -
e.stopPropagation()} onClick={() => this.movementChanged('none')}>None
-
e.stopPropagation()} onClick={() => this.movementChanged('zoom')}>Pan and Zoom
-
e.stopPropagation()} onClick={() => this.movementChanged('pan')}>Pan
-
e.stopPropagation()} onClick={() => this.movementChanged('jump')}>Jump cut
+
e.stopPropagation()} onClick={() => this.updateMovement('none', activeItem, targetDoc)}>None
+
e.stopPropagation()} onClick={() => this.updateMovement('zoom', activeItem, targetDoc)}>Pan and Zoom
+
e.stopPropagation()} onClick={() => this.updateMovement('pan', activeItem, targetDoc)}>Pan
+
e.stopPropagation()} onClick={() => this.updateMovement('jump', activeItem, targetDoc)}>Jump cut
-
+
Transition Speed
- ) => { e.stopPropagation(); this.setTransitionTime(e.target.value); }} /> -
+ ) => { e.stopPropagation(); this.setTransitionTime(e.target.value); }} /> +
Fast
Medium
Slow
@@ -858,10 +897,8 @@ export class PresBox extends ViewBoxBaseComponent } @computed get effectDirection(): string { - const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); let effect = ''; - switch (targetDoc.presEffectDirection) { + switch (this.targetDoc.presEffectDirection) { case 'left': effect = "Enter from left"; break; case 'right': effect = "Enter from right"; break; case 'top': effect = "Enter from top"; break; @@ -874,8 +911,8 @@ export class PresBox extends ViewBoxBaseComponent @undoBatch @action applyTo = (array: Doc[]) => { - const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); + const activeItem: Doc = this.activeItem; + const targetDoc: Doc = this.targetDoc; array.forEach((doc, index) => { const curDoc = Cast(doc, Doc, null); const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null); @@ -885,14 +922,15 @@ export class PresBox extends ViewBoxBaseComponent tagDoc.presEffect = targetDoc.presEffect; tagDoc.presEffectDirection = targetDoc.presEffectDirection; curDoc.presMovement = activeItem.presMovement; + this.updateMovement(activeItem.presMovement, curDoc, tagDoc); curDoc.presHideTillShownButton = activeItem.presHideTillShownButton; curDoc.presHideAfterButton = activeItem.presHideAfterButton; } }); } @computed get optionsDropdown() { - const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); + const activeItem: Doc = this.activeItem; + const targetDoc: Doc = this.targetDoc; if (activeItem && targetDoc) { return (
@@ -909,6 +947,7 @@ export class PresBox extends ViewBoxBaseComponent
{ activeItem.presPinView = !activeItem.presPinView; + targetDoc.presPinView = activeItem.presPinView; if (activeItem.presPinView) { const x = targetDoc._panX; const y = targetDoc._panY; @@ -1065,8 +1104,8 @@ export class PresBox extends ViewBoxBaseComponent } createTemplate = (layout: string, input?: string) => { - const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); + const activeItem: Doc = this.activeItem; + const targetDoc: Doc = this.targetDoc; let x = 0; let y = 0; if (activeItem && targetDoc) { @@ -1120,7 +1159,7 @@ export class PresBox extends ViewBoxBaseComponent // Case in which the document has keyframes to navigate to next key frame @undoBatch @action - nextKeyframe = (tagDoc: Doc, activeItem: Doc): void => { + nextKeyframe = (tagDoc: Doc, curDoc: Doc): void => { const childDocs = DocListCast(tagDoc[Doc.LayoutFieldKey(tagDoc)]); const currentFrame = Cast(tagDoc.currentFrame, "number", null); if (currentFrame === undefined) { @@ -1132,20 +1171,20 @@ export class PresBox extends ViewBoxBaseComponent CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0, tagDoc); tagDoc.currentFrame = Math.max(0, (currentFrame || 0) + 1); tagDoc.lastFrame = Math.max(NumCast(tagDoc.currentFrame), NumCast(tagDoc.lastFrame)); - if (activeItem.zoomProgressivize) { + if (curDoc.zoomProgressivize) { const resize = document.getElementById('resizable'); if (resize) { - 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'; + resize.style.width = this.checkList(tagDoc, curDoc["viewfinder-width-indexed"]) + 'px'; + resize.style.height = this.checkList(tagDoc, curDoc["viewfinder-height-indexed"]) + 'px'; + resize.style.top = this.checkList(tagDoc, curDoc["viewfinder-top-indexed"]) + 'px'; + resize.style.left = this.checkList(tagDoc, curDoc["viewfinder-left-indexed"]) + 'px'; } } } @undoBatch @action - prevKeyframe = (tagDoc: Doc, activeItem: Doc): void => { + prevKeyframe = (tagDoc: Doc, actItem: Doc): void => { const childDocs = DocListCast(tagDoc[Doc.LayoutFieldKey(tagDoc)]); const currentFrame = Cast(tagDoc.currentFrame, "number", null); if (currentFrame === undefined) { @@ -1154,13 +1193,13 @@ export class PresBox extends ViewBoxBaseComponent } CollectionFreeFormDocumentView.gotoKeyframe(childDocs.slice()); tagDoc.currentFrame = Math.max(0, (currentFrame || 0) - 1); - if (activeItem.zoomProgressivize) { + if (actItem.zoomProgressivize) { const resize = document.getElementById('resizable'); if (resize) { - 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'; + resize.style.width = this.checkList(tagDoc, actItem["viewfinder-width-indexed"]) + 'px'; + resize.style.height = this.checkList(tagDoc, actItem["viewfinder-height-indexed"]) + 'px'; + resize.style.top = this.checkList(tagDoc, actItem["viewfinder-top-indexed"]) + 'px'; + resize.style.left = this.checkList(tagDoc, actItem["viewfinder-left-indexed"]) + 'px'; } } } @@ -1169,8 +1208,8 @@ export class PresBox extends ViewBoxBaseComponent * Returns the collection type as a string for headers */ @computed get stringType(): string { - const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); + const activeItem: Doc = this.activeItem; + const targetDoc: Doc = this.targetDoc; let type: string = ''; if (activeItem) { switch (targetDoc.type) { @@ -1193,11 +1232,11 @@ export class PresBox extends ViewBoxBaseComponent @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"; + const activeItem: Doc = this.activeItem; + const targetDoc: Doc = this.targetDoc; if (activeItem && targetDoc) { + 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"; return (
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}> @@ -1256,8 +1295,8 @@ export class PresBox extends ViewBoxBaseComponent @undoBatch @action switchActive = (color: ColorState) => { - const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); + const activeItem: Doc = this.activeItem; + const targetDoc: Doc = this.targetDoc; const val = String(color.hex); targetDoc["pres-text-color"] = val; return true; @@ -1265,16 +1304,16 @@ export class PresBox extends ViewBoxBaseComponent @undoBatch @action switchPresented = (color: ColorState) => { - const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); + const activeItem: Doc = this.activeItem; + const targetDoc: Doc = this.targetDoc; 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); + const activeItem: Doc = this.activeItem; + const targetDoc: Doc = this.targetDoc; return !this.openActiveColorPicker ? (null) : } @computed get viewedColorPicker() { - const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); + const activeItem: Doc = this.activeItem; + const targetDoc: Doc = this.targetDoc; return !this.openViewedColorPicker ? (null) : //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); + const activeItem: Doc = this.activeItem; + const targetDoc: Doc = this.targetDoc; if (!targetDoc.editZoomProgressivize) { if (!activeItem.zoomProgressivize) activeItem.zoomProgressivize = true; targetDoc.zoomProgressivize = true; targetDoc.editZoomProgressivize = true; @@ -1323,8 +1362,8 @@ export class PresBox extends ViewBoxBaseComponent //Toggle whether the user edits or not @action editScrollProgressivize = (e: React.MouseEvent) => { - const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); + const activeItem: Doc = this.activeItem; + const targetDoc: Doc = this.targetDoc; if (!targetDoc.editScrollProgressivize) { if (!targetDoc.scrollProgressivize) { targetDoc.scrollProgressivize = true; activeItem.scrollProgressivize = true; } targetDoc.editScrollProgressivize = true; @@ -1337,9 +1376,9 @@ export class PresBox extends ViewBoxBaseComponent @action progressivizeScroll = (e: React.MouseEvent) => { e.stopPropagation(); - const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); + const activeItem: Doc = this.activeItem; activeItem.scrollProgressivize = !activeItem.scrollProgressivize; - const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); + const targetDoc: Doc = this.targetDoc; targetDoc.scrollProgressivize = !targetDoc.scrollProgressivize; CollectionFreeFormDocumentView.setupScroll(targetDoc, NumCast(targetDoc.currentFrame), true); if (targetDoc.editScrollProgressivize) { @@ -1353,9 +1392,9 @@ export class PresBox extends ViewBoxBaseComponent @action progressivizeZoom = (e: React.MouseEvent) => { e.stopPropagation(); - const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); + const activeItem: Doc = this.activeItem; activeItem.zoomProgressivize = !activeItem.zoomProgressivize; - const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); + const targetDoc: Doc = this.targetDoc; targetDoc.zoomProgressivize = !targetDoc.zoomProgressivize; CollectionFreeFormDocumentView.setupZoom(activeItem, targetDoc, true); if (activeItem.editZoomProgressivize) { @@ -1368,8 +1407,8 @@ export class PresBox extends ViewBoxBaseComponent //Progressivize Child Docs @action editProgressivize = (e: React.MouseEvent) => { - const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); + const activeItem: Doc = this.activeItem; + const targetDoc: Doc = this.targetDoc; targetDoc.currentFrame = targetDoc.lastFrame; if (!targetDoc.editProgressivize) { if (!activeItem.presProgressivize) { activeItem.presProgressivize = true; targetDoc.presProgressivize = true; } @@ -1382,8 +1421,8 @@ export class PresBox extends ViewBoxBaseComponent @action progressivizeChild = (e: React.MouseEvent) => { e.stopPropagation(); - const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); + const activeItem: Doc = this.activeItem; + const targetDoc: Doc = this.targetDoc; const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]); if (!activeItem.presProgressivize) { targetDoc.editing = false; @@ -1448,8 +1487,7 @@ export class PresBox extends ViewBoxBaseComponent } @computed get progressivizeChildDocs() { - const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); + const targetDoc: Doc = this.targetDoc; const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]); const tags: JSX.Element[] = []; docs.forEach((doc, index) => { @@ -1469,8 +1507,8 @@ export class PresBox extends ViewBoxBaseComponent @undoBatch @action nextAppearFrame = (doc: Doc, i: number): void => { - const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); + // const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); + // const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); const appearFrame = Cast(doc.appearFrame, "number", null); if (appearFrame === undefined) { doc.appearFrame = 0; @@ -1482,8 +1520,8 @@ export class PresBox extends ViewBoxBaseComponent @undoBatch @action prevAppearFrame = (doc: Doc, i: number): void => { - const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); + // const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); + // const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); const appearFrame = Cast(doc.appearFrame, "number", null); if (appearFrame === undefined) { doc.appearFrame = 0; @@ -1604,11 +1642,10 @@ export class PresBox extends ViewBoxBaseComponent } @computed get playButtonFrames() { - const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null); - const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null); + const targetDoc: Doc = this.targetDoc; return ( <> - {targetDoc ?
= 0 ? "inline-flex" : "none" }}> + {this.targetDoc ?
= 0 ? "inline-flex" : "none" }}>
{targetDoc.currentFrame}
{targetDoc.lastFrame}
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index a25a8ee33..127ad9d01 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -205,6 +205,15 @@ export class PresElementBox extends ViewBoxBaseComponent { + this.props.removeDocument?.(this.rootDoc); + if (PresBox.Instance._selectedArray.includes(this.rootDoc)) { + PresBox.Instance._selectedArray.splice(PresBox.Instance._selectedArray.indexOf(this.rootDoc), 1); + } + e.stopPropagation(); + } + render() { const className = "presElementBox-item" + (PresBox.Instance._selectedArray.includes(this.rootDoc) ? " presElementBox-active" : ""); const pbi = "presElementBox-interaction"; @@ -253,10 +262,7 @@ export class PresElementBox extends ViewBoxBaseComponent
{"Presentation pin view"}
}>
300 ? "block" : "none" }}>V
{"Remove from presentation"}
}>
{ - this.props.removeDocument?.(this.rootDoc); - e.stopPropagation(); - }}> + onClick={this.removeItem}> e.stopPropagation()} />
{this.rootDoc.presExpandInlineButton ? "Minimize" : "Expand"}
}>
{ e.stopPropagation(); this.presExpandDocumentClick(); }}> -- cgit v1.2.3-70-g09d2 From 8f180cd9ef75eb1aaa6fed9e6544b7b6256cda73 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Mon, 17 Aug 2020 23:28:55 +0530 Subject: properties panel acl issue fixed --- src/client/views/collections/collectionFreeForm/PropertiesView.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx index 85a1d7137..ed451beab 100644 --- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx +++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx @@ -383,11 +383,12 @@ export class PropertiesView extends React.Component { [AclAdmin, SharingPermissions.Admin] ]); - const effectiveAcl = GetEffectiveAcl(this.selectedDoc!); + const target = this.layoutDocAcls ? this.selectedDoc! : this.selectedDoc![DataSym]; + + const effectiveAcl = GetEffectiveAcl(target); const tableEntries = []; // DocCastAsync(Doc.UserDoc().sidebarUsersDisplayed).then(sidebarUsersDisplayed => { - const target = this.layoutDocAcls ? this.selectedDoc! : this.selectedDoc![DataSym]; if (target[AclSym]) { for (const [key, value] of Object.entries(target[AclSym])) { const name = key.substring(4).replace("_", "."); -- cgit v1.2.3-70-g09d2 From 454b4aac706939bdd602343683012c8497b70c3c Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 18 Aug 2020 10:27:09 -0400 Subject: disabled ink gestures (can be reneanbled with Doc.UserDoc().recognizeGestures. fixed z-index setting of new documents in freeform view. --- src/client/views/GestureOverlay.tsx | 4 ++-- .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index 76e786257..c25ebbf11 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -613,10 +613,10 @@ export default class GestureOverlay extends Touchable { } } // if we're not drawing in a toolglass try to recognize as gesture - else { + else { // need to decide when to turn gestures back on const result = points.length > 2 && GestureUtils.GestureRecognizer.Recognize(new Array(points)); let actionPerformed = false; - if (result && result.Score > 0.7) { + if (Doc.UserDoc().recognizeGestures && result && result.Score > 0.7) { switch (result.Name) { case GestureUtils.Gestures.Box: actionPerformed = this.dispatchGesture(GestureUtils.Gestures.Box); break; case GestureUtils.Gestures.StartBracket: actionPerformed = this.dispatchGesture(GestureUtils.Gestures.StartBracket); break; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 46e30f616..b595ec2ac 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -850,7 +850,7 @@ export class CollectionFreeFormView extends CollectionSubView pair.layout); docs.slice().sort((doc1, doc2) => NumCast(doc1.zIndex) - NumCast(doc2.zIndex)); - let zlast = docs.length ? NumCast(docs[docs.length - 1].zIndex) : 1; + let zlast = docs.length ? Math.max(docs.length, NumCast(docs[docs.length - 1].zIndex)) : 1; if (zlast - docs.length > 100) { for (let i = 0; i < docs.length; i++) doc.zIndex = i + 1; zlast = docs.length + 1; -- cgit v1.2.3-70-g09d2 From f02d2ca93534141570a5dc01fda8165d1e6d22d5 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 18 Aug 2020 16:15:42 -0400 Subject: fixed undoing typed text boxes to happen in one step (not undo to first character, then undo again fo whole box) --- src/client/views/collections/collectionFreeForm/MarqueeView.tsx | 3 ++- src/client/views/nodes/formattedText/FormattedTextBox.tsx | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index c0b19fcd2..b6a0504e2 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -12,7 +12,7 @@ import { CognitiveServices } from "../../../cognitive_services/CognitiveServices import { Docs, DocumentOptions, DocUtils } from "../../../documents/Documents"; import { SelectionManager } from "../../../util/SelectionManager"; import { Transform } from "../../../util/Transform"; -import { undoBatch } from "../../../util/UndoManager"; +import { undoBatch, UndoManager } from "../../../util/UndoManager"; import { ContextMenu } from "../../ContextMenu"; import { FormattedTextBox } from "../../nodes/formattedText/FormattedTextBox"; import { PreviewCursor } from "../../PreviewCursor"; @@ -138,6 +138,7 @@ export class MarqueeView extends React.Component { FormattedTextBox.HadSelection = window.getSelection()?.toString() !== ""; @@ -1441,6 +1442,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp this.endUndoTypingBatch(); this.doLinkOnDeselect(); + FormattedTextBox.LiveTextUndo?.end(); + FormattedTextBox.LiveTextUndo = undefined; // move the richtextmenu offscreen //if (!RichTextMenu.Instance.Pinned) RichTextMenu.Instance.delayHide(); } -- cgit v1.2.3-70-g09d2 From 913cd0d93c0ef2d138606e146d9b3133d6a25026 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 18 Aug 2020 21:26:26 -0400 Subject: fixed snapping to work when dragging an alias to allow snapping to original --- src/client/views/DocumentDecorations.tsx | 2 +- .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 6 +++--- src/client/views/nodes/DocumentView.tsx | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 535e86457..0cc492ee9 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -360,7 +360,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> this._offY = this._resizeHdlId.toLowerCase().includes("top") ? bounds.bottom - e.clientY : bounds.top - e.clientY; this.Interacting = true; this._resizeUndo = UndoManager.StartBatch("DocDecs resize"); - SelectionManager.SelectedDocuments()[0].props.setupDragLines?.(); + SelectionManager.SelectedDocuments()[0].props.setupDragLines?.(e.ctrlKey || e.shiftKey); } this._snapX = e.pageX; this._snapY = e.pageY; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index b595ec2ac..5d6d7924e 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1315,7 +1315,7 @@ export class CollectionFreeFormView extends CollectionSubView { + setupDragLines = (snapToDraggedDoc: boolean = false) => { const activeDocs = this.getActiveDocuments(); if (activeDocs.length > 50) { DragManager.SetSnapLines([], []); @@ -1337,7 +1337,7 @@ export class CollectionFreeFormView extends CollectionSubView !DragManager.docsBeingDragged.includes(Cast(doc.rootDocument, Doc, null) || doc)).forEach(doc => { + snappableDocs.filter(doc => snapToDraggedDoc || !DragManager.docsBeingDragged.includes(Cast(doc.rootDocument, Doc, null) || doc)).forEach(doc => { const { left, top, width, height } = docDims(doc); const topLeftInScreen = this.getTransform().inverse().transformPoint(left, top); const docSize = this.getTransform().inverse().transformDirection(width, height); @@ -1349,7 +1349,7 @@ export class CollectionFreeFormView extends CollectionSubView { if (SnappingManager.GetIsDragging()) { - this.setupDragLines(); + this.setupDragLines(e.ctrlKey || e.shiftKey); } e.stopPropagation(); } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 168a0df38..0939ccdf7 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -69,7 +69,7 @@ export interface DocumentViewProps { removeDocument?: (doc: Doc | Doc[]) => boolean; moveDocument?: (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[]) => boolean) => boolean; ScreenToLocalTransform: () => Transform; - setupDragLines?: () => void; + setupDragLines?: (snapToDraggedDoc: boolean) => void; renderDepth: number; ContentScaling: () => number; PanelWidth: () => number; -- cgit v1.2.3-70-g09d2 From a9f029cad5588ef127de753a4ee4ac0a8c739eb0 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 18 Aug 2020 23:08:13 -0400 Subject: added document selection for items in a SchemaView so that Properties and context menu can operate on them. --- src/client/util/SelectionManager.ts | 17 ++++++++++++-- src/client/util/SharingManager.tsx | 6 ++--- .../views/collections/CollectionSchemaView.tsx | 26 ++++++++++++++++++++-- src/client/views/collections/SchemaTable.tsx | 6 +++-- .../collectionFreeForm/PropertiesView.tsx | 10 +++++---- src/client/views/nodes/DocumentView.tsx | 4 ++-- 6 files changed, 54 insertions(+), 15 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index 113278593..14d06b9b6 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -1,10 +1,11 @@ import { observable, action, runInAction, ObservableMap } from "mobx"; -import { Doc } from "../../fields/Doc"; +import { Doc, Opt } from "../../fields/Doc"; import { DocumentView } from "../views/nodes/DocumentView"; import { computedFn } from "mobx-utils"; import { List } from "../../fields/List"; import { Scripting } from "./Scripting"; import { DocumentManager } from "./DocumentManager"; +import { MobileDocumentUploadContent } from "../../server/Message"; export namespace SelectionManager { @@ -12,7 +13,12 @@ export namespace SelectionManager { @observable IsDragging: boolean = false; SelectedDocuments: ObservableMap = new ObservableMap(); + @observable SelectedSchemaDocument: Doc | undefined; + @action + SelectSchemaDoc(doc: Opt) { + manager.SelectedSchemaDocument = doc; + } @action SelectDoc(docView: DocumentView, ctrlPressed: boolean): void { @@ -26,6 +32,7 @@ export namespace SelectionManager { docView.props.whenActiveChanged(true); } else if (!ctrlPressed && Array.from(manager.SelectedDocuments.entries()).length > 1) { Array.from(manager.SelectedDocuments.keys()).map(dv => dv !== docView && dv.props.whenActiveChanged(false)); + manager.SelectedSchemaDocument = undefined; manager.SelectedDocuments.clear(); manager.SelectedDocuments.set(docView, true); } @@ -42,7 +49,7 @@ export namespace SelectionManager { } @action DeselectAll(): void { - + manager.SelectedSchemaDocument = undefined; Array.from(manager.SelectedDocuments.keys()).map(dv => dv.props.whenActiveChanged(false)); manager.SelectedDocuments.clear(); Doc.UserDoc().activeSelection = new List([]); @@ -57,6 +64,9 @@ export namespace SelectionManager { export function SelectDoc(docView: DocumentView, ctrlPressed: boolean): void { manager.SelectDoc(docView, ctrlPressed); } + export function SelectSchemaDoc(document: Opt): void { + manager.SelectSchemaDoc(document); + } // computed functions, such as used in IsSelected generate errors if they're called outside of a // reaction context. Specifying the context with 'outsideReaction' allows an efficiency feature @@ -84,4 +94,7 @@ export namespace SelectionManager { export function SelectedDocuments(): Array { return Array.from(manager.SelectedDocuments.keys()); } + export function SelectedSchemaDoc(): Doc | undefined { + return manager.SelectedSchemaDocument; + } } \ No newline at end of file diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index 5a863c813..b9918e900 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -82,15 +82,15 @@ export default class SharingManager extends React.Component<{}> { // return this.sharingDoc ? this.sharingDoc[PublicKey] !== SharingPermissions.None : false; // } - public open = (target: DocumentView) => { + public open = (target?: DocumentView, target_doc?: Doc) => { runInAction(() => this.users = []); // SelectionManager.DeselectAll(); this.populateUsers(); runInAction(() => { this.targetDocView = target; - this.targetDoc = target.props.Document; + this.targetDoc = target_doc || target?.props.Document; DictationOverlay.Instance.hasActiveModal = true; - this.isOpen = true; + this.isOpen = this.targetDoc !== undefined; this.permissions = SharingPermissions.Edit; }); this.targetDoc!.author === Doc.CurrentUserEmail && !this.targetDoc![`ACL-${Doc.CurrentUserEmail.replace(".", "_")}`] && distributeAcls(`ACL-${Doc.CurrentUserEmail.replace(".", "_")}`, SharingPermissions.Admin, this.targetDoc!); diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index a72b349ec..f34ac7d03 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -7,7 +7,7 @@ import { observer } from "mobx-react"; import Measure from "react-measure"; import { Resize } from "react-table"; import "react-table/react-table.css"; -import { Doc } from "../../../fields/Doc"; +import { Doc, Opt } from "../../../fields/Doc"; import { List } from "../../../fields/List"; import { listSpec } from "../../../fields/Schema"; import { PastelSchemaPalette, SchemaHeaderField } from "../../../fields/SchemaHeaderField"; @@ -24,6 +24,9 @@ import { KeysDropdown } from "./CollectionSchemaHeaders"; import "./CollectionSchemaView.scss"; import { CollectionSubView } from "./CollectionSubView"; import { SchemaTable } from "./SchemaTable"; +import { SelectionManager } from "../../util/SelectionManager"; +import { ContextMenu } from "../ContextMenu"; +import { ContextMenuProps } from "../ContextMenuItem"; library.add(faCog, faPlus, faSortUp, faSortDown); library.add(faTable); @@ -388,7 +391,10 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { @action setFocused = (doc: Doc) => this._focusedTable = doc; - @action setPreviewDoc = (doc: Doc) => this.previewDoc = doc; + @action setPreviewDoc = (doc: Opt) => { + SelectionManager.SelectSchemaDoc(doc); + this.previewDoc = doc; + } //toggles preview side-panel of schema @action @@ -515,9 +521,24 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
; } + onSpecificMenu = (e: React.MouseEvent) => { + if ((e.target as any)?.className?.includes?.("collectionSchemaView-cell") || (e.target instanceof HTMLSpanElement)) { + const cm = ContextMenu.Instance; + const options = cm.findByDescription("Options..."); + const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : []; + optionItems.push({ description: "remove", event: () => this.previewDoc && this.props.removeDocument(this.previewDoc), icon: "trash" }); + !options && cm.addItem({ description: "Options...", subitems: optionItems, icon: "compass" }); + cm.displayMenu(e.clientX, e.clientY); + (e.nativeEvent as any).SchemaHandled = true; // not sure why this is needed, but if you right-click quickly on a cell, the Document/Collection contextMenu handlers still fire without this. + e.stopPropagation(); + } + } @action onTablePointerDown = (e: React.PointerEvent): void => { + if (!(e.target as any)?.className?.includes?.("collectionSchemaView-cell") && !(e.target instanceof HTMLSpanElement)) { + this.setPreviewDoc(undefined); + } this.setFocused(this.props.Document); if (e.button === 0 && !e.altKey && !e.ctrlKey && !e.metaKey && this.props.isSelected(true)) { e.stopPropagation(); @@ -601,6 +622,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
this.props.active(true) && e.stopPropagation()} onDrop={e => this.onExternalDrop(e, {})} diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx index 5a86150fe..7913c92a4 100644 --- a/src/client/views/collections/SchemaTable.tsx +++ b/src/client/views/collections/SchemaTable.tsx @@ -70,7 +70,7 @@ export interface SchemaTableProps { isSelected: (outsideReaction?: boolean) => boolean; isFocused: (document: Doc, outsideReaction: boolean) => boolean; setFocused: (document: Doc) => void; - setPreviewDoc: (document: Doc) => void; + setPreviewDoc: (document: Opt) => void; columns: SchemaHeaderField[]; documentKeys: any[]; headerIsEditing: boolean; @@ -385,7 +385,9 @@ export class SchemaTable extends React.Component { const pdoc = FieldValue(this.childDocs[this._focusedCell.row]); pdoc && this.props.setPreviewDoc(pdoc); - } else if ((this._cellIsEditing || this.props.headerIsEditing) && (e.keyCode === 37 || e.keyCode === 39)) { + e.stopPropagation(); + } else if (e.keyCode === 27) { + this.props.setPreviewDoc(undefined); e.stopPropagation(); // stopPropagation for left/right arrows } } diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx index ed451beab..6fc03c3b5 100644 --- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx +++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx @@ -49,8 +49,11 @@ export class PropertiesView extends React.Component { @computed get MAX_EMBED_HEIGHT() { return 200; } + @computed get selectedDoc() { return SelectionManager.SelectedSchemaDoc() || this.selectedDocumentView?.rootDoc; } @computed get selectedDocumentView() { - if (SelectionManager.SelectedDocuments().length) { + if (SelectionManager.SelectedSchemaDoc()) + return undefined; + else if (SelectionManager.SelectedDocuments().length) { return SelectionManager.SelectedDocuments()[0]; } else if (PresBox.Instance && PresBox.Instance._selectedArray.length) { return DocumentManager.Instance.getDocumentView(PresBox.Instance.rootDoc); @@ -60,7 +63,6 @@ export class PropertiesView extends React.Component { if (this.selectedDoc?.type === DocumentType.PRES) return true; return false; } - @computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; } @computed get dataDoc() { return this.selectedDocumentView?.dataDoc; } @observable layoutFields: boolean = false; @@ -345,8 +347,8 @@ export class PropertiesView extends React.Component { @computed get expansionIcon() { return {"Show more permissions"}
}>
{ - if (this.selectedDocumentView) { - SharingManager.Instance.open(this.selectedDocumentView); + if (this.selectedDocumentView || this.selectedDoc) { + SharingManager.Instance.open(this.selectedDocumentView, this.selectedDoc); } }}> diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 0939ccdf7..9ae113150 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -684,7 +684,7 @@ export class DocumentView extends DocComponent(Docu } @action - onContextMenu = async (e: React.MouseEvent | Touch): Promise => { + onContextMenu = (e: React.MouseEvent | Touch) => { // the touch onContextMenu is button 0, the pointer onContextMenu is button 2 if (!(e instanceof Touch)) { if (e.button === 0 && !e.ctrlKey) { @@ -703,7 +703,7 @@ export class DocumentView extends DocComponent(Docu } const cm = ContextMenu.Instance; - if (!cm) return; + if (!cm || ((e as any)?.nativeEvent as any)?.SchemaHandled) return; const customScripts = Cast(this.props.Document.contextMenuScripts, listSpec(ScriptField), []); Cast(this.props.Document.contextMenuLabels, listSpec("string"), []).forEach((label, i) => -- cgit v1.2.3-70-g09d2 From bf4baf81576cfd7363cccdd2526914f6afd59c98 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 19 Aug 2020 00:12:50 -0400 Subject: updated PropertiesButtons to work with selected documents in schemaViews --- src/client/util/SelectionManager.ts | 17 +++++--- src/client/views/PropertiesButtons.tsx | 49 +++++++++++----------- .../views/collections/CollectionSchemaView.tsx | 3 +- .../collectionFreeForm/PropertiesView.tsx | 6 +-- 4 files changed, 39 insertions(+), 36 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index 14d06b9b6..35b82cc30 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -3,9 +3,7 @@ import { Doc, Opt } from "../../fields/Doc"; import { DocumentView } from "../views/nodes/DocumentView"; import { computedFn } from "mobx-utils"; import { List } from "../../fields/List"; -import { Scripting } from "./Scripting"; -import { DocumentManager } from "./DocumentManager"; -import { MobileDocumentUploadContent } from "../../server/Message"; +import { CollectionSchemaView } from "../views/collections/CollectionSchemaView"; export namespace SelectionManager { @@ -14,10 +12,12 @@ export namespace SelectionManager { @observable IsDragging: boolean = false; SelectedDocuments: ObservableMap = new ObservableMap(); @observable SelectedSchemaDocument: Doc | undefined; + @observable SelectedSchemaCollection: CollectionSchemaView | undefined; @action - SelectSchemaDoc(doc: Opt) { + SelectSchemaDoc(collectionView: Opt, doc: Opt) { manager.SelectedSchemaDocument = doc; + manager.SelectedSchemaCollection = collectionView; } @action SelectDoc(docView: DocumentView, ctrlPressed: boolean): void { @@ -33,6 +33,7 @@ export namespace SelectionManager { } else if (!ctrlPressed && Array.from(manager.SelectedDocuments.entries()).length > 1) { Array.from(manager.SelectedDocuments.keys()).map(dv => dv !== docView && dv.props.whenActiveChanged(false)); manager.SelectedSchemaDocument = undefined; + manager.SelectedSchemaCollection = undefined; manager.SelectedDocuments.clear(); manager.SelectedDocuments.set(docView, true); } @@ -49,6 +50,7 @@ export namespace SelectionManager { } @action DeselectAll(): void { + manager.SelectedSchemaCollection = undefined; manager.SelectedSchemaDocument = undefined; Array.from(manager.SelectedDocuments.keys()).map(dv => dv.props.whenActiveChanged(false)); manager.SelectedDocuments.clear(); @@ -64,8 +66,8 @@ export namespace SelectionManager { export function SelectDoc(docView: DocumentView, ctrlPressed: boolean): void { manager.SelectDoc(docView, ctrlPressed); } - export function SelectSchemaDoc(document: Opt): void { - manager.SelectSchemaDoc(document); + export function SelectSchemaDoc(colSchema: Opt, document: Opt): void { + manager.SelectSchemaDoc(colSchema, document); } // computed functions, such as used in IsSelected generate errors if they're called outside of a @@ -97,4 +99,7 @@ export namespace SelectionManager { export function SelectedSchemaDoc(): Doc | undefined { return manager.SelectedSchemaDocument; } + export function SelectedSchemaCollection(): CollectionSchemaView | undefined { + return manager.SelectedSchemaCollection; + } } \ No newline at end of file diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index dfedc9ccc..e220bd7fc 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -77,12 +77,12 @@ export class PropertiesButtons extends React.Component<{}, {}> { public static hasPulledHack = false; + @computed get selectedDoc() { return SelectionManager.SelectedSchemaDoc() || this.selectedDocumentView?.rootDoc; } @computed get selectedDocumentView() { if (SelectionManager.SelectedDocuments().length) { return SelectionManager.SelectedDocuments()[0]; - } else { return undefined; } + } else return undefined; } - @computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; } @computed get dataDoc() { return this.selectedDocumentView?.dataDoc; } @computed get onClick() { return this.selectedDoc?.onClickBehavior ? this.selectedDoc?.onClickBehavior : "nothing"; } @@ -297,9 +297,9 @@ export class PropertiesButtons extends React.Component<{}, {}> { } @undoBatch onAliasButtonMoved = () => { - if (this._dragRef.current) { + if (this._dragRef.current && this.selectedDoc) { const dragDocView = this.selectedDocumentView!; - const dragData = new DragManager.DocumentDragData([dragDocView.props.Document]); + const dragData = new DragManager.DocumentDragData([this.selectedDoc]); const [left, top] = dragDocView.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); dragData.dropAction = "alias"; DragManager.StartDocumentDrag([dragDocView.ContentDiv!], dragData, left, top, { @@ -314,7 +314,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { @computed get templateButton() { - const docView = this.selectedDocumentView; + const docView = this.selectedDocumentView?.props.Document === this.selectedDoc ? this.selectedDocumentView : undefined; const templates: Map = new Map(); const views = [this.selectedDocumentView]; Array.from(Object.values(Templates.TemplateList)).map(template => @@ -366,7 +366,8 @@ export class PropertiesButtons extends React.Component<{}, {}> { @action @undoBatch onLock = () => { - this.selectedDocumentView?.toggleLockPosition(); + const docView = this.selectedDocumentView?.props.Document === this.selectedDoc ? this.selectedDocumentView : undefined; + docView?.toggleLockPosition(); } @computed @@ -401,8 +402,8 @@ export class PropertiesButtons extends React.Component<{}, {}> {
{ - if (this.selectedDocumentView?.props.Document) { - Doc.Zip(this.selectedDocumentView?.props.Document); + if (this.selectedDoc) { + Doc.Zip(this.selectedDoc); } }}> { { @undoBatch @action deleteDocument = () => { - const selected = SelectionManager.SelectedDocuments().slice(); - selected.map(dv => dv.props.removeDocument?.(dv.props.Document)); - this.selectedDoc && (this.selectedDoc.deleted = true); - this.selectedDocumentView?.props.ContainingCollectionView?.removeDocument(this.selectedDocumentView?.props.Document); + const removeDoc = this.selectedDocumentView?.props.Document === this.selectedDoc ? this.selectedDocumentView?.props.removeDocument : SelectionManager.SelectedSchemaCollection()?.props.removeDocument; + this.selectedDoc && removeDoc?.(this.selectedDoc); SelectionManager.DeselectAll(); } @computed get sharingButton() { const targetDoc = this.selectedDoc; + const docView = this.selectedDocumentView?.props.Document === this.selectedDoc ? this.selectedDocumentView : undefined; return !targetDoc ? (null) :
{"Share Document"}
} placement="top">
{ if (this.selectedDocumentView) { - SharingManager.Instance.open(this.selectedDocumentView); + SharingManager.Instance.open(docView, this.selectedDoc); } }}> { { handleOptionChange = (e: any) => { const value = e.target.value; this.selectedDoc && (this.selectedDoc.onClickBehavior = e.target.value); + const docView = this.selectedDocumentView?.props.Document === this.selectedDoc ? this.selectedDocumentView : undefined; if (value === "nothing") { - this.selectedDocumentView?.noOnClick(); + docView?.noOnClick(); } else if (value === "enterPortal") { - this.selectedDocumentView?.noOnClick(); - this.selectedDocumentView?.makeIntoPortal(); + docView?.noOnClick(); + docView?.makeIntoPortal(); } else if (value === "toggleDetail") { - this.selectedDocumentView?.noOnClick(); - this.selectedDocumentView?.toggleDetail(); + docView?.noOnClick(); + docView?.toggleDetail(); } else if (value === "linkInPlace") { - this.selectedDocumentView?.noOnClick(); - this.selectedDocumentView?.toggleFollowLink("inPlace", true, false); + docView?.noOnClick(); + docView?.toggleFollowLink("inPlace", true, false); } else if (value === "linkOnRight") { - this.selectedDocumentView?.noOnClick(); - this.selectedDocumentView?.toggleFollowLink("onRight", false, false); + docView?.noOnClick(); + docView?.toggleFollowLink("onRight", false, false); } } @@ -565,8 +566,8 @@ export class PropertiesButtons extends React.Component<{}, {}> {
{ - if (this.selectedDocumentView) { - GooglePhotos.Export.CollectionToAlbum({ collection: this.selectedDocumentView.Document }).then(console.log); + if (this.selectedDoc) { + GooglePhotos.Export.CollectionToAlbum({ collection: this.selectedDoc }).then(console.log); } }}> { doc) { @action setFocused = (doc: Doc) => this._focusedTable = doc; @action setPreviewDoc = (doc: Opt) => { - SelectionManager.SelectSchemaDoc(doc); + SelectionManager.SelectSchemaDoc(this, doc); this.previewDoc = doc; } diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx index 6fc03c3b5..fb138ecc0 100644 --- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx +++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx @@ -51,9 +51,7 @@ export class PropertiesView extends React.Component { @computed get selectedDoc() { return SelectionManager.SelectedSchemaDoc() || this.selectedDocumentView?.rootDoc; } @computed get selectedDocumentView() { - if (SelectionManager.SelectedSchemaDoc()) - return undefined; - else if (SelectionManager.SelectedDocuments().length) { + if (SelectionManager.SelectedDocuments().length) { return SelectionManager.SelectedDocuments()[0]; } else if (PresBox.Instance && PresBox.Instance._selectedArray.length) { return DocumentManager.Instance.getDocumentView(PresBox.Instance.rootDoc); @@ -348,7 +346,7 @@ export class PropertiesView extends React.Component { return {"Show more permissions"}
}>
{ if (this.selectedDocumentView || this.selectedDoc) { - SharingManager.Instance.open(this.selectedDocumentView, this.selectedDoc); + SharingManager.Instance.open(this.selectedDocumentView?.props.Document === this.selectedDocumentView ? this.selectedDocumentView : undefined, this.selectedDoc); } }}> -- cgit v1.2.3-70-g09d2 From 2473613caf8d9d397e3b132f95b136a0c26a1ebd Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 19 Aug 2020 19:06:31 -0400 Subject: fixed frame animations and added frames to bookmarked views. --- src/client/documents/Documents.ts | 2 -- src/client/views/collections/CollectionMenu.tsx | 21 +++++++++++---- .../collectionFreeForm/CollectionFreeFormView.tsx | 4 +-- .../views/nodes/CollectionFreeFormDocumentView.tsx | 31 +++++++++------------- src/client/views/nodes/PresBox.tsx | 26 +++++++++--------- 5 files changed, 44 insertions(+), 40 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index f07b718ba..7d114d417 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -144,8 +144,6 @@ export interface DocumentOptions { presTransition?: number; //the time taken for the transition TO a document presDuration?: number; //the duration of the slide in presentation view presProgressivize?: boolean; - // xArray?: number[]; - // yArray?: number[]; borderRounding?: string; boxShadow?: string; dontRegisterChildViews?: boolean; diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index b2e55adc7..28ba6945a 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -11,7 +11,6 @@ import { Id } from "../../../fields/FieldSymbols"; import { InkTool } from "../../../fields/InkField"; import { List } from "../../../fields/List"; import { ObjectField } from "../../../fields/ObjectField"; -import { RichTextField } from "../../../fields/RichTextField"; import { listSpec } from "../../../fields/Schema"; import { ScriptField } from "../../../fields/ScriptField"; import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types"; @@ -30,6 +29,7 @@ import { DocumentView } from "../nodes/DocumentView"; import RichTextMenu from "../nodes/formattedText/RichTextMenu"; import "./CollectionMenu.scss"; import { CollectionViewType, COLLECTION_BORDER_WIDTH } from "./CollectionView"; +import { Scripting } from "../../util/Scripting"; @observer export default class CollectionMenu extends AntimodeMenu { @@ -161,9 +161,9 @@ export class CollectionViewBaseChrome extends React.Component { this.target._panX = 0; this.target._panY = 0; this.target._viewScale = 1; }), - initialize: (button: Doc) => { button['target-panX'] = this.target._panX; button['target-panY'] = this.target._panY; button['target-viewScale'] = this.target._viewScale; }, + script: "self.target._panX = self['target-panX']; self.target._panY = self['target-panY']; self.target._viewScale = self['target-viewScale']; gotoFrame(self.target, self['target-currentFrame']);", + immediate: undoBatch((source: Doc[]) => { this.target._panX = 0; this.target._panY = 0; this.target._viewScale = 1; this.target.currentFrame = 0; }), + initialize: (button: Doc) => { button['target-panX'] = this.target._panX; button['target-panY'] = this.target._panY; button['target-viewScale'] = this.target._viewScale; button['target-currentFrame'] = this.target.currentFrame; }, }; _clusterCommand = { params: ["target"], title: "fit content", @@ -1078,4 +1078,15 @@ export class CollectionGridViewChrome extends React.Component ); } -} \ No newline at end of file +} +Scripting.addGlobal(function gotoFrame(doc: any, newFrame: any) { + const dataField = doc[Doc.LayoutFieldKey(doc)]; + const childDocs = DocListCast(dataField); + const currentFrame = Cast(doc.currentFrame, "number", null); + if (currentFrame === undefined) { + doc.currentFrame = 0; + CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0); + } + CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0); + doc.currentFrame = Math.max(0, newFrame); +}); \ No newline at end of file diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 5d6d7924e..f6bb375fc 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -179,7 +179,7 @@ export class CollectionFreeFormView extends CollectionSubView doc.dataTransition = "inherit", 1010); } - public static setupScroll(doc: Doc, timecode: number, scrollProgressivize: boolean = false) { + public static setupScroll(doc: Doc, timecode: number) { const scrollList = new List(); scrollList[timecode] = NumCast(doc._scrollTop); doc["scroll-indexed"] = scrollList; @@ -165,7 +165,7 @@ export class CollectionFreeFormDocumentView extends DocComponent(); const height = new List(); const top = new List(); @@ -180,31 +180,24 @@ export class CollectionFreeFormDocumentView extends DocComponent { - if (doc.appearFrame === undefined) doc.appearFrame = i; - const curTimecode = progressivize ? i : timecode; - const xlist = new List(numberRange(timecode + 1).map(i => undefined) as any as number[]); - const ylist = new List(numberRange(timecode + 1).map(i => undefined) as any as number[]); - const wlist = new List(numberRange(timecode + 1).map(i => undefined) as any as number[]); - const hlist = new List(numberRange(timecode + 1).map(i => undefined) as any as number[]); - const olist = new List(numberRange(timecode + 1).map(t => progressivize && t < (doc.appearFrame ? doc.appearFrame : i) ? 0 : 1)); - const oarray = olist; - oarray.fill(0, 0, NumCast(doc.appearFrame) - 1); - oarray.fill(1, NumCast(doc.appearFrame), timecode); - // oarray.fill(0, 0, NumCast(doc.appearFrame) - 1); - // oarray.fill(1, NumCast(doc.appearFrame), timecode);\ + public static setupKeyframes(docs: Doc[], currTimecode: number, makeAppear: boolean = false) { + docs.forEach(doc => { + if (doc.appearFrame === undefined) doc.appearFrame = currTimecode; + const curTimecode = currTimecode; + const xlist = new List(numberRange(currTimecode + 1).map(i => undefined) as any as number[]); + const ylist = new List(numberRange(currTimecode + 1).map(i => undefined) as any as number[]); + const wlist = new List(numberRange(currTimecode + 1).map(i => undefined) as any as number[]); + const hlist = new List(numberRange(currTimecode + 1).map(i => undefined) as any as number[]); + const olist = new List(numberRange(currTimecode + 1).map(t => !doc.z && makeAppear && t < NumCast(doc.appearFrame) ? 0 : 1)); wlist[curTimecode] = NumCast(doc._width); hlist[curTimecode] = NumCast(doc._height); xlist[curTimecode] = NumCast(doc.x); ylist[curTimecode] = NumCast(doc.y); - doc.xArray = xlist; - doc.yArray = ylist; doc["x-indexed"] = xlist; doc["y-indexed"] = ylist; doc["w-indexed"] = wlist; doc["h-indexed"] = hlist; - doc["opacity-indexed"] = oarray; + doc["opacity-indexed"] = olist; doc.activeFrame = ComputedField.MakeFunction("self.context?.currentFrame||0"); doc._height = ComputedField.MakeInterpolated("h", "activeFrame"); doc._width = ComputedField.MakeInterpolated("w", "activeFrame"); diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 5fc76223d..f39413e9f 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -1052,15 +1052,17 @@ export class PresBox extends ViewBoxBaseComponent if (layout) doc = this.createTemplate(layout); if (freeform && layout) doc = this.createTemplate(layout, title); if (!freeform && !layout) doc = Docs.Create.TextDocument("", { _nativeWidth: 400, _width: 225, title: title }); - const presCollection = Cast(this.layoutDoc.presCollection, Doc, null); - const data = Cast(presCollection?.data, listSpec(Doc)); - const presData = Cast(this.rootDoc.data, listSpec(Doc)); - if (data && doc && presData) { - data.push(doc); - DockedFrameRenderer.PinDoc(doc, false); - this.gotoDocument(this.childDocs.length, this.itemIndex); - } else { - this.props.addDocTab(doc as Doc, "onRight"); + if (doc) { + const presCollection = Cast(this.layoutDoc.presCollection, Doc, null); + const data = Cast(presCollection?.data, listSpec(Doc)); + const presData = Cast(this.rootDoc.data, listSpec(Doc)); + if (data && presData) { + data.push(doc); + DockedFrameRenderer.PinDoc(doc, false); + this.gotoDocument(this.childDocs.length, this.itemIndex); + } else { + this.props.addDocTab(doc as Doc, "onRight"); + } } } @@ -1341,7 +1343,7 @@ export class PresBox extends ViewBoxBaseComponent activeItem.scrollProgressivize = !activeItem.scrollProgressivize; const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); targetDoc.scrollProgressivize = !targetDoc.scrollProgressivize; - CollectionFreeFormDocumentView.setupScroll(targetDoc, NumCast(targetDoc.currentFrame), true); + CollectionFreeFormDocumentView.setupScroll(targetDoc, NumCast(targetDoc.currentFrame)); if (targetDoc.editScrollProgressivize) { targetDoc.editScrollProgressivize = false; targetDoc.currentFrame = 0; @@ -1357,7 +1359,7 @@ export class PresBox extends ViewBoxBaseComponent activeItem.zoomProgressivize = !activeItem.zoomProgressivize; const targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null); targetDoc.zoomProgressivize = !targetDoc.zoomProgressivize; - CollectionFreeFormDocumentView.setupZoom(activeItem, targetDoc, true); + CollectionFreeFormDocumentView.setupZoom(activeItem, targetDoc); if (activeItem.editZoomProgressivize) { activeItem.editZoomProgressivize = false; targetDoc.currentFrame = 0; @@ -1390,7 +1392,7 @@ export class PresBox extends ViewBoxBaseComponent activeItem.presProgressivize = true; targetDoc.presProgressivize = true; targetDoc.currentFrame = 0; - CollectionFreeFormDocumentView.setupKeyframes(docs, docs.length, true); + docs.forEach((doc, i) => CollectionFreeFormDocumentView.setupKeyframes([doc], i, true)); targetDoc.lastFrame = docs.length - 1; } else { targetDoc.editProgressivize = false; -- cgit v1.2.3-70-g09d2 From 14066426ecbb34dd53909b2aecd4be0edceb4c23 Mon Sep 17 00:00:00 2001 From: yunahi <60233430+yunahi@users.noreply.github.com> Date: Thu, 20 Aug 2020 22:03:41 +0900 Subject: fixed lasso --- src/client/views/collections/collectionFreeForm/MarqueeView.tsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 1a708d67d..3606d5402 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -729,14 +729,12 @@ export class MarqueeView extends React.Component; } else { - //subtracted 250 for offset var str: string = ""; for (var i = 0; i < this._pointsX.length; i++) { - var x = 0; - x = this._pointsX[i] - 250; - str += x.toString(); + const pt = this.props.getContainerTransform().transformPoint(this._pointsX[i], this._pointsY[i]); + str += pt[0].toString(); str += ","; - str += this._pointsY[i].toString(); + str += pt[1].toString(); str += (" "); } -- cgit v1.2.3-70-g09d2 From 36630b9aa2e1c4710a69a4fdf4ec98c3f5bca92c Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 21 Aug 2020 16:05:52 -0400 Subject: trying scenes instead of workspaces --- src/client/util/CurrentUserUtils.ts | 40 ++++++------- src/client/util/History.ts | 2 +- src/client/util/SettingsManager.tsx | 2 +- src/client/views/DocumentDecorations.tsx | 2 +- src/client/views/MainView.scss | 2 +- src/client/views/MainView.tsx | 50 ++++++++-------- .../views/collections/CollectionDockingView.tsx | 12 ++-- .../views/collections/CollectionTreeView.tsx | 8 +-- src/client/views/collections/CollectionView.tsx | 2 +- .../CollectionFreeFormLayoutEngines.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 1 - src/client/views/nodes/DocumentView.tsx | 10 ++-- .../views/nodes/formattedText/DashDocView.tsx | 4 +- .../views/nodes/formattedText/RichTextSchema.tsx | 4 +- src/mobile/MobileInterface.tsx | 70 +++++++++++----------- 15 files changed, 105 insertions(+), 106 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 8dd7b033b..4b1c48bd3 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -36,7 +36,7 @@ export class CurrentUserUtils { @computed public static get UserDocument() { return Doc.UserDoc(); } @observable public static GuestTarget: Doc | undefined; - @observable public static GuestWorkspace: Doc | undefined; + @observable public static GuestScene: Doc | undefined; @observable public static GuestMobile: Doc | undefined; @observable public static propertiesWidth: number = 0; @@ -511,7 +511,7 @@ export class CurrentUserUtils { this.setupSharingSidebar(doc); // sets up the right sidebar collection for mobile upload documents and sharing return [ { title: "Sharing", target: Cast(doc["sidebar-sharing"], Doc, null), icon: "users", click: 'selectMainMenu(self)', watchedDocuments: doc["sidebar-sharing"] as Doc }, - { title: "Workspace", target: Cast(doc["sidebar-workspaces"], Doc, null), icon: "desktop", click: 'selectMainMenu(self)' }, + { title: "Scenes", target: Cast(doc["sidebar-scenes"], Doc, null), icon: "desktop", click: 'selectMainMenu(self)' }, { title: "Catalog", target: undefined as any, icon: "file", click: 'selectMainMenu(self)' }, { title: "Archive", target: Cast(doc["sidebar-recentlyClosed"], Doc, null), icon: "archive", click: 'selectMainMenu(self)' }, { title: "Import", target: Cast(doc["sidebar-import"], Doc, null), icon: "upload", click: 'selectMainMenu(self)' }, @@ -592,7 +592,7 @@ export class CurrentUserUtils { // SEts up mobile buttons for inside mobile menu static setupMobileButtons(doc?: Doc, buttons?: string[]) { const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, ischecked?: string, activePen?: Doc, backgroundColor?: string, info: string, dragFactory?: Doc }[] = [ - { title: "WORKSPACES", icon: "bars", click: 'switchToMobileLibrary()', backgroundColor: "lightgrey", info: "Access your Workspaces from your mobile, and navigate through all of your documents. " }, + { title: "SCENES", icon: "bars", click: 'switchToMobileLibrary()', backgroundColor: "lightgrey", info: "Access your Scenes from your mobile, and navigate through all of your documents. " }, { title: "UPLOAD", icon: "upload", click: 'openMobileUploads()', backgroundColor: "lightgrey", info: "Upload files from your mobile device so they can be accessed on Dash Web." }, { title: "MOBILE UPLOAD", icon: "mobile", click: 'switchToMobileUploadCollection()', backgroundColor: "lightgrey", info: "Access the collection of your mobile uploads." }, { title: "RECORD", icon: "microphone", click: 'openMobileAudio()', backgroundColor: "lightgrey", info: "Use your phone to record, dictate and then upload audio onto Dash Web." }, @@ -689,7 +689,7 @@ export class CurrentUserUtils { } static setupLibrary(userDoc: Doc) { - return CurrentUserUtils.setupWorkspaces(userDoc); + return CurrentUserUtils.setupScenes(userDoc); } // setup the Creator button which will display the creator panel. This panel will include the drag creators and the color picker. @@ -724,28 +724,28 @@ export class CurrentUserUtils { } } - static async setupWorkspaces(doc: Doc) { - // setup workspaces library item - await doc.myWorkspaces; - if (doc.myWorkspaces === undefined) { - doc.myWorkspaces = new PrefetchProxy(Docs.Create.TreeDocument([], { - title: "WORKSPACES", _height: 100, forceActive: true, boxShadow: "0 0", lockedPosition: true, treeViewOpen: true, system: true + static async setupScenes(doc: Doc) { + // setup scenes library item + await doc.myScenes; + if (doc.myScenes === undefined) { + doc.myScenes = new PrefetchProxy(Docs.Create.TreeDocument([], { + title: "SCENES", _height: 100, forceActive: true, boxShadow: "0 0", lockedPosition: true, treeViewOpen: true, system: true })); } - if (doc["sidebar-workspaces"] === undefined) { - const newWorkspace = ScriptField.MakeScript(`createNewWorkspace()`); - (doc.myWorkspaces as Doc).contextMenuScripts = new List([newWorkspace!]); - (doc.myWorkspaces as Doc).contextMenuLabels = new List(["Create New Workspace"]); + if (doc["sidebar-scenes"] === undefined) { + const newScene = ScriptField.MakeScript(`createNewScene()`); + (doc.myScenes as Doc).contextMenuScripts = new List([newScene!]); + (doc.myScenes as Doc).contextMenuLabels = new List(["Create New Scene"]); - const workspaces = doc.myWorkspaces as Doc; + const scenes = doc.myScenes as Doc; - doc["sidebar-workspaces"] = new PrefetchProxy(Docs.Create.TreeDocument([workspaces], { + doc["sidebar-scenes"] = new PrefetchProxy(Docs.Create.TreeDocument([scenes], { treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "alias", treeViewTruncateTitleWidth: 150, hideFilterView: true, treeViewPreventOpen: false, treeViewOpen: true, lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true })) as any as Doc; } - return doc.myWorkspaces as any as Doc; + return doc.myScenes as any as Doc; } static setupCatalog(doc: Doc) { @@ -821,7 +821,7 @@ export class CurrentUserUtils { static async setupSidebarButtons(doc: Doc) { CurrentUserUtils.setupSidebarContainer(doc); await CurrentUserUtils.setupToolsBtnPanel(doc); - CurrentUserUtils.setupWorkspaces(doc); + CurrentUserUtils.setupScenes(doc); CurrentUserUtils.setupCatalog(doc); CurrentUserUtils.setupRecentlyClosed(doc); CurrentUserUtils.setupUserDoc(doc); @@ -1002,8 +1002,8 @@ export class CurrentUserUtils { } } -Scripting.addGlobal(function createNewWorkspace() { return MainView.Instance.createNewWorkspace(); }, - "creates a new workspace when called"); +Scripting.addGlobal(function createNewScene() { return MainView.Instance.createNewScene(); }, + "creates a new scene when called"); 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)"); diff --git a/src/client/util/History.ts b/src/client/util/History.ts index 7b7d4b835..aed887055 100644 --- a/src/client/util/History.ts +++ b/src/client/util/History.ts @@ -197,7 +197,7 @@ export namespace HistoryUtil { await Promise.all(Object.keys(init).map(id => initDoc(id, init[id]))); } if (field instanceof Doc) { - MainView.Instance.openWorkspace(field, true); + MainView.Instance.openScene(field, true); } } diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx index 5642c5a42..b2131c9b2 100644 --- a/src/client/util/SettingsManager.tsx +++ b/src/client/util/SettingsManager.tsx @@ -158,7 +158,7 @@ export default class SettingsManager extends React.Component<{}> {
Settings
{Doc.CurrentUserEmail}
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 0cc492ee9..fdce8bf71 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -596,7 +596,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> return ; } render() { - const darkScheme = Cast(Doc.UserDoc().activeWorkspace, Doc, null)?.darkScheme ? "dimgray" : undefined; + const darkScheme = Cast(Doc.UserDoc().activeScene, Doc, null)?.darkScheme ? "dimgray" : undefined; const bounds = this.Bounds; const seldoc = SelectionManager.SelectedDocuments().length ? SelectionManager.SelectedDocuments()[0] : undefined; if (SnappingManager.GetIsDragging() || bounds.r - bounds.x < 1 || bounds.x === Number.MAX_VALUE || !seldoc || this._hidden || isNaN(bounds.r) || isNaN(bounds.b) || isNaN(bounds.x) || isNaN(bounds.y)) { diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss index a05a2b858..fb80bfc0d 100644 --- a/src/client/views/MainView.scss +++ b/src/client/views/MainView.scss @@ -313,7 +313,7 @@ } -.mainView-workspace { +.mainView-scene { height: 200px; position: relative; display: flex; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 6bbe09974..08ac69a38 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -77,10 +77,10 @@ export class MainView extends React.Component { @observable private _panelHeight: number = 0; @observable private _flyoutTranslate: boolean = false; @observable public flyoutWidth: number = 0; - private get darkScheme() { return BoolCast(Cast(this.userDoc?.activeWorkspace, Doc, null)?.darkScheme); } + private get darkScheme() { return BoolCast(Cast(this.userDoc?.activeScene, Doc, null)?.darkScheme); } @computed private get userDoc() { return Doc.UserDoc(); } - @computed private get mainContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeWorkspace, Doc)) : CurrentUserUtils.GuestWorkspace; } + @computed private get mainContainer() { return this.userDoc ? FieldValue(Cast(this.userDoc.activeScene, Doc)) : CurrentUserUtils.GuestScene; } @computed public get mainFreeform(): Opt { return (docs => (docs && docs.length > 1) ? docs[1] : undefined)(DocListCast(this.mainContainer!.data)); } @computed public get searchDoc() { return Cast(this.userDoc["search-panel"], Doc) as Doc; } @@ -224,12 +224,12 @@ export class MainView extends React.Component { } initAuthenticationRouters = async () => { - // Load the user's active workspace, or create a new one if initial session after signup + // Load the user's active scene, or create a new one if initial session after signup const received = CurrentUserUtils.MainDocId; if (received && !this.userDoc) { reaction( () => CurrentUserUtils.GuestTarget, - target => target && this.createNewWorkspace(), + target => target && this.createNewScene(), { fireImmediately: true } ); } else { @@ -242,21 +242,21 @@ export class MainView extends React.Component { }), ); } - const doc = this.userDoc && await Cast(this.userDoc.activeWorkspace, Doc); + const doc = this.userDoc && await Cast(this.userDoc.activeScene, Doc); if (doc) { - this.openWorkspace(doc); + this.openScene(doc); } else { - this.createNewWorkspace(); + this.createNewScene(); } } } @action - createNewWorkspace = async (id?: string) => { + createNewScene = async (id?: string) => { const myCatalog = Doc.UserDoc().myCatalog as Doc; const presentation = Doc.MakeCopy(Doc.UserDoc().emptyPresentation as Doc, true); - const workspaces = Cast(this.userDoc.myWorkspaces, Doc) as Doc; - const workspaceCount = DocListCast(workspaces.data).length + 1; + const scenes = Cast(this.userDoc.myScenes, Doc) as Doc; + const sceneCount = DocListCast(scenes.data).length + 1; const freeformOptions: DocumentOptions = { x: 0, y: 400, @@ -265,28 +265,28 @@ export class MainView extends React.Component { title: "Untitled Collection", }; const freeformDoc = CurrentUserUtils.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions); - const workspaceDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600, path: [myCatalog] }], { title: `Workspace ${workspaceCount}` }, id, "row"); + const sceneDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600, path: [myCatalog] }], { title: `Scene ${sceneCount}` }, id, "row"); Doc.AddDocToList(myCatalog, "data", freeformDoc); Doc.AddDocToList(myCatalog, "data", presentation); Doc.UserDoc().activePresentation = presentation; const toggleTheme = ScriptField.MakeScript(`self.darkScheme = !self.darkScheme`); const toggleComic = ScriptField.MakeScript(`toggleComicMode()`); - const copyWorkspace = ScriptField.MakeScript(`copyWorkspace()`); - workspaceDoc.contextMenuScripts = new List([toggleTheme!, toggleComic!, copyWorkspace!]); - workspaceDoc.contextMenuLabels = new List(["Toggle Theme Colors", "Toggle Comic Mode", "Snapshot Workspace"]); + const copyScene = ScriptField.MakeScript(`copyScene()`); + sceneDoc.contextMenuScripts = new List([toggleTheme!, toggleComic!, copyScene!]); + sceneDoc.contextMenuLabels = new List(["Toggle Theme Colors", "Toggle Comic Mode", "Snapshot Scene"]); - Doc.AddDocToList(workspaces, "data", workspaceDoc); + Doc.AddDocToList(scenes, "data", sceneDoc); // bcz: strangely, we need a timeout to prevent exceptions/issues initializing GoldenLayout (the rendering engine for Main Container) - setTimeout(() => this.openWorkspace(workspaceDoc), 0); + setTimeout(() => this.openScene(sceneDoc), 0); } @action - openWorkspace = (doc: Doc, fromHistory = false) => { + openScene = (doc: Doc, fromHistory = false) => { CurrentUserUtils.MainDocId = doc[Id]; - if (doc) { // this has the side-effect of setting the main container since we're assigning the active/guest workspace + if (doc) { // this has the side-effect of setting the main container since we're assigning the active/guest scene !("presentationView" in doc) && (doc.presentationView = new List([Docs.Create.TreeDocument([], { title: "Presentation" })])); - this.userDoc ? (this.userDoc.activeWorkspace = doc) : (CurrentUserUtils.GuestWorkspace = doc); + this.userDoc ? (this.userDoc.activeScene = doc) : (CurrentUserUtils.GuestScene = doc); } const state = this._urlState; if (state.sharing === true && !this.userDoc) { @@ -438,7 +438,7 @@ export class MainView extends React.Component { flyoutWidthFunc = () => this.flyoutWidth; addDocTabFunc = (doc: Doc, where: string, libraryPath?: Doc[]): boolean => { return where === "close" ? CollectionDockingView.CloseRightSplit(doc) : - doc.dockingConfig ? this.openWorkspace(doc) : + doc.dockingConfig ? this.openScene(doc) : CollectionDockingView.AddRightSplit(doc, libraryPath); } sidebarScreenToLocal = () => new Transform(0, (CollectionMenu.Instance.Pinned ? -35 : 0) - Number(SEARCH_PANEL_HEIGHT.replace("px", "")), 1); @@ -977,12 +977,12 @@ export class MainView extends React.Component { } Scripting.addGlobal(function selectMainMenu(doc: Doc, title: string) { MainView.Instance.selectMenu(doc); }); Scripting.addGlobal(function toggleComicMode() { Doc.UserDoc().fontFamily = "Comic Sans MS"; Doc.UserDoc().renderStyle = Doc.UserDoc().renderStyle === "comic" ? undefined : "comic"; }); -Scripting.addGlobal(function copyWorkspace() { - const copiedWorkspace = Doc.MakeCopy(Cast(Doc.UserDoc().activeWorkspace, Doc, null), true); - const workspaces = Cast(Doc.UserDoc().myWorkspaces, Doc, null); - Doc.AddDocToList(workspaces, "data", copiedWorkspace); +Scripting.addGlobal(function copyScene() { + const copiedScene = Doc.MakeCopy(Cast(Doc.UserDoc().activeScene, Doc, null), true); + const scenes = Cast(Doc.UserDoc().myScenes, Doc, null); + Doc.AddDocToList(scenes, "data", copiedScene); // bcz: strangely, we need a timeout to prevent exceptions/issues initializing GoldenLayout (the rendering engine for Main Container) - setTimeout(() => MainView.Instance.openWorkspace(copiedWorkspace), 0); + setTimeout(() => MainView.Instance.openScene(copiedScene), 0); }); Scripting.addGlobal(function importDocument() { return MainView.Instance.importDocument(); }, "imports files from device directly into the import sidebar"); diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 43da0d3cf..6338e69a4 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -96,7 +96,7 @@ export class CollectionDockingView extends React.Component this.setupGoldenLayout(), 1); - DocListCast((Doc.UserDoc().myWorkspaces as Doc).data).map(d => d.workspaceBrush = false); - this.props.Document.workspaceBrush = true; + DocListCast((Doc.UserDoc().myScenes as Doc).data).map(d => d.sceneBrush = false); + this.props.Document.sceneBrush = true; } this._ignoreStateChange = ""; }, { fireImmediately: true }); @@ -421,7 +421,7 @@ export class CollectionDockingView extends React.Component void = () => { try { - this.props.Document.workspaceBrush = false; + this.props.Document.sceneBrush = false; this._goldenLayout.unbind('itemDropped', this.itemDropped); this._goldenLayout.unbind('tabCreated', this.tabCreated); this._goldenLayout.unbind('stackCreated', this.stackCreated); @@ -668,7 +668,7 @@ export class CollectionDockingView extends React.Component 0) { - return
Nested workspaces can't be rendered
; + return
Nested scenes can't be rendered
; } return ; diff --git a/src/client/views/Palette.tsx b/src/client/views/Palette.tsx index 0a4334302..92c3f09b4 100644 --- a/src/client/views/Palette.tsx +++ b/src/client/views/Palette.tsx @@ -3,7 +3,7 @@ import { observer } from "mobx-react"; import * as React from "react"; import { Doc } from "../../fields/Doc"; import { NumCast } from "../../fields/Types"; -import { emptyFunction, emptyPath, returnEmptyString, returnZero, returnFalse, returnOne, returnTrue, returnEmptyFilter } from "../../Utils"; +import { emptyFunction, emptyPath, returnEmptyString, returnZero, returnFalse, returnOne, returnTrue, returnEmptyFilter, returnEmptyDoclist } from "../../Utils"; import { Transform } from "../util/Transform"; import { DocumentView } from "./nodes/DocumentView"; import "./Palette.scss"; @@ -60,6 +60,7 @@ export default class Palette extends React.Component { whenActiveChanged={emptyFunction} bringToFront={emptyFunction} docFilters={returnEmptyFilter} + searchFilterDocs={returnEmptyDoclist} ContainingCollectionView={undefined} ContainingCollectionDoc={undefined} />
diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx index eb20fc257..e4ba45648 100644 --- a/src/client/views/TemplateMenu.tsx +++ b/src/client/views/TemplateMenu.tsx @@ -10,7 +10,7 @@ import { Doc, DocListCast } from "../../fields/Doc"; import { Docs, DocUtils, } from "../documents/Documents"; import { StrCast, Cast } from "../../fields/Types"; import { CollectionTreeView } from "./collections/CollectionTreeView"; -import { returnTrue, emptyFunction, returnFalse, returnOne, emptyPath, returnZero, returnEmptyFilter } from "../../Utils"; +import { returnTrue, emptyFunction, returnFalse, returnOne, emptyPath, returnZero, returnEmptyFilter, returnEmptyDoclist } from "../../Utils"; import { Transform } from "../util/Transform"; import { ScriptField, ComputedField } from "../../fields/ScriptField"; import { Scripting } from "../util/Scripting"; @@ -133,6 +133,7 @@ export class TemplateMenu extends React.Component { ContainingCollectionDoc={undefined} ContainingCollectionView={undefined} docFilters={returnEmptyFilter} + searchFilterDocs={returnEmptyDoclist} rootSelected={returnFalse} onCheckedClick={this.scriptField} onChildClick={this.scriptField} diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 83321d6e0..74b1e5714 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -14,7 +14,7 @@ import { FieldId } from "../../../fields/RefField"; import { listSpec } from '../../../fields/Schema'; import { Cast, NumCast, StrCast } from "../../../fields/Types"; import { TraceMobx } from '../../../fields/util'; -import { emptyFunction, emptyPath, returnEmptyFilter, returnFalse, returnOne, returnTrue, returnZero, setupMoveUpEvents, Utils } from "../../../Utils"; +import { emptyFunction, emptyPath, returnEmptyFilter, returnFalse, returnOne, returnTrue, returnZero, setupMoveUpEvents, Utils, returnEmptyDoclist } from "../../../Utils"; import { DocServer } from "../../DocServer"; import { Docs } from '../../documents/Documents'; import { DocumentManager } from '../../util/DocumentManager'; @@ -938,6 +938,7 @@ export class DockedFrameRenderer extends React.Component { addDocTab={this.addDocTab} pinToPres={DockedFrameRenderer.PinDoc} docFilters={returnEmptyFilter} + searchFilterDocs={returnEmptyDoclist} fitToBox={true} />
@@ -979,6 +980,7 @@ export class DockedFrameRenderer extends React.Component { addDocTab={this.addDocTab} pinToPres={DockedFrameRenderer.PinDoc} docFilters={returnEmptyFilter} + searchFilterDocs={returnEmptyDoclist} ContainingCollectionView={undefined} ContainingCollectionDoc={undefined} /> {document._viewType === CollectionViewType.Freeform && !this._document?.hideMinimap ? this.renderMiniMap() : (null)} diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx index e1b07077e..0fd18034f 100644 --- a/src/client/views/collections/CollectionLinearView.tsx +++ b/src/client/views/collections/CollectionLinearView.tsx @@ -166,6 +166,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) { whenActiveChanged={emptyFunction} bringToFront={emptyFunction} docFilters={this.props.docFilters} + searchFilterDocs={this.props.searchFilterDocs} ContainingCollectionView={undefined} ContainingCollectionDoc={undefined} />
; diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 388eda2b3..5580c32f2 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -131,7 +131,7 @@ export class CollectionViewBaseChrome extends React.Component Doc.GetProto(this.target).data = new List(source)), // Doc.aliasDocs(source), + immediate: undoBatch((source: Doc[]) => Doc.GetProto(this.target).data = new List(source)), initialize: emptyFunction, }; _onClickCommand = { @@ -180,12 +180,16 @@ export class CollectionViewBaseChrome extends React.Component this.target._docFilters = undefined), - initialize: (button: Doc) => { button['target-docFilters'] = this.target._docFilters instanceof ObjectField ? ObjectField.MakeCopy(this.target._docFilters as any as ObjectField) : ""; }, + script: `self.target._docFilters = copyField(self['target-docFilters']); + self.target._searchFilterDocs = compareLists(self['target-searchFilterDocs'],self.target._searchFilterDocs) ? undefined: copyField(self['target-searchFilterDocs']);`, + immediate: undoBatch((source: Doc[]) => { this.target._docFilters = undefined; this.target._searchFilterDocs = undefined; }), + initialize: (button: Doc) => { + button['target-docFilters'] = this.target._docFilters instanceof ObjectField ? ObjectField.MakeCopy(this.target._docFilters as any as ObjectField) : undefined; + button['target-searchFilterDocs'] = this.target._searchFilterDocs instanceof ObjectField ? ObjectField.MakeCopy(this.target._searchFilterDocs as any as ObjectField) : undefined; + }, }; - @computed get _freeform_commands() { return Doc.UserDoc().noviceMode ? [this._viewCommand] : [this._viewCommand, this._saveFilterCommand, this._contentCommand, this._templateCommand, this._narrativeCommand]; } + @computed get _freeform_commands() { return Doc.UserDoc().noviceMode ? [this._viewCommand, this._saveFilterCommand] : [this._viewCommand, this._saveFilterCommand, this._contentCommand, this._templateCommand, this._narrativeCommand]; } @computed get _stacking_commands() { return Doc.UserDoc().noviceMode ? undefined : [this._contentCommand, this._templateCommand]; } @computed get _masonry_commands() { return Doc.UserDoc().noviceMode ? undefined : [this._contentCommand, this._templateCommand]; } @computed get _schema_commands() { return Doc.UserDoc().noviceMode ? undefined : [this._templateCommand, this._narrativeCommand]; } diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index 4bd69041b..2f1f7a90f 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -229,7 +229,7 @@ export class CollectionSchemaCell extends React.Component { const fieldIsDoc = (type === "document" && typeof field === "object") || (typeof field === "object" && doc); const onItemDown = async (e: React.PointerEvent) => { - if (this.props.Document._searchDoc !== undefined) { + if (this.props.Document._searchDoc) { const doc = Doc.GetProto(this.props.rowProps.original); const aliasdoc = await SearchUtil.GetAliasesOfDocument(doc); let targetContext = undefined; @@ -315,7 +315,7 @@ export class CollectionSchemaCell extends React.Component { } } let search = false; - if (this.props.Document._searchDoc !== undefined) { + if (this.props.Document._searchDoc) { search = true; } @@ -900,7 +900,7 @@ export class CollectionSchemaButtons extends CollectionSchemaCell { // (!this.props.CollectionView || !this.props.CollectionView.props.isSelected() ? undefined : // SetupDrag(reference, () => this._document, this.props.moveDocument, this.props.Document.schemaDoc ? "copy" : undefined)(e)); // }; - return !BoolCast(this.props.Document._searchDoc) ? <> + return !this.props.Document._searchDoc ? <> : [DocumentType.PDF, DocumentType.RTF].includes(StrCast(doc.type) as DocumentType) ?
; } diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 82ece7dc3..6e452e52d 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -24,6 +24,7 @@ import React = require("react"); import { DocumentLinksButton } from './nodes/DocumentLinksButton'; import { Tooltip } from '@material-ui/core'; import SharingManager from '../util/SharingManager'; +import { CurrentUserUtils } from '../util/CurrentUserUtils'; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -216,6 +217,17 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
; } + @computed + get moreButton() { + const targetDoc = this.view0?.props.Document; + return !targetDoc ? (null) :
{"Open Properties Panel"}
}> +
+ CurrentUserUtils.propertiesWidth = CurrentUserUtils.propertiesWidth > 0 ? 0 : 250)}> + +
; + } + @computed get metadataButton() { const view0 = this.view0; @@ -304,8 +316,11 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
{this.pinButton}
-
+ {/*
{this.shareButton} +
*/} +
+ {this.moreButton}
{/*
{this.considerGoogleDocsPush} diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index ec3e754fb..b96802f06 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -227,7 +227,10 @@ export class EditableView extends React.Component { ref={this._ref} style={{ display: this.props.display, minHeight: "17px", whiteSpace: "nowrap", height: `${this.props.height ? this.props.height : "auto"}`, maxHeight: `${this.props.maxHeight}` }} onClick={this.onClick} placeholder={this.props.placeholder}> - {this.props.highlight === undefined || this.props.positions === undefined || this.props.bing === undefined ? {this.props.contents ? this.props.contents?.valueOf() : this.props.placeholder?.valueOf()} + {this.props.highlight === undefined || this.props.positions === undefined || this.props.bing === undefined ? + {//}, color: this.props.contents ? "black" : "grey" }}>{ + this.props.contents ? this.props.contents?.valueOf() : this.props.placeholder?.valueOf()} + : this.returnHighlights()}
); diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index ccb051f6d..f8be58f8d 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -182,7 +182,7 @@ export class MainView extends React.Component { fa.faDesktop, fa.faTrashRestore, fa.faUsers, fa.faWrench, fa.faCog, fa.faMap, fa.faBellSlash, fa.faExpandAlt, fa.faArchive, fa.faBezierCurve, fa.faCircle, fa.faLongArrowAltRight, fa.faPenFancy, fa.faAngleDoubleRight, faBuffer, fa.faExpand, fa.faUndo, fa.faSlidersH, fa.faAngleDoubleLeft, fa.faAngleUp, fa.faAngleDown, fa.faPlayCircle, fa.faClock, fa.faRocket, fa.faExchangeAlt, faBuffer, fa.faHashtag, fa.faAlignJustify, fa.faCheckSquare, fa.faListUl, - fa.faWindowMinimize, fa.faWindowRestore); + fa.faWindowMinimize, fa.faWindowRestore, fa.faTextWidth, fa.faClosedCaptioning); this.initEventListeners(); this.initAuthenticationRouters(); } diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx index 0eee46275..5d8f30354 100644 --- a/src/client/views/PreviewCursor.tsx +++ b/src/client/views/PreviewCursor.tsx @@ -92,6 +92,7 @@ export class PreviewCursor extends React.Component<{}> { _width: 500, limitHeight: 400, _autoHeight: true, + _showTitle: Doc.UserDoc().showTitle ? "title" : undefined, x: newPoint[0], y: newPoint[1], title: "-pasted text-" diff --git a/src/client/views/PropertiesButtons.scss b/src/client/views/PropertiesButtons.scss index 8d9d56c9e..d63eb874c 100644 --- a/src/client/views/PropertiesButtons.scss +++ b/src/client/views/PropertiesButtons.scss @@ -43,6 +43,13 @@ $linkGap : 3px; cursor: pointer; } } +.propertiesButtons-linkButton-empty.toggle-on { + background-color: white; + color: black; +} +.propertiesButtons-linkButton-empty.toggle-off { + color: white; +} .propertiesButtons { margin-top: 3px; diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index bcb492c49..ecd0ee37e 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -219,18 +219,11 @@ export class PropertiesButtons extends React.Component<{}, {}> { const isPinned = targetDoc && Doc.isDocPinned(targetDoc); return !targetDoc ? (null) : {Doc.isDocPinned(targetDoc) ? "Unpin from presentation" : "Pin to presentation"}
} placement="top">
-
DockedFrameRenderer.PinDoc(targetDoc, isPinned)}> +
DockedFrameRenderer.PinDoc(targetDoc, isPinned)}>
-
{Doc.isDocPinned(targetDoc) ? "Unpin" : "Pin"}
+
{Doc.isDocPinned(targetDoc) ? "Unpin" : "Pin"}
; } @@ -375,17 +368,12 @@ export class PropertiesButtons extends React.Component<{}, {}> { return !targetDoc ? (null) : {`${this.selectedDoc?.lockedPosition ? "Unlock" : "Lock"} " Position"`}
} placement="top">
-
+
Position
; @@ -426,12 +414,88 @@ export class PropertiesButtons extends React.Component<{}, {}> { SelectionManager.DeselectAll(); } + @undoBatch + @action + setDictation = () => { + this.selectedDoc && (this.selectedDoc._showAudio = !this.selectedDoc._showAudio); + } + + @computed + get dictationButton() { + const targetDoc = this.selectedDoc; + return !targetDoc ? (null) : {"Show Dictation Controls"}
} placement="top"> +
+
+ +
+
Dictate
+
+ ; + } + + + @undoBatch + @action + setTitle = () => { + this.selectedDoc && (this.selectedDoc._showTitle = this.selectedDoc._showTitle === undefined ? "title" : undefined); + } + + @computed + get titleButton() { + const targetDoc = this.selectedDoc; + return !targetDoc ? (null) : {"Show Title Header"}
} placement="top"> +
+
+ +
+
Title
+
+ ; + } + + @undoBatch + @action + setCaption = () => { + this.selectedDoc && (this.selectedDoc._showCaption = this.selectedDoc._showCaption === undefined ? "caption" : undefined); + } + + @computed + get captionButton() { + const targetDoc = this.selectedDoc; + return !targetDoc ? (null) : {"Show Caption Footer"}
} placement="top"> +
+
+ +
+
Caption
+
+ ; + } + + @undoBatch + @action + setChrome = () => { + this.selectedDoc && (this.selectedDoc._chromeStatus = this.selectedDoc._chromeStatus === "disabled" ? "enabled" : "disabled"); + } + + @computed + get chromeButton() { + const targetDoc = this.selectedDoc; + return !targetDoc ? (null) : {"Show Editing UI"}
} placement="top"> +
+
+ +
+
Controls
+
+ ; + } + @computed get sharingButton() { const targetDoc = this.selectedDoc; const docView = this.selectedDocumentView?.props.Document === this.selectedDoc ? this.selectedDocumentView : undefined; - return !targetDoc ? (null) :
{"Share Document"}
} placement="top"> + return !targetDoc ? (null) : {"Share Document"}
} placement="top">
this.selectedDocumentView && SharingManager.Instance.open(docView, this.selectedDoc)}> @@ -561,19 +625,10 @@ export class PropertiesButtons extends React.Component<{}, {}> { return !targetDoc ? (null) :
{this.selectedDoc?.useClusters ? "Stop Showing Clusters" : "Show Clusters"}
} placement="top">
-
- {} +
+
-
clusters
+
clusters
; } @@ -594,19 +649,10 @@ export class PropertiesButtons extends React.Component<{}, {}> { return !targetDoc ? (null) :
{this.selectedDoc?._fitToBox ? "Stop Fitting Content" : "Fit Content"}
} placement="top">
-
- {} +
+
-
{this.selectedDoc?._fitToBox ? "unfit" : "fit"}
+
{this.selectedDoc?._fitToBox ? "unfit" : "fit"}
; } @@ -690,9 +736,9 @@ export class PropertiesButtons extends React.Component<{}, {}> { const collectionAcl = GetEffectiveAcl(this.selectedDocumentView?.props.ContainingCollectionDoc?.[DataSym]); return
-
+ {/*
{this.templateButton} -
+
*/} {/*
{this.metadataButton}
*/} @@ -705,9 +751,21 @@ export class PropertiesButtons extends React.Component<{}, {}> {
{this.copyButton}
+
+ {this.titleButton} +
+
+ {this.captionButton} +
+
+ {this.chromeButton} +
{this.lockButton}
+
+ {this.dictationButton} +
{this.downloadButton}
diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx index e4ba45648..870af03aa 100644 --- a/src/client/views/TemplateMenu.tsx +++ b/src/client/views/TemplateMenu.tsx @@ -116,9 +116,9 @@ export class TemplateMenu extends React.Component { const addedTypes = DocListCast(Cast(Doc.UserDoc()["template-buttons"], Doc, null)?.data); const layout = Doc.Layout(firstDoc); const templateMenu: Array = []; - this.props.templates.forEach((checked, template) => - templateMenu.push()); - templateMenu.push(); + //this.props.templates.forEach((checked, template) => + // templateMenu.push()); + //templateMenu.push(); templateMenu.push(); templateMenu.push(); addedTypes.concat(noteTypes).map(template => template.treeViewChecked = this.templateIsUsed(firstDoc, template)); diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx index c772dcfe7..1c96f69bf 100644 --- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx +++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx @@ -140,7 +140,7 @@ export class CollectionMasonryViewFieldRow extends React.Component { this._createAliasSelected = false; const key = StrCast(this.props.parent.props.Document._pivotField); - const newDoc = Docs.Create.TextDocument(value, { _autoHeight: true, _width: 200, title: value }); + const newDoc = Docs.Create.TextDocument(value, { _autoHeight: true, _showTitle: Doc.UserDoc().showTitle ? "title" : undefined, _width: 200, title: value }); newDoc[key] = this.getValue(this.props.heading); const docs = this.props.parent.childDocList; return docs ? (docs.splice(0, 0, newDoc) ? true : false) : this.props.parent.props.addDocument(newDoc); diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index ede75fba8..0a206a6c6 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -136,7 +136,7 @@ export class CollectionStackingViewFieldColumn extends React.Component { if (!value) return false; const key = StrCast(this.props.parent.props.Document._pivotField); - const newDoc = Docs.Create.TextDocument(value, { _height: 18, _width: 200, title: value, _autoHeight: true }); + const newDoc = Docs.Create.TextDocument(value, { _height: 18, _showTitle: Doc.UserDoc().showTitle ? "title" : undefined, _width: 200, title: value, _autoHeight: true }); newDoc[key] = this.getValue(this.props.heading); const maxHeading = this.props.docList.reduce((maxHeading, doc) => NumCast(doc.heading) > maxHeading ? NumCast(doc.heading) : maxHeading, 0); const heading = maxHeading === 0 || this.props.docList.length === 0 ? 1 : maxHeading === 1 ? 2 : 3; @@ -269,7 +269,7 @@ export class CollectionStackingViewFieldColumn extends React.Component { Doc.GetProto(this.props.parent.props.Document)[name] = ""; - const created = Docs.Create.TextDocument("", { title: name, _width: 250, _autoHeight: true }); + const created = Docs.Create.TextDocument("", { title: name, _showTitle: Doc.UserDoc().showTitle ? "title" : undefined, _width: 250, _autoHeight: true }); if (created) { if (this.props.parent.Document.isTemplateDoc) { Doc.MakeMetadataFieldTemplate(created, this.props.parent.props.Document); diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 71e891045..cb3f486bb 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -284,7 +284,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: this.addDocument(Docs.Create.WebDocument(href, { ...options, title: href })); } } else if (text) { - this.addDocument(Docs.Create.TextDocument(text, { ...options, _width: 100, _height: 25 })); + this.addDocument(Docs.Create.TextDocument(text, { ...options, _showTitle: Doc.UserDoc().showTitle ? "title" : undefined, _width: 100, _height: 25 })); } return; } @@ -460,7 +460,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: completed?.(); } else { if (text && !text.includes("https://")) { - UndoManager.RunInBatch(() => this.addDocument(Docs.Create.TextDocument(text, { ...options, title: text.substring(0, 20), _width: 400, _height: 315 })), "drop"); + UndoManager.RunInBatch(() => this.addDocument(Docs.Create.TextDocument(text, { ...options, _showTitle: Doc.UserDoc().showTitle ? "title" : undefined, title: text.substring(0, 20), _width: 400, _height: 315 })), "drop"); } } disposer(); diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx index 7de0b14ac..4dafa4ac4 100644 --- a/src/client/views/collections/SchemaTable.tsx +++ b/src/client/views/collections/SchemaTable.tsx @@ -363,7 +363,7 @@ export class SchemaTable extends React.Component { @undoBatch createRow = action(() => { - this.props.addDocument(Docs.Create.TextDocument("", { title: "", _width: 100, _height: 30 })); + this.props.addDocument(Docs.Create.TextDocument("", { title: "", _showTitle: Doc.UserDoc().showTitle ? "title" : undefined, _width: 100, _height: 30 })); this._focusedCell = { row: this.childDocs.length, col: this._focusedCell.col }; }); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 0c0f6ca58..206d04cf7 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1045,7 +1045,7 @@ export class CollectionFreeFormView extends CollectionSubView val === undefined) ? undefined : { - ele:
this.onViewDefDivClick(e, viewDef)} + ele:
this.onViewDefDivClick(e, viewDef)} style={{ width, height, backgroundColor: color, transform }} />, bounds: viewDef }; @@ -1597,18 +1597,15 @@ class CollectionFreeFormViewPannableContents extends React.Component - {!activeItem.editZoomProgressivize ? (null) :
-
-
-
-
-
-
-
} - - ); + return !activeItem.editZoomProgressivize ? (null) : +
+
+
+
+
+
+
+
; } } @@ -1622,30 +1619,30 @@ class CollectionFreeFormViewPannableContents extends React.Component - {!this.props.presPaths ? (null) : <>
{PresBox.Instance.order}
- - - - - - - - - - - - - - - - ; - {PresBox.Instance.paths} - } - ); + return !PresBox.Instance || !this.props.presPaths ? (null) : <> +
{PresBox.Instance.order}
+ + + + + + + + + + + + + + + + + {PresBox.Instance.paths} + + ; } render() { diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 0918e8389..3a9f31bef 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -130,6 +130,7 @@ export class MarqueeView extends React.Component(selected); Doc.GetProto(summary).layout_portal = CollectionView.LayoutString(Doc.LayoutFieldKey(summary) + "-annotations"); diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.scss b/src/client/views/collections/collectionFreeForm/PropertiesView.scss index 278f3b964..e3ced887d 100644 --- a/src/client/views/collections/collectionFreeForm/PropertiesView.scss +++ b/src/client/views/collections/collectionFreeForm/PropertiesView.scss @@ -303,7 +303,6 @@ margin-left: auto; .permissions-select { - z-index: 1; border: none; background-color: inherit; width: 75px; @@ -734,7 +733,7 @@ background: #eeeeee; border-top: 1px solid; border-left: 1px solid; - + &:hover { border: 0.75px solid rgb(122, 28, 28); } diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx index 50597f2eb..e128f6aab 100644 --- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx +++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx @@ -184,7 +184,7 @@ export class PropertiesView extends React.Component { const noviceReqFields = ["author", "creationDate"]; const noviceLayoutFields = ["curPage"]; const noviceKeys = [...Array.from(Object.keys(ids)).filter(key => key[0] === "#" || key.indexOf("lastModified") !== -1 || (key[0] === key[0].toUpperCase() && !key.startsWith("ACL") && key !== "UseCors")), - ...noviceReqFields, ...noviceLayoutFields] + ...noviceReqFields, ...noviceLayoutFields]; for (const key of noviceKeys.sort()) { const contents = this.selectedDoc[key]; if (key[0] === "#") { @@ -200,7 +200,7 @@ export class PropertiesView extends React.Component {
{value}
); } else { - let contentElement = { if (doubleTap) { undoBatch(action(() => { - const text = Docs.Create.TextDocument("", { _width: 150, _height: 50 }); + const text = Docs.Create.TextDocument("", { _showTitle: Doc.UserDoc().showTitle ? "title" : undefined, _width: 150, _height: 50 }); FormattedTextBox.SelectOnLoad = text[Id];// track the new text box so we can give it a prop that tells it to focus itself when it's displayed Doc.AddDocToList(this.props.Document, this.props.fieldKey, text); this.setLayoutList(this.addLayoutItem(this.savedLayoutList, this.makeLayoutItem(text, this.screenToCell(e.clientX, e.clientY)))); diff --git a/src/client/views/linking/LinkMenu.tsx b/src/client/views/linking/LinkMenu.tsx index 8ecde959f..519b78add 100644 --- a/src/client/views/linking/LinkMenu.tsx +++ b/src/client/views/linking/LinkMenu.tsx @@ -93,7 +93,6 @@ export class LinkMenu extends React.Component { } render() { - console.log("computed", this.position.x, this.position.b); const sourceDoc = this.props.docView.props.Document; const groups: Map = LinkManager.Instance.getRelatedGroupedLinks(sourceDoc); return
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 5c8cb5e35..7b9a32dbe 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -109,12 +109,14 @@ export class AudioBox extends ViewBoxAnnotatableComponent this.audioState = this.path ? "paused" : undefined); + this.audioState = this.path ? "paused" : undefined; this._linkPlayDisposer = reaction(() => this.layoutDoc.scrollToLinkID, scrollLinkId => { if (scrollLinkId) { @@ -285,7 +287,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent { const newDoc = Docs.Create.TextDocument("", { - title: "", _chromeStatus: "disabled", + _showTitle: Doc.UserDoc().showTitle ? "title" : undefined, title: "", _chromeStatus: "disabled", x: NumCast(this.props.Document.x), y: NumCast(this.props.Document.y) + NumCast(this.props.Document._height) + 10, _width: NumCast(this.props.Document._width), _height: 2 * NumCast(this.props.Document._height) }); diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss index e6b8928d4..2dd3bba91 100644 --- a/src/client/views/nodes/DocumentView.scss +++ b/src/client/views/nodes/DocumentView.scss @@ -133,6 +133,8 @@ bottom: 0; width: 100%; transform-origin: bottom left; + opacity: 0.1; + transition: opacity 0.5s; } } @@ -144,4 +146,9 @@ display:inline-block; } } + > .documentView-styleWrapper { + > .documentView-captionWrapper { + opacity: 1; + } + } } \ No newline at end of file diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index bf42f30fe..db6d30aac 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -771,7 +771,7 @@ export class DocumentView extends DocComponent(Docu moreItems.push({ description: "Write Back Link to Album", event: () => GooglePhotos.Transactions.AddTextEnrichment(this.props.Document), icon: "caret-square-right" }); } moreItems.push({ description: "Copy ID", event: () => Utils.CopyText(Utils.prepend("/doc/" + this.props.Document[Id])), icon: "fingerprint" }); - 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" }); + Doc.AreProtosEqual(this.props.Document, Cast(Doc.UserDoc()["sidebar-userDoc"], Doc, null)) && moreItems.push({ description: "Toggle Always Show Link End", event: () => Doc.UserDoc()["documentLinksButton-hideEnd"] = !Doc.UserDoc()["documentLinksButton-hideEnd"], icon: "eye" }); } const collectionAcl = GetEffectiveAcl(this.props.ContainingCollectionDoc?.[DataSym]); diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index dd3914df7..5f31f8c8d 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -111,23 +111,17 @@ export class ImageBox extends ViewBoxAnnotatableComponent { + const [{ result }] = await Networking.UploadFilesToServer(e.data); + if (!(result instanceof Error)) { + const audioDoc = Docs.Create.AudioDocument(Utils.prepend(result.accessPaths.agnostic.client), { title: "audio test", _width: 200, _height: 32 }); + audioDoc.treeViewExpandedView = "layout"; + const audioAnnos = Cast(self.dataDoc[self.fieldKey + "-audioAnnotations"], listSpec(Doc)); + if (audioAnnos === undefined) { + self.dataDoc[self.fieldKey + "-audioAnnotations"] = new List([audioDoc]); + } else { + audioAnnos.push(audioDoc); + } } }; runInAction(() => self._audioState = 2); diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index d30ea03b1..ba59c2df7 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -1459,7 +1459,7 @@ export class PresBox extends ViewBoxBaseComponent tags.push(
{this.checkMovementLists(doc, doc["x-indexed"], doc["y-indexed"])}
); } tags.push( -
{ if (NumCast(targetDoc.currentFrame) < NumCast(doc.appearFrame)) doc.opacity = 0; }} onPointerOver={() => { if (NumCast(targetDoc.currentFrame) < NumCast(doc.appearFrame)) doc.opacity = 0.5; }} onClick={e => { this.toggleDisplayMovement(doc); e.stopPropagation(); }} style={{ backgroundColor: doc.displayMovement ? "#aedff8" : "#c8c8c8", top: NumCast(doc.y), left: NumCast(doc.x) }}> +
{ if (NumCast(targetDoc.currentFrame) < NumCast(doc.appearFrame)) doc.opacity = 0; }} onPointerOver={() => { if (NumCast(targetDoc.currentFrame) < NumCast(doc.appearFrame)) doc.opacity = 0.5; }} onClick={e => { this.toggleDisplayMovement(doc); e.stopPropagation(); }} style={{ backgroundColor: doc.displayMovement ? "#aedff8" : "#c8c8c8", top: NumCast(doc.y), left: NumCast(doc.x) }}>
{ e.stopPropagation(); this.prevAppearFrame(doc, index); }} />
{doc.appearFrame}
{ e.stopPropagation(); this.nextAppearFrame(doc, index); }} />
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.scss b/src/client/views/nodes/formattedText/FormattedTextBox.scss index afdd8fea2..160f4ba72 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.scss +++ b/src/client/views/nodes/formattedText/FormattedTextBox.scss @@ -32,8 +32,8 @@ .formattedTextBox-dictation { height: 12px; width: 10px; - top: 0px; - left: 0px; + bottom: 5px; + right: 8px; position: absolute; } } diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 7a6d263f9..b473ad425 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -100,7 +100,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp private _pause: boolean = false; @computed get _recording() { return this.dataDoc.audioState === "recording"; } - set _recording(value) { this.dataDoc.audioState = value ? "recording" : undefined; } + set _recording(value) { + this.dataDoc.audioState = value ? "recording" : undefined; + } @observable private _entered = false; @@ -350,7 +352,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp updateTitle = () => { if ((this.props.Document.isTemplateForField === "text" || !this.props.Document.isTemplateForField) && // only update the title if the data document's data field is changing - StrCast(this.dataDoc.title).startsWith("-") && this._editorView && !this.dataDoc["title-custom"]) { + StrCast(this.dataDoc.title).startsWith("-") && this._editorView && !this.dataDoc["title-custom"] && + Doc.LayoutFieldKey(this.rootDoc) === this.fieldKey) { let node = this._editorView.state.doc; while (node.firstChild && node.firstChild.type.name !== "text") node = node.firstChild; const str = node.textContent; @@ -383,7 +386,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp let tr = this._editorView.state.tr; const flattened: TextSelection[] = []; res.map(r => r.map(h => flattened.push(h))); - console.log("Search:" + this.rootDoc.title + " " + this._searchIndex + " => " + (this._searchIndex + 1 > flattened.length - 1 ? 0 : this._searchIndex + 1)); this._searchIndex = ++this._searchIndex > flattened.length - 1 ? 0 : this._searchIndex; if (backward === true) { if (this._searchIndex > 1) { @@ -658,7 +660,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const newBullets: Doc[] = this.recursiveProgressivize(1, list)[0]; mainBulletList.push.apply(mainBulletList, newBullets); } - console.log(mainBulletList.length); const title = Docs.Create.TextDocument(StrCast(this.rootDoc.title), { title: "Title", _width: 800, _height: 70, x: 20, y: -10, _fontSize: '20pt', backgroundColor: "rgba(0,0,0,0)", appearFrame: 0, _fontWeight: 700 }); mainBulletList.push(title); const doc = Docs.Create.FreeformDocument(mainBulletList, { @@ -713,7 +714,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp recordDictation = () => { DictationManager.Controls.listen({ - interimHandler: this.setCurrentBulletContent, + interimHandler: this.setDictationContent, continuous: { indefinite: false }, }).then(results => { if (results && [DictationManager.Controls.Infringed].includes(results)) { @@ -724,22 +725,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } stopDictation = (abort: boolean) => { DictationManager.Controls.stop(!abort); }; - recordBullet = async () => { - const completedCue = "end session"; - const results = await DictationManager.Controls.listen({ - interimHandler: this.setCurrentBulletContent, - continuous: { indefinite: false }, - terminators: [completedCue, "bullet", "next"] - }); - if (results && [DictationManager.Controls.Infringed, completedCue].includes(results)) { - DictationManager.Controls.stop(); - return; - } - this.nextBullet(this._editorView!.state.selection.to); - setTimeout(this.recordBullet, 2000); - } - - setCurrentBulletContent = (value: string) => { + setDictationContent = (value: string) => { if (this._editorView) { const state = this._editorView.state; const now = Date.now(); @@ -754,33 +740,17 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } } } - const recordingStart = DateCast(this.props.Document.recordingStart).date.getTime(); - this._break = false; - value = "" + (mark.attrs.modified * 1000 - recordingStart) / 1000 + value; const from = state.selection.from; - const inserted = state.tr.insertText(value).addMark(from, from + value.length + 1, mark); - this._editorView.dispatch(inserted.setSelection(TextSelection.create(inserted.doc, from, from + value.length + 1))); - } - } - - nextBullet = (pos: number) => { - if (this._editorView) { - const frag = Fragment.fromArray(this.newListItems(2)); - if (this._editorView.state.doc.resolve(pos).depth >= 2) { - const slice = new Slice(frag, 2, 2); - let state = this._editorView.state; - this._editorView.dispatch(state.tr.step(new ReplaceStep(pos, pos, slice))); - pos += 4; - state = this._editorView.state; - this._editorView.dispatch(state.tr.setSelection(TextSelection.create(this._editorView.state.doc, pos, pos))); + this._break = false; + if (this.props.Document.recordingStart) { + const recordingStart = DateCast(this.props.Document.recordingStart)?.date.getTime(); + value = "" + (mark.attrs.modified * 1000 - recordingStart) / 1000 + value; } + const tr = state.tr.insertText(value).addMark(from, from + value.length + 1, mark); + this._editorView.dispatch(tr.setSelection(TextSelection.create(tr.doc, from, from + value.length + 1))); } } - private newListItems = (count: number) => { - return numberRange(count).map(x => schema.nodes.list_item.create(undefined, schema.nodes.paragraph.create())); - } - _keymap: any = undefined; _rules: RichTextRules | undefined; @computed get config() { @@ -903,21 +873,23 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp this.setupEditor(this.config, this.props.fieldKey); this._disposers.search = reaction(() => Doc.IsSearchMatch(this.rootDoc), - search => { - search ? this.highlightSearchTerms([Doc.SearchQuery()], search.searchMatch < 0) : this.unhighlightSearchTerms(); - }, + search => search ? this.highlightSearchTerms([Doc.SearchQuery()], search.searchMatch < 0) : this.unhighlightSearchTerms(), { fireImmediately: Doc.IsSearchMatchUnmemoized(this.rootDoc) ? true : false }); - this._disposers.record = reaction(() => this._recording, - () => { - if (this._recording) { - setTimeout(action(() => { - this.stopDictation(true); - setTimeout(() => this.recordDictation(), 500); - }), 500); - } else setTimeout(() => this.stopDictation(true), 0); - } - ); + this._disposers.selected = reaction(() => this.props.isSelected(), action(() => this._recording = false)); + + if (!this.props.dontRegisterView) { + this._disposers.record = reaction(() => this._recording, + () => { + if (this._recording) { + setTimeout(action(() => { + this.stopDictation(true); + setTimeout(() => this.recordDictation(), 500); + }), 500); + } else setTimeout(() => this.stopDictation(true), 0); + } + ); + } this._disposers.scrollToRegion = reaction( () => StrCast(this.layoutDoc.scrollToLinkID), async (scrollToLinkID) => { @@ -1410,7 +1382,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const self = this; return new Plugin({ view(newView) { - self.props.isSelected(true) && (RichTextMenu.Instance.view = newView); + self.props.isSelected(true) && RichTextMenu.Instance && (RichTextMenu.Instance.view = newView); return self.menuPlugin = new RichTextMenuPlugin({ editorProps: this.props }); } }); @@ -1432,7 +1404,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp public static HadSelection: boolean = false; onBlur = (e: any) => { FormattedTextBox.HadSelection = window.getSelection()?.toString() !== ""; - //DictationManager.Controls.stop(false); this.endUndoTypingBatch(); this.doLinkOnDeselect(); @@ -1545,13 +1516,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp width: "100%", height: this.props.height ? this.props.height : this.layoutDoc._autoHeight && this.props.renderDepth ? "max-content" : undefined, background: Doc.UserDoc().renderStyle === "comic" ? "transparent" : this.props.background ? this.props.background : StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], this.props.hideOnLeave ? "rgba(0,0,0 ,0.4)" : ""), - opacity: this.props.hideOnLeave ? (this._entered ? 1 : 0.1) : 1, color: this.props.color ? this.props.color : StrCast(this.layoutDoc[this.props.fieldKey + "-color"], this.props.hideOnLeave ? "white" : "inherit"), pointerEvents: interactive ? undefined : "none", fontSize: Cast(this.layoutDoc._fontSize, "string", null), fontWeight: Cast(this.layoutDoc._fontWeight, "number", null), fontFamily: StrCast(this.layoutDoc._fontFamily, "inherit"), - transition: "opacity 1s" }} onContextMenu={this.specificContextMenu} onKeyDown={this.onKeyPress} @@ -1615,14 +1584,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
} {!this.layoutDoc._showAudio ? (null) : -
{ - runInAction(() => this._recording = !this._recording); - setTimeout(() => this._editorView!.focus(), 500); - e.stopPropagation(); - }} > +
this._recording = !this._recording)} > + style={{ + color: this._recording ? "red" : "blue", + transitionDelay: "0.6s", + opacity: this._recording ? 1 : 0.25, + }} + icon={"microphone"} size="sm" />
}
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index e93fc86b5..bed6c83b4 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -442,7 +442,7 @@ export class SearchBox extends ViewBoxBaseComponent this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight panelHeight = () => this.props.PanelHeight(); - selectElement = (doc: Doc) => { /* this.gotoDocument(this.childDocs.indexOf(doc), NumCasst(this.layoutDoc._itemIndex)); */ } + selectElement = (doc: Doc) => { /* this.gotoDocument(this.childDocs.indexOf(doc), NumCasst(this.layoutDoc._itemIndex)); */ }; returnHeight = () => 31 + 31 * 6; returnLength = () => Math.min(window.innerWidth, 51 + 205 * Cast(this.props.Document._schemaHeaders, listSpec(SchemaHeaderField), []).length); -- cgit v1.2.3-70-g09d2 From 7b081d6f4d73811b280c1c4a6b931ef318427610 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 23 Aug 2020 17:40:18 -0400 Subject: fixed start/end link for text selections on start link. fixed display of link target from link text hyperlink --- src/client/util/HypothesisUtils.ts | 1 + src/client/views/GlobalKeyHandler.ts | 1 + src/client/views/collections/CollectionLinearView.tsx | 1 + .../collectionFreeForm/CollectionFreeFormView.tsx | 5 ++++- src/client/views/nodes/DocumentLinksButton.tsx | 16 ++++++++++++++-- .../nodes/formattedText/FormattedTextBoxComment.tsx | 4 ++-- 6 files changed, 23 insertions(+), 5 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/util/HypothesisUtils.ts b/src/client/util/HypothesisUtils.ts index 04e937878..ddd2b89d1 100644 --- a/src/client/util/HypothesisUtils.ts +++ b/src/client/util/HypothesisUtils.ts @@ -60,6 +60,7 @@ export namespace Hypothesis { DocumentLinksButton.AnnotationId = annotationId; DocumentLinksButton.AnnotationUri = annotationUri; DocumentLinksButton.StartLink = sourceDoc; + DocumentLinksButton.StartLinkView = undefined; }); } else { // if a link has already been started, complete the link to sourceDoc runInAction(() => { diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts index be6aa6be2..9e7f525b7 100644 --- a/src/client/views/GlobalKeyHandler.ts +++ b/src/client/views/GlobalKeyHandler.ts @@ -89,6 +89,7 @@ export default class KeyManager { // } // } DocumentLinksButton.StartLink = undefined; + DocumentLinksButton.StartLinkView = undefined; const main = MainView.Instance; Doc.SetSelectedTool(InkTool.None); diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx index 0fd18034f..866d7245a 100644 --- a/src/client/views/collections/CollectionLinearView.tsx +++ b/src/client/views/collections/CollectionLinearView.tsx @@ -89,6 +89,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) { } } DocumentLinksButton.StartLink = undefined; + DocumentLinksButton.StartLinkView = undefined; } @action diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 206d04cf7..1cf06be3e 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -591,7 +591,10 @@ export class CollectionFreeFormView extends CollectionSubView { if (this.layoutDoc.targetScale && (Math.abs(e.pageX - this._downX) < 3 && Math.abs(e.pageY - this._downY) < 3)) { if (Date.now() - this._lastTap < 300) { - runInAction(() => DocumentLinksButton.StartLink = undefined); + runInAction(() => { + DocumentLinksButton.StartLink = undefined; + DocumentLinksButton.StartLinkView = undefined; + }); const docpt = this.getTransform().transformPoint(e.clientX, e.clientY); this.scaleAtPt(docpt, 1); e.stopPropagation(); diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx index 429bc27ad..318f7b7e9 100644 --- a/src/client/views/nodes/DocumentLinksButton.tsx +++ b/src/client/views/nodes/DocumentLinksButton.tsx @@ -36,6 +36,7 @@ export class DocumentLinksButton extends React.Component(); @observable public static StartLink: Doc | undefined; + @observable public static StartLinkView: DocumentView | undefined; @observable public static AnnotationId: string | undefined; @observable public static AnnotationUri: string | undefined; @@ -79,8 +80,10 @@ export class DocumentLinksButton extends React.Component Doc.BrushDoc(this.props.View.Document)); if (DocumentLinksButton.StartLink === this.props.View.props.Document) { DocumentLinksButton.StartLink = undefined; + DocumentLinksButton.StartLinkView = undefined; } else { DocumentLinksButton.StartLink = this.props.View.props.Document; + DocumentLinksButton.StartLinkView = this.props.View; } } else if (!this.props.InMenu) { DocumentLinksButton.EditLink = this.props.View; @@ -95,8 +98,10 @@ export class DocumentLinksButton extends React.Component Doc.BrushDoc(this.props.View.Document)); @@ -110,6 +115,7 @@ export class DocumentLinksButton extends React.Component { if (startLink === endLink) { DocumentLinksButton.StartLink = undefined; + DocumentLinksButton.StartLinkView = undefined; DocumentLinksButton.AnnotationId = undefined; DocumentLinksButton.AnnotationUri = undefined; //!this.props.StartLink @@ -157,8 +164,12 @@ export class DocumentLinksButton extends React.Component startLink._link = endLinkView._link = undefined), 0); + endLinkView._link = linkDoc; + DocumentLinksButton.StartLinkView && (DocumentLinksButton.StartLinkView._link = linkDoc); + setTimeout(action(() => { + DocumentLinksButton.StartLinkView && (DocumentLinksButton.StartLinkView._link = undefined); + endLinkView._link = undefined; + }), 0); } LinkManager.currentLink = linkDoc; @@ -203,6 +214,7 @@ export class DocumentLinksButton extends React.Component Date: Mon, 24 Aug 2020 20:34:13 +0800 Subject: Add with marquee view adds new pres to myPresentations list Small change --- src/client/util/CurrentUserUtils.ts | 4 +--- src/client/views/collections/collectionFreeForm/MarqueeView.tsx | 3 +++ src/client/views/nodes/PresBox.tsx | 6 ++---- 3 files changed, 6 insertions(+), 7 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 821bb917a..3ee0c7003 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -908,9 +908,7 @@ export class CurrentUserUtils { // Import sidebar is where shared documents are contained static setupImportSidebar(doc: Doc) { if (doc["sidebar-import-documents"] === undefined) { - const sidebar = Cast(doc["sidebar-import-documents"], Doc, null); - const height: number = sidebar ? NumCast(sidebar._height) - 150 : 400; - 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", system: true, _height: height })); + doc["sidebar-import-documents"] = new PrefetchProxy(Docs.Create.StackingDocument([], { title: "Imported Documents", forceActive: true, _showTitle: "title", childDropAction: "alias", _yMargin: 30, lockedPosition: true, _chromeStatus: "disabled", system: true, _height: 500 })); } if (doc["sidebar-import"] === undefined) { const uploads = Cast(doc["sidebar-import-documents"], Doc, null); diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 8dbc2bd43..7e02673f4 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -401,6 +401,9 @@ export class MarqueeView extends React.Component case 'none': default: output = 'None'; break; //None } return output; - }) + }); whenActiveChanged = action((isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive)); // For dragging documents into the presentation trail @@ -527,9 +527,7 @@ export class PresBox extends ViewBoxBaseComponent return true; } childLayoutTemplate = () => this.rootDoc._viewType !== CollectionViewType.Stacking ? undefined : this.presElement; - removeDocument = (doc: Doc) => { - Doc.RemoveDocFromList(this.dataDoc, this.fieldKey, doc); - }; + removeDocument = (doc: Doc) => { Doc.RemoveDocFromList(this.dataDoc, this.fieldKey, doc); }; getTransform = () => this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight panelHeight = () => this.props.PanelHeight() - 40; active = (outsideReaction?: boolean) => ((Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc.isBackground) && -- cgit v1.2.3-70-g09d2 From 505ad0d2e2a37795f1877b2319a8ba3a1ce65d28 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 24 Aug 2020 11:21:20 -0400 Subject: cleaned up all library() calls to add icons. fixed import styles. fixed keyboard events for presentation views to trigger when no input box is the target. --- src/client/DocServer.ts | 2 +- src/client/apis/GoogleAuthenticationManager.tsx | 8 +- .../apis/google_docs/GooglePhotosClientUtils.ts | 2 +- src/client/util/CurrentUserUtils.ts | 2 +- src/client/util/GroupManager.tsx | 43 +++---- src/client/util/GroupMemberView.tsx | 22 ++-- .../util/Import & Export/DirectoryImportBox.tsx | 9 +- .../util/Import & Export/ImportMetadataEntry.tsx | 8 +- src/client/util/SettingsManager.tsx | 30 +++-- src/client/util/SharingManager.tsx | 53 ++++---- src/client/views/AntimodeMenu.tsx | 2 +- src/client/views/ContextMenu.tsx | 5 - src/client/views/ContextMenuItem.tsx | 7 +- src/client/views/DictationOverlay.tsx | 2 +- src/client/views/DocumentButtonBar.tsx | 32 ++--- src/client/views/DocumentDecorations.tsx | 43 ++----- src/client/views/EditableView.tsx | 10 +- src/client/views/GestureOverlay.tsx | 2 +- src/client/views/GlobalKeyHandler.ts | 14 +-- src/client/views/InkingStroke.tsx | 17 +-- src/client/views/MainView.tsx | 49 ++++---- src/client/views/MainViewModal.tsx | 2 +- src/client/views/PropertiesButtons.tsx | 45 +++---- src/client/views/ScriptingRepl.tsx | 17 +-- .../views/collections/CollectionDockingView.tsx | 2 +- src/client/views/collections/CollectionMenu.tsx | 8 +- .../views/collections/CollectionSchemaCells.tsx | 58 ++++----- .../CollectionSchemaMovableTableHOC.tsx | 6 +- .../views/collections/CollectionSchemaView.tsx | 15 +-- .../CollectionStackingViewFieldColumn.tsx | 14 +-- src/client/views/collections/CollectionView.tsx | 7 +- .../views/collections/ParentDocumentSelector.tsx | 24 ++-- .../collectionFreeForm/CollectionFreeFormView.tsx | 22 ++-- .../collectionFreeForm/FormatShapePane.tsx | 4 +- .../collectionFreeForm/MarqueeOptionsMenu.tsx | 9 +- .../collections/collectionFreeForm/MarqueeView.tsx | 11 +- .../collectionFreeForm/PropertiesView.tsx | 52 ++++---- src/client/views/linking/LinkEditor.tsx | 5 - src/client/views/linking/LinkMenu.tsx | 16 +-- src/client/views/linking/LinkMenuItem.tsx | 26 ++-- src/client/views/nodes/DocumentView.tsx | 2 +- src/client/views/nodes/FaceRectangles.tsx | 2 +- src/client/views/nodes/ImageBox.tsx | 15 +-- src/client/views/nodes/PresBox.tsx | 33 +++-- src/client/views/nodes/RadialMenuItem.tsx | 8 +- src/client/views/nodes/ScreenshotBox.tsx | 6 +- src/client/views/nodes/SliderBox.tsx | 5 - src/client/views/nodes/WebBox.tsx | 4 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 13 +- .../formattedText/ProsemirrorExampleTransfer.ts | 2 +- .../views/nodes/formattedText/RichTextMenu.tsx | 19 ++- .../views/nodes/formattedText/RichTextRules.ts | 2 +- src/client/views/pdf/Annotation.tsx | 4 +- src/client/views/pdf/PDFMenu.tsx | 14 +-- src/client/views/pdf/PDFViewer.tsx | 18 +-- src/client/views/search/IconBar.tsx | 25 +--- src/client/views/search/IconButton.tsx | 140 ++++++--------------- src/client/views/webcam/DashWebRTCVideo.tsx | 24 ++-- src/mobile/AudioUpload.tsx | 4 +- src/mobile/ImageUpload.tsx | 20 +-- src/mobile/MobileInterface.tsx | 43 +++---- 61 files changed, 423 insertions(+), 685 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts index dde75497c..9da5b8632 100644 --- a/src/client/DocServer.ts +++ b/src/client/DocServer.ts @@ -5,7 +5,7 @@ import { Utils, emptyFunction } from '../Utils'; import { SerializationHelper } from './util/SerializationHelper'; import { RefField } from '../fields/RefField'; import { Id, HandleUpdate, Parent } from '../fields/FieldSymbols'; -import GestureOverlay from './views/GestureOverlay'; +import { GestureOverlay } from './views/GestureOverlay'; import MobileInkOverlay from '../mobile/MobileInkOverlay'; import { runInAction } from 'mobx'; import { ObjectField } from '../fields/ObjectField'; diff --git a/src/client/apis/GoogleAuthenticationManager.tsx b/src/client/apis/GoogleAuthenticationManager.tsx index 117d1fa1e..cda108058 100644 --- a/src/client/apis/GoogleAuthenticationManager.tsx +++ b/src/client/apis/GoogleAuthenticationManager.tsx @@ -1,17 +1,17 @@ -import { observable, action, reaction, runInAction, IReactionDisposer } from "mobx"; +import { action, IReactionDisposer, observable, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; import * as React from "react"; -import MainViewModal from "../views/MainViewModal"; import { Opt } from "../../fields/Doc"; import { Networking } from "../Network"; -import "./GoogleAuthenticationManager.scss"; import { Scripting } from "../util/Scripting"; +import { MainViewModal } from "../views/MainViewModal"; +import "./GoogleAuthenticationManager.scss"; const AuthenticationUrl = "https://accounts.google.com/o/oauth2/v2/auth"; const prompt = "Paste authorization code here..."; @observer -export default class GoogleAuthenticationManager extends React.Component<{}> { +export class GoogleAuthenticationManager extends React.Component<{}> { public static Instance: GoogleAuthenticationManager; private authenticationLink: Opt = undefined; @observable private openState = false; diff --git a/src/client/apis/google_docs/GooglePhotosClientUtils.ts b/src/client/apis/google_docs/GooglePhotosClientUtils.ts index 92eaf2e73..899e65a16 100644 --- a/src/client/apis/google_docs/GooglePhotosClientUtils.ts +++ b/src/client/apis/google_docs/GooglePhotosClientUtils.ts @@ -11,7 +11,7 @@ import { Utils } from "../../../Utils"; import { Docs, DocumentOptions, DocUtils } from "../../documents/Documents"; import { Networking } from "../../Network"; import { FormattedTextBox } from "../../views/nodes/formattedText/FormattedTextBox"; -import GoogleAuthenticationManager from "../GoogleAuthenticationManager"; +import { GoogleAuthenticationManager } from "../GoogleAuthenticationManager"; import Photos = require('googlephotos'); export namespace GooglePhotos { diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 3ee0c7003..be584c3cf 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -908,7 +908,7 @@ export class CurrentUserUtils { // Import sidebar is where shared documents are contained static setupImportSidebar(doc: Doc) { if (doc["sidebar-import-documents"] === undefined) { - doc["sidebar-import-documents"] = new PrefetchProxy(Docs.Create.StackingDocument([], { title: "Imported Documents", forceActive: true, _showTitle: "title", childDropAction: "alias", _yMargin: 30, lockedPosition: true, _chromeStatus: "disabled", system: true, _height: 500 })); + 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", system: true })); } if (doc["sidebar-import"] === undefined) { const uploads = Cast(doc["sidebar-import-documents"], Doc, null); diff --git a/src/client/util/GroupManager.tsx b/src/client/util/GroupManager.tsx index d03989675..612ca7be7 100644 --- a/src/client/util/GroupManager.tsx +++ b/src/client/util/GroupManager.tsx @@ -1,24 +1,19 @@ -import * as React from "react"; -import { observable, action, runInAction, computed } from "mobx"; -import { SelectionManager } from "./SelectionManager"; -import MainViewModal from "../views/MainViewModal"; -import { observer } from "mobx-react"; -import { Doc, DocListCast, Opt, DocListCastAsync } from "../../fields/Doc"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import * as fa from '@fortawesome/free-solid-svg-icons'; -import { library } from "@fortawesome/fontawesome-svg-core"; -import SharingManager, { User } from "./SharingManager"; -import { Utils } from "../../Utils"; -import * as RequestPromise from "request-promise"; +import { action, computed, observable, runInAction } from "mobx"; +import { observer } from "mobx-react"; +import * as React from "react"; import Select from 'react-select'; -import "./GroupManager.scss"; -import { StrCast, Cast } from "../../fields/Types"; -import GroupMemberView from "./GroupMemberView"; +import * as RequestPromise from "request-promise"; +import { Doc, DocListCast, DocListCastAsync, Opt } from "../../fields/Doc"; +import { Cast, StrCast } from "../../fields/Types"; import { setGroups } from "../../fields/util"; +import { Utils } from "../../Utils"; import { DocServer } from "../DocServer"; +import { MainViewModal } from "../views/MainViewModal"; import { TaskCompletionBox } from "../views/nodes/TaskCompletedBox"; - -library.add(fa.faPlus, fa.faTimes, fa.faInfoCircle, fa.faCaretUp, fa.faCaretRight, fa.faCaretDown); +import "./GroupManager.scss"; +import { GroupMemberView } from "./GroupMemberView"; +import { SharingManager, User } from "./SharingManager"; /** * Interface for options for the react-select component @@ -29,7 +24,7 @@ export interface UserOptions { } @observer -export default class GroupManager extends React.Component<{}> { +export class GroupManager extends React.Component<{}> { static Instance: GroupManager; @observable isOpen: boolean = false; // whether the GroupManager is to be displayed or not. @@ -314,7 +309,7 @@ export default class GroupManager extends React.Component<{}> {
{ this.createGroupModalOpen = false; TaskCompletionBox.taskCompleted = false; })}> - +
{

Manage Groups

- +
this.groupSort = this.groupSort === "ascending" ? "descending" : this.groupSort === "descending" ? "none" : "ascending")}> - Name {this.groupSort === "ascending" ? - : this.groupSort === "descending" ? - : + Name {this.groupSort === "ascending" ? + : this.groupSort === "descending" ? + : }
@@ -421,7 +416,7 @@ export default class GroupManager extends React.Component<{}> { >
{group.groupName}
this.currentGroup = group)}> - +
)} diff --git a/src/client/util/GroupMemberView.tsx b/src/client/util/GroupMemberView.tsx index 531ef988a..4ead01e9f 100644 --- a/src/client/util/GroupMemberView.tsx +++ b/src/client/util/GroupMemberView.tsx @@ -1,25 +1,21 @@ -import * as React from "react"; -import MainViewModal from "../views/MainViewModal"; -import { observer } from "mobx-react"; -import GroupManager, { UserOptions } from "./GroupManager"; -import { library } from "@fortawesome/fontawesome-svg-core"; -import { StrCast } from "../../fields/Types"; -import { action, observable } from "mobx"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import * as fa from '@fortawesome/free-solid-svg-icons'; +import { action, observable } from "mobx"; +import { observer } from "mobx-react"; +import * as React from "react"; import Select from "react-select"; import { Doc } from "../../fields/Doc"; +import { StrCast } from "../../fields/Types"; +import { MainViewModal } from "../views/MainViewModal"; +import { GroupManager, UserOptions } from "./GroupManager"; import "./GroupMemberView.scss"; -library.add(fa.faTimes, fa.faTrashAlt); - interface GroupMemberViewProps { group: Doc; onCloseButtonClick: () => void; } @observer -export default class GroupMemberView extends React.Component { +export class GroupMemberView extends React.Component { @observable private memberSort: "ascending" | "descending" | "none" = "none"; @@ -43,7 +39,7 @@ export default class GroupMemberView extends React.Component
- +
{GroupManager.Instance.hasEditAccess(this.props.group) ?
@@ -88,7 +84,7 @@ export default class GroupMemberView extends React.Component {hasEditAccess ?
GroupManager.Instance.removeMemberFromGroup(this.props.group, member)}> - +
: null}
diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx index 77f13e9f4..d04270afa 100644 --- a/src/client/util/Import & Export/DirectoryImportBox.tsx +++ b/src/client/util/Import & Export/DirectoryImportBox.tsx @@ -1,5 +1,3 @@ -import { library } from '@fortawesome/fontawesome-svg-core'; -import { faCloudUploadAlt, faPlus, faTag } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { BatchedArray } from "array-batcher"; import "fs"; @@ -47,7 +45,6 @@ export class DirectoryImportBox extends React.Component { constructor(props: FieldViewProps) { super(props); - library.add(faTag, faPlus); const doc = this.props.Document; this.editingMetadata = this.editingMetadata || false; this.persistent = this.persistent || false; @@ -301,7 +298,7 @@ export class DirectoryImportBox extends React.Component { opacity: uploading ? 0 : 1, transition: "0.4s opacity ease" }}> - +
{ opacity: uploading ? 0 : 1, transition: "0.4s opacity ease" }} - icon={isEditing ? faCloudUploadAlt : faTag} + icon={isEditing ? "cloud-upload-alt" : "tag"} color="#FFFFFF" size={"1x"} /> @@ -399,7 +396,7 @@ export class DirectoryImportBox extends React.Component { marginLeft: 6.4, marginTop: 5.2 }} - icon={faPlus} + icon={"plus"} size={"1x"} />
diff --git a/src/client/util/Import & Export/ImportMetadataEntry.tsx b/src/client/util/Import & Export/ImportMetadataEntry.tsx index dcb94e2e0..1870213b9 100644 --- a/src/client/util/Import & Export/ImportMetadataEntry.tsx +++ b/src/client/util/Import & Export/ImportMetadataEntry.tsx @@ -4,7 +4,6 @@ import { EditableView } from "../../views/EditableView"; import { action, computed } from "mobx"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faPlus } from "@fortawesome/free-solid-svg-icons"; -import { library } from '@fortawesome/fontawesome-svg-core'; import { Doc } from "../../../fields/Doc"; import { StrCast, BoolCast } from "../../../fields/Types"; @@ -24,11 +23,6 @@ export default class ImportMetadataEntry extends React.Component private valueRef = React.createRef(); private checkRef = React.createRef(); - constructor(props: KeyValueProps) { - super(props); - library.add(faPlus); - } - @computed public get valid() { return (this.key.length > 0 && this.key !== keyPlaceholder) && (this.value.length > 0 && this.value !== valuePlaceholder); @@ -132,7 +126,7 @@ export default class ImportMetadataEntry extends React.Component
this.props.remove(this)} title={"Delete Entry"}> { +export class SettingsManager extends React.Component<{}> { public static Instance: SettingsManager; static _settingsStyle = addStyleSheet(); @observable private isOpen = false; @@ -166,7 +164,7 @@ export default class SettingsManager extends React.Component<{}> { {CurrentUserUtils.GuestDashboard ? "Exit" : "Log Out"}
- +
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index b9918e900..a73cb63d0 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -1,29 +1,24 @@ -import { observable, runInAction, action } from "mobx"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { action, observable, runInAction } from "mobx"; +import { observer } from "mobx-react"; import * as React from "react"; -import MainViewModal from "../views/MainViewModal"; -import { Doc, Opt, AclAdmin, AclPrivate, DocListCast, DataSym } from "../../fields/Doc"; -import { DocServer } from "../DocServer"; -import { Cast, StrCast } from "../../fields/Types"; +import Select from "react-select"; import * as RequestPromise from "request-promise"; +import { AclAdmin, AclPrivate, DataSym, Doc, DocListCast, Opt } from "../../fields/Doc"; +import { List } from "../../fields/List"; +import { Cast, StrCast } from "../../fields/Types"; +import { distributeAcls, GetEffectiveAcl, SharingPermissions } from "../../fields/util"; import { Utils } from "../../Utils"; -import "./SharingManager.scss"; -import { observer } from "mobx-react"; -import * as fa from '@fortawesome/free-solid-svg-icons'; -import { DocumentView } from "../views/nodes/DocumentView"; -import { SelectionManager } from "./SelectionManager"; -import { DocumentManager } from "./DocumentManager"; +import { DocServer } from "../DocServer"; import { CollectionView } from "../views/collections/CollectionView"; import { DictationOverlay } from "../views/DictationOverlay"; -import GroupManager, { UserOptions } from "./GroupManager"; -import GroupMemberView from "./GroupMemberView"; -import Select from "react-select"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { List } from "../../fields/List"; -import { distributeAcls, SharingPermissions, GetEffectiveAcl } from "../../fields/util"; +import { MainViewModal } from "../views/MainViewModal"; +import { DocumentView } from "../views/nodes/DocumentView"; import { TaskCompletionBox } from "../views/nodes/TaskCompletedBox"; -import { library } from "@fortawesome/fontawesome-svg-core"; - -library.add(fa.faInfoCircle, fa.faCaretUp, fa.faCaretRight, fa.faCaretDown); +import { DocumentManager } from "./DocumentManager"; +import { GroupManager, UserOptions } from "./GroupManager"; +import { GroupMemberView } from "./GroupMemberView"; +import "./SharingManager.scss"; export interface User { email: string; @@ -58,7 +53,7 @@ interface ValidatedUser { @observer -export default class SharingManager extends React.Component<{}> { +export class SharingManager extends React.Component<{}> { public static Instance: SharingManager; @observable private isOpen = false; // whether the SharingManager modal is open or not @observable private users: ValidatedUser[] = []; // the list of users with notificationDocs @@ -486,7 +481,7 @@ export default class SharingManager extends React.Component<{}> { >
{group.groupName}
GroupManager.Instance.currentGroup = group)}> - +
setter(e.target.value)} /> + onChange={e => { + setter(e.target.value); + }} + onKeyPress={e => { + e.stopPropagation(); + }} />
this.upDownButtons("up", key)))} > diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx index ed64bde32..11a905fb6 100644 --- a/src/client/views/linking/LinkEditor.tsx +++ b/src/client/views/linking/LinkEditor.tsx @@ -1,5 +1,3 @@ -import { library } from "@fortawesome/fontawesome-svg-core"; -import { faArrowLeft, faCog, faEllipsisV, faExchangeAlt, faPlus, faTable, faTimes, faTrash } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Tooltip } from "@material-ui/core"; import { action, computed, observable } from "mobx"; @@ -12,9 +10,6 @@ import { undoBatch } from "../../util/UndoManager"; import './LinkEditor.scss'; import React = require("react"); -library.add(faArrowLeft, faEllipsisV, faTable, faTrash, faCog, faExchangeAlt, faTimes, faPlus); - - interface GroupTypesDropdownProps { groupType: string; setGroupType: (group: string) => void; diff --git a/src/client/views/linking/LinkMenu.tsx b/src/client/views/linking/LinkMenu.tsx index 519b78add..31d08edae 100644 --- a/src/client/views/linking/LinkMenu.tsx +++ b/src/client/views/linking/LinkMenu.tsx @@ -1,18 +1,14 @@ -import { action, observable, computed } from "mobx"; +import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; -import { DocumentView } from "../nodes/DocumentView"; -import { LinkEditor } from "./LinkEditor"; -import './LinkMenu.scss'; -import React = require("react"); import { Doc } from "../../../fields/Doc"; import { LinkManager } from "../../util/LinkManager"; -import { LinkMenuGroup } from "./LinkMenuGroup"; -import { faTrash } from '@fortawesome/free-solid-svg-icons'; -import { library } from "@fortawesome/fontawesome-svg-core"; import { DocumentLinksButton } from "../nodes/DocumentLinksButton"; +import { DocumentView } from "../nodes/DocumentView"; import { LinkDocPreview } from "../nodes/LinkDocPreview"; - -library.add(faTrash); +import { LinkEditor } from "./LinkEditor"; +import './LinkMenu.scss'; +import { LinkMenuGroup } from "./LinkMenuGroup"; +import React = require("react"); interface Props { docView: DocumentView; diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx index 21c666a4d..a77122456 100644 --- a/src/client/views/linking/LinkMenuItem.tsx +++ b/src/client/views/linking/LinkMenuItem.tsx @@ -1,27 +1,23 @@ -import { library } from '@fortawesome/fontawesome-svg-core'; -import { faArrowRight, faChevronDown, faChevronUp, faEdit, faEye, faTimes, faPencilAlt, faEyeSlash } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon, FontAwesomeIconProps } from '@fortawesome/react-fontawesome'; +import { Tooltip } from '@material-ui/core'; import { action, observable, runInAction } from 'mobx'; import { observer } from "mobx-react"; -import { Doc, DocListCast, Opt } from '../../../fields/Doc'; +import { Doc, DocListCast } from '../../../fields/Doc'; import { Cast, StrCast } from '../../../fields/Types'; +import { WebField } from '../../../fields/URLField'; +import { emptyFunction, setupMoveUpEvents } from '../../../Utils'; +import { DocumentType } from '../../documents/DocumentTypes'; +import { DocumentManager } from '../../util/DocumentManager'; import { DragManager } from '../../util/DragManager'; +import { Hypothesis } from '../../util/HypothesisUtils'; import { LinkManager } from '../../util/LinkManager'; +import { undoBatch } from '../../util/UndoManager'; import { ContextMenu } from '../ContextMenu'; -import './LinkMenuItem.scss'; -import React = require("react"); -import { DocumentManager } from '../../util/DocumentManager'; -import { setupMoveUpEvents, emptyFunction, Utils, simulateMouseClick } from '../../../Utils'; -import { DocumentView } from '../nodes/DocumentView'; import { DocumentLinksButton } from '../nodes/DocumentLinksButton'; +import { DocumentView } from '../nodes/DocumentView'; import { LinkDocPreview } from '../nodes/LinkDocPreview'; -import { Hypothesis } from '../../util/HypothesisUtils'; -import { Id } from '../../../fields/FieldSymbols'; -import { Tooltip } from '@material-ui/core'; -import { DocumentType } from '../../documents/DocumentTypes'; -import { undoBatch } from '../../util/UndoManager'; -import { WebField } from '../../../fields/URLField'; -library.add(faEye, faEdit, faTimes, faArrowRight, faChevronDown, faChevronUp, faPencilAlt, faEyeSlash); +import './LinkMenuItem.scss'; +import React = require("react"); interface LinkMenuItemProps { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index db6d30aac..80d83c3cb 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -21,7 +21,7 @@ import { InteractionUtils } from '../../util/InteractionUtils'; import { LinkManager } from '../../util/LinkManager'; import { Scripting } from '../../util/Scripting'; import { SelectionManager } from "../../util/SelectionManager"; -import SharingManager from '../../util/SharingManager'; +import { SharingManager } from '../../util/SharingManager'; import { SnappingManager } from '../../util/SnappingManager'; import { Transform } from "../../util/Transform"; import { undoBatch, UndoManager } from "../../util/UndoManager"; diff --git a/src/client/views/nodes/FaceRectangles.tsx b/src/client/views/nodes/FaceRectangles.tsx index 92ca276cb..0d1e063af 100644 --- a/src/client/views/nodes/FaceRectangles.tsx +++ b/src/client/views/nodes/FaceRectangles.tsx @@ -17,7 +17,7 @@ export interface RectangleTemplate { } @observer -export default class FaceRectangles extends React.Component { +export class FaceRectangles extends React.Component { render() { const faces = DocListCast(this.props.document.faces); diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 5f31f8c8d..410033197 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -1,6 +1,3 @@ -import { library } from '@fortawesome/fontawesome-svg-core'; -import { faEye } from '@fortawesome/free-regular-svg-icons'; -import { faAsterisk, faBrain, faFileAudio, faImage, faPaintBrush } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, observable, runInAction } from 'mobx'; import { observer } from "mobx-react"; @@ -14,7 +11,8 @@ import { ComputedField } from '../../../fields/ScriptField'; import { Cast, NumCast, StrCast } from '../../../fields/Types'; import { AudioField, ImageField } from '../../../fields/URLField'; import { TraceMobx } from '../../../fields/util'; -import { emptyFunction, returnOne, Utils, returnZero } from '../../../Utils'; +import { emptyFunction, returnOne, returnZero, Utils } from '../../../Utils'; +import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils'; import { CognitiveServices, Confidence, Service, Tag } from '../../cognitive_services/CognitiveServices'; import { Docs } from '../../documents/Documents'; import { Networking } from '../../Network'; @@ -24,20 +22,15 @@ import { ContextMenu } from "../../views/ContextMenu"; import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView'; import { ContextMenuProps } from '../ContextMenuItem'; import { ViewBoxAnnotatableComponent } from '../DocComponent'; -import FaceRectangles from './FaceRectangles'; +import { FaceRectangles } from './FaceRectangles'; import { FieldView, FieldViewProps } from './FieldView'; import "./ImageBox.scss"; import React = require("react"); -import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils'; const requestImageSize = require('../../util/request-image-size'); const path = require('path'); const { Howl } = require('howler'); -library.add(faImage, faEye as any, faPaintBrush, faBrain); -library.add(faFileAudio, faAsterisk); - - export const pageSchema = createSchema({ curPage: "number", fitWidth: "boolean", @@ -431,7 +424,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent + icon={!DocListCast(this.dataDoc[this.fieldKey + "-audioAnnotations"]).length ? "microphone" : "file-audio"} size="sm" />
} {this.considerDownloadIcon} {this.considerGooglePhotosLink()} diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 050ecfc49..1228a285e 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -87,14 +87,12 @@ export class PresBox extends ViewBoxBaseComponent } else { return undefined; } } @computed get isPres(): boolean { + document.removeEventListener("keydown", this.keyEvents, true); if (this.selectedDoc?.type === DocumentType.PRES) { - document.removeEventListener("keydown", this.keyEvents, true); document.addEventListener("keydown", this.keyEvents, true); return true; - } else { - document.removeEventListener("keydown", this.keyEvents, true); - return false; } + return false; } @computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; } @@ -373,7 +371,7 @@ export class PresBox extends ViewBoxBaseComponent if (this.layoutDoc.presStatus === 'auto' && !this.layoutDoc.presLoop) this.layoutDoc.presStatus = "manual"; else if (this.layoutDoc.presLoop) this.startAutoPres(0); }, duration); - }; + } } }; this.layoutDoc.presStatus = "auto"; @@ -614,6 +612,7 @@ export class PresBox extends ViewBoxBaseComponent // Key for when the presentaiton is active @action keyEvents = (e: KeyboardEvent) => { + if (e.target instanceof HTMLInputElement) return; let handled = false; const anchorNode = document.activeElement as HTMLDivElement; if (anchorNode && anchorNode.className?.includes("lm_title")) return; @@ -629,10 +628,12 @@ export class PresBox extends ViewBoxBaseComponent handled = true; } } if (e.keyCode === 37 || e.keyCode === 38) { // left(37) / a(65) / up(38) to go back - this.back(); if (this._presTimer) clearTimeout(this._presTimer); + 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(); if (this._presTimer) clearTimeout(this._presTimer); + 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); @@ -640,9 +641,7 @@ export class PresBox extends ViewBoxBaseComponent handled = true; } if (e.keyCode === 8) { // delete selected items if (this.layoutDoc.presStatus === "edit") { - this._selectedArray.forEach((doc, i) => { - this.removeDocument(doc); - }); + this._selectedArray.forEach((doc, i) => this.removeDocument(doc)); this._selectedArray = []; this._eleArray = []; this._dragArray = []; @@ -815,7 +814,7 @@ export class PresBox extends ViewBoxBaseComponent
{ document.removeEventListener("keydown", this.keyEvents, true); }} + onFocus={() => document.removeEventListener("keydown", this.keyEvents, true)} onChange={action((e) => this.setTransitionTime(e.target.value))} /> s
@@ -845,7 +844,7 @@ export class PresBox extends ViewBoxBaseComponent
{ document.removeEventListener("keydown", this.keyEvents, true); }} + onFocus={() => document.removeEventListener("keydown", this.keyEvents, true)} onChange={action((e) => this.setDurationTime(e.target.value))} /> s
@@ -974,7 +973,7 @@ export class PresBox extends ViewBoxBaseComponent { document.removeEventListener("keydown", this.keyEvents, true); }} + onFocus={() => document.removeEventListener("keydown", this.keyEvents, true)} onChange={action((e: React.ChangeEvent) => { const val = e.target.value; activeItem.presPinViewX = Number(val); })} />
@@ -984,7 +983,7 @@ export class PresBox extends ViewBoxBaseComponent { document.removeEventListener("keydown", this.keyEvents, true); }} + onFocus={() => document.removeEventListener("keydown", this.keyEvents, true)} onChange={action((e: React.ChangeEvent) => { const val = e.target.value; activeItem.presPinViewY = Number(val); })} />
@@ -994,7 +993,7 @@ export class PresBox extends ViewBoxBaseComponent { document.removeEventListener("keydown", this.keyEvents, true); }} + onFocus={() => document.removeEventListener("keydown", this.keyEvents, true)} onChange={action((e: React.ChangeEvent) => { const val = e.target.value; activeItem.presPinViewScale = Number(val); })} />
@@ -1044,9 +1043,7 @@ export class PresBox extends ViewBoxBaseComponent
Slide Title:

{ - document.removeEventListener("keydown", this.keyEvents, true); - }} + onFocus={() => document.removeEventListener("keydown", this.keyEvents, true)} onChange={(e) => { e.stopPropagation(); e.preventDefault(); diff --git a/src/client/views/nodes/RadialMenuItem.tsx b/src/client/views/nodes/RadialMenuItem.tsx index bd5b3bff4..8876b4879 100644 --- a/src/client/views/nodes/RadialMenuItem.tsx +++ b/src/client/views/nodes/RadialMenuItem.tsx @@ -1,13 +1,9 @@ import React = require("react"); -import { observable, action } from "mobx"; -import { observer } from "mobx-react"; -import { IconProp, library } from '@fortawesome/fontawesome-svg-core'; -import { faAngleRight } from '@fortawesome/free-solid-svg-icons'; +import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { observer } from "mobx-react"; import { UndoManager } from "../../util/UndoManager"; -library.add(faAngleRight); - export interface RadialMenuProps { description: string; event: (stuff?: any) => void; diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx index 1cd29d795..866e41ee0 100644 --- a/src/client/views/nodes/ScreenshotBox.tsx +++ b/src/client/views/nodes/ScreenshotBox.tsx @@ -1,12 +1,11 @@ import React = require("react"); -import { library } from "@fortawesome/fontawesome-svg-core"; -import { faVideo } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { action, computed, IReactionDisposer, observable, runInAction } from "mobx"; import { observer } from "mobx-react"; import * as rp from 'request-promise'; import { Doc } from "../../../fields/Doc"; import { documentSchema } from "../../../fields/documentSchemas"; +import { InkTool } from "../../../fields/InkField"; import { listSpec, makeInterface } from "../../../fields/Schema"; import { Cast, NumCast } from "../../../fields/Types"; import { VideoField } from "../../../fields/URLField"; @@ -18,14 +17,11 @@ import { ContextMenuProps } from "../ContextMenuItem"; import { ViewBoxBaseComponent } from "../DocComponent"; import { FieldView, FieldViewProps } from './FieldView'; import "./ScreenshotBox.scss"; -import { InkTool } from "../../../fields/InkField"; const path = require('path'); type ScreenshotDocument = makeInterface<[typeof documentSchema]>; const ScreenshotDocument = makeInterface(documentSchema); -library.add(faVideo); - @observer export class ScreenshotBox extends ViewBoxBaseComponent(ScreenshotDocument) { private _reactionDisposer?: IReactionDisposer; diff --git a/src/client/views/nodes/SliderBox.tsx b/src/client/views/nodes/SliderBox.tsx index 45cdfc5ad..d13680046 100644 --- a/src/client/views/nodes/SliderBox.tsx +++ b/src/client/views/nodes/SliderBox.tsx @@ -1,5 +1,3 @@ -import { library } from '@fortawesome/fontawesome-svg-core'; -import { faEdit } from '@fortawesome/free-regular-svg-icons'; import { runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; @@ -16,9 +14,6 @@ import { FieldView, FieldViewProps } from './FieldView'; import { Handle, Tick, TooltipRail, Track } from './SliderBox-components'; import './SliderBox.scss'; - -library.add(faEdit as any); - const SliderSchema = createSchema({ _sliderMin: "number", _sliderMax: "number", diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 7d7426e31..f0e3a2b54 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -24,8 +24,8 @@ import { ContextMenu } from "../ContextMenu"; import { ContextMenuProps } from "../ContextMenuItem"; import { ViewBoxAnnotatableComponent } from "../DocComponent"; import { DocumentDecorations } from "../DocumentDecorations"; -import Annotation from "../pdf/Annotation"; -import PDFMenu from "../pdf/PDFMenu"; +import { Annotation } from "../pdf/Annotation"; +import { PDFMenu } from "../pdf/PDFMenu"; import { PdfViewerMarquee } from "../pdf/PDFViewer"; import { FieldView, FieldViewProps } from './FieldView'; import "./WebBox.scss"; diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 77483a179..063cdb0cc 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1,5 +1,3 @@ -import { library } from '@fortawesome/fontawesome-svg-core'; -import { faEdit, faSmile, faTextHeight, faUpload } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { isEqual } from "lodash"; import { action, computed, IReactionDisposer, Lambda, observable, reaction, runInAction, trace } from "mobx"; @@ -22,7 +20,7 @@ import { InkTool } from '../../../../fields/InkField'; import { PrefetchProxy } from '../../../../fields/Proxy'; import { RichTextField } from "../../../../fields/RichTextField"; import { RichTextUtils } from '../../../../fields/RichTextUtils'; -import { createSchema, makeInterface } from "../../../../fields/Schema"; +import { makeInterface } from "../../../../fields/Schema"; import { Cast, DateCast, NumCast, StrCast, ScriptCast, BoolCast } from "../../../../fields/Types"; import { TraceMobx, OVERRIDE_ACL, GetEffectiveAcl } from '../../../../fields/util'; import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, numberRange, returnOne, returnZero, Utils, setupMoveUpEvents } from '../../../../Utils'; @@ -33,8 +31,8 @@ import { DocumentType } from '../../../documents/DocumentTypes'; import { DictationManager } from '../../../util/DictationManager'; import { DragManager } from "../../../util/DragManager"; import { makeTemplate } from '../../../util/DropConverter'; -import buildKeymap, { updateBullets } from "./ProsemirrorExampleTransfer"; -import RichTextMenu, { RichTextMenuPlugin } from './RichTextMenu'; +import { buildKeymap, updateBullets } from "./ProsemirrorExampleTransfer"; +import { RichTextMenu, RichTextMenuPlugin } from './RichTextMenu'; import { RichTextRules } from "./RichTextRules"; //import { DashDocView } from "./DashDocView"; @@ -61,9 +59,6 @@ import { FormattedTextBoxComment, formattedTextBoxCommentPlugin, findLinkMark } import React = require("react"); import { DocumentManager } from '../../../util/DocumentManager'; -library.add(faEdit); -library.add(faSmile, faTextHeight, faUpload); - export interface FormattedTextBoxProps { makeLink?: () => Opt; // bcz: hack: notifies the text document when the container has made a link. allows the text doc to react and setup a hyeprlink for any selected text hideOnLeave?: boolean; // used by DocumentView for setting caption's hide on leave (bcz: would prefer to have caption-hideOnLeave field set or something similar) @@ -915,7 +910,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp return linkIndex !== -1 && marks[linkIndex].attrs.allLinks.find((item: { href: string }) => scrollToLinkID === item.href.replace(/.*\/doc\//, "")) ? node : undefined; }; - let start = 0; + const start = 0; if (this._editorView && scrollToLinkID) { const editor = this._editorView; const ret = findLinkFrag(editor.state.doc.content, editor); diff --git a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts index 8faf752b4..0eb675b4e 100644 --- a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts +++ b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts @@ -33,7 +33,7 @@ export let updateBullets = (tx2: Transaction, schema: Schema, assignedMapStyle?: return tx2; }; -export default function buildKeymap>(schema: S, props: any, mapKeys?: KeyMap): KeyMap { +export function buildKeymap>(schema: S, props: any, mapKeys?: KeyMap): KeyMap { const keys: { [key: string]: any } = {}; function bind(key: string, cmd: any) { diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx index 96628949a..a0e2d4351 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.tsx +++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx @@ -1,8 +1,8 @@ import React = require("react"); -import { IconProp, library } from '@fortawesome/fontawesome-svg-core'; -import { faBold, faCaretDown, faChevronLeft, faEyeDropper, faHighlighter, faOutdent, faIndent, faHandPointLeft, faHandPointRight, faItalic, faLink, faPaintRoller, faPalette, faStrikethrough, faSubscript, faSuperscript, faUnderline } from "@fortawesome/free-solid-svg-icons"; +import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { action, observable, IReactionDisposer, reaction } from "mobx"; +import { Tooltip } from "@material-ui/core"; +import { action, IReactionDisposer, observable, reaction } from "mobx"; import { observer } from "mobx-react"; import { lift, wrapIn } from "prosemirror-commands"; import { Mark, MarkType, Node as ProsNode, NodeType, ResolvedPos } from "prosemirror-model"; @@ -11,27 +11,24 @@ import { EditorState, NodeSelection, TextSelection } from "prosemirror-state"; import { EditorView } from "prosemirror-view"; import { Doc } from "../../../../fields/Doc"; import { DarkPastelSchemaPalette, PastelSchemaPalette } from '../../../../fields/SchemaHeaderField'; -import { Cast, StrCast, BoolCast, NumCast } from "../../../../fields/Types"; +import { Cast, StrCast } from "../../../../fields/Types"; +import { TraceMobx } from "../../../../fields/util"; import { unimplementedFunction, Utils } from "../../../../Utils"; import { DocServer } from "../../../DocServer"; import { LinkManager } from "../../../util/LinkManager"; import { SelectionManager } from "../../../util/SelectionManager"; -import AntimodeMenu, { AntimodeMenuProps } from "../../AntimodeMenu"; +import { undoBatch, UndoManager } from "../../../util/UndoManager"; +import { AntimodeMenu, AntimodeMenuProps } from "../../AntimodeMenu"; import { FieldViewProps } from "../FieldView"; import { FormattedTextBox, FormattedTextBoxProps } from "./FormattedTextBox"; import { updateBullets } from "./ProsemirrorExampleTransfer"; import "./RichTextMenu.scss"; import { schema } from "./schema_rts"; -import { TraceMobx } from "../../../../fields/util"; -import { UndoManager, undoBatch } from "../../../util/UndoManager"; -import { Tooltip } from "@material-ui/core"; const { toggleMark } = require("prosemirror-commands"); -library.add(faBold, faItalic, faChevronLeft, faUnderline, faStrikethrough, faSuperscript, faSubscript, faOutdent, faIndent, faHandPointLeft, faHandPointRight, faEyeDropper, faCaretDown, faPalette, faHighlighter, faLink, faPaintRoller); - @observer -export default class RichTextMenu extends AntimodeMenu { +export class RichTextMenu extends AntimodeMenu { static Instance: RichTextMenu; public overMenu: boolean = false; // kind of hacky way to prevent selects not being selectable diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts index a455516a3..7e632a0ee 100644 --- a/src/client/views/nodes/formattedText/RichTextRules.ts +++ b/src/client/views/nodes/formattedText/RichTextRules.ts @@ -9,7 +9,7 @@ import { DocServer } from "../../../DocServer"; import { Docs, DocUtils } from "../../../documents/Documents"; import { FormattedTextBox } from "./FormattedTextBox"; import { wrappingInputRule } from "./prosemirrorPatches"; -import RichTextMenu from "./RichTextMenu"; +import { RichTextMenu } from "./RichTextMenu"; import { schema } from "./schema_rts"; import { List } from "../../../../fields/List"; diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx index d29b638e6..98638ecc2 100644 --- a/src/client/views/pdf/Annotation.tsx +++ b/src/client/views/pdf/Annotation.tsx @@ -6,7 +6,7 @@ import { Id } from "../../../fields/FieldSymbols"; import { List } from "../../../fields/List"; import { Cast, FieldValue, NumCast, StrCast } from "../../../fields/Types"; import { DocumentManager } from "../../util/DocumentManager"; -import PDFMenu from "./PDFMenu"; +import { PDFMenu } from "./PDFMenu"; import "./Annotation.scss"; interface IAnnotationProps { @@ -19,7 +19,7 @@ interface IAnnotationProps { } @observer -export default +export class Annotation extends React.Component { render() { return DocListCast(this.props.anno.annotations).map(a => ( diff --git a/src/client/views/pdf/PDFMenu.tsx b/src/client/views/pdf/PDFMenu.tsx index 0f7b0a688..32dd376ac 100644 --- a/src/client/views/pdf/PDFMenu.tsx +++ b/src/client/views/pdf/PDFMenu.tsx @@ -1,17 +1,17 @@ import React = require("react"); -import "./PDFMenu.scss"; -import { observable, action, computed, } from "mobx"; -import { observer } from "mobx-react"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { unimplementedFunction, returnFalse, Utils } from "../../../Utils"; -import AntimodeMenu, { AntimodeMenuProps } from "../AntimodeMenu"; -import { Doc, Opt } from "../../../fields/Doc"; +import { action, computed, observable } from "mobx"; +import { observer } from "mobx-react"; import { ColorState } from "react-color"; +import { Doc, Opt } from "../../../fields/Doc"; +import { returnFalse, unimplementedFunction, Utils } from "../../../Utils"; +import { AntimodeMenu, AntimodeMenuProps } from "../AntimodeMenu"; import { ButtonDropdown } from "../nodes/formattedText/RichTextMenu"; +import "./PDFMenu.scss"; @observer -export default class PDFMenu extends AntimodeMenu { +export class PDFMenu extends AntimodeMenu { static Instance: PDFMenu; private _commentCont = React.createRef(); diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 201333d95..c8f98e249 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -1,39 +1,39 @@ import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; -const pdfjs = require('pdfjs-dist/es5/build/pdf.js'); import * as Pdfjs from "pdfjs-dist"; import "pdfjs-dist/web/pdf_viewer.css"; import { Dictionary } from "typescript-collections"; -import { Doc, DocListCast, FieldResult, HeightSym, Opt, WidthSym, AclAddonly, AclEdit, AclAdmin, DataSym } from "../../../fields/Doc"; +import { AclAddonly, AclAdmin, AclEdit, DataSym, Doc, DocListCast, HeightSym, Opt, WidthSym } from "../../../fields/Doc"; import { documentSchema } from "../../../fields/documentSchemas"; import { Id } from "../../../fields/FieldSymbols"; import { InkTool } from "../../../fields/InkField"; import { List } from "../../../fields/List"; -import { createSchema, makeInterface, listSpec } from "../../../fields/Schema"; -import { ScriptField, ComputedField } from "../../../fields/ScriptField"; +import { createSchema, makeInterface } from "../../../fields/Schema"; +import { ScriptField } from "../../../fields/ScriptField"; import { Cast, NumCast } from "../../../fields/Types"; import { PdfField } from "../../../fields/URLField"; -import { TraceMobx, GetEffectiveAcl } from "../../../fields/util"; +import { GetEffectiveAcl, TraceMobx } from "../../../fields/util"; import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, emptyPath, intersectRect, returnZero, smoothScroll, Utils } from "../../../Utils"; import { Docs, DocUtils } from "../../documents/Documents"; import { DocumentType } from "../../documents/DocumentTypes"; +import { Networking } from "../../Network"; import { DragManager } from "../../util/DragManager"; import { CompiledScript, CompileScript } from "../../util/Scripting"; import { SelectionManager } from "../../util/SelectionManager"; +import { SnappingManager } from "../../util/SnappingManager"; import { Transform } from "../../util/Transform"; import { undoBatch } from "../../util/UndoManager"; import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView"; import { CollectionView } from "../collections/CollectionView"; import { ViewBoxAnnotatableComponent } from "../DocComponent"; import { DocumentDecorations } from "../DocumentDecorations"; -import Annotation from "./Annotation"; -import PDFMenu from "./PDFMenu"; +import { Annotation } from "./Annotation"; +import { PDFMenu } from "./PDFMenu"; import "./PDFViewer.scss"; +const pdfjs = require('pdfjs-dist/es5/build/pdf.js'); import React = require("react"); -import { SnappingManager } from "../../util/SnappingManager"; const PDFJSViewer = require("pdfjs-dist/web/pdf_viewer"); const pdfjsLib = require("pdfjs-dist"); -import { Networking } from "../../Network"; export const pageSchema = createSchema({ curPage: "number", diff --git a/src/client/views/search/IconBar.tsx b/src/client/views/search/IconBar.tsx index 9b7cf2fc6..f1dd106a7 100644 --- a/src/client/views/search/IconBar.tsx +++ b/src/client/views/search/IconBar.tsx @@ -1,28 +1,11 @@ -import * as React from 'react'; +import { action, observable } from 'mobx'; import { observer } from 'mobx-react'; -import { observable, action } from 'mobx'; +import * as React from 'react'; +import { DocumentType } from "../../documents/DocumentTypes"; // import "./SearchBox.scss"; import "./IconBar.scss"; -import "./IconButton.scss"; -import { faSearch, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote, faMusic, faLink, faChartBar, faGlobeAsia, faBan, faTimesCircle, faCheckCircle } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { library } from '@fortawesome/fontawesome-svg-core'; -import * as _ from "lodash"; import { IconButton } from './IconButton'; -import { DocumentType } from "../../documents/DocumentTypes"; - - -library.add(faSearch); -library.add(faObjectGroup); -library.add(faImage); -library.add(faStickyNote); -library.add(faFilePdf); -library.add(faFilm); -library.add(faMusic); -library.add(faLink); -library.add(faChartBar); -library.add(faGlobeAsia); -library.add(faBan); +import "./IconButton.scss"; export interface IconBarProps { setIcons: (icons: string[]) => void; diff --git a/src/client/views/search/IconButton.tsx b/src/client/views/search/IconButton.tsx index 52641c543..349690b20 100644 --- a/src/client/views/search/IconButton.tsx +++ b/src/client/views/search/IconButton.tsx @@ -1,30 +1,14 @@ -import * as React from 'react'; -import { observer } from 'mobx-react'; -import { observable, action, runInAction, IReactionDisposer, reaction } from 'mobx'; -import "./SearchBox.scss"; -import "./IconButton.scss"; -import { faSearch, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote, faMusic, faLink, faChartBar, faGlobeAsia, faBan, faVideo, faCaretDown } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { library, icon } from '@fortawesome/fontawesome-svg-core'; +import * as _ from "lodash"; +import { action, IReactionDisposer, observable, reaction, runInAction } from 'mobx'; +import { observer } from 'mobx-react'; +import * as React from 'react'; import { DocumentType } from "../../documents/DocumentTypes"; import '../globalCssVariables.scss'; -import * as _ from "lodash"; import { IconBar } from './IconBar'; -import { props } from 'bluebird'; -import { Search } from '../../../server/Search'; -import { gravity } from 'sharp'; - -library.add(faSearch); -library.add(faObjectGroup); -library.add(faImage); -library.add(faStickyNote); -library.add(faFilePdf); -library.add(faFilm); -library.add(faMusic); -library.add(faLink); -library.add(faChartBar); -library.add(faGlobeAsia); -library.add(faBan); +import "./IconButton.scss"; +import "./SearchBox.scss"; +import { Font } from '@react-pdf/renderer'; interface IconButtonProps { type: string; @@ -47,59 +31,46 @@ export class IconButton extends React.Component{ componentDidMount = () => { this._resetReaction = reaction( () => IconBar.Instance._resetClicked, - () => { + action(() => { if (IconBar.Instance._resetClicked) { - runInAction(() => { - this.reset(); - IconBar.Instance._reset++; - if (IconBar.Instance._reset === 9) { - IconBar.Instance._reset = 0; - IconBar.Instance._resetClicked = false; - } - }); + this._isSelected = false; + IconBar.Instance._reset++; + if (IconBar.Instance._reset === 9) { + IconBar.Instance._reset = 0; + IconBar.Instance._resetClicked = false; + } } - }, + }), ); + this._selectAllReaction = reaction( () => IconBar.Instance._selectAllClicked, - () => { + action(() => { if (IconBar.Instance._selectAllClicked) { - runInAction(() => { - this.select(); - IconBar.Instance._select++; - if (IconBar.Instance._select === 9) { - IconBar.Instance._select = 0; - IconBar.Instance._selectAllClicked = false; - } - }); + this._isSelected = true; + IconBar.Instance._select++; + if (IconBar.Instance._select === 9) { + IconBar.Instance._select = 0; + IconBar.Instance._selectAllClicked = false; + } } - }, + }), ); } @action.bound getIcon() { switch (this.props.type) { - case (DocumentType.NONE): - return faBan; - case (DocumentType.AUDIO): - return faMusic; - case (DocumentType.COL): - return faObjectGroup; - case (DocumentType.IMG): - return faImage; - case (DocumentType.LINK): - return faLink; - case (DocumentType.PDF): - return faFilePdf; - case (DocumentType.RTF): - return faStickyNote; - case (DocumentType.VID): - return faVideo; - case (DocumentType.WEB): - return faGlobeAsia; - default: - return faCaretDown; + case (DocumentType.NONE): return "ban"; + case (DocumentType.AUDIO): return "music"; + case (DocumentType.COL): return "object-group"; + case (DocumentType.IMG): return "image"; + case (DocumentType.LINK): return "link"; + case (DocumentType.PDF): return "file-pdf"; + case (DocumentType.RTF): return "sticky-note"; + case (DocumentType.VID): return "video"; + case (DocumentType.WEB): return "globe-asia"; + default: return "caret-down"; } } @@ -136,53 +107,16 @@ export class IconButton extends React.Component{ //backgroundColor: "rgb(178, 206, 248)" //$darker-alt-accent }; - @action.bound - public reset() { this._isSelected = false; } - - @action.bound - public select() { this._isSelected = true; } - - @action - onMouseLeave = () => { this._hover = false; } - - @action - onMouseEnter = () => { this._hover = true; } - - getFA = () => { - switch (this.props.type) { - case (DocumentType.NONE): - return (); - case (DocumentType.AUDIO): - return (); - case (DocumentType.COL): - return (); - case (DocumentType.IMG): - return (); - case (DocumentType.LINK): - return (); - case (DocumentType.PDF): - return (); - case (DocumentType.RTF): - return (); - case (DocumentType.VID): - return (); - case (DocumentType.WEB): - return (); - default: - return (); - } - } - render() { return (
this._hover = true} + onMouseLeave={() => this._hover = false} onClick={this.onClick}>
- {this.getFA()} +
{/*
{this.props.type}
*/}
diff --git a/src/client/views/webcam/DashWebRTCVideo.tsx b/src/client/views/webcam/DashWebRTCVideo.tsx index 647e1ce6f..82c0e19c8 100644 --- a/src/client/views/webcam/DashWebRTCVideo.tsx +++ b/src/client/views/webcam/DashWebRTCVideo.tsx @@ -1,20 +1,16 @@ -import { observer } from "mobx-react"; -import React = require("react"); -import { CollectionFreeFormDocumentViewProps } from "../nodes/CollectionFreeFormDocumentView"; -import { FieldViewProps, FieldView } from "../nodes/FieldView"; -import { observable, action } from "mobx"; -import { DocumentDecorations } from "../DocumentDecorations"; -import "../../views/nodes/WebBox.scss"; -import "./DashWebRTCVideo.scss"; -import { initialize, hangup, refreshVideos } from "./WebCamLogic"; +import { faPhoneSlash, faSync } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { IconProp, library } from '@fortawesome/fontawesome-svg-core'; -import { faSync, faPhoneSlash } from "@fortawesome/free-solid-svg-icons"; +import { action, observable } from "mobx"; +import { observer } from "mobx-react"; import { Doc } from "../../../fields/Doc"; import { InkTool } from "../../../fields/InkField"; - -library.add(faSync); -library.add(faPhoneSlash); +import "../../views/nodes/WebBox.scss"; +import { DocumentDecorations } from "../DocumentDecorations"; +import { CollectionFreeFormDocumentViewProps } from "../nodes/CollectionFreeFormDocumentView"; +import { FieldView, FieldViewProps } from "../nodes/FieldView"; +import "./DashWebRTCVideo.scss"; +import { hangup, initialize, refreshVideos } from "./WebCamLogic"; +import React = require("react"); /** diff --git a/src/mobile/AudioUpload.tsx b/src/mobile/AudioUpload.tsx index 738de09c6..c412059dd 100644 --- a/src/mobile/AudioUpload.tsx +++ b/src/mobile/AudioUpload.tsx @@ -7,14 +7,14 @@ import { Utils, emptyPath, returnFalse, emptyFunction, returnOne, returnZero, re import { Doc, Opt } from '../fields/Doc'; import { Cast, FieldValue } from '../fields/Types'; import { listSpec } from '../fields/Schema'; -import MainViewModal from '../client/views/MainViewModal'; +import { MainViewModal } from '../client/views/MainViewModal'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { nullAudio } from '../fields/URLField'; import { Transform } from '../client/util/Transform'; import { DocumentView } from '../client/views/nodes/DocumentView'; import { MobileInterface } from './MobileInterface'; import { DictationOverlay } from '../client/views/DictationOverlay'; -import RichTextMenu from '../client/views/nodes/formattedText/RichTextMenu'; +import { RichTextMenu } from '../client/views/nodes/formattedText/RichTextMenu'; import { ContextMenu } from '../client/views/ContextMenu'; @observer diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx index d21d326f6..0ae952304 100644 --- a/src/mobile/ImageUpload.tsx +++ b/src/mobile/ImageUpload.tsx @@ -1,19 +1,19 @@ +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { action, observable } from 'mobx'; +import { observer } from 'mobx-react'; import * as rp from 'request-promise'; -import { Docs } from '../client/documents/Documents'; -import "./ImageUpload.scss"; -import React = require('react'); import { DocServer } from '../client/DocServer'; -import { observer } from 'mobx-react'; -import { observable, action } from 'mobx'; -import { Utils } from '../Utils'; +import { Docs } from '../client/documents/Documents'; import { Networking } from '../client/Network'; +import { MainViewModal } from '../client/views/MainViewModal'; import { Doc, Opt } from '../fields/Doc'; -import { Cast } from '../fields/Types'; -import { listSpec } from '../fields/Schema'; import { List } from '../fields/List'; -import MainViewModal from '../client/views/MainViewModal'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { listSpec } from '../fields/Schema'; +import { Cast } from '../fields/Types'; +import { Utils } from '../Utils'; +import "./ImageUpload.scss"; import { MobileInterface } from './MobileInterface'; +import React = require('react'); export interface ImageUploadProps { Document: Doc; // Target document for upload (upload location) diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx index 05a695147..8ca67f9ee 100644 --- a/src/mobile/MobileInterface.tsx +++ b/src/mobile/MobileInterface.tsx @@ -1,4 +1,4 @@ -import * as React from "react"; + import { library } from '@fortawesome/fontawesome-svg-core'; import { faTasks, faReply, faQuoteLeft, faHandPointLeft, faFolderOpen, faAngleDoubleLeft, faExternalLinkSquareAlt, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus, @@ -10,34 +10,34 @@ import { faAlignRight, faAlignLeft } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, observable, reaction, trace, runInAction } from 'mobx'; +import { action, computed, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; -import { Doc, DocListCast } from '../fields/Doc'; -import { CurrentUserUtils } from '../client/util/CurrentUserUtils'; -import { emptyFunction, emptyPath, returnFalse, returnOne, returnTrue, returnZero, returnEmptyFilter, returnEmptyDoclist } from '../Utils'; +import * as React from "react"; import { Docs, DocumentOptions } from '../client/documents/Documents'; +import { DocumentType } from "../client/documents/DocumentTypes"; +import { CurrentUserUtils } from '../client/util/CurrentUserUtils'; import { Scripting } from '../client/util/Scripting'; -import { DocumentView } from '../client/views/nodes/DocumentView'; +import { SettingsManager } from '../client/util/SettingsManager'; import { Transform } from '../client/util/Transform'; -import "./MobileInterface.scss"; -import "./ImageUpload.scss"; -import "./AudioUpload.scss"; -import SettingsManager from '../client/util/SettingsManager'; -import { Uploader } from "./ImageUpload"; +import { UndoManager } from "../client/util/UndoManager"; import { DockedFrameRenderer } from '../client/views/collections/CollectionDockingView'; -import { InkTool } from '../fields/InkField'; -import GestureOverlay from "../client/views/GestureOverlay"; -import { ScriptField } from "../fields/ScriptField"; +import { CollectionViewType } from "../client/views/collections/CollectionView"; +import { GestureOverlay } from "../client/views/GestureOverlay"; +import { AudioBox } from "../client/views/nodes/AudioBox"; +import { DocumentView } from '../client/views/nodes/DocumentView'; +import { RichTextMenu } from "../client/views/nodes/formattedText/RichTextMenu"; import { RadialMenu } from "../client/views/nodes/RadialMenu"; -import { UndoManager } from "../client/util/UndoManager"; +import { Doc, DocListCast } from '../fields/Doc'; +import { InkTool } from '../fields/InkField'; import { List } from "../fields/List"; -import { AudioUpload } from "./AudioUpload"; +import { ScriptField } from "../fields/ScriptField"; import { Cast, FieldValue } from '../fields/Types'; -import RichTextMenu from "../client/views/nodes/formattedText/RichTextMenu"; -import { AudioBox } from "../client/views/nodes/AudioBox"; -import { CollectionViewType } from "../client/views/collections/CollectionView"; -import { DocumentType } from "../client/documents/DocumentTypes"; -import { CollectionFreeFormViewChrome } from "../client/views/collections/CollectionMenu"; +import { emptyFunction, emptyPath, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, returnTrue, returnZero } from '../Utils'; +import { AudioUpload } from "./AudioUpload"; +import { Uploader } from "./ImageUpload"; +import "./AudioUpload.scss"; +import "./ImageUpload.scss"; +import "./MobileInterface.scss"; library.add(faTasks, faReply, faQuoteLeft, faHandPointLeft, faFolderOpen, faAngleDoubleLeft, faExternalLinkSquareAlt, faMobile, faThLarge, faWindowClose, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus, faTerminal, faToggleOn, fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard, @@ -47,6 +47,7 @@ library.add(faTasks, faReply, faQuoteLeft, faHandPointLeft, faFolderOpen, faAngl faThumbtack, faTree, faTv, faUndoAlt, faBook, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faHome, faLongArrowAltLeft, faBars, faTh, faChevronLeft, faAlignLeft, faAlignRight); + @observer export class MobileInterface extends React.Component { static Instance: MobileInterface; -- cgit v1.2.3-70-g09d2 From a6728f81c8192c910ed1f2b70091c39634aca05c Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 24 Aug 2020 11:48:00 -0400 Subject: fixed presentation trails being added to myPresentations. fixed properties pane to set title "in place". --- src/client/views/MainView.tsx | 2 ++ src/client/views/collections/CollectionDockingView.tsx | 3 --- src/client/views/collections/CollectionTreeView.tsx | 4 ++-- src/client/views/collections/CollectionView.tsx | 5 ----- src/client/views/collections/collectionFreeForm/MarqueeView.tsx | 3 --- src/client/views/collections/collectionFreeForm/PropertiesView.tsx | 2 +- src/client/views/nodes/PresBox.tsx | 3 +++ 7 files changed, 8 insertions(+), 14 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 9d6bffa60..3958b2a8c 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -274,6 +274,7 @@ export class MainView extends React.Component { @action createNewDashboard = async (id?: string) => { const myCatalog = Doc.UserDoc().myCatalog as Doc; + const myPresentations = Doc.UserDoc().myPresentations as Doc; const presentation = Doc.MakeCopy(Doc.UserDoc().emptyPresentation as Doc, true); const dashboards = Cast(this.userDoc.myDashboards, Doc) as Doc; const dashboardCount = DocListCast(dashboards.data).length + 1; @@ -290,6 +291,7 @@ export class MainView extends React.Component { const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600, path: [myCatalog] }], { title: `Dashboard ${dashboardCount}` }, id, "row"); Doc.AddDocToList(myCatalog, "data", freeformDoc); Doc.AddDocToList(myCatalog, "data", presentation); + Doc.AddDocToList(myPresentations, "data", presentation); Doc.UserDoc().activePresentation = presentation; const toggleTheme = ScriptField.MakeScript(`self.darkScheme = !self.darkScheme`); const toggleComic = ScriptField.MakeScript(`toggleComicMode()`); diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index cc2220f62..4d4bc2a97 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -757,9 +757,6 @@ export class DockedFrameRenderer extends React.Component { CollectionDockingView.AddRightSplit(curPres); } DocumentManager.Instance.jumpToDocument(doc, false, undefined, Cast(doc.context, Doc, null)); - const myPresentations = Doc.UserDoc().myPresentations as Doc; - const presData = DocListCast(myPresentations.data); - if (!presData.includes(curPres)) Doc.AddDocToList(myPresentations, "data", curPres); } } } diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 9460095e4..c43349059 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -736,8 +736,8 @@ export class CollectionTreeView extends CollectionSubView Doc.UserDoc().myRecentlyClosed = new List(), icon: "plus" }); + } else if (!e.isPropagationStopped() && this.doc === Doc.UserDoc().myInactiveDocs) { + ContextMenu.Instance.addItem({ description: "Clear All", event: () => Doc.UserDoc().myInactiveDocs = new List(), icon: "plus" }); e.stopPropagation(); e.preventDefault(); ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15); diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 97336798b..1ad63c34e 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -179,11 +179,6 @@ export class CollectionView extends Touchable Doc.AddDocToList(Cast(Doc.UserDoc().myCatalog, Doc, null), "data", add)); - const myPresentations = Doc.UserDoc().myPresentations as Doc; - added.map(add => { - if (add.type === DocumentType.PRES) Doc.AddDocToList(myPresentations, "data", add); - }); - // targetDataDoc[this.props.fieldKey] = new List([...docList, ...added]); (targetDataDoc[this.props.fieldKey] as List).push(...added); targetDataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now())); const lastModified = "lastModified"; diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index d161f49f7..b8019e37b 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -400,9 +400,6 @@ export class MarqueeView extends React.Component { @action setTitle = (value: string) => { if (this.dataDoc) { - this.selectedDoc && (this.selectedDoc.title = value); + this.selectedDoc && Doc.SetInPlace(this.selectedDoc, "title", value, true); KeyValueBox.SetField(this.dataDoc, "title", value, true); return true; } diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 1228a285e..9070bf2ae 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -107,6 +107,9 @@ export class PresBox extends ViewBoxBaseComponent this.rootDoc._replacedChrome = "replaced"; this.layoutDoc.presStatus = "edit"; this.layoutDoc._gridGap = 5; + if (!DocListCast((Doc.UserDoc().myPresentations as Doc).data).includes(this.rootDoc)) { + Doc.AddDocToList(Doc.UserDoc().myPresentations as Doc, "data", this.rootDoc); + } } updateCurrentPresentation = () => { -- cgit v1.2.3-70-g09d2 From 502457143a151bb6bd504b313160a462c9b00aa3 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 24 Aug 2020 12:51:20 -0400 Subject: fixed use clusters icon in propertiesButtons --- src/client/views/PropertiesButtons.tsx | 6 +++--- src/client/views/collections/CollectionMenu.tsx | 4 ++-- .../collectionFreeForm/CollectionFreeFormView.tsx | 20 ++++++++++---------- 3 files changed, 15 insertions(+), 15 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index 4abb2cb7a..cdc894678 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -610,9 +610,9 @@ export class PropertiesButtons extends React.Component<{}, {}> { get clustersButton() { const targetDoc = this.selectedDoc; return !targetDoc ? (null) :
{this.selectedDoc?.useClusters ? "Stop Showing Clusters" : "Show Clusters"}
} placement="top"> + title={<>
{this.selectedDoc?._useClusters ? "Stop Showing Clusters" : "Show Clusters"}
} placement="top">
-
+
clusters
@@ -627,7 +627,7 @@ export class PropertiesButtons extends React.Component<{}, {}> { @action @undoBatch changeClusters = () => { - this.selectedDoc && (this.selectedDoc.useClusters = !this.selectedDoc.useClusters); + this.selectedDoc && (this.selectedDoc._useClusters = !this.selectedDoc._useClusters); } @computed diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index d086c8b1f..9f0a493d2 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -174,8 +174,8 @@ export class CollectionViewBaseChrome extends React.Component this.target.useClusters = !this.target.useClusters), + script: "self.target._useClusters = !self.target._useClusters;", + immediate: undoBatch((source: Doc[]) => this.target._useClusters = !this.target._useClusters), initialize: emptyFunction }; _saveFilterCommand = { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index d64b49c4d..75fc297fd 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -54,7 +54,7 @@ export const panZoomSchema = createSchema({ displayTimecode: "number", currentFrame: "number", arrangeInit: ScriptField, - useClusters: "boolean", + _useClusters: "boolean", fitToBox: "boolean", _xPadding: "number", // pixels of padding on left/right of collectionfreeformview contents when fitToBox is set _yPadding: "number", // pixels of padding on left/right of collectionfreeformview contents when fitToBox is set @@ -301,8 +301,8 @@ export class CollectionFreeFormView extends CollectionSubView pair.layout).map(c => this.updateCluster(c)); } @@ -310,7 +310,7 @@ export class CollectionFreeFormView extends CollectionSubView pair.layout); - if (this.props.Document.useClusters) { + if (this.props.Document._useClusters) { const docFirst = docs[0]; docs.map(doc => this._clusterSets.map(set => Doc.IndexOf(doc, set) !== -1 && set.splice(Doc.IndexOf(doc, set), 1))); const preferredInd = NumCast(docFirst.cluster); @@ -345,7 +345,7 @@ export class CollectionFreeFormView extends CollectionSubView pair.layout); - if (this.props.Document.useClusters) { + if (this.props.Document._useClusters) { this._clusterSets.map(set => Doc.IndexOf(doc, set) !== -1 && set.splice(Doc.IndexOf(doc, set), 1)); const preferredInd = NumCast(doc.cluster); doc.cluster = -1; @@ -375,7 +375,7 @@ export class CollectionFreeFormView extends CollectionSubView { let clusterColor = this.props.backgroundColor?.(doc, this.props.renderDepth + 1); const cluster = NumCast(doc.cluster); - if (this.Document.useClusters) { + if (this.Document._useClusters) { if (this._clusterSets.length <= cluster) { setTimeout(() => this.updateCluster(doc), 0); } else { @@ -397,7 +397,7 @@ export class CollectionFreeFormView extends CollectionSubView this.props.childClickScript || ScriptCast(this.Document.onChildClick); onChildDoubleClickHandler = () => this.props.childDoubleClickScript || ScriptCast(this.Document.onChildDoubleClick); - backgroundHalo = () => BoolCast(this.Document.useClusters); + backgroundHalo = () => BoolCast(this.Document._useClusters); parentActive = (outsideReaction: boolean) => this.props.active(outsideReaction) || this.backgroundActive ? true : false; getChildDocumentViewProps(childLayout: Doc, childData?: Doc): DocumentViewProps { return { @@ -1137,7 +1137,7 @@ export class CollectionFreeFormView extends CollectionSubView Doc.UserDoc().showSnapLines = !Doc.UserDoc().showSnapLines, icon: "compress-arrows-alt" }) : null; - !Doc.UserDoc().noviceMode ? viewCtrlItems.push({ description: (this.Document.useClusters ? "Hide" : "Show") + " Clusters", event: () => this.updateClusters(!this.Document.useClusters), icon: "braille" }) : null; + !Doc.UserDoc().noviceMode ? viewCtrlItems.push({ description: (this.Document._useClusters ? "Hide" : "Show") + " Clusters", event: () => this.updateClusters(!this.Document._useClusters), icon: "braille" }) : null; !viewctrls && ContextMenu.Instance.addItem({ description: "UI Controls...", subitems: viewCtrlItems, icon: "eye" }); const options = ContextMenu.Instance.findByDescription("Options..."); -- cgit v1.2.3-70-g09d2 From 11ad6626648b8f1c06c477705a34731a8255bf31 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 24 Aug 2020 14:14:49 -0400 Subject: changed names of currentFrame, curPage, and currentTimecode to start with "_'. moved actions out of the properties options buttons to colelction menu. --- src/client/documents/Documents.ts | 14 +-- src/client/util/DocumentManager.ts | 4 +- src/client/views/MainView.tsx | 2 +- src/client/views/PropertiesButtons.tsx | 131 +-------------------- .../views/collections/CollectionDockingView.tsx | 3 +- src/client/views/collections/CollectionMenu.tsx | 119 +++++++++++++++++-- .../views/collections/CollectionSchemaView.tsx | 2 +- .../views/collections/CollectionStackingView.tsx | 2 +- src/client/views/collections/SchemaTable.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 18 +-- .../collectionFreeForm/PropertiesView.tsx | 20 ++-- src/client/views/nodes/AudioBox.tsx | 18 +-- .../views/nodes/CollectionFreeFormDocumentView.tsx | 4 +- src/client/views/nodes/ImageBox.tsx | 2 +- src/client/views/nodes/PDFBox.tsx | 10 +- src/client/views/nodes/PresBox.tsx | 50 ++++---- src/client/views/nodes/VideoBox.tsx | 28 ++--- src/client/views/pdf/PDFViewer.tsx | 12 +- src/fields/documentSchemas.ts | 5 +- 19 files changed, 206 insertions(+), 240 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index cce50e306..e4c704ce7 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -135,10 +135,10 @@ export interface DocumentOptions { _fontSize?: string; _fontWeight?: number; _fontFamily?: string; - curPage?: number; - currentTimecode?: number; // the current timecode of a time-based document (e.g., current time of a video) value is in seconds + _curPage?: number; + _currentTimecode?: number; // the current timecode of a time-based document (e.g., current time of a video) value is in seconds + _currentFrame?: number; // the current frame of a frame-based collection (e.g., progressive slide) displayTimecode?: number; // the time that a document should be displayed (e.g., time an annotation should be displayed on a video) - currentFrame?: number; // the current frame of a frame-based collection (e.g., progressive slide) lastFrame?: number; // the last frame of a frame-based collection (e.g., progressive slide) activeFrame?: number; // the active frame of a document in a frame base collection appearFrame?: number; // the frame in which the document appears @@ -270,7 +270,7 @@ export namespace Docs { }], [DocumentType.VID, { layout: { view: VideoBox, dataField: defaultDataKey }, - options: { currentTimecode: 0 }, + options: { _currentTimecode: 0 }, }], [DocumentType.AUDIO, { layout: { view: AudioBox, dataField: defaultDataKey }, @@ -278,7 +278,7 @@ export namespace Docs { }], [DocumentType.PDF, { layout: { view: PDFBox, dataField: defaultDataKey }, - options: { curPage: 1 } + options: { _curPage: 1 } }], [DocumentType.IMPORT, { layout: { view: DirectoryImportBox, dataField: defaultDataKey }, @@ -688,8 +688,8 @@ export namespace Docs { const linkDocProto = Doc.GetProto(doc); linkDocProto.anchor1 = source.doc; linkDocProto.anchor2 = target.doc; - linkDocProto.anchor1_timecode = source.doc.currentTimecode || source.doc.displayTimecode; - linkDocProto.anchor2_timecode = target.doc.currentTimecode || target.doc.displayTimecode; + linkDocProto.anchor1_timecode = source.doc._currentTimecode || source.doc.displayTimecode; + linkDocProto.anchor2_timecode = target.doc._currentTimecode || target.doc.displayTimecode; if (linkDocProto.linkBoxExcludedKeys === undefined) { Cast(linkDocProto.proto, Doc, null).linkBoxExcludedKeys = new List(["treeViewExpandedView", "treeViewHideTitle", "removeDropProperties", "linkBoxExcludedKeys", "treeViewOpen", "aliasNumber", "isPrototype", "lastOpened", "creationDate", "author"]); diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index bd57e7f48..fb54fbefc 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -181,7 +181,7 @@ export class DocumentManager { // now find the target document within the context if (targetDoc.displayTimecode) { // if the target has a timecode, it should show up once the (presumed) video context scrubs to the display timecode; - targetDocContext.currentTimecode = targetDoc.displayTimecode; + targetDocContext._currentTimecode = targetDoc.displayTimecode; finished?.(); } else { // no timecode means we need to find the context view and focus on our target setTimeout(() => { @@ -228,7 +228,7 @@ export class DocumentManager { (Doc.AreProtosEqual(doc, linkDoc.anchor1 as Doc) ? Cast(linkDoc.anchor2_timecode, "number") : Cast(linkDoc.anchor1_timecode, "number"))); if (target) { const containerDoc = (await Cast(target.annotationOn, Doc)) || target; - containerDoc.currentTimecode = targetTimecode; + containerDoc._currentTimecode = targetTimecode; const targetContext = await target?.context as Doc; const targetNavContext = !Doc.AreProtosEqual(targetContext, currentContext) ? targetContext : undefined; DocumentManager.Instance.jumpToDocument(target, zoom, (doc, finished) => createViewFunc(doc, StrCast(linkDoc.followLinkLocation, "onRight"), finished), targetNavContext, linkDoc, undefined, doc, finished); diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 3958b2a8c..22dc023bb 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -167,7 +167,7 @@ export class MainView extends React.Component { } library.add(fa.faEdit, fa.faTrash, fa.faTrashAlt, fa.faShare, fa.faDownload, fa.faExpandArrowsAlt, fa.faLayerGroup, fa.faExternalLinkAlt, fa.faCalendar, - fa.faSquare, fa.faConciergeBell, fa.faWindowRestore, fa.faFolder, fa.faMapPin, fa.faFingerprint, fa.faCrosshairs, fa.faDesktop, fa.faUnlock, + fa.faSquare, fa.faConciergeBell, fa.faWindowRestore, fa.faFolder, fa.faMapPin, fa.faMapMarker, fa.faFingerprint, fa.faCrosshairs, fa.faDesktop, fa.faUnlock, fa.faLock, fa.faLaptopCode, fa.faMale, fa.faCopy, fa.faHandPointLeft, fa.faHandPointRight, fa.faCompass, fa.faSnowflake, fa.faMicrophone, fa.faKeyboard, fa.faQuestion, fa.faTasks, fa.faPalette, fa.faAngleLeft, fa.faAngleRight, fa.faBell, fa.faCamera, fa.faExpand, fa.faCaretDown, fa.faCaretLeft, fa.faCaretRight, fa.faCaretSquareDown, fa.faCaretSquareRight, fa.faArrowsAltH, fa.faPlus, fa.faMinus, fa.faTerminal, fa.faToggleOn, fa.faFile, fa.faLocationArrow, diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index cdc894678..63837282c 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -46,7 +46,6 @@ enum UtilityButtonState { @observer export class PropertiesButtons extends React.Component<{}, {}> { - private _dragRef = React.createRef(); private _pullAnimating = false; private _pushAnimating = false; private _pullColorAnimating = false; @@ -200,54 +199,6 @@ export class PropertiesButtons extends React.Component<{}, {}> {
; } - @computed - get pinButton() { - const targetDoc = this.selectedDoc; - const isPinned = targetDoc && Doc.isDocPinned(targetDoc); - return !targetDoc ? (null) : {Doc.isDocPinned(targetDoc) ? "Unpin from presentation" : "Pin to presentation"}
} placement="top"> -
-
DockedFrameRenderer.PinDoc(targetDoc, isPinned)}> - -
- -
{Doc.isDocPinned(targetDoc) ? "Unpin" : "Pin"}
-
-
; - } - - @computed - get pinWithViewButton() { - const targetDoc = this.selectedDoc; - if (targetDoc) { - const x = targetDoc._panX; - const y = targetDoc._panY; - const scale = targetDoc._viewScale; - } - return !targetDoc ? (null) :
{"Pin to presentation with current view"}
} placement="top"> -
-
{ - if (targetDoc) { - DockedFrameRenderer.PinDoc(targetDoc, false); - const activeDoc = PresBox.Instance.childDocs[PresBox.Instance.childDocs.length - 1]; - const x = targetDoc._panX; - const y = targetDoc._panY; - const scale = targetDoc._viewScale; - activeDoc.presPinView = true; - activeDoc.presPinViewX = x; - activeDoc.presPinViewY = y; - activeDoc.presPinViewScale = scale; - } - }}> - -
V
-
- -
{"View"}
-
-
; - } - @computed get metadataButton() { @@ -271,26 +222,6 @@ export class PropertiesButtons extends React.Component<{}, {}> { } - @observable _aliasDown = false; - onAliasButtonDown = (e: React.PointerEvent): void => { - setupMoveUpEvents(this, e, this.onAliasButtonMoved, emptyFunction, emptyFunction); - } - @undoBatch - onAliasButtonMoved = (e: PointerEvent) => { - if (this._dragRef.current && this.selectedDoc) { - const dragData = new DragManager.DocumentDragData([this.selectedDoc]); - const [left, top] = [e.clientX, e.clientY]; - dragData.dropAction = "alias"; - DragManager.StartDocumentDrag([this._dragRef.current], dragData, left, top, { - offsetX: dragData.offset[0], - offsetY: dragData.offset[1], - hideSource: false - }); - return true; - } - return false; - } - @computed get templateButton() { const docView = this.selectedDocumentView?.props.Document === this.selectedDoc ? this.selectedDocumentView : undefined; @@ -313,35 +244,6 @@ export class PropertiesButtons extends React.Component<{}, {}> {
; } - @undoBatch - onCopy = () => { - if (this.selectedDoc && this.selectedDocumentView) { - // const copy = Doc.MakeCopy(this.selectedDocumentView.props.Document, true); - // copy.x = NumCast(this.selectedDoc.x) + NumCast(this.selectedDoc._width); - // copy.y = NumCast(this.selectedDoc.y) + 30; - // this.selectedDocumentView.props.addDocument?.(copy); - const alias = Doc.MakeAlias(this.selectedDoc); - alias.x = NumCast(this.selectedDoc.x) + NumCast(this.selectedDoc._width); - alias.y = NumCast(this.selectedDoc.y) + 30; - this.selectedDocumentView.props.addDocument?.(alias); - } - } - - @computed - get copyButton() { - const targetDoc = this.selectedDoc; - return !targetDoc ? (null) : {"Tap or Drag to create an alias"}
} placement="top"> -
-
- -
-
Alias
-
- ; - } @action @undoBatch onLock = () => { @@ -478,20 +380,6 @@ export class PropertiesButtons extends React.Component<{}, {}> { ; } - @computed - get sharingButton() { - const targetDoc = this.selectedDoc; - const docView = this.selectedDocumentView?.props.Document === this.selectedDoc ? this.selectedDocumentView : undefined; - return !targetDoc ? (null) : {"Share Document"}
} placement="top"> -
-
this.selectedDocumentView && SharingManager.Instance.open(docView, this.selectedDoc)}> - -
-
share
-
-
; - } - @computed get onClickButton() { if (this.selectedDoc) { @@ -729,15 +617,6 @@ export class PropertiesButtons extends React.Component<{}, {}> { {/*
{this.metadataButton}
*/} -
- {this.pinButton} -
-
- {this.pinWithViewButton} -
-
- {this.copyButton} -
{this.titleButton}
@@ -753,20 +632,14 @@ export class PropertiesButtons extends React.Component<{}, {}> {
{this.dictationButton}
-
- {this.downloadButton} -
- {collectionAcl === AclAdmin || collectionAcl === AclEdit ? + {/* {collectionAcl === AclAdmin || collectionAcl === AclEdit ?
{this.deleteButton}
- : (null)} + : (null)} */}
{this.onClickButton}
-
- {this.sharingButton} -
{this.contextButton}
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 4d4bc2a97..cae7d0ca1 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -890,8 +890,7 @@ export class DockedFrameRenderer extends React.Component { } getCurrentFrame = (): number => { const presTargetDoc = Cast(PresBox.Instance.childDocs[PresBox.Instance.itemIndex].presentationTargetDoc, Doc, null); - const currentFrame = Cast(presTargetDoc.currentFrame, "number", null); - return currentFrame; + return Cast(presTargetDoc._currentFrame, "number", null); } renderMiniMap() { diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 9f0a493d2..4137b6c27 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -31,6 +31,8 @@ import { DocumentView } from "../nodes/DocumentView"; import { RichTextMenu } from "../nodes/formattedText/RichTextMenu"; import "./CollectionMenu.scss"; import { CollectionViewType, COLLECTION_BORDER_WIDTH } from "./CollectionView"; +import { DockedFrameRenderer } from "./CollectionDockingView"; +import { PresBox } from "../nodes/PresBox"; @observer export class CollectionMenu extends AntimodeMenu { @@ -163,8 +165,8 @@ export class CollectionViewBaseChrome extends React.Component { this.target._panX = 0; this.target._panY = 0; this.target._viewScale = 1; this.target.currentFrame = 0; }), - initialize: (button: Doc) => { button['target-panX'] = this.target._panX; button['target-panY'] = this.target._panY; button['target-viewScale'] = this.target._viewScale; button['target-currentFrame'] = this.target.currentFrame; }, + immediate: undoBatch((source: Doc[]) => { this.target._panX = 0; this.target._panY = 0; this.target._viewScale = 1; this.target._currentFrame = 0; }), + initialize: (button: Doc) => { button['target-panX'] = this.target._panX; button['target-panY'] = this.target._panY; button['target-viewScale'] = this.target._viewScale; button['target-currentFrame'] = this.target._currentFrame; }, }; _clusterCommand = { params: ["target"], title: "fit content", @@ -371,6 +373,94 @@ export class CollectionViewBaseChrome extends React.Component{Doc.isDocPinned(targetDoc) ? "Unpin from presentation" : "Pin to presentation"}
} placement="top"> + +
; + } + + @undoBatch + onAlias = () => { + if (this.selectedDoc && this.selectedDocumentView) { + // const copy = Doc.MakeCopy(this.selectedDocumentView.props.Document, true); + // copy.x = NumCast(this.selectedDoc.x) + NumCast(this.selectedDoc._width); + // copy.y = NumCast(this.selectedDoc.y) + 30; + // this.selectedDocumentView.props.addDocument?.(copy); + const alias = Doc.MakeAlias(this.selectedDoc); + alias.x = NumCast(this.selectedDoc.x) + NumCast(this.selectedDoc._width); + alias.y = NumCast(this.selectedDoc.y) + 30; + this.selectedDocumentView.props.addDocument?.(alias); + } + } + private _dragRef = React.createRef(); + + @observable _aliasDown = false; + onAliasButtonDown = (e: React.PointerEvent): void => { + setupMoveUpEvents(this, e, this.onAliasButtonMoved, emptyFunction, emptyFunction); + } + @undoBatch + onAliasButtonMoved = (e: PointerEvent) => { + if (this._dragRef.current && this.selectedDoc) { + const dragData = new DragManager.DocumentDragData([this.selectedDoc]); + const [left, top] = [e.clientX, e.clientY]; + dragData.dropAction = "alias"; + DragManager.StartDocumentDrag([this._dragRef.current], dragData, left, top, { + offsetX: dragData.offset[0], + offsetY: dragData.offset[1], + hideSource: false + }); + return true; + } + return false; + } + + @computed + get aliasButton() { + const targetDoc = this.selectedDoc; + return !targetDoc ? (null) : {"Tap or Drag to create an alias"}
} placement="top"> + + ; + } + + @computed + get pinWithViewButton() { + const targetDoc = this.selectedDoc; + if (targetDoc) { + const x = targetDoc._panX; + const y = targetDoc._panY; + const scale = targetDoc._viewScale; + } + return !targetDoc ? (null) :
{"Pin to presentation with current view"}
} placement="top"> + +
; + } + render() { return ( @@ -396,6 +486,9 @@ export class CollectionViewBaseChrome extends React.Component } + {this.aliasButton} + {this.pinButton} + {this.props.docView.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Freeform ? (null) : this.pinWithViewButton}
{this.subChrome}
@@ -444,25 +537,25 @@ export class CollectionFreeFormViewChrome extends React.Component { - const currentFrame = Cast(this.document.currentFrame, "number", null); + const currentFrame = Cast(this.document._currentFrame, "number", null); if (currentFrame === undefined) { - this.document.currentFrame = 0; + this.document._currentFrame = 0; CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0); } CollectionFreeFormDocumentView.updateKeyframe(this.childDocs, currentFrame || 0); - this.document.currentFrame = Math.max(0, (currentFrame || 0) + 1); - this.document.lastFrame = Math.max(NumCast(this.document.currentFrame), NumCast(this.document.lastFrame)); + this.document._currentFrame = Math.max(0, (currentFrame || 0) + 1); + this.document.lastFrame = Math.max(NumCast(this.document._currentFrame), NumCast(this.document.lastFrame)); } @undoBatch @action prevKeyframe = (): void => { - const currentFrame = Cast(this.document.currentFrame, "number", null); + const currentFrame = Cast(this.document._currentFrame, "number", null); if (currentFrame === undefined) { - this.document.currentFrame = 0; + this.document._currentFrame = 0; CollectionFreeFormDocumentView.setupKeyframes(this.childDocs, 0); } CollectionFreeFormDocumentView.gotoKeyframe(this.childDocs.slice()); - this.document.currentFrame = Math.max(0, (currentFrame || 0) - 1); + this.document._currentFrame = Math.max(0, (currentFrame || 0) - 1); } @undoBatch @action @@ -784,7 +877,7 @@ export class CollectionFreeFormViewChrome extends React.ComponentToggle View All
} placement="bottom">
this.document.editing = !this.document.editing)} > - {NumCast(this.document.currentFrame)} + {NumCast(this.document._currentFrame)}
: null} {!this.isText && !this.props.isDoc ? Forward Frame
} placement="bottom"> @@ -1242,11 +1335,11 @@ export class CollectionGridViewChrome extends React.Component = new Map([ ["title", ColumnType.String], ["x", ColumnType.Number], ["y", ColumnType.Number], ["_width", ColumnType.Number], ["_height", ColumnType.Number], ["_nativeWidth", ColumnType.Number], ["_nativeHeight", ColumnType.Number], ["isPrototype", ColumnType.Boolean], - ["page", ColumnType.Number], ["curPage", ColumnType.Number], ["currentTimecode", ColumnType.Number], ["zIndex", ColumnType.Number] + ["_curPage", ColumnType.Number], ["_currentTimecode", ColumnType.Number], ["zIndex", ColumnType.Number] ]); @observer diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index a50dab54d..5386d617c 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -193,7 +193,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) getDisplayDoc(doc: Doc, dataDoc: Doc | undefined, dxf: () => Transform, width: () => number) { const height = () => this.getDocHeight(doc); - const opacity = () => this.Document.currentFrame === undefined ? this.props.childOpacity?.() : CollectionFreeFormDocumentView.getValues(doc, NumCast(this.Document.currentFrame))?.opacity; + const opacity = () => this.Document._currentFrame === undefined ? this.props.childOpacity?.() : CollectionFreeFormDocumentView.getValues(doc, NumCast(this.Document._currentFrame))?.opacity; return = new Map([ ["title", ColumnType.String], ["x", ColumnType.Number], ["y", ColumnType.Number], ["_width", ColumnType.Number], ["_height", ColumnType.Number], ["_nativeWidth", ColumnType.Number], ["_nativeHeight", ColumnType.Number], ["isPrototype", ColumnType.Boolean], - ["page", ColumnType.Number], ["curPage", ColumnType.Number], ["currentTimecode", ColumnType.Number], ["zIndex", ColumnType.Number] + ["_curPage", ColumnType.Number], ["_currentTimecode", ColumnType.Number], ["zIndex", ColumnType.Number] ]); export interface SchemaTableProps { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 75fc297fd..549610e53 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -50,9 +50,9 @@ import React = require("react"); export const panZoomSchema = createSchema({ _panX: "number", _panY: "number", - currentTimecode: "number", + _currentTimecode: "number", displayTimecode: "number", - currentFrame: "number", + _currentFrame: "number", arrangeInit: ScriptField, _useClusters: "boolean", fitToBox: "boolean", @@ -173,8 +173,8 @@ export class CollectionFreeFormView extends CollectionSubView DocumentManager.Instance.getDocumentView(doc, this.props.CollectionView)).map(dv => dv && SelectionManager.SelectDoc(dv, true)); } - public isCurrent(doc: Doc) { return (Math.abs(NumCast(doc.displayTimecode, -1) - NumCast(this.Document.currentTimecode, -1)) < 1.5 || NumCast(doc.displayTimecode, -1) === -1); } + public isCurrent(doc: Doc) { return (Math.abs(NumCast(doc.displayTimecode, -1) - NumCast(this.Document._currentTimecode, -1)) < 1.5 || NumCast(doc.displayTimecode, -1) === -1); } public getActiveDocuments = () => { return this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map(pair => pair.layout); @@ -207,9 +207,9 @@ export class CollectionFreeFormView extends CollectionSubView { @observable layoutFields: boolean = false; - @observable openActions: boolean = true; + @observable openOptions: boolean = true; @observable openSharing: boolean = true; @observable openFields: boolean = true; @observable openLayout: boolean = true; @@ -76,7 +76,7 @@ export class PropertiesView extends React.Component { @observable openAddSlide: boolean = false; @observable openSlideOptions: boolean = false; - @observable inActions: boolean = false; + @observable inOptions: boolean = false; @observable _controlBtn: boolean = false; @observable _lock: boolean = false; @@ -177,7 +177,7 @@ export class PropertiesView extends React.Component { doc && Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key)); const rows: JSX.Element[] = []; const noviceReqFields = ["author", "creationDate"]; - const noviceLayoutFields = ["curPage"]; + const noviceLayoutFields = ["_curPage"]; const noviceKeys = [...Array.from(Object.keys(ids)).filter(key => key[0] === "#" || key.indexOf("lastModified") !== -1 || (key[0] === key[0].toUpperCase() && !key.startsWith("ACL") && key !== "UseCors")), ...noviceReqFields, ...noviceLayoutFields]; for (const key of noviceKeys.sort()) { @@ -843,17 +843,17 @@ export class PropertiesView extends React.Component {
{this.editableTitle}
-
runInAction(() => { this.inActions = true; })} - onPointerLeave={action(() => this.inActions = false)}> +
runInAction(() => { this.inOptions = true; })} + onPointerLeave={action(() => this.inOptions = false)}>
runInAction(() => { this.openActions = !this.openActions; })} - style={{ backgroundColor: this.openActions ? "black" : "" }}> - Actions + onPointerDown={() => runInAction(() => { this.openOptions = !this.openOptions; })} + style={{ backgroundColor: this.openOptions ? "black" : "" }}> + Options
- +
- {!this.openActions ? (null) : + {!this.openOptions ? (null) :
} diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 7b9a32dbe..0e3c4462c 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -171,11 +171,11 @@ export class AudioBox extends ViewBoxAnnotatableComponent this.dataDoc.duration = htmlEle.duration); DocListCast(this.dataDoc.links).map(l => { const { la1, linkTime } = this.getLinkData(l); - if (linkTime > NumCast(this.layoutDoc.currentTimecode) && linkTime < htmlEle.currentTime) { + if (linkTime > NumCast(this.layoutDoc._currentTimecode) && linkTime < htmlEle.currentTime) { Doc.linkFollowHighlight(la1); } }); - this.layoutDoc.currentTimecode = htmlEle.currentTime; + this.layoutDoc._currentTimecode = htmlEle.currentTime; } } @@ -225,7 +225,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent this._ele!.currentTime = this.layoutDoc.currentTimecode = toTimeline(e.clientX - rect.x), + () => this._ele!.currentTime = this.layoutDoc._currentTimecode = toTimeline(e.clientX - rect.x), emptyFunction); } @@ -465,7 +465,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent
-
{formatTime(Math.round(NumCast(this.layoutDoc.currentTimecode)))}
+
{formatTime(Math.round(NumCast(this.layoutDoc._currentTimecode)))}
: