aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorusodhi <61431818+usodhi@users.noreply.github.com>2020-11-26 19:53:57 +0530
committerusodhi <61431818+usodhi@users.noreply.github.com>2020-11-26 19:53:57 +0530
commit58b850cf84e258933cfc075e58311cd122e5fd0d (patch)
tree7c59ec7a089324b46f48229c0b7c912dbac666f6 /src
parent339316da8c4c3620f643e70c1844ca0680a5b89e (diff)
some sharing menu changes
Diffstat (limited to 'src')
-rw-r--r--src/client/util/SharingManager.tsx59
-rw-r--r--src/client/views/nodes/DocumentView.scss66
-rw-r--r--src/client/views/nodes/DocumentView.tsx22
3 files changed, 105 insertions, 42 deletions
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";
@@ -165,6 +165,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
* @param permission
@@ -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<DocumentViewProps, Document>(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<DocumentViewProps, Document>(Docu
{/* {this.allAnchors} */}
{this.props.forcedBackgroundColor?.(this.Document) === "transparent" || (!this.isSelected() && (this.layoutDoc.isLinkButton || this.layoutDoc.hideLinkButton)) || this.props.dontRegisterView ? (null) :
<DocumentLinksButton View={this} links={this.allLinks} Offset={this.linkOffset} />}
- </div>
+
+ {!this.props.Document.numUsersShared && !this.props.Document.numGroupsShared ? (null) :
+ <Tooltip title={<> <div className="dash-tooltip">Tap to open sharing menu</div></>}>
+ <div className="sharingIndicator" onPointerDown={() => SharingManager.Instance.open(undefined, this.props.Document)}>
+ <FontAwesomeIcon size="lg" icon={this.indicatorIcon} />
+ </div>
+ </Tooltip >
+
+ }
+ </div >
);
}
+ 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.