From 4508b7feacd4ac1ea8145d3284527b523829606a Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Thu, 8 Oct 2020 13:53:31 +0530 Subject: fixes userlistcontents issue --- src/client/util/SharingManager.tsx | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index d2e25dc26..4aa8d74e4 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -76,7 +76,16 @@ export class SharingManager extends React.Component<{}> { @observable private showGroupOptions: boolean = false; // // whether to show groups as options when sharing (in the react-select component) 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 - @observable private myDocAcls: boolean = false; + @observable private myDocAcls: boolean = false; // whether the My Docs checkbox is selected or not + + // maps acl symbols to SharingPermissions + private AclMap = new Map([ + [AclPrivate, SharingPermissions.None], + [AclReadonly, SharingPermissions.View], + [AclAddonly, SharingPermissions.Add], + [AclEdit, SharingPermissions.Edit], + [AclAdmin, SharingPermissions.Admin] + ]); // private get linkVisible() { // return this.sharingDoc ? this.sharingDoc[PublicKey] !== SharingPermissions.None : false; @@ -368,20 +377,12 @@ export class SharingManager extends React.Component<{}> { } distributeOverCollection = (targetDoc?: Doc) => { - const AclMap = new Map([ - [AclPrivate, SharingPermissions.None], - [AclReadonly, SharingPermissions.View], - [AclAddonly, SharingPermissions.Add], - [AclEdit, SharingPermissions.Edit], - [AclAdmin, SharingPermissions.Admin] - ]); - const target = targetDoc || this.targetDoc!; const docs = SelectionManager.SelectedDocuments().length < 2 ? [target] : SelectionManager.SelectedDocuments().map(docView => docView.props.Document); docs.forEach(doc => { for (const [key, value] of Object.entries(doc[AclSym])) { - distributeAcls(key, AclMap.get(value)! as SharingPermissions, target); + distributeAcls(key, this.AclMap.get(value)! as SharingPermissions, target); } }); } @@ -442,7 +443,8 @@ export class SharingManager extends React.Component<{}> { const targetDoc = docs[0]; // tslint:disable-next-line: no-unnecessary-callback-wrapper - const admin = this.myDocAcls ? Boolean(docs.length) : docs.map(doc => GetEffectiveAcl(doc)).every(acl => acl === AclAdmin); // if the user has admin access to all selected docs + const effectiveAcls = docs.map(doc => GetEffectiveAcl(doc)); + const admin = this.myDocAcls ? Boolean(docs.length) : effectiveAcls.every(acl => acl === AclAdmin); // users in common between all docs const commonKeys = intersection(...docs.map(doc => this.layoutDocAcls ? doc?.[AclSym] && Object.keys(doc[AclSym]) : doc?.[DataSym]?.[AclSym] && Object.keys(doc[DataSym][AclSym]))); @@ -506,7 +508,7 @@ export class SharingManager extends React.Component<{}> { Me
- {targetDoc?.[`acl-${Doc.CurrentUserEmailNormalized}`]} + {effectiveAcls.every(acl => acl === effectiveAcls[0]) ? this.AclMap.get(effectiveAcls[0])! : "-multiple-"}
-- cgit v1.2.3-70-g09d2 From ae57452f05cca70a498e826fb3320bd2182ba88b Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Sat, 10 Oct 2020 21:54:20 +0530 Subject: some group fixes --- src/client/util/GroupManager.tsx | 20 ++++++++++++++------ src/client/util/SharingManager.tsx | 35 ++++++++++++++++++++++++++++------- 2 files changed, 42 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/client/util/GroupManager.tsx b/src/client/util/GroupManager.tsx index fb3342e68..3264b75f7 100644 --- a/src/client/util/GroupManager.tsx +++ b/src/client/util/GroupManager.tsx @@ -1,11 +1,11 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { action, computed, observable, runInAction } from "mobx"; +import { action, autorun, computed, Lambda, observable, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; import * as React from "react"; import Select from 'react-select'; import * as RequestPromise from "request-promise"; import { Doc, DocListCast, DocListCastAsync, Opt } from "../../fields/Doc"; -import { Cast, StrCast } from "../../fields/Types"; +import { StrCast } from "../../fields/Types"; import { setGroups } from "../../fields/util"; import { Utils } from "../../Utils"; import { DocServer } from "../DocServer"; @@ -34,10 +34,12 @@ export class GroupManager extends React.Component<{}> { @observable private createGroupModalOpen: boolean = false; private inputRef: React.RefObject = React.createRef(); // the ref for the input box. private createGroupButtonRef: React.RefObject = React.createRef(); // the ref for the group creation button - private currentUserGroups: string[] = []; // the list of groups the current user is a member of + private currentUserGroups: string[] = ["Public"]; // the list of groups the current user is a member of @observable private buttonColour: "#979797" | "black" = "#979797"; @observable private groupSort: "ascending" | "descending" | "none" = "none"; private populating: boolean = false; + private groupListener: Opt; + private observableAllGroups: Doc[] = observable([]); @@ -51,7 +53,11 @@ export class GroupManager extends React.Component<{}> { */ componentDidMount() { this.populateUsers(); - this.populateGroups(); + this.groupListener = autorun(this.populateGroups); + } + + componentWillUnmount() { + this.groupListener?.(); } /** @@ -77,13 +83,15 @@ export class GroupManager extends React.Component<{}> { * Populates the list of groups the current user is a member of and sets this list to be used in the GetEffectiveAcl in util.ts */ populateGroups = () => { + this.observableAllGroups.map(g => g.members); DocListCastAsync(this.GroupManagerDoc?.data).then(groups => { groups?.forEach(group => { const members: string[] = JSON.parse(StrCast(group.members)); - if (members.includes(Doc.CurrentUserEmail)) this.currentUserGroups.push(StrCast(group.groupName)); + if (members.includes(Doc.CurrentUserEmail) && this.currentUserGroups.indexOf(StrCast(group.groupName)) === -1) this.currentUserGroups.push(StrCast(group.groupName)); + if (this.observableAllGroups.indexOf(group) === -1) runInAction(() => this.observableAllGroups.push(group)); }); - this.currentUserGroups.push("Public"); setGroups(this.currentUserGroups); + console.log("populating groups"); }); } diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index 6c1ec6091..742811c18 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -4,7 +4,7 @@ import { observer } from "mobx-react"; import * as React from "react"; import Select from "react-select"; import * as RequestPromise from "request-promise"; -import { AclAdmin, AclPrivate, DataSym, Doc, DocListCast, Opt, AclSym, AclAddonly, AclEdit, AclReadonly } from "../../fields/Doc"; +import { AclAdmin, AclPrivate, DataSym, Doc, DocListCast, Opt, AclSym, AclAddonly, AclEdit, AclReadonly, DocListCastAsync } from "../../fields/Doc"; import { List } from "../../fields/List"; import { Cast, StrCast } from "../../fields/Types"; import { distributeAcls, GetEffectiveAcl, SharingPermissions, TraceMobx, normalizeEmail } from "../../fields/util"; @@ -145,9 +145,9 @@ export class SharingManager extends React.Component<{}> { }); return Promise.all(evaluating).then(() => { runInAction(() => { - for (let i = 0; i < sharingDocs.length; i++) { - if (!this.users.find(user => user.user.email === sharingDocs[i].user.email)) { - this.users.push(sharingDocs[i]); + for (const sharingDoc of sharingDocs) { + if (!this.users.find(user => user.user.email === sharingDoc.user.email)) { + this.users.push(sharingDoc); } } }); @@ -195,7 +195,21 @@ export 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.sharingDoc[storage])) === -1 && Doc.AddDocToList(user.sharingDoc, storage, doc)); + if (group.docsShared) { + DocListCastAsync(group.docsShared).then(async docs => { + if (docs) { + const memberDocs = await DocListCastAsync(user.sharingDoc[storage]); + memberDocs && docs.forEach(doc => { + const index = Doc.IndexOf(doc, memberDocs); + console.log(index); + console.log(doc); + index === -1 && (console.log(Doc.AddDocToList(user.sharingDoc, storage, doc))); + }); + } + + }); + // === -1 && Doc.AddDocToList(user.sharingDoc, storage, doc)); + } } /** @@ -225,9 +239,16 @@ export class SharingManager extends React.Component<{}> { const user: ValidatedUser = this.users.find(({ user: { email } }) => email === emailId)!; if (group.docsShared) { - DocListCast(group.docsShared).forEach(doc => { - Doc.IndexOf(doc, DocListCast(user.sharingDoc[storage])) !== -1 && Doc.RemoveDocFromList(user.sharingDoc, storage, doc); // remove the doc only if it is in the list + DocListCastAsync(group.docsShared).then(docs => { + docs?.forEach(doc => { + DocListCastAsync(user.sharingDoc[storage]).then(sharedDocs => { + sharedDocs && Doc.IndexOf(doc, sharedDocs) !== -1 && Doc.RemoveDocFromList(user.sharingDoc, storage, doc); + }); + }); }); + // DocListCast(group.docsShared).forEach(doc => { + // Doc.IndexOf(doc, DocListCast(user.sharingDoc[storage])) !== -1 && Doc.RemoveDocFromList(user.sharingDoc, storage, doc); // remove the doc only if it is in the list + // }); } } -- cgit v1.2.3-70-g09d2 From 3408a32172e4cf31c74e42609f26e1b508936b2c Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Wed, 25 Nov 2020 14:39:28 +0530 Subject: filter + bug? --- src/client/util/CurrentUserUtils.ts | 2 +- src/client/views/collections/CollectionTreeView.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index b6bf70528..99dfbaf1c 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1051,7 +1051,7 @@ export class CurrentUserUtils { await Docs.Prototypes.initialize(); const userDoc = Docs.newAccount ? new Doc(userDocumentId, true) : field as Doc; const updated = this.updateUserDocument(Doc.SetUserDoc(userDoc), sharingDocumentId, linkDatabaseId); - (await DocListCastAsync(Cast(Doc.UserDoc().myLinkDatabase, Doc, null).data))?.forEach(async link => { // make sure anchors are loaded to avoid incremental updates to computedFn's in LinkManager + (await DocListCastAsync(Cast(Doc.UserDoc().myLinkDatabase, Doc, null)?.data))?.forEach(async link => { // make sure anchors are loaded to avoid incremental updates to computedFn's in LinkManager const a1 = await Cast(link?.anchor1, Doc, null); const a2 = await Cast(link?.anchor2, Doc, null); }); diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 85bf76e6d..439384e08 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -219,12 +219,12 @@ export class CollectionTreeView extends CollectionSubView
this._mainEle && this._mainEle.scrollHeight > this._mainEle.clientHeight && e.stopPropagation()} onDrop={this.onTreeDrop} ref={this.createTreeDropTarget}> -- cgit v1.2.3-70-g09d2 From 58b850cf84e258933cfc075e58311cd122e5fd0d Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Thu, 26 Nov 2020 19:53:57 +0530 Subject: some sharing menu changes --- src/client/util/SharingManager.tsx | 59 ++++++++++++++++++---------- src/client/views/nodes/DocumentView.scss | 66 +++++++++++++++++++++++--------- src/client/views/nodes/DocumentView.tsx | 22 +++++++++-- 3 files changed, 105 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index 53a6b2587..c4285ee30 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -6,7 +6,7 @@ import Select from "react-select"; import * as RequestPromise from "request-promise"; import { AclAdmin, AclPrivate, DataSym, Doc, DocListCast, Opt, AclSym, AclAddonly, AclEdit, AclReadonly, DocListCastAsync } from "../../fields/Doc"; import { List } from "../../fields/List"; -import { Cast, StrCast } from "../../fields/Types"; +import { Cast, NumCast, StrCast } from "../../fields/Types"; import { distributeAcls, GetEffectiveAcl, SharingPermissions, TraceMobx, normalizeEmail } from "../../fields/util"; import { Utils } from "../../Utils"; import { DocServer } from "../DocServer"; @@ -164,6 +164,35 @@ export class SharingManager extends React.Component<{}> { } } + /** + * Shares the document with a user. + */ + setInternalSharing = (recipient: ValidatedUser, permission: string, targetDoc?: Doc) => { + const { user, sharingDoc } = recipient; + const target = targetDoc || this.targetDoc!; + const acl = `acl-${normalizeEmail(user.email)}`; + const myAcl = `acl-${Doc.CurrentUserEmailNormalized}`; + + const docs = SelectionManager.SelectedDocuments().length < 2 ? [target] : SelectionManager.SelectedDocuments().map(docView => docView.props.Document); + docs.forEach(doc => { + doc.author === Doc.CurrentUserEmail && !doc[myAcl] && distributeAcls(myAcl, SharingPermissions.Admin, doc); + + if (permission === SharingPermissions.None) { + if (doc[acl] && doc[acl] !== SharingPermissions.None) doc.numUsersShared = NumCast(doc.numUsersShared, 1) - 1; + } + else { + if (!doc[acl] || doc[acl] === SharingPermissions.None) doc.numUsersShared = NumCast(doc.numUsersShared, 0) + 1; + } + + console.log(doc.numUsersShared); + + distributeAcls(acl, permission as SharingPermissions, doc); + + if (permission !== SharingPermissions.None) Doc.AddDocToList(sharingDoc, storage, doc); + else GetEffectiveAcl(doc, user.email) === AclPrivate && Doc.RemoveDocFromList(sharingDoc, storage, (doc.aliasOf as Doc || doc)); + }); + } + /** * Sets the permission on the target for the group. * @param group @@ -179,6 +208,15 @@ export class SharingManager extends React.Component<{}> { docs.forEach(doc => { doc.author === Doc.CurrentUserEmail && !doc[`acl-${Doc.CurrentUserEmailNormalized}`] && distributeAcls(`acl-${Doc.CurrentUserEmailNormalized}`, SharingPermissions.Admin, doc); + + if (permission === SharingPermissions.None) { + if (doc[acl] && doc[acl] !== SharingPermissions.None) doc.numGroupsShared = NumCast(doc.numGroupsShared, 1) - 1; + } + else { + if (!doc[acl] || doc[acl] === SharingPermissions.None) doc.numGroupsShared = NumCast(doc.numGroupsShared, 0) + 1; + } + + console.log(doc.numGroupsShared); distributeAcls(acl, permission as SharingPermissions, doc); if (group instanceof Doc) { @@ -271,25 +309,6 @@ export class SharingManager extends React.Component<{}> { } } - /** - * Shares the document with a user. - */ - setInternalSharing = (recipient: ValidatedUser, permission: string, targetDoc?: Doc) => { - const { user, sharingDoc } = recipient; - const target = targetDoc || this.targetDoc!; - const acl = `acl-${normalizeEmail(user.email)}`; - const myAcl = `acl-${Doc.CurrentUserEmailNormalized}`; - - const docs = SelectionManager.SelectedDocuments().length < 2 ? [target] : SelectionManager.SelectedDocuments().map(docView => docView.props.Document); - docs.forEach(doc => { - doc.author === Doc.CurrentUserEmail && !doc[myAcl] && distributeAcls(myAcl, SharingPermissions.Admin, doc); - distributeAcls(acl, permission as SharingPermissions, doc); - - if (permission !== SharingPermissions.None) Doc.AddDocToList(sharingDoc, storage, doc); - else GetEffectiveAcl(doc, user.email) === AclPrivate && Doc.RemoveDocFromList(sharingDoc, storage, (doc.aliasOf as Doc || doc)); - }); - } - // private setExternalSharing = (permission: string) => { // const sharingDoc = this.sharingDoc; diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss index ad72250b6..3cbf88839 100644 --- a/src/client/views/nodes/DocumentView.scss +++ b/src/client/views/nodes/DocumentView.scss @@ -34,14 +34,16 @@ overflow-y: scroll; height: calc(100% - 20px); } + .documentView-linkAnchorBoxAnchor { - display:flex; + display: flex; overflow: hidden; .documentView-node { - width:10px !important; + width: 10px !important; } } + .documentView-treeView { max-height: 1.5em; text-overflow: ellipsis; @@ -49,7 +51,8 @@ white-space: pre; width: 100%; overflow: hidden; - > .documentView-node { + + >.documentView-node { position: absolute; } } @@ -58,23 +61,42 @@ border-radius: inherit; width: 100%; height: 100%; + + .sharingIndicator { + height: 30px; + width: 30px; + border-radius: 50%; + position: absolute; + right: -15; + opacity: 0.9; + pointer-events: auto; + background-color: #9dca96; + letter-spacing: 2px; + font-size: 10px; + transition: transform 0.2s; + text-align: center; + display: flex; + justify-content: center; + align-items: center; + cursor: pointer; + } } .documentView-anchorCont { position: absolute; - top: 0; - left: 0; + top: 0; + left: 0; width: 100%; - height: 100%; + height: 100%; display: inline-block; pointer-events: none; } .documentView-lock { - width: 20; - height: 20; - position: absolute; - right: -5; + width: 20; + height: 20; + position: absolute; + right: -5; top: -5; background: transparent; pointer-events: all; @@ -85,8 +107,9 @@ justify-content: center; cursor: default; } + .documentView-lock:hover { - opacity:1; + opacity: 1; } .documentView-contentBlocker { @@ -97,6 +120,7 @@ top: 0; left: 0; } + .documentView-styleWrapper { position: absolute; display: inline-block; @@ -110,7 +134,8 @@ position: absolute; } - .documentView-titleWrapper, .documentView-titleWrapper-hover { + .documentView-titleWrapper, + .documentView-titleWrapper-hover { overflow: hidden; color: white; transform-origin: top left; @@ -123,8 +148,9 @@ white-space: pre; position: absolute; } + .documentView-titleWrapper-hover { - display:none; + display: none; } .documentView-searchHighlight { @@ -147,14 +173,16 @@ } -.documentView-node:hover, .documentView-node-topmost:hover { - > .documentView-styleWrapper { - > .documentView-titleWrapper-hover { - display:inline-block; +.documentView-node:hover, +.documentView-node-topmost:hover { + >.documentView-styleWrapper { + >.documentView-titleWrapper-hover { + display: inline-block; } } - > .documentView-styleWrapper { - > .documentView-captionWrapper { + + >.documentView-styleWrapper { + >.documentView-captionWrapper { opacity: 1; } } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index e8fcf027e..18ebb569a 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -9,7 +9,7 @@ import { RichTextField } from '../../../fields/RichTextField'; import { listSpec } from "../../../fields/Schema"; import { ScriptField } from '../../../fields/ScriptField'; import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Types"; -import { GetEffectiveAcl, TraceMobx } from '../../../fields/util'; +import { GetEffectiveAcl, SharingPermissions, TraceMobx } from '../../../fields/util'; import { MobileInterface } from '../../../mobile/MobileInterface'; import { GestureUtils } from '../../../pen-gestures/GestureUtils'; import { emptyFunction, OmitKeys, returnOne, returnTransparent, returnVal, Utils, returnFalse } from "../../../Utils"; @@ -42,6 +42,7 @@ import { RadialMenu } from './RadialMenu'; import { TaskCompletionBox } from './TaskCompletedBox'; import React = require("react"); import { List } from '../../../fields/List'; +import { Tooltip } from '@material-ui/core'; export type DocAfterFocusFunc = (notFocused: boolean) => boolean; export type DocFocusFunc = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc, dontCenter?: boolean, focused?: boolean) => void; @@ -675,7 +676,7 @@ export class DocumentView extends DocComponent(Docu if ((e.target as any)?.closest?.("*.lm_content")) { alert("You can't perform this move most likely because you don't have permission to modify the destination."); } - else alert("linking to document tabs not yet supported. Drop link on document content."); + else alert("Linking to document tabs not yet supported. Drop link on document content."); return; } const makeLink = action((linkDoc: Doc) => { @@ -960,10 +961,25 @@ export class DocumentView extends DocComponent(Docu {/* {this.allAnchors} */} {this.props.forcedBackgroundColor?.(this.Document) === "transparent" || (!this.isSelected() && (this.layoutDoc.isLinkButton || this.layoutDoc.hideLinkButton)) || this.props.dontRegisterView ? (null) : } -
+ + {!this.props.Document.numUsersShared && !this.props.Document.numGroupsShared ? (null) : +
Tap to open sharing menu
}> +
SharingManager.Instance.open(undefined, this.props.Document)}> + +
+
+ + } + ); } + get indicatorIcon() { + if (this.props.Document["acl-Public"] !== SharingPermissions.None) return "globe-americas"; + else if (this.props.Document.numGroupsShared || NumCast(this.props.Document.numUsersShared, 0) > 1) return "users"; + else return "user"; + } + // used to decide whether a link anchor view should be created or not. // if it's a temporal link (currently just for Audio), then the audioBox will display the anchor and we don't want to display it here. // would be good to generalize this some way. -- cgit v1.2.3-70-g09d2 From 1f9baca276426444a4ebea06023402876f033ebe Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Fri, 27 Nov 2020 19:07:43 +0530 Subject: removed override --- src/client/util/SharingManager.tsx | 13 +++++-------- src/client/views/PropertiesView.tsx | 6 +++--- 2 files changed, 8 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index c4285ee30..fcd10406d 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -184,8 +184,6 @@ export class SharingManager extends React.Component<{}> { if (!doc[acl] || doc[acl] === SharingPermissions.None) doc.numUsersShared = NumCast(doc.numUsersShared, 0) + 1; } - console.log(doc.numUsersShared); - distributeAcls(acl, permission as SharingPermissions, doc); if (permission !== SharingPermissions.None) Doc.AddDocToList(sharingDoc, storage, doc); @@ -216,7 +214,6 @@ export class SharingManager extends React.Component<{}> { if (!doc[acl] || doc[acl] === SharingPermissions.None) doc.numGroupsShared = NumCast(doc.numGroupsShared, 0) + 1; } - console.log(doc.numGroupsShared); distributeAcls(acl, permission as SharingPermissions, doc); if (group instanceof Doc) { @@ -566,7 +563,7 @@ export class SharingManager extends React.Component<{}> { // the list of groups shared with const groupListMap: (Doc | { title: string })[] = groups.filter(({ title }) => docs.length > 1 ? commonKeys.includes(`acl-${normalizeEmail(StrCast(title))}`) : true); - groupListMap.unshift({ title: "Public" }, { title: "Override" }); + groupListMap.unshift({ title: "Public" });//, { title: "Override" }); const groupListContents = groupListMap.map(group => { const groupKey = `acl-${StrCast(group.title)}`; const uniform = docs.every(doc => this.layoutDocAcls ? doc?.[AclSym]?.[groupKey] === docs[0]?.[AclSym]?.[groupKey] : doc?.[DataSym]?.[AclSym]?.[groupKey] === docs[0]?.[DataSym]?.[AclSym]?.[groupKey]); @@ -644,16 +641,16 @@ export class SharingManager extends React.Component<{}> {
-
+ {/*
this.myDocAcls = !this.myDocAcls)} checked={this.myDocAcls} /> -
+
*/} {Doc.UserDoc().noviceMode ? (null) :
this.layoutDocAcls = !this.layoutDocAcls)} checked={this.layoutDocAcls} />
} - + */}
} diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 245e612b3..db9475afd 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -416,7 +416,7 @@ export class PropertiesView extends React.Component { const ownerSame = Doc.CurrentUserEmail !== target.author && docs.filter(doc => doc).every(doc => doc.author === docs[0].author); // shifts the current user, owner, public to the top of the doc. - tableEntries.unshift(this.sharingItem("Override", showAdmin, docs.filter(doc => doc).every(doc => doc["acl-Override"] === docs[0]["acl-Override"]) ? (AclMap.get(target[AclSym]?.["acl-Override"]) || "None") : "-multiple-")); + // tableEntries.unshift(this.sharingItem("Override", showAdmin, docs.filter(doc => doc).every(doc => doc["acl-Override"] === docs[0]["acl-Override"]) ? (AclMap.get(target[AclSym]?.["acl-Override"]) || "None") : "-multiple-")); tableEntries.unshift(this.sharingItem("Public", showAdmin, docs.filter(doc => doc).every(doc => doc["acl-Public"] === docs[0]["acl-Public"]) ? (AclMap.get(target[AclSym]?.["acl-Public"]) || SharingPermissions.None) : "-multiple-")); tableEntries.unshift(this.sharingItem("Me", showAdmin, docs.filter(doc => doc).every(doc => doc.author === Doc.CurrentUserEmail) ? "Owner" : effectiveAcls.every(acl => acl === effectiveAcls[0]) ? AclMap.get(effectiveAcls[0])! : "-multiple-", !ownerSame)); if (ownerSame) tableEntries.unshift(this.sharingItem(StrCast(target.author), showAdmin, "Owner")); @@ -900,11 +900,11 @@ export class PropertiesView extends React.Component { />
Layout
) : (null)} -
{"Re-distribute sharing settings"}
}> + {/*
{"Re-distribute sharing settings"}
}> -
+
*/} {this.sharingTable} } -- cgit v1.2.3-70-g09d2 From 92c0f12098866a0e1936a74e9e50a9c0c5c1ad27 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Thu, 3 Dec 2020 17:13:16 +0530 Subject: greyed out sharing indicator --- src/client/views/nodes/DocumentView.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 79ee0291d..514130c3d 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -964,7 +964,10 @@ export class DocumentView extends DocComponent(Docu {!this.props.Document.numUsersShared && !this.props.Document.numGroupsShared ? (null) :
Tap to open sharing menu
}> -
SharingManager.Instance.open(undefined, this.props.Document)}> +
SharingManager.Instance.open(undefined, this.props.Document)} + style={{ backgroundColor: GetEffectiveAcl(this.props.Document[DataSym]) === AclAdmin ? "#9dca96" : "lightgrey" }} + >
-- cgit v1.2.3-70-g09d2 From 1e3e178ca1c54bb43ba22dcfecaf338adc4abc54 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Fri, 18 Dec 2020 11:56:40 +0530 Subject: added something that was removed --- src/client/util/GroupManager.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/util/GroupManager.tsx b/src/client/util/GroupManager.tsx index a9059ff3d..48676a393 100644 --- a/src/client/util/GroupManager.tsx +++ b/src/client/util/GroupManager.tsx @@ -1,5 +1,5 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { action, autorun, computed, Lambda, observable, reaction, runInAction } from "mobx"; +import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; import * as React from "react"; import Select from 'react-select'; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index e40b23ea5..02bfa65aa 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -42,6 +42,7 @@ import { RadialMenu } from './RadialMenu'; import React = require("react"); import { List } from '../../../fields/List'; import { Tooltip } from '@material-ui/core'; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; export type DocAfterFocusFunc = (notFocused: boolean) => boolean; export type DocFocusFunc = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc, dontCenter?: boolean, focused?: boolean) => void; @@ -714,6 +715,16 @@ export class DocumentViewInternal extends DocComponent} + {!this.props.Document.numUsersShared && !this.props.Document.numGroupsShared ? (null) : +
Tap to open sharing menu
}> +
SharingManager.Instance.open(undefined, this.props.Document)} + style={{ backgroundColor: GetEffectiveAcl(this.props.Document[DataSym]) === AclAdmin ? "#9dca96" : "lightgrey" }} + > + +
+
+ }
; } -- cgit v1.2.3-70-g09d2 From 45dee9388ad4f5c3c70df3a5ff1852c6bd41dec0 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Sun, 20 Dec 2020 01:23:44 +0530 Subject: added settings manager to esc key handler --- src/client/util/SharingManager.tsx | 44 +++++++++++----------- src/client/views/GlobalKeyHandler.ts | 2 + .../views/collections/CollectionTreeView.tsx | 4 +- 3 files changed, 26 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index 8c36a7f3c..f1fe7c22f 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -7,7 +7,7 @@ import Select from "react-select"; import * as RequestPromise from "request-promise"; import { AclAddonly, AclAdmin, AclEdit, AclPrivate, AclReadonly, AclSym, DataSym, Doc, DocListCast, DocListCastAsync, Opt } from "../../fields/Doc"; import { List } from "../../fields/List"; -import { Cast, StrCast } from "../../fields/Types"; +import { Cast, NumCast, StrCast } from "../../fields/Types"; import { distributeAcls, GetEffectiveAcl, normalizeEmail, SharingPermissions, TraceMobx } from "../../fields/util"; import { Utils } from "../../Utils"; import { DocServer } from "../DocServer"; @@ -173,7 +173,7 @@ export class SharingManager extends React.Component<{}> { const acl = `acl-${normalizeEmail(user.email)}`; const myAcl = `acl-${Doc.CurrentUserEmailNormalized}`; - const docs = SelectionManager.SelectedDocuments().length < 2 ? [target] : SelectionManager.SelectedDocuments().map(docView => docView.props.Document); + const docs = SelectionManager.Views().length < 2 ? [target] : SelectionManager.Views().map(docView => docView.props.Document); docs.forEach(doc => { doc.author === Doc.CurrentUserEmail && !doc[myAcl] && distributeAcls(myAcl, SharingPermissions.Admin, doc); @@ -309,21 +309,21 @@ export class SharingManager extends React.Component<{}> { /** * Shares the document with a user. */ - setInternalSharing = (recipient: ValidatedUser, permission: string, targetDoc?: Doc) => { - const { user, sharingDoc } = recipient; - const target = targetDoc || this.targetDoc!; - const acl = `acl-${normalizeEmail(user.email)}`; - const myAcl = `acl-${Doc.CurrentUserEmailNormalized}`; - - const docs = SelectionManager.Views().length < 2 ? [target] : SelectionManager.Views().map(docView => docView.props.Document); - docs.forEach(doc => { - doc.author === Doc.CurrentUserEmail && !doc[myAcl] && distributeAcls(myAcl, SharingPermissions.Admin, doc); - distributeAcls(acl, permission as SharingPermissions, doc); - - if (permission !== SharingPermissions.None) Doc.AddDocToList(sharingDoc, storage, doc); - else GetEffectiveAcl(doc, user.email) === AclPrivate && Doc.RemoveDocFromList(sharingDoc, storage, (doc.aliasOf as Doc || doc)); - }); - } + // setInternalSharing = (recipient: ValidatedUser, permission: string, targetDoc?: Doc) => { + // const { user, sharingDoc } = recipient; + // const target = targetDoc || this.targetDoc!; + // const acl = `acl-${normalizeEmail(user.email)}`; + // const myAcl = `acl-${Doc.CurrentUserEmailNormalized}`; + + // const docs = SelectionManager.Views().length < 2 ? [target] : SelectionManager.Views().map(docView => docView.props.Document); + // docs.forEach(doc => { + // doc.author === Doc.CurrentUserEmail && !doc[myAcl] && distributeAcls(myAcl, SharingPermissions.Admin, doc); + // distributeAcls(acl, permission as SharingPermissions, doc); + + // if (permission !== SharingPermissions.None) Doc.AddDocToList(sharingDoc, storage, doc); + // else GetEffectiveAcl(doc, user.email) === AclPrivate && Doc.RemoveDocFromList(sharingDoc, storage, (doc.aliasOf as Doc || doc)); + // }); + // } // private setExternalSharing = (permission: string) => { @@ -357,11 +357,11 @@ export class SharingManager extends React.Component<{}> { if (!uniform) dropdownValues.unshift("-multiple-"); if (override) dropdownValues.unshift("None"); return dropdownValues.filter(permission => permission !== SharingPermissions.View).map(permission => - ( - - ) + ( + + ) ); } diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts index c38842c4f..26dc0071c 100644 --- a/src/client/views/GlobalKeyHandler.ts +++ b/src/client/views/GlobalKeyHandler.ts @@ -27,6 +27,7 @@ import { SnappingManager } from "../util/SnappingManager"; import { SearchBox } from "./search/SearchBox"; import { random } from "lodash"; import { DocumentView } from "./nodes/DocumentView"; +import { SettingsManager } from "../util/SettingsManager"; const modifiers = ["control", "meta", "shift", "alt"]; type KeyHandler = (keycode: string, e: KeyboardEvent) => KeyControlInfo | Promise; @@ -128,6 +129,7 @@ export class KeyManager { DictationManager.Controls.stop(); GoogleAuthenticationManager.Instance.cancel(); SharingManager.Instance.close(); + if (!GroupManager.Instance.isOpen) SettingsManager.Instance.close(); GroupManager.Instance.close(); CollectionFreeFormViewChrome.Instance?.clearKeep(); window.getSelection()?.empty(); diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 18921e9e0..344a6c103 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -215,12 +215,12 @@ export class CollectionTreeView extends CollectionSubView
this._mainEle && this._mainEle.scrollHeight > this._mainEle.clientHeight && e.stopPropagation()} onDrop={this.onTreeDrop} ref={this.createTreeDropTarget}> -- cgit v1.2.3-70-g09d2 From b7296dc3bfb9ad0842a4c0298152f2023d47e1b3 Mon Sep 17 00:00:00 2001 From: anika Date: Sun, 27 Dec 2020 14:19:01 -0600 Subject: rough UI restructure --- src/client/views/MainView.tsx | 2 +- src/client/views/nodes/FilterBox.scss | 128 ++++++++++++++++++++++++++++++---- src/client/views/nodes/FilterBox.tsx | 97 +++++++++++++++++++++++--- 3 files changed, 206 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 5eb8429f0..b05346d4c 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -163,7 +163,7 @@ export class MainView extends React.Component { fa.faWindowMinimize, fa.faWindowRestore, fa.faTextWidth, fa.faTextHeight, fa.faClosedCaptioning, fa.faInfoCircle, fa.faTag, fa.faSyncAlt, fa.faPhotoVideo, fa.faArrowAltCircleDown, fa.faArrowAltCircleUp, fa.faArrowAltCircleLeft, fa.faArrowAltCircleRight, fa.faStopCircle, fa.faCheckCircle, fa.faGripVertical, fa.faSortUp, fa.faSortDown, fa.faTable, fa.faTh, fa.faThList, fa.faProjectDiagram, fa.faSignature, fa.faColumns, fa.faChevronCircleUp, fa.faUpload, fa.faBorderAll, - fa.faBraille, fa.faChalkboard, fa.faPencilAlt, fa.faEyeSlash, fa.faSmile, fa.faIndent, fa.faOutdent, fa.faChartBar, fa.faBan, fa.faPhoneSlash, fa.faGripLines); + fa.faBraille, fa.faChalkboard, fa.faPencilAlt, fa.faEyeSlash, fa.faSmile, fa.faIndent, fa.faOutdent, fa.faChartBar, fa.faBan, fa.faPhoneSlash, fa.faGripLines, fa.faBookmark); this.initAuthenticationRouters(); } diff --git a/src/client/views/nodes/FilterBox.scss b/src/client/views/nodes/FilterBox.scss index d32cc0d2b..9843c4b1c 100644 --- a/src/client/views/nodes/FilterBox.scss +++ b/src/client/views/nodes/FilterBox.scss @@ -1,17 +1,124 @@ - - .filterBox-flyout { - width: 400px; display: block; text-align: left; + .filterBox-flyout-facet { - background-color: lightgray; - text-align: left; - display: inline-block; - position: relative; - width: 100%; + background-color: lightgray; + text-align: left; + display: inline-block; + position: relative; + width: 100%; + } +} + + +.filter-bookmark { + //display: flex; + + .filter-bookmark-icon { + float: right; + margin-right: 10px; + margin-top: 7px; + } +} + + +.filterBox-saveBookmark { + width: 105px; + background-color: rgb(216, 214, 214); + border-radius: 6px; + padding: 5px; + margin: 5px; + display: flex; + font-size: 17px; + + &:hover { + background-color: white; + } + + .filterBox-saveBookmark-icon { + margin-right: 10px; + margin-top: 4px; + margin-left: 10px; } + } + +.filterBox-title { + + justify-content: center; + text-align: center; + padding-bottom: 13px; + font-size: 20px; + font-weight: bold; + + .filterBox-span { + margin-right: 15px; + } + +} + +.filterBox-select-scope, +.filterBox-select-bool, +.filterBox-addWrapper, +.filterBox-select-matched, +.filterBox-saveWrapper { + font-size: 12px; + justify-content: center; + justify-items: center; + padding-bottom: 10px; + display: flex; +} + +.filterBox-addWrapper { + font-size: 15px; + width: 100%; +} + +.filterBox-saveWrapper { + width: 100%; +} + +.filterBox-select-scope { + margin-bottom: 5px; + // border-bottom: 1px solid black; +} + +.filterBox-select-text { + margin-right: 8px; + margin-left: 8px; +} + +.filterBox-select-box { + margin-right: 2px; + font-size: 30px; + border: none; +} + +.filterBox-selection { + border-radius: 6px; + border: none; + background-color: rgb(216, 214, 214); + padding: 2px; + + &:hover { + background-color: white; + } +} + +.filterBox-addFilter { + width: 100px; + background-color: rgb(216, 214, 214); + border-radius: 6px; + padding: 5px; + margin: 5px; + display: flex; + + &:hover { + background-color: white; + } +} + .filterBox-treeView { display: flex; flex-direction: column; @@ -22,6 +129,7 @@ top: 0; border-left: solid 1px; z-index: 1; + background-color: darkGray; .filterBox-addfacet { display: inline-block; @@ -34,10 +142,6 @@ display: flex; margin: auto; cursor: pointer; - - .filterBox-span { - margin-right: 15px; - } } >div, diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index 730ae8f10..7c03b0835 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -1,6 +1,6 @@ import React = require("react"); import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { computed } from "mobx"; +import { action, computed } from "mobx"; import { observer } from "mobx-react"; import { DataSym, Doc, DocListCast, Field, Opt } from "../../../fields/Doc"; import { documentSchema } from "../../../fields/documentSchemas"; @@ -20,6 +20,7 @@ import { FieldView, FieldViewProps } from './FieldView'; import './FilterBox.scss'; import { Scripting } from "../../util/Scripting"; import { values } from "lodash"; +import { tokenToString } from "typescript"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -31,6 +32,11 @@ const FilterBoxDocument = makeInterface(documentSchema); export class FilterBox extends ViewBoxBaseComponent(FilterBoxDocument) { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(FilterBox, fieldKey); } + public _filterBoolean = "AND"; + public _filterScope = "Current Dashboard"; + public _filterSelected = false; + public _filterMatch = "matched"; + @computed get allDocs() { const allDocs = new Set(); if (CollectionDockingView.Instance) { @@ -159,6 +165,37 @@ export class FilterBox extends ViewBoxBaseComponent script : undefined; } + @action + changeBool = (e: any) => { + this._filterBoolean = e.currentTarget.value; + console.log(this._filterBoolean); + } + + @action + changeScope = (e: any) => { + this._filterScope = e.currentTarget.value; + console.log(this._filterScope); + } + + @action + changeMatch = (e: any) => { + this._filterMatch = e.currentTarget.value; + console.log(this._filterMatch); + } + + + @action + changeSelected = (e: any) => { + if (this._filterSelected) { + this._filterSelected = false; + // helper method to deselect all documents + } else { + this._filterSelected = true; + // helper method to select specified docs + } + console.log(this._filterSelected); + } + render() { const facetCollection = this.props.Document; const flyout =
e.stopPropagation()}> @@ -170,14 +207,35 @@ export class FilterBox extends ViewBoxBaseComponent; return this.props.dontRegisterView ? (null) :
-
e.stopPropagation()}> - -
- - Choose Facets -
-
+
+
+ + {/*
e.stopPropagation()}> +
*/} +
+ Choose Filters +
+ {/*
+
*/} + +
+ +
specified filters
+
+ +
+
Scope:
+ +
+
+ +
+
+ add a filter
+
+
+ +
+ this.changeSelected(e)} /> +
select
+ +
documents
+
+ +
+
+ +
SAVE
+
+
; } } -- cgit v1.2.3-70-g09d2 From 4c572c61dabf9032853019a9287ddf5f1dd5863b Mon Sep 17 00:00:00 2001 From: anika Date: Mon, 28 Dec 2020 20:14:48 -0600 Subject: finishing overall structure of the UI --- src/client/views/nodes/FilterBox.scss | 29 ++++++++++++++------ src/client/views/nodes/FilterBox.tsx | 50 +++++++++++++++++++++-------------- 2 files changed, 51 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/FilterBox.scss b/src/client/views/nodes/FilterBox.scss index 9843c4b1c..62f972218 100644 --- a/src/client/views/nodes/FilterBox.scss +++ b/src/client/views/nodes/FilterBox.scss @@ -22,10 +22,16 @@ } } +.filterBox-bottom { + position: fixed; + bottom: 0; + width: 100%; +} + .filterBox-saveBookmark { width: 105px; - background-color: rgb(216, 214, 214); + background-color: #f5f5f5; border-radius: 6px; padding: 5px; margin: 5px; @@ -79,9 +85,17 @@ width: 100%; } +// .filterBox-top { +// padding-bottom: 20px; +// border-bottom: 2px solid black; +// position: fixed; +// top: 0; +// width: 100%; +// } + .filterBox-select-scope { - margin-bottom: 5px; - // border-bottom: 1px solid black; + padding-bottom: 20px; + border-bottom: 2px solid black; } .filterBox-select-text { @@ -98,7 +112,7 @@ .filterBox-selection { border-radius: 6px; border: none; - background-color: rgb(216, 214, 214); + background-color: #f5f5f5; padding: 2px; &:hover { @@ -108,7 +122,7 @@ .filterBox-addFilter { width: 100px; - background-color: rgb(216, 214, 214); + background-color: #f5f5f5; border-radius: 6px; padding: 5px; margin: 5px; @@ -129,13 +143,12 @@ top: 0; border-left: solid 1px; z-index: 1; - background-color: darkGray; + background-color: #D3D3D3; .filterBox-addfacet { display: inline-block; width: 200px; height: 30px; - background: darkGray; text-align: left; .filterBox-addFacetButton { @@ -154,6 +167,6 @@ .filterBox-tree { display: inline-block; width: 100%; - height: calc(100% - 30px); + //height: calc(100% - 30px); } } \ No newline at end of file diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index 7c03b0835..95ffc6f8c 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -21,6 +21,7 @@ import './FilterBox.scss'; import { Scripting } from "../../util/Scripting"; import { values } from "lodash"; import { tokenToString } from "typescript"; +import { SelectionManager } from "../../util/SelectionManager"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -158,7 +159,7 @@ export class FilterBox extends ViewBoxBaseComponent "rgba(105, 105, 105, 0.432)"; + filterBackground = () => "#d3d3d3"; @computed get scriptField() { const scriptText = "setDocFilter(this?.target, heading, this.title, checked)"; const script = ScriptField.MakeScript(scriptText, { this: Doc.name, heading: "string", checked: "string", containingTreeView: Doc.name }); @@ -188,7 +189,7 @@ export class FilterBox extends ViewBoxBaseComponent { if (this._filterSelected) { this._filterSelected = false; - // helper method to deselect all documents + SelectionManager.DeselectAll(); } else { this._filterSelected = true; // helper method to select specified docs @@ -206,18 +207,24 @@ export class FilterBox extends ViewBoxBaseComponent)}
; + const newFlyout =
e.stopPropagation()}> + {this._allFacets.map(facet => )} +
+ return this.props.dontRegisterView ? (null) :
+ + {/*
*/}
- {/*
e.stopPropagation()}> -
*/}
Choose Filters
- {/*
-
*/}
+ {/*
*/}
-
- this.changeSelected(e)} /> -
select
- -
documents
-
+
+
+ this.changeSelected(e)} /> +
select
+ +
documents
+
-
-
- -
SAVE
+
+
+ +
SAVE
+
; -- cgit v1.2.3-70-g09d2 From 6b211be7c96a3d7f275509d094d9e96dd6dff6ba Mon Sep 17 00:00:00 2001 From: anika Date: Mon, 28 Dec 2020 22:01:58 -0600 Subject: more cleaning --- src/client/views/collections/TreeView.scss | 22 ++++++++++++++++++---- src/client/views/nodes/FilterBox.scss | 6 ++++-- src/client/views/nodes/FilterBox.tsx | 4 ++-- 3 files changed, 24 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/TreeView.scss b/src/client/views/collections/TreeView.scss index 7a654c7cf..7a719b4a4 100644 --- a/src/client/views/collections/TreeView.scss +++ b/src/client/views/collections/TreeView.scss @@ -8,6 +8,7 @@ width: 100%; overflow: hidden; } + .treeView-container, .treeView-container-active { .bullet-outline { @@ -20,21 +21,26 @@ .treeView-bulletIcons { width: 15px; + .treeView-expandIcon { display: none; left: -10px; position: absolute; } + .treeView-checkIcon { - left: -10px; + left: 3px; + top: 2px; position: absolute; } + &:hover { .treeView-expandIcon { display: unset; } } } + .bullet { position: relative; width: $TREE_BULLET_WIDTH; @@ -45,9 +51,11 @@ border-radius: 4px; } } + .treeView-container-active { z-index: 100; position: relative; + .formattedTextbox-sidebar { background-color: #ffff001f !important; height: 500px !important; @@ -70,7 +78,8 @@ display: flex; overflow: hidden; } -.treeView-border{ + +.treeView-border { border-left: dashed 1px #00000042; } @@ -78,15 +87,20 @@ .treeView-header { border: transparent 1px solid; display: flex; + //align-items: center; ::-webkit-scrollbar { - display: none; + display: none; } + .formattedTextBox-cont { - .formattedTextbox-sidebar, .formattedTextbox-sidebar-inking { + + .formattedTextbox-sidebar, + .formattedTextbox-sidebar-inking { overflow: visible !important; border-left: unset; } + overflow: visible !important; } diff --git a/src/client/views/nodes/FilterBox.scss b/src/client/views/nodes/FilterBox.scss index 62f972218..6d72af679 100644 --- a/src/client/views/nodes/FilterBox.scss +++ b/src/client/views/nodes/FilterBox.scss @@ -3,7 +3,7 @@ text-align: left; .filterBox-flyout-facet { - background-color: lightgray; + background-color: white; text-align: left; display: inline-block; position: relative; @@ -106,7 +106,8 @@ .filterBox-select-box { margin-right: 2px; font-size: 30px; - border: none; + border: 0; + background: transparent; } .filterBox-selection { @@ -167,6 +168,7 @@ .filterBox-tree { display: inline-block; width: 100%; + margin-bottom: 10px; //height: calc(100% - 30px); } } \ No newline at end of file diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index 95ffc6f8c..dec6f67d8 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -207,7 +207,7 @@ export class FilterBox extends ViewBoxBaseComponent)}
; - const newFlyout =
e.stopPropagation()}> + const newFlyout =
e.stopPropagation()}> {this._allFacets.map(facet =>
- +
+ add a filter
-- cgit v1.2.3-70-g09d2 From 7174328702fe6b350780728db890141f50ceec5b Mon Sep 17 00:00:00 2001 From: anika Date: Thu, 31 Dec 2020 10:29:20 -0600 Subject: last add b efore pull --- src/client/views/StyleProvider.tsx | 6 ++++++ src/client/views/collections/TreeView.tsx | 6 +++++- src/client/views/nodes/FilterBox.scss | 5 +++++ src/client/views/nodes/FilterBox.tsx | 14 +++----------- 4 files changed, 19 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 312cfc73e..35fe30a56 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -23,6 +23,7 @@ export enum StyleLayers { } export enum StyleProp { + TreeViewIcon = "treeViewIcon", DocContents = "docContents", // when specified, the JSX returned will replace the normal rendering of the document view Opacity = "opacity", // opacity of the document view Hidden = "hidden", // whether the document view should not be isplayed @@ -64,11 +65,14 @@ export function DefaultStyleProvider(doc: Opt, props: Opt StrListCast(doc?.layers).includes(StyleLayers.Background); const backgroundCol = () => props?.styleProvider?.(doc, props, StyleProp.BackgroundColor); const opacity = () => props?.styleProvider?.(doc, props, StyleProp.Opacity); switch (property.split(":")[0]) { + case StyleProp.TreeViewIcon: return doc && Doc.toIcon(doc); case StyleProp.DocContents: return undefined; case StyleProp.WidgetColor: return darkScheme() ? "lightgrey" : "dimgrey"; case StyleProp.Opacity: return Cast(doc?._opacity, "number", Cast(doc?.opacity, "number", null)); @@ -152,6 +156,8 @@ export function DefaultStyleProvider(doc: Opt, props: Opt 0 && ((doc.type === DocumentType.COL && doc._viewType !== CollectionViewType.Pile) || [DocumentType.RTF, DocumentType.IMG, DocumentType.INK].includes(doc.type as DocumentType)) ? diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 93d3be1fc..b5e498503 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -441,7 +441,11 @@ export class TreeView extends React.Component { @computed get renderBullet() { TraceMobx(); - const iconType = Doc.toIcon(this.doc); + const iconType = this.titleStyleProvider?.(this.doc, this.props.treeView.props, StyleProp.TreeViewIcon); + + + // const footerDecoration = this.titleStyleProvider?.(this.doc, this.props.treeView.props, StyleProp.Decoration + ":footer"); + const checked = this.onCheckedClick ? (this.doc.treeViewChecked ?? "unchecked") : undefined; return
e.stopPropagation()}> + const flyout =
e.stopPropagation()}> {this._allFacets.map(facet => )}
; - const newFlyout =
e.stopPropagation()}> - {this._allFacets.map(facet => )} -
- return this.props.dontRegisterView ? (null) :
{/*
*/} @@ -279,7 +271,7 @@ export class FilterBox extends ViewBoxBaseComponent
- +
+ add a filter
-- cgit v1.2.3-70-g09d2 From a70a224d40ed511e8278ce01a74fb0a8a012b075 Mon Sep 17 00:00:00 2001 From: anika Date: Thu, 31 Dec 2020 11:32:41 -0600 Subject: small merge fixes --- src/client/views/MainView.tsx | 5 ++-- src/client/views/StyleProvider.tsx | 40 ++++++++++++++++++++++++++++++ src/client/views/collections/TreeView.scss | 21 +++++++++++----- src/client/views/collections/TreeView.tsx | 5 +++- 4 files changed, 62 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index e43b8baf1..d17b72639 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -44,6 +44,7 @@ import { KeyManager } from './GlobalKeyHandler'; import { InkStrokeProperties } from './InkStrokeProperties'; import { LinkMenu } from './linking/LinkMenu'; import "./MainView.scss"; +import "./collections/TreeView.scss"; import { AudioBox } from './nodes/AudioBox'; import { DocumentLinksButton } from './nodes/DocumentLinksButton'; import { DocumentView, DocumentViewProps } from './nodes/DocumentView'; @@ -58,7 +59,7 @@ import { PDFMenu } from './pdf/PDFMenu'; import { PreviewCursor } from './PreviewCursor'; import { PropertiesView } from './PropertiesView'; import { SearchBox } from './search/SearchBox'; -import { DefaultStyleProvider, StyleProp } from './StyleProvider'; +import { DefaultStyleProvider, DashboardStyleProvider, StyleProp } from './StyleProvider'; import { FieldViewProps } from './nodes/FieldView'; const _global = (window /* browser */ || global /* node */) as any; @@ -342,7 +343,7 @@ export class MainView extends React.Component { PanelHeight={this.getContentsHeight} renderDepth={0} focus={emptyFunction} - styleProvider={this._sidebarContent.proto === Doc.UserDoc().myDashboards ? this.DashboardStyleProvider : DefaultStyleProvider} + styleProvider={this._sidebarContent.title === "My Dashboards" ? DashboardStyleProvider : DefaultStyleProvider} parentActive={returnTrue} whenActiveChanged={emptyFunction} bringToFront={emptyFunction} diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index a6e3516ed..c9eedb85d 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -15,6 +15,7 @@ import { MainView } from './MainView'; import { DocumentViewProps } from "./nodes/DocumentView"; import { FieldViewProps } from './nodes/FieldView'; import "./StyleProvider.scss"; +import "./collections/TreeView.scss"; import React = require("react"); import Color = require('color'); @@ -169,6 +170,45 @@ export function DefaultStyleProvider(doc: Opt, props: Opt runInAction(() => { + e.stopPropagation(); + doc.hidden = doc.hidden ? undefined : true; + }), "toggleHidden"); +} + +function toggleLock(e: React.MouseEvent, doc: Doc) { + UndoManager.RunInBatch(() => runInAction(() => { + e.stopPropagation(); + doc.lockedPosition = doc.lockedPosition ? undefined : true; + }), "toggleHidden"); +} + +/** + * add lock and hide button decorations for the "Dashboards" flyout TreeView + */ +export function DashboardStyleProvider(doc: Opt, props: Opt, property: string) { + switch (property.split(":")[0]) { + case StyleProp.Decorations: + if (doc) { + const hidden = doc.hidden; + const locked = doc.lockedPosition; + return doc._viewType === CollectionViewType.Docking || (Doc.IsSystem(doc) && Doc.UserDoc().noviceMode) ? (null) : + <> +
toggleHidden(e, doc)}> + +
+
toggleLock(e, doc)}> + +
+ ; + } + default: return DefaultStyleProvider(doc, props, property); + + } +} + // // a preliminary semantic-"layering/grouping" mechanism for determining interactive properties of documents // currently, the provider tests whether the docuemnt's layer field matches the activeLayer field of the tab. diff --git a/src/client/views/collections/TreeView.scss b/src/client/views/collections/TreeView.scss index 1208fa07d..2f74a49bb 100644 --- a/src/client/views/collections/TreeView.scss +++ b/src/client/views/collections/TreeView.scss @@ -29,7 +29,7 @@ } .treeView-checkIcon { - left: 3px; + left: 3.5px; top: 2px; position: absolute; } @@ -118,12 +118,18 @@ margin-left: 0.25rem; opacity: 0.75; - >svg, .styleProvider-treeView-lock, .styleProvider-treeView-hide, .styleProvider-treeView-lock-active, .styleProvider-treeView-hide-active { + >svg, + .styleProvider-treeView-lock, + .styleProvider-treeView-hide, + .styleProvider-treeView-lock-active, + .styleProvider-treeView-hide-active { margin-left: 0.25rem; - margin-right: 0.25rem; + margin-right: 0.25rem; } - - >svg, .styleProvider-treeView-lock, .styleProvider-treeView-hide { + + >svg, + .styleProvider-treeView-lock, + .styleProvider-treeView-hide { display: none; } } @@ -148,7 +154,10 @@ } .right-buttons-container { - >svg, .styleProvider-treeView-lock, .styleProvider-treeView-hide { + + >svg, + .styleProvider-treeView-lock, + .styleProvider-treeView-hide { display: inherit; } } diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 2f9a2f3eb..a297ad708 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -590,7 +590,10 @@ export class TreeView extends React.Component { }} > {view}
- {this.headerElements} +
+ {this.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.Decorations)} {/* hide and lock buttons */} + {this.headerElements} +
; } -- cgit v1.2.3-70-g09d2 From ac4a5689a8421aea8c41949152b15809cc0ba13a Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Sat, 2 Jan 2021 12:37:53 +0530 Subject: updating --- src/client/util/CurrentUserUtils.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 00ee0f4b9..0623cca99 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -522,7 +522,7 @@ export class CurrentUserUtils { { title: "Import", target: Cast(doc.myImportPanel, Doc, null), icon: "upload", click: 'selectMainMenu(self)' }, { title: "Sharing", target: Cast(doc.mySharedDocs, Doc, null), icon: "users", click: 'selectMainMenu(self)', watchedDocuments: doc.mySharedDocs as Doc }, { title: "Tools", target: Cast(doc.myTools, Doc, null), icon: "wrench", click: 'selectMainMenu(self)' }, - { title: "Filter", target: Cast(doc.myFilter, Doc, null), icon: "filter", click: 'selectMainMenu(self)' }, + { title: "Filter", target: Cast(doc.currentFilter, Doc, null), icon: "filter", click: 'selectMainMenu(self)' }, { title: "Pres. Trails", target: Cast(doc.myPresentations, Doc, null), icon: "pres-trail", click: 'selectMainMenu(self)' }, { title: "Catalog", target: undefined as any, icon: "file", click: 'selectMainMenu(self)' }, { title: "Help", target: undefined as any, icon: "question-circle", click: 'selectMainMenu(self)' }, @@ -786,18 +786,18 @@ export class CurrentUserUtils { } } static setupFilterDocs(doc: Doc) { - // setup Recently Closed library item - doc.myFilter === undefined; - if (doc.myFilter === undefined) { - doc.myFilter = new PrefetchProxy(Docs.Create.FilterDocument({ + // setup Filter item + doc.currentFilter === undefined; + if (doc.currentFilter === undefined) { + doc.currentFilter = new PrefetchProxy(Docs.Create.FilterDocument({ title: "FilterDoc", _height: 500, treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "none", treeViewTruncateTitleWidth: 150, treeViewPreventOpen: false, ignoreClick: true, lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true })); const clearAll = ScriptField.MakeScript(`getProto(self).data = new List([])`); - (doc.myFilter as any as Doc).contextMenuScripts = new List([clearAll!]); - (doc.myFilter as any as Doc).contextMenuLabels = new List(["Clear All"]); + (doc.currentFilter as any as Doc).contextMenuScripts = new List([clearAll!]); + (doc.currentFilter as any as Doc).contextMenuLabels = new List(["Clear All"]); } } @@ -1005,6 +1005,7 @@ export class CurrentUserUtils { await this.setupSidebarButtons(doc); // the pop-out left sidebar of tools/panels await this.setupMenuPanel(doc, sharingDocumentId, linkDatabaseId); if (!doc.globalScriptDatabase) doc.globalScriptDatabase = Docs.Prototypes.MainScriptDocument(); + // doc.savedFilters = new List(); setTimeout(() => this.setupDefaultPresentation(doc), 0); // presentation that's initially triggered -- cgit v1.2.3-70-g09d2 From b98c90c3c59eb5f65a4c7aad7ff8247558a5564c Mon Sep 17 00:00:00 2001 From: anika Date: Thu, 7 Jan 2021 10:33:04 -0600 Subject: last before pull --- src/client/views/StyleProvider.tsx | 2 +- src/client/views/collections/TreeView.tsx | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index c9eedb85d..607783d51 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -73,7 +73,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt props?.styleProvider?.(doc, props, StyleProp.Opacity); switch (property.split(":")[0]) { - case StyleProp.TreeViewIcon: return doc && Doc.toIcon(doc); + case StyleProp.TreeViewIcon: return doc ? Doc.toIcon(doc) : "question"; case StyleProp.DocContents: return undefined; case StyleProp.WidgetColor: return darkScheme() ? "lightgrey" : "dimgrey"; case StyleProp.Opacity: return Cast(doc?._opacity, "number", Cast(doc?.opacity, "number", null)); diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index a297ad708..6a0e05215 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -441,14 +441,17 @@ export class TreeView extends React.Component { @computed get renderBullet() { TraceMobx(); + const iconType = Doc.toIcon(this.doc); + // console.log(this.titleStyleProvider?.(this.doc, this.props.treeView.props, StyleProp.TreeViewIcon)); <- always undefined //const iconType = this.titleStyleProvider?.(this.doc, this.props.treeView.props, StyleProp.TreeViewIcon); // const footerDecoration = this.titleStyleProvider?.(this.doc, this.props.treeView.props, StyleProp.Decoration + ":footer"); const checked = this.onCheckedClick ? (this.doc.treeViewChecked ?? "unchecked") : undefined; + return
Date: Thu, 7 Jan 2021 11:23:48 -0600 Subject: shift to right --- src/client/views/PropertiesView.tsx | 45 ++++++++++++++++++++-- .../views/collections/CollectionTreeView.tsx | 5 ++- src/client/views/nodes/FilterBox.scss | 9 ++--- src/client/views/nodes/FilterBox.tsx | 4 +- 4 files changed, 51 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 6e33b5c2f..a8b65c114 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -11,7 +11,7 @@ import { InkField } from "../../fields/InkField"; import { ComputedField } from "../../fields/ScriptField"; import { Cast, NumCast, StrCast } from "../../fields/Types"; import { denormalizeEmail, GetEffectiveAcl, SharingPermissions } from "../../fields/util"; -import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse } from "../../Utils"; +import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from "../../Utils"; import { DocumentType } from "../documents/DocumentTypes"; import { DocumentManager } from "../util/DocumentManager"; import { SelectionManager } from "../util/SelectionManager"; @@ -29,6 +29,7 @@ import { PropertiesButtons } from "./PropertiesButtons"; import { PropertiesDocContextSelector } from "./PropertiesDocContextSelector"; import "./PropertiesView.scss"; import { DefaultStyleProvider } from "./StyleProvider"; +import { FilterBox } from "./nodes/FilterBox"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -67,6 +68,8 @@ export class PropertiesView extends React.Component { @observable openContexts: boolean = true; @observable openAppearance: boolean = true; @observable openTransform: boolean = true; + @observable openFilters: boolean = true; + // @observable selectedUser: string = ""; // @observable addButtonPressed: boolean = false; @observable layoutDocAcls: boolean = false; @@ -510,8 +513,6 @@ export class PropertiesView extends React.Component { } } - - @computed get controlPointsButton() { const formatInstance = InkStrokeProperties.Instance; @@ -907,6 +908,44 @@ export class PropertiesView extends React.Component {
}
+
+
this.openFilters = !this.openFilters)} + style={{ backgroundColor: this.openFilters ? "black" : "" }}> + Filters +
+ +
+
+ {!this.openFilters ? (null) : +
+ +
} +
+ {!this.isInk ? (null) :
>(Document) { +export class + CollectionTreeView extends CollectionSubView>(Document) { private treedropDisposer?: DragManager.DragDropDisposer; private _isChildActive = false; private _mainEle?: HTMLDivElement; @@ -212,7 +213,7 @@ export class CollectionTreeView extends CollectionSubView {/*
*/} -
+ {/*
Choose Filters -
+
*/}
-
specified filters
+
filters in
+
-
+ {/*
Scope:
-
+
*/} {/*
*/}
@@ -291,10 +296,18 @@ export class FilterBox extends ViewBoxBaseComponentdocuments
-
-
- -
SAVE
+
+
+
+ +
SAVE
+
+
+
+
+ +
MY FILTERS
+
-- cgit v1.2.3-70-g09d2 From 346975d67de02181bb0e518e376dc7e4ccaccfa7 Mon Sep 17 00:00:00 2001 From: anika Date: Fri, 8 Jan 2021 01:41:03 -0600 Subject: quick contrast fix --- src/client/views/nodes/FilterBox.scss | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/FilterBox.scss b/src/client/views/nodes/FilterBox.scss index 59ef2c5cf..144f161bc 100644 --- a/src/client/views/nodes/FilterBox.scss +++ b/src/client/views/nodes/FilterBox.scss @@ -35,8 +35,8 @@ .filterBox-saveBookmark { - background-color: #f5f5f5; - border-radius: 6px; + background-color: #e9e9e9; + border-radius: 11px; padding-left: 8px; padding-right: 8px; padding-top: 5px; @@ -126,7 +126,7 @@ .filterBox-selection { border-radius: 6px; border: none; - background-color: #f5f5f5; + background-color: #e9e9e9; padding: 2px; &:hover { @@ -136,8 +136,8 @@ .filterBox-addFilter { width: 120px; - background-color: #f5f5f5; - border-radius: 10px; + background-color: #e9e9e9; + border-radius: 12px; padding: 5px; margin: 5px; display: flex; -- cgit v1.2.3-70-g09d2 From 39e8bd2671d70e1e8fd708c5210120a9d09b64fa Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Mon, 11 Jan 2021 01:34:10 +0530 Subject: initial flyout to dropdown change --- src/client/util/GroupManager.tsx | 3 +-- src/client/util/SharingManager.tsx | 5 +++-- src/client/views/nodes/FilterBox.tsx | 16 ++++++++++++++-- 3 files changed, 18 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/client/util/GroupManager.tsx b/src/client/util/GroupManager.tsx index 48676a393..b24c8f681 100644 --- a/src/client/util/GroupManager.tsx +++ b/src/client/util/GroupManager.tsx @@ -284,8 +284,7 @@ export class GroupManager extends React.Component<{}> { placeholder="Group name" onChange={action(() => this.buttonColour = this.inputRef.current?.value ? "black" : "#979797")} /> ; const FilterBoxDocument = makeInterface(documentSchema); @@ -207,6 +209,8 @@ export class FilterBox extends ViewBoxBaseComponent)}
; + const options = this._allFacets.map(facet => ({ value: facet, label: facet })); + return this.props.dontRegisterView ? (null) :
{/*
*/} @@ -278,11 +282,19 @@ export class FilterBox extends ViewBoxBaseComponent
- + {/*
+ add a filter
-
+
*/} + changeFilterBool(e, doc)}> + + + +
+
closeFilter(e, doc)}> + +
+ ; + } + default: return DefaultStyleProvider(doc, props, property); + + } +} + // // a preliminary semantic-"layering/grouping" mechanism for determining interactive properties of documents // currently, the provider tests whether the docuemnt's layer field matches the activeLayer field of the tab. diff --git a/src/client/views/nodes/FilterBox.scss b/src/client/views/nodes/FilterBox.scss index 144f161bc..fb1783ad4 100644 --- a/src/client/views/nodes/FilterBox.scss +++ b/src/client/views/nodes/FilterBox.scss @@ -33,6 +33,12 @@ // width: 100%; } +.filterBox-select { + width: 90%; + margin-top: 5px; + margin-bottom: 15px; +} + .filterBox-saveBookmark { background-color: #e9e9e9; diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index 2db610e43..c7dc4c155 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -8,7 +8,7 @@ import { List } from "../../../fields/List"; import { RichTextField } from "../../../fields/RichTextField"; import { listSpec, makeInterface } from "../../../fields/Schema"; import { ComputedField, ScriptField } from "../../../fields/ScriptField"; -import { Cast } from "../../../fields/Types"; +import { Cast, StrCast } from "../../../fields/Types"; import { emptyFunction, emptyPath, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, returnZero, returnTrue } from "../../../Utils"; import { Docs } from "../../documents/Documents"; import { DocumentType } from "../../documents/DocumentTypes"; @@ -27,6 +27,9 @@ export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; import Select from "react-select"; import { UserOptions } from "../../util/GroupManager"; +import { DocumentViewProps } from "./DocumentView"; +import { DefaultStyleProvider, StyleProp } from "../StyleProvider"; +import { CollectionViewType } from "../collections/CollectionView"; type FilterBoxDocument = makeInterface<[typeof documentSchema]>; const FilterBoxDocument = makeInterface(documentSchema); @@ -206,6 +209,29 @@ export class FilterBox extends ViewBoxBaseComponent, props: Opt, property: string) { + switch (property.split(":")[0]) { + case StyleProp.Decorations: + if (doc) { + return doc._viewType === CollectionViewType.Docking || (Doc.IsSystem(doc)) ? (null) : + <> +
+ +
+
this.facetClick(StrCast(doc.title))}> + +
+ ; + } + default: return DefaultStyleProvider(doc, props, property); + + } + } + + render() { const facetCollection = this.props.Document; const flyout =
e.stopPropagation()}> @@ -286,7 +312,7 @@ export class FilterBox extends ViewBoxBaseComponent + add a filter
*/} - this.facetClick((val as UserOptions).value)} + value={null} + closeMenuOnSelect={false} + /> +
-- cgit v1.2.3-70-g09d2 From 5b0a4a154a6e68139d3d7e462ca421d3fbbdd224 Mon Sep 17 00:00:00 2001 From: anika Date: Thu, 28 Jan 2021 09:20:52 -0500 Subject: functionality for adding and removing filters --- src/client/util/CurrentUserUtils.ts | 2 +- src/client/views/nodes/FilterBox.tsx | 55 +++++++++++++++++++++++++++++------- 2 files changed, 46 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index f3fec9ae6..f869fe4f5 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -792,7 +792,7 @@ export class CurrentUserUtils { doc.currentFilter = new PrefetchProxy(Docs.Create.FilterDocument({ title: "FilterDoc", _height: 500, treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "none", - treeViewTruncateTitleWidth: 150, treeViewPreventOpen: false, ignoreClick: true, + treeViewTruncateTitleWidth: 90, treeViewPreventOpen: false, ignoreClick: true, lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true })); const clearAll = ScriptField.MakeScript(`getProto(self).data = new List([])`); diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index 61f5232ce..6b1cd793e 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -63,6 +63,7 @@ export class FilterBox extends ViewBoxBaseComponent key[0]).filter(key => key[0] === "#" || key.indexOf("lastModified") !== -1 || (key[0] === key[0].toUpperCase() && !key.startsWith("_")) || noviceFields.includes(key) || !Doc.UserDoc().noviceMode).sort(); } + /** * The current attributes selected to filter based on */ @@ -70,6 +71,10 @@ export class FilterBox extends ViewBoxBaseComponent StrCast(attribute.title)); + } + gatherFieldValues(dashboard: Doc, facetKey: string) { const childDocs = DocListCast((dashboard.data as any)[0].data); const valueSet = new Set(); @@ -102,28 +107,58 @@ export class FilterBox extends ViewBoxBaseComponent { + + public static removeFilter = (filterName: string) => { + console.log("remove filter"); const targetDoc = SelectionManager.Views()[0].Document; // CollectionDockingView.Instance.props.Document; - const found = this.activeAttributes.findIndex(doc => doc.title === facetHeader); + const filterDoc = Doc.UserDoc().currentFilter as any as Doc; + const attributes = DocListCast(filterDoc["data"]); + const found = attributes.findIndex(doc => doc.title === filterName); if (found !== -1) { - (this.dataDoc[this.props.fieldKey] as List).splice(found, 1); + (filterDoc["data"] as List).splice(found, 1); const docFilter = Cast(targetDoc._docFilters, listSpec("string")); if (docFilter) { let index: number; - while ((index = docFilter.findIndex(item => item.split(":")[0] === facetHeader)) !== -1) { + while ((index = docFilter.findIndex(item => item.split(":")[0] === filterName)) !== -1) { docFilter.splice(index, 1); } } const docRangeFilters = Cast(targetDoc._docRangeFilters, listSpec("string")); if (docRangeFilters) { let index: number; - while ((index = docRangeFilters.findIndex(item => item.split(":")[0] === facetHeader)) !== -1) { + while ((index = docRangeFilters.findIndex(item => item.split(":")[0] === filterName)) !== -1) { docRangeFilters.splice(index, 3); } } + } + } + + /** + * Responds to clicking the check box in the flyout menu + */ + facetClick = (facetHeader: string) => { + + console.log("facetClick: " + facetHeader); + console.log(this.props.fieldKey); + + const targetDoc = SelectionManager.Views()[0].Document; // CollectionDockingView.Instance.props.Document; + const found = this.activeAttributes.findIndex(doc => doc.title === facetHeader); + if (found !== -1) { + // (this.dataDoc[this.props.fieldKey] as List).splice(found, 1); + // const docFilter = Cast(targetDoc._docFilters, listSpec("string")); + // if (docFilter) { + // let index: number; + // while ((index = docFilter.findIndex(item => item.split(":")[0] === facetHeader)) !== -1) { + // docFilter.splice(index, 1); + // } + // } + // const docRangeFilters = Cast(targetDoc._docRangeFilters, listSpec("string")); + // if (docRangeFilters) { + // let index: number; + // while ((index = docRangeFilters.findIndex(item => item.split(":")[0] === facetHeader)) !== -1) { + // docRangeFilters.splice(index, 3); + // } + // } } else { const allCollectionDocs = DocListCast((targetDoc.data as any)[0].data); const facetValues = this.gatherFieldValues(targetDoc, facetHeader); @@ -221,7 +256,7 @@ export class FilterBox extends ViewBoxBaseComponentIs Not
-
this.facetClick(StrCast(doc.title))}> +
FilterBox.removeFilter(StrCast(doc.title))}>
; @@ -245,7 +280,7 @@ export class FilterBox extends ViewBoxBaseComponent !attributes.some(attribute => attribute.title === facet)).map(facet => ({ value: facet, label: facet })); - const options = this._allFacets.map(facet => ({ value: facet, label: facet })); + const options = this._allFacets.filter(facet => this.currentFacets.indexOf(facet) === -1).map(facet => ({ value: facet, label: facet })); return this.props.dontRegisterView ? (null) :
-- cgit v1.2.3-70-g09d2 From 6f1fa5e8211518cbb6ebff5cb6849101e36983ab Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Mon, 1 Feb 2021 18:40:01 -0500 Subject: filters changes --- .gitignore | 3 ++- package-lock.json | 6 ++--- package.json | 4 ++-- src/client/util/CurrentUserUtils.ts | 7 +++--- src/client/views/EditableView.scss | 2 ++ src/client/views/EditableView.tsx | 1 + src/client/views/PropertiesView.tsx | 19 ++++++++++------ src/client/views/nodes/FilterBox.scss | 11 +++++----- src/client/views/nodes/FilterBox.tsx | 41 +++++++++++++++++++++++++++++++---- src/fields/Doc.ts | 2 +- 10 files changed, 70 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/.gitignore b/.gitignore index 6d4b98289..aeb343fd1 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,5 @@ src/server/session_manager/logs/**/*.log *.crt *.key *.pfx -*.properties \ No newline at end of file +*.properties +debug.log \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 42cbc1fd6..ed4f697b6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9062,9 +9062,9 @@ "integrity": "sha512-vTgEjKjS89C5yHL5qWPpT6BzKuOVqABp+A3Szpbx34pIy3sngxlGaFpgHhfj6fKze1w0QKeOSDbU7SKu7wDvRQ==" }, "mobx": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/mobx/-/mobx-5.15.4.tgz", - "integrity": "sha512-xRFJxSU2Im3nrGCdjSuOTFmxVDGeqOHL+TyADCGbT0k4HHqGmx5u2yaHNryvoORpI4DfbzjJ5jPmuv+d7sioFw==" + "version": "5.15.7", + "resolved": "https://registry.npmjs.org/mobx/-/mobx-5.15.7.tgz", + "integrity": "sha512-wyM3FghTkhmC+hQjyPGGFdpehrcX1KOXsDuERhfK2YbJemkUhEB+6wzEN639T21onxlfYBmriA1PFnvxTUhcKw==" }, "mobx-react": { "version": "5.4.4", diff --git a/package.json b/package.json index 13849c0f3..c7d674cf0 100644 --- a/package.json +++ b/package.json @@ -183,8 +183,8 @@ "lodash": "^4.17.15", "material-ui": "^0.20.2", "mobile-detect": "^1.4.4", - "mobx": "^5.15.3", - "mobx-react": "^5.3.5", + "mobx": "^5.15.7", + "mobx-react": "^5.4.4", "mobx-react-devtools": "^6.1.1", "mobx-utils": "^5.6.1", "mongodb": "^3.5.9", diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index f3fec9ae6..0d31060d4 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -522,7 +522,7 @@ export class CurrentUserUtils { { title: "Import", target: Cast(doc.myImportPanel, Doc, null), icon: "upload", click: 'selectMainMenu(self)' }, { title: "Sharing", target: Cast(doc.mySharedDocs, Doc, null), icon: "users", click: 'selectMainMenu(self)', watchedDocuments: doc.mySharedDocs as Doc }, { title: "Tools", target: Cast(doc.myTools, Doc, null), icon: "wrench", click: 'selectMainMenu(self)' }, - { title: "Filter", target: Cast(doc.currentFilter, Doc, null), icon: "filter", click: 'selectMainMenu(self)' }, + // { title: "Filter", target: Cast(doc.currentFilter, Doc, null), icon: "filter", click: 'selectMainMenu(self)' }, { title: "Pres. Trails", target: Cast(doc.myPresentations, Doc, null), icon: "pres-trail", click: 'selectMainMenu(self)' }, { title: "Catalog", target: undefined as any, icon: "file", click: 'selectMainMenu(self)' }, { title: "Help", target: undefined as any, icon: "question-circle", click: 'selectMainMenu(self)' }, @@ -790,7 +790,7 @@ export class CurrentUserUtils { doc.currentFilter === undefined; if (doc.currentFilter === undefined) { doc.currentFilter = new PrefetchProxy(Docs.Create.FilterDocument({ - title: "FilterDoc", _height: 500, + title: `FilterDoc(${(doc.filterDocCount as number)++})`, _height: 500, treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "none", treeViewTruncateTitleWidth: 150, treeViewPreventOpen: false, ignoreClick: true, lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true @@ -999,6 +999,8 @@ export class CurrentUserUtils { doc["constants-snapThreshold"] = NumCast(doc["constants-snapThreshold"], 10); // doc["constants-dragThreshold"] = NumCast(doc["constants-dragThreshold"], 4); // Utils.DRAG_THRESHOLD = NumCast(doc["constants-dragThreshold"]); + doc.savedFilters = new List(); + doc.filterDocCount = 0; this.setupDefaultIconTemplates(doc); // creates a set of icon templates triggered by the document deoration icon this.setupDocTemplates(doc); // sets up the template menu of templates this.setupImportSidebar(doc); @@ -1009,7 +1011,6 @@ export class CurrentUserUtils { await this.setupSidebarButtons(doc); // the pop-out left sidebar of tools/panels await this.setupMenuPanel(doc, sharingDocumentId, linkDatabaseId); if (!doc.globalScriptDatabase) doc.globalScriptDatabase = Docs.Prototypes.MainScriptDocument(); - // doc.savedFilters = new List(); setTimeout(() => this.setupDefaultPresentation(doc), 0); // presentation that's initially triggered diff --git a/src/client/views/EditableView.scss b/src/client/views/EditableView.scss index 4a89cc69c..5953baec1 100644 --- a/src/client/views/EditableView.scss +++ b/src/client/views/EditableView.scss @@ -8,6 +8,8 @@ } .editableView-container-editing-oneLine { + width: 100%; + span { white-space: nowrap; overflow: hidden; diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index ed7a8265f..828a2eb78 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -55,6 +55,7 @@ export interface EditableProps { color?: string | undefined; onDrop?: any; placeholder?: string; + fullWidth?: boolean; // used in PropertiesView to make the whole key:value input box clickable } /** diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index c6be7cae1..f0d3f1f3f 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -152,6 +152,7 @@ export class PropertiesView extends React.Component { rows.push(
{ rows.push(
{ const titles = new Set(); SelectionManager.Views().forEach(dv => titles.add(StrCast(dv.rootDoc.title))); const title = Array.from(titles.keys()).length > 1 ? "--multiple selected--" : StrCast(this.selectedDoc?.title); - return
title} - SetValue={this.setTitle} />
; + return
+ title} + SetValue={this.setTitle} /> +
; } @undoBatch @@ -1016,6 +1020,7 @@ export class PropertiesView extends React.Component { // } render() { + // console.log(this.props.width); if (!this.selectedDoc && !this.isPres) { return
diff --git a/src/client/views/nodes/FilterBox.scss b/src/client/views/nodes/FilterBox.scss index 144f161bc..4b4dfa8a4 100644 --- a/src/client/views/nodes/FilterBox.scss +++ b/src/client/views/nodes/FilterBox.scss @@ -27,11 +27,11 @@ } } -.filterBox-bottom { - // position: fixed; - // bottom: 0; - // width: 100%; -} +// .filterBox-bottom { + // // position: fixed; + // // bottom: 0; + // // width: 100%; + // } .filterBox-saveBookmark { @@ -44,6 +44,7 @@ margin: 8px; display: flex; font-size: 11px; + cursor: pointer; &:hover { background-color: white; diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index 63455e3d1..b06bfa8c3 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -33,12 +33,16 @@ const FilterBoxDocument = makeInterface(documentSchema); @observer export class FilterBox extends ViewBoxBaseComponent(FilterBoxDocument) { + constructor(props: Readonly) { + super(props); + } public static LayoutString(fieldKey: string) { return FieldView.LayoutString(FilterBox, fieldKey); } public _filterBoolean = "AND"; public _filterScope = "Current Dashboard"; public _filterSelected = false; public _filterMatch = "matched"; + private myFiltersRef = React.createRef(); @computed get allDocs() { const allDocs = new Set(); @@ -103,7 +107,7 @@ export class FilterBox extends ViewBoxBaseComponent { - const targetDoc = SelectionManager.Views()[0].Document; // CollectionDockingView.Instance.props.Document; + const targetDoc = CollectionDockingView.Instance.props.Document; //SelectionManager.Views()[0].Document; const found = this.activeAttributes.findIndex(doc => doc.title === facetHeader); if (found !== -1) { (this.dataDoc[this.props.fieldKey] as List).splice(found, 1); @@ -193,6 +197,10 @@ export class FilterBox extends ViewBoxBaseComponent { @@ -206,6 +214,12 @@ export class FilterBox extends ViewBoxBaseComponent { + Doc.AddDocToList(Doc.UserDoc(), "savedFilters", this.props.Document); + console.log("saved filter"); + console.log(Doc.UserDoc().savedFilters); + } + render() { const facetCollection = this.props.Document; // const flyout =
e.stopPropagation()}> @@ -220,6 +234,16 @@ export class FilterBox extends ViewBoxBaseComponent !attributes.some(attribute => attribute.title === facet)).map(facet => ({ value: facet, label: facet })); const options = this._allFacets.map(facet => ({ value: facet, label: facet })); + // console.log(this.props.Document); + // console.log(Doc.UserDoc().currentFilter); + console.log(this.yPos); + console.log(this.myFiltersRef.current?.getBoundingClientRect()); + + const flyout = <> +
e.stopPropagation()}> + testing flyout +
+ ; return this.props.dontRegisterView ? (null) :
@@ -320,18 +344,27 @@ export class FilterBox extends ViewBoxBaseComponent
-
+
SAVE
-
+
-
MY FILTERS
+ +
MY FILTERS
+
+
+ floot floot +
; } diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 9aacf5375..493dd2ba4 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -1062,7 +1062,7 @@ export namespace Doc { // all documents with the specified value for the specified key are included/excluded // based on the modifiers :"check", "x", undefined export function setDocFilter(target: Opt, key: string, value: any, modifiers?: "remove" | "match" | "check" | "x" | undefined) { - console.log("m8"); + // console.log(key, value, modifiers); const container = target ?? CollectionDockingView.Instance.props.Document; const docFilters = Cast(container._docFilters, listSpec("string"), []); runInAction(() => { -- cgit v1.2.3-70-g09d2 From ee3561896e1bbfae4f81bce109fa3df2618cfbc8 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Mon, 1 Feb 2021 18:48:01 -0500 Subject: whoops --- src/client/views/nodes/FilterBox.tsx | 9 --------- 1 file changed, 9 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index a7227ecb8..67a56d563 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -111,14 +111,6 @@ export class FilterBox extends ViewBoxBaseComponent { - const targetDoc = CollectionDockingView.Instance.props.Document; //SelectionManager.Views()[0].Document; - const found = this.activeAttributes.findIndex(doc => doc.title === facetHeader); -======= public static removeFilter = (filterName: string) => { console.log("remove filter"); @@ -126,7 +118,6 @@ export class FilterBox extends ViewBoxBaseComponent doc.title === filterName); ->>>>>>> 5b0a4a154a6e68139d3d7e462ca421d3fbbdd224 if (found !== -1) { (filterDoc["data"] as List).splice(found, 1); const docFilter = Cast(targetDoc._docFilters, listSpec("string")); -- cgit v1.2.3-70-g09d2 From aede6226aa367ff3137b126e0d0e23e1b2ca84db Mon Sep 17 00:00:00 2001 From: anika Date: Thu, 11 Feb 2021 16:08:38 -0500 Subject: last minor changes before switching branches --- src/client/views/PropertiesView.tsx | 6 +++--- src/client/views/nodes/FilterBox.tsx | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index c6b94456f..13a594afc 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -68,7 +68,7 @@ export class PropertiesView extends React.Component { @observable openContexts: boolean = true; @observable openAppearance: boolean = true; @observable openTransform: boolean = true; - @observable openFilters: boolean = false; + @observable openFilters: boolean = true; // @observable selectedUser: string = ""; // @observable addButtonPressed: boolean = false; @@ -1040,8 +1040,6 @@ export class PropertiesView extends React.Component { {this.sharingSubMenu} - {this.filtersSubMenu} - {this.inkSubMenu} {this.fieldsSubMenu} @@ -1049,6 +1047,8 @@ export class PropertiesView extends React.Component { {this.contextsSubMenu} {this.layoutSubMenu} + + {this.filtersSubMenu}
; } if (this.isPres) { diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index 6b1cd793e..a1b55f490 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -250,8 +250,8 @@ export class FilterBox extends ViewBoxBaseComponent -
- -- cgit v1.2.3-70-g09d2 From 7cbf63ed6fa7517d5b80fba50529544e0cf1d625 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Sat, 20 Feb 2021 11:38:45 -0500 Subject: unrelated --- src/client/ClientRecommender.tsx | 2 -- src/client/util/SelectionManager.ts | 2 +- src/fields/Schema.ts | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/client/ClientRecommender.tsx b/src/client/ClientRecommender.tsx index 3f875057e..1d4653471 100644 --- a/src/client/ClientRecommender.tsx +++ b/src/client/ClientRecommender.tsx @@ -40,8 +40,6 @@ const fieldkey = "data"; @observer export class ClientRecommender extends React.Component { - - static Instance: ClientRecommender; private mainDoc?: RecommenderDocument; private docVectors: Set = new Set(); diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index f657e5b40..b132af035 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -66,7 +66,7 @@ export namespace SelectionManager { manager.SelectSchemaView(colSchema, document); } - const IsSelectedCache = computedFn(function isSelected(doc: DocumentView) { // wraapping get() in a computedFn only generates mobx() invalidations when the return value of the function for the specific get parameters has changed + const IsSelectedCache = computedFn(function isSelected(doc: DocumentView) { // wrapping get() in a computedFn only generates mobx() invalidations when the return value of the function for the specific get parameters has changed return manager.SelectedViews.get(doc) ? true : false; }); // computed functions, such as used in IsSelected generate errors if they're called outside of a diff --git a/src/fields/Schema.ts b/src/fields/Schema.ts index 4607e0fd5..e0fc5902b 100644 --- a/src/fields/Schema.ts +++ b/src/fields/Schema.ts @@ -68,7 +68,7 @@ export function makeInterface(...schemas: T): InterfaceFu if (doc instanceof Doc || doc === undefined) { return fn(doc || new Doc); } else { - return doc.map(fn); + if (!doc instanceof Promise) return doc.map(fn); } }; } -- cgit v1.2.3-70-g09d2 From c2bcb4ac83ecafb0bf23f72ed1bc2d05b877da6d Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Sat, 20 Feb 2021 11:39:22 -0500 Subject: filterdocs setup --- src/client/util/CurrentUserUtils.ts | 14 +++++--------- src/client/views/nodes/DocumentView.tsx | 4 +++- 2 files changed, 8 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 8cb5e3903..2cba99355 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -791,20 +791,16 @@ export class CurrentUserUtils { // setup Filter item doc.currentFilter === undefined; if (doc.currentFilter === undefined) { - doc.currentFilter = new PrefetchProxy(Docs.Create.FilterDocument({ - title: `FilterDoc(${(doc.filterDocCount as number)++})`, _height: 500, - treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "none", + doc.currentFilter = Docs.Create.FilterDocument({ + title: "FilterDoc", _height: 20, + treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _yPadding: 10, forceActive: true, childDropAction: "none", treeViewTruncateTitleWidth: 90, treeViewPreventOpen: false, ignoreClick: true, lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true - })); + }); const clearAll = ScriptField.MakeScript(`getProto(self).data = new List([])`); (doc.currentFilter as any as Doc).contextMenuScripts = new List([clearAll!]); (doc.currentFilter as any as Doc).contextMenuLabels = new List(["Clear All"]); } - // const clearAll = ScriptField.MakeScript(`getProto(self).data = new List([]); scriptContext._docFilters = scriptContext._docRangeFilters = undefined;`, { scriptContext: Doc.name }); - // (doc.myFilter as any as Doc).contextMenuScripts = new List([clearAll!]); - // (doc.myFilter as any as Doc).contextMenuLabels = new List(["Clear All"]); - } static setupUserDoc(doc: Doc) { @@ -836,7 +832,7 @@ export class CurrentUserUtils { CurrentUserUtils.setupDashboards(doc); CurrentUserUtils.setupPresentations(doc); CurrentUserUtils.setupRecentlyClosedDocs(doc); - CurrentUserUtils.setupFilterDocs(doc); + // CurrentUserUtils.setupFilterDocs(doc); CurrentUserUtils.setupUserDoc(doc); } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 7fa790768..5afbec7e6 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -119,6 +119,8 @@ export interface DocumentViewSharedProps { cantBrush?: boolean; // whether the document doesn't show brush highlighting pointerEvents?: string; scriptContext?: any; // can be assigned anything and will be passed as 'scriptContext' to any OnClick script that executes on this document + filterSaveCallback?: () => void; + myFiltersCallback?: (doc: Doc) => void; } export interface DocumentViewProps extends DocumentViewSharedProps { // properties specific to DocumentViews but not to FieldView @@ -1075,7 +1077,7 @@ export class DocumentView extends React.Component { } componentDidMount() { - !BoolCast(this.props.Document.dontRegisterView, this.props.dontRegisterView) && DocumentManager.Instance.AddView(this); + !BoolCast(this.props.Document?.dontRegisterView, this.props.dontRegisterView) && DocumentManager.Instance.AddView(this); } componentWillUnmount() { !this.props.dontRegisterView && DocumentManager.Instance.RemoveView(this); -- cgit v1.2.3-70-g09d2 From 0381050cab3cbcf6f1c3552fa86cace3a1654a07 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Mon, 22 Feb 2021 21:25:25 -0500 Subject: filters scope changes --- src/client/views/PropertiesView.scss | 62 ++++++++++++ src/client/views/PropertiesView.tsx | 107 +++++++++++++------- src/client/views/nodes/FilterBox.scss | 34 +++---- src/client/views/nodes/FilterBox.tsx | 182 +++++++++++++++++----------------- src/fields/Doc.ts | 6 +- 5 files changed, 240 insertions(+), 151 deletions(-) (limited to 'src') diff --git a/src/client/views/PropertiesView.scss b/src/client/views/PropertiesView.scss index 1365725cb..134c50972 100644 --- a/src/client/views/PropertiesView.scss +++ b/src/client/views/PropertiesView.scss @@ -157,6 +157,67 @@ } } + .propertiesView-filters { + //border-bottom: 1px solid black; + //padding: 8.5px; + + .propertiesView-filters-title { + font-weight: bold; + font-size: 12.5px; + padding: 4px; + display: flex; + color: white; + padding-left: 8px; + background-color: rgb(51, 51, 51); + + &:hover { + cursor: pointer; + } + + .propertiesView-filters-title-icon { + float: right; + justify-items: right; + align-items: flex-end; + margin-left: auto; + margin-right: 9px; + + &:hover { + cursor: pointer; + } + } + } + + .propertiesView-filters-content { + font-size: 10px; + padding: 10px; + margin-left: 5px; + max-height: 40%; + overflow-y: auto; + + .propertiesView-buttonContainer { + float: right; + display: flex; + + button { + width: 15; + height: 15; + padding: 0; + margin-top: -5; + } + } + + button { + width: 5; + height: 5; + } + + input { + width: 100%; + } + } + } + + .propertiesView-appearance { //border-bottom: 1px solid black; //padding: 8.5px; @@ -332,6 +393,7 @@ } } } + .propertiesView-fields { //border-bottom: 1px solid black; //padding: 8.5px; diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index ae6c7c50c..388b688cd 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -2,10 +2,10 @@ import React = require("react"); import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Checkbox, Tooltip } from "@material-ui/core"; import { intersection } from "lodash"; -import { action, computed, observable } from "mobx"; +import { action, autorun, computed, Lambda, observable, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; import { ColorState, SketchPicker } from "react-color"; -import { AclAddonly, AclAdmin, AclEdit, AclPrivate, AclReadonly, AclSym, AclUnset, DataSym, Doc, Field, HeightSym, WidthSym } from "../../fields/Doc"; +import { AclAddonly, AclAdmin, AclEdit, AclPrivate, AclReadonly, AclSym, AclUnset, DataSym, Doc, Field, HeightSym, Opt, WidthSym } from "../../fields/Doc"; import { Id } from "../../fields/FieldSymbols"; import { InkField } from "../../fields/InkField"; import { ComputedField } from "../../fields/ScriptField"; @@ -29,6 +29,7 @@ import { PropertiesButtons } from "./PropertiesButtons"; import { PropertiesDocContextSelector } from "./PropertiesDocContextSelector"; import "./PropertiesView.scss"; import { DefaultStyleProvider, FilteringStyleProvider } from "./StyleProvider"; +import { CurrentUserUtils } from "../util/CurrentUserUtils"; import { FilterBox } from "./nodes/FilterBox"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; @@ -48,6 +49,9 @@ export class PropertiesView extends React.Component { @computed get MAX_EMBED_HEIGHT() { return 200; } @computed get selectedDoc() { return SelectionManager.SelectedSchemaDoc() || this.selectedDocumentView?.rootDoc; } + @computed get filterDoc() { + return FilterBox._filterScope === "Current Collection" ? this.selectedDoc || CollectionDockingView.Instance.props.Document : CollectionDockingView.Instance.props.Document; + } @computed get selectedDocumentView() { if (SelectionManager.Views().length) return SelectionManager.Views()[0]; if (PresBox.Instance?._selectedArray.size) return DocumentManager.Instance.getDocumentView(PresBox.Instance.rootDoc); @@ -68,7 +72,9 @@ export class PropertiesView extends React.Component { @observable openContexts: boolean = true; @observable openAppearance: boolean = true; @observable openTransform: boolean = true; - @observable openFilters: boolean = true; + @observable openFilters: boolean = true; // should be false + + private selectedDocListenerDisposer: Opt; // @observable selectedUser: string = ""; // @observable addButtonPressed: boolean = false; @@ -84,6 +90,15 @@ export class PropertiesView extends React.Component { @observable _controlBtn: boolean = false; @observable _lock: boolean = false; + componentDidMount() { + this.selectedDocListenerDisposer?.(); + this.selectedDocListenerDisposer = autorun(() => this.openFilters && this.selectedDoc && this.checkFilterDoc()); + } + + componentWillUnmount() { + this.selectedDocListenerDisposer?.(); + } + @computed get isInk() { return this.selectedDoc?.type === DocumentType.INK; } rtfWidth = () => { @@ -885,44 +900,63 @@ export class PropertiesView extends React.Component {
; } + checkFilterDoc() { + if (this.filterDoc.type === DocumentType.COL && !this.filterDoc.currentFilter) CurrentUserUtils.setupFilterDocs(this.filterDoc!); + } + + saveFilter = () => { + this.filterDoc.currentFilter = undefined; + CurrentUserUtils.setupFilterDocs(this.filterDoc); + } + + myFiltersSelect = (doc: Doc) => { + this.filterDoc.currentFilter = doc; + } + @computed get filtersSubMenu() { - return
-
+
this.openFilters = !this.openFilters)} style={{ backgroundColor: this.openFilters ? "black" : "" }}> Filters -
+
- {!this.openFilters ? (null) : -
- -
} -
; + { + !this.openFilters || !this.filterDoc.currentFilter ? (null) : +
+ +
+ } +
; } @computed get inkSubMenu() { @@ -1022,7 +1056,6 @@ export class PropertiesView extends React.Component { // } render() { - // console.log(this.props.width); if (!this.selectedDoc && !this.isPres) { return
@@ -1047,6 +1080,8 @@ export class PropertiesView extends React.Component { {this.sharingSubMenu} + {this.selectedDoc.type === DocumentType.COL && this.filtersSubMenu} + {this.inkSubMenu} {this.fieldsSubMenu} @@ -1054,8 +1089,6 @@ export class PropertiesView extends React.Component { {this.contextsSubMenu} {this.layoutSubMenu} - - {this.filtersSubMenu}
; } if (this.isPres) { diff --git a/src/client/views/nodes/FilterBox.scss b/src/client/views/nodes/FilterBox.scss index b1b3c0f25..4fe1fa2eb 100644 --- a/src/client/views/nodes/FilterBox.scss +++ b/src/client/views/nodes/FilterBox.scss @@ -28,15 +28,15 @@ } // .filterBox-bottom { - // // position: fixed; - // // bottom: 0; - // // width: 100%; - // } +// // position: fixed; +// // bottom: 0; +// // width: 100%; +// } .filterBox-select { - width: 90%; + // width: 90%; margin-top: 5px; - margin-bottom: 15px; + // margin-bottom: 15px; } @@ -64,20 +64,6 @@ } -.filterBox-title { - - justify-content: center; - text-align: center; - padding-bottom: 13px; - font-size: 20px; - font-weight: bold; - - .filterBox-span { - margin-right: 15px; - } - -} - .filterBox-select-scope, .filterBox-select-bool, .filterBox-addWrapper, @@ -112,6 +98,14 @@ border-bottom: 2px solid black; } +.filterBox-title { + font-size: 15; + // border: 2px solid black; + width: 100%; + align-self: center; + text-align: center; + background-color: #d3d3d3; +} .filterBox-select-bool { margin-top: 6px; diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index ec77775be..987939d65 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -1,8 +1,8 @@ import React = require("react"); import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { action, computed } from "mobx"; +import { action, computed, observable, runInAction } from "mobx"; import { observer } from "mobx-react"; -import { DataSym, Doc, DocListCast, Field, Opt } from "../../../fields/Doc"; +import { DataSym, Doc, DocListCast, DocListCastAsync, Field, Opt } from "../../../fields/Doc"; import { documentSchema } from "../../../fields/documentSchemas"; import { List } from "../../../fields/List"; import { RichTextField } from "../../../fields/RichTextField"; @@ -30,22 +30,30 @@ import { UserOptions } from "../../util/GroupManager"; import { DocumentViewProps } from "./DocumentView"; import { DefaultStyleProvider, StyleProp } from "../StyleProvider"; import { CollectionViewType } from "../collections/CollectionView"; +import { CurrentUserUtils } from "../../util/CurrentUserUtils"; type FilterBoxDocument = makeInterface<[typeof documentSchema]>; const FilterBoxDocument = makeInterface(documentSchema); @observer export class FilterBox extends ViewBoxBaseComponent(FilterBoxDocument) { + + static Instance: FilterBox; + constructor(props: Readonly) { super(props); + FilterBox.Instance = this; + if (!CollectionDockingView.Instance.props.Document.currentFilter) CurrentUserUtils.setupFilterDocs(CollectionDockingView.Instance.props.Document); } public static LayoutString(fieldKey: string) { return FieldView.LayoutString(FilterBox, fieldKey); } public _filterBoolean = "AND"; - public _filterScope = "Current Dashboard"; + public static _filterScope = "Current Dashboard"; public _filterSelected = false; public _filterMatch = "matched"; - private myFiltersRef = React.createRef(); + // private myFiltersRef = React.createRef(); + + @observable private showFilterDialog = false; @computed get allDocs() { const allDocs = new Set(); @@ -112,10 +120,12 @@ export class FilterBox extends ViewBoxBaseComponent { + public removeFilter = (filterName: string) => { console.log("remove filter"); - const targetDoc = SelectionManager.Views()[0].Document; // CollectionDockingView.Instance.props.Document; - const filterDoc = Doc.UserDoc().currentFilter as any as Doc; + const targetDoc = FilterBox._filterScope === "Current Collection" ? SelectionManager.Views()[0].Document || CollectionDockingView.Instance.props.Document : CollectionDockingView.Instance.props.Document; + // const targetDoc = SelectionManager.Views()[0].props.Document; + // const targetDoc = SelectionManager.Views()[0].Document; // CollectionDockingView.Instance.props.Document; + const filterDoc = targetDoc.currentFilter as Doc; const attributes = DocListCast(filterDoc["data"]); const found = attributes.findIndex(doc => doc.title === filterName); if (found !== -1) { @@ -145,7 +155,8 @@ export class FilterBox extends ViewBoxBaseComponent doc.title === facetHeader); if (found !== -1) { // (this.dataDoc[this.props.fieldKey] as List).splice(found, 1); @@ -164,7 +175,7 @@ export class FilterBox extends ViewBoxBaseComponent; - if (facetHeader === "text" || facetValues.rtFields / allCollectionDocs.length > 0.1) { + if (facetHeader === "text") {//} || facetValues.rtFields / allCollectionDocs.length > 0.1) { newFacet = Docs.Create.TextDocument("", { _width: 100, _height: 25, system: true, _stayInCollection: true, _hideContextMenu: true, treeViewExpandedView: "layout", title: facetHeader, treeViewOpen: true, forceActive: true, ignoreClick: true }); Doc.GetProto(newFacet).type = DocumentType.COL; // forces item to show an open/close button instead ofa checkbox newFacet._textBoxPadding = 4; @@ -225,8 +236,8 @@ export class FilterBox extends ViewBoxBaseComponent { - this._filterScope = e.currentTarget.value; - console.log(this._filterScope); + FilterBox._filterScope = e.currentTarget.value; + console.log(FilterBox._filterScope); } @action @@ -234,14 +245,9 @@ export class FilterBox extends ViewBoxBaseComponent { + changeSelected = () => { if (this._filterSelected) { this._filterSelected = false; SelectionManager.DeselectAll(); @@ -252,12 +258,6 @@ export class FilterBox extends ViewBoxBaseComponent { - Doc.AddDocToList(Doc.UserDoc(), "savedFilters", this.props.Document); - console.log("saved filter"); - console.log(Doc.UserDoc().savedFilters); - } - FilteringStyleProvider(doc: Opt, props: Opt, property: string) { switch (property.split(":")[0]) { case StyleProp.Decorations: @@ -270,7 +270,7 @@ export class FilterBox extends ViewBoxBaseComponentIs Not
-
FilterBox.removeFilter(StrCast(doc.title))}> +
this.removeFilter(StrCast(doc.title))}>
; @@ -280,45 +280,47 @@ export class FilterBox extends ViewBoxBaseComponent ScriptField.MakeScript("")!; + + saveFilter = () => { + // const doc: Doc = new Doc; + // for (const key of Object.keys(this.props.Document)) { + // doc[key] = SerializationHelper.Serialize(this.props.Document[key] as Field); + // } + // console.log(doc); + runInAction(() => this.showFilterDialog = true); + console.log("saved filter"); + } + + onTitleValueChange = (e: React.ChangeEvent) => { + this.props.Document.title = e.currentTarget.value || `FilterDoc for ${SelectionManager.Views()[0].Document.title}`; + } + + onKeyDown = (e: React.KeyboardEvent) => { + if (e.key === "Enter") { + runInAction(() => this.showFilterDialog = false); + Doc.AddDocToList(Doc.UserDoc(), "savedFilters", this.props.Document); + } + } + render() { const facetCollection = this.props.Document; - // const flyout =
e.stopPropagation()}> - // {this._allFacets.map(facet => )} - //
; - - // const attributes = this.activeAttributes; - - // const options = this._allFacets.filter(facet => !attributes.some(attribute => attribute.title === facet)).map(facet => ({ value: facet, label: facet })); - // const options = this._allFacets.map(facet => ({ value: facet, label: facet })); - // console.log(this.props.Document); - // console.log(Doc.UserDoc().currentFilter); - console.log(this.yPos); - console.log(this.myFiltersRef.current?.getBoundingClientRect()); - - const flyout = <> -
e.stopPropagation()}> - testing flyout -
- ; - const options = this._allFacets.filter(facet => this.currentFacets.indexOf(facet) === -1).map(facet => ({ value: facet, label: facet })); - return this.props.dontRegisterView ? (null) :
+ const flyout = DocListCast(Doc.UserDoc().savedFilters).map(doc => { + // console.log("mapping"); + return <> +
e.stopPropagation()} style={{ height: 50, border: "2px" }} onPointerDown={() => this.props.myFiltersCallback?.(doc)}> + {StrCast(doc.title)} +
+ ; + } + ); - {/*
*/} - {/*
- -
+ const options = this._allFacets.filter(facet => this.currentFacets.indexOf(facet) === -1).map(facet => ({ value: facet, label: facet })); -
- Choose Filters -
*/} + return this.props.dontRegisterView ? (null) :
+
Current FilterDoc: {this.props.Document.title}
this.changeScope(e)}> - - - + + {/* */} +
- {/*
-
Scope:
- -
*/} - {/*
*/} +
+ this.facetClick((val as UserOptions).value)} - value={null} - closeMenuOnSelect={false} - /> -
-
this.changeSelected(e)} /> + onChange={this.changeSelected} />
select
+ }
; } diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 5e9ab4baa..9b539d1b7 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -25,6 +25,7 @@ import { Cast, FieldValue, NumCast, StrCast, ToConstructor } from "./Types"; import { AudioField, ImageField, PdfField, VideoField, WebField } from "./URLField"; import { deleteProperty, GetEffectiveAcl, getField, getter, makeEditable, makeReadOnly, normalizeEmail, setter, SharingPermissions, updateFunction } from "./util"; import JSZip = require("jszip"); +import { FilterBox } from "../client/views/nodes/FilterBox"; export namespace Field { export function toKeyValueString(doc: Doc, key: string): string { @@ -1063,9 +1064,8 @@ export namespace Doc { // all documents with the specified value for the specified key are included/excluded // based on the modifiers :"check", "x", undefined export function setDocFilter(target: Opt, key: string, value: any, modifiers?: "remove" | "match" | "check" | "x" | undefined) { - // console.log(key, value, modifiers); - const container = target ?? CollectionDockingView.Instance.props.Document; - const docFilters = Cast(container._docFilters, listSpec("string"), []); + const container = target ?? FilterBox._filterScope === "Current Collection" ? SelectionManager.Views()[0].Document || CollectionDockingView.Instance.props.Document : CollectionDockingView.Instance.props.Document; + const docFilters = Cast(SelectionManager.Views()[0].Document._docFilters, listSpec("string"), []); runInAction(() => { for (let i = 0; i < docFilters.length; i++) { const fields = docFilters[i].split(":"); // split key:value:modifier -- cgit v1.2.3-70-g09d2 From 02bceed486ecb03b94c757ae669f69912f282cdd Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Tue, 23 Feb 2021 10:34:47 -0500 Subject: current collection vs dashboard works a bit better - they have different filterdocs now --- src/client/views/PropertiesView.tsx | 20 +++++++++++++++----- src/client/views/nodes/DocumentView.tsx | 4 ++-- src/client/views/nodes/FilterBox.tsx | 6 +++--- src/fields/Doc.ts | 2 +- 4 files changed, 21 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 388b688cd..a159a9948 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -31,6 +31,7 @@ import "./PropertiesView.scss"; import { DefaultStyleProvider, FilteringStyleProvider } from "./StyleProvider"; import { CurrentUserUtils } from "../util/CurrentUserUtils"; import { FilterBox } from "./nodes/FilterBox"; +import { List } from "../../fields/List"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -901,16 +902,25 @@ export class PropertiesView extends React.Component { } checkFilterDoc() { - if (this.filterDoc.type === DocumentType.COL && !this.filterDoc.currentFilter) CurrentUserUtils.setupFilterDocs(this.filterDoc!); + if (this.filterDoc.type === DocumentType.COL && !this.filterDoc.currentFilter) CurrentUserUtils.setupFilterDocs(this.filterDoc); } - saveFilter = () => { + createNewFilterDoc = () => { + const temp = this.filterDoc._docFilters; + this.filterDoc._docFilters = new List(); + (this.filterDoc.currentFilter as Doc)._docFiltersList = temp; this.filterDoc.currentFilter = undefined; CurrentUserUtils.setupFilterDocs(this.filterDoc); } - myFiltersSelect = (doc: Doc) => { + updateFilterDoc = (doc: Doc) => { + const temp = doc._docFiltersList; + const otherTemp = this.filterDoc._docFilters; + this.filterDoc._docFilters = new List(); + (this.filterDoc.currentFilter as Doc)._docFiltersList = otherTemp; this.filterDoc.currentFilter = doc; + doc._docFiltersList = new List(); + this.filterDoc._docFilters = temp; } @computed get filtersSubMenu() { @@ -949,8 +959,8 @@ export class PropertiesView extends React.Component { searchFilterDocs={returnEmptyDoclist} ContainingCollectionView={undefined} ContainingCollectionDoc={undefined} - filterSaveCallback={this.saveFilter} - myFiltersCallback={this.myFiltersSelect} + createNewFilterDoc={this.createNewFilterDoc} + updateFilterDoc={this.updateFilterDoc} docViewPath={returnEmptyDoclist} layerProvider={undefined} /> diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index f99eb1b3b..ee4df97ed 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -120,8 +120,8 @@ export interface DocumentViewSharedProps { cantBrush?: boolean; // whether the document doesn't show brush highlighting pointerEvents?: string; scriptContext?: any; // can be assigned anything and will be passed as 'scriptContext' to any OnClick script that executes on this document - filterSaveCallback?: () => void; - myFiltersCallback?: (doc: Doc) => void; + createNewFilterDoc?: () => void; + updateFilterDoc?: (doc: Doc) => void; } export interface DocumentViewProps extends DocumentViewSharedProps { // properties specific to DocumentViews but not to FieldView diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index 987939d65..a3a3ec662 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -48,7 +48,7 @@ export class FilterBox extends ViewBoxBaseComponent(); @@ -309,7 +309,7 @@ export class FilterBox extends ViewBoxBaseComponent { // console.log("mapping"); return <> -
e.stopPropagation()} style={{ height: 50, border: "2px" }} onPointerDown={() => this.props.myFiltersCallback?.(doc)}> +
e.stopPropagation()} style={{ height: 50, border: "2px" }} onPointerDown={() => this.props.updateFilterDoc?.(doc)}> {StrCast(doc.title)}
; @@ -419,7 +419,7 @@ export class FilterBox extends ViewBoxBaseComponent
NEW
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 9b539d1b7..4cc0925a9 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -1065,7 +1065,7 @@ export namespace Doc { // based on the modifiers :"check", "x", undefined export function setDocFilter(target: Opt, key: string, value: any, modifiers?: "remove" | "match" | "check" | "x" | undefined) { const container = target ?? FilterBox._filterScope === "Current Collection" ? SelectionManager.Views()[0].Document || CollectionDockingView.Instance.props.Document : CollectionDockingView.Instance.props.Document; - const docFilters = Cast(SelectionManager.Views()[0].Document._docFilters, listSpec("string"), []); + const docFilters = Cast(container._docFilters, listSpec("string"), []); runInAction(() => { for (let i = 0; i < docFilters.length; i++) { const fields = docFilters[i].split(":"); // split key:value:modifier -- cgit v1.2.3-70-g09d2 From 59044880fcf0eb5ed4ca164de4c533fb7e6378a7 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Wed, 3 Mar 2021 11:18:47 -0500 Subject: minor changes --- src/client/util/CurrentUserUtils.ts | 4 ++-- src/client/views/nodes/FilterBox.tsx | 20 +++++++++++--------- 2 files changed, 13 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index a2f59e48f..0f7c2571b 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -809,9 +809,9 @@ export class CurrentUserUtils { if (doc.currentFilter === undefined) { doc.currentFilter = Docs.Create.FilterDocument({ title: "FilterDoc", _height: 20, - treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _yPadding: 10, forceActive: true, childDropAction: "none", + treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _yPadding: 10, _forceActive: true, childDropAction: "none", treeViewTruncateTitleWidth: 90, treeViewPreventOpen: false, ignoreClick: true, - lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true + _lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true }); const clearAll = ScriptField.MakeScript(`getProto(self).data = new List([])`); (doc.currentFilter as any as Doc).contextMenuScripts = new List([clearAll!]); diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index b25d78a1e..a4ae0b5a3 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -43,7 +43,8 @@ export class FilterBox extends ViewBoxBaseComponent) { super(props); FilterBox.Instance = this; - if (!CollectionDockingView.Instance.props.Document.currentFilter) CurrentUserUtils.setupFilterDocs(CollectionDockingView.Instance.props.Document); + const targetDoc = FilterBox._filterScope === "Current Collection" ? SelectionManager.Views()[0].Document || CollectionDockingView.Instance.props.Document : CollectionDockingView.Instance.props.Document; + if (!targetDoc) CurrentUserUtils.setupFilterDocs(targetDoc); } public static LayoutString(fieldKey: string) { return FieldView.LayoutString(FilterBox, fieldKey); } @@ -51,16 +52,20 @@ export class FilterBox extends ViewBoxBaseComponent(); @observable private showFilterDialog = false; + @computed get targetDoc() { + return FilterBox._filterScope === "Current Collection" ? SelectionManager.Views()[0].Document || CollectionDockingView.Instance.props.Document : CollectionDockingView.Instance.props.Document; + } + @computed get allDocs() { const allDocs = new Set(); - if (CollectionDockingView.Instance) { - const activeTabs = DocListCast(CollectionDockingView.Instance.props.Document.data); + const targetDoc = FilterBox._filterScope === "Current Collection" ? SelectionManager.Views()[0].Document || CollectionDockingView.Instance.props.Document : CollectionDockingView.Instance.props.Document; + if (targetDoc) { + const activeTabs = DocListCast(targetDoc.data); SearchBox.foreachRecursiveDoc(activeTabs, (doc: Doc) => allDocs.add(doc)); - setTimeout(() => CollectionDockingView.Instance.props.Document.allDocuments = new List(Array.from(allDocs))); + setTimeout(() => targetDoc.allDocuments = new List(Array.from(allDocs))); } return allDocs; } @@ -123,8 +128,6 @@ export class FilterBox extends ViewBoxBaseComponent { console.log("remove filter"); const targetDoc = FilterBox._filterScope === "Current Collection" ? SelectionManager.Views()[0].Document || CollectionDockingView.Instance.props.Document : CollectionDockingView.Instance.props.Document; - // const targetDoc = SelectionManager.Views()[0].props.Document; - // const targetDoc = SelectionManager.Views()[0].Document; // CollectionDockingView.Instance.props.Document; const filterDoc = targetDoc.currentFilter as Doc; const attributes = DocListCast(filterDoc["data"]); const found = attributes.findIndex(doc => doc.title === filterName); @@ -175,7 +178,7 @@ export class FilterBox extends ViewBoxBaseComponent { if (this._filterSelected) { -- cgit v1.2.3-70-g09d2 From 1c6a3568005bb25541d45db4b53f1955ff3b0e39 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Thu, 11 Mar 2021 16:22:09 -0500 Subject: adding and/or to filtering, added editableview, changed a bunch of things --- debug.log | 3 - src/client/documents/Documents.ts | 29 +++- src/client/views/PropertiesView.tsx | 1 + src/client/views/collections/CollectionSubView.tsx | 2 +- src/client/views/nodes/FilterBox.tsx | 176 ++++++++++----------- src/fields/Doc.ts | 10 +- 6 files changed, 114 insertions(+), 107 deletions(-) delete mode 100644 debug.log (limited to 'src') diff --git a/debug.log b/debug.log deleted file mode 100644 index ff92d4544..000000000 --- a/debug.log +++ /dev/null @@ -1,3 +0,0 @@ -[0122/125519.017:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) -[0122/192130.891:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) -[0123/134808.113:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 1726c42d3..5ceb62cbe 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -987,6 +987,13 @@ export namespace DocUtils { } return false; } + /** + * @param docs + * @param docFilters + * @param docRangeFilters + * @param viewSpecScript + * Given a list of docs and docFilters, @returns the list of Docs that match those filters + */ export function FilterDocs(docs: Doc[], docFilters: string[], docRangeFilters: string[], viewSpecScript?: ScriptField) { const childDocs = viewSpecScript ? docs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result) : docs; if (!docFilters?.length && !docRangeFilters?.length) { @@ -1011,14 +1018,19 @@ export namespace DocUtils { if (d.cookies && (!filterFacets.cookies || !Object.keys(filterFacets.cookies).some(key => d.cookies === key))) { return false; } + + console.log(FilterBox._filterBoolean); for (const facetKey of Object.keys(filterFacets).filter(fkey => fkey !== "cookies")) { const facet = filterFacets[facetKey]; + console.log(facet) const matches = Object.keys(facet).filter(value => value !== "cookies" && facet[value] === "match"); const checks = Object.keys(facet).filter(value => facet[value] === "check"); const xs = Object.keys(facet).filter(value => facet[value] === "x"); + + if (!xs.length && !checks.length && !matches.length) return true; const failsNotEqualFacets = !xs.length ? false : xs.some(value => Doc.matchFieldValue(d, facetKey, value)); const satisfiesCheckFacets = !checks.length ? true : checks.some(value => Doc.matchFieldValue(d, facetKey, value)); - const satisfiesMatchFacets = !matches.length ? true : matches.some(value => { + const satisfiesMatchFacets = matches.some(value => { if (facetKey.startsWith("*")) { // fields starting with a '*' are used to match families of related fields. ie, *lastModified will match text-lastModified, data-lastModified, etc const allKeys = Array.from(Object.keys(d)); allKeys.push(...Object.keys(Doc.GetProto(d))); @@ -1027,11 +1039,20 @@ export namespace DocUtils { } return Field.toString(d[facetKey] as Field).includes(value); }); - if (!satisfiesCheckFacets || !satisfiesMatchFacets || failsNotEqualFacets) { - return false; + console.log(satisfiesCheckFacets, failsNotEqualFacets); + if (FilterBox._filterBoolean === "OR") { + if (satisfiesCheckFacets && !failsNotEqualFacets) { + return true; + } } + else { + if (!satisfiesCheckFacets || failsNotEqualFacets) { + return false; + } + } + } - return true; + return FilterBox._filterBoolean === "OR" ? false : true; }) : childDocs; const rangeFilteredDocs = filteredDocs.filter(d => { for (let i = 0; i < docRangeFilters.length; i += 3) { diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 4b6f1c912..499d8ff0c 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -913,6 +913,7 @@ export class PropertiesView extends React.Component { } updateFilterDoc = (doc: Doc) => { + if (doc === this.filterDoc.currentFilter) return; // causes problems if you try to reapply the same doc const temp = doc._docFiltersList; const otherTemp = this.filterDoc._docFilters; this.filterDoc._docFilters = new List(); diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 59e1824c1..8b7782948 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -118,7 +118,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: const docsforFilter: Doc[] = []; childDocs.forEach((d) => { - if (DocUtils.Excluded(d, docFilters)) return; + // if (DocUtils.Excluded(d, docFilters)) return; let notFiltered = d.z || ((!searchDocs.length || searchDocs.includes(d)) && (DocUtils.FilterDocs([d], docFilters, docRangeFilters, viewSpecScript).length > 0)); const fieldKey = Doc.LayoutFieldKey(d); const annos = !Field.toString(Doc.LayoutField(d) as Field).includes("CollectionView"); diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index 569f0d23b..88bb91b38 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -9,7 +9,7 @@ import { RichTextField } from "../../../fields/RichTextField"; import { listSpec, makeInterface } from "../../../fields/Schema"; import { ComputedField, ScriptField } from "../../../fields/ScriptField"; import { Cast, StrCast } from "../../../fields/Types"; -import { emptyFunction, emptyPath, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, returnZero, returnTrue } from "../../../Utils"; +import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from "../../../Utils"; import { Docs } from "../../documents/Documents"; import { DocumentType } from "../../documents/DocumentTypes"; import { CollectionDockingView } from "../collections/CollectionDockingView"; @@ -29,6 +29,7 @@ import { DocumentViewProps } from "./DocumentView"; import { DefaultStyleProvider, StyleProp } from "../StyleProvider"; import { CollectionViewType } from "../collections/CollectionView"; import { CurrentUserUtils } from "../../util/CurrentUserUtils"; +import { EditableView } from "../EditableView"; type FilterBoxDocument = makeInterface<[typeof documentSchema]>; const FilterBoxDocument = makeInterface(documentSchema); @@ -36,23 +37,21 @@ const FilterBoxDocument = makeInterface(documentSchema); @observer export class FilterBox extends ViewBoxBaseComponent(FilterBoxDocument) { - static Instance: FilterBox; - constructor(props: Readonly) { super(props); - FilterBox.Instance = this; - const targetDoc = FilterBox._filterScope === "Current Collection" ? SelectionManager.Views()[0].Document || CollectionDockingView.Instance.props.Document : CollectionDockingView.Instance.props.Document; + const targetDoc = this.targetDoc; if (!targetDoc) CurrentUserUtils.setupFilterDocs(targetDoc); } public static LayoutString(fieldKey: string) { return FieldView.LayoutString(FilterBox, fieldKey); } - public _filterBoolean = "AND"; - @observable public static _filterScope = "Current Dashboard"; + @observable static _filterBoolean = "AND"; + @observable static _filterScope = "Current Dashboard"; public _filterSelected = false; public _filterMatch = "matched"; - @observable private showFilterDialog = false; - + /** + * @returns the relevant doc according to the value of FilterBox._filterScope i.e. either the Current Dashboard or the Current Collection + */ @computed get targetDoc() { return FilterBox._filterScope === "Current Collection" ? SelectionManager.Views()[0].Document || CollectionDockingView.Instance.props.Document : CollectionDockingView.Instance.props.Document; } @@ -69,8 +68,9 @@ export class FilterBox extends ViewBoxBaseComponent(); - const targetDoc = FilterBox._filterScope === "Current Collection" ? SelectionManager.Views()[0].Document || CollectionDockingView.Instance.props.Document : CollectionDockingView.Instance.props.Document; + const targetDoc = this.targetDoc; if (this._loaded && targetDoc) { + // if (targetDoc) { const activeTabs = DocListCast(targetDoc.data); SearchBox.foreachRecursiveDoc(activeTabs, (doc: Doc) => allDocs.add(doc)); setTimeout(() => targetDoc.allDocuments = new List(Array.from(allDocs))); @@ -97,6 +97,9 @@ export class FilterBox extends ViewBoxBaseComponent StrCast(attribute.title)); } @@ -121,7 +124,7 @@ export class FilterBox extends ViewBoxBaseComponent { const facetVal = t[facetKey]; if (facetVal instanceof RichTextField) rtFields++; - facetVal && valueSet.add(Field.toString(facetVal as Field)); + facetVal !== undefined && valueSet.add(Field.toString(facetVal as Field)); const fieldKey = Doc.LayoutFieldKey(t); const annos = !Field.toString(Doc.LayoutField(t) as Field).includes("CollectionView"); DocListCast(t[annos ? fieldKey + "-annotations" : fieldKey]).forEach((newdoc) => newarray.push(newdoc)); @@ -136,7 +139,7 @@ export class FilterBox extends ViewBoxBaseComponent { console.log("remove filter"); - const targetDoc = FilterBox._filterScope === "Current Collection" ? SelectionManager.Views()[0].Document || CollectionDockingView.Instance.props.Document : CollectionDockingView.Instance.props.Document; + const targetDoc = this.targetDoc; const filterDoc = targetDoc.currentFilter as Doc; const attributes = DocListCast(filterDoc["data"]); const found = attributes.findIndex(doc => doc.title === filterName); @@ -166,26 +169,25 @@ export class FilterBox extends ViewBoxBaseComponent doc.title === facetHeader); if (found !== -1) { - // (this.dataDoc[this.props.fieldKey] as List).splice(found, 1); - // const docFilter = Cast(targetDoc._docFilters, listSpec("string")); - // if (docFilter) { - // let index: number; - // while ((index = docFilter.findIndex(item => item.split(":")[0] === facetHeader)) !== -1) { - // docFilter.splice(index, 1); - // } - // } - // const docRangeFilters = Cast(targetDoc._docRangeFilters, listSpec("string")); - // if (docRangeFilters) { - // let index: number; - // while ((index = docRangeFilters.findIndex(item => item.split(":")[0] === facetHeader)) !== -1) { - // docRangeFilters.splice(index, 3); - // } - // } + // comment this bit out later once the x works in treeview + (this.dataDoc[this.props.fieldKey] as List).splice(found, 1); + const docFilter = Cast(targetDoc._docFilters, listSpec("string")); + if (docFilter) { + let index: number; + while ((index = docFilter.findIndex(item => item.split(":")[0] === facetHeader)) !== -1) { + docFilter.splice(index, 1); + } + } + const docRangeFilters = Cast(targetDoc._docRangeFilters, listSpec("string")); + if (docRangeFilters) { + let index: number; + while ((index = docRangeFilters.findIndex(item => item.split(":")[0] === facetHeader)) !== -1) { + docRangeFilters.splice(index, 3); + } + } } else { const allCollectionDocs = DocListCast((targetDoc.data as any)[0].data); const facetValues = this.gatherFieldValues(targetDoc, facetHeader); @@ -208,6 +210,8 @@ export class FilterBox extends ViewBoxBaseComponent { - this._filterBoolean = e.currentTarget.value; - console.log(this._filterBoolean); + FilterBox._filterBoolean = e.currentTarget.value; } @action changeScope = (e: any) => { FilterBox._filterScope = e.currentTarget.value; - console.log(FilterBox._filterScope); } @action changeMatch = (e: any) => { this._filterMatch = e.currentTarget.value; - console.log(this._filterMatch); } @action changeSelected = () => { @@ -266,7 +269,6 @@ export class FilterBox extends ViewBoxBaseComponent, props: Opt, property: string) { @@ -294,51 +296,62 @@ export class FilterBox extends ViewBoxBaseComponent ScriptField.MakeScript("")!; saveFilter = () => { - // const doc: Doc = new Doc; - // for (const key of Object.keys(this.props.Document)) { - // doc[key] = SerializationHelper.Serialize(this.props.Document[key] as Field); - // } - // console.log(doc); - runInAction(() => this.showFilterDialog = true); + Doc.AddDocToList(Doc.UserDoc(), "savedFilters", this.props.Document); console.log("saved filter"); } - onTitleValueChange = (e: React.ChangeEvent) => { - this.props.Document.title = e.currentTarget.value || `FilterDoc for ${SelectionManager.Views()[0].Document.title}`; + onTitleValueChange = (val: string) => { + this.props.Document.title = val || `FilterDoc for ${SelectionManager.Views()[0].Document.title}`; + return true; } - onKeyDown = (e: React.KeyboardEvent) => { - if (e.key === "Enter") { - runInAction(() => this.showFilterDialog = false); - Doc.AddDocToList(Doc.UserDoc(), "savedFilters", this.props.Document); - } - } - - render() { - const facetCollection = this.props.Document; - - const flyout = DocListCast(Doc.UserDoc().savedFilters).map(doc => { + @computed get flyoutPanel() { + return DocListCast(Doc.UserDoc().savedFilters).map(doc => { // console.log("mapping"); return <> -
e.stopPropagation()} style={{ height: 50, border: "2px" }} onPointerDown={() => this.props.updateFilterDoc?.(doc)}> +
e.stopPropagation()} style={{ height: 50, border: "2px" }} onPointerDown={() => this.props.updateFilterDoc?.(doc)}> {StrCast(doc.title)}
; } ); + } - const options = this._allFacets.filter(facet => this.currentFacets.indexOf(facet) === -1).map(facet => ({ value: facet, label: facet })); + render() { + const facetCollection = this.props.Document; + // const flyout = DocListCast(Doc.UserDoc().savedFilters).map(doc => { + // // console.log("mapping"); + // return <> + //
e.stopPropagation()} style={{ height: 50, border: "2px" }} onPointerDown={() => this.props.updateFilterDoc?.(doc)}> + // {StrCast(doc.title)} + //
+ // ; + // } + // ); + // TODO uncomment the line below when the treeview x works + // const options = this._allFacets.filter(facet => this.currentFacets.indexOf(facet) === -1).map(facet => ({ value: facet, label: facet })); + const options = this._allFacets.map(facet => ({ value: facet, label: facet })); return this.props.dontRegisterView ? (null) :
-
Current FilterDoc: {this.props.Document.title}
+
+ StrCast(this.props.Document.title)} + SetValue={this.onTitleValueChange} + /> +
+
-
filters in
- {/* */} @@ -354,26 +367,6 @@ export class FilterBox extends ViewBoxBaseComponent - {/* @computed get flyoutpanel() { - return
e.stopPropagation()}> - {this._allFacets.map(facet => )} -
; - } - render() { - const facetCollection = this.props.Document; - - return this.props.dontRegisterView ? (null) :
-
e.stopPropagation()}> - -
- - Choose Facets -
-
*/}
@@ -444,7 +437,7 @@ export class FilterBox extends ViewBoxBaseComponent
- +
FILTERS
@@ -457,14 +450,6 @@ export class FilterBox extends ViewBoxBaseComponent
- {!this.showFilterDialog ? (null) : - - }
; } @@ -480,7 +465,7 @@ Scripting.addGlobal(function determineCheckedState(layoutDoc: Doc, facetHeader: } return undefined; }); -Scripting.addGlobal(function readFacetData(targetDoc: Doc, facetHeader: string) { +Scripting.addGlobal(function readFacetData(layoutDoc: Doc, facetHeader: string) { const allCollectionDocs = DocListCast(CollectionDockingView.Instance?.props.Document.allDocuments); const set = new Set(); if (facetHeader === "tags") allCollectionDocs.forEach(child => Field.toString(child[facetHeader] as Field).split(":").forEach(key => set.add(key))); @@ -493,10 +478,11 @@ Scripting.addGlobal(function readFacetData(targetDoc: Doc, facetHeader: string) const doc = new Doc(); doc.system = true; doc.title = facetValue.toString(); - doc.target = targetDoc; - doc.facetHeader = facetHeader; - doc.facetValue = facetValue; - doc.treeViewChecked = ComputedField.MakeFunction("determineCheckedState(self.target, self.facetHeader, self.facetValue)"); + doc.treeViewChecked = ComputedField.MakeFunction("determineCheckedState(layoutDoc, facetHeader, facetValue)", {}, { layoutDoc, facetHeader, facetValue }); + // doc.target = layoutDoc; + // doc.facetHeader = facetHeader; + // doc.facetValue = facetValue; + // doc.treeViewChecked = ComputedField.MakeFunction("determineCheckedState(self.target, self.facetHeader, self.facetValue)"); return doc; }); return new List(facetValueDocSet); diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 75d15c409..b0d77f0de 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -1049,7 +1049,7 @@ export namespace Doc { doc.layoutKey = deiconify || "layout"; } export function setDocFilterRange(target: Doc, key: string, range?: number[]) { - const container = target ?? CollectionDockingView.Instance.props.Document; + const container = target ?? FilterBox._filterScope === "Current Collection" ? SelectionManager.Views()[0].Document || CollectionDockingView.Instance.props.Document : CollectionDockingView.Instance.props.Document; const docRangeFilters = Cast(container._docRangeFilters, listSpec("string"), []); for (let i = 0; i < docRangeFilters.length; i += 3) { if (docRangeFilters[i] === key) { @@ -1065,9 +1065,11 @@ export namespace Doc { } } - // filters document in a container collection: - // all documents with the specified value for the specified key are included/excluded - // based on the modifiers :"check", "x", undefined + /** + * Filters document in a container collection: + * all documents with the specified value for the specified key are included/excluded + * based on the modifiers :"check", "x", undefined + */ export function setDocFilter(target: Opt, key: string, value: any, modifiers?: "remove" | "match" | "check" | "x" | undefined) { const container = target ?? FilterBox._filterScope === "Current Collection" ? SelectionManager.Views()[0].Document || CollectionDockingView.Instance.props.Document : CollectionDockingView.Instance.props.Document; const docFilters = Cast(container._docFilters, listSpec("string"), []); -- cgit v1.2.3-70-g09d2 From 983957cf513b355d043ad8a712475f344eb7b553 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Thu, 11 Mar 2021 16:51:48 -0500 Subject: bringing errors back --- src/client/views/nodes/FilterBox.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index 88bb91b38..8f8e087f6 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -478,11 +478,11 @@ Scripting.addGlobal(function readFacetData(layoutDoc: Doc, facetHeader: string) const doc = new Doc(); doc.system = true; doc.title = facetValue.toString(); - doc.treeViewChecked = ComputedField.MakeFunction("determineCheckedState(layoutDoc, facetHeader, facetValue)", {}, { layoutDoc, facetHeader, facetValue }); - // doc.target = layoutDoc; - // doc.facetHeader = facetHeader; - // doc.facetValue = facetValue; - // doc.treeViewChecked = ComputedField.MakeFunction("determineCheckedState(self.target, self.facetHeader, self.facetValue)"); + // doc.treeViewChecked = ComputedField.MakeFunction("determineCheckedState(layoutDoc, facetHeader, facetValue)", {}, { layoutDoc, facetHeader, facetValue }); + doc.target = layoutDoc; + doc.facetHeader = facetHeader; + doc.facetValue = facetValue; + doc.treeViewChecked = ComputedField.MakeFunction("determineCheckedState(self.target, self.facetHeader, self.facetValue)"); return doc; }); return new List(facetValueDocSet); -- cgit v1.2.3-70-g09d2 From 795616a0f2e12b74cfd634837610c5a678473160 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 11 Mar 2021 22:05:11 -0500 Subject: fixed problem with filter box for dashboard not staying checked. --- src/client/views/nodes/FilterBox.tsx | 1 - src/fields/Doc.ts | 10 +++------- 2 files changed, 3 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index 8f8e087f6..65d2fe618 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -478,7 +478,6 @@ Scripting.addGlobal(function readFacetData(layoutDoc: Doc, facetHeader: string) const doc = new Doc(); doc.system = true; doc.title = facetValue.toString(); - // doc.treeViewChecked = ComputedField.MakeFunction("determineCheckedState(layoutDoc, facetHeader, facetValue)", {}, { layoutDoc, facetHeader, facetValue }); doc.target = layoutDoc; doc.facetHeader = facetHeader; doc.facetValue = facetValue; diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index b0d77f0de..780be51a0 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -9,7 +9,6 @@ import { Scripting, scriptingGlobal } from "../client/util/Scripting"; import { SelectionManager } from "../client/util/SelectionManager"; import { afterDocDeserialize, autoObject, Deserializable, SerializationHelper } from "../client/util/SerializationHelper"; import { UndoManager } from "../client/util/UndoManager"; -import { CollectionDockingView } from "../client/views/collections/CollectionDockingView"; import { intersectRect, Utils } from "../Utils"; import { DateField } from "./DateField"; import { Copy, HandleUpdate, Id, OnUpdate, Parent, Self, SelfProxy, ToScriptString, ToString, Update } from "./FieldSymbols"; @@ -25,8 +24,6 @@ import { Cast, FieldValue, NumCast, StrCast, ToConstructor } from "./Types"; import { AudioField, ImageField, PdfField, VideoField, WebField } from "./URLField"; import { deleteProperty, GetEffectiveAcl, getField, getter, makeEditable, makeReadOnly, normalizeEmail, setter, SharingPermissions, updateFunction } from "./util"; import JSZip = require("jszip"); -import { FilterBox } from "../client/views/nodes/FilterBox"; -import { prefix } from "@fortawesome/free-regular-svg-icons"; export namespace Field { export function toKeyValueString(doc: Doc, key: string): string { @@ -1048,8 +1045,7 @@ export namespace Doc { prevLayout === "icon" && (doc.deiconifyLayout = undefined); doc.layoutKey = deiconify || "layout"; } - export function setDocFilterRange(target: Doc, key: string, range?: number[]) { - const container = target ?? FilterBox._filterScope === "Current Collection" ? SelectionManager.Views()[0].Document || CollectionDockingView.Instance.props.Document : CollectionDockingView.Instance.props.Document; + export function setDocFilterRange(container: Doc, key: string, range?: number[]) { const docRangeFilters = Cast(container._docRangeFilters, listSpec("string"), []); for (let i = 0; i < docRangeFilters.length; i += 3) { if (docRangeFilters[i] === key) { @@ -1070,8 +1066,8 @@ export namespace Doc { * all documents with the specified value for the specified key are included/excluded * based on the modifiers :"check", "x", undefined */ - export function setDocFilter(target: Opt, key: string, value: any, modifiers?: "remove" | "match" | "check" | "x" | undefined) { - const container = target ?? FilterBox._filterScope === "Current Collection" ? SelectionManager.Views()[0].Document || CollectionDockingView.Instance.props.Document : CollectionDockingView.Instance.props.Document; + export function setDocFilter(container: Opt, key: string, value: any, modifiers?: "remove" | "match" | "check" | "x" | undefined) { + if (!container) return; const docFilters = Cast(container._docFilters, listSpec("string"), []); runInAction(() => { for (let i = 0; i < docFilters.length; i++) { -- cgit v1.2.3-70-g09d2 From 8811fb0f177ed1448fa7b3d08ff42145254a0475 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Sun, 14 Mar 2021 21:21:05 -0400 Subject: minor --- .gitignore | 3 ++- src/client/views/PropertiesView.tsx | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/.gitignore b/.gitignore index aeb343fd1..43b63a362 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,5 @@ src/server/session_manager/logs/**/*.log *.key *.pfx *.properties -debug.log \ No newline at end of file +debug.log +.vscodeignore \ No newline at end of file diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 128256733..8bffb0778 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -919,6 +919,9 @@ export class PropertiesView extends React.Component { CurrentUserUtils.setupFilterDocs(this.filterDoc); } + /** + * Updates this.filterDoc's currentFilter and saves the docFilters on the currentFilter + */ updateFilterDoc = (doc: Doc) => { if (doc === this.filterDoc.currentFilter) return; // causes problems if you try to reapply the same doc const temp = doc._docFiltersList; @@ -953,7 +956,7 @@ export class PropertiesView extends React.Component { removeDocument={returnFalse} ScreenToLocalTransform={this.getTransform} PanelWidth={this.docWidth} - PanelHeight={() => this.docHeight} + PanelHeight={this.docHeight} renderDepth={0} scriptContext={this.filterDoc.currentFilter as Doc} focus={emptyFunction} -- cgit v1.2.3-70-g09d2 From 7c6ccf0c6dce1b778163f03ae271b3c17896a560 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Wed, 17 Mar 2021 01:30:02 -0400 Subject: starting process of addingfilter attributes to new docs in collection --- src/client/documents/Documents.ts | 25 ++++++++++++------------- src/client/views/PropertiesView.scss | 4 ++-- src/client/views/collections/CollectionView.tsx | 16 ++++++++++++++++ src/client/views/nodes/FilterBox.tsx | 10 +++++----- 4 files changed, 35 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 0f1abb3ac..c13a69402 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -636,9 +636,7 @@ export namespace Docs { protoProps.system = delegateProps.system; - if (!("author" in protoProps)) { - protoProps.author = Doc.CurrentUserEmail; - } + if (!("author" in protoProps)) protoProps.author = Doc.CurrentUserEmail; if (!("creationDate" in protoProps)) { protoProps.creationDate = new DateField; @@ -1019,18 +1017,22 @@ export namespace DocUtils { return false; } - console.log(FilterBox._filterBoolean); for (const facetKey of Object.keys(filterFacets).filter(fkey => fkey !== "cookies")) { const facet = filterFacets[facetKey]; - console.log(facet) + + // facets that match some value in the field of the document (e.g. some text field) const matches = Object.keys(facet).filter(value => value !== "cookies" && facet[value] === "match"); + + // facets that have a check next to them const checks = Object.keys(facet).filter(value => facet[value] === "check"); + + // facets that have an x next to them const xs = Object.keys(facet).filter(value => facet[value] === "x"); if (!xs.length && !checks.length && !matches.length) return true; const failsNotEqualFacets = !xs.length ? false : xs.some(value => Doc.matchFieldValue(d, facetKey, value)); const satisfiesCheckFacets = !checks.length ? true : checks.some(value => Doc.matchFieldValue(d, facetKey, value)); - const satisfiesMatchFacets = matches.some(value => { + const satisfiesMatchFacets = !matches.length ? true : matches.some(value => { if (facetKey.startsWith("*")) { // fields starting with a '*' are used to match families of related fields. ie, *lastModified will match text-lastModified, data-lastModified, etc const allKeys = Array.from(Object.keys(d)); allKeys.push(...Object.keys(Doc.GetProto(d))); @@ -1039,16 +1041,13 @@ export namespace DocUtils { } return Field.toString(d[facetKey] as Field).includes(value); }); - console.log(satisfiesCheckFacets, failsNotEqualFacets); + // if we're ORing them together, the default return is false, and we return true for a doc if it satisfies any one set of criteria if (FilterBox._filterBoolean === "OR") { - if (satisfiesCheckFacets && !failsNotEqualFacets) { - return true; - } + if (satisfiesCheckFacets && !failsNotEqualFacets && satisfiesMatchFacets) return true; } + // if we're ANDing them together, the default return is true, and we return false for a doc if it doesn't satisfy any set of criteria else { - if (!satisfiesCheckFacets || failsNotEqualFacets) { - return false; - } + if (!satisfiesCheckFacets || failsNotEqualFacets || (matches.length && satisfiesMatchFacets)) return false; } } diff --git a/src/client/views/PropertiesView.scss b/src/client/views/PropertiesView.scss index 1d52136de..7c6d507b8 100644 --- a/src/client/views/PropertiesView.scss +++ b/src/client/views/PropertiesView.scss @@ -191,8 +191,8 @@ font-size: 10px; padding: 10px; margin-left: 5px; - // max-height: 40%; - overflow-y: visible; + max-height: 40%; + overflow-y: scroll; .propertiesView-buttonContainer { float: right; diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 34fd20f1a..4f37747b0 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -38,6 +38,8 @@ import { SubCollectionViewProps } from './CollectionSubView'; import { CollectionTimeView } from './CollectionTimeView'; import { CollectionTreeView } from "./CollectionTreeView"; import './CollectionView.scss'; +import { FilterBox } from '../nodes/FilterBox'; +import { listSpec } from '../../../fields/Schema'; export const COLLECTION_BORDER_WIDTH = 2; const path = require('path'); @@ -116,6 +118,19 @@ export class CollectionView extends Touchable { whenActiveChanged = (isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive); + /** + * Applies the collection/dashboard's current filter attributes to the doc being added + */ + addFilterAttributes = (doc: Doc) => { + Cast(FilterBox.targetDoc._docFilters, listSpec("string"))?.forEach(attribute => { + if (attribute.charAt(0).toUpperCase() === attribute.charAt(0)) { + const fields = attribute.split(':'); + if (fields[2] === "check") doc[DataSym][fields[0]] = fields[1]; + else if (fields[2] === "x" && doc[DataSym][fields[0]] === fields[1]) doc[DataSym][fields[0]] = undefined; + } + }); + } + @action.bound addDocument = (doc: Doc | Doc[]): boolean => { if (this.props.filterAddDocument?.(doc) === false) { @@ -157,6 +172,7 @@ export class CollectionView extends Touchable { DocUtils.LeavePushpin(doc); doc._stayInCollection = undefined; doc.context = this.props.Document; + this.addFilterAttributes(doc); // }); added.map(doc => this.props.layerProvider?.(doc, true));// assigns layer values to the newly added document... testing the utility of this (targetDataDoc[this.props.fieldKey] as List).push(...added); diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index 41e274e7a..541693cdf 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -39,7 +39,7 @@ export class FilterBox extends ViewBoxBaseComponent) { super(props); - const targetDoc = this.targetDoc; + const targetDoc = FilterBox.targetDoc; if (!targetDoc) CurrentUserUtils.setupFilterDocs(targetDoc); } public static LayoutString(fieldKey: string) { return FieldView.LayoutString(FilterBox, fieldKey); } @@ -52,7 +52,7 @@ export class FilterBox extends ViewBoxBaseComponent(); - const targetDoc = this.targetDoc; + const targetDoc = FilterBox.targetDoc; if (this._loaded && targetDoc) { // if (targetDoc) { const activeTabs = DocListCast(targetDoc.data); @@ -140,7 +140,7 @@ export class FilterBox extends ViewBoxBaseComponent { console.log("remove filter"); - const targetDoc = this.targetDoc; + const targetDoc = FilterBox.targetDoc; const filterDoc = targetDoc.currentFilter as Doc; const attributes = DocListCast(filterDoc["data"]); const found = attributes.findIndex(doc => doc.title === filterName); @@ -170,7 +170,7 @@ export class FilterBox extends ViewBoxBaseComponent doc.title === facetHeader); if (found !== -1) { // comment this bit out later once the x works in treeview -- cgit v1.2.3-70-g09d2 From 9c612838c775a6fa9737963618aeebbc427e794c Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Wed, 17 Mar 2021 21:56:31 -0400 Subject: converted dockingview.instance to dashboard + started commenting --- src/client/views/PropertiesView.tsx | 11 +++--- src/client/views/nodes/FilterBox.tsx | 73 +++++++++++++++++++++++++++--------- 2 files changed, 61 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 8bffb0778..c677478cb 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -51,7 +51,7 @@ export class PropertiesView extends React.Component { @computed get selectedDoc() { return SelectionManager.SelectedSchemaDoc() || this.selectedDocumentView?.rootDoc; } @computed get filterDoc() { - return FilterBox._filterScope === "Current Collection" ? this.selectedDoc || CollectionDockingView.Instance.props.Document : CollectionDockingView.Instance.props.Document; + return FilterBox.targetDoc; } @computed get selectedDocumentView() { if (SelectionManager.Views().length) return SelectionManager.Views()[0]; @@ -59,8 +59,7 @@ export class PropertiesView extends React.Component { return undefined; } @computed get isPres(): boolean { - if (this.selectedDoc?.type === DocumentType.PRES) return true; - return false; + return this.selectedDoc?.type === DocumentType.PRES; } @computed get dataDoc() { return this.selectedDoc?.[DataSym]; } @@ -934,7 +933,7 @@ export class PropertiesView extends React.Component { } @computed get filtersSubMenu() { - return
+ return !this.filterDoc?.currentFilter ? (null) :
this.openFilters = !this.openFilters)} style={{ backgroundColor: this.openFilters ? "black" : "" }}> @@ -944,7 +943,7 @@ export class PropertiesView extends React.Component {
{ - !this.openFilters || !this.filterDoc.currentFilter ? (null) : + !this.openFilters ? (null) :
{ {this.sharingSubMenu} - {this.selectedDoc.type === DocumentType.COL && this.filtersSubMenu} + {this.filtersSubMenu} {this.inkSubMenu} diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index 541693cdf..d410d2b33 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -40,7 +40,7 @@ export class FilterBox extends ViewBoxBaseComponent) { super(props); const targetDoc = FilterBox.targetDoc; - if (!targetDoc) CurrentUserUtils.setupFilterDocs(targetDoc); + if (targetDoc && !targetDoc.currentFilter) CurrentUserUtils.setupFilterDocs(targetDoc); } public static LayoutString(fieldKey: string) { return FieldView.LayoutString(FilterBox, fieldKey); } @@ -49,11 +49,43 @@ export class FilterBox extends ViewBoxBaseComponent(); const targetDoc = FilterBox.targetDoc; if (this._loaded && targetDoc) { - // if (targetDoc) { const activeTabs = DocListCast(targetDoc.data); SearchBox.foreachRecursiveDoc(activeTabs, (doc: Doc) => allDocs.add(doc)); setTimeout(() => targetDoc.allDocuments = new List(Array.from(allDocs))); @@ -247,20 +278,30 @@ export class FilterBox extends ViewBoxBaseComponent script : undefined; } + /** + * Changes the value of the variable that determines whether filters are ANDed or ORed together + */ @action changeBool = (e: any) => { FilterBox._filterBoolean = e.currentTarget.value; } + /** + * Changes the value of the variable that determines whether the filters should apply to the dashboard or the collection + */ @action changeScope = (e: any) => { FilterBox._filterScope = e.currentTarget.value; } + /** + * Changes whether to select matched or unmatched documents + */ @action changeMatch = (e: any) => { this._filterMatch = e.currentTarget.value; } + @action changeSelected = () => { if (this._filterSelected) { @@ -296,19 +337,26 @@ export class FilterBox extends ViewBoxBaseComponent ScriptField.MakeScript("")!; + /** + * Adds a filterDoc to the list of saved filters + */ saveFilter = () => { Doc.AddDocToList(Doc.UserDoc(), "savedFilters", this.props.Document); - console.log("saved filter"); } + /** + * Changes the title of the filterDoc + */ onTitleValueChange = (val: string) => { - this.props.Document.title = val || `FilterDoc for ${SelectionManager.Views()[0].Document.title}`; + this.props.Document.title = val || `FilterDoc for ${FilterBox.targetDoc.title}`; return true; } + /** + * The flyout from which you can select a saved filter to apply + */ @computed get flyoutPanel() { return DocListCast(Doc.UserDoc().savedFilters).map(doc => { - // console.log("mapping"); return <>
e.stopPropagation()} style={{ height: 50, border: "2px" }} onPointerDown={() => this.props.updateFilterDoc?.(doc)}> {StrCast(doc.title)} @@ -320,15 +368,6 @@ export class FilterBox extends ViewBoxBaseComponent { - // // console.log("mapping"); - // return <> - //
e.stopPropagation()} style={{ height: 50, border: "2px" }} onPointerDown={() => this.props.updateFilterDoc?.(doc)}> - // {StrCast(doc.title)} - //
- // ; - // } - // ); // TODO uncomment the line below when the treeview x works // const options = this._allFacets.filter(facet => this.currentFacets.indexOf(facet) === -1).map(facet => ({ value: facet, label: facet })); -- cgit v1.2.3-70-g09d2 From a8c02cba0bf96e435e062f2251890243ad8f49e0 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Wed, 17 Mar 2021 22:36:16 -0400 Subject: made and/or a property of the document so it's saved with the filter --- src/client/documents/Documents.ts | 4 ++-- src/client/util/CurrentUserUtils.ts | 5 +++-- src/client/views/PropertiesView.tsx | 3 +++ src/client/views/nodes/FilterBox.tsx | 9 ++++----- 4 files changed, 12 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 0d2f04569..ef6623f20 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -1040,7 +1040,7 @@ export namespace DocUtils { return Field.toString(d[facetKey] as Field).includes(value); }); // if we're ORing them together, the default return is false, and we return true for a doc if it satisfies any one set of criteria - if (FilterBox._filterBoolean === "OR") { + if ((FilterBox.targetDoc.currentFilter as Doc).filterBoolean === "OR") { if (satisfiesCheckFacets && !failsNotEqualFacets && satisfiesMatchFacets) return true; } // if we're ANDing them together, the default return is true, and we return false for a doc if it doesn't satisfy any set of criteria @@ -1049,7 +1049,7 @@ export namespace DocUtils { } } - return FilterBox._filterBoolean === "OR" ? false : true; + return (FilterBox.targetDoc.currentFilter as Doc).filterBoolean === "OR" ? false : true; }) : childDocs; const rangeFilteredDocs = filteredDocs.filter(d => { for (let i = 0; i < docRangeFilters.length; i += 3) { diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 88bb1207f..157a88de7 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -810,8 +810,9 @@ export class CurrentUserUtils { _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true }); const clearAll = ScriptField.MakeScript(`getProto(self).data = new List([])`); - (doc.currentFilter as any as Doc).contextMenuScripts = new List([clearAll!]); - (doc.currentFilter as any as Doc).contextMenuLabels = new List(["Clear All"]); + (doc.currentFilter as Doc).contextMenuScripts = new List([clearAll!]); + (doc.currentFilter as Doc).contextMenuLabels = new List(["Clear All"]); + (doc.currentFilter as Doc).filterBoolean = "AND"; } } diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index c677478cb..b4e15b536 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -74,6 +74,9 @@ export class PropertiesView extends React.Component { @observable openTransform: boolean = true; @observable openFilters: boolean = true; // should be false + /** + * autorun to set up the filter doc of a collection if that collection has been selected and the filters panel is open + */ private selectedDocListenerDisposer: Opt; // @observable selectedUser: string = ""; diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index d410d2b33..2ed3dc21f 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -44,7 +44,6 @@ export class FilterBox extends ViewBoxBaseComponent { - FilterBox._filterBoolean = e.currentTarget.value; + (FilterBox.targetDoc.currentFilter as Doc).filterBoolean = e.currentTarget.value; } /** @@ -388,8 +387,8 @@ export class FilterBox extends ViewBoxBaseComponent
filters in
select
@@ -465,7 +460,7 @@ export class FilterBox extends ViewBoxBaseComponentunmatched
documents
-
+
*/}
-- cgit v1.2.3-70-g09d2 From 4df769e20b9588fea61b602ec67ca2208fc3d747 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Thu, 25 Mar 2021 02:25:12 -0400 Subject: filters is going to kill me the files I should look at on return to this branch are documents.ts, propertiesview, colsubview, colview, filterbox --- src/client/documents/Documents.ts | 8 ++++---- src/client/views/PropertiesView.scss | 3 +-- src/client/views/PropertiesView.tsx | 2 +- src/client/views/collections/CollectionSubView.tsx | 14 ++++++++++---- src/client/views/collections/CollectionView.tsx | 2 +- src/client/views/nodes/FilterBox.tsx | 8 ++++---- 6 files changed, 21 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 0c16d9f8f..3e29a4edf 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -990,7 +990,7 @@ export namespace DocUtils { * @param viewSpecScript * Given a list of docs and docFilters, @returns the list of Docs that match those filters */ - export function FilterDocs(docs: Doc[], docFilters: string[], docRangeFilters: string[], viewSpecScript?: ScriptField) { + export function FilterDocs(docs: Doc[], docFilters: string[], docRangeFilters: string[], viewSpecScript?: ScriptField, parentCollection?: Doc) { const childDocs = viewSpecScript ? docs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result) : docs; if (!docFilters?.length && !docRangeFilters?.length) { return childDocs.filter(d => !d.cookies); // remove documents that need a cookie if there are no filters to provide one @@ -1040,16 +1040,16 @@ export namespace DocUtils { return Field.toString(d[facetKey] as Field).includes(value); }); // if we're ORing them together, the default return is false, and we return true for a doc if it satisfies any one set of criteria - if ((FilterBox.targetDoc.currentFilter as Doc).filterBoolean === "OR") { + if (((FilterBox._filterScope === "Current Collection" ? parentCollection || CurrentUserUtils.ActiveDashboard : CurrentUserUtils.ActiveDashboard).currentFilter as Doc)?.filterBoolean === "OR") { if (satisfiesCheckFacets && !failsNotEqualFacets && satisfiesMatchFacets) return true; } // if we're ANDing them together, the default return is true, and we return false for a doc if it doesn't satisfy any set of criteria else { - if (!satisfiesCheckFacets || failsNotEqualFacets || (matches.length && satisfiesMatchFacets)) return false; + if (!satisfiesCheckFacets || failsNotEqualFacets || (matches.length && !satisfiesMatchFacets)) return false; } } - return (FilterBox.targetDoc.currentFilter as Doc).filterBoolean === "OR" ? false : true; + return ((FilterBox._filterScope === "Current Collection" ? parentCollection || CurrentUserUtils.ActiveDashboard : CurrentUserUtils.ActiveDashboard).currentFilter as Doc)?.filterBoolean === "OR" ? false : true; }) : childDocs; const rangeFilteredDocs = filteredDocs.filter(d => { for (let i = 0; i < docRangeFilters.length; i += 3) { diff --git a/src/client/views/PropertiesView.scss b/src/client/views/PropertiesView.scss index 7c6d507b8..04934d50b 100644 --- a/src/client/views/PropertiesView.scss +++ b/src/client/views/PropertiesView.scss @@ -191,8 +191,7 @@ font-size: 10px; padding: 10px; margin-left: 5px; - max-height: 40%; - overflow-y: scroll; + max-height: 40%;overflow-y: scroll; .propertiesView-buttonContainer { float: right; diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 1f4685bf2..1e96d62d2 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -51,7 +51,7 @@ export class PropertiesView extends React.Component { @computed get selectedDoc() { return SelectionManager.SelectedSchemaDoc() || this.selectedDocumentView?.rootDoc; } @computed get filterDoc() { - return FilterBox.targetDoc; + return FilterBox._filterScope === "Current Collection" ? this.selectedDoc! : CurrentUserUtils.ActiveDashboard; } @computed get selectedDocumentView() { if (SelectionManager.Views().length) return SelectionManager.Views()[0]; diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 05e9ac265..3e6deaf3a 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -82,7 +82,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: return Cast(this.dataField, listSpec(Doc)); } docFilters = () => { - return [...this.props.docFilters(), ...Cast(this.props.Document._docFilters, listSpec("string"), [])]; + return [...this.props.docFilters(), ...Cast(FilterBox._filterScope === "Current Collection" ? this.props.Document._docFilters : CurrentUserUtils.ActiveDashboard._docFilters, listSpec("string"), [])]; } docRangeFilters = () => { return [...this.props.docRangeFilters(), ...Cast(this.props.Document._docRangeFilters, listSpec("string"), [])]; @@ -114,10 +114,15 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: return childDocs.filter(cd => !cd.cookies); // remove any documents that require a cookie if there are no filters to provide one } + // console.log(CurrentUserUtils.ActiveDashboard._docFilters); + if (!this.props.Document._docFilters && this.props.Document.currentFilter) { + (this.props.Document.currentFilter as Doc).filterBoolean = (this.props.ContainingCollectionDoc?.currentFilter as Doc)?.filterBoolean; + } const docsforFilter: Doc[] = []; + console.log(this.props.Document.system); childDocs.forEach((d) => { // if (DocUtils.Excluded(d, docFilters)) return; - let notFiltered = d.z || ((!searchDocs.length || searchDocs.includes(d)) && (DocUtils.FilterDocs([d], docFilters, docRangeFilters, viewSpecScript).length > 0)); + let notFiltered = d.z || ((!searchDocs.length || searchDocs.includes(d)) && (DocUtils.FilterDocs([d], docFilters, docRangeFilters, viewSpecScript, this.props.Document).length > 0)); const fieldKey = Doc.LayoutFieldKey(d); const annos = !Field.toString(Doc.LayoutField(d) as Field).includes("CollectionView"); const data = d[annos ? fieldKey + "-annotations" : fieldKey]; @@ -125,13 +130,13 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: let subDocs = DocListCast(data); if (subDocs.length > 0) { let newarray: Doc[] = []; - notFiltered = notFiltered || (!searchDocs.length && DocUtils.FilterDocs(subDocs, docFilters, docRangeFilters, viewSpecScript).length); + notFiltered = notFiltered || (!searchDocs.length && DocUtils.FilterDocs(subDocs, docFilters, docRangeFilters, viewSpecScript, this.props.Document).length); while (subDocs.length > 0 && !notFiltered) { newarray = []; subDocs.forEach((t) => { const fieldKey = Doc.LayoutFieldKey(t); const annos = !Field.toString(Doc.LayoutField(t) as Field).includes("CollectionView"); - notFiltered = notFiltered || ((!searchDocs.length || searchDocs.includes(t)) && ((!docFilters.length && !docRangeFilters.length) || DocUtils.FilterDocs([t], docFilters, docRangeFilters, viewSpecScript).length)); + notFiltered = notFiltered || ((!searchDocs.length || searchDocs.includes(t)) && ((!docFilters.length && !docRangeFilters.length) || DocUtils.FilterDocs([t], docFilters, docRangeFilters, viewSpecScript, this.props.Document).length)); DocListCast(t[annos ? fieldKey + "-annotations" : fieldKey]).forEach((newdoc) => newarray.push(newdoc)); }); subDocs = newarray; @@ -481,4 +486,5 @@ import { SelectionManager } from "../../util/SelectionManager"; import { OverlayView } from "../OverlayView"; import { Hypothesis } from "../../util/HypothesisUtils"; import { GetEffectiveAcl } from "../../../fields/util"; +import { FilterBox } from "../nodes/FilterBox"; diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 4f37747b0..020bb374a 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -122,7 +122,7 @@ export class CollectionView extends Touchable { * Applies the collection/dashboard's current filter attributes to the doc being added */ addFilterAttributes = (doc: Doc) => { - Cast(FilterBox.targetDoc._docFilters, listSpec("string"))?.forEach(attribute => { + Cast((FilterBox._filterScope === "Current Collection" ? this.props.Document : CurrentUserUtils.ActiveDashboard)._docFilters, listSpec("string"))?.forEach(attribute => { if (attribute.charAt(0).toUpperCase() === attribute.charAt(0)) { const fields = attribute.split(':'); if (fields[2] === "check") doc[DataSym][fields[0]] = fields[1]; diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index 01372c284..b9a981e77 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -81,8 +81,9 @@ export class FilterBox extends ViewBoxBaseComponent(); const targetDoc = FilterBox.targetDoc; if (this._loaded && targetDoc) { @@ -109,7 +110,7 @@ export class FilterBox extends ViewBoxBaseComponent(noviceFields); this.allDocs.forEach(doc => SearchBox.documentKeys(doc).filter(key => keys.add(key))); return Array.from(keys.keys()).filter(key => key[0]).filter(key => key[0] === "#" || key.indexOf("lastModified") !== -1 || (key[0] === key[0].toUpperCase() && !key.startsWith("_")) || noviceFields.includes(key) || !Doc.UserDoc().noviceMode).sort(); - // return []; } -- cgit v1.2.3-70-g09d2 From f98acc39b7bd88e1f260bab9b6e072c5401b46d3 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Sun, 4 Apr 2021 14:51:22 -0400 Subject: stopped system docs from being filtered --- src/client/documents/Documents.ts | 2 +- src/client/views/collections/CollectionSubView.tsx | 3 +-- src/fields/Doc.ts | 3 ++- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 12d8445b4..adebb9b1c 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -651,7 +651,7 @@ export namespace Docs { const viewKeys = ["x", "y", "system"]; // keys that should be addded to the view document even though they don't begin with an "_" const { omit: dataProps, extract: viewProps } = OmitKeys(options, viewKeys, "^_"); - dataProps.system = viewProps.system; + dataProps.system = viewProps.system ? (viewProps.system) : (viewProps.system = false); dataProps.isPrototype = true; dataProps.author = Doc.CurrentUserEmail; dataProps.creationDate = new DateField; diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 79fab8b62..89df60213 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -119,10 +119,9 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: (this.props.Document.currentFilter as Doc).filterBoolean = (this.props.ContainingCollectionDoc?.currentFilter as Doc)?.filterBoolean; } const docsforFilter: Doc[] = []; - console.log(this.props.Document.system); childDocs.forEach((d) => { // if (DocUtils.Excluded(d, docFilters)) return; - let notFiltered = d.z || ((!searchDocs.length || searchDocs.includes(d)) && (DocUtils.FilterDocs([d], docFilters, docRangeFilters, viewSpecScript, this.props.Document).length > 0)); + let notFiltered = d.z || d.system || ((!searchDocs.length || searchDocs.includes(d)) && (DocUtils.FilterDocs([d], docFilters, docRangeFilters, viewSpecScript, this.props.Document).length > 0)); const fieldKey = Doc.LayoutFieldKey(d); const annos = !Field.toString(Doc.LayoutField(d) as Field).includes("CollectionView"); const data = d[annos ? fieldKey + "-annotations" : fieldKey]; diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index c36bfb04b..44eb7536e 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -1077,7 +1077,7 @@ export namespace Doc { // filters document in a container collection: // all documents with the specified value for the specified key are included/excluded // based on the modifiers :"check", "x", undefined - export function setDocFilter(container: Opt, key: string, value: any, modifiers: "remove" | "match" | "check" | "x", toggle?: boolean, fieldSuffix?: string) { + export function setDocFilter(container: Opt, key: string, value: any, modifiers: "remove" | "match" | "check" | "x", toggle?: boolean, fieldSuffix?: string, append: boolean = true) { if (!container) return; const filterField = "_" + (fieldSuffix ? fieldSuffix + "-" : "") + "docFilters"; const docFilters = Cast(container[filterField], listSpec("string"), []); @@ -1146,6 +1146,7 @@ export namespace Doc { dragFactory["dragFactory-count"] = NumCast(dragFactory["dragFactory-count"]) + 1; Doc.SetInPlace(ndoc, "title", ndoc.title + " " + NumCast(dragFactory["dragFactory-count"]).toString(), true); } + ndoc && (ndoc.system = false); return ndoc; } export function delegateDragFactory(dragFactory: Doc) { -- cgit v1.2.3-70-g09d2 From d913e2dd6f5a292cf1bc90e65280133642219949 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Mon, 5 Apr 2021 01:27:06 -0400 Subject: deleted some commented code + other small stuff --- src/client/views/PropertiesView.scss | 3 ++- src/client/views/PropertiesView.tsx | 4 ++-- src/client/views/collections/CollectionTreeView.tsx | 3 +-- src/client/views/nodes/FilterBox.scss | 4 ++++ src/client/views/nodes/FilterBox.tsx | 13 +++---------- 5 files changed, 12 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/client/views/PropertiesView.scss b/src/client/views/PropertiesView.scss index 04934d50b..7c6d507b8 100644 --- a/src/client/views/PropertiesView.scss +++ b/src/client/views/PropertiesView.scss @@ -191,7 +191,8 @@ font-size: 10px; padding: 10px; margin-left: 5px; - max-height: 40%;overflow-y: scroll; + max-height: 40%; + overflow-y: scroll; .propertiesView-buttonContainer { float: right; diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 9fc19253e..9c1b8e593 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -965,8 +965,8 @@ export class PropertiesView extends React.Component { scriptContext={this.filterDoc.currentFilter as Doc} focus={emptyFunction} styleProvider={DefaultStyleProvider} - parentActive={returnTrue} - whenActiveChanged={emptyFunction} + isContentActive={returnTrue} + whenChildContentsActiveChanged={emptyFunction} bringToFront={emptyFunction} docFilters={returnEmptyFilter} docRangeFilters={returnEmptyFilter} diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 37600fa4d..ed0ed63b3 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -37,8 +37,7 @@ export type collectionTreeViewProps = { }; @observer -export class - CollectionTreeView extends CollectionSubView>(Document) { +export class CollectionTreeView extends CollectionSubView>(Document) { private treedropDisposer?: DragManager.DragDropDisposer; private _mainEle?: HTMLDivElement; MainEle = () => this._mainEle; diff --git a/src/client/views/nodes/FilterBox.scss b/src/client/views/nodes/FilterBox.scss index 4fe1fa2eb..107ad2e36 100644 --- a/src/client/views/nodes/FilterBox.scss +++ b/src/client/views/nodes/FilterBox.scss @@ -161,6 +161,10 @@ z-index: 1; background-color: #9F9F9F; + .filterBox-tree { + z-index: 0; + } + .filterBox-addfacet { display: inline-block; width: 200px; diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index 1d3f6a7cc..af95c96fb 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -2,7 +2,7 @@ import React = require("react"); import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { computed, observable, action, trace, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; -import { DataSym, Doc, DocListCast, Field, Opt, DocListCastAsync } from "../../../fields/Doc"; +import { Doc, DocListCast, Field, Opt, DocListCastAsync } from "../../../fields/Doc"; import { documentSchema } from "../../../fields/documentSchemas"; import { List } from "../../../fields/List"; import { RichTextField } from "../../../fields/RichTextField"; @@ -198,9 +198,6 @@ export class FilterBox extends ViewBoxBaseComponent { - - console.log("facetClick: " + facetHeader); - console.log(this.props.fieldKey); const targetDoc = FilterBox.targetDoc; const found = this.activeAttributes.findIndex(doc => doc.title === facetHeader); if (found !== -1) { @@ -242,8 +239,6 @@ export class FilterBox extends ViewBoxBaseComponent
filters in
-- cgit v1.2.3-70-g09d2 From 00127a4fccbd00eb3d05699a3a14f52feb7b57db Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Tue, 6 Apr 2021 00:14:21 -0400 Subject: minor cleanup + style across files --- src/client/views/DocumentDecorations.tsx | 10 +++++----- src/client/views/PropertiesView.tsx | 4 ++-- src/client/views/StyleProvider.tsx | 1 + src/client/views/collections/CollectionTreeView.tsx | 2 +- src/client/views/collections/TreeView.tsx | 2 +- src/client/views/nodes/FilterBox.tsx | 7 +++---- src/client/views/nodes/LinkDocPreview.tsx | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index ce7ff1bbd..e23374cea 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -83,7 +83,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b UndoManager.RunInBatch(() => titleFieldKey && SelectionManager.Views().forEach(d => { titleFieldKey === "title" && (d.dataDoc["title-custom"] = !this._accumulatedTitle.startsWith("-")); //@ts-ignore - Doc.SetInPlace(d.rootDoc, titleFieldKey, +this._accumulatedTitle == this._accumulatedTitle ? +this._accumulatedTitle : this._accumulatedTitle, true); + Doc.SetInPlace(d.rootDoc, titleFieldKey, +this._accumulatedTitle === this._accumulatedTitle ? +this._accumulatedTitle : this._accumulatedTitle, true); }), "title blur"); } } @@ -376,10 +376,10 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b this._inkDragDocs.map(oldbds => ({ oldbds, inkPts: Cast(oldbds.doc.data, InkField)?.inkData || [] })) .forEach(({ oldbds: { doc, x, y, width, height }, inkPts }) => { Doc.GetProto(doc).data = new InkField(inkPts.map(ipt => // (new x — oldx) + newWidth * (oldxpoint /oldWidth) - ({ - X: (NumCast(doc.x) - x) + NumCast(doc.width) * ipt.X / width, - Y: (NumCast(doc.y) - y) + NumCast(doc.height) * ipt.Y / height - }))); + ({ + X: (NumCast(doc.x) - x) + NumCast(doc.width) * ipt.X / width, + Y: (NumCast(doc.y) - y) + NumCast(doc.height) * ipt.Y / height + }))); Doc.SetNativeWidth(doc, undefined); Doc.SetNativeHeight(doc, undefined); }); diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index df4dd7788..782a0e29e 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -951,7 +951,7 @@ export class PropertiesView extends React.Component { !this.openFilters ? (null) :
{ PanelWidth={() => this.props.width} PanelHeight={this.filterDoc.currentFilter[HeightSym]} renderDepth={0} - scriptContext={this.filterDoc.currentFilter as Doc} + scriptContext={this.filterDoc.currentFilter} focus={emptyFunction} styleProvider={DefaultStyleProvider} isContentActive={returnTrue} diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index d1e2fefcb..3853d5888 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -18,6 +18,7 @@ import "./collections/TreeView.scss"; import "./nodes/FilterBox.scss"; import React = require("react"); import Color = require('color'); +import { FieldViewProps } from './nodes/FieldView'; export enum StyleLayers { Background = "background" diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index a9e73583d..959864a60 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -59,7 +59,7 @@ export class CollectionTreeView extends CollectionSubView this.rootDoc.autoHeight, auto => auto && this.computeHeight(), - { fireImmediately: true }) + { fireImmediately: true }); } refList: Set = new Set(); diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 2c3a6c0d7..5df33afe0 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -174,7 +174,7 @@ export class TreeView extends React.Component { componentWillUnmount() { this._selDisposer?.(); - this._treeEle && this.props.unobserveHeight(this._treeEle) + this._treeEle && this.props.unobserveHeight(this._treeEle); document.removeEventListener("pointermove", this.onDragMove, true); document.removeEventListener("pointermove", this.onDragUp, true); } diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index ae5b79aec..30d7ed187 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -82,9 +82,8 @@ export class FilterBox extends ViewBoxBaseComponent { const targetDoc = FilterBox.targetDoc; const filterDoc = targetDoc.currentFilter as Doc; - const attributes = DocListCast(filterDoc["data"]); + const attributes = DocListCast(filterDoc.data); const found = attributes.findIndex(doc => doc.title === filterName); if (found !== -1) { - (filterDoc["data"] as List).splice(found, 1); + (filterDoc.data as List).splice(found, 1); const docFilter = Cast(targetDoc._docFilters, listSpec("string")); if (docFilter) { let index: number; diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx index 45e3c8382..b73fb10df 100644 --- a/src/client/views/nodes/LinkDocPreview.tsx +++ b/src/client/views/nodes/LinkDocPreview.tsx @@ -26,7 +26,7 @@ interface LinkDocPreviewProps { @observer export class LinkDocPreview extends React.Component { @action public static Clear() { LinkDocPreview.LinkInfo = undefined; } - @action public static SetLinkInfo(info?: LinkDocPreviewProps) { LinkDocPreview.LinkInfo != info && (LinkDocPreview.LinkInfo = info); } + @action public static SetLinkInfo(info?: LinkDocPreviewProps) { LinkDocPreview.LinkInfo !== info && (LinkDocPreview.LinkInfo = info); } _infoRef = React.createRef(); @observable public static LinkInfo: Opt; -- cgit v1.2.3-70-g09d2 From e675858cfab46300a543b1013c7f88c8233ed7ad Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 6 Apr 2021 11:09:26 -0400 Subject: added ability to remove filters using inline context menu --- .../views/collections/CollectionTreeView.tsx | 2 +- src/client/views/collections/TreeView.tsx | 12 +++++--- src/client/views/nodes/DocumentView.tsx | 5 ++-- src/client/views/nodes/FilterBox.tsx | 34 ++++++++-------------- 4 files changed, 24 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 959864a60..55fe84835 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -101,7 +101,7 @@ export class CollectionTreeView extends CollectionSubView !docs.includes(v)); - SelectionManager.DeselectAll(); + if ((doc instanceof Doc ? [doc] : doc).some(doc => SelectionManager.Views().some(dv => Doc.AreProtosEqual(dv.rootDoc, doc)))) SelectionManager.DeselectAll(); if (result.length !== value.length) { const ind = targetDataDoc[this.props.fieldKey].indexOf(doc); const prev = ind && targetDataDoc[this.props.fieldKey][ind - 1]; diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 5df33afe0..8a5425992 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -21,7 +21,7 @@ import { Transform } from '../../util/Transform'; import { undoBatch, UndoManager } from '../../util/UndoManager'; import { EditableView } from "../EditableView"; import { TREE_BULLET_WIDTH } from '../globalCssVariables.scss'; -import { DocumentView, DocumentViewProps, StyleProviderFunc } from '../nodes/DocumentView'; +import { DocumentView, DocumentViewProps, StyleProviderFunc, DocumentViewInternal } from '../nodes/DocumentView'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; import { RichTextMenu } from '../nodes/formattedText/RichTextMenu'; import { KeyValueBox } from '../nodes/KeyValueBox'; @@ -483,17 +483,21 @@ export class TreeView extends React.Component { } @computed get headerElements() { - return this.props.treeViewHideHeaderFields() || Doc.IsSystem(this.doc) ? (null) + return this.props.treeViewHideHeaderFields() ? (null) : <> { this.showContextMenu(e); e.stopPropagation(); }} /> - {this.doc.treeViewExpandedViewLock ? (null) : + {this.doc.treeViewExpandedViewLock || Doc.IsSystem(this.doc) ? (null) : {this.treeViewExpandedView} } ; } - showContextMenu = (e: React.MouseEvent) => simulateMouseClick(this._docRef?.ContentDiv, e.clientX, e.clientY + 30, e.screenX, e.screenY + 30); + showContextMenu = (e: React.MouseEvent) => { + DocumentViewInternal.SelectOnContextsMenu = false; + simulateMouseClick(this._docRef?.ContentDiv, e.clientX, e.clientY + 30, e.screenX, e.screenY + 30); + DocumentViewInternal.SelectOnContextsMenu = true; + } contextMenuItems = () => Doc.IsSystem(this.doc) ? [] : this.doc.isFolder ? [{ script: ScriptField.MakeFunction(`scriptContext.makeFolder()`, { scriptContext: "any" })!, label: "New Folder" }] : this.props.treeView.fileSysMode && this.doc === Doc.GetProto(this.doc) ? diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 1c4008a55..703e78470 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -658,7 +658,7 @@ export class DocumentViewInternal extends DocComponent - cm.addItem({ description: label, event: () => customScripts[i]?.script.run({ this: this.layoutDoc, scriptContext: this.props.scriptContext, self: this.rootDoc }), icon: "sticky-note" })); + cm.addItem({ description: label, event: () => customScripts[i]?.script.run({ documentView: this, this: this.layoutDoc, scriptContext: this.props.scriptContext, self: this.rootDoc }), icon: "sticky-note" })); this.props.contextMenuItems?.().forEach(item => item.label && cm.addItem({ description: item.label, event: () => item.script.script.run({ this: this.layoutDoc, scriptContext: this.props.scriptContext, self: this.rootDoc }), icon: "sticky-note" })); @@ -746,8 +746,9 @@ export class DocumentViewInternal extends DocComponent SelectionManager.SelectView(this.props.DocumentView(), false), 300); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear. + DocumentViewInternal.SelectOnContextsMenu && !this.props.isSelected(true) && setTimeout(() => SelectionManager.SelectView(this.props.DocumentView(), false), 300); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear. } + public static SelectOnContextsMenu = true; rootSelected = (outsideReaction?: boolean) => this.props.isSelected(outsideReaction) || (this.props.Document.rootDocument && this.props.rootSelected?.(outsideReaction)) || false; panelHeight = () => this.props.PanelHeight() - this.headerMargin; diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index 30d7ed187..0a010c105 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -167,7 +167,7 @@ export class FilterBox extends ViewBoxBaseComponent (doc instanceof Doc ? [doc] : doc).map(doc => this.removeFilter(StrCast(doc.title))).length ? true : false; public removeFilter = (filterName: string) => { const targetDoc = FilterBox.targetDoc; const filterDoc = targetDoc.currentFilter as Doc; @@ -190,8 +190,8 @@ export class FilterBox extends ViewBoxBaseComponent doc.title === facetHeader); if (found !== -1) { - // comment this bit out later once the x works in treeview - (this.dataDoc[this.props.fieldKey] as List).splice(found, 1); - const docFilter = Cast(targetDoc._docFilters, listSpec("string")); - if (docFilter) { - let index: number; - while ((index = docFilter.findIndex(item => item.split(":")[0] === facetHeader)) !== -1) { - docFilter.splice(index, 1); - } - } - const docRangeFilters = Cast(targetDoc._docRangeFilters, listSpec("string")); - if (docRangeFilters) { - let index: number; - while ((index = docRangeFilters.findIndex(item => item.split(":")[0] === facetHeader)) !== -1) { - docRangeFilters.splice(index, 3); - } - } + this.removeFilter(facetHeader); } else { const allCollectionDocs = DocListCast((targetDoc.data as any)[0].data); const facetValues = this.gatherFieldValues(targetDoc, facetHeader); @@ -232,7 +217,7 @@ export class FilterBox extends ViewBoxBaseComponent; if (facetHeader === "text" || facetValues.rtFields / allCollectionDocs.length > 0.1) { - newFacet = Docs.Create.TextDocument("", { _width: 100, _height: 25, system: true, _stayInCollection: true, _hideContextMenu: true, treeViewExpandedView: "layout", title: facetHeader, treeViewOpen: true, _forceActive: true, ignoreClick: true }); + newFacet = Docs.Create.TextDocument("", { _width: 100, _height: 25, system: true, _stayInCollection: true, treeViewExpandedView: "layout", title: facetHeader, treeViewOpen: true, _forceActive: true, ignoreClick: true }); Doc.GetProto(newFacet).type = DocumentType.COL; // forces item to show an open/close button instead ofa checkbox newFacet._textBoxPadding = 4; const scriptText = `setDocFilter(this?.target, "${facetHeader}", text, "match")`; @@ -261,7 +246,11 @@ export class FilterBox extends ViewBoxBaseComponent([remove!]); + newFacet.contextMenuLabels = new List(["Remove"]); + Doc.AddDocToList(this.dataDoc, this.props.fieldKey, newFacet); } } @@ -450,7 +439,7 @@ export class FilterBox extends ViewBoxBaseComponent
@@ -519,6 +508,7 @@ Scripting.addGlobal(function readFacetData(layoutDoc: Doc, facetHeader: string) const facetValues = Array.from(set).filter(v => v); let nonNumbers = 0; + facetValues.map(val => Number.isNaN(Number(val)) && nonNumbers++); const facetValueDocSet = (nonNumbers / facetValues.length > .1 ? facetValues.sort() : facetValues.sort((n1: string, n2: string) => Number(n1) - Number(n2))).map(facetValue => { const doc = new Doc(); -- cgit v1.2.3-70-g09d2 From d01fdacae8e96c99a095dd2c97f62144ab81def5 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 6 Apr 2021 13:01:12 -0400 Subject: fix to get text filtering to work. --- src/client/views/collections/CollectionTreeView.tsx | 2 +- src/client/views/collections/TreeView.tsx | 2 +- src/client/views/nodes/FilterBox.tsx | 10 ++++++++-- 3 files changed, 10 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index ca8777de8..a8a2aaa5a 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -67,7 +67,7 @@ export class CollectionTreeView extends CollectionSubView disposer?.()); } - componentWillMount() { + componentDidMount() { this._disposers.autoheight = reaction(() => this.rootDoc.autoHeight, auto => auto && this.computeHeight(), { fireImmediately: true }); diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 8a5425992..827dadae2 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -730,7 +730,7 @@ export class TreeView extends React.Component { return this.props.renderedIds.indexOf(this.doc[Id]) !== -1 ? "<" + this.doc.title + ">" : // just print the title of documents we've previously rendered in this hierarchical path to avoid cycles
this.props.isContentActive(true) && SelectionManager.DeselectAll()} + //onPointerDown={e => this.props.isContentActive(true) && SelectionManager.DeselectAll()} // bcz: this breaks entering a text filter in a filterBox since it deselects the filter's target document onKeyDown={this.onKeyDown}>
  • {hideTitle && this.doc.type !== DocumentType.RTF ? diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index 0a010c105..718ebca28 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -217,13 +217,19 @@ export class FilterBox extends ViewBoxBaseComponent; if (facetHeader === "text" || facetValues.rtFields / allCollectionDocs.length > 0.1) { - newFacet = Docs.Create.TextDocument("", { _width: 100, _height: 25, system: true, _stayInCollection: true, treeViewExpandedView: "layout", title: facetHeader, treeViewOpen: true, _forceActive: true, ignoreClick: true }); + newFacet = Docs.Create.TextDocument("", { + _width: 100, _height: 25, system: true, _stayInCollection: true, target: targetDoc, + treeViewExpandedView: "layout", title: facetHeader, treeViewOpen: true, _forceActive: true, ignoreClick: true + }); Doc.GetProto(newFacet).type = DocumentType.COL; // forces item to show an open/close button instead ofa checkbox newFacet._textBoxPadding = 4; const scriptText = `setDocFilter(this?.target, "${facetHeader}", text, "match")`; newFacet.onTextChanged = ScriptField.MakeScript(scriptText, { this: Doc.name, text: "string" }); } else if (facetHeader !== "tags" && nonNumbers / facetValues.strings.length < .1) { - newFacet = Docs.Create.SliderDocument({ title: facetHeader, _overflow: "visible", _fitWidth: true, _height: 40, _stayInCollection: true, _hideContextMenu: true, treeViewExpandedView: "layout", treeViewOpen: true }); + newFacet = Docs.Create.SliderDocument({ + title: facetHeader, _overflow: "visible", _fitWidth: true, + _height: 40, _stayInCollection: true, treeViewExpandedView: "layout", treeViewOpen: true + }); const newFacetField = Doc.LayoutFieldKey(newFacet); const ranged = Doc.readDocRangeFilter(targetDoc, facetHeader); Doc.GetProto(newFacet).type = DocumentType.COL; // forces item to show an open/close button instead ofa checkbox -- cgit v1.2.3-70-g09d2 From a6d6eec7557325ef8a99f7cc545c17313afce9a1 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Tue, 6 Apr 2021 13:09:32 -0400 Subject: added docrangefilters to updating filterdoc --- src/client/views/PropertiesView.tsx | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 782a0e29e..0b1d75970 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -916,9 +916,12 @@ export class PropertiesView extends React.Component { * Creates a new currentFilter for this.filterDoc, */ createNewFilterDoc = () => { - const temp = this.filterDoc._docFilters; + const currentDocFilters = this.filterDoc._docFilters; + const currentDocRangeFilters = this.filterDoc._docRangeFilters; this.filterDoc._docFilters = new List(); - (this.filterDoc.currentFilter as Doc)._docFiltersList = temp; + this.filterDoc._docRangeFilters = new List(); + (this.filterDoc.currentFilter as Doc)._docFiltersList = currentDocFilters; + (this.filterDoc.currentFilter as Doc)._docRangeFiltersList = currentDocRangeFilters; this.filterDoc.currentFilter = undefined; CurrentUserUtils.setupFilterDocs(this.filterDoc); } @@ -928,13 +931,21 @@ export class PropertiesView extends React.Component { */ updateFilterDoc = (doc: Doc) => { if (doc === this.filterDoc.currentFilter) return; // causes problems if you try to reapply the same doc - const temp = doc._docFiltersList; - const otherTemp = this.filterDoc._docFilters; + const savedDocFilters = doc._docFiltersList; + const currentDocFilters = this.filterDoc._docFilters; this.filterDoc._docFilters = new List(); - (this.filterDoc.currentFilter as Doc)._docFiltersList = otherTemp; + (this.filterDoc.currentFilter as Doc)._docFiltersList = currentDocFilters; this.filterDoc.currentFilter = doc; doc._docFiltersList = new List(); - this.filterDoc._docFilters = temp; + this.filterDoc._docFilters = savedDocFilters; + + const savedDocRangeFilters = doc._docRangeFiltersList; + const currentDocRangeFilters = this.filterDoc._docRangeFilters; + this.filterDoc._docRangeFilters = new List(); + (this.filterDoc.currentFilter as Doc)._docRangeFiltersList = currentDocRangeFilters; + this.filterDoc.currentFilter = doc; + doc._docRangeFiltersList = new List(); + this.filterDoc._docRangeFilters = savedDocRangeFilters; } @computed get filtersSubMenu() { -- cgit v1.2.3-70-g09d2 From ddc432ee518a9201f04d8ea3715ae7d00583fa76 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Tue, 6 Apr 2021 13:14:58 -0400 Subject: finished adding docrangefilters --- src/client/views/collections/CollectionSubView.tsx | 2 +- src/client/views/nodes/FilterBox.tsx | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 57e1a50bb..0c022eba3 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -82,7 +82,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: return Cast(this.dataField, listSpec(Doc)); } docFilters = () => { - return [...this.props.docFilters(), ...Cast(this.props.Document?._docFilters, listSpec("string"), [])]; + return [...this.props.docFilters(), ...Cast(this.props.Document._docFilters, listSpec("string"), [])]; } docRangeFilters = () => { return [...this.props.docRangeFilters(), ...Cast(this.props.Document._docRangeFilters, listSpec("string"), [])]; diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index 30d7ed187..2f354c2da 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -287,14 +287,22 @@ export class FilterBox extends ViewBoxBaseComponent { if (FilterBox._filterScope === "Current Dashboard" && e.currentTarget.value === "Current Collection") { - const temp = CurrentUserUtils.ActiveDashboard._docFilters; + const currentDashboardDocFilters = CurrentUserUtils.ActiveDashboard._docFilters; CurrentUserUtils.ActiveDashboard._docFilters = new List(); - (CurrentUserUtils.ActiveDashboard.currentFilter as Doc)._docFilterList = temp; + (CurrentUserUtils.ActiveDashboard.currentFilter as Doc)._docFilterList = currentDashboardDocFilters; + + const currentDashboardDocRangeFilters = CurrentUserUtils.ActiveDashboard._docRangeFilters; + CurrentUserUtils.ActiveDashboard._docRangeFilters = new List(); + (CurrentUserUtils.ActiveDashboard.currentFilter as Doc)._docRangeFilterList = currentDashboardDocRangeFilters; } else if (FilterBox._filterScope === "Current Collection" && e.currentTarget.value === "Current Dashboard") { - const temp = (CurrentUserUtils.ActiveDashboard.currentFilter as Doc)._docFilterList; + const savedDashboardDocFilters = (CurrentUserUtils.ActiveDashboard.currentFilter as Doc)._docFilterList; (CurrentUserUtils.ActiveDashboard.currentFilter as Doc)._docFilterList = undefined; - CurrentUserUtils.ActiveDashboard._docFilters = temp; + CurrentUserUtils.ActiveDashboard._docFilters = savedDashboardDocFilters; + + const savedDashboardDocRangeFilters = (CurrentUserUtils.ActiveDashboard.currentFilter as Doc)._docRangeFilterList; + (CurrentUserUtils.ActiveDashboard.currentFilter as Doc)._docRangeFilterList = undefined; + CurrentUserUtils.ActiveDashboard._docRangeFilters = savedDashboardDocRangeFilters; } FilterBox._filterScope = e.currentTarget.value; } -- cgit v1.2.3-70-g09d2 From 30888cd69690448e0ccf1a7a5b3fe544dea7c218 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Tue, 6 Apr 2021 14:27:57 -0400 Subject: docrangefilter bugfix --- src/client/views/nodes/FilterBox.tsx | 5 ++--- src/client/views/nodes/SliderBox.tsx | 5 ++--- src/fields/Doc.ts | 5 +++-- 3 files changed, 7 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index c8e9cc162..c6b5d4a0a 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -227,8 +227,7 @@ export class FilterBox extends ViewBoxBaseComponent runInAction(() => { this.dataDoc[this.minThumbKey] = values[0]; this.dataDoc[this.maxThumbKey] = values[1]; - Cast(this.layoutDoc.onThumbChanged, ScriptField, null)?.script.run({ + ScriptCast(this.layoutDoc.onThumbChanged, null)?.script.run({ self: this.rootDoc, scriptContext: this.props.scriptContext, range: values, this: this.layoutDoc }); diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 44eb7536e..c1b1ed7f6 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -1058,7 +1058,8 @@ export namespace Doc { prevLayout === "icon" && (doc.deiconifyLayout = undefined); doc.layoutKey = deiconify || "layout"; } - export function setDocFilterRange(container: Doc, key: string, range?: number[]) { + export function setDocRangeFilter(container: Opt, key: string, range?: number[]) { + if (!container) return; const docRangeFilters = Cast(container._docRangeFilters, listSpec("string"), []); for (let i = 0; i < docRangeFilters.length; i += 3) { if (docRangeFilters[i] === key) { @@ -1352,4 +1353,4 @@ Scripting.addGlobal(function selectedDocs(container: Doc, excludeCollections: bo return docs.length ? new List(docs) : prevValue; }); Scripting.addGlobal(function setDocFilter(container: Doc, key: string, value: any, modifiers: "match" | "check" | "x" | "remove") { Doc.setDocFilter(container, key, value, modifiers); }); -Scripting.addGlobal(function setDocFilterRange(container: Doc, key: string, range: number[]) { Doc.setDocFilterRange(container, key, range); }); +Scripting.addGlobal(function setDocRangeFilter(container: Doc, key: string, range: number[]) { Doc.setDocRangeFilter(container, key, range); }); -- cgit v1.2.3-70-g09d2 From 998e9b239d1d97d5f4a44e8b7fb29c97e02002c4 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 6 Apr 2021 14:28:50 -0400 Subject: another fix for texts filters and for not recomputing when a docfilter change doesn't actually affect the colletion children list. --- src/client/views/collections/CollectionSubView.tsx | 5 +++-- src/client/views/collections/CollectionTreeView.tsx | 12 +++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 57e1a50bb..542cbfe75 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -90,7 +90,8 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: searchFilterDocs = () => { return [...this.props.searchFilterDocs(), ...DocListCast(this.props.Document._searchFilterDocs)]; } - @computed get childDocs() { + @computed.struct get childDocs() { + TraceMobx(); let rawdocs: (Doc | Promise)[] = []; if (this.dataField instanceof Doc) { // if collection data is just a document, then promote it to a singleton list; rawdocs = [this.dataField]; @@ -478,6 +479,6 @@ import { CollectionView, CollectionViewType, CollectionViewProps } from "./Colle import { SelectionManager } from "../../util/SelectionManager"; import { OverlayView } from "../OverlayView"; import { Hypothesis } from "../../util/HypothesisUtils"; -import { GetEffectiveAcl } from "../../../fields/util"; +import { GetEffectiveAcl, TraceMobx } from "../../../fields/util"; import { FilterBox } from "../nodes/FilterBox"; diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index a8a2aaa5a..82c8a9114 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -49,7 +49,7 @@ export class CollectionTreeView extends CollectionSubView p + Number(getComputedStyle(r).height.replace("px", "")), 0); this.props.setHeight(hgt); } - unobserveHeight = (ref: any) => this.refList.delete(ref); + unobserveHeight = (ref: any) => { + this.refList.delete(ref); + this.rootDoc.autoHeight && this.computeHeight(); + } observerHeight = (ref: any) => { if (ref) { this.refList.add(ref); @@ -116,11 +119,10 @@ export class CollectionTreeView extends CollectionSubView(result); + this.props.removeDocument?.(doc); if (ind > 0) { FormattedTextBox.SelectOnLoad = prev[Id]; - const prevView = DocumentManager.Instance.getDocumentView(prev, this.props.CollectionView); - prevView?.select(false); + DocumentManager.Instance.getDocumentView(prev, this.props.CollectionView)?.select(false); } return true; } -- cgit v1.2.3-70-g09d2 From 3389e8231362e48fc0df522db1317b87c71969c6 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 6 Apr 2021 14:39:42 -0400 Subject: fixed initial treeViewOpen state for non-checkbox filters. --- src/client/documents/Documents.ts | 1 + src/client/views/nodes/FilterBox.tsx | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index adebb9b1c..65dd826ef 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -248,6 +248,7 @@ export class DocumentOptions { treeViewHideHeaderFields?: boolean; // whether to hide the drop down options for tree view items. treeViewShowClearButton?: boolean; // whether a clear button should be displayed treeViewOpenIsTransient?: boolean; // ignores the treeViewOpen Doc flag, allowing a treeViewItem's expand/collapse state to be independent of other views of the same document in the same or any other tree view + _treeViewOpen?: boolean; // whether this document is expanded in a tree view (note: need _ and regular versions since this can be specified for both proto and layout docs) treeViewOpen?: boolean; // whether this document is expanded in a tree view treeViewExpandedView?: string; // which field/thing is displayed when this item is opened in tree view treeViewExpandedViewLock?: boolean; // whether the expanded view can be changed diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index c6b5d4a0a..e1227b81d 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -219,7 +219,7 @@ export class FilterBox extends ViewBoxBaseComponent 0.1) { newFacet = Docs.Create.TextDocument("", { _width: 100, _height: 25, system: true, _stayInCollection: true, target: targetDoc, - treeViewExpandedView: "layout", title: facetHeader, treeViewOpen: true, _forceActive: true, ignoreClick: true + treeViewExpandedView: "layout", title: facetHeader, _treeViewOpen: true, _forceActive: true, ignoreClick: true }); Doc.GetProto(newFacet).type = DocumentType.COL; // forces item to show an open/close button instead ofa checkbox newFacet._textBoxPadding = 4; @@ -227,7 +227,7 @@ export class FilterBox extends ViewBoxBaseComponent Date: Tue, 6 Apr 2021 16:41:41 -0400 Subject: switched from context menu to a delete button on filterBox filters. don't select treeView items after expanding them. --- src/client/views/collections/TreeView.tsx | 6 ++-- src/client/views/nodes/FilterBox.tsx | 56 +++++++++++++++++++------------ 2 files changed, 37 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 827dadae2..c7322598c 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -152,7 +152,6 @@ export class TreeView extends React.Component { } else { this.props.addDocTab(this.props.document, "add:right"); } - docView?.select(false); } constructor(props: any) { super(props); @@ -483,9 +482,9 @@ export class TreeView extends React.Component { } @computed get headerElements() { - return this.props.treeViewHideHeaderFields() ? (null) + return this.props.treeViewHideHeaderFields() || this.doc.treeViewHideHeaderFields ? (null) : <> - { this.showContextMenu(e); e.stopPropagation(); }} /> + {this.doc.hideContextMenu ? (null) : { this.showContextMenu(e); e.stopPropagation(); }} />} {this.doc.treeViewExpandedViewLock || Doc.IsSystem(this.doc) ? (null) : {this.treeViewExpandedView} @@ -526,7 +525,6 @@ export class TreeView extends React.Component { }}> {StrCast(doc?.title)}
  • ; - case StyleProp.Decorations: return (null); default: return this.props?.treeView?.props.styleProvider?.(doc, props, property); } } diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index e1227b81d..a43b80e5b 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -31,6 +31,7 @@ import { DefaultStyleProvider, StyleProp } from "../StyleProvider"; import { CollectionViewType } from "../collections/CollectionView"; import { CurrentUserUtils } from "../../util/CurrentUserUtils"; import { EditableView } from "../EditableView"; +import { undoBatch } from "../../util/UndoManager"; type FilterBoxDocument = makeInterface<[typeof documentSchema]>; const FilterBoxDocument = makeInterface(documentSchema); @@ -251,10 +252,7 @@ export class FilterBox extends ViewBoxBaseComponent([remove!]); - newFacet.contextMenuLabels = new List(["Remove"]); + newFacet.hideContextMenu = true; Doc.AddDocToList(this.dataDoc, this.props.fieldKey, newFacet); } } @@ -323,23 +321,21 @@ export class FilterBox extends ViewBoxBaseComponent, props: Opt, property: string) { switch (property.split(":")[0]) { case StyleProp.Decorations: - if (doc) { - return doc._viewType === CollectionViewType.Docking || (Doc.IsSystem(doc)) ? (null) : - <> -
    - -
    -
    this.removeFilter(StrCast(doc.title))}> - -
    - ; + if (doc && !doc.treeViewHideHeaderFields) { + return <> +
    + +
    +
    this.removeFilter(StrCast(doc.title))}> + +
    + ; } - default: return DefaultStyleProvider(doc, props, property); - } + return DefaultStyleProvider(doc, props, property); } suppressChildClick = () => ScriptField.MakeScript("")!; @@ -376,6 +372,24 @@ export class FilterBox extends ViewBoxBaseComponent, props: Opt, property: string) => { + switch (property.split(":")[0]) { + case StyleProp.Decorations: + return !doc || doc.treeViewHideHeaderFields ? (null) : // bcz: Todo: afterHeader should be generalized into a renderPath that is a list of the documents rendered so far which would mimic much of CSS property selectors + <> +
    + this.removeFilter(StrCast(doc.title)) + )}> + +
    + ; + } + return this.props.styleProvider?.(doc, props, property); + } + layoutHeight = () => this.layoutDoc[HeightSym](); render() { const facetCollection = this.props.Document; @@ -431,7 +445,6 @@ export class FilterBox extends ViewBoxBaseComponent Date: Tue, 6 Apr 2021 17:46:55 -0400 Subject: from last --- src/client/views/nodes/FilterBox.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index a43b80e5b..3e735404f 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -378,7 +378,7 @@ export class FilterBox extends ViewBoxBaseComponent, props: Opt, property: string) => { switch (property.split(":")[0]) { case StyleProp.Decorations: - return !doc || doc.treeViewHideHeaderFields ? (null) : // bcz: Todo: afterHeader should be generalized into a renderPath that is a list of the documents rendered so far which would mimic much of CSS property selectors + return !doc || doc.treeViewHideHeaderFields ? (null) : <>
    this.removeFilter(StrCast(doc.title)) @@ -433,7 +433,7 @@ export class FilterBox extends ViewBoxBaseComponent this.facetClick((val as UserOptions).value)} value={null} - closeMenuOnSelect={false} + closeMenuOnSelect={true} />
    -- cgit v1.2.3-70-g09d2 From d5b1abae714b4bae0f02ce57a91477bdb2502078 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 6 Apr 2021 17:59:50 -0400 Subject: little cleanup --- src/client/views/EditableView.tsx | 1 - src/client/views/StyleProvider.tsx | 3 ++- src/client/views/collections/TreeView.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index 5daac77ee..03d9efff3 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -47,7 +47,6 @@ export interface EditableProps { toggle?: () => void; background?: string | undefined; placeholder?: string; - fullWidth?: boolean; // used in PropertiesView to make the whole key:value input box clickable } /** diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 3853d5888..d15cd5458 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -69,13 +69,14 @@ export function DefaultStyleProvider(doc: Opt, props: Opt StrListCast(doc?._layerTags).includes(StyleLayers.Background); const backgroundCol = () => props?.styleProvider?.(doc, props, StyleProp.BackgroundColor); const opacity = () => props?.styleProvider?.(doc, props, StyleProp.Opacity); const showTitle = () => props?.styleProvider?.(doc, props, StyleProp.ShowTitle); switch (property.split(":")[0]) { - case StyleProp.TreeViewIcon: return doc ? Doc.toIcon(doc) : "question"; + case StyleProp.TreeViewIcon: return doc?.isFolder ? "chevron-" + (isOpen ? "down" : "right") : doc ? Doc.toIcon(doc) : "question"; case StyleProp.DocContents: return undefined; case StyleProp.WidgetColor: return isAnnotated ? "lightBlue" : darkScheme() ? "lightgrey" : "dimgrey"; case StyleProp.Opacity: return Cast(doc?._opacity, "number", Cast(doc?.opacity, "number", null)); diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index c7322598c..5cf8a6986 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -441,7 +441,7 @@ export class TreeView extends React.Component { @computed get renderBullet() { TraceMobx(); - const iconType = this.doc.isFolder ? (this.treeViewOpen ? "chevron-down" : "chevron-right") : Doc.toIcon(this.doc); + const iconType = this.props.treeView.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.TreeViewIcon + (this.treeViewOpen ? ":open" : "")) || "question"; const checked = this.onCheckedClick ? (this.doc.treeViewChecked ?? "unchecked") : undefined; return
    Date: Tue, 6 Apr 2021 18:08:44 -0400 Subject: from last --- src/client/views/StyleProvider.tsx | 2 +- src/fields/Doc.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index d15cd5458..2ab6d448a 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -76,7 +76,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt props?.styleProvider?.(doc, props, StyleProp.ShowTitle); switch (property.split(":")[0]) { - case StyleProp.TreeViewIcon: return doc?.isFolder ? "chevron-" + (isOpen ? "down" : "right") : doc ? Doc.toIcon(doc) : "question"; + case StyleProp.TreeViewIcon: return Doc.toIcon(doc, isOpen); case StyleProp.DocContents: return undefined; case StyleProp.WidgetColor: return isAnnotated ? "lightBlue" : darkScheme() ? "lightgrey" : "dimgrey"; case StyleProp.Opacity: return Cast(doc?._opacity, "number", Cast(doc?.opacity, "number", null)); diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index c1b1ed7f6..06b1b8539 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -1160,12 +1160,12 @@ export namespace Doc { return ndoc; } - export function toIcon(doc: Doc) { - switch (StrCast(doc.type)) { + export function toIcon(doc?: Doc, isOpen?: boolean) { + switch (StrCast(doc?.type)) { case DocumentType.IMG: return "image"; case DocumentType.COMPARISON: return "columns"; case DocumentType.RTF: return "sticky-note"; - case DocumentType.COL: return !doc.isFolder ? "folder" : "chevron-right"; + case DocumentType.COL: return !doc?.isFolder ? "folder" + (isOpen ? "-open" : "") : "chevron-" + (isOpen ? "down" : "right"); case DocumentType.WEB: return "globe-asia"; case DocumentType.SCREENSHOT: return "photo-video"; case DocumentType.WEBCAM: return "video"; -- cgit v1.2.3-70-g09d2 From cdfa4390641f5dd4ba5664217417fb42374ed9ea Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 6 Apr 2021 18:10:44 -0400 Subject: from last --- src/client/views/StyleProvider.tsx | 25 ------------------------- 1 file changed, 25 deletions(-) (limited to 'src') diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 2ab6d448a..9102b9fa4 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -231,31 +231,6 @@ function closeFilter(e: React.MouseEvent, doc: Doc) { } -/** - * add (to treeView) for filtering decorations - */ -export function FilteringStyleProvider(doc: Opt, props: Opt, property: string) { - switch (property.split(":")[0]) { - case StyleProp.Decorations: - if (doc) { - return doc._viewType === CollectionViewType.Docking || (Doc.IsSystem(doc)) ? (null) : - <> -
    - -
    -
    closeFilter(e, doc)}> - -
    - ; - } - default: return DefaultStyleProvider(doc, props, property); - - } -} - // // a preliminary semantic-"layering/grouping" mechanism for determining interactive properties of documents // currently, the provider tests whether the docuemnt's layer field matches the activeLayer field of the tab. -- cgit v1.2.3-70-g09d2 From 69563c0c81a3e6ade2fe460af8fad76cef3a3897 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 6 Apr 2021 18:39:20 -0400 Subject: reverted back to not setting 'system' for non-system documents. --- src/client/documents/Documents.ts | 2 +- src/client/views/PropertiesView.tsx | 2 +- src/client/views/collections/CollectionSubView.tsx | 2 +- src/fields/Doc.ts | 1 - 4 files changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 65dd826ef..3b40f0cc7 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -652,7 +652,7 @@ export namespace Docs { const viewKeys = ["x", "y", "system"]; // keys that should be addded to the view document even though they don't begin with an "_" const { omit: dataProps, extract: viewProps } = OmitKeys(options, viewKeys, "^_"); - dataProps.system = viewProps.system ? (viewProps.system) : (viewProps.system = false); + dataProps.system = viewProps.system; dataProps.isPrototype = true; dataProps.author = Doc.CurrentUserEmail; dataProps.creationDate = new DateField; diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 0b1d75970..92fe3acb5 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -28,7 +28,7 @@ import { PresBox } from "./nodes/PresBox"; import { PropertiesButtons } from "./PropertiesButtons"; import { PropertiesDocContextSelector } from "./PropertiesDocContextSelector"; import "./PropertiesView.scss"; -import { DefaultStyleProvider, FilteringStyleProvider } from "./StyleProvider"; +import { DefaultStyleProvider } from "./StyleProvider"; import { CurrentUserUtils } from "../util/CurrentUserUtils"; import { FilterBox } from "./nodes/FilterBox"; import { List } from "../../fields/List"; diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index bc5a6129c..b998555d8 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -122,7 +122,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: const docsforFilter: Doc[] = []; childDocs.forEach((d) => { // if (DocUtils.Excluded(d, docFilters)) return; - let notFiltered = d.z || d.system || ((!searchDocs.length || searchDocs.includes(d)) && (DocUtils.FilterDocs([d], docFilters, docRangeFilters, viewSpecScript, this.props.Document).length > 0)); + let notFiltered = d.z || Doc.IsSystem(d) || ((!searchDocs.length || searchDocs.includes(d)) && (DocUtils.FilterDocs([d], docFilters, docRangeFilters, viewSpecScript, this.props.Document).length > 0)); const fieldKey = Doc.LayoutFieldKey(d); const annos = !Field.toString(Doc.LayoutField(d) as Field).includes("CollectionView"); const data = d[annos ? fieldKey + "-annotations" : fieldKey]; diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 06b1b8539..01d0a8176 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -1147,7 +1147,6 @@ export namespace Doc { dragFactory["dragFactory-count"] = NumCast(dragFactory["dragFactory-count"]) + 1; Doc.SetInPlace(ndoc, "title", ndoc.title + " " + NumCast(dragFactory["dragFactory-count"]).toString(), true); } - ndoc && (ndoc.system = false); return ndoc; } export function delegateDragFactory(dragFactory: Doc) { -- cgit v1.2.3-70-g09d2 From fcbe1957d985655167ee8365fbb8f2755bbfd206 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 6 Apr 2021 18:51:01 -0400 Subject: cleanup --- src/client/views/collections/CollectionView.tsx | 4 +--- src/client/views/collections/TreeView.tsx | 4 ++-- src/client/views/nodes/DocumentView.tsx | 4 ++-- 3 files changed, 5 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 91f159d8e..4dc0ee3e6 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -1,4 +1,4 @@ -import { action, computed, observable } from 'mobx'; +import { computed, observable } from 'mobx'; import { observer } from "mobx-react"; import * as React from 'react'; import 'react-image-lightbox-with-rotate/style.css'; // This only needs to be imported once in your app @@ -35,8 +35,6 @@ import { SubCollectionViewProps } from './CollectionSubView'; import { CollectionTimeView } from './CollectionTimeView'; import { CollectionTreeView } from "./CollectionTreeView"; import './CollectionView.scss'; -import { FilterBox } from '../nodes/FilterBox'; -import { listSpec } from '../../../fields/Schema'; export const COLLECTION_BORDER_WIDTH = 2; const path = require('path'); diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 5cf8a6986..2cce9c2f5 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -493,9 +493,9 @@ export class TreeView extends React.Component { } showContextMenu = (e: React.MouseEvent) => { - DocumentViewInternal.SelectOnContextsMenu = false; + DocumentViewInternal.SelectAfterContextMenu = false; simulateMouseClick(this._docRef?.ContentDiv, e.clientX, e.clientY + 30, e.screenX, e.screenY + 30); - DocumentViewInternal.SelectOnContextsMenu = true; + DocumentViewInternal.SelectAfterContextMenu = true; } contextMenuItems = () => Doc.IsSystem(this.doc) ? [] : this.doc.isFolder ? [{ script: ScriptField.MakeFunction(`scriptContext.makeFolder()`, { scriptContext: "any" })!, label: "New Folder" }] : diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 703e78470..5c3d7e415 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -162,6 +162,7 @@ export interface DocumentViewInternalProps extends DocumentViewProps { @observer export class DocumentViewInternal extends DocComponent(Document) { + public static SelectAfterContextMenu = true; // whether a document should be selected after it's contextmenu is triggered. @observable _animateScalingTo = 0; @observable _mediaState = 0; @observable _pendingDoubleClick = false; @@ -746,9 +747,8 @@ export class DocumentViewInternal extends DocComponent SelectionManager.SelectView(this.props.DocumentView(), false), 300); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear. + DocumentViewInternal.SelectAfterContextMenu && !this.props.isSelected(true) && setTimeout(() => SelectionManager.SelectView(this.props.DocumentView(), false), 300); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear. } - public static SelectOnContextsMenu = true; rootSelected = (outsideReaction?: boolean) => this.props.isSelected(outsideReaction) || (this.props.Document.rootDocument && this.props.rootSelected?.(outsideReaction)) || false; panelHeight = () => this.props.PanelHeight() - this.headerMargin; -- cgit v1.2.3-70-g09d2 From a14e2da6130ac3c0c55b03cbc8a5fa3723be45bc Mon Sep 17 00:00:00 2001 From: Geireann <60007097+geireann@users.noreply.github.com> Date: Tue, 6 Apr 2021 20:31:25 -0400 Subject: updates --- src/client/util/CaptureManager.scss | 465 +++++++++++++++++++++ src/client/util/CaptureManager.tsx | 75 ++++ src/client/views/AntimodeMenu.scss | 14 +- src/client/views/AntimodeMenu.tsx | 2 +- src/client/views/MainView.scss | 3 - src/client/views/MainView.tsx | 6 +- src/client/views/collections/CollectionMenu.scss | 126 ++++-- src/client/views/collections/CollectionMenu.tsx | 78 +++- src/client/views/nodes/ScreenshotBox.tsx | 121 +++--- src/client/views/nodes/VideoBox.scss | 10 + .../views/nodes/formattedText/RichTextMenu.scss | 7 +- .../views/nodes/formattedText/RichTextMenu.tsx | 2 +- 12 files changed, 790 insertions(+), 119 deletions(-) create mode 100644 src/client/util/CaptureManager.scss create mode 100644 src/client/util/CaptureManager.tsx (limited to 'src') diff --git a/src/client/util/CaptureManager.scss b/src/client/util/CaptureManager.scss new file mode 100644 index 000000000..5ca54517c --- /dev/null +++ b/src/client/util/CaptureManager.scss @@ -0,0 +1,465 @@ +@import "../views/globalCssVariables"; + +.settings-interface { + //background-color: whitesmoke !important; + color: grey; + width: 450px; + + button { + background: #315a96; + outline: none; + border-radius: 5px; + border: 0px; + color: #fcfbf7; + text-transform: uppercase; + letter-spacing: 2px; + font-size: 75%; + padding: 10px; + margin: 10px; + transition: transform 0.2s; + margin: 2px; + } +} + +.settings-title { + font-size: 25px; + font-weight: bold; + padding-right: 10px; + color: black; +} + +.settings-username { + font-size: 12px; + padding-right: 15px; + color: black; + margin-top: 10px; + margin-bottom: 10px; + /* right: 135; */ + // position: absolute; + // left: 243; +} + +.settings-section { + display: flex; + border-bottom: 1px solid grey; + padding-bottom: 8px; + padding-top: 6px; + + .settings-section-title { + font-size: 16; + font-weight: bold; + text-align: left; + color: black; + width: 80; + margin-right: 50px; + } + + &:last-child { + border-bottom: none; + } +} + + +.password-content { + display: flex; + flex-direction: column; + + .password-content-inputs { + width: 100; + // margin-bottom: 10px; + font-size: 10px; + + .password-inputs { + border: 1px solid rgb(160, 160, 160); + margin-bottom: 8px; + width: 130; + color: black; + border-radius: 5px; + padding:7px; + + } + } + + .password-content-buttons { + //margin-left: 84px; + //width: 100; + padding: 7px; + + .password-submit { + //margin-left: 85px; + margin-top: 5px; + } + + .password-forgot { + //margin-left: 65px; + //margin-top: -20px; + font-size: 12px; + white-space: nowrap; + } + } +} + +.accounts-content { + display: flex; +} + +.modes-content { + display: flex; + margin-left: 10px; + font-size: 12px; + + .modes-select { + // width: 170px; + width: 80%; + height: 35px; + margin-right: 10px; + color: black; + border-radius: 5px; + + &:hover { + cursor: pointer; + } + } + + .modes-playground, + .default-acl { + display: flex; + margin-left: 10px; + margin-top: 10px; + font-size: 10px; + + .playground-check, + .acl-check { + margin-right: 5px; + + &:hover { + cursor: pointer; + } + } + + .playground-text { + color: black; + margin-right: 10px; + margin-top: 2; + } + + .acl-text { + color: black; + margin-top: 2; + text-align: left; + } + + } +} + +.colorFlyout { + margin-top: 2px; + //margin-right: 18px; + + &:hover { + cursor: pointer; + } + + .colorFlyout-button { + width: 20px; + height: 20px; + border: 0.5px solid black; + border-radius: 5px; + padding-top: 3px; + } +} + +.prefs-content{ + text-align: left; +} + +.appearances-content { + display: flex; + margin-top: 4px; + color: black; + font-size: 10px; + + .preferences-color { + display: flex; + margin-top: 2px; + + .preferences-color-text { + margin-top: 3px; + margin-right: 4; + flex: 1 1 auto; + text-align: left; + } + + .colorFlyout { + align-self: flex-end; + } + } + + .preferences-font { + //height: 23px; + margin-top: 2px; + + .preferences-font-text { + color: black; + margin-top: 4; + margin-right: 4; + margin-bottom: 2px; + text-align: left; + } + + .preferences-font-controls { + display: flex; + justify-content: space-between; + } + + .font-select { + height: 35px; + color: black; + font-size: 9; + margin-right: 6; + border-radius: 5px; + width: 65%; + + &:hover { + cursor: pointer; + } + } + + .size-select { + height: 35px; + color: black; + font-size: 9; + border-radius: 5px; + width: 30%; + + &:hover { + cursor: pointer; + } + } + } + + .preferences-check { + color: black; + margin-right: 4; + margin-bottom: -3; + margin-left: 5; + margin-top: -1px; + display: inline-block; + padding-left: 5px; + text-align: left; + } +} + +.settings-interface { + display: flex; + flex-direction: column; + + button { + width: auto; + align-self: center; + background: #252b33; + margin-right: 15px; + + //margin-top: 4px; + + &:hover { + background: $main-accent; + } + } + + // .delete-button { + // background: rgb(227, 86, 86); + // } + + .close-button { + position: absolute; + right: 1em; + top: 1em; + cursor: pointer; + } + + // .logout-button { + // right: 355; + // position: absolute; + // } + + .settings-content { + background: #e4e4e4; + //border-radius: 6px; + padding: 10px; + //width: 560px; + flex: 1 1 auto; + } + + .settings-top { + display: flex; + margin-bottom: 10px; + } + + + .error-text { + color: #C40233; + width: 300; + margin-left: -20; + font-size: 10; + margin-bottom: 4; + margin-top: -3; + } + + .success-text { + width: 300; + margin-left: -20; + font-size: 10; + margin-bottom: 4; + margin-top: -3; + color: #009F6B; + } + + .focus-span { + text-decoration: underline; + } + + h1 { + color: #121721; + text-transform: uppercase; + letter-spacing: 2px; + font-size: 19; + margin-top: 0; + font-weight: bold; + } + + .container { + display: block; + position: relative; + margin-top: 10px; + margin-bottom: 10px; + font-size: 22px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + width: 700px; + min-width: 700px; + max-width: 700px; + text-align: left; + font-style: normal; + font-size: 15; + font-weight: normal; + padding: 0; + + .padding { + padding: 0 0 0 20px; + color: black; + } + + } +} + +.settings-interface { + flex-direction: row; + position: relative; + min-height: 250px; + width: 100%; + + .settings-content { + background-color: #fdfdfd; + } +} + +.settings-panel { + position: relative; + min-width: 150px; + background-color: #e4e4e4; + + .settings-user { + position: absolute; + bottom: 10px; + text-align: center; + left: 0; + right: 0; + + .settings-username { + padding-right: 0px; + } + + .logout-button { + margin-right: 2px; + } + } +} + +.settings-tabs { + // font-size: 16px; + font-weight: 600; + color: black; + + .tab-control { + padding: 10px; + border-bottom: 1px solid #9f9e9e; + cursor: pointer; + + &.active { + background-color: #fdfdfd; + } + } +} + +.settings-section-context { + width: 100%; +} + +.tab-section { + display: none; + height: 200px; + + &.active { + display: block; + } +} + +.tab-content { + display: flex; + margin: 20px 0; + + .tab-column { + flex: 0 0 50%; + + .tab-column-title { + color: black; + font-size: 16px; + font-weight: bold; + margin-bottom: 16px; + } + + .tab-column-title, .tab-column-content { + padding-left: 16px; + } + + } + +} + +.tab-column button { + font-size: 9px; +} + +@media only screen and (max-device-width: 480px) { + .settings-interface { + width: 80vw; + height: 400px; + } + + .settings-interface .settings-body .settings-content input { + font-size: 30; + } + + .settings-interface button { + width: 100%; + font-size: 30px; + background: #315a96; + } + + .settings-interface .settings-heading { + font-size: 25; + } +} diff --git a/src/client/util/CaptureManager.tsx b/src/client/util/CaptureManager.tsx new file mode 100644 index 000000000..f01fcd0d2 --- /dev/null +++ b/src/client/util/CaptureManager.tsx @@ -0,0 +1,75 @@ +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { action, computed, observable, runInAction } from "mobx"; +import { observer } from "mobx-react"; +import * as React from "react"; +import { ColorState, SketchPicker } from "react-color"; +import { Doc } from "../../fields/Doc"; +import { BoolCast, StrCast, Cast } from "../../fields/Types"; +import { addStyleSheet, addStyleSheetRule, Utils } from "../../Utils"; +import { GoogleAuthenticationManager } from "../apis/GoogleAuthenticationManager"; +import { DocServer } from "../DocServer"; +import { Networking } from "../Network"; +import { MainViewModal } from "../views/MainViewModal"; +import { CurrentUserUtils } from "./CurrentUserUtils"; +import { GroupManager } from "./GroupManager"; +import "./CaptureManager.scss"; +import { undoBatch } from "./UndoManager"; +const higflyout = require("@hig/flyout"); +export const { anchorPoints } = higflyout; +export const Flyout = higflyout.default; + +@observer +export class CaptureManager extends React.Component<{}> { + public static Instance: CaptureManager; + static _settingsStyle = addStyleSheet(); + @observable isOpen: boolean = false; // whether the CaptureManager is to be displayed or not. + + + constructor(props: {}) { + super(props); + CaptureManager.Instance = this; + } + + public close = action(() => this.isOpen = false); + public open = action(() => this.isOpen = true); + + + @computed get colorsContent() { + + return
    + +
    ; + } + + @computed get formatsContent() { + return
    + +
    ; + } + + + + + + private get captureInterface() { + return
    +
    + +
    + +
    + +
    +
    ; + + } + + render() { + return ; + } +} \ No newline at end of file diff --git a/src/client/views/AntimodeMenu.scss b/src/client/views/AntimodeMenu.scss index c9b5e7658..a275901be 100644 --- a/src/client/views/AntimodeMenu.scss +++ b/src/client/views/AntimodeMenu.scss @@ -7,7 +7,7 @@ height: $antimodemenu-height; background: #323232; box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.25); - border-radius: 0px 6px 6px 6px; + // border-radius: 0px 6px 6px 6px; z-index: 1001; display: flex; @@ -24,6 +24,16 @@ background-color: transparent; width: 35px; height: 35px; + padding: 5; + text-align: center; + display: flex; + justify-content: center; + align-items: center; + position: relative; + + .svg { + margin: 0; + } &.active { background-color: #121212; @@ -31,7 +41,7 @@ } .antimodeMenu-button:hover { - background-color: #121212; + background-color: rgba(0, 0, 0, 0.4); } .antimodeMenu-dragger { diff --git a/src/client/views/AntimodeMenu.tsx b/src/client/views/AntimodeMenu.tsx index 5acb3e4c8..fe6d39ca4 100644 --- a/src/client/views/AntimodeMenu.tsx +++ b/src/client/views/AntimodeMenu.tsx @@ -140,7 +140,7 @@ export abstract class AntimodeMenu extends React.Co left: this._left, top: this._top, opacity: this._opacity, transitionProperty: this._transitionProperty, transitionDuration: this._transitionDuration, transitionDelay: this._transitionDelay, position: this.Pinned ? "unset" : undefined }}> -
    + {/* {this.getDragger} */} {buttons}
    ); diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss index 8ccb64744..3f04a0f3a 100644 --- a/src/client/views/MainView.scss +++ b/src/client/views/MainView.scss @@ -358,9 +358,6 @@ .mainView-libraryFlyout-out { transition: width .25s; box-shadow: rgb(156, 147, 150) 0.2vw 0.2vw 0.2vw; - .mainView-docButtons { - left: 0; - } } diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 204ec370f..7d78d74e3 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -17,6 +17,7 @@ import { emptyFunction, emptyPath, returnEmptyDoclist, returnEmptyFilter, return import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager'; import { DocServer } from '../DocServer'; import { Docs, DocUtils } from '../documents/Documents'; +import { CaptureManager } from '../util/CaptureManager'; import { CurrentUserUtils } from '../util/CurrentUserUtils'; import { DocumentManager } from '../util/DocumentManager'; import { GroupManager } from '../util/GroupManager'; @@ -177,8 +178,8 @@ export class MainView extends React.Component { const targClass = targets[0].className.toString(); if (SearchBox.Instance._searchbarOpen || SearchBox.Instance.open) { const check = targets.some((thing) => - (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" || - thing.className === "collectionSchema-header-menuOptions")); + (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" || + thing.className === "collectionSchema-header-menuOptions")); !check && SearchBox.Instance.resetSearch(true); } !targClass.includes("contextMenu") && ContextMenu.Instance.closeMenu(); @@ -619,6 +620,7 @@ export class MainView extends React.Component { + diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss index 2c81d727e..9eac75f4b 100644 --- a/src/client/views/collections/CollectionMenu.scss +++ b/src/client/views/collections/CollectionMenu.scss @@ -14,35 +14,53 @@ top: 0; width: 100%; - .antimodeMenu-button { - padding: 0; - width: 30px; + .recordButtonOutline { + border-radius: 100%; + width: 18px; + height: 18px; + border: solid 1px #f5f5f5; display: flex; + align-items: center; + justify-content: center; + } - svg { - margin: auto; - } + .recordButtonInner { + border-radius: 100%; + width: 70%; + height: 70%; + background: white; } .collectionMenu { display: flex; - padding-bottom: 1px; - height: 32px; - border-bottom: .5px solid rgb(180, 180, 180); + height: 100%; overflow: visible; z-index: 901; border: unset; + .collectionMenu-divider { + height: 85%; + margin-left: 3px; + margin-right: 3px; + width: 1.5px; + background-color: #656060; + } + .collectionViewBaseChrome { display: flex; + align-items: center; .collectionViewBaseChrome-viewPicker { font-size: 75%; - background: #323232; outline-color: black; color: white; border: none; - border-right: solid gray 1px; + background: #323232; + } + + .collectionViewBaseChrome-viewPicker:focus { + outline: none; + border: none; } .collectionViewBaseChrome-viewPicker:active { @@ -65,18 +83,26 @@ margin-left: 3px; margin-right: 0px; font-size: 75%; - background: #323232; + text-transform: capitalize; color: white; border: none; - border-right: solid gray 1px; + background: #323232; + } + + .collectionViewBaseChrome-cmdPicker:focus { + border: none; + outline: none; } .commandEntry-outerDiv { pointer-events: all; - background-color: #323232; + background-color: transparent; display: flex; flex-direction: row; - height: 30px; + align-items: center; + justify-content: center; + height: 100%; + overflow: hidden; .commandEntry-drop { color: white; @@ -86,6 +112,15 @@ } } + .commandEntry-outerDiv:hover{ + background-color: rgba(0,0,0,0.2); + + .collectionViewBaseChrome-viewPicker, + .collectionViewBaseChrome-cmdPicker{ + background: rgb(41,41,41); + } + } + .collectionViewBaseChrome-collapse { transition: all .5s, opacity 0.3s; position: absolute; @@ -103,11 +138,12 @@ .collectionViewBaseChrome-template, .collectionViewBaseChrome-viewModes { - display: grid; - background: rgb(238, 238, 238); + align-items: center; + height: 100%; + display: flex; + background: transparent; color: grey; - margin-top: auto; - margin-bottom: auto; + justify-content: center; } .collectionViewBaseChrome-viewSpecs { @@ -263,27 +299,52 @@ .collectionTreeViewChrome-pivotField-cont, .collection3DCarouselViewChrome-scrollSpeed-cont { justify-self: right; - display: flex; + align-items: center; + display: grid; + grid-auto-columns: auto; font-size: 75%; letter-spacing: 2px; .collectionStackingViewChrome-pivotField-label, .collectionTreeViewChrome-pivotField-label, .collection3DCarouselViewChrome-scrollSpeed-label { - vertical-align: center; - padding-left: 10px; - margin: auto; + grid-column: 1; + margin-right: 7px; + user-select: none; + font-family: 'Roboto'; + letter-spacing: normal; + } + + .collectionStackingViewChrome-sortIcon { + transition: transform .5s; + grid-column: 3; + text-align: center; + display: flex; + justify-content: center; + align-items: center; + cursor: pointer; + width: 25px; + height: 25px; + border-radius: 100%; + } + + .collectionStackingViewChrome-sortIcon:hover { + background-color: rgba(0,0,0,0.2); } .collectionStackingViewChrome-pivotField, .collectionTreeViewChrome-pivotField, .collection3DCarouselViewChrome-scrollSpeed { color: white; - width: 100%; + grid-column: 2; + grid-row: 1; + width: 90%; min-width: 100px; display: flex; + height: 80%; + border-radius: 7px; align-items: center; - background: rgb(238, 238, 238); + background: #eeeeee; .editable-view-input, input, @@ -378,20 +439,13 @@ display: inline-flex; position: relative; align-items: center; - margin-left: 10px; - - .antimodeMenu-button { - text-align: center; - display: block; - position: relative; - } + height: 100%; .color-previewI { - width: 80%; - height: 20%; - bottom: 0; + width: 60%; + top: 80%; position: absolute; - margin-left: 2px; + height: 4px; } .color-previewII { diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 623e05b33..3321a8d8f 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -15,7 +15,7 @@ import { RichTextField } from "../../../fields/RichTextField"; import { listSpec } from "../../../fields/Schema"; import { ScriptField } from "../../../fields/ScriptField"; import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types"; -import { emptyFunction, setupMoveUpEvents, Utils } from "../../../Utils"; +import { DeepCopy, emptyFunction, setupMoveUpEvents, Utils } from "../../../Utils"; import { DocumentType } from "../../documents/DocumentTypes"; import { CurrentUserUtils } from "../../util/CurrentUserUtils"; import { DragManager } from "../../util/DragManager"; @@ -34,6 +34,9 @@ import "./CollectionMenu.scss"; import { CollectionViewType, COLLECTION_BORDER_WIDTH } from "./CollectionView"; import { TabDocView } from "./TabDocView"; import { LightboxView } from "../LightboxView"; +import { Docs } from "../../documents/Documents"; +import { DocumentManager } from "../../util/DocumentManager"; +import { CollectionDockingView } from "./CollectionDockingView"; @observer export class CollectionMenu extends AntimodeMenu { @@ -388,7 +391,32 @@ export class CollectionViewBaseChrome extends React.Component{Doc.isDocPinned(targetDoc) ? "Unpin from presentation" : "Pin to presentation"}
    } placement="top"> + ; + } + + @undoBatch + @action + startRecording = () => { + const doc = Docs.Create.ScreenshotDocument("", { _fitWidth: true, _width: 400, _height: 200, title: "screen snapshot", system: true, cloneFieldFilter: new List(["system"]) }); + doc.x = 0; + doc.y = 0; + Doc.AddDocToList((Doc.UserDoc().myOverlayDocs as Doc), undefined, doc); + CollectionDockingView.AddSplit(doc, "right"); + // doc.startRec = true; + } + + @computed + get recordButton() { + const targetDoc = this.selectedDoc; + return {"Capture screen"}
    } placement="top"> + ; } @@ -478,7 +506,7 @@ export class CollectionViewBaseChrome extends React.Component{"Tap or Drag to create an alias"}
    } placement="top"> ; } @@ -486,38 +514,48 @@ export class CollectionViewBaseChrome extends React.Component{"View in Lightbox"}
    } placement="top"> - ; } + @computed get toggleOverlayButton() { + return <> + Toggle Overlay Layer
    } placement="bottom"> + + + + } + render() { return (
    + {this.notACollection || this.props.type === CollectionViewType.Invalid ? (null) : this.viewModes} +
    {this.aliasButton} {/* {this.pinButton} */} - {this.pinWithViewButton} - {this.lightboxButton} - Toggle Overlay Layer
    } placement="bottom"> - - + {/* {this.pinWithViewButton} */} + {this.toggleOverlayButton} +
    {this.subChrome} - {this.notACollection || this.props.type === CollectionViewType.Invalid ? (null) : this.viewModes} - {!this._buttonizableCommands ? (null) : this.templateChrome} +
    + {this.lightboxButton} + {this.recordButton} + {/* {!this._buttonizableCommands ? (null) : this.templateChrome} */}
    diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx index 8163b652c..4c24dc5e1 100644 --- a/src/client/views/nodes/ScreenshotBox.tsx +++ b/src/client/views/nodes/ScreenshotBox.tsx @@ -1,6 +1,6 @@ import React = require("react"); import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { action, computed, observable } from "mobx"; +import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; import { DateField } from "../../../fields/DateField"; import { Doc, WidthSym } from "../../../fields/Doc"; @@ -25,6 +25,7 @@ import "./ScreenshotBox.scss"; import { VideoBox } from "./VideoBox"; import { TraceMobx } from "../../../fields/util"; import { FormattedTextBox } from "./formattedText/FormattedTextBox"; +import { CaptureManager } from "../../util/CaptureManager"; declare class MediaRecorder { constructor(e: any, options?: any); // whatever MediaRecorder has } @@ -40,6 +41,8 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent this.rootDoc.startRec == true, + this.toggleRecording + ); } componentWillUnmount() { const ind = DocUtils.ActiveRecordings.indexOf(this); ind !== -1 && (DocUtils.ActiveRecordings.splice(ind, 1)); + Object.values(this._disposers).forEach(disposer => disposer?.()); } specificContextMenu = (e: React.MouseEvent): void => { @@ -91,6 +98,13 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent { + console.log("toggleRecording"); + console.log("2:" + this._videoRef.current!.srcObject); + if (this._screenCapture) { + CaptureManager.Instance.open(this.rootDoc); + } else { + console.log("opening"); + } this._screenCapture = !this._screenCapture; if (this._screenCapture) { this._audioRec = new MediaRecorder(await navigator.mediaDevices.getUserMedia({ audio: true })); @@ -149,57 +163,62 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent Math.max(0, this.props.PanelHeight() - this.videoPanelHeight()); render() { TraceMobx(); - return
    -
    -
    - - {this.contentFunc} -
    -
    - -
    + return this.rootDoc.startRec ? +
    +
    - {!this.props.isSelected() ? (null) :
    -
    - + : +
    +
    +
    + + {this.contentFunc} +
    +
    + +
    -
    } -
    ; + {!this.props.isSelected() ? (null) :
    +
    + +
    +
    } +
    ; } } \ No newline at end of file diff --git a/src/client/views/nodes/VideoBox.scss b/src/client/views/nodes/VideoBox.scss index dd8d77603..30f0c4393 100644 --- a/src/client/views/nodes/VideoBox.scss +++ b/src/client/views/nodes/VideoBox.scss @@ -1,3 +1,13 @@ +.mini-viewer{ + cursor: grab; + position: absolute; + right: 10; + top: 10; + opacity: 0.1; + transition: all 0.4s; + color: white; +} + .videoBox { transform-origin: top left; width: 100%; diff --git a/src/client/views/nodes/formattedText/RichTextMenu.scss b/src/client/views/nodes/formattedText/RichTextMenu.scss index fbc468292..1d24d6833 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.scss +++ b/src/client/views/nodes/formattedText/RichTextMenu.scss @@ -95,9 +95,10 @@ .color-preview-button { .color-preview { - width: 100%; - height: 3px; - margin-top: 3px; + width: 60%; + top: 80%; + position: absolute; + height: 4px; } } diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx index 5da868281..071491463 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.tsx +++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx @@ -976,7 +976,7 @@ export class RichTextMenu extends AntimodeMenu { const row2 =
    {this.collapsed ? this.getDragger() : (null)}
    -
    , +
    {[this.createMarksDropdown(this.activeFontSize, this.fontSizeOptions, "font size", action((val: string) => { this.activeFontSize = val; SelectionManager.Views().map(dv => dv.props.Document._fontSize = val); -- cgit v1.2.3-70-g09d2 From c60be390a83520c0be1a5de2c4748b60aa15fd45 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 7 Apr 2021 11:44:05 -0400 Subject: restricted scope of filter values/keys to documents in scope of filter --- src/client/views/nodes/FilterBox.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index 3e735404f..d7f51c57b 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -12,7 +12,6 @@ import { Cast, StrCast } from "../../../fields/Types"; import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from "../../../Utils"; import { Docs } from "../../documents/Documents"; import { DocumentType } from "../../documents/DocumentTypes"; -import { CollectionDockingView } from "../collections/CollectionDockingView"; import { CollectionTreeView } from "../collections/CollectionTreeView"; import { ViewBoxBaseComponent } from "../DocComponent"; import { SearchBox } from "../search/SearchBox"; @@ -91,7 +90,7 @@ export class FilterBox extends ViewBoxBaseComponent DocListCastAsync(CollectionDockingView.Instance.props.Document.data), + reaction(() => DocListCastAsync(this.layoutDoc.data), async (activeTabsAsync) => { const activeTabs = await activeTabsAsync; activeTabs && (await SearchBox.foreachRecursiveDocAsync(activeTabs, emptyFunction)); @@ -527,7 +526,7 @@ Scripting.addGlobal(function determineCheckedState(layoutDoc: Doc, facetHeader: return undefined; }); Scripting.addGlobal(function readFacetData(layoutDoc: Doc, facetHeader: string) { - const allCollectionDocs = DocListCast(CollectionDockingView.Instance?.props.Document.allDocuments); + const allCollectionDocs = DocListCast(layoutDoc.allDocuments); const set = new Set(); if (facetHeader === "tags") allCollectionDocs.forEach(child => Field.toString(child[facetHeader] as Field).split(":").forEach(key => set.add(key))); else allCollectionDocs.forEach(child => set.add(Field.toString(child[facetHeader] as Field))); -- cgit v1.2.3-70-g09d2 From 210dd143113b9813fc681ff50efd755658526ce9 Mon Sep 17 00:00:00 2001 From: Geireann <60007097+geireann@users.noreply.github.com> Date: Wed, 7 Apr 2021 11:46:35 -0400 Subject: Update LightboxView.tsx --- src/client/views/LightboxView.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index e33b3b35e..2fd9cb854 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -189,8 +189,10 @@ export class LightboxView extends React.Component { } else { const coll = LightboxView._docTarget; if (coll) { + console.log('test'); const fieldKey = Doc.LayoutFieldKey(coll); - LightboxView.SetLightboxDoc(coll, undefined, [...DocListCast(coll[fieldKey]), ...DocListCast(coll[fieldKey + "-annotations"])]); + LightboxView.SetLightboxDoc(coll, undefined); + // LightboxView.SetLightboxDoc(coll, undefined, [...DocListCast(coll[fieldKey]), ...DocListCast(coll[fieldKey + "-annotations"])]); TabDocView.PinDoc(coll, { hidePresBox: true }); } } -- cgit v1.2.3-70-g09d2 From 797ebbe8a82c54104a96c6e570310fb1d02da69c Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 7 Apr 2021 12:15:20 -0400 Subject: removed scope option for filters in favor of selecting dashboard. --- src/client/documents/Documents.ts | 4 +-- src/client/util/CurrentUserUtils.ts | 2 +- src/client/views/PropertiesView.tsx | 56 +++++++++++++++++------------------- src/client/views/nodes/FilterBox.tsx | 53 ++++++---------------------------- 4 files changed, 38 insertions(+), 77 deletions(-) (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 3b40f0cc7..560806078 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -1005,7 +1005,7 @@ export namespace DocUtils { return Field.toString(d[facetKey] as Field).includes(value); }); // if we're ORing them together, the default return is false, and we return true for a doc if it satisfies any one set of criteria - if (((FilterBox._filterScope === "Current Collection" ? parentCollection || CurrentUserUtils.ActiveDashboard : CurrentUserUtils.ActiveDashboard).currentFilter as Doc)?.filterBoolean === "OR") { + if ((parentCollection?.currentFilter as Doc)?.filterBoolean === "OR") { if (satisfiesCheckFacets && !failsNotEqualFacets && satisfiesMatchFacets) return true; } // if we're ANDing them together, the default return is true, and we return false for a doc if it doesn't satisfy any set of criteria @@ -1014,7 +1014,7 @@ export namespace DocUtils { } } - return ((FilterBox._filterScope === "Current Collection" ? parentCollection || CurrentUserUtils.ActiveDashboard : CurrentUserUtils.ActiveDashboard).currentFilter as Doc)?.filterBoolean === "OR" ? false : true; + return (parentCollection?.currentFilter as Doc)?.filterBoolean === "OR" ? false : true; }) : childDocs; const rangeFilteredDocs = filteredDocs.filter(d => { for (let i = 0; i < docRangeFilters.length; i += 3) { diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 4b0a49180..417a1f405 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -806,7 +806,7 @@ export class CurrentUserUtils { // setup Filter item if (doc.currentFilter === undefined) { doc.currentFilter = Docs.Create.FilterDocument({ - title: "FilterDoc", _height: 150, + title: "unnamed filter", _height: 150, treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "none", treeViewTruncateTitleWidth: 150, ignoreClick: true, _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true, _autoHeight: true, _fitWidth: true diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 92fe3acb5..bb0ad4c66 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -30,7 +30,6 @@ import { PropertiesDocContextSelector } from "./PropertiesDocContextSelector"; import "./PropertiesView.scss"; import { DefaultStyleProvider } from "./StyleProvider"; import { CurrentUserUtils } from "../util/CurrentUserUtils"; -import { FilterBox } from "./nodes/FilterBox"; import { List } from "../../fields/List"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; @@ -49,10 +48,7 @@ export class PropertiesView extends React.Component { @computed get MAX_EMBED_HEIGHT() { return 200; } - @computed get selectedDoc() { return SelectionManager.SelectedSchemaDoc() || this.selectedDocumentView?.rootDoc; } - @computed get filterDoc() { - return FilterBox._filterScope === "Current Collection" ? this.selectedDoc! : CurrentUserUtils.ActiveDashboard; - } + @computed get selectedDoc() { return SelectionManager.SelectedSchemaDoc() || this.selectedDocumentView?.rootDoc || CurrentUserUtils.ActiveDashboard; } @computed get selectedDocumentView() { if (SelectionManager.Views().length) return SelectionManager.Views()[0]; if (PresBox.Instance?._selectedArray.size) return DocumentManager.Instance.getDocumentView(PresBox.Instance.rootDoc); @@ -909,47 +905,47 @@ export class PropertiesView extends React.Component { * If it doesn't exist, it creates it. */ checkFilterDoc() { - if (this.filterDoc.type === DocumentType.COL && !this.filterDoc.currentFilter) CurrentUserUtils.setupFilterDocs(this.filterDoc); + if (this.selectedDoc.type === DocumentType.COL && !this.selectedDoc.currentFilter) CurrentUserUtils.setupFilterDocs(this.selectedDoc); } /** * Creates a new currentFilter for this.filterDoc, */ createNewFilterDoc = () => { - const currentDocFilters = this.filterDoc._docFilters; - const currentDocRangeFilters = this.filterDoc._docRangeFilters; - this.filterDoc._docFilters = new List(); - this.filterDoc._docRangeFilters = new List(); - (this.filterDoc.currentFilter as Doc)._docFiltersList = currentDocFilters; - (this.filterDoc.currentFilter as Doc)._docRangeFiltersList = currentDocRangeFilters; - this.filterDoc.currentFilter = undefined; - CurrentUserUtils.setupFilterDocs(this.filterDoc); + const currentDocFilters = this.selectedDoc._docFilters; + const currentDocRangeFilters = this.selectedDoc._docRangeFilters; + this.selectedDoc._docFilters = new List(); + this.selectedDoc._docRangeFilters = new List(); + (this.selectedDoc.currentFilter as Doc)._docFiltersList = currentDocFilters; + (this.selectedDoc.currentFilter as Doc)._docRangeFiltersList = currentDocRangeFilters; + this.selectedDoc.currentFilter = undefined; + CurrentUserUtils.setupFilterDocs(this.selectedDoc); } /** * Updates this.filterDoc's currentFilter and saves the docFilters on the currentFilter */ updateFilterDoc = (doc: Doc) => { - if (doc === this.filterDoc.currentFilter) return; // causes problems if you try to reapply the same doc + if (doc === this.selectedDoc.currentFilter) return; // causes problems if you try to reapply the same doc const savedDocFilters = doc._docFiltersList; - const currentDocFilters = this.filterDoc._docFilters; - this.filterDoc._docFilters = new List(); - (this.filterDoc.currentFilter as Doc)._docFiltersList = currentDocFilters; - this.filterDoc.currentFilter = doc; + const currentDocFilters = this.selectedDoc._docFilters; + this.selectedDoc._docFilters = new List(); + (this.selectedDoc.currentFilter as Doc)._docFiltersList = currentDocFilters; + this.selectedDoc.currentFilter = doc; doc._docFiltersList = new List(); - this.filterDoc._docFilters = savedDocFilters; + this.selectedDoc._docFilters = savedDocFilters; const savedDocRangeFilters = doc._docRangeFiltersList; - const currentDocRangeFilters = this.filterDoc._docRangeFilters; - this.filterDoc._docRangeFilters = new List(); - (this.filterDoc.currentFilter as Doc)._docRangeFiltersList = currentDocRangeFilters; - this.filterDoc.currentFilter = doc; + const currentDocRangeFilters = this.selectedDoc._docRangeFilters; + this.selectedDoc._docRangeFilters = new List(); + (this.selectedDoc.currentFilter as Doc)._docRangeFiltersList = currentDocRangeFilters; + this.selectedDoc.currentFilter = doc; doc._docRangeFiltersList = new List(); - this.filterDoc._docRangeFilters = savedDocRangeFilters; + this.selectedDoc._docRangeFilters = savedDocRangeFilters; } @computed get filtersSubMenu() { - return !(this.filterDoc?.currentFilter instanceof Doc) ? (null) :
    + return !(this.selectedDoc?.currentFilter instanceof Doc) ? (null) :
    this.openFilters = !this.openFilters)} style={{ backgroundColor: this.openFilters ? "black" : "" }}> @@ -960,9 +956,9 @@ export class PropertiesView extends React.Component {
    { !this.openFilters ? (null) : -
    +
    { removeDocument={returnFalse} ScreenToLocalTransform={this.getTransform} PanelWidth={() => this.props.width} - PanelHeight={this.filterDoc.currentFilter[HeightSym]} + PanelHeight={this.selectedDoc.currentFilter[HeightSym]} renderDepth={0} - scriptContext={this.filterDoc.currentFilter} + scriptContext={this.selectedDoc.currentFilter} focus={emptyFunction} styleProvider={DefaultStyleProvider} isContentActive={returnTrue} diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index d7f51c57b..05bb69d61 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -27,7 +27,6 @@ import Select from "react-select"; import { UserOptions } from "../../util/GroupManager"; import { DocumentViewProps } from "./DocumentView"; import { DefaultStyleProvider, StyleProp } from "../StyleProvider"; -import { CollectionViewType } from "../collections/CollectionView"; import { CurrentUserUtils } from "../../util/CurrentUserUtils"; import { EditableView } from "../EditableView"; import { undoBatch } from "../../util/UndoManager"; @@ -45,7 +44,6 @@ export class FilterBox extends ViewBoxBaseComponent this._loaded = true); }, { fireImmediately: true }); } + @observable _allDocs = [] as Doc[]; @computed get allDocs() { // trace(); - const allDocs = new Set(); const targetDoc = FilterBox.targetDoc; if (this._loaded && targetDoc) { + const allDocs = new Set(); const activeTabs = DocListCast(targetDoc.data); SearchBox.foreachRecursiveDoc(activeTabs, (doc: Doc) => allDocs.add(doc)); - setTimeout(() => targetDoc.allDocuments = new List(Array.from(allDocs))); + setTimeout(action(() => this._allDocs = Array.from(allDocs))); } - return allDocs; + return this._allDocs; } @computed get _allFacets() { @@ -270,34 +269,6 @@ export class FilterBox extends ViewBoxBaseComponent { - if (FilterBox._filterScope === "Current Dashboard" && e.currentTarget.value === "Current Collection") { - const currentDashboardDocFilters = CurrentUserUtils.ActiveDashboard._docFilters; - CurrentUserUtils.ActiveDashboard._docFilters = new List(); - (CurrentUserUtils.ActiveDashboard.currentFilter as Doc)._docFilterList = currentDashboardDocFilters; - - const currentDashboardDocRangeFilters = CurrentUserUtils.ActiveDashboard._docRangeFilters; - CurrentUserUtils.ActiveDashboard._docRangeFilters = new List(); - (CurrentUserUtils.ActiveDashboard.currentFilter as Doc)._docRangeFilterList = currentDashboardDocRangeFilters; - } - else if (FilterBox._filterScope === "Current Collection" && e.currentTarget.value === "Current Dashboard") { - const savedDashboardDocFilters = (CurrentUserUtils.ActiveDashboard.currentFilter as Doc)._docFilterList; - (CurrentUserUtils.ActiveDashboard.currentFilter as Doc)._docFilterList = undefined; - CurrentUserUtils.ActiveDashboard._docFilters = savedDashboardDocFilters; - - const savedDashboardDocRangeFilters = (CurrentUserUtils.ActiveDashboard.currentFilter as Doc)._docRangeFilterList; - (CurrentUserUtils.ActiveDashboard.currentFilter as Doc)._docRangeFilterList = undefined; - CurrentUserUtils.ActiveDashboard._docRangeFilters = savedDashboardDocRangeFilters; - } - FilterBox._filterScope = e.currentTarget.value; - } - /** * Changes whether to select matched or unmatched documents */ @@ -415,14 +386,6 @@ export class FilterBox extends ViewBoxBaseComponentOR
    filters in
    -
    @@ -526,7 +489,9 @@ Scripting.addGlobal(function determineCheckedState(layoutDoc: Doc, facetHeader: return undefined; }); Scripting.addGlobal(function readFacetData(layoutDoc: Doc, facetHeader: string) { - const allCollectionDocs = DocListCast(layoutDoc.allDocuments); + const allCollectionDocs = new Set(); + const activeTabs = DocListCast(layoutDoc.data); + SearchBox.foreachRecursiveDoc(activeTabs, (doc: Doc) => allCollectionDocs.add(doc)); const set = new Set(); if (facetHeader === "tags") allCollectionDocs.forEach(child => Field.toString(child[facetHeader] as Field).split(":").forEach(key => set.add(key))); else allCollectionDocs.forEach(child => set.add(Field.toString(child[facetHeader] as Field))); -- cgit v1.2.3-70-g09d2 From d0b37d7b5a8749cb6157d938ff576c7714c8ce0b Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 7 Apr 2021 13:39:42 -0400 Subject: fixes for lightbox stepping into --- src/client/documents/Documents.ts | 6 +++--- src/client/util/DragManager.ts | 2 +- src/client/views/LightboxView.tsx | 4 ++-- src/client/views/nodes/formattedText/FormattedTextBox.tsx | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 337c3e928..90db8644d 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -668,7 +668,7 @@ export namespace Docs { viewProps["acl-Override"] = "None"; viewProps["acl-Public"] = Doc.UserDoc()?.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Add; const viewDoc = Doc.assign(Doc.MakeDelegate(dataDoc, delegId), viewProps, true, true); - ![DocumentType.LINK, DocumentType.TEXTANCHOR, DocumentType.LABEL].includes(viewDoc.type as any) && DocUtils.MakeLinkToActiveAudio(viewDoc); + ![DocumentType.LINK, DocumentType.TEXTANCHOR, DocumentType.LABEL].includes(viewDoc.type as any) && DocUtils.MakeLinkToActiveAudio(() => viewDoc); !Doc.IsSystem(dataDoc) && ![DocumentType.HTMLANCHOR, DocumentType.KVP, DocumentType.LINK, DocumentType.LINKANCHOR, DocumentType.TEXTANCHOR].includes(proto.type as any) && !dataDoc.isFolder && !dataProps.annotationOn && Doc.AddDocToList(Cast(Doc.UserDoc().myFileOrphans, Doc, null), "data", dataDoc); @@ -1046,10 +1046,10 @@ export namespace DocUtils { export let ActiveRecordings: { props: FieldViewProps, getAnchor: () => Doc }[] = []; - export function MakeLinkToActiveAudio(doc: Doc, broadcastEvent = true) { + export function MakeLinkToActiveAudio(getSourceDoc: () => Doc, broadcastEvent = true) { broadcastEvent && runInAction(() => DocumentManager.Instance.RecordingEvent = DocumentManager.Instance.RecordingEvent + 1); return DocUtils.ActiveRecordings.map(audio => - DocUtils.MakeLink({ doc: doc }, { doc: audio.getAnchor() || audio.props.Document }, "recording link", "recording timeline")); + DocUtils.MakeLink({ doc: getSourceDoc() }, { doc: audio.getAnchor() || audio.props.Document }, "recording link", "recording timeline")); } export function MakeLink(source: { doc: Doc }, target: { doc: Doc }, linkRelationship: string = "", description: string = "", id?: string, allowParCollectionLink?: boolean, showPopup?: number[]) { diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index c1235163b..d8c2f913e 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -207,7 +207,7 @@ export namespace DragManager { ) { const addAudioTag = (dropDoc: any) => { dropDoc && !dropDoc.creationDate && (dropDoc.creationDate = new DateField); - dropDoc instanceof Doc && DocUtils.MakeLinkToActiveAudio(dropDoc); + dropDoc instanceof Doc && DocUtils.MakeLinkToActiveAudio(() => dropDoc); return dropDoc; }; const finishDrag = (e: DragCompleteEvent) => { diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index e33b3b35e..b26765fa7 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -116,7 +116,7 @@ export class LightboxView extends React.Component { const target = LightboxView._docTarget = LightboxView._future?.pop(); const targetDocView = target && DocumentManager.Instance.getLightboxDocumentView(target); if (targetDocView && target) { - const l = DocUtils.MakeLinkToActiveAudio(targetDocView.ComponentView?.getAnchor?.() || target).lastElement(); + const l = DocUtils.MakeLinkToActiveAudio(() => targetDocView.ComponentView?.getAnchor?.() || target).lastElement(); l && (Cast(l.anchor2, Doc, null).backgroundColor = "lightgreen"); targetDocView.focus(target, { originalTarget: target, willZoom: true, scale: 0.9 }); if (LightboxView._history?.lastElement().target !== target) LightboxView._history?.push({ doc, target }); @@ -282,7 +282,7 @@ interface LightboxTourBtnProps { export class LightboxTourBtn extends React.Component { render() { return this.props.navBtn("50%", 0, 0, "chevron-down", - () => LightboxView.LightboxDoc && this.props.future()?.length ? "" : "none", e => { + () => LightboxView.LightboxDoc /*&& this.props.future()?.length*/ ? "" : "none", e => { e.stopPropagation(); this.props.stepInto(); }, diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 208accfc7..9482b632a 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -669,7 +669,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp if (this._break) { const textanchor = Docs.Create.TextanchorDocument({ title: "dictation anchor" }); this.addDocument(textanchor); - const link = DocUtils.MakeLinkToActiveAudio(textanchor, false).lastElement(); + const link = DocUtils.MakeLinkToActiveAudio(() => textanchor, false).lastElement(); link && (Doc.GetProto(link).isDictation = true); if (!link) return; const audioanchor = Cast(link.anchor2, Doc, null); -- cgit v1.2.3-70-g09d2 From 6a73699a10edb842b2b5eba4ef05731772859f13 Mon Sep 17 00:00:00 2001 From: Geireann <60007097+geireann@users.noreply.github.com> Date: Wed, 7 Apr 2021 14:45:14 -0400 Subject: bug fixes --- src/client/util/CaptureManager.scss | 450 ++------------------- src/client/util/CaptureManager.tsx | 47 ++- src/client/views/LightboxView.tsx | 7 +- src/client/views/MainViewModal.tsx | 2 +- src/client/views/collections/CollectionMenu.tsx | 2 +- src/client/views/nodes/ScreenshotBox.tsx | 150 +++---- .../views/presentationview/PresElementBox.tsx | 2 + 7 files changed, 160 insertions(+), 500 deletions(-) (limited to 'src') diff --git a/src/client/util/CaptureManager.scss b/src/client/util/CaptureManager.scss index 5ca54517c..8447bd2d5 100644 --- a/src/client/util/CaptureManager.scss +++ b/src/client/util/CaptureManager.scss @@ -1,8 +1,7 @@ @import "../views/globalCssVariables"; -.settings-interface { +.capture-interface { //background-color: whitesmoke !important; - color: grey; width: 450px; button { @@ -21,14 +20,35 @@ } } -.settings-title { - font-size: 25px; - font-weight: bold; - padding-right: 10px; +.capture-t1 { + display: flex; + justify-content: left; + align-items: center; + font-size: 20px; + font-family: 'Roboto'; + font-weight: 600; color: black; + + .recordButtonOutline { + border-radius: 100%; + width: 25px; + height: 25px; + margin-right: 10px; + border: solid 1px #a94442; + display: flex; + align-items: center; + justify-content: center; + } + + .recordButtonInner { + border-radius: 100%; + width: 70%; + height: 70%; + background: #a94442; + } } -.settings-username { +.capture-t2 { font-size: 12px; padding-right: 15px; color: black; @@ -39,13 +59,13 @@ // left: 243; } -.settings-section { +.capture-block { display: flex; border-bottom: 1px solid grey; padding-bottom: 8px; padding-top: 6px; - .settings-section-title { + .capture-block-title { font-size: 16; font-weight: bold; text-align: left; @@ -59,407 +79,21 @@ } } - -.password-content { - display: flex; - flex-direction: column; - - .password-content-inputs { - width: 100; - // margin-bottom: 10px; - font-size: 10px; - - .password-inputs { - border: 1px solid rgb(160, 160, 160); - margin-bottom: 8px; - width: 130; - color: black; - border-radius: 5px; - padding:7px; - - } - } - - .password-content-buttons { - //margin-left: 84px; - //width: 100; - padding: 7px; - - .password-submit { - //margin-left: 85px; - margin-top: 5px; - } - - .password-forgot { - //margin-left: 65px; - //margin-top: -20px; - font-size: 12px; - white-space: nowrap; - } - } -} - -.accounts-content { +.close-button { + position: absolute; + top: 10; + right: 10; + background:transparent; + border-radius:100%; + width: 25px; + height: 25px; display: flex; + align-items: center; + justify-content: center; + transition: 0.2s; } -.modes-content { - display: flex; - margin-left: 10px; - font-size: 12px; - - .modes-select { - // width: 170px; - width: 80%; - height: 35px; - margin-right: 10px; - color: black; - border-radius: 5px; - - &:hover { - cursor: pointer; - } - } - - .modes-playground, - .default-acl { - display: flex; - margin-left: 10px; - margin-top: 10px; - font-size: 10px; - - .playground-check, - .acl-check { - margin-right: 5px; - - &:hover { - cursor: pointer; - } - } - - .playground-text { - color: black; - margin-right: 10px; - margin-top: 2; - } - - .acl-text { - color: black; - margin-top: 2; - text-align: left; - } - - } -} - -.colorFlyout { - margin-top: 2px; - //margin-right: 18px; - - &:hover { - cursor: pointer; - } - - .colorFlyout-button { - width: 20px; - height: 20px; - border: 0.5px solid black; - border-radius: 5px; - padding-top: 3px; - } -} - -.prefs-content{ - text-align: left; -} - -.appearances-content { - display: flex; - margin-top: 4px; - color: black; - font-size: 10px; - - .preferences-color { - display: flex; - margin-top: 2px; - - .preferences-color-text { - margin-top: 3px; - margin-right: 4; - flex: 1 1 auto; - text-align: left; - } - - .colorFlyout { - align-self: flex-end; - } - } - - .preferences-font { - //height: 23px; - margin-top: 2px; - - .preferences-font-text { - color: black; - margin-top: 4; - margin-right: 4; - margin-bottom: 2px; - text-align: left; - } - - .preferences-font-controls { - display: flex; - justify-content: space-between; - } - - .font-select { - height: 35px; - color: black; - font-size: 9; - margin-right: 6; - border-radius: 5px; - width: 65%; - - &:hover { - cursor: pointer; - } - } - - .size-select { - height: 35px; - color: black; - font-size: 9; - border-radius: 5px; - width: 30%; - - &:hover { - cursor: pointer; - } - } - } - - .preferences-check { - color: black; - margin-right: 4; - margin-bottom: -3; - margin-left: 5; - margin-top: -1px; - display: inline-block; - padding-left: 5px; - text-align: left; - } +.close-button:hover { + background: rgba(0,0,0,0.1); } -.settings-interface { - display: flex; - flex-direction: column; - - button { - width: auto; - align-self: center; - background: #252b33; - margin-right: 15px; - - //margin-top: 4px; - - &:hover { - background: $main-accent; - } - } - - // .delete-button { - // background: rgb(227, 86, 86); - // } - - .close-button { - position: absolute; - right: 1em; - top: 1em; - cursor: pointer; - } - - // .logout-button { - // right: 355; - // position: absolute; - // } - - .settings-content { - background: #e4e4e4; - //border-radius: 6px; - padding: 10px; - //width: 560px; - flex: 1 1 auto; - } - - .settings-top { - display: flex; - margin-bottom: 10px; - } - - - .error-text { - color: #C40233; - width: 300; - margin-left: -20; - font-size: 10; - margin-bottom: 4; - margin-top: -3; - } - - .success-text { - width: 300; - margin-left: -20; - font-size: 10; - margin-bottom: 4; - margin-top: -3; - color: #009F6B; - } - - .focus-span { - text-decoration: underline; - } - - h1 { - color: #121721; - text-transform: uppercase; - letter-spacing: 2px; - font-size: 19; - margin-top: 0; - font-weight: bold; - } - - .container { - display: block; - position: relative; - margin-top: 10px; - margin-bottom: 10px; - font-size: 22px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - width: 700px; - min-width: 700px; - max-width: 700px; - text-align: left; - font-style: normal; - font-size: 15; - font-weight: normal; - padding: 0; - - .padding { - padding: 0 0 0 20px; - color: black; - } - - } -} - -.settings-interface { - flex-direction: row; - position: relative; - min-height: 250px; - width: 100%; - - .settings-content { - background-color: #fdfdfd; - } -} - -.settings-panel { - position: relative; - min-width: 150px; - background-color: #e4e4e4; - - .settings-user { - position: absolute; - bottom: 10px; - text-align: center; - left: 0; - right: 0; - - .settings-username { - padding-right: 0px; - } - - .logout-button { - margin-right: 2px; - } - } -} - -.settings-tabs { - // font-size: 16px; - font-weight: 600; - color: black; - - .tab-control { - padding: 10px; - border-bottom: 1px solid #9f9e9e; - cursor: pointer; - - &.active { - background-color: #fdfdfd; - } - } -} - -.settings-section-context { - width: 100%; -} - -.tab-section { - display: none; - height: 200px; - - &.active { - display: block; - } -} - -.tab-content { - display: flex; - margin: 20px 0; - - .tab-column { - flex: 0 0 50%; - - .tab-column-title { - color: black; - font-size: 16px; - font-weight: bold; - margin-bottom: 16px; - } - - .tab-column-title, .tab-column-content { - padding-left: 16px; - } - - } - -} - -.tab-column button { - font-size: 9px; -} - -@media only screen and (max-device-width: 480px) { - .settings-interface { - width: 80vw; - height: 400px; - } - - .settings-interface .settings-body .settings-content input { - font-size: 30; - } - - .settings-interface button { - width: 100%; - font-size: 30px; - background: #315a96; - } - - .settings-interface .settings-heading { - font-size: 25; - } -} diff --git a/src/client/util/CaptureManager.tsx b/src/client/util/CaptureManager.tsx index f01fcd0d2..cea0c182f 100644 --- a/src/client/util/CaptureManager.tsx +++ b/src/client/util/CaptureManager.tsx @@ -2,16 +2,10 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { action, computed, observable, runInAction } from "mobx"; import { observer } from "mobx-react"; import * as React from "react"; -import { ColorState, SketchPicker } from "react-color"; import { Doc } from "../../fields/Doc"; import { BoolCast, StrCast, Cast } from "../../fields/Types"; import { addStyleSheet, addStyleSheetRule, Utils } from "../../Utils"; -import { GoogleAuthenticationManager } from "../apis/GoogleAuthenticationManager"; -import { DocServer } from "../DocServer"; -import { Networking } from "../Network"; import { MainViewModal } from "../views/MainViewModal"; -import { CurrentUserUtils } from "./CurrentUserUtils"; -import { GroupManager } from "./GroupManager"; import "./CaptureManager.scss"; import { undoBatch } from "./UndoManager"; const higflyout = require("@hig/flyout"); @@ -22,6 +16,7 @@ export const Flyout = higflyout.default; export class CaptureManager extends React.Component<{}> { public static Instance: CaptureManager; static _settingsStyle = addStyleSheet(); + @observable _document: any; @observable isOpen: boolean = false; // whether the CaptureManager is to be displayed or not. @@ -31,18 +26,27 @@ export class CaptureManager extends React.Component<{}> { } public close = action(() => this.isOpen = false); - public open = action(() => this.isOpen = true); + public open = action((doc: Doc) => { + this.isOpen = true; + this._document = doc; + }); - @computed get colorsContent() { - - return
    + @computed get visibilityContent() { + return
    +
    Visibility +
    + Private + Public +
    +
    ; } - @computed get formatsContent() { - return
    + @computed get linksContent() { + return
    +
    Links
    ; } @@ -52,11 +56,19 @@ export class CaptureManager extends React.Component<{}> { private get captureInterface() { - return
    -
    - + return
    +
    +
    +
    +
    +
    + Conversation Capture
    +
    +
    + {this.visibilityContent} + {this.linksContent}
    @@ -70,6 +82,9 @@ export class CaptureManager extends React.Component<{}> { isDisplayed={this.isOpen} interactive={true} closeOnExternalClick={this.close} - dialogueBoxStyle={{ width: "500px", height: "300px", background: Cast(Doc.SharingDoc().userColor, "string", null) }} />; + dialogueBoxStyle={{ width: "500px", height: "300px", border: "none", background: Cast(Doc.SharingDoc().userColor, "string", null) }} + overlayStyle={{ background: "black" }} + overlayDisplayedOpacity={0.6} + /> } } \ No newline at end of file diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index 2fd9cb854..efd3d733f 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -188,10 +188,13 @@ export class LightboxView extends React.Component { LightboxView._future?.push(...DocListCast(tours[0][fieldKey]).reverse()); } else { const coll = LightboxView._docTarget; - if (coll) { + const doc = LightboxView.LightboxDoc; + if (coll && doc) { console.log('test'); + console.log('target: ' + coll.title); + console.log('doc: ' + doc.title); const fieldKey = Doc.LayoutFieldKey(coll); - LightboxView.SetLightboxDoc(coll, undefined); + LightboxView.SetLightboxDoc(doc); // LightboxView.SetLightboxDoc(coll, undefined, [...DocListCast(coll[fieldKey]), ...DocListCast(coll[fieldKey + "-annotations"])]); TabDocView.PinDoc(coll, { hidePresBox: true }); } diff --git a/src/client/views/MainViewModal.tsx b/src/client/views/MainViewModal.tsx index 7f91c0079..55dee005d 100644 --- a/src/client/views/MainViewModal.tsx +++ b/src/client/views/MainViewModal.tsx @@ -34,7 +34,7 @@ export class MainViewModal extends React.Component {
    (["system"]) }); doc.x = 0; doc.y = 0; + doc.startRec = true; Doc.AddDocToList((Doc.UserDoc().myOverlayDocs as Doc), undefined, doc); CollectionDockingView.AddSplit(doc, "right"); - // doc.startRec = true; } @computed diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx index 4c24dc5e1..cecc593f0 100644 --- a/src/client/views/nodes/ScreenshotBox.tsx +++ b/src/client/views/nodes/ScreenshotBox.tsx @@ -1,6 +1,6 @@ import React = require("react"); import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from "mobx"; +import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction, trace } from "mobx"; import { observer } from "mobx-react"; import { DateField } from "../../../fields/DateField"; import { Doc, WidthSym } from "../../../fields/Doc"; @@ -36,7 +36,7 @@ const ScreenshotDocument = makeInterface(documentSchema); @observer export class ScreenshotBox extends ViewBoxAnnotatableComponent(ScreenshotDocument) { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(ScreenshotBox, fieldKey); } - private _videoRef = React.createRef(); + private _videoRef: HTMLVideoElement | undefined | null; private _audioRec: any; private _videoRec: any; @observable _screenCapture = false; @@ -56,7 +56,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent { - const aspect = this._videoRef.current!.videoWidth / this._videoRef.current!.videoHeight; + const aspect = this._videoRef!.videoWidth / this._videoRef!.videoHeight; const nativeWidth = Doc.NativeWidth(this.layoutDoc); const nativeHeight = Doc.NativeHeight(this.layoutDoc); if (!nativeWidth || !nativeHeight) { @@ -69,9 +69,6 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent this.rootDoc.startRec == true, - this.toggleRecording - ); } componentWillUnmount() { const ind = DocUtils.ActiveRecordings.indexOf(this); @@ -85,10 +82,22 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent { + console.log('ref: ', r); + this._videoRef = r; + setTimeout(() => { + if (this.rootDoc.startRec && this._videoRef) { // TODO glr: use mediaState + this.toggleRecording(); + this.rootDoc.startRec = undefined; + } + }, 1000); + }} + autoPlay={true} + style={{ width: "100%", height: "100%" }} onCanPlay={this.videoLoad} controls={true} onClick={e => e.preventDefault()}> @@ -99,14 +108,11 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent { console.log("toggleRecording"); - console.log("2:" + this._videoRef.current!.srcObject); - if (this._screenCapture) { - CaptureManager.Instance.open(this.rootDoc); - } else { - console.log("opening"); - } + console.log("2:" + this._videoRef!.srcObject); + this._screenCapture = !this._screenCapture; if (this._screenCapture) { + console.log("opening"); this._audioRec = new MediaRecorder(await navigator.mediaDevices.getUserMedia({ audio: true })); const aud_chunks: any = []; this._audioRec.ondataavailable = (e: any) => aud_chunks.push(e.data); @@ -116,12 +122,13 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent this.dataDoc[this.props.fieldKey + "-recordingStart"] = new DateField(new Date()); this._videoRec.ondataavailable = (e: any) => vid_chunks.push(e.data); this._videoRec.onstop = async (e: any) => { + console.log("onStop: video end"); const file = new File(vid_chunks, `${this.rootDoc[Id]}.mkv`, { type: vid_chunks[0].type, lastModified: Date.now() }); const [{ result }] = await Networking.UploadFilesToServer(file); this.dataDoc[this.fieldKey + "-duration"] = (new Date().getTime() - this.recordingStart!) / 1000; @@ -143,6 +150,9 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent Math.max(0, this.props.PanelHeight() - this.videoPanelHeight()); render() { TraceMobx(); - return this.rootDoc.startRec ? -
    - + console.log('rendering'); + return
    +
    +
    + + {this.contentFunc} +
    +
    + +
    - : -
    -
    -
    - - {this.contentFunc} -
    -
    - -
    + {!this.props.isSelected() ? (null) :
    +
    +
    - {!this.props.isSelected() ? (null) :
    -
    - -
    -
    } -
    ; +
    } +
    ; } } \ No newline at end of file diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index a1fc77a92..f15d51764 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -57,6 +57,7 @@ export class PresElementBox extends ViewBoxBaseComponent [this.rootDoc.presExpandInlineButton, this.collapsedHeight], params => this.layoutDoc._height = NumCast(params[1]) + (Number(params[0]) ? 100 : 0), { fireImmediately: true }); } @@ -114,6 +115,7 @@ export class PresElementBox extends ViewBoxBaseComponent
    ; -- cgit v1.2.3-70-g09d2 From 821f1395198e4fe4cb06192ce1ba1a2864914159 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 7 Apr 2021 15:44:17 -0400 Subject: can't make two different views of a recording. --- src/client/views/collections/CollectionMenu.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 3299ea3a9..e0c68e51c 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -403,7 +403,7 @@ export class CollectionViewBaseChrome extends React.Component Date: Thu, 8 Apr 2021 04:07:42 -0400 Subject: changes --- src/client/util/CaptureManager.scss | 84 ++++++++++++++++++++-- src/client/util/CaptureManager.tsx | 66 ++++++++++++++--- src/client/views/collections/CollectionMenu.tsx | 3 +- .../collections/CollectionStackedTimeline.tsx | 8 +-- src/client/views/nodes/DocumentView.tsx | 2 +- src/client/views/nodes/VideoBox.tsx | 3 +- 6 files changed, 146 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/client/util/CaptureManager.scss b/src/client/util/CaptureManager.scss index 8447bd2d5..71539ee1e 100644 --- a/src/client/util/CaptureManager.scss +++ b/src/client/util/CaptureManager.scss @@ -60,8 +60,7 @@ } .capture-block { - display: flex; - border-bottom: 1px solid grey; + display: block; padding-bottom: 8px; padding-top: 6px; @@ -72,10 +71,87 @@ color: black; width: 80; margin-right: 50px; + margin-bottom: 5px; + } + + .capture-block-list { + height: 135px; + width: calc(100% + 15px); + overflow: scroll; + } + + .capture-block-radio { + font-size: 12; + display: block; + font-weight: normal; + + .radio-container { + display: flex; + justify-content: left; + align-items: center; + font-size: 13px; + font-family: 'Roboto'; + } } - &:last-child { - border-bottom: none; + .list-item { + display: flex; + height: 25px; + font-family: 'Roboto'; + font-size: 13px; + + .number { + width: 20px; + height: 20px; + display: flex; + justify-content: center; + align-items: center; + background-color: #BDDBE8; + border-radius: 100%; + font-weight: 800; + margin-right: 5px; + } + } + + .buttons { + display: flex; + position: absolute; + bottom: 0; + right: 15; + justify-content: flex-end; + align-items: center; + height: 60px; + + .save { + cursor: pointer; + width: 80px; + height: 40px; + font-size: 14px; + display: flex; + font-weight: bold; + justify-content: center; + align-items: center; + background: #337ab7; + color: whitesmoke; + border-radius: 5px; + text-transform: uppercase; + } + + .cancel { + cursor: pointer; + width: 80px; + height: 40px; + font-size: 14px; + display: flex; + font-weight: 100; + justify-content: center; + align-items: center; + background: #ccc; + color: black; + border-radius: 5px; + text-transform: uppercase; + margin-left: 10px; + } } } diff --git a/src/client/util/CaptureManager.tsx b/src/client/util/CaptureManager.tsx index cea0c182f..c38337c91 100644 --- a/src/client/util/CaptureManager.tsx +++ b/src/client/util/CaptureManager.tsx @@ -2,11 +2,14 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { action, computed, observable, runInAction } from "mobx"; import { observer } from "mobx-react"; import * as React from "react"; -import { Doc } from "../../fields/Doc"; +import { convertToObject } from "typescript"; +import { Doc, DocListCast } from "../../fields/Doc"; import { BoolCast, StrCast, Cast } from "../../fields/Types"; import { addStyleSheet, addStyleSheetRule, Utils } from "../../Utils"; +import { LightboxView } from "../views/LightboxView"; import { MainViewModal } from "../views/MainViewModal"; import "./CaptureManager.scss"; +import { SelectionManager } from "./SelectionManager"; import { undoBatch } from "./UndoManager"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; @@ -35,23 +38,69 @@ export class CaptureManager extends React.Component<{}> { @computed get visibilityContent() { return
    -
    Visibility -
    - Private - Public +
    Visibility
    +
    +
    + Private +
    +
    + Public
    ; } @computed get linksContent() { + const doc = this._document; + const order: JSX.Element[] = []; + if (doc) { + console.log('title', doc.title); + console.log('links', doc.links); + const linkDocs = DocListCast(doc.links); + const firstDocs = linkDocs.filter(linkDoc => Doc.AreProtosEqual(linkDoc.anchor1 as Doc, doc) || Doc.AreProtosEqual((linkDoc.anchor1 as Doc).annotationOn as Doc, doc)); // link docs where 'doc' is anchor1 + const secondDocs = linkDocs.filter(linkDoc => Doc.AreProtosEqual(linkDoc.anchor2 as Doc, doc) || Doc.AreProtosEqual((linkDoc.anchor2 as Doc).annotationOn as Doc, doc)); // link docs where 'doc' is anchor2 + linkDocs.forEach((l, i) => { + if (l) { + console.log(i, (l.anchor1 as Doc).title); + console.log(i, (l.anchor2 as Doc).title); + order.push( +
    +
    {i}
    + {(l.anchor1 as Doc).title} +
    + ); + } + }); + } + return
    Links
    - +
    + {order} +
    ; } - + @computed get closeButtons() { + return
    +
    +
    { + LightboxView.SetLightboxDoc(this._document); + this.close(); + }}> + Save +
    +
    { + const selected = SelectionManager.Views().slice(); + SelectionManager.DeselectAll(); + selected.map(dv => dv.props.removeDocument?.(dv.props.Document)); + this.close(); + }}> + Cancel +
    +
    +
    + } @@ -72,6 +121,7 @@ export class CaptureManager extends React.Component<{}> {
    + {this.closeButtons}
    ; } @@ -82,7 +132,7 @@ export class CaptureManager extends React.Component<{}> { isDisplayed={this.isOpen} interactive={true} closeOnExternalClick={this.close} - dialogueBoxStyle={{ width: "500px", height: "300px", border: "none", background: Cast(Doc.SharingDoc().userColor, "string", null) }} + dialogueBoxStyle={{ width: "500px", height: "350px", border: "none", background: "whitesmoke" }} overlayStyle={{ background: "black" }} overlayDisplayedOpacity={0.6} /> diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 3299ea3a9..6816b4739 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -403,7 +403,6 @@ export class CollectionViewBaseChrome extends React.Component
    {this.aliasButton} {/* {this.pinButton} */} - {/* {this.pinWithViewButton} */} {this.toggleOverlayButton} + {this.pinWithViewButton}
    {this.subChrome}
    diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx index 6a1242f20..4f9f297a2 100644 --- a/src/client/views/collections/CollectionStackedTimeline.tsx +++ b/src/client/views/collections/CollectionStackedTimeline.tsx @@ -234,15 +234,15 @@ export class CollectionStackedTimeline extends CollectionSubView this.props.PanelHeight() / 3; - timelineContentHeight = () => this.props.PanelHeight() * 2 / 3; + dictationHeight = () => "50%"; + timelineContentHeight = () => this.props.PanelHeight() / 2; dictationScreenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(0, -this.timelineContentHeight()); @computed get renderDictation() { const dictation = Cast(this.dataDoc[this.props.dictationKey], Doc, null); - return !dictation ? (null) :
    + return !dictation ? (null) :
    "100%"} isAnnotationOverlay={true} isDocumentActive={returnFalse} select={emptyFunction} diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 26cf52f17..153603c3c 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -1105,7 +1105,7 @@ export class DocumentView extends React.Component { position: this.props.Document.isInkMask ? "absolute" : undefined, transform: `translate(${this.centeringX}px, ${this.centeringY}px)`, width: xshift() ?? `${100 * (this.props.PanelWidth() - this.Xshift * 2) / this.props.PanelWidth()}%`, - height: yshift() ?? (this.fitWidth ? `${this.panelHeight}px` : + height: this.props.Document.type === DocumentType.VID ? "100%" : yshift() ?? (this.fitWidth ? `${this.panelHeight}px` : `${100 * this.effectiveNativeHeight / this.effectiveNativeWidth * this.props.PanelWidth() / this.props.PanelHeight()}%`), }}> { this._clicking = true; + console.log('timeline click'); setupMoveUpEvents(this, e, action((e: PointerEvent) => { this._clicking = false; if (this.isContentActive()) { const local = this.props.ScreenToLocalTransform().scale(this.props.scaling?.() || 1).transformPoint(e.clientX, e.clientY); - this.layoutDoc._timelineHeightPercent = Math.max(0, Math.min(100, local[1] / this.props.PanelHeight() * 100)); + this.layoutDoc._timelineHeightPercent = 50; } return false; }), emptyFunction, -- cgit v1.2.3-70-g09d2 From d021eb6fe792e9c76b139b5a706a90a086f3fe53 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 8 Apr 2021 12:59:22 -0400 Subject: made "search" only appear if context menu is > 15 items. --- src/client/views/ContextMenu.tsx | 27 ++-- src/client/views/ContextMenuItem.tsx | 7 +- src/client/views/collections/TreeView.tsx | 17 ++- .../collections/collectionFreeForm/MarqueeView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 149 +++++++++++---------- 5 files changed, 106 insertions(+), 96 deletions(-) (limited to 'src') diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx index 1f7abf61a..d96de72e3 100644 --- a/src/client/views/ContextMenu.tsx +++ b/src/client/views/ContextMenu.tsx @@ -15,6 +15,7 @@ export class ContextMenu extends React.Component { @observable private _pageY: number = 0; @observable private _display: boolean = false; @observable private _searchString: string = ""; + @observable private _showSearch: boolean = false; // afaik displaymenu can be called before all the items are added to the menu, so can't determine in displayMenu what the height of the menu will be @observable private _yRelativeToTop: boolean = true; @observable selectedIndex = -1; @@ -137,11 +138,13 @@ export class ContextMenu extends React.Component { return y; } + @action - displayMenu = (x: number, y: number, initSearch = "") => { + displayMenu = (x: number, y: number, initSearch = "", showSearch = false) => { //maxX and maxY will change if the UI/font size changes, but will work for any amount //of items added to the menu + this._showSearch = showSearch; this._pageX = x; this._pageY = y; this._searchString = initSearch; @@ -215,11 +218,15 @@ export class ContextMenu extends React.Component { @computed get menuItems() { if (!this._searchString) { - return this._items.map(item => ); + return this._items.map(item => ); } return this.filteredViews; } + @computed get itemsNeedSearch() { + return this._showSearch ? 1 : this._items.reduce((p, mi) => p + ((mi as any).noexpand ? 1 : (mi as any).subitems?.length || 1), 0) > 15; + } + render() { if (!this._display) { return null; @@ -229,12 +236,13 @@ export class ContextMenu extends React.Component { const contents = ( <> - - - - - - + {!this.itemsNeedSearch ? (null) : + + + + + + } {this.menuItems} ); @@ -244,8 +252,7 @@ export class ContextMenu extends React.Component {
    {contents}
    - ) - } + )} ); } diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx index e63631161..6fe2abd21 100644 --- a/src/client/views/ContextMenuItem.tsx +++ b/src/client/views/ContextMenuItem.tsx @@ -4,7 +4,6 @@ import { observer } from "mobx-react"; import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { UndoManager } from "../util/UndoManager"; -import { NumberLiteralType } from "typescript"; export interface OriginalMenuProps { description: string; @@ -33,8 +32,8 @@ export class ContextMenuItem extends React.Component this._items.push(i)); + if ((this.props as SubmenuProps).subitems) { + (this.props as SubmenuProps).subitems?.forEach(i => this._items.push(i)); } } @@ -107,7 +106,7 @@ export class ContextMenuItem extends React.Component {this._items.map(prop => )}
    ; - if (!("noexpand" in this.props)) { + if (!(this.props as SubmenuProps).noexpand) { return
    {this._items.map(prop => )}
    ; diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 2c3a6c0d7..43f9627e2 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -483,10 +483,10 @@ export class TreeView extends React.Component { } @computed get headerElements() { - return this.props.treeViewHideHeaderFields() || Doc.IsSystem(this.doc) ? (null) + return this.props.treeViewHideHeaderFields() || (Doc.IsSystem(this.doc) && !this.doc.isFolder) ? (null) : <> { this.showContextMenu(e); e.stopPropagation(); }} /> - {this.doc.treeViewExpandedViewLock ? (null) : + {this.doc.isFolder || this.doc.treeViewExpandedViewLock ? (null) : {this.treeViewExpandedView} } @@ -494,11 +494,14 @@ export class TreeView extends React.Component { } showContextMenu = (e: React.MouseEvent) => simulateMouseClick(this._docRef?.ContentDiv, e.clientX, e.clientY + 30, e.screenX, e.screenY + 30); - contextMenuItems = () => Doc.IsSystem(this.doc) ? [] : this.doc.isFolder ? - [{ script: ScriptField.MakeFunction(`scriptContext.makeFolder()`, { scriptContext: "any" })!, label: "New Folder" }] : - this.props.treeView.fileSysMode && this.doc === Doc.GetProto(this.doc) ? - [{ script: ScriptField.MakeFunction(`openOnRight(getAlias(self))`)!, label: "Open Alias" }] : - [{ script: ScriptField.MakeFunction(`DocFocusOrOpen(self)`)!, label: "Focus or Open" }] + contextMenuItems = () => { + const makeFolder = { script: ScriptField.MakeFunction(`scriptContext.makeFolder()`, { scriptContext: "any" })!, label: "New Folder" }; + return this.doc.isFolder ? [makeFolder] : + Doc.IsSystem(this.doc) ? [] : + this.props.treeView.fileSysMode && this.doc === Doc.GetProto(this.doc) ? + [{ script: ScriptField.MakeFunction(`openOnRight(getAlias(self))`)!, label: "Open Alias" }, makeFolder] : + [{ script: ScriptField.MakeFunction(`DocFocusOrOpen(self)`)!, label: "Focus or Open" }]; + } onChildClick = () => this.props.onChildClick?.() ?? (this._editTitleScript?.() || ScriptCast(this.doc.treeChildClick)); onChildDoubleClick = () => (!this.props.treeView.outlineMode && this._openScript?.()) || ScriptCast(this.doc.treeChildDoubleClick); diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index d14b68fa7..a4f129b8c 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -101,7 +101,7 @@ export class MarqueeView extends React.Component item.label && cm.addItem({ description: item.label, event: () => item.script.script.run({ this: this.layoutDoc, scriptContext: this.props.scriptContext, self: this.rootDoc }), icon: "sticky-note" })); - const templateDoc = Cast(this.props.Document[StrCast(this.props.Document.layoutKey)], Doc, null); - const appearance = cm.findByDescription("UI Controls..."); - const appearanceItems: ContextMenuProps[] = appearance && "subitems" in appearance ? appearance.subitems : []; - !Doc.UserDoc().noviceMode && templateDoc && appearanceItems.push({ description: "Open Template ", event: () => this.props.addDocTab(templateDoc, "add:right"), icon: "eye" }); - DocListCast(this.Document.links).length && appearanceItems.splice(0, 0, { description: `${this.layoutDoc.hideLinkButton ? "Show" : "Hide"} Link Button`, event: action(() => this.layoutDoc.hideLinkButton = !this.layoutDoc.hideLinkButton), icon: "eye" }); - !appearance && cm.addItem({ description: "UI Controls...", subitems: appearanceItems, icon: "compass" }); - - if (!Doc.IsSystem(this.rootDoc) && this.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Tree) { - !Doc.UserDoc().noviceMode && appearanceItems.splice(0, 0, { description: `${!this.layoutDoc._showAudio ? "Show" : "Hide"} Audio Button`, event: action(() => this.layoutDoc._showAudio = !this.layoutDoc._showAudio), icon: "microphone" }); - const existingOnClick = cm.findByDescription("OnClick..."); - const onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : []; - - const zorders = cm.findByDescription("ZOrder..."); - const zorderItems: ContextMenuProps[] = zorders && "subitems" in zorders ? zorders.subitems : []; - zorderItems.push({ description: "Bring to Front", event: () => SelectionManager.Views().forEach(dv => dv.props.bringToFront(dv.rootDoc, false)), icon: "expand-arrows-alt" }); - zorderItems.push({ description: "Send to Back", event: () => SelectionManager.Views().forEach(dv => dv.props.bringToFront(dv.rootDoc, true)), icon: "expand-arrows-alt" }); - zorderItems.push({ description: this.rootDoc._raiseWhenDragged !== false ? "Keep ZIndex when dragged" : "Allow ZIndex to change when dragged", event: undoBatch(action(() => this.rootDoc._raiseWhenDragged = this.rootDoc._raiseWhenDragged === undefined ? false : undefined)), icon: "expand-arrows-alt" }); - !zorders && cm.addItem({ description: "ZOrder...", subitems: zorderItems, icon: "compass" }); - - onClicks.push({ description: "Enter Portal", event: this.makeIntoPortal, icon: "window-restore" }); - onClicks.push({ description: "Toggle Detail", event: () => this.Document.onClick = ScriptField.MakeScript(`toggleDetail(self, "${this.Document.layoutKey}")`), icon: "concierge-bell" }); - onClicks.push({ description: (this.Document.followLinkZoom ? "Don't" : "") + " zoom following link", event: () => this.Document.followLinkZoom = !this.Document.followLinkZoom, icon: this.Document.ignoreClick ? "unlock" : "lock" }); - - if (!this.Document.annotationOn) { - const options = cm.findByDescription("Options..."); - const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : []; - !options && cm.addItem({ description: "Options...", subitems: optionItems, icon: "compass" }); - - onClicks.push({ description: this.Document.ignoreClick ? "Select" : "Do Nothing", event: () => this.Document.ignoreClick = !this.Document.ignoreClick, icon: this.Document.ignoreClick ? "unlock" : "lock" }); - onClicks.push({ description: this.Document.isLinkButton ? "Remove Follow Behavior" : "Follow Link in Place", event: () => this.toggleFollowLink("inPlace", true, false), icon: "link" }); - !this.Document.isLinkButton && onClicks.push({ description: "Follow Link on Right", event: () => this.toggleFollowLink("add:right", false, false), icon: "link" }); - onClicks.push({ description: this.Document.isLinkButton || this.onClickHandler ? "Remove Click Behavior" : "Follow Link", event: () => this.toggleFollowLink(undefined, false, false), icon: "link" }); - onClicks.push({ description: (this.Document.isPushpin ? "Remove" : "Make") + " Pushpin", event: () => this.toggleFollowLink(undefined, false, true), icon: "map-pin" }); - onClicks.push({ description: "Edit onClick Script", event: () => UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this.props.Document, undefined, "onClick"), "edit onClick"), icon: "terminal" }); - !existingOnClick && cm.addItem({ description: "OnClick...", addDivider: true, noexpand: true, subitems: onClicks, icon: "mouse-pointer" }); - } else if (DocListCast(this.Document.links).length) { - onClicks.push({ description: "Select on Click", event: () => this.selectOnClick(), icon: "link" }); - onClicks.push({ description: "Follow Link on Click", event: () => this.followLinkOnClick(undefined, false), icon: "link" }); - onClicks.push({ description: "Toggle Link Target on Click", event: () => this.toggleTargetOnClick(), icon: "map-pin" }); - !existingOnClick && cm.addItem({ description: "OnClick...", addDivider: true, subitems: onClicks, icon: "mouse-pointer" }); + if (!this.props.Document.isFolder) { + const templateDoc = Cast(this.props.Document[StrCast(this.props.Document.layoutKey)], Doc, null); + const appearance = cm.findByDescription("UI Controls..."); + const appearanceItems: ContextMenuProps[] = appearance && "subitems" in appearance ? appearance.subitems : []; + !Doc.UserDoc().noviceMode && templateDoc && appearanceItems.push({ description: "Open Template ", event: () => this.props.addDocTab(templateDoc, "add:right"), icon: "eye" }); + DocListCast(this.Document.links).length && appearanceItems.splice(0, 0, { description: `${this.layoutDoc.hideLinkButton ? "Show" : "Hide"} Link Button`, event: action(() => this.layoutDoc.hideLinkButton = !this.layoutDoc.hideLinkButton), icon: "eye" }); + !appearance && cm.addItem({ description: "UI Controls...", subitems: appearanceItems, icon: "compass" }); + + if (!Doc.IsSystem(this.rootDoc) && this.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Tree) { + !Doc.UserDoc().noviceMode && appearanceItems.splice(0, 0, { description: `${!this.layoutDoc._showAudio ? "Show" : "Hide"} Audio Button`, event: action(() => this.layoutDoc._showAudio = !this.layoutDoc._showAudio), icon: "microphone" }); + const existingOnClick = cm.findByDescription("OnClick..."); + const onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : []; + + const zorders = cm.findByDescription("ZOrder..."); + const zorderItems: ContextMenuProps[] = zorders && "subitems" in zorders ? zorders.subitems : []; + zorderItems.push({ description: "Bring to Front", event: () => SelectionManager.Views().forEach(dv => dv.props.bringToFront(dv.rootDoc, false)), icon: "expand-arrows-alt" }); + zorderItems.push({ description: "Send to Back", event: () => SelectionManager.Views().forEach(dv => dv.props.bringToFront(dv.rootDoc, true)), icon: "expand-arrows-alt" }); + zorderItems.push({ description: this.rootDoc._raiseWhenDragged !== false ? "Keep ZIndex when dragged" : "Allow ZIndex to change when dragged", event: undoBatch(action(() => this.rootDoc._raiseWhenDragged = this.rootDoc._raiseWhenDragged === undefined ? false : undefined)), icon: "expand-arrows-alt" }); + !zorders && cm.addItem({ description: "ZOrder...", subitems: zorderItems, icon: "compass" }); + + onClicks.push({ description: "Enter Portal", event: this.makeIntoPortal, icon: "window-restore" }); + onClicks.push({ description: "Toggle Detail", event: () => this.Document.onClick = ScriptField.MakeScript(`toggleDetail(self, "${this.Document.layoutKey}")`), icon: "concierge-bell" }); + onClicks.push({ description: (this.Document.followLinkZoom ? "Don't" : "") + " zoom following link", event: () => this.Document.followLinkZoom = !this.Document.followLinkZoom, icon: this.Document.ignoreClick ? "unlock" : "lock" }); + + if (!this.Document.annotationOn) { + const options = cm.findByDescription("Options..."); + const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : []; + !options && cm.addItem({ description: "Options...", subitems: optionItems, icon: "compass" }); + + onClicks.push({ description: this.Document.ignoreClick ? "Select" : "Do Nothing", event: () => this.Document.ignoreClick = !this.Document.ignoreClick, icon: this.Document.ignoreClick ? "unlock" : "lock" }); + onClicks.push({ description: this.Document.isLinkButton ? "Remove Follow Behavior" : "Follow Link in Place", event: () => this.toggleFollowLink("inPlace", true, false), icon: "link" }); + !this.Document.isLinkButton && onClicks.push({ description: "Follow Link on Right", event: () => this.toggleFollowLink("add:right", false, false), icon: "link" }); + onClicks.push({ description: this.Document.isLinkButton || this.onClickHandler ? "Remove Click Behavior" : "Follow Link", event: () => this.toggleFollowLink(undefined, false, false), icon: "link" }); + onClicks.push({ description: (this.Document.isPushpin ? "Remove" : "Make") + " Pushpin", event: () => this.toggleFollowLink(undefined, false, true), icon: "map-pin" }); + onClicks.push({ description: "Edit onClick Script", event: () => UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this.props.Document, undefined, "onClick"), "edit onClick"), icon: "terminal" }); + !existingOnClick && cm.addItem({ description: "OnClick...", addDivider: true, noexpand: true, subitems: onClicks, icon: "mouse-pointer" }); + } else if (DocListCast(this.Document.links).length) { + onClicks.push({ description: "Select on Click", event: () => this.selectOnClick(), icon: "link" }); + onClicks.push({ description: "Follow Link on Click", event: () => this.followLinkOnClick(undefined, false), icon: "link" }); + onClicks.push({ description: "Toggle Link Target on Click", event: () => this.toggleTargetOnClick(), icon: "map-pin" }); + !existingOnClick && cm.addItem({ description: "OnClick...", addDivider: true, subitems: onClicks, icon: "mouse-pointer" }); + } } - } - const funcs: ContextMenuProps[] = []; - if (!Doc.UserDoc().noviceMode && this.layoutDoc.onDragStart) { - funcs.push({ description: "Drag an Alias", icon: "edit", event: () => this.Document.dragFactory && (this.layoutDoc.onDragStart = ScriptField.MakeFunction('getAlias(this.dragFactory)')) }); - funcs.push({ description: "Drag a Copy", icon: "edit", event: () => this.Document.dragFactory && (this.layoutDoc.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)')) }); - funcs.push({ description: "Drag Document", icon: "edit", event: () => this.layoutDoc.onDragStart = undefined }); - cm.addItem({ description: "OnDrag...", noexpand: true, subitems: funcs, icon: "asterisk" }); - } + const funcs: ContextMenuProps[] = []; + if (!Doc.UserDoc().noviceMode && this.layoutDoc.onDragStart) { + funcs.push({ description: "Drag an Alias", icon: "edit", event: () => this.Document.dragFactory && (this.layoutDoc.onDragStart = ScriptField.MakeFunction('getAlias(this.dragFactory)')) }); + funcs.push({ description: "Drag a Copy", icon: "edit", event: () => this.Document.dragFactory && (this.layoutDoc.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)')) }); + funcs.push({ description: "Drag Document", icon: "edit", event: () => this.layoutDoc.onDragStart = undefined }); + cm.addItem({ description: "OnDrag...", noexpand: true, subitems: funcs, icon: "asterisk" }); + } - const more = cm.findByDescription("More..."); - const moreItems = more && "subitems" in more ? more.subitems : []; - if (!Doc.IsSystem(this.rootDoc)) { - (this.rootDoc._viewType !== CollectionViewType.Docking || !Doc.UserDoc().noviceMode) && moreItems.push({ description: "Share", event: () => SharingManager.Instance.open(this.props.DocumentView()), icon: "users" }); - if (!Doc.UserDoc().noviceMode) { - moreItems.push({ description: "Make View of Metadata Field", event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc), icon: "concierge-bell" }); - moreItems.push({ description: `${this.Document._chromeHidden ? "Show" : "Hide"} Chrome`, event: () => this.Document._chromeHidden = !this.Document._chromeHidden, icon: "project-diagram" }); - - if (Cast(Doc.GetProto(this.props.Document).data, listSpec(Doc))) { - moreItems.push({ description: "Export to Google Photos Album", event: () => GooglePhotos.Export.CollectionToAlbum({ collection: this.props.Document }).then(console.log), icon: "caret-square-right" }); - moreItems.push({ description: "Tag Child Images via Google Photos", event: () => GooglePhotos.Query.TagChildImages(this.props.Document), icon: "caret-square-right" }); - moreItems.push({ description: "Write Back Link to Album", event: () => GooglePhotos.Transactions.AddTextEnrichment(this.props.Document), icon: "caret-square-right" }); + const more = cm.findByDescription("More..."); + const moreItems = more && "subitems" in more ? more.subitems : []; + if (!Doc.IsSystem(this.rootDoc)) { + (this.rootDoc._viewType !== CollectionViewType.Docking || !Doc.UserDoc().noviceMode) && moreItems.push({ description: "Share", event: () => SharingManager.Instance.open(this.props.DocumentView()), icon: "users" }); + if (!Doc.UserDoc().noviceMode) { + moreItems.push({ description: "Make View of Metadata Field", event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc), icon: "concierge-bell" }); + moreItems.push({ description: `${this.Document._chromeHidden ? "Show" : "Hide"} Chrome`, event: () => this.Document._chromeHidden = !this.Document._chromeHidden, icon: "project-diagram" }); + + if (Cast(Doc.GetProto(this.props.Document).data, listSpec(Doc))) { + moreItems.push({ description: "Export to Google Photos Album", event: () => GooglePhotos.Export.CollectionToAlbum({ collection: this.props.Document }).then(console.log), icon: "caret-square-right" }); + moreItems.push({ description: "Tag Child Images via Google Photos", event: () => GooglePhotos.Query.TagChildImages(this.props.Document), icon: "caret-square-right" }); + 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" }); } - moreItems.push({ description: "Copy ID", event: () => Utils.CopyText(Utils.prepend("/doc/" + this.props.Document[Id])), icon: "fingerprint" }); } - } - - if (this.props.removeDocument && !Doc.IsSystem(this.rootDoc) && CurrentUserUtils.ActiveDashboard !== this.props.Document) { // need option to gray out menu items ... preferably with a '?' that explains why they're grayed out (eg., no permissions) - 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...")!); + if (this.props.removeDocument && !Doc.IsSystem(this.rootDoc) && CurrentUserUtils.ActiveDashboard !== this.props.Document) { // need option to gray out menu items ... preferably with a '?' that explains why they're grayed out (eg., no permissions) + moreItems.push({ description: "Close", event: this.deleteClicked, icon: "times" }); + } - const help = cm.findByDescription("Help..."); - const helpItems: ContextMenuProps[] = help && "subitems" in help ? help.subitems : []; - !Doc.UserDoc().novice && helpItems.push({ description: "Show Fields ", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { _width: 300, _height: 300 }), "add:right"), icon: "layer-group" }); - helpItems.push({ description: "Text Shortcuts Ctrl+/", event: () => this.props.addDocTab(Docs.Create.PdfDocument(Utils.prepend("/assets/cheat-sheet.pdf"), { _width: 300, _height: 300 }), "add:right"), icon: "keyboard" }); - !Doc.UserDoc().novice && helpItems.push({ description: "Print Document in Console", event: () => console.log(this.props.Document), icon: "hand-point-right" }); - cm.addItem({ description: "Help...", noexpand: true, subitems: helpItems, icon: "question" }); + !more && cm.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" }); + cm.moveAfter(cm.findByDescription("More...")!, cm.findByDescription("OnClick...")!); + const help = cm.findByDescription("Help..."); + const helpItems: ContextMenuProps[] = help && "subitems" in help ? help.subitems : []; + !Doc.UserDoc().novice && helpItems.push({ description: "Show Fields ", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { _width: 300, _height: 300 }), "add:right"), icon: "layer-group" }); + helpItems.push({ description: "Text Shortcuts Ctrl+/", event: () => this.props.addDocTab(Docs.Create.PdfDocument(Utils.prepend("/assets/cheat-sheet.pdf"), { _width: 300, _height: 300 }), "add:right"), icon: "keyboard" }); + !Doc.UserDoc().novice && helpItems.push({ description: "Print Document in Console", event: () => console.log(this.props.Document), icon: "hand-point-right" }); + cm.addItem({ description: "Help...", noexpand: true, subitems: helpItems, icon: "question" }); + } if (!this.topMost) e?.stopPropagation(); // DocumentViews should stop propagation of this event cm.displayMenu((e?.pageX || pageX || 0) - 15, (e?.pageY || pageY || 0) - 15); !this.props.isSelected(true) && setTimeout(() => SelectionManager.SelectView(this.props.DocumentView(), false), 300); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear. -- cgit v1.2.3-70-g09d2 From ffcb1cdf35e1f666034a1471cdd757c64b03ab52 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 8 Apr 2021 13:51:18 -0400 Subject: from last --- src/client/views/collections/TreeView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 43f9627e2..a4d734a70 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -545,7 +545,7 @@ export class TreeView extends React.Component { } } } - titleWidth = () => Math.max(20, Math.min(this.props.treeView.truncateTitleWidth(), this.props.panelWidth() - treeBulletWidth())); + titleWidth = () => Math.max(20, Math.min(this.props.treeView.truncateTitleWidth(), this.props.panelWidth() - 2 * treeBulletWidth())); /** * Renders the EditableView title element for placement into the tree. -- cgit v1.2.3-70-g09d2 From 5b1de482065a9aaec5ad026c9fecb2c8ae513fd3 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 8 Apr 2021 14:30:37 -0400 Subject: added idToDoc --- src/client/views/nodes/KeyValueBox.tsx | 2 +- src/fields/Doc.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx index 111509fdb..bf9ca1de0 100644 --- a/src/client/views/nodes/KeyValueBox.tsx +++ b/src/client/views/nodes/KeyValueBox.tsx @@ -58,7 +58,7 @@ export class KeyValueBox extends React.Component { value = eq ? value.substr(1) : value; const dubEq = value.startsWith(":=") ? "computed" : value.startsWith(";=") ? "script" : false; value = dubEq ? value.substr(2) : value; - const options: ScriptOptions = { addReturn: true, params: { this: "Doc", _last_: "any" }, editable: false }; + const options: ScriptOptions = { addReturn: true, params: { this: "Doc", _last_: "any" }, globals: true, editable: false }; if (dubEq) options.typecheck = false; const script = CompileScript(value, options); return !script.compiled ? undefined : { script, type: dubEq, onDelegate: eq }; diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 5b3e21e34..2203fc876 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -201,7 +201,7 @@ export class Doc extends RefField { public [FieldsSym] = () => this[Self].___fields; // Object.keys(this).reduce((fields, key) => { fields[key] = this[key]; return fields; }, {} as any); public [WidthSym] = () => NumCast(this[SelfProxy]._width); public [HeightSym] = () => NumCast(this[SelfProxy]._height); - public [ToScriptString] = () => `DOC-"${this[Self][Id]}"-`; + public [ToScriptString] = () => `idToDoc("${this[Self][Id]}")`; public [ToString] = () => `Doc(${GetEffectiveAcl(this[SelfProxy]) === AclPrivate ? "-inaccessible-" : this[SelfProxy].title})`; public get [LayoutSym]() { return this[SelfProxy].__LAYOUT__; } public get [DataSym]() { @@ -1325,6 +1325,7 @@ export namespace Doc { } +Scripting.addGlobal(function idToDoc(id: string) { return DocServer.GetCachedRefField(id); }); Scripting.addGlobal(function renameAlias(doc: any, n: any) { return StrCast(Doc.GetProto(doc).title).replace(/\([0-9]*\)/, "") + `(${n})`; }); Scripting.addGlobal(function getProto(doc: any) { return Doc.GetProto(doc); }); Scripting.addGlobal(function getDocTemplate(doc?: any) { return Doc.getDocTemplate(doc); }); -- cgit v1.2.3-70-g09d2 From 742cd3d9e76f188e0a78b2c4288e0d7e6af14fe8 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 8 Apr 2021 15:42:09 -0400 Subject: fixed pushpins to be created only when removed from a collection. fixed webbox links which weren't showing up in link menu. --- src/client/documents/Documents.ts | 4 ++-- src/client/views/DocComponent.tsx | 4 ++-- src/client/views/collections/CollectionSubView.tsx | 2 +- src/client/views/nodes/WebBox.tsx | 9 +++++++-- 4 files changed, 12 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 90db8644d..38a9bd0e1 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -1317,7 +1317,7 @@ export namespace DocUtils { } } - export function LeavePushpin(doc: Doc) { + export function LeavePushpin(doc: Doc, annotationField: string) { if (doc.isPushpin) return undefined; const context = Cast(doc.context, Doc, null) ?? Cast(doc.annotationOn, Doc, null); const hasContextAnchor = DocListCast(doc.links). @@ -1330,7 +1330,7 @@ export namespace DocUtils { icon: "map-pin", x: Cast(doc.x, "number", null), y: Cast(doc.y, "number", null), backgroundColor: "#ACCEF7", _width: 15, _height: 15, _xPadding: 0, _isLinkButton: true, _timecodeToShow: Cast(doc._timecodeToShow, "number", null) }); - Doc.AddDocToList(context, Doc.LayoutFieldKey(context) + "-annotations", pushpin); + Doc.AddDocToList(context, annotationField, pushpin); const pushpinLink = DocUtils.MakeLink({ doc: pushpin }, { doc: doc }, "pushpin", ""); doc._timecodeToShow = undefined; return pushpin; diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index 5ff96ac8d..c017b7015 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -151,7 +151,7 @@ export function ViewBoxAnnotatableComponent

    { - leavePushpin && DocUtils.LeavePushpin(doc); + leavePushpin && DocUtils.LeavePushpin(doc, annotationKey ?? this.annotationKey); Doc.RemoveDocFromList(targetDataDoc, annotationKey ?? this.annotationKey, doc); doc.context = undefined; recent && Doc.AddDocToList(recent, "data", doc, undefined, true, true); @@ -216,7 +216,7 @@ export function ViewBoxAnnotatableComponent

    [AclAdmin, AclEdit].includes(GetEffectiveAcl(doc))).map(doc => { // only make a pushpin if we have acl's to edit the document this.props.layerProvider?.(doc, true); - DocUtils.LeavePushpin(doc); + //DocUtils.LeavePushpin(doc); doc._stayInCollection = undefined; doc.context = this.props.Document; if (annotationKey ?? this._annotationKey) Doc.GetProto(doc).annotationOn = this.props.Document; diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index a5d679df0..071422131 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -74,7 +74,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: const { Document, DataDoc } = this.props; const validPairs = this.childDocs.map(doc => Doc.GetLayoutDataDocPair(Document, !this.props.isAnnotationOverlay ? DataDoc : undefined, doc)). filter(pair => { // filter out any documents that have a proto that we don't have permissions to (which we determine by not having any keys - return pair.layout && !pair.layout.hidden && (!pair.layout.proto || (pair.layout.proto instanceof Doc && GetEffectiveAcl(pair.layout.proto) !== AclPrivate));// Object.keys(pair.layout.proto).length)); + return pair.layout && /*!pair.layout.hidden &&*/ (!pair.layout.proto || (pair.layout.proto instanceof Doc && GetEffectiveAcl(pair.layout.proto) !== AclPrivate));// Object.keys(pair.layout.proto).length)); }); return validPairs.map(({ data, layout }) => ({ data: data as Doc, layout: layout! })); // this mapping is a bit of a hack to coerce types } diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index ab178c60b..cea3833bb 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -12,7 +12,7 @@ import { makeInterface, listSpec } from "../../../fields/Schema"; import { Cast, NumCast, StrCast } from "../../../fields/Types"; import { WebField } from "../../../fields/URLField"; import { TraceMobx } from "../../../fields/util"; -import { emptyFunction, getWordAtPoint, OmitKeys, returnOne, smoothScroll, Utils, setupMoveUpEvents } from "../../../Utils"; +import { emptyFunction, getWordAtPoint, OmitKeys, returnOne, smoothScroll, Utils, setupMoveUpEvents, returnFalse } from "../../../Utils"; import { Docs } from "../../documents/Documents"; import { DocumentType } from '../../documents/DocumentTypes'; import { CurrentUserUtils } from "../../util/CurrentUserUtils"; @@ -32,6 +32,7 @@ import { FieldView, FieldViewProps } from './FieldView'; import { LinkDocPreview } from "./LinkDocPreview"; import "./WebBox.scss"; import React = require("react"); +import { ComputedField } from "../../../fields/ScriptField"; const _global = (window /* browser */ || global /* node */) as any; const htmlToText = require("html-to-text"); @@ -80,6 +81,7 @@ export class WebBox extends ViewBoxAnnotatableComponent { this._url = this.webField?.toString() || ""; this._annotationKey = "annotations-" + this.urlHash(this._url); + this.dataDoc[this.fieldKey + "-annotations"] = ComputedField.MakeFunction(`copyField(this["${this.annotationKey}"])`); }); this._disposers.selection = reaction(() => this.props.isSelected(), @@ -290,6 +292,7 @@ export class WebBox extends ViewBoxAnnotatableComponent Date: Fri, 9 Apr 2021 11:18:59 -0400 Subject: fix for removing documents from pdfs/web boxes. fixes for making objects draggable again in PDFs. fixes for lightboxview to allow stepping into collecitons. fix for stacking view to skip hidden documents --- src/client/views/LightboxView.tsx | 6 +----- src/client/views/collections/CollectionStackedTimeline.tsx | 3 ++- src/client/views/collections/CollectionStackingView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 2 +- src/client/views/nodes/PDFBox.tsx | 2 ++ src/client/views/nodes/VideoBox.tsx | 2 +- src/client/views/nodes/WebBox.tsx | 5 ----- src/client/views/pdf/PDFViewer.tsx | 3 ++- 8 files changed, 10 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index 098c40df4..9444446b1 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -190,12 +190,8 @@ export class LightboxView extends React.Component { const coll = LightboxView._docTarget; const doc = LightboxView.LightboxDoc; if (coll && doc) { - console.log('test'); - console.log('target: ' + coll.title); - console.log('doc: ' + doc.title); const fieldKey = Doc.LayoutFieldKey(coll); - LightboxView.SetLightboxDoc(doc); - // LightboxView.SetLightboxDoc(coll, undefined, [...DocListCast(coll[fieldKey]), ...DocListCast(coll[fieldKey + "-annotations"])]); + LightboxView.SetLightboxDoc(coll, undefined, [...DocListCast(coll[fieldKey]), ...DocListCast(coll[fieldKey + "-annotations"])]); TabDocView.PinDoc(coll, { hidePresBox: true }); } } diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx index 4f9f297a2..5b5d05681 100644 --- a/src/client/views/collections/CollectionStackedTimeline.tsx +++ b/src/client/views/collections/CollectionStackedTimeline.tsx @@ -235,6 +235,7 @@ export class CollectionStackedTimeline extends CollectionSubView "50%"; + documentHeight = () => "100%"; timelineContentHeight = () => this.props.PanelHeight() / 2; dictationScreenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(0, -this.timelineContentHeight()); @computed get renderDictation() { @@ -242,7 +243,7 @@ export class CollectionStackedTimeline extends CollectionSubView "100%"} + PanelHeight={this.documentHeight} isAnnotationOverlay={true} isDocumentActive={returnFalse} select={emptyFunction} diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 8d8c69fd5..1aed40bc3 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -55,7 +55,7 @@ export class CollectionStackingView extends CollectionSubView pair.layout instanceof Doc).map(pair => pair.layout); } + @computed get filteredChildren() { return this.childLayoutPairs.filter(pair => (pair.layout instanceof Doc) && !pair.layout.hidden).map(pair => pair.layout); } @computed get headerMargin() { return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.HeaderMargin); } @computed get xMargin() { return NumCast(this.layoutDoc._xMargin, 2 * Math.min(this.gridGap, .05 * this.props.PanelWidth())); } @computed get yMargin() { return this.props.yMargin || NumCast(this.layoutDoc._yMargin, 5); } // 2 * this.gridGap)); } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 859aff2e8..22543cc8a 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -1106,7 +1106,7 @@ export class DocumentView extends React.Component { position: this.props.Document.isInkMask ? "absolute" : undefined, transform: `translate(${this.centeringX}px, ${this.centeringY}px)`, width: xshift() ?? `${100 * (this.props.PanelWidth() - this.Xshift * 2) / this.props.PanelWidth()}%`, - height: this.props.Document.type === DocumentType.VID ? "100%" : yshift() ?? (this.fitWidth ? `${this.panelHeight}px` : + height: yshift() ?? (this.fitWidth ? `${this.panelHeight}px` : `${100 * this.effectiveNativeHeight / this.effectiveNativeWidth * this.props.PanelWidth() / this.props.PanelHeight()}%`), }}> { this._url = this.webField?.toString() || ""; this._annotationKey = "annotations-" + this.urlHash(this._url); - this.dataDoc[this.fieldKey + "-annotations"] = ComputedField.MakeFunction(`copyField(this["${this.annotationKey}"])`); }); this._disposers.selection = reaction(() => this.props.isSelected(), @@ -292,7 +290,6 @@ export class WebBox extends ViewBoxAnnotatableComponent { }}> Date: Fri, 9 Apr 2021 11:53:48 -0400 Subject: pres box audio changes --- src/client/views/nodes/PresBox.tsx | 25 +++++++++++----------- .../views/nodes/formattedText/FormattedTextBox.tsx | 4 +++- 2 files changed, 16 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 8c5f77550..446db3549 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -29,6 +29,7 @@ import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView import { FieldView, FieldViewProps } from './FieldView'; import "./PresBox.scss"; import Color = require("color"); +import { LightboxView } from "../LightboxView"; export enum PresMovement { Zoom = "zoom", @@ -433,10 +434,12 @@ export class PresBox extends ViewBoxBaseComponent }; // If openDocument is selected then it should open the document for the user if (activeItem.openDocument) { - openInTab(targetDoc); + LightboxView.SetLightboxDoc(targetDoc); } else if (curDoc.presMovement === PresMovement.Pan && targetDoc) { + LightboxView.SetLightboxDoc(undefined); await DocumentManager.Instance.jumpToDocument(targetDoc, false, openInTab, srcContext, undefined, undefined, undefined, includesDoc || tab ? undefined : resetSelection); // documents open in new tab instead of on right } else if ((curDoc.presMovement === PresMovement.Zoom || curDoc.presMovement === PresMovement.Jump) && targetDoc) { + LightboxView.SetLightboxDoc(undefined); //awaiting jump so that new scale can be found, since jumping is async await DocumentManager.Instance.jumpToDocument(targetDoc, true, openInTab, srcContext, undefined, undefined, undefined, includesDoc || tab ? undefined : resetSelection); // documents open in new tab instead of on right } @@ -574,6 +577,9 @@ export class PresBox extends ViewBoxBaseComponent if (this._presTimer) clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; this.layoutDoc.presLoop = false; + this.childDocs.forEach((doc) => { + this.stopTempMedia(Cast(doc.presentationTargetDoc, Doc, null)); + }); } } @@ -633,10 +639,12 @@ export class PresBox extends ViewBoxBaseComponent updateMinimize = () => { const docView = DocumentManager.Instance.getDocumentView(this.layoutDoc); if (CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) { + console.log("case 1"); this.layoutDoc.presStatus = PresStatus.Edit; Doc.RemoveDocFromList((Doc.UserDoc().myOverlayDocs as Doc), undefined, this.rootDoc); CollectionDockingView.AddSplit(this.rootDoc, "right"); } else if (this.layoutDoc.context && docView) { + console.log("case 2"); this.layoutDoc.presStatus = PresStatus.Edit; clearTimeout(this._presTimer); const pt = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); @@ -647,15 +655,8 @@ export class PresBox extends ViewBoxBaseComponent docView.props.removeDocument?.(this.layoutDoc); Doc.AddDocToList((Doc.UserDoc().myOverlayDocs as Doc), undefined, this.rootDoc); } else { - this.layoutDoc.presStatus = PresStatus.Edit; - clearTimeout(this._presTimer); - const pt = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); - this.rootDoc.x = pt[0] + (this.props.PanelWidth() - 250); - this.rootDoc.y = pt[1] + 10; - this.rootDoc._height = 35; - this.rootDoc._width = 250; - this.props.addDocTab?.(this.rootDoc, "close"); - Doc.AddDocToList((Doc.UserDoc().myOverlayDocs as Doc), undefined, this.rootDoc); + console.log("case 3"); + // TODO glr: fix this case } } @@ -1193,7 +1194,7 @@ export class PresBox extends ViewBoxBaseComponent const effect = targetDoc.presEffect ? targetDoc.presEffect : 'None'; activeItem.presMovement = activeItem.presMovement ? activeItem.presMovement : 'Zoom'; return ( -

    e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onClick={action(e => { e.stopPropagation(); this.openMovementDropdown = false; this.openEffectDropdown = false; })}> +
    e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onClick={action(e => { e.stopPropagation(); this.openMovementDropdown = false; this.openEffectDropdown = false; })}>
    Movement {isPresCollection || (isPresCollection && isPinWithView) ? @@ -1248,7 +1249,7 @@ export class PresBox extends ViewBoxBaseComponent
    {isPresCollection ? (null) :
    {"Hide before presented"}
    }>
    this.updateHideBefore(activeItem)}>Hide before
    } {isPresCollection ? (null) :
    {"Hide after presented"}
    }>
    this.updateHideAfter(activeItem)}>Hide after
    } -
    {"Open document in a new tab"}
    }>
    this.updateOpenDoc(activeItem)}>Open
    +
    {"Open in lightbox view"}
    }>
    this.updateOpenDoc(activeItem)}>Lightbox
    {(type === DocumentType.AUDIO || type === DocumentType.VID) ? (null) : <>
    diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 9482b632a..1e901c0aa 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -297,7 +297,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp this._editorView.updateState(EditorState.fromJSON(this.config, json)); } } - if (window.getSelection()?.isCollapsed) AnchorMenu.Instance.fadeOut(true); + if (window.getSelection()?.isCollapsed && this.props.isSelected) { + AnchorMenu.Instance.fadeOut(true); + } } } -- cgit v1.2.3-70-g09d2 From 813dcbeaf3359dc184067f597e731b44a0446e1b Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 9 Apr 2021 12:22:37 -0400 Subject: fixed not following links on video in lightbox --- src/client/views/collections/CollectionStackedTimeline.tsx | 3 ++- .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 2 +- src/client/views/nodes/FieldView.tsx | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx index 5b5d05681..782726456 100644 --- a/src/client/views/collections/CollectionStackedTimeline.tsx +++ b/src/client/views/collections/CollectionStackedTimeline.tsx @@ -349,7 +349,8 @@ class StackedTimelineAnchor extends React.Component (time) => { const dictationDoc = Cast(this.props.layoutDoc["data-dictation"], Doc, null); const isDictation = dictationDoc && DocListCast(this.props.mark.links).some(link => Cast(link.anchor1, Doc, null)?.annotationOn === dictationDoc); - if ((isDictation || !Doc.AreProtosEqual(LightboxView.LightboxDoc, this.props.layoutDoc)) && DocListCast(this.props.mark.links).length && + if ((!LightboxView.LightboxDoc + /*isDictation || !Doc.AreProtosEqual(LightboxView.LightboxDoc, this.props.layoutDoc)*/) && DocListCast(this.props.mark.links).length && time > NumCast(this.props.mark[this.props.startTag]) && time < NumCast(this.props.mark[this.props.endTag]) && this._lastTimecode < NumCast(this.props.mark[this.props.startTag])) { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index c623ce653..004d29127 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1032,7 +1032,7 @@ export class CollectionFreeFormView extends CollectionSubView void; isContentActive: (outsideReaction?: boolean) => boolean; + isDocumentActive?: () => boolean; isSelected: (outsideReaction?: boolean) => boolean; scaling?: () => number; setHeight: (height: number) => void; -- cgit v1.2.3-70-g09d2 From ebf301a8382e01fa3463f7295bfba175b905e59e Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 9 Apr 2021 13:27:15 -0400 Subject: fixed webBox to display link icon w/ all related links properly. --- src/client/views/MainView.tsx | 10 +++++++--- src/client/views/nodes/WebBox.tsx | 6 ++++++ 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 7d78d74e3..c31e82ba0 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -178,8 +178,8 @@ export class MainView extends React.Component { const targClass = targets[0].className.toString(); if (SearchBox.Instance._searchbarOpen || SearchBox.Instance.open) { const check = targets.some((thing) => - (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" || - thing.className === "collectionSchema-header-menuOptions")); + (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" || + thing.className === "collectionSchema-header-menuOptions")); !check && SearchBox.Instance.resetSearch(true); } !targClass.includes("contextMenu") && ContextMenu.Instance.closeMenu(); @@ -273,7 +273,11 @@ export class MainView extends React.Component { @computed get dockingContent() { return
    { e.stopPropagation(); e.preventDefault(); }} - style={{ minWidth: `calc(100% - ${this._flyoutWidth + this.menuPanelWidth() + this.propertiesWidth()}px)`, width: `calc(100% - ${this._flyoutWidth + this.menuPanelWidth() + this.propertiesWidth()}px)` }}> + style={{ + minWidth: `calc(100% - ${this._flyoutWidth + this.menuPanelWidth() + this.propertiesWidth()}px)`, + transform: LightboxView.LightboxDoc ? "scale(0.0001)" : undefined, + width: `calc(100% - ${this._flyoutWidth + this.menuPanelWidth() + this.propertiesWidth()}px)` + }}> {!this.mainContainer ? (null) : this.mainDocView}
    ; } diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 2a575ca9b..2f2b242f5 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -32,6 +32,7 @@ import { FieldView, FieldViewProps } from './FieldView'; import { LinkDocPreview } from "./LinkDocPreview"; import "./WebBox.scss"; import React = require("react"); +import { ComputedField } from "../../../fields/ScriptField"; const _global = (window /* browser */ || global /* node */) as any; const htmlToText = require("html-to-text"); @@ -80,6 +81,8 @@ export class WebBox extends ViewBoxAnnotatableComponent { this._url = this.webField?.toString() || ""; this._annotationKey = "annotations-" + this.urlHash(this._url); + this.dataDoc["annotation-active"] = this._annotationKey; + this.dataDoc[this.fieldKey + "-annotations"] = ComputedField.MakeFunction(`copyField(this["${this.fieldKey}-"+this["annotation-active"]])`); }); this._disposers.selection = reaction(() => this.props.isSelected(), @@ -290,6 +293,7 @@ export class WebBox extends ViewBoxAnnotatableComponent Date: Fri, 9 Apr 2021 14:28:36 -0400 Subject: fixed : in lightbox view from creating a document --- src/client/views/collections/CollectionStackingViewFieldColumn.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index bee7aeb87..47733994b 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -235,7 +235,7 @@ export class CollectionStackingViewFieldColumn extends React.Component Date: Fri, 9 Apr 2021 14:54:16 -0400 Subject: fix for disappearing anchor menu when dictating and highlighting a pdf/web . --- src/client/views/nodes/formattedText/FormattedTextBox.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 1e901c0aa..c2860af76 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -297,7 +297,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp this._editorView.updateState(EditorState.fromJSON(this.config, json)); } } - if (window.getSelection()?.isCollapsed && this.props.isSelected) { + if (window.getSelection()?.isCollapsed && this.props.isSelected()) { AnchorMenu.Instance.fadeOut(true); } } -- cgit v1.2.3-70-g09d2 From a27ab0649aa66acd510f7cf7fc2aa92bfec7b03e Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Fri, 9 Apr 2021 23:30:48 -0400 Subject: in -> together --- src/client/views/nodes/FilterBox.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index 05bb69d61..78449636a 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -385,7 +385,7 @@ export class FilterBox extends ViewBoxBaseComponentAND -
    filters in
    +
    filters together
    -- cgit v1.2.3-70-g09d2 From 9135b7c1c414dc8caf255ef3d4b2b3d3f220289c Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Fri, 9 Apr 2021 23:45:20 -0400 Subject: removed some old comments + some unused imports --- src/client/util/SharingManager.tsx | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src') diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index b7a39a963..5a247730e 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -644,16 +644,10 @@ export class SharingManager extends React.Component<{}> {
    - {/*
    - this.myDocAcls = !this.myDocAcls)} checked={this.myDocAcls} /> -
    */} {Doc.UserDoc().noviceMode ? (null) :
    this.layoutDocAcls = !this.layoutDocAcls)} checked={this.layoutDocAcls} />
    } - {/* */}
    } -- cgit v1.2.3-70-g09d2 From f87c528f95912319c4181b3955cad4f1042c021e Mon Sep 17 00:00:00 2001 From: bobzel Date: Sat, 10 Apr 2021 10:16:30 -0400 Subject: from last --- src/client/util/CurrentUserUtils.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 417a1f405..0875d9be7 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -511,13 +511,13 @@ export class CurrentUserUtils { static async menuBtnDescriptions(doc: Doc) { return [ { title: "Dashboards", target: Cast(doc.myDashboards, Doc, null), icon: "desktop", click: 'selectMainMenu(self)' }, - { title: "Recently Closed", target: Cast(doc.myRecentlyClosedDocs, Doc, null), icon: "archive", click: 'selectMainMenu(self)' }, + { title: "My Files", target: Cast(doc.myFilesystem, Doc, null), icon: "file", click: 'selectMainMenu(self)' }, + { title: "Tools", target: Cast(doc.myTools, Doc, null), icon: "wrench", click: 'selectMainMenu(self)' }, { title: "Import", target: Cast(doc.myImportPanel, Doc, null), icon: "upload", click: 'selectMainMenu(self)' }, + { title: "Recently Closed", target: Cast(doc.myRecentlyClosedDocs, Doc, null), icon: "archive", click: 'selectMainMenu(self)' }, { title: "Sharing", target: Cast(doc.mySharedDocs, Doc, null), icon: "users", click: 'selectMainMenu(self)', watchedDocuments: doc.mySharedDocs as Doc }, - { title: "Tools", target: Cast(doc.myTools, Doc, null), icon: "wrench", click: 'selectMainMenu(self)' }, // { title: "Filter", target: Cast(doc.currentFilter, Doc, null), icon: "filter", click: 'selectMainMenu(self)' }, { title: "Pres. Trails", target: Cast(doc.myPresentations, Doc, null), icon: "pres-trail", click: 'selectMainMenu(self)' }, - { title: "My Files", target: Cast(doc.myFilesystem, Doc, null), icon: "file", click: 'selectMainMenu(self)' }, { title: "Help", target: undefined as any, icon: "question-circle", click: 'selectMainMenu(self)' }, { title: "Settings", target: undefined as any, icon: "cog", click: 'selectMainMenu(self)' }, { title: "User Doc", target: Cast(doc.myUserDoc, Doc, null), icon: "address-card", click: 'selectMainMenu(self)' }, -- cgit v1.2.3-70-g09d2 From 9669ebd0c0e76bbfbbc898e8b379cff41b1031ed Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 11 Apr 2021 12:07:10 -0400 Subject: some cleanup of demo_changes --- src/client/views/collections/CollectionMenu.tsx | 2 +- .../collections/CollectionStackedTimeline.tsx | 17 ++++++++------- src/client/views/nodes/PresBox.tsx | 24 +++++++++------------- src/client/views/nodes/ScreenshotBox.tsx | 12 +---------- src/client/views/nodes/VideoBox.tsx | 1 - src/client/views/nodes/WebBox.tsx | 5 +++++ 6 files changed, 27 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index f56f12c67..337595f1c 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -15,7 +15,7 @@ import { RichTextField } from "../../../fields/RichTextField"; import { listSpec } from "../../../fields/Schema"; import { ScriptField } from "../../../fields/ScriptField"; import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types"; -import { DeepCopy, emptyFunction, setupMoveUpEvents, Utils } from "../../../Utils"; +import { emptyFunction, setupMoveUpEvents, Utils } from "../../../Utils"; import { DocumentType } from "../../documents/DocumentTypes"; import { CurrentUserUtils } from "../../util/CurrentUserUtils"; import { DragManager } from "../../util/DragManager"; diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx index 782726456..ab9c4aa2c 100644 --- a/src/client/views/collections/CollectionStackedTimeline.tsx +++ b/src/client/views/collections/CollectionStackedTimeline.tsx @@ -234,16 +234,16 @@ export class CollectionStackedTimeline extends CollectionSubView "50%"; - documentHeight = () => "100%"; - timelineContentHeight = () => this.props.PanelHeight() / 2; + dictationHeightPercent = 50; + dictationHeight = () => `${this.dictationHeightPercent}%`; + timelineContentHeight = () => this.props.PanelHeight() * this.dictationHeightPercent / 100; dictationScreenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(0, -this.timelineContentHeight()); @computed get renderDictation() { const dictation = Cast(this.dataDoc[this.props.dictationKey], Doc, null); - return !dictation ? (null) :
    + return !dictation ? (null) :
    (time) => { const dictationDoc = Cast(this.props.layoutDoc["data-dictation"], Doc, null); const isDictation = dictationDoc && DocListCast(this.props.mark.links).some(link => Cast(link.anchor1, Doc, null)?.annotationOn === dictationDoc); - if ((!LightboxView.LightboxDoc - /*isDictation || !Doc.AreProtosEqual(LightboxView.LightboxDoc, this.props.layoutDoc)*/) && DocListCast(this.props.mark.links).length && + if (!LightboxView.LightboxDoc + // bcz: when should links be followed? we don't want to move away from the video to follow a link but we can open it in a sidebar/etc. But we don't know that upfront. + // for now, we won't follow any links when the lightbox is oepn to avoid "losing" the video. + /*(isDictation || !Doc.AreProtosEqual(LightboxView.LightboxDoc, this.props.layoutDoc))*/ + && DocListCast(this.props.mark.links).length && time > NumCast(this.props.mark[this.props.startTag]) && time < NumCast(this.props.mark[this.props.endTag]) && this._lastTimecode < NumCast(this.props.mark[this.props.startTag])) { diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 446db3549..f3fb6ff17 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -5,7 +5,7 @@ import { action, computed, IReactionDisposer, observable, ObservableMap, reactio import { observer } from "mobx-react"; import { ColorState, SketchPicker } from "react-color"; import { Bounce, Fade, Flip, LightSpeed, Roll, Rotate, Zoom } from 'react-reveal'; -import { Doc, DocListCast, DocListCastAsync } from "../../../fields/Doc"; +import { Doc, DocListCast, DocListCastAsync, FieldResult } from "../../../fields/Doc"; import { documentSchema } from "../../../fields/documentSchemas"; import { InkTool } from "../../../fields/InkField"; import { List } from "../../../fields/List"; @@ -247,11 +247,12 @@ export class PresBox extends ViewBoxBaseComponent // } } - stopTempMedia = (targetDoc: Doc) => { - if (targetDoc.type === DocumentType.AUDIO) { + stopTempMedia = (targetDocField: FieldResult) => { + const targetDoc = Cast(targetDocField, Doc, null); + if (targetDoc?.type === DocumentType.AUDIO) { if (this._mediaTimer && this._mediaTimer[1] === targetDoc) clearTimeout(this._mediaTimer[0]); targetDoc._audioStop = true; - } else if (targetDoc.type === DocumentType.VID) { + } else if (targetDoc?.type === DocumentType.VID) { if (this._mediaTimer && this._mediaTimer[1] === targetDoc) clearTimeout(this._mediaTimer[0]); targetDoc._triggerVideoStop = true; } @@ -331,14 +332,11 @@ export class PresBox extends ViewBoxBaseComponent this.rootDoc._itemIndex = index; const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; - if (from && from.mediaStopTriggerList && this.layoutDoc.presStatus !== PresStatus.Edit) { - const mediaDocList = DocListCast(from.mediaStopTriggerList); - mediaDocList.forEach((doc) => { - this.stopTempMedia(Cast(doc.presentationTargetDoc, Doc, null)); - }); + if (from?.mediaStopTriggerList && this.layoutDoc.presStatus !== PresStatus.Edit) { + DocListCast(from.mediaStopTriggerList).forEach(this.stopTempMedia); } - if (from && from.mediaStop === "auto" && this.layoutDoc.presStatus !== PresStatus.Edit) { - this.stopTempMedia(Cast(from.presentationTargetDoc, Doc, null)); + if (from?.mediaStop === "auto" && this.layoutDoc.presStatus !== PresStatus.Edit) { + this.stopTempMedia(from.presentationTargetDoc); } // If next slide is audio / video 'Play automatically' then the next slide should be played if (this.layoutDoc.presStatus !== PresStatus.Edit && (targetDoc.type === DocumentType.AUDIO || targetDoc.type === DocumentType.VID) && (activeItem.mediaStart === "auto")) { @@ -577,9 +575,7 @@ export class PresBox extends ViewBoxBaseComponent if (this._presTimer) clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; this.layoutDoc.presLoop = false; - this.childDocs.forEach((doc) => { - this.stopTempMedia(Cast(doc.presentationTargetDoc, Doc, null)); - }); + this.childDocs.forEach(this.stopTempMedia); } } diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx index cecc593f0..6449c99a1 100644 --- a/src/client/views/nodes/ScreenshotBox.tsx +++ b/src/client/views/nodes/ScreenshotBox.tsx @@ -36,7 +36,7 @@ const ScreenshotDocument = makeInterface(documentSchema); @observer export class ScreenshotBox extends ViewBoxAnnotatableComponent(ScreenshotDocument) { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(ScreenshotBox, fieldKey); } - private _videoRef: HTMLVideoElement | undefined | null; + private _videoRef: HTMLVideoElement | null = null; private _audioRec: any; private _videoRec: any; @observable _screenCapture = false; @@ -82,12 +82,9 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent { - console.log('ref: ', r); this._videoRef = r; setTimeout(() => { if (this.rootDoc.startRec && this._videoRef) { // TODO glr: use mediaState @@ -107,12 +104,8 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent { - console.log("toggleRecording"); - console.log("2:" + this._videoRef!.srcObject); - this._screenCapture = !this._screenCapture; if (this._screenCapture) { - console.log("opening"); this._audioRec = new MediaRecorder(await navigator.mediaDevices.getUserMedia({ audio: true })); const aud_chunks: any = []; this._audioRec.ondataavailable = (e: any) => aud_chunks.push(e.data); @@ -128,7 +121,6 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent this.dataDoc[this.props.fieldKey + "-recordingStart"] = new DateField(new Date()); this._videoRec.ondataavailable = (e: any) => vid_chunks.push(e.data); this._videoRec.onstop = async (e: any) => { - console.log("onStop: video end"); const file = new File(vid_chunks, `${this.rootDoc[Id]}.mkv`, { type: vid_chunks[0].type, lastModified: Date.now() }); const [{ result }] = await Networking.UploadFilesToServer(file); this.dataDoc[this.fieldKey + "-duration"] = (new Date().getTime() - this.recordingStart!) / 1000; @@ -152,7 +144,6 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent Math.max(0, this.props.PanelHeight() - this.videoPanelHeight()); render() { TraceMobx(); - console.log('rendering'); return
    diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 3b0fb4091..fb58ddefc 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -417,7 +417,6 @@ export class VideoBox extends ViewBoxAnnotatableComponent { this._clicking = true; - console.log('timeline click'); setupMoveUpEvents(this, e, action((e: PointerEvent) => { this._clicking = false; diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 2f2b242f5..a632d1fcc 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -81,7 +81,12 @@ export class WebBox extends ViewBoxAnnotatableComponent { this._url = this.webField?.toString() || ""; this._annotationKey = "annotations-" + this.urlHash(this._url); + // bcz: this is messy. logically, setting the url alone should direct where annotations should go. But + // right now we need to set doc.annotation-active to be the field suffix for the annotations + // and we need to set a computed field to copy the annotations to where everyone else expects them in doc.field-annotations + // TODO: always write annotations to doc.field-anotations and then copy them to doc.field-annotaitons-hash only when the page is changed. this.dataDoc["annotation-active"] = this._annotationKey; + // bcz: need to make sure that doc.data-annotations points to the currently active web page's annotations (this could/should be in the constructor) this.dataDoc[this.fieldKey + "-annotations"] = ComputedField.MakeFunction(`copyField(this["${this.fieldKey}-"+this["annotation-active"]])`); }); -- cgit v1.2.3-70-g09d2 From 79171e0275b45393cc56f54955c0056920ab2c40 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 11 Apr 2021 12:09:43 -0400 Subject: from last --- src/client/views/LightboxView.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index 9444446b1..b26765fa7 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -188,8 +188,7 @@ export class LightboxView extends React.Component { LightboxView._future?.push(...DocListCast(tours[0][fieldKey]).reverse()); } else { const coll = LightboxView._docTarget; - const doc = LightboxView.LightboxDoc; - if (coll && doc) { + if (coll) { const fieldKey = Doc.LayoutFieldKey(coll); LightboxView.SetLightboxDoc(coll, undefined, [...DocListCast(coll[fieldKey]), ...DocListCast(coll[fieldKey + "-annotations"])]); TabDocView.PinDoc(coll, { hidePresBox: true }); -- cgit v1.2.3-70-g09d2 From 6accc320ae70c6607e67a1befe37f5712b092c02 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 11 Apr 2021 12:18:18 -0400 Subject: added childDocumentsActive prop to avoid hardwiring reference to "starburst" in freeformview. --- src/client/views/collections/CollectionPileView.tsx | 13 ++++++++++--- src/client/views/collections/CollectionView.tsx | 1 + .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionPileView.tsx b/src/client/views/collections/CollectionPileView.tsx index 6f6cdd5d2..6baf633dd 100644 --- a/src/client/views/collections/CollectionPileView.tsx +++ b/src/client/views/collections/CollectionPileView.tsx @@ -2,7 +2,7 @@ import { action, computed } from "mobx"; import { observer } from "mobx-react"; import { Doc, HeightSym, WidthSym } from "../../../fields/Doc"; import { NumCast, StrCast } from "../../../fields/Types"; -import { emptyFunction, setupMoveUpEvents } from "../../../Utils"; +import { emptyFunction, setupMoveUpEvents, returnTrue } from "../../../Utils"; import { DocUtils } from "../../documents/Documents"; import { SelectionManager } from "../../util/SelectionManager"; import { SnappingManager } from "../../util/SnappingManager"; @@ -31,9 +31,16 @@ export class CollectionPileView extends CollectionSubView(doc => doc) { // returns the contents of the pileup in a CollectionFreeFormView @computed get contents() { + const isStarburst = this.layoutEngine() === "starburst"; const draggingSelf = this.props.isSelected(); - return
    - + { (doc instanceof Doc ? [doc] : doc).map((d) => DocUtils.iconify(d)); return this.props.addDocument?.(doc) || false; diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 4dc0ee3e6..85ae66fdc 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -66,6 +66,7 @@ export interface CollectionViewProps extends FieldViewProps { // property overrides for child documents children?: never | (() => JSX.Element[]) | React.ReactNode; childDocuments?: Doc[]; // used to override the documents shown by the sub collection to an explicit list (see LinkBox) + childDocumentsActive?: () => boolean;// whether child documents can be dragged if collection can be dragged (eg., in a when a Pile document is in startburst mode) childFitWidth?: () => boolean; childOpacity?: () => number; childHideTitle?: () => boolean; // whether to hide the documentdecorations title for children diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 004d29127..7a879ecde 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1032,7 +1032,7 @@ export class CollectionFreeFormView extends CollectionSubView Date: Sun, 11 Apr 2021 12:21:54 -0400 Subject: from last --- src/client/views/nodes/ScreenshotBox.tsx | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx index 6449c99a1..73fe8d68a 100644 --- a/src/client/views/nodes/ScreenshotBox.tsx +++ b/src/client/views/nodes/ScreenshotBox.tsx @@ -1,6 +1,6 @@ import React = require("react"); import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction, trace } from "mobx"; +import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; import { DateField } from "../../../fields/DateField"; import { Doc, WidthSym } from "../../../fields/Doc"; @@ -11,21 +11,21 @@ import { makeInterface } from "../../../fields/Schema"; import { ComputedField } from "../../../fields/ScriptField"; import { Cast, NumCast } from "../../../fields/Types"; import { AudioField, VideoField } from "../../../fields/URLField"; +import { TraceMobx } from "../../../fields/util"; import { emptyFunction, OmitKeys, returnFalse, returnOne, Utils } from "../../../Utils"; import { DocUtils } from "../../documents/Documents"; import { DocumentType } from "../../documents/DocumentTypes"; import { Networking } from "../../Network"; +import { CaptureManager } from "../../util/CaptureManager"; import { CurrentUserUtils } from "../../util/CurrentUserUtils"; import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView"; import { CollectionStackedTimeline } from "../collections/CollectionStackedTimeline"; import { ContextMenu } from "../ContextMenu"; import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from "../DocComponent"; import { FieldView, FieldViewProps } from './FieldView'; +import { FormattedTextBox } from "./formattedText/FormattedTextBox"; import "./ScreenshotBox.scss"; import { VideoBox } from "./VideoBox"; -import { TraceMobx } from "../../../fields/util"; -import { FormattedTextBox } from "./formattedText/FormattedTextBox"; -import { CaptureManager } from "../../util/CaptureManager"; declare class MediaRecorder { constructor(e: any, options?: any); // whatever MediaRecorder has } @@ -41,8 +41,6 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent disposer?.()); } specificContextMenu = (e: React.MouseEvent): void => { -- cgit v1.2.3-70-g09d2 From 470240a50c3af2ff29a6d61ee256374e70933eb9 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 11 Apr 2021 12:34:51 -0400 Subject: updated startRect to use mediaState and added pendingRecording as an option. --- src/client/documents/Documents.ts | 5 +++-- src/client/util/CurrentUserUtils.ts | 2 +- src/client/views/collections/CollectionMenu.tsx | 5 +---- src/client/views/nodes/AudioBox.tsx | 2 +- src/client/views/nodes/ScreenshotBox.tsx | 3 +-- 5 files changed, 7 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 96aa43c79..219890945 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -164,6 +164,7 @@ export class DocumentOptions { version?: string; // version identifier for a document label?: string; hidden?: boolean; + mediaState?: string; // status of media document: "pendingRecording", "recording", "paused", "playing" autoPlayAnchors?: boolean; // whether to play audio/video when an anchor is clicked in a stackedTimeline. dontPlayLinkOnSelect?: boolean; // whether an audio/video should start playing when a link is followed to it. toolTip?: string; // tooltip to display on hover @@ -703,8 +704,8 @@ export namespace Docs { return InstanceFromProto(Prototypes.get(DocumentType.WEBCAM), "", options); } - export function ScreenshotDocument(url: string, options: DocumentOptions = {}) { - return InstanceFromProto(Prototypes.get(DocumentType.SCREENSHOT), "", options); + export function ScreenshotDocument(title: string, options: DocumentOptions = {}) { + return InstanceFromProto(Prototypes.get(DocumentType.SCREENSHOT), "", { ...options, title }); } export function ComparisonDocument(options: DocumentOptions = { title: "Comparison Box" }) { diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 0875d9be7..cb8bf5a7f 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -423,7 +423,7 @@ export class CurrentUserUtils { ((doc.emptyScript as Doc).proto as Doc)["dragFactory-count"] = 0; } if (doc.emptyScreenshot === undefined) { - doc.emptyScreenshot = Docs.Create.ScreenshotDocument("", { _fitWidth: true, _width: 400, _height: 200, title: "screen snapshot", system: true, cloneFieldFilter: new List(["system"]) }); + doc.emptyScreenshot = Docs.Create.ScreenshotDocument("empty screenshot", { _fitWidth: true, _width: 400, _height: 200, system: true, cloneFieldFilter: new List(["system"]) }); } if (doc.emptyAudio === undefined) { doc.emptyAudio = Docs.Create.AudioDocument(nullAudio, { _width: 200, title: "audio recording", system: true, cloneFieldFilter: new List(["system"]) }); diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 337595f1c..a26953ff6 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -399,10 +399,7 @@ export class CollectionViewBaseChrome extends React.Component { - const doc = Docs.Create.ScreenshotDocument("", { _fitWidth: true, _width: 400, _height: 200, title: "screen snapshot", system: true, cloneFieldFilter: new List(["system"]) }); - doc.x = 0; - doc.y = 0; - doc.startRec = true; + const doc = Docs.Create.ScreenshotDocument("screen recording", { _fitWidth: true, _width: 400, _height: 200, mediaState: "pendingRecording" }); //Doc.AddDocToList((Doc.UserDoc().myOverlayDocs as Doc), undefined, doc); CollectionDockingView.AddSplit(doc, "right"); } diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 85899578c..a2e36f12e 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -53,7 +53,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent = this.layoutDoc._height; @observable _paused: boolean = false; - @computed get mediaState(): undefined | "recording" | "paused" | "playing" { return this.dataDoc.mediaState as (undefined | "recording" | "paused" | "playing"); } + @computed get mediaState(): undefined | "pendingRecording" | "recording" | "paused" | "playing" { return this.dataDoc.mediaState as (undefined | "pendingRecording" | "recording" | "paused" | "playing"); } set mediaState(value) { this.dataDoc.mediaState = value; } public static SetScrubTime = action((timeInMillisFrom1970: number) => { AudioBox._scrubTime = 0; AudioBox._scrubTime = timeInMillisFrom1970; }); @computed get recordingStart() { return Cast(this.dataDoc[this.props.fieldKey + "-recordingStart"], DateField)?.date.getTime(); } diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx index 73fe8d68a..c4f8d1143 100644 --- a/src/client/views/nodes/ScreenshotBox.tsx +++ b/src/client/views/nodes/ScreenshotBox.tsx @@ -84,9 +84,8 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent { this._videoRef = r; setTimeout(() => { - if (this.rootDoc.startRec && this._videoRef) { // TODO glr: use mediaState + if (this.rootDoc.mediaState === "pendingRecording" && this._videoRef) { // TODO glr: use mediaState this.toggleRecording(); - this.rootDoc.startRec = undefined; } }, 1000); }} -- cgit v1.2.3-70-g09d2 From b215d4860454fca9050bb96a5f7c222c1eb9a3c7 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 11 Apr 2021 13:16:31 -0400 Subject: clean up of webBox annotation field updating when navigating between pages. --- src/client/views/nodes/KeyValueBox.tsx | 2 +- src/client/views/nodes/WebBox.tsx | 34 ++++++++++++++-------------------- src/fields/Doc.ts | 2 +- 3 files changed, 16 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx index bf9ca1de0..111509fdb 100644 --- a/src/client/views/nodes/KeyValueBox.tsx +++ b/src/client/views/nodes/KeyValueBox.tsx @@ -58,7 +58,7 @@ export class KeyValueBox extends React.Component { value = eq ? value.substr(1) : value; const dubEq = value.startsWith(":=") ? "computed" : value.startsWith(";=") ? "script" : false; value = dubEq ? value.substr(2) : value; - const options: ScriptOptions = { addReturn: true, params: { this: "Doc", _last_: "any" }, globals: true, editable: false }; + const options: ScriptOptions = { addReturn: true, params: { this: "Doc", _last_: "any" }, editable: false }; if (dubEq) options.typecheck = false; const script = CompileScript(value, options); return !script.compiled ? undefined : { script, type: dubEq, onDelegate: eq }; diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index a632d1fcc..fc6f9ceab 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -2,20 +2,22 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; import * as WebRequest from 'web-request'; -import { Doc, DocListCast, HeightSym, Opt, StrListCast, WidthSym } from "../../../fields/Doc"; +import { Doc, DocListCast, HeightSym, Opt, WidthSym } from "../../../fields/Doc"; import { documentSchema } from "../../../fields/documentSchemas"; import { Id } from "../../../fields/FieldSymbols"; import { HtmlField } from "../../../fields/HtmlField"; import { InkTool } from "../../../fields/InkField"; import { List } from "../../../fields/List"; -import { makeInterface, listSpec } from "../../../fields/Schema"; +import { listSpec, makeInterface } from "../../../fields/Schema"; +import { ComputedField } from "../../../fields/ScriptField"; import { Cast, NumCast, StrCast } from "../../../fields/Types"; import { WebField } from "../../../fields/URLField"; import { TraceMobx } from "../../../fields/util"; -import { emptyFunction, getWordAtPoint, OmitKeys, returnOne, smoothScroll, Utils, setupMoveUpEvents, returnFalse } from "../../../Utils"; +import { emptyFunction, getWordAtPoint, OmitKeys, returnFalse, returnOne, setupMoveUpEvents, smoothScroll, Utils } from "../../../Utils"; import { Docs } from "../../documents/Documents"; import { DocumentType } from '../../documents/DocumentTypes'; import { CurrentUserUtils } from "../../util/CurrentUserUtils"; +import { Scripting } from "../../util/Scripting"; import { SnappingManager } from "../../util/SnappingManager"; import { undoBatch } from "../../util/UndoManager"; import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView"; @@ -32,7 +34,6 @@ import { FieldView, FieldViewProps } from './FieldView'; import { LinkDocPreview } from "./LinkDocPreview"; import "./WebBox.scss"; import React = require("react"); -import { ComputedField } from "../../../fields/ScriptField"; const _global = (window /* browser */ || global /* node */) as any; const htmlToText = require("html-to-text"); @@ -80,14 +81,9 @@ export class WebBox extends ViewBoxAnnotatableComponent { this._url = this.webField?.toString() || ""; - this._annotationKey = "annotations-" + this.urlHash(this._url); - // bcz: this is messy. logically, setting the url alone should direct where annotations should go. But - // right now we need to set doc.annotation-active to be the field suffix for the annotations - // and we need to set a computed field to copy the annotations to where everyone else expects them in doc.field-annotations - // TODO: always write annotations to doc.field-anotations and then copy them to doc.field-annotaitons-hash only when the page is changed. - this.dataDoc["annotation-active"] = this._annotationKey; - // bcz: need to make sure that doc.data-annotations points to the currently active web page's annotations (this could/should be in the constructor) - this.dataDoc[this.fieldKey + "-annotations"] = ComputedField.MakeFunction(`copyField(this["${this.fieldKey}-"+this["annotation-active"]])`); + this._annotationKey = "annotations-" + WebBox.urlHash(this._url); + // bcz: need to make sure that doc.data-annotations points to the currently active web page's annotations (this could/should be when the doc is created) + this.dataDoc[this.fieldKey + "-annotations"] = ComputedField.MakeFunction(`copyField(this["${this.fieldKey}-annotations-"+urlHash(this["${this.fieldKey}"]?.url?.toString()))`); }); this._disposers.selection = reaction(() => this.props.isSelected(), @@ -297,8 +293,7 @@ export class WebBox extends ViewBoxAnnotatableComponent([this._url]); else future.push(this._url); this.dataDoc[this.fieldKey] = new WebField(new URL(this._url = history.pop()!)); - this._annotationKey = "annotations-" + this.urlHash(this._url); - this.dataDoc["annotation-active"] = this._annotationKey; + this._annotationKey = "annotations-" + WebBox.urlHash(this._url); return true; } return false; } - urlHash = (s: string) => { + static urlHash = (s: string) => { return s.split('').reduce((a: any, b: any) => { a = ((a << 5) - a) + b.charCodeAt(0); return a & a; }, 0); } @@ -341,8 +335,7 @@ export class WebBox extends ViewBoxAnnotatableComponent
    ); } -} \ No newline at end of file +} +Scripting.addGlobal(function urlHash(url: string) { return WebBox.urlHash(url); }); \ No newline at end of file diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 300dae0aa..9faba9486 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -1324,7 +1324,7 @@ export namespace Doc { } -Scripting.addGlobal(function idToDoc(id: string) { return DocServer.GetCachedRefField(id); }); +Scripting.addGlobal(function idToDoc(id: string): any { return DocServer.GetCachedRefField(id); }); Scripting.addGlobal(function renameAlias(doc: any, n: any) { return StrCast(Doc.GetProto(doc).title).replace(/\([0-9]*\)/, "") + `(${n})`; }); Scripting.addGlobal(function getProto(doc: any) { return Doc.GetProto(doc); }); Scripting.addGlobal(function getDocTemplate(doc?: any) { return Doc.getDocTemplate(doc); }); -- cgit v1.2.3-70-g09d2 From cc41e1e5e8bf6cfb1710cc1acd2a3cad711554d0 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 11 Apr 2021 18:20:53 -0400 Subject: added declaration for idToDoc so that edits to doc lists can be made in kvp --- src/client/util/type_decls.d | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/client/util/type_decls.d b/src/client/util/type_decls.d index 3b23d5d56..ac0bea46a 100644 --- a/src/client/util/type_decls.d +++ b/src/client/util/type_decls.d @@ -215,5 +215,6 @@ declare const Docs: { StackingDocument(documents: Doc[], options?: DocumentOptions): Doc; }; +declare function idToDoc(id:string):any; declare function assignDoc(doc:Doc, field:any, id:any):string; declare function d(...args:any[]):any; -- cgit v1.2.3-70-g09d2 From 07ad05653c419a197a58a4f076f4d63697c375d9 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 12 Apr 2021 13:43:34 -0400 Subject: added placeholder comment --- src/client/views/collections/TreeView.tsx | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index ce3ba7981..e1fd78270 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -150,6 +150,7 @@ export class TreeView extends React.Component { if (this.props.document.isFolder || Doc.IsSystem(this.props.document)) { this.treeViewOpen = !this.treeViewOpen; } else { + // choose an appropriate alias or make one. --- choose the first alias that (1) user owns, (2) has no context field ... otherwise make a new alias this.props.addDocTab(this.props.document, "add:right"); } } -- cgit v1.2.3-70-g09d2 From c4cc3cc6a43cbb61c4557da1b6809502645b371a Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 14 Apr 2021 18:01:32 -0400 Subject: fixed audiowaveform height. --- src/client/views/collections/CollectionStackedTimeline.scss | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/client/views/collections/CollectionStackedTimeline.scss b/src/client/views/collections/CollectionStackedTimeline.scss index 19ad5cefa..e456c0664 100644 --- a/src/client/views/collections/CollectionStackedTimeline.scss +++ b/src/client/views/collections/CollectionStackedTimeline.scss @@ -62,6 +62,7 @@ .collectionStackedTimeline-waveform { position: absolute; width: 100%; + height: 100%; top: 0; left: 0; pointer-events: none; -- cgit v1.2.3-70-g09d2 From 3ca56576e187e2f3cc87770b0fbdf8aa6cae73f3 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 14 Apr 2021 23:12:19 -0400 Subject: fixed image templates to set/use the appropriate nativewidth/height. fixed carousel views and style provider to better support properties for components of a document view. fixed menus to show text options when captions and other sub text components are focused. --- src/client/views/DocComponent.tsx | 4 +- src/client/views/StyleProvider.tsx | 3 +- .../views/collections/CollectionCarousel3DView.tsx | 23 +---------- .../views/collections/CollectionCarouselView.tsx | 46 +++++++--------------- src/client/views/collections/CollectionMenu.scss | 2 +- src/client/views/collections/CollectionMenu.tsx | 3 ++ src/client/views/collections/TabDocView.tsx | 3 +- src/client/views/nodes/ImageBox.tsx | 4 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 6 ++- src/fields/Doc.ts | 4 +- 10 files changed, 35 insertions(+), 63 deletions(-) (limited to 'src') diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index c017b7015..3c565fd62 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -124,8 +124,8 @@ export function ViewBoxAnnotatableComponent

    { - const p = (this.props as any)[prop] as string; - p && (style[prop] = p?.replace(/{([^.'][^}']+)}/g, replacer)); + const p = (this.props as any)[prop]; + typeof p === "string" && (style[prop] = p?.replace(/{([^.'][^}']+)}/g, replacer)); }); return style; } diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 9102b9fa4..ebd453295 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -65,6 +65,7 @@ export function testDocProps(toBeDetermined: any): toBeDetermined is DocumentVie // export function DefaultStyleProvider(doc: Opt, props: Opt, property: string): any { const docProps = testDocProps(props) ? props : undefined; + const fieldKey = (props as any)?.fieldKey ? (props as any).fieldKey + "-" : ""; const selected = property.includes(":selected"); const isCaption = property.includes(":caption"); const isAnchor = property.includes(":anchor"); @@ -99,7 +100,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt = StrCast(doc?._backgroundColor); + let docColor: Opt = StrCast(doc?.[fieldKey + "backgroundColor"], StrCast(doc?._backgroundColor)); if (MainView.Instance.LastButton === doc) return darkScheme() ? "dimgrey" : "lightgrey"; switch (doc?.type) { case DocumentType.PRESELEMENT: docColor = docColor || (darkScheme() ? "" : ""); break; diff --git a/src/client/views/collections/CollectionCarousel3DView.tsx b/src/client/views/collections/CollectionCarousel3DView.tsx index b2ae441d6..9a3183d88 100644 --- a/src/client/views/collections/CollectionCarousel3DView.tsx +++ b/src/client/views/collections/CollectionCarousel3DView.tsx @@ -104,27 +104,6 @@ export class CollectionCarousel3DView extends CollectionSubView(Carousel3DDocume }, 1500); } - _downX = 0; - _downY = 0; - onPointerDown = (e: React.PointerEvent) => { - this._downX = e.clientX; - this._downY = e.clientY; - document.addEventListener("pointerup", this.onpointerup); - } - private _lastTap: number = 0; - private _doubleTap = false; - onpointerup = (e: PointerEvent) => { - this._doubleTap = (Date.now() - this._lastTap < 300 && e.button === 0 && Math.abs(e.clientX - this._downX) < 2 && Math.abs(e.clientY - this._downY) < 2); - this._lastTap = Date.now(); - } - - onClick = (e: React.MouseEvent) => { - if (this._doubleTap) { - e.stopPropagation(); - this.props.Document.isLightboxOpen = true; - } - } - @computed get buttons() { if (!this.props.isContentActive()) return null; return

    @@ -167,7 +146,7 @@ export class CollectionCarousel3DView extends CollectionSubView(Carousel3DDocume const index = NumCast(this.layoutDoc._itemIndex); const translateX = this.panelWidth() * (1 - index); - return
    + return
    {this.content}
    diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx index cc90b9134..0642a1f9b 100644 --- a/src/client/views/collections/CollectionCarouselView.tsx +++ b/src/client/views/collections/CollectionCarouselView.tsx @@ -62,53 +62,37 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument)
    + Document={curDoc.layout} DataDoc={undefined} fieldKey={"caption"} + fontSize={NumCast(this.layoutDoc["caption-fontSize"])} + xMargin={NumCast(this.layoutDoc["caption-xMargin"])} + yMargin={NumCast(this.layoutDoc["caption-yMargin"])} />
    ; } @computed get buttons() { return <> -
    +
    -
    +
    ; } - _downX = 0; - _downY = 0; - onPointerDown = (e: React.PointerEvent) => { - this._downX = e.clientX; - this._downY = e.clientY; - document.addEventListener("pointerup", this.onpointerup); - } - private _lastTap: number = 0; - private _doubleTap = false; - onpointerup = (e: PointerEvent) => { - this._doubleTap = (Date.now() - this._lastTap < 300 && e.button === 0 && Math.abs(e.clientX - this._downX) < 2 && Math.abs(e.clientY - this._downY) < 2); - this._lastTap = Date.now(); - } - - onClick = (e: React.MouseEvent) => { - if (this._doubleTap) { - e.stopPropagation(); - this.props.Document.isLightboxOpen = true; - } - } - render() { - return
    + return
    {this.content} - {!this.props.Document._chromeHidden ? (null) : this.buttons} + {this.props.Document._chromeHidden ? (null) : this.buttons}
    ; } } \ No newline at end of file diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss index 9eac75f4b..dc5231a3a 100644 --- a/src/client/views/collections/CollectionMenu.scss +++ b/src/client/views/collections/CollectionMenu.scss @@ -300,7 +300,7 @@ .collection3DCarouselViewChrome-scrollSpeed-cont { justify-self: right; align-items: center; - display: grid; + display: flex; grid-auto-columns: auto; font-size: 75%; letter-spacing: 2px; diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index a26953ff6..95b0ef790 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -37,6 +37,7 @@ import { LightboxView } from "../LightboxView"; import { Docs } from "../../documents/Documents"; import { DocumentManager } from "../../util/DocumentManager"; import { CollectionDockingView } from "./CollectionDockingView"; +import { FormattedTextBox } from "../nodes/formattedText/FormattedTextBox"; @observer export class CollectionMenu extends AntimodeMenu { @@ -260,6 +261,7 @@ export class CollectionViewBaseChrome extends React.Component); case CollectionViewType.Tree: return (); case CollectionViewType.Masonry: return (); + case CollectionViewType.Carousel: case CollectionViewType.Carousel3D: return (); case CollectionViewType.Grid: return (); case CollectionViewType.Docking: return (); @@ -1021,6 +1023,7 @@ export class Collection3DCarouselViewChrome extends React.Component
    + {FormattedTextBox.Focused ? : (null)}
    AUTOSCROLL SPEED:
    diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index f6aecbb14..4417038fa 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -92,7 +92,8 @@ export class TabDocView extends React.Component { }; tab.element[0].style.borderTopRightRadius = "8px"; tab.element[0].children[1].appendChild(toggle); - tab._disposers.layerDisposer = reaction(() => ({ layer: tab.DashDoc.activeLayer, color: this.tabColor }), + tab._disposers.layerDisposer = reaction(() => + ({ layer: tab.DashDoc.activeLayer, color: this.tabColor }), ({ layer, color }) => toggle.style.background = !layer ? color : "dimgrey", { fireImmediately: true }); } // shifts the focus to this tab when another tab is dragged over it diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 8a6946b78..1ab367395 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -102,8 +102,8 @@ export class ImageBox extends ViewBoxAnnotatableComponent disposer?.()); this.endUndoTypingBatch(); this.unhighlightSearchTerms(); @@ -1236,8 +1237,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp @action onFocused = (e: React.FocusEvent): void => { //applyDevTools.applyDevTools(this._editorView); + FormattedTextBox.Focused = this; this._editorView && RichTextMenu.Instance?.updateMenu(this._editorView, undefined, this.props); } + @observable public static Focused: FormattedTextBox | undefined; onClick = (e: React.MouseEvent): void => { if (Math.abs(e.clientX - this._downX) > 4 || Math.abs(e.clientY - this._downY) > 4) { @@ -1340,6 +1343,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp return wasUndoing; } onBlur = (e: any) => { + FormattedTextBox.Focused === this && (FormattedTextBox.Focused = undefined); if (RichTextMenu.Instance?.view === this._editorView && !this.props.isSelected(true)) { RichTextMenu.Instance?.updateMenu(undefined, undefined, undefined); } diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 9faba9486..bd0ba3ad7 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -910,8 +910,8 @@ export namespace Doc { } export function NativeWidth(doc?: Doc, dataDoc?: Doc, useWidth?: boolean) { return !doc ? 0 : NumCast(doc._nativeWidth, NumCast((dataDoc || doc)[Doc.LayoutFieldKey(doc) + "-nativeWidth"], useWidth ? doc[WidthSym]() : 0)); } export function NativeHeight(doc?: Doc, dataDoc?: Doc, useHeight?: boolean) { return !doc ? 0 : NumCast(doc._nativeHeight, NumCast((dataDoc || doc)[Doc.LayoutFieldKey(doc) + "-nativeHeight"], useHeight ? doc[HeightSym]() : 0)); } - export function SetNativeWidth(doc: Doc, width: number | undefined) { doc[Doc.LayoutFieldKey(doc) + "-nativeWidth"] = width; } - export function SetNativeHeight(doc: Doc, height: number | undefined) { doc[Doc.LayoutFieldKey(doc) + "-nativeHeight"] = height; } + export function SetNativeWidth(doc: Doc, width: number | undefined, fieldKey?: string) { doc[(fieldKey ?? Doc.LayoutFieldKey(doc)) + "-nativeWidth"] = width; } + export function SetNativeHeight(doc: Doc, height: number | undefined, fieldKey?: string) { doc[(fieldKey ?? Doc.LayoutFieldKey(doc)) + "-nativeHeight"] = height; } const manager = new DocData(); -- cgit v1.2.3-70-g09d2 From 4334a553fdfdf44b1d1c609290fe2a874a408967 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 15 Apr 2021 00:04:18 -0400 Subject: fixed up carousels to work with templated documents --- .../views/collections/CollectionCarousel3DView.tsx | 40 +++++++++++++++++----- .../views/collections/CollectionCarouselView.tsx | 32 +++++++++++++---- src/client/views/collections/CollectionMenu.tsx | 2 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 1 + 4 files changed, 59 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionCarousel3DView.tsx b/src/client/views/collections/CollectionCarousel3DView.tsx index 9a3183d88..7cebabaa9 100644 --- a/src/client/views/collections/CollectionCarousel3DView.tsx +++ b/src/client/views/collections/CollectionCarousel3DView.tsx @@ -9,10 +9,11 @@ import { makeInterface } from '../../../fields/Schema'; import { ScriptField } from '../../../fields/ScriptField'; import { NumCast, ScriptCast, StrCast } from '../../../fields/Types'; import { OmitKeys, returnFalse, Utils } from '../../../Utils'; -import { DragManager } from '../../util/DragManager'; +import { DragManager, dropActionType } from '../../util/DragManager'; import { DocumentView } from '../nodes/DocumentView'; import "./CollectionCarousel3DView.scss"; import { CollectionSubView } from './CollectionSubView'; +import { StyleProp } from '../StyleProvider'; type Carousel3DDocument = makeInterface<[typeof documentSchema, typeof collectionSchema]>; const Carousel3DDocument = makeInterface(documentSchema, collectionSchema); @@ -42,17 +43,36 @@ export class CollectionCarousel3DView extends CollectionSubView(Carousel3DDocume const displayDoc = (childPair: { layout: Doc, data: Doc }) => { const script = ScriptField.MakeScript("this._showCaption = 'caption'", { this: Doc.name }); const onChildClick = script && (() => script); - return ; }; @@ -146,7 +166,11 @@ export class CollectionCarousel3DView extends CollectionSubView(Carousel3DDocume const index = NumCast(this.layoutDoc._itemIndex); const translateX = this.panelWidth() * (1 - index); - return
    + return
    {this.content}
    diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx index 0642a1f9b..4a7bdf6db 100644 --- a/src/client/views/collections/CollectionCarouselView.tsx +++ b/src/client/views/collections/CollectionCarouselView.tsx @@ -7,7 +7,7 @@ import { collectionSchema, documentSchema } from '../../../fields/documentSchema import { makeInterface } from '../../../fields/Schema'; import { NumCast, ScriptCast, StrCast } from '../../../fields/Types'; import { OmitKeys, returnFalse } from '../../../Utils'; -import { DragManager } from '../../util/DragManager'; +import { DragManager, dropActionType } from '../../util/DragManager'; import { DocumentView } from '../nodes/DocumentView'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; import { StyleProp } from '../StyleProvider'; @@ -47,16 +47,34 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument) return !(curDoc?.layout instanceof Doc) ? (null) : <>
    -
    diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 95b0ef790..ab4f197a6 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -554,7 +554,7 @@ export class CollectionViewBaseChrome extends React.Component
    {this.lightboxButton} {this.recordButton} - {/* {!this._buttonizableCommands ? (null) : this.templateChrome} */} + {!this._buttonizableCommands ? (null) : this.templateChrome}
    diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 9203207d7..25dc93605 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1342,6 +1342,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp this._undoTyping = undefined; return wasUndoing; } + @action onBlur = (e: any) => { FormattedTextBox.Focused === this && (FormattedTextBox.Focused = undefined); if (RichTextMenu.Instance?.view === this._editorView && !this.props.isSelected(true)) { -- cgit v1.2.3-70-g09d2 From 70f92c85461dc50fb0e63d3ecd5c429bcae37cc7 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 15 Apr 2021 00:20:57 -0400 Subject: simplified carousel DocumentView calls. --- .../views/collections/CollectionCarousel3DView.tsx | 35 ++++------------------ .../views/collections/CollectionCarouselView.tsx | 33 +++++--------------- 2 files changed, 13 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionCarousel3DView.tsx b/src/client/views/collections/CollectionCarousel3DView.tsx index 7cebabaa9..2251b60e5 100644 --- a/src/client/views/collections/CollectionCarousel3DView.tsx +++ b/src/client/views/collections/CollectionCarousel3DView.tsx @@ -9,7 +9,7 @@ import { makeInterface } from '../../../fields/Schema'; import { ScriptField } from '../../../fields/ScriptField'; import { NumCast, ScriptCast, StrCast } from '../../../fields/Types'; import { OmitKeys, returnFalse, Utils } from '../../../Utils'; -import { DragManager, dropActionType } from '../../util/DragManager'; +import { DragManager } from '../../util/DragManager'; import { DocumentView } from '../nodes/DocumentView'; import "./CollectionCarousel3DView.scss"; import { CollectionSubView } from './CollectionSubView'; @@ -41,38 +41,15 @@ export class CollectionCarousel3DView extends CollectionSubView(Carousel3DDocume @computed get content() { const currentIndex = NumCast(this.layoutDoc._itemIndex); const displayDoc = (childPair: { layout: Doc, data: Doc }) => { - const script = ScriptField.MakeScript("this._showCaption = 'caption'", { this: Doc.name }); - const onChildClick = script && (() => script); - return ; }; diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx index 4a7bdf6db..d28a4d87d 100644 --- a/src/client/views/collections/CollectionCarouselView.tsx +++ b/src/client/views/collections/CollectionCarouselView.tsx @@ -7,7 +7,7 @@ import { collectionSchema, documentSchema } from '../../../fields/documentSchema import { makeInterface } from '../../../fields/Schema'; import { NumCast, ScriptCast, StrCast } from '../../../fields/Types'; import { OmitKeys, returnFalse } from '../../../Utils'; -import { DragManager, dropActionType } from '../../util/DragManager'; +import { DragManager } from '../../util/DragManager'; import { DocumentView } from '../nodes/DocumentView'; import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; import { StyleProp } from '../StyleProvider'; @@ -47,34 +47,15 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument) return !(curDoc?.layout instanceof Doc) ? (null) : <>
    -
    -- cgit v1.2.3-70-g09d2 From e55aed8d419d9e1d7385d0556c09405035f01e7c Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 15 Apr 2021 23:09:26 -0400 Subject: cleaned up CollectionCarousel and styleprovider to handle sub-component properties better. updated resizers in multicol/row to be visible. --- src/client/views/SidebarAnnos.tsx | 2 -- src/client/views/StyleProvider.tsx | 12 ++++--- .../views/collections/CollectionCarouselView.scss | 15 ++++---- .../views/collections/CollectionCarouselView.tsx | 40 ++++++++++++++-------- .../views/collections/CollectionStackingView.tsx | 2 +- .../collections/collectionFreeForm/MarqueeView.tsx | 2 +- .../CollectionMulticolumnView.tsx | 2 ++ .../CollectionMultirowView.tsx | 2 ++ .../collectionMulticolumn/MulticolumnResizer.tsx | 27 ++++++++------- .../collectionMulticolumn/MultirowResizer.tsx | 27 ++++++++------- src/client/views/nodes/DocumentView.tsx | 7 ++-- src/client/views/nodes/FieldView.tsx | 4 +-- src/client/views/nodes/ScreenshotBox.tsx | 4 +-- .../views/nodes/formattedText/FormattedTextBox.tsx | 16 ++++----- 14 files changed, 90 insertions(+), 72 deletions(-) (limited to 'src') diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx index 6c3eb1e95..bff4c95fc 100644 --- a/src/client/views/SidebarAnnos.tsx +++ b/src/client/views/SidebarAnnos.tsx @@ -113,8 +113,6 @@ export class SidebarAnnos extends React.Component { NativeHeight={returnZero} PanelHeight={this.panelHeight} PanelWidth={this.panelWidth} - xMargin={0} - yMargin={0} styleProvider={this.sidebarStyleProvider} docFilters={this.docFilters} scaleField={this.sidebarKey() + "-scale"} diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index ebd453295..bde741959 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -86,21 +86,23 @@ export function DefaultStyleProvider(doc: Opt, props: Opt = StrCast(doc?.[fieldKey + "color"], StrCast(doc?._color)); + if (docColor) return docColor; if (isCaption) return "white"; - const backColor = backgroundCol() || "black"; + const backColor = backgroundCol();// || (darkScheme() ? "black" : "white"); + if (!backColor) return undefined; const col = Color(backColor).rgb(); const colsum = (col.red() + col.green() + col.blue()); if (colsum / col.alpha() > 400 || col.alpha() < 0.25) return "black"; return "white"; case StyleProp.Hidden: return BoolCast(doc?._hidden); - case StyleProp.BorderRounding: return StrCast(doc?._borderRounding); + case StyleProp.BorderRounding: return StrCast(doc?.[fieldKey + "borderRounding"], StrCast(doc?._borderRounding)); case StyleProp.TitleHeight: return 15; case StyleProp.HeaderMargin: return ([CollectionViewType.Stacking, CollectionViewType.Masonry].includes(doc?._viewType as any) || doc?.type === DocumentType.RTF) && showTitle() && !StrCast(doc?.showTitle).includes(":hover") ? 15 : 0; case StyleProp.BackgroundColor: { - if (isCaption) return "rgba(0,0,0 ,0.4)"; if (Doc.UserDoc().renderStyle === "comic") return "transparent"; - let docColor: Opt = StrCast(doc?.[fieldKey + "backgroundColor"], StrCast(doc?._backgroundColor)); + let docColor: Opt = StrCast(doc?.[fieldKey + "backgroundColor"], StrCast(doc?._backgroundColor, isCaption ? "rbga(0,0,0,0.4)" : "")); if (MainView.Instance.LastButton === doc) return darkScheme() ? "dimgrey" : "lightgrey"; switch (doc?.type) { case DocumentType.PRESELEMENT: docColor = docColor || (darkScheme() ? "" : ""); break; @@ -131,7 +133,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt; const CarouselDocument = makeInterface(documentSchema, collectionSchema); @@ -38,12 +38,19 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument) e.stopPropagation(); this.layoutDoc._itemIndex = (NumCast(this.layoutDoc._itemIndex) - 1 + this.childLayoutPairs.length) % this.childLayoutPairs.length; } - panelHeight = () => this.props.PanelHeight() - 50; + captionStyleProvider = (doc: (Doc | undefined), props: Opt, property: string): any => { + const captionProps = { ...this.props, fieldKey: "caption" }; + return this.props.styleProvider?.(doc, props, property) || this.props.styleProvider?.(this.layoutDoc, captionProps, property); + } + panelHeight = () => this.props.PanelHeight() - (StrCast(this.layoutDoc._showCaption) ? 50 : 0); onContentDoubleClick = () => ScriptCast(this.layoutDoc.onChildDoubleClick); onContentClick = () => ScriptCast(this.layoutDoc.onChildClick); @computed get content() { const index = NumCast(this.layoutDoc._itemIndex); const curDoc = this.childLayoutPairs?.[index]; + const captionProps = { ...this.props, fieldKey: "caption" }; + const marginX = NumCast(this.layoutDoc["caption-xMargin"]); + const marginY = NumCast(this.layoutDoc["caption-yMargin"]); return !(curDoc?.layout instanceof Doc) ? (null) : <>
    @@ -51,6 +58,7 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument) onDoubleClick={this.onContentDoubleClick} onClick={this.onContentClick} renderDepth={this.props.renderDepth + 1} + ContainingCollectionView={this} LayoutTemplate={this.props.childLayoutTemplate} LayoutTemplateString={this.props.childLayoutString} Document={curDoc.layout} @@ -61,25 +69,27 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument)
    - + xPadding={NumCast(this.layoutDoc["caption-xPadding"])} + yPadding={NumCast(this.layoutDoc["caption-yPadding"])} />
    ; } @computed get buttons() { return <> -
    - +
    +
    -
    - +
    +
    ; } diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 1aed40bc3..30f8e0112 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -58,7 +58,7 @@ export class CollectionStackingView extends CollectionSubView (pair.layout instanceof Doc) && !pair.layout.hidden).map(pair => pair.layout); } @computed get headerMargin() { return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.HeaderMargin); } @computed get xMargin() { return NumCast(this.layoutDoc._xMargin, 2 * Math.min(this.gridGap, .05 * this.props.PanelWidth())); } - @computed get yMargin() { return this.props.yMargin || NumCast(this.layoutDoc._yMargin, 5); } // 2 * this.gridGap)); } + @computed get yMargin() { return this.props.yPadding || NumCast(this.layoutDoc._yMargin, 5); } // 2 * this.gridGap)); } @computed get gridGap() { return NumCast(this.layoutDoc._gridGap, 10); } @computed get isStackingView() { return (this.props.viewType ?? this.layoutDoc._viewType) === CollectionViewType.Stacking; } @computed get numGroupColumns() { return this.isStackingView ? Math.max(1, this.Sections.size + (this.showAddAGroup ? 1 : 0)) : 1; } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index a4f129b8c..b1f2750c3 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -155,7 +155,7 @@ export class MarqueeView extends React.Component, boolean; columnUnitLength(): number | undefined; toLeft?: Doc; toRight?: Doc; @@ -85,19 +89,16 @@ export default class ResizeBar extends React.Component { } render() { - return ( -
    this.isHoverActive = true)} - onPointerLeave={action(() => !this.isResizingActive && (this.isHoverActive = false))} - > -
    this.registerResizing(e)} /> -
    - ); + return
    this.isHoverActive = true)} + onPointerLeave={action(() => !this.isResizingActive && (this.isHoverActive = false))} + > +
    this.registerResizing(e)} /> +
    ; } } \ No newline at end of file diff --git a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx index d0bc4d01c..5478bf709 100644 --- a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx +++ b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx @@ -5,9 +5,13 @@ import { Doc } from "../../../../fields/Doc"; import { NumCast, StrCast } from "../../../../fields/Types"; import { DimUnit } from "./CollectionMultirowView"; import { UndoManager } from "../../../util/UndoManager"; +import { StyleProp } from "../../StyleProvider"; +import { StyleProviderFunc } from "../../nodes/DocumentView"; interface ResizerProps { height: number; + styleProvider?: StyleProviderFunc; + isContentActive?: () => boolean; columnUnitLength(): number | undefined; toTop?: Doc; toBottom?: Doc; @@ -83,19 +87,16 @@ export default class ResizeBar extends React.Component { } render() { - return ( -
    this.isHoverActive = true)} - onPointerLeave={action(() => !this.isResizingActive && (this.isHoverActive = false))} - > -
    this.registerResizing(e)} /> -
    - ); + return
    this.isHoverActive = true)} + onPointerLeave={action(() => !this.isResizingActive && (this.isHoverActive = false))} + > +
    this.registerResizing(e)} /> +
    ; } } \ No newline at end of file diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index f08cda92c..5e97b07f0 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -508,6 +508,7 @@ export class DocumentViewInternal extends DocComponent 0))) { if ((this.props.isDocumentActive?.() || this.layoutDoc.onDragStart) && + !this.Document.ignoreClick && !e.ctrlKey && (e.button === 0 || InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE)) && !CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) { @@ -891,7 +892,7 @@ export class DocumentViewInternal extends DocComponent 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) - xMargin?: number; // used to override document's settings for xMargin --- see CollectionCarouselView - yMargin?: number; + xPadding?: number; // used to override document's settings for xMargin --- see CollectionCarouselView + yPadding?: number; noSidebar?: boolean; dontSelectOnLoad?: boolean; // suppress selecting the text box when loaded } @@ -1477,8 +1477,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp NativeHeight={returnZero} PanelHeight={this.props.PanelHeight} PanelWidth={this.sidebarWidth} - xMargin={0} - yMargin={0} + xPadding={0} + yPadding={0} scaleField={this.SidebarKey + "-scale"} isAnnotationOverlay={false} select={emptyFunction} @@ -1510,7 +1510,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const interactive = (CurrentUserUtils.SelectedTool === InkTool.None || SnappingManager.GetIsDragging()) && (this.layoutDoc.z || this.props.layerProvider?.(this.layoutDoc) !== false); if (!selected && FormattedTextBoxComment.textBox === this) setTimeout(FormattedTextBoxComment.Hide); const minimal = this.props.ignoreAutoHeight; - const margins = NumCast(this.layoutDoc._yMargin, this.props.yMargin || 0); + const margins = NumCast(this.layoutDoc._yMargin, this.props.yPadding || 0); const selPad = Math.min(margins, 10); const padding = Math.max(margins + ((selected && !this.layoutDoc._singleLine) || minimal ? -selPad : 0), 0); const selPaddingClass = selected && !this.layoutDoc._singleLine && margins >= 10 ? "-selected" : ""; @@ -1529,8 +1529,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp style={{ overflow: this.autoHeight ? "hidden" : undefined, height: this.props.height || (this.autoHeight && this.props.renderDepth ? "max-content" : undefined), - background: this.props.background ? this.props.background : StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BackgroundColor)), - color: this.props.color ? this.props.color : StrCast(this.layoutDoc[this.props.fieldKey + "-color"], this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Color)), + background: this.props.background ? this.props.background : this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BackgroundColor), + color: this.props.color ? this.props.color : this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Color), pointerEvents: interactive ? undefined : "none", fontSize: this.props.fontSize || Cast(this.layoutDoc._fontSize, "string", null), fontWeight: Cast(this.layoutDoc._fontWeight, "number", null), @@ -1565,7 +1565,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp {(this.props.noSidebar || this.Document._noSidebar) || this.Document._singleLine ? (null) : this.sidebarHandle} {!this.layoutDoc._showAudio ? (null) : this.audioHandle}
    -
    +
    ); } } -- cgit v1.2.3-70-g09d2 From e7f4439446200833082e23c7b6091817031235a5 Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 16 Apr 2021 13:12:17 -0400 Subject: fixed so that minimaps can't appear on non freeform collections. fixed multirow/col to work with templates & stopped normalizing dimensions (which breaks templates). added quick and dirty lightboxDocTemplate to display templated documents. fixed TextDocs to work with template fields that just have a text string. --- src/client/views/LightboxView.tsx | 10 ++++--- src/client/views/collections/TabDocView.tsx | 10 ++++--- .../CollectionMulticolumnView.tsx | 27 +++++++++++-------- .../CollectionMultirowView.tsx | 31 +++++++++++++--------- src/client/views/nodes/DocumentView.tsx | 11 ++++---- .../views/nodes/formattedText/FormattedTextBox.tsx | 6 ++--- 6 files changed, 58 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index b26765fa7..9c03b457b 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -26,6 +26,8 @@ interface LightboxViewProps { export class LightboxView extends React.Component { @computed public static get LightboxDoc() { return this._doc; } + private static LightboxDocTemplate = () => LightboxView._layoutTemplate; + @observable private static _layoutTemplate: Opt; @observable private static _doc: Opt; @observable private static _docTarget: Opt; @observable private static _docFilters: string[] = []; // filters @@ -35,7 +37,7 @@ export class LightboxView extends React.Component { private static _future: Opt = []; private static _docView: Opt; static path: { doc: Opt, target: Opt, history: Opt<{ doc: Doc, target?: Doc }[]>, future: Opt, saved: Opt<{ panX: Opt, panY: Opt, scale: Opt, scrollTop: Opt }> }[] = []; - @action public static SetLightboxDoc(doc: Opt, target?: Doc, future?: Doc[]) { + @action public static SetLightboxDoc(doc: Opt, target?: Doc, future?: Doc[], layoutTemplate?: Doc) { if (this.LightboxDoc && this.LightboxDoc !== doc && this._savedState) { this.LightboxDoc._panX = this._savedState.panX; this.LightboxDoc._panY = this._savedState.panY; @@ -62,6 +64,7 @@ export class LightboxView extends React.Component { this._future = future.slice().sort((a, b) => NumCast(b._timecodeToShow) - NumCast(a._timecodeToShow)).sort((a, b) => DocListCast(a.links).length - DocListCast(b.links).length); } this._doc = doc; + this._layoutTemplate = layoutTemplate; this._docTarget = target || doc; this._tourMap = DocListCast(doc?.links).map(link => { const opp = LinkManager.getOppositeAnchor(link, doc!); @@ -101,13 +104,13 @@ export class LightboxView extends React.Component { this._docFilters = (f => this._docFilters ? [this._docFilters.push(f) as any, this._docFilters][1] : [f])(`cookies:${cookie}:provide`); } } - public static AddDocTab = (doc: Doc, location: string) => { + public static AddDocTab = (doc: Doc, location: string, layoutTemplate?: Doc) => { SelectionManager.DeselectAll(); return LightboxView.SetLightboxDoc(doc, undefined, [...DocListCast(doc[Doc.LayoutFieldKey(doc)]), ...DocListCast(doc[Doc.LayoutFieldKey(doc) + "-annotations"]), ...(LightboxView._future ?? []) - ].sort((a: Doc, b: Doc) => NumCast(b._timecodeToShow) - NumCast(a._timecodeToShow))); + ].sort((a: Doc, b: Doc) => NumCast(b._timecodeToShow) - NumCast(a._timecodeToShow)), layoutTemplate); } docFilters = () => LightboxView._docFilters || []; addDocTab = LightboxView.AddDocTab; @@ -229,6 +232,7 @@ export class LightboxView extends React.Component { })} Document={LightboxView.LightboxDoc} DataDoc={undefined} + LayoutTemplate={LightboxView.LightboxDocTemplate} addDocument={undefined} fitContentsToDoc={this.fitToBox} isDocumentActive={returnFalse} diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 4417038fa..983c3732f 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -9,7 +9,7 @@ import * as ReactDOM from 'react-dom'; import { DataSym, Doc, DocListCast, DocListCastAsync, HeightSym, Opt, WidthSym } from "../../../fields/Doc"; import { Id } from '../../../fields/FieldSymbols'; import { FieldId } from "../../../fields/RefField"; -import { Cast, NumCast, StrCast } from "../../../fields/Types"; +import { Cast, NumCast, StrCast, BoolCast } from "../../../fields/Types"; import { TraceMobx } from '../../../fields/util'; import { emptyFunction, returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents, Utils } from "../../../Utils"; import { DocServer } from "../../DocServer"; @@ -299,6 +299,8 @@ export class TabDocView extends React.Component { PanelHeight = () => this._panelHeight; miniMapColor = () => this.tabColor; tabView = () => this._view; + disableMinimap = () => !this._document || (this._document.layout !== CollectionView.LayoutString(Doc.LayoutFieldKey(this._document)) || this._document?._viewType !== CollectionViewType.Freeform); + hideMinimap = () => this.disableMinimap() || BoolCast(this._document?.hideMinimap); @computed get layerProvider() { return this._document && DefaultLayerProvider(this._document); } @computed get docView() { @@ -330,13 +332,14 @@ export class TabDocView extends React.Component { bringToFront={emptyFunction} pinToPres={TabDocView.PinDoc} /> - {"toggle minimap"}
    }> + {"toggle minimap"}
    }>
    e.stopPropagation()} onClick={action(e => { e.stopPropagation(); this._document!.hideMinimap = !this._document!.hideMinimap; })} >
    @@ -361,6 +364,7 @@ export class TabDocView extends React.Component { interface TabMinimapViewProps { document: Doc; + hideMinimap: () => boolean; tabView: () => DocumentView | undefined; addDocTab: (doc: Doc, where: string) => boolean; PanelWidth: () => number; @@ -411,7 +415,7 @@ export class TabMinimapView extends React.Component { const miniLeft = 50 + (NumCast(this.props.document._panX) - this.renderBounds.cx) / this.renderBounds.dim * 100 - miniWidth / 2; const miniTop = 50 + (NumCast(this.props.document._panY) - this.renderBounds.cy) / this.renderBounds.dim * 100 - miniHeight / 2; const miniSize = this.returnMiniSize(); - return this.props.document.hideMinimap ? (null) : + return this.props.hideMinimap() ? (null) :
    pair.layout).filter(layout => StrCast(layout._dimUnit, "*") === DimUnit.Ratio); } + @computed + private get minimumDim() { + return Math.min(...this.ratioDefinedDocs.filter(layout => layout._dimMagnitude).map(layout => NumCast(layout._dimMagnitude))); + } + /** * This loops through all childLayoutPairs and extracts the values for _dimUnit * and _dimMagnitude, ignoring any that are malformed. Additionally, it then @@ -63,7 +68,7 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu const widthSpecifiers: WidthSpecifier[] = []; this.childLayoutPairs.map(pair => { const unit = StrCast(pair.layout._dimUnit, "*"); - const magnitude = NumCast(pair.layout._dimMagnitude, 1); + const magnitude = NumCast(pair.layout._dimMagnitude, this.minimumDim); if (unit && magnitude && magnitude > 0 && resolvedUnits.includes(unit)) { (unit === DimUnit.Ratio) && (starSum += magnitude); widthSpecifiers.push({ magnitude, unit }); @@ -80,15 +85,15 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu * themselves to drift toward zero. Thus, whenever we change any of the values, * we normalize everything (dividing by the smallest magnitude). */ - setTimeout(() => { - const { ratioDefinedDocs } = this; - if (this.childLayoutPairs.length) { - const minimum = Math.min(...ratioDefinedDocs.map(doc => NumCast(doc._dimMagnitude, 1))); - if (minimum !== 0) { - ratioDefinedDocs.forEach(layout => layout._dimMagnitude = NumCast(layout._dimMagnitude, 1) / minimum, 1); - } - } - }); + // setTimeout(() => { + // const { ratioDefinedDocs } = this; + // if (this.childLayoutPairs.length) { + // const minimum = this.minimumDim; + // if (minimum !== 0) { + // ratioDefinedDocs.forEach(layout => layout._dimMagnitude = NumCast(layout._dimMagnitude, 1) / minimum, 1); + // } + // } + // }); return { widthSpecifiers, starSum }; } @@ -161,7 +166,7 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu if (columnUnitLength === undefined) { return 0; // we're still waiting on promises to resolve } - let width = NumCast(layout._dimMagnitude, 1); + let width = NumCast(layout._dimMagnitude, this.minimumDim); if (StrCast(layout._dimUnit, "*") === DimUnit.Ratio) { width *= columnUnitLength; } diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx index 40b155c34..29cb3511a 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx @@ -49,6 +49,11 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) return this.childLayoutPairs.map(pair => pair.layout).filter(layout => StrCast(layout._dimUnit, "*") === DimUnit.Ratio); } + @computed + private get minimumDim() { + return Math.min(...this.ratioDefinedDocs.filter(layout => layout._dimMagnitude).map(layout => NumCast(layout._dimMagnitude))); + } + /** * This loops through all childLayoutPairs and extracts the values for _dimUnit * and _dimUnit, ignoring any that are malformed. Additionally, it then @@ -63,7 +68,7 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) const heightSpecifiers: HeightSpecifier[] = []; this.childLayoutPairs.map(pair => { const unit = StrCast(pair.layout._dimUnit, "*"); - const magnitude = NumCast(pair.layout._dimMagnitude, 1); + const magnitude = NumCast(pair.layout._dimMagnitude, this.minimumDim); if (unit && magnitude && magnitude > 0 && resolvedUnits.includes(unit)) { (unit === DimUnit.Ratio) && (starSum += magnitude); heightSpecifiers.push({ magnitude, unit }); @@ -80,15 +85,15 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) * themselves to drift toward zero. Thus, whenever we change any of the values, * we normalize everything (dividing by the smallest magnitude). */ - setTimeout(() => { - const { ratioDefinedDocs } = this; - if (this.childLayoutPairs.length) { - const minimum = Math.min(...ratioDefinedDocs.map(layout => NumCast(layout._dimMagnitude, 1))); - if (minimum !== 0) { - ratioDefinedDocs.forEach(layout => layout._dimMagnitude = NumCast(layout._dimMagnitude, 1) / minimum); - } - } - }); + // setTimeout(() => { + // const { ratioDefinedDocs } = this; + // if (this.childLayoutPairs.length) { + // const minimum = Math.min(...ratioDefinedDocs.map(layout => NumCast(layout._dimMagnitude, 1))); + // if (minimum !== 0) { + // ratioDefinedDocs.forEach(layout => layout._dimMagnitude = NumCast(layout._dimMagnitude, 1) / minimum); + // } + // } + // }); return { heightSpecifiers, starSum }; } @@ -161,7 +166,7 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) if (rowUnitLength === undefined) { return 0; // we're still waiting on promises to resolve } - let height = NumCast(layout._dimMagnitude, 1); + let height = NumCast(layout._dimMagnitude, this.minimumDim); if (StrCast(layout._dimUnit, "*") === DimUnit.Ratio) { height *= rowUnitLength; } @@ -261,7 +266,9 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) const height = () => this.lookupPixels(layout); const width = () => PanelWidth() - 2 * NumCast(Document._xMargin) - (BoolCast(Document.showWidthLabels) ? 20 : 0); collector.push( -
    +
    {this.getDisplayDoc(layout, dxf, width, height)}
    , diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 5e97b07f0..857d06ea7 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -200,7 +200,7 @@ export class DocumentViewInternal extends DocComponent func().result?.select === true ? this.props.select(false) : "", "on double click"); } else if (!Doc.IsSystem(this.rootDoc)) { - if (this.props.Document.type !== DocumentType.LABEL) { - UndoManager.RunInBatch(() => this.props.addDocTab((this.rootDoc._fullScreenView as Doc) || this.rootDoc, "lightbox"), "double tap"); - SelectionManager.DeselectAll(); - } + UndoManager.RunInBatch(() => + LightboxView.AddDocTab(this.rootDoc, "lightbox", this.props.LayoutTemplate?.()) + //this.props.addDocTab((this.rootDoc._fullScreenView as Doc) || this.rootDoc, "lightbox") + , "double tap"); + SelectionManager.DeselectAll(); Doc.UnBrushDoc(this.props.Document); } } else if (this.onClickHandler?.script && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes(ScriptingBox.name)) { // bcz: hack? don't execute script if you're clicking on a scripting box itself diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index ea854ebe7..8039e777e 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1064,8 +1064,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp }); } setupEditor(config: any, fieldKey: string) { - const curText = Cast(this.dataDoc[this.props.fieldKey], RichTextField, null); - const rtfField = Cast((!curText?.Text && this.layoutDoc[this.props.fieldKey]) || this.dataDoc[fieldKey], RichTextField); + const curText = Cast(this.dataDoc[this.props.fieldKey], RichTextField, null) || StrCast(this.dataDoc[this.props.fieldKey]); + const rtfField = Cast((!curText && this.layoutDoc[this.props.fieldKey]) || this.dataDoc[fieldKey], RichTextField); if (this.ProseRef) { const self = this; this._editorView?.destroy(); @@ -1118,7 +1118,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const tr = this._editorView.state.tr.setStoredMarks(storedMarks).insertText(FormattedTextBox.SelectOnLoadChar, this._editorView.state.doc.content.size - 1, this._editorView.state.doc.content.size).setStoredMarks(storedMarks); this._editorView.dispatch(tr.setSelection(new TextSelection(tr.doc.resolve(tr.doc.content.size)))); FormattedTextBox.SelectOnLoadChar = ""; - } else if (curText?.Text && !FormattedTextBox.DontSelectInitialText) { + } else if (curText && !FormattedTextBox.DontSelectInitialText) { selectAll(this._editorView!.state, this._editorView?.dispatch); this.startUndoTypingBatch(); } -- cgit v1.2.3-70-g09d2 From e26e07f6956c1a4cb7593f66fc88f219b7349e05 Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 16 Apr 2021 15:44:23 -0400 Subject: addded documents as fields --- src/client/views/DocComponent.tsx | 2 +- src/client/views/DocumentDecorations.tsx | 27 +++++++++++++++++----- src/client/views/nodes/DocumentView.tsx | 15 ++++++++++++ .../views/nodes/formattedText/FormattedTextBox.tsx | 2 +- 4 files changed, 38 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index 3c565fd62..a878a7afb 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -182,7 +182,7 @@ export function ViewBoxAnnotatableComponent

    Doc.AreProtosEqual(doc, this.props.Document))) { + docs.find(doc => Doc.AreProtosEqual(doc, this.props.Document) && Doc.LayoutField(doc) === Doc.LayoutField(this.props.Document))) { return false; } const targetDataDoc = this.props.Document[DataSym]; diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index e23374cea..24ca3a8fa 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -8,7 +8,7 @@ import { Document } from '../../fields/documentSchemas'; import { HtmlField } from '../../fields/HtmlField'; import { InkField } from "../../fields/InkField"; import { ScriptField } from '../../fields/ScriptField'; -import { Cast, NumCast } from "../../fields/Types"; +import { Cast, NumCast, StrCast } from "../../fields/Types"; import { GetEffectiveAcl } from '../../fields/util'; import { setupMoveUpEvents, emptyFunction, returnFalse } from "../../Utils"; import { Docs, DocUtils } from "../documents/Documents"; @@ -26,6 +26,7 @@ import { InkStrokeProperties } from './InkStrokeProperties'; import { LightboxView } from './LightboxView'; import { DocumentView } from "./nodes/DocumentView"; import React = require("react"); +import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; @observer export class DocumentDecorations extends React.Component<{ boundsLeft: number, boundsTop: number }, { value: string }> { @@ -83,7 +84,21 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b UndoManager.RunInBatch(() => titleFieldKey && SelectionManager.Views().forEach(d => { titleFieldKey === "title" && (d.dataDoc["title-custom"] = !this._accumulatedTitle.startsWith("-")); //@ts-ignore - Doc.SetInPlace(d.rootDoc, titleFieldKey, +this._accumulatedTitle === this._accumulatedTitle ? +this._accumulatedTitle : this._accumulatedTitle, true); + const titleField = (+this._accumulatedTitle === this._accumulatedTitle ? +this._accumulatedTitle : this._accumulatedTitle); + Doc.SetInPlace(d.rootDoc, titleFieldKey, titleField, true); + + if (d.rootDoc.syncLayoutFieldWithTitle) { + const title = titleField.toString(); + const curKey = Doc.LayoutFieldKey(d.rootDoc); + if (curKey !== title && d.dataDoc[title] === undefined) { + d.rootDoc.layout = FormattedTextBox.LayoutString(title); + setTimeout(() => { + const val = d.dataDoc[curKey]; + d.dataDoc[curKey] = undefined; + d.dataDoc[title] = val; + }); + } + } }), "title blur"); } } @@ -376,10 +391,10 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b this._inkDragDocs.map(oldbds => ({ oldbds, inkPts: Cast(oldbds.doc.data, InkField)?.inkData || [] })) .forEach(({ oldbds: { doc, x, y, width, height }, inkPts }) => { Doc.GetProto(doc).data = new InkField(inkPts.map(ipt => // (new x — oldx) + newWidth * (oldxpoint /oldWidth) - ({ - X: (NumCast(doc.x) - x) + NumCast(doc.width) * ipt.X / width, - Y: (NumCast(doc.y) - y) + NumCast(doc.height) * ipt.Y / height - }))); + ({ + X: (NumCast(doc.x) - x) + NumCast(doc.width) * ipt.X / width, + Y: (NumCast(doc.y) - y) + NumCast(doc.height) * ipt.Y / height + }))); Doc.SetNativeWidth(doc, undefined); Doc.SetNativeHeight(doc, undefined); }); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 857d06ea7..01b83644e 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -47,6 +47,7 @@ import { PresBox } from './PresBox'; import { RadialMenu } from './RadialMenu'; import React = require("react"); import { ScriptingBox } from "./ScriptingBox"; +import { FormattedTextBox } from "./formattedText/FormattedTextBox"; const { Howl } = require('howler'); interface Window { @@ -670,6 +671,20 @@ export class DocumentViewInternal extends DocComponent this.props.addDocTab(templateDoc, "add:right"), icon: "eye" }); + appearanceItems.push({ + description: "Add a Field", event: () => { + const alias = Doc.MakeAlias(this.rootDoc); + alias.layout = FormattedTextBox.LayoutString("newfield"); + alias.title = "newfield"; + alias._yMargin = 10; + alias._height = 35; + alias._width = 100; + alias.syncLayoutFieldWithTitle = true; + alias.x = NumCast(this.rootDoc.x) + NumCast(this.rootDoc.width); + alias.y = NumCast(this.rootDoc.y); + this.props.addDocument?.(alias); + }, icon: "eye" + }); DocListCast(this.Document.links).length && appearanceItems.splice(0, 0, { description: `${this.layoutDoc.hideLinkButton ? "Show" : "Hide"} Link Button`, event: action(() => this.layoutDoc.hideLinkButton = !this.layoutDoc.hideLinkButton), icon: "eye" }); !appearance && cm.addItem({ description: "UI Controls...", subitems: appearanceItems, icon: "compass" }); diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 8039e777e..b98ec870a 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1556,7 +1556,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp onScroll={this.onScroll} onDrop={this.ondrop} >

    -- cgit v1.2.3-70-g09d2 From 8824730d44f52ad41c2687205109a271f8c63e80 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 19 Apr 2021 12:27:33 -0400 Subject: started to cleanup comic mode. --- src/client/views/StyleProvider.tsx | 1 - src/client/views/collections/TabDocView.tsx | 5 +++- .../nodes/CollectionFreeFormDocumentView.scss | 6 ++++ .../views/nodes/CollectionFreeFormDocumentView.tsx | 33 +++++++++++++--------- 4 files changed, 30 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index bde741959..0702f0d6b 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -101,7 +101,6 @@ export function DefaultStyleProvider(doc: Opt, props: Opt = StrCast(doc?.[fieldKey + "backgroundColor"], StrCast(doc?._backgroundColor, isCaption ? "rbga(0,0,0,0.4)" : "")); if (MainView.Instance.LastButton === doc) return darkScheme() ? "dimgrey" : "lightgrey"; switch (doc?.type) { diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 983c3732f..7e2f7811e 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -350,7 +350,10 @@ export class TabDocView extends React.Component { render() { this.tab && CollectionDockingView.Instance.tabMap.delete(this.tab); return ( -
    { +
    { if (this._mainCont = ref) { (this._mainCont as any).InitTab = (tab: any) => this.init(tab, this._document); DocServer.GetRefField(this.props.documentId).then(action(doc => doc instanceof Doc && (this._document = doc) && this.tab && this.init(this.tab, this._document))); diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.scss b/src/client/views/nodes/CollectionFreeFormDocumentView.scss index 724394025..98208c2a6 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.scss +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.scss @@ -6,4 +6,10 @@ top: 0; left: 0; pointer-events: none; + .collectionFreeFormDocumentView-comic { + width:100%; + height: 100%; + position: absolute; + top: 0; + } } \ No newline at end of file diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 1fda4cc5e..807a61094 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -37,10 +37,14 @@ export class CollectionFreeFormDocumentView extends DocComponent this.props.PanelHeight() ? 0.5 : 1); + return rot; + } random(min: number, max: number) { /* min should not be equal to max */ return min + ((Math.abs(this.X * this.Y) * 9301 + 49297) % 233280 / 233280) * (max - min); } get displayName() { return "CollectionFreeFormDocumentView(" + this.rootDoc.title + ")"; } // this makes mobx trace() statements more descriptive get maskCentering() { return this.props.Document.isInkMask ? InkingStroke.MaskDim / 2 : 0; } - get transform() { return `translate(${this.X - this.maskCentering}px, ${this.Y - this.maskCentering}px) rotate(${this.random(-1, 1) * this.props.jitterRotation}deg)`; } + get transform() { return `translate(${this.X - this.maskCentering}px, ${this.Y - this.maskCentering}px) rotate(${this.jitterRotation}deg)`; } get X() { return this.dataProvider ? this.dataProvider.x : (this.Document.x || 0); } get Y() { return this.dataProvider ? this.dataProvider.y : (this.Document.y || 0); } get ZInd() { return this.dataProvider ? this.dataProvider.zIndex : (this.Document.zIndex || 0); } @@ -156,7 +160,9 @@ export class CollectionFreeFormDocumentView extends DocComponent this; render() { TraceMobx(); - const backgroundColor = () => this.props.styleProvider?.(this.Document, this.props, StyleProp.BackgroundColor); + const pw = this.panelWidth(); + const ph = this.panelHeight(); + const path = `M ${pw * .5} ${ph * .05} C ${pw * .6} ${ph * .05} ${pw * .9} 0 ${pw * .95} ${ph * .05} C ${pw} ${ph * .1} ${pw * .95} ${ph * .2} ${pw * .95} ${ph * .25} C ${pw * .95} ${ph * .35} ${pw} ${ph * .9} ${pw * .95} ${ph * .95} C ${pw * .9} ${ph} ${pw * .6} ${ph * .95} ${pw * .5} ${ph * .95} C ${pw * .3} ${ph * .95} ${pw * .1} ${ph} ${pw * .05} ${ph * .95} C 0 ${ph * .9} ${pw * .05} ${ph * .85} ${pw * .05} ${ph * .8} C ${pw * .05} ${ph * .75} 0 ${ph * .1} ${pw * .05} ${ph * .05} C ${pw * .1} 0 ${pw * .25} ${ph * .05} ${pw * .5} ${ph * .05}`; const divProps: DocumentViewProps = { ...this.props, CollectionFreeFormDocumentView: this.returnThis, @@ -175,18 +181,19 @@ export class CollectionFreeFormDocumentView extends DocComponent - - {Doc.UserDoc().renderStyle !== "comic" ? (null) : -
    - - - -
    } - - this._contentView = r)} /> + {Doc.UserDoc().renderStyle !== "comic" ? this._contentView = r)} /> : + <> +
    + this._contentView = r)} /> +
    +
    + + + +
    + }
    ; } } -- cgit v1.2.3-70-g09d2 From b7296ff9e0cf083ef1ae3423aa307e0dedf56f94 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 19 Apr 2021 16:10:19 -0400 Subject: more improvements to comic mode. --- src/client/util/CurrentUserUtils.ts | 2 ++ src/client/views/MainView.tsx | 7 +++---- src/client/views/StyleProvider.tsx | 12 ++++++++++-- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- .../nodes/CollectionFreeFormDocumentView.scss | 6 ------ .../views/nodes/CollectionFreeFormDocumentView.tsx | 22 ++-------------------- src/client/views/nodes/DocumentView.scss | 7 +++++++ src/client/views/nodes/DocumentView.tsx | 14 +++++++++++++- 8 files changed, 38 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index cb8bf5a7f..b1b7f8a09 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1242,3 +1242,5 @@ Scripting.addGlobal(function links(doc: any) { return new List(LinkManager.Insta "returns all the links to the document or its annotations", "(doc: any)"); Scripting.addGlobal(function importDocument() { return CurrentUserUtils.importDocument(); }, "imports files from device directly into the import sidebar"); +Scripting.addGlobal(function toggleComicMode() { Doc.UserDoc().renderStyle = Doc.UserDoc().renderStyle === "comic" ? undefined : "comic"; }, + "toggle between regular rendeing and an informal sketch/comic style"); diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index fa2a738c8..e54d84a6c 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -180,8 +180,8 @@ export class MainView extends React.Component { const targClass = targets[0].className.toString(); if (SearchBox.Instance._searchbarOpen || SearchBox.Instance.open) { const check = targets.some((thing) => - (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" || - thing.className === "collectionSchema-header-menuOptions")); + (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" || + thing.className === "collectionSchema-header-menuOptions")); !check && SearchBox.Instance.resetSearch(true); } !targClass.includes("contextMenu") && ContextMenu.Instance.closeMenu(); @@ -704,5 +704,4 @@ 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"; }); \ No newline at end of file +Scripting.addGlobal(function selectMainMenu(doc: Doc, title: string) { MainView.Instance.selectMenu(doc); }); \ No newline at end of file diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 0702f0d6b..a9fcd4717 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -41,6 +41,8 @@ export enum StyleProp { HeaderMargin = "headerMargin", // margin at top of documentview, typically for displaying a title -- doc contents will start below that TitleHeight = "titleHeight", // Height of Title area ShowTitle = "showTitle", // whether to display a title on a Document (optional :hover suffix) + JitterRotation = "jitterRotation", // whether documents should be randomly rotated + BorderPath = "customBorder", // border path for document view } function darkScheme() { return BoolCast(CurrentUserUtils.ActiveDashboard?.darkScheme); } @@ -60,7 +62,10 @@ export function testDocProps(toBeDetermined: any): toBeDetermined is DocumentVie return (toBeDetermined?.isContentActive) ? toBeDetermined : undefined; } -// +function wavyBorderPath(pw: number, ph: number) { + return `M ${pw * .5} ${ph * .05} C ${pw * .6} ${ph * .05} ${pw * .9} 0 ${pw * .95} ${ph * .05} C ${pw} ${ph * .1} ${pw * .95} ${ph * .2} ${pw * .95} ${ph * .25} C ${pw * .95} ${ph * .35} ${pw} ${ph * .9} ${pw * .95} ${ph * .95} C ${pw * .9} ${ph} ${pw * .6} ${ph * .95} ${pw * .5} ${ph * .95} C ${pw * .3} ${ph * .95} ${pw * .1} ${ph} ${pw * .05} ${ph * .95} C 0 ${ph * .9} ${pw * .05} ${ph * .85} ${pw * .05} ${ph * .8} C ${pw * .05} ${ph * .75} 0 ${ph * .1} ${pw * .05} ${ph * .05} C ${pw * .1} 0 ${pw * .25} ${ph * .05} ${pw * .5} ${ph * .05}`; +} + // a preliminary implementation of a dash style sheet for setting rendering properties of documents nested within a Tab // export function DefaultStyleProvider(doc: Opt, props: Opt, property: string): any { @@ -71,11 +76,12 @@ export function DefaultStyleProvider(doc: Opt, props: Opt doc && !Doc.IsSystem(doc) && Doc.UserDoc().renderStyle === "comic"; const isBackground = () => StrListCast(doc?._layerTags).includes(StyleLayers.Background); const backgroundCol = () => props?.styleProvider?.(doc, props, StyleProp.BackgroundColor); const opacity = () => props?.styleProvider?.(doc, props, StyleProp.Opacity); const showTitle = () => props?.styleProvider?.(doc, props, StyleProp.ShowTitle); - + const random = (min: number, max: number, x: number, y: number) => { /* min should not be equal to max */ return min + ((Math.abs(x * y) * 9301 + 49297) % 233280 / 233280) * (max - min); } switch (property.split(":")[0]) { case StyleProp.TreeViewIcon: return Doc.toIcon(doc, isOpen); case StyleProp.DocContents: return undefined; @@ -98,6 +104,8 @@ export function DefaultStyleProvider(doc: Opt, props: Opt (props?.PanelHeight() || 0) ? 5 : 10) : 0; case StyleProp.HeaderMargin: return ([CollectionViewType.Stacking, CollectionViewType.Masonry].includes(doc?._viewType as any) || doc?.type === DocumentType.RTF) && showTitle() && !StrCast(doc?.showTitle).includes(":hover") ? 15 : 0; case StyleProp.BackgroundColor: { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 7a879ecde..407216217 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1051,7 +1051,7 @@ export class CollectionFreeFormView extends CollectionSubView; } diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.scss b/src/client/views/nodes/CollectionFreeFormDocumentView.scss index 98208c2a6..724394025 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.scss +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.scss @@ -6,10 +6,4 @@ top: 0; left: 0; pointer-events: none; - .collectionFreeFormDocumentView-comic { - width:100%; - height: 100%; - position: absolute; - top: 0; - } } \ No newline at end of file diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 807a61094..092823603 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -37,14 +37,9 @@ export class CollectionFreeFormDocumentView extends DocComponent this.props.PanelHeight() ? 0.5 : 1); - return rot; - } - random(min: number, max: number) { /* min should not be equal to max */ return min + ((Math.abs(this.X * this.Y) * 9301 + 49297) % 233280 / 233280) * (max - min); } get displayName() { return "CollectionFreeFormDocumentView(" + this.rootDoc.title + ")"; } // this makes mobx trace() statements more descriptive get maskCentering() { return this.props.Document.isInkMask ? InkingStroke.MaskDim / 2 : 0; } - get transform() { return `translate(${this.X - this.maskCentering}px, ${this.Y - this.maskCentering}px) rotate(${this.jitterRotation}deg)`; } + get transform() { return `translate(${this.X - this.maskCentering}px, ${this.Y - this.maskCentering}px) rotate(${this.props.jitterRotation}deg)`; } get X() { return this.dataProvider ? this.dataProvider.x : (this.Document.x || 0); } get Y() { return this.dataProvider ? this.dataProvider.y : (this.Document.y || 0); } get ZInd() { return this.dataProvider ? this.dataProvider.zIndex : (this.Document.zIndex || 0); } @@ -160,9 +155,6 @@ export class CollectionFreeFormDocumentView extends DocComponent this; render() { TraceMobx(); - const pw = this.panelWidth(); - const ph = this.panelHeight(); - const path = `M ${pw * .5} ${ph * .05} C ${pw * .6} ${ph * .05} ${pw * .9} 0 ${pw * .95} ${ph * .05} C ${pw} ${ph * .1} ${pw * .95} ${ph * .2} ${pw * .95} ${ph * .25} C ${pw * .95} ${ph * .35} ${pw} ${ph * .9} ${pw * .95} ${ph * .95} C ${pw * .9} ${ph} ${pw * .6} ${ph * .95} ${pw * .5} ${ph * .95} C ${pw * .3} ${ph * .95} ${pw * .1} ${ph} ${pw * .05} ${ph * .95} C 0 ${ph * .9} ${pw * .05} ${ph * .85} ${pw * .05} ${ph * .8} C ${pw * .05} ${ph * .75} 0 ${ph * .1} ${pw * .05} ${ph * .05} C ${pw * .1} 0 ${pw * .25} ${ph * .05} ${pw * .5} ${ph * .05}`; const divProps: DocumentViewProps = { ...this.props, CollectionFreeFormDocumentView: this.returnThis, @@ -183,17 +175,7 @@ export class CollectionFreeFormDocumentView extends DocComponent - {Doc.UserDoc().renderStyle !== "comic" ? this._contentView = r)} /> : - <> -
    - this._contentView = r)} /> -
    -
    - - - -
    - } + this._contentView = r)} />
    ; } } diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss index 36572b861..bdbece621 100644 --- a/src/client/views/nodes/DocumentView.scss +++ b/src/client/views/nodes/DocumentView.scss @@ -4,6 +4,13 @@ border-radius: inherit; } +.documentView-customBorder { + width:100%; + height: 100%; + position: absolute; + top: 0; +} + .documentView-node, .documentView-node-topmost { position: inherit; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 01b83644e..810868c75 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -978,6 +978,8 @@ export class DocumentViewInternal extends DocComponent - {PresBox.EffectsProvider(this.layoutDoc, this.renderDoc) || this.renderDoc} + {!borderPath.path ? internal : + <> + {internal} +
    + + + +
    + + }
    ; } } -- cgit v1.2.3-70-g09d2 From 0e9a512020c145a11357aac8573dd6cb24197748 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 19 Apr 2021 19:17:17 -0400 Subject: fixed crash with lightboxview and stepping into an image. --- src/client/views/nodes/ImageBox.tsx | 44 ++++++++++++++++++------------------- src/client/views/nodes/VideoBox.tsx | 21 +++++++++--------- 2 files changed, 33 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 1ab367395..c7067f313 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -1,14 +1,13 @@ -import { action, computed, IReactionDisposer, observable, reaction, runInAction, ObservableMap, untracked } from 'mobx'; +import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from 'mobx'; import { observer } from "mobx-react"; -import { Dictionary } from 'typescript-collections'; import { DataSym, Doc, DocListCast, WidthSym } from '../../../fields/Doc'; import { documentSchema } from '../../../fields/documentSchemas'; import { Id } from '../../../fields/FieldSymbols'; import { List } from '../../../fields/List'; import { ObjectField } from '../../../fields/ObjectField'; -import { createSchema, listSpec, makeInterface } from '../../../fields/Schema'; +import { createSchema, makeInterface } from '../../../fields/Schema'; import { ComputedField } from '../../../fields/ScriptField'; -import { Cast, NumCast, StrCast } from '../../../fields/Types'; +import { Cast, NumCast } from '../../../fields/Types'; import { ImageField } from '../../../fields/URLField'; import { TraceMobx } from '../../../fields/util'; import { emptyFunction, OmitKeys, returnOne, Utils } from '../../../Utils'; @@ -59,8 +58,12 @@ export class ImageBox extends ViewBoxAnnotatableComponent { + + } // sets viewing information for a componentview, typically when following a link. 'preview' tells the view to use the values without writing to the document componentDidMount() { + this.props.setContentView?.(this); // bcz: do not remove this. without it, stepping into an image in the lightbox causes an infinite loop.... this._disposers.sizer = reaction(() => ( { forceFull: this.props.renderDepth < 1 || this.layoutDoc._showFullRes, @@ -315,6 +318,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent(); @computed get annotationLayer() { + TraceMobx(); return
    ; } @action @@ -331,7 +335,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent + scaling={returnOne} + whenChildContentsActiveChanged={this.whenChildContentsActiveChanged} + removeDocument={this.removeDocument} + moveDocument={this.moveDocument} + addDocument={this.addDocument}> {this.contentFunc} {this.annotationLayer} {!this._marqueeing || !this._mainCont.current || !this._annotationLayer.current ? (null) : -
    + addDocument={this.addDocWithTimecode}> {this.contentFunc}
    @@ -591,16 +591,17 @@ export class VideoBox extends ViewBoxAnnotatableComponent}
    ); -- cgit v1.2.3-70-g09d2 From f716a679d8abad1c26088cf5f8795cb745da18b0 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 20 Apr 2021 10:25:25 -0400 Subject: added a possible border for comic mode but commented out. --- src/client/views/StyleProvider.tsx | 6 +++--- src/client/views/nodes/DocumentView.tsx | 7 +++++-- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index a9fcd4717..95c5c8502 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -62,8 +62,8 @@ export function testDocProps(toBeDetermined: any): toBeDetermined is DocumentVie return (toBeDetermined?.isContentActive) ? toBeDetermined : undefined; } -function wavyBorderPath(pw: number, ph: number) { - return `M ${pw * .5} ${ph * .05} C ${pw * .6} ${ph * .05} ${pw * .9} 0 ${pw * .95} ${ph * .05} C ${pw} ${ph * .1} ${pw * .95} ${ph * .2} ${pw * .95} ${ph * .25} C ${pw * .95} ${ph * .35} ${pw} ${ph * .9} ${pw * .95} ${ph * .95} C ${pw * .9} ${ph} ${pw * .6} ${ph * .95} ${pw * .5} ${ph * .95} C ${pw * .3} ${ph * .95} ${pw * .1} ${ph} ${pw * .05} ${ph * .95} C 0 ${ph * .9} ${pw * .05} ${ph * .85} ${pw * .05} ${ph * .8} C ${pw * .05} ${ph * .75} 0 ${ph * .1} ${pw * .05} ${ph * .05} C ${pw * .1} 0 ${pw * .25} ${ph * .05} ${pw * .5} ${ph * .05}`; +function wavyBorderPath(pw: number, ph: number, inset: number = 0.05) { + return `M ${pw * .5} ${ph * inset} C ${pw * .6} ${ph * inset} ${pw * (1 - 2 * inset)} 0 ${pw * (1 - inset)} ${ph * inset} C ${pw} ${ph * (2 * inset)} ${pw * (1 - inset)} ${ph * .25} ${pw * (1 - inset)} ${ph * .3} C ${pw * (1 - inset)} ${ph * .4} ${pw} ${ph * (1 - 2 * inset)} ${pw * (1 - inset)} ${ph * (1 - inset)} C ${pw * (1 - 2 * inset)} ${ph} ${pw * .6} ${ph * (1 - inset)} ${pw * .5} ${ph * (1 - inset)} C ${pw * .3} ${ph * (1 - inset)} ${pw * (2 * inset)} ${ph} ${pw * inset} ${ph * (1 - inset)} C 0 ${ph * (1 - 2 * inset)} ${pw * inset} ${ph * .8} ${pw * inset} ${ph * .75} C ${pw * inset} ${ph * .7} 0 ${ph * (2 * inset)} ${pw * inset} ${ph * inset} C ${pw * (2 * inset)} 0 ${pw * .25} ${ph * inset} ${pw * .5} ${ph * inset}`; } // a preliminary implementation of a dash style sheet for setting rendering properties of documents nested within a Tab @@ -104,7 +104,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt (props?.PanelHeight() || 0) ? 5 : 10) : 0; case StyleProp.HeaderMargin: return ([CollectionViewType.Stacking, CollectionViewType.Masonry].includes(doc?._viewType as any) || doc?.type === DocumentType.RTF) && showTitle() && !StrCast(doc?.showTitle).includes(":hover") ? 15 : 0; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 810868c75..903ce3acb 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -995,12 +995,15 @@ export class DocumentViewInternal extends DocComponent {!borderPath.path ? internal : <> + {/*
    + {internal} +
    */} {internal} -
    +
    -- cgit v1.2.3-70-g09d2 From 484ec015ff061d78d6ae9a7ec474d83315aaaebb Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 20 Apr 2021 13:58:56 -0400 Subject: made lightbox fit comic mode too. --- src/client/views/LightboxView.tsx | 5 +++-- src/client/views/StyleProvider.tsx | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index 9c03b457b..ce36d9182 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -14,7 +14,7 @@ import { Transform } from '../util/Transform'; import { TabDocView } from './collections/TabDocView'; import "./LightboxView.scss"; import { DocumentView, ViewAdjustment } from './nodes/DocumentView'; -import { DefaultStyleProvider } from './StyleProvider'; +import { DefaultStyleProvider, wavyBorderPath } from './StyleProvider'; interface LightboxViewProps { PanelWidth: number; @@ -217,7 +217,8 @@ export class LightboxView extends React.Component { left: this.leftBorder, top: this.topBorder, width: this.lightboxWidth(), - height: this.lightboxHeight() + height: this.lightboxHeight(), + clipPath: `path('${Doc.UserDoc().renderStyle === "comic" ? wavyBorderPath(this.lightboxWidth(), this.lightboxHeight()) : undefined}')` }}> { LightboxView._docView = r !== null ? r : undefined; diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 95c5c8502..a1b3027c4 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -62,7 +62,7 @@ export function testDocProps(toBeDetermined: any): toBeDetermined is DocumentVie return (toBeDetermined?.isContentActive) ? toBeDetermined : undefined; } -function wavyBorderPath(pw: number, ph: number, inset: number = 0.05) { +export function wavyBorderPath(pw: number, ph: number, inset: number = 0.05) { return `M ${pw * .5} ${ph * inset} C ${pw * .6} ${ph * inset} ${pw * (1 - 2 * inset)} 0 ${pw * (1 - inset)} ${ph * inset} C ${pw} ${ph * (2 * inset)} ${pw * (1 - inset)} ${ph * .25} ${pw * (1 - inset)} ${ph * .3} C ${pw * (1 - inset)} ${ph * .4} ${pw} ${ph * (1 - 2 * inset)} ${pw * (1 - inset)} ${ph * (1 - inset)} C ${pw * (1 - 2 * inset)} ${ph} ${pw * .6} ${ph * (1 - inset)} ${pw * .5} ${ph * (1 - inset)} C ${pw * .3} ${ph * (1 - inset)} ${pw * (2 * inset)} ${ph} ${pw * inset} ${ph * (1 - inset)} C 0 ${ph * (1 - 2 * inset)} ${pw * inset} ${ph * .8} ${pw * inset} ${ph * .75} C ${pw * inset} ${ph * .7} 0 ${ph * (2 * inset)} ${pw * inset} ${ph * inset} C ${pw * (2 * inset)} 0 ${pw * .25} ${ph * inset} ${pw * .5} ${ph * inset}`; } @@ -76,7 +76,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt doc && !Doc.IsSystem(doc) && Doc.UserDoc().renderStyle === "comic"; + const comicStyle = () => doc && props?.renderDepth && !Doc.IsSystem(doc) && Doc.UserDoc().renderStyle === "comic"; const isBackground = () => StrListCast(doc?._layerTags).includes(StyleLayers.Background); const backgroundCol = () => props?.styleProvider?.(doc, props, StyleProp.BackgroundColor); const opacity = () => props?.styleProvider?.(doc, props, StyleProp.Opacity); -- cgit v1.2.3-70-g09d2 From 45a43e9f0417d6929a6f351fea0cf97fe11b0ef0 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 20 Apr 2021 14:13:56 -0400 Subject: fixed toggling out of comic mode. --- src/client/views/StyleProvider.tsx | 4 ++-- src/client/views/nodes/DocumentView.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index a1b3027c4..96f9eab97 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -76,7 +76,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt doc && props?.renderDepth && !Doc.IsSystem(doc) && Doc.UserDoc().renderStyle === "comic"; + const comicStyle = () => doc && !Doc.IsSystem(doc) && Doc.UserDoc().renderStyle === "comic"; const isBackground = () => StrListCast(doc?._layerTags).includes(StyleLayers.Background); const backgroundCol = () => props?.styleProvider?.(doc, props, StyleProp.BackgroundColor); const opacity = () => props?.styleProvider?.(doc, props, StyleProp.Opacity); @@ -104,7 +104,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt (props?.PanelHeight() || 0) ? 5 : 10) : 0; case StyleProp.HeaderMargin: return ([CollectionViewType.Stacking, CollectionViewType.Masonry].includes(doc?._viewType as any) || doc?.type === DocumentType.RTF) && showTitle() && !StrCast(doc?.showTitle).includes(":hover") ? 15 : 0; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 903ce3acb..7f6905042 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -995,7 +995,7 @@ export class DocumentViewInternal extends DocComponent {!borderPath.path ? internal : <> -- cgit v1.2.3-70-g09d2