aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/DocumentDecorations.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/DocumentDecorations.tsx')
-rw-r--r--src/client/views/DocumentDecorations.tsx107
1 files changed, 76 insertions, 31 deletions
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 528b82e3e..dcfaecbc1 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -5,34 +5,35 @@ import { IconButton } from 'browndash-components';
import { action, computed, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import { FaUndo } from 'react-icons/fa';
+import { Utils, aggregateBounds, emptyFunction, numberValue, returnFalse, setupMoveUpEvents } from '../../Utils';
import { DateField } from '../../fields/DateField';
-import { Doc, DocListCast, Field } from '../../fields/Doc';
-import { AclAdmin, AclEdit, DocData, Height, Width } from '../../fields/DocSymbols';
+import { Doc, DocListCast, Field, HierarchyMapping, ReverseHierarchyMap } from '../../fields/Doc';
+import { AclAdmin, AclAugment, AclEdit, DocData, Height, Width } from '../../fields/DocSymbols';
import { InkField } from '../../fields/InkField';
import { RichTextField } from '../../fields/RichTextField';
import { ScriptField } from '../../fields/ScriptField';
import { Cast, DocCast, NumCast, StrCast } from '../../fields/Types';
-import { GetEffectiveAcl } from '../../fields/util';
-import { aggregateBounds, emptyFunction, numberValue, returnFalse, setupMoveUpEvents, Utils } from '../../Utils';
-import { Docs } from '../documents/Documents';
+import { GetEffectiveAcl, normalizeEmail, SharingPermissions } from '../../fields/util';
import { DocumentType } from '../documents/DocumentTypes';
+import { Docs } from '../documents/Documents';
import { DocumentManager } from '../util/DocumentManager';
import { DragManager } from '../util/DragManager';
import { LinkFollower } from '../util/LinkFollower';
import { SelectionManager } from '../util/SelectionManager';
+import { SettingsManager } from '../util/SettingsManager';
import { SnappingManager } from '../util/SnappingManager';
import { UndoManager } from '../util/UndoManager';
-import { CollectionDockingView } from './collections/CollectionDockingView';
-import { CollectionFreeFormView } from './collections/collectionFreeForm';
import { DocumentButtonBar } from './DocumentButtonBar';
import './DocumentDecorations.scss';
-import { Colors } from './global/globalEnums';
-import { InkingStroke } from './InkingStroke';
import { InkStrokeProperties } from './InkStrokeProperties';
+import { InkingStroke } from './InkingStroke';
import { LightboxView } from './LightboxView';
+import { CollectionDockingView } from './collections/CollectionDockingView';
+import { CollectionFreeFormView } from './collections/collectionFreeForm';
+import { Colors } from './global/globalEnums';
import { DocumentView, OpenWhereMod } from './nodes/DocumentView';
-import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
import { ImageBox } from './nodes/ImageBox';
+import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
import React = require('react');
import _ = require('lodash');
@@ -162,34 +163,48 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
};
@action onContainerDown = (e: React.PointerEvent): void => {
- setupMoveUpEvents(
- this,
- e,
- e => this.onBackgroundMove(true, e),
- e => {},
- emptyFunction
- );
+ const first = SelectionManager.Views()[0];
+ const effectiveAcl = GetEffectiveAcl(first.rootDoc);
+ console.log(effectiveAcl)
+ if (effectiveAcl == AclAdmin || effectiveAcl == AclEdit || effectiveAcl == AclAugment) {
+ setupMoveUpEvents(
+ this,
+ e,
+ e => this.onBackgroundMove(true, e),
+ e => {},
+ emptyFunction
+ );
+ }
};
@action onTitleDown = (e: React.PointerEvent): void => {
- setupMoveUpEvents(
- this,
- e,
- e => this.onBackgroundMove(true, e),
- e => {},
- action(e => {
- !this._editingTitle && (this._accumulatedTitle = this._titleControlString.startsWith('#') ? this.selectionTitle : this._titleControlString);
- this._editingTitle = true;
- this._keyinput.current && setTimeout(this._keyinput.current.focus);
- })
- );
+ const first = SelectionManager.Views()[0];
+ const effectiveAcl = GetEffectiveAcl(first.rootDoc);
+ if (effectiveAcl == AclAdmin || effectiveAcl == AclEdit || effectiveAcl == AclAugment) {
+ setupMoveUpEvents(
+ this,
+ e,
+ e => this.onBackgroundMove(true, e),
+ e => {},
+ action(e => {
+ !this._editingTitle && (this._accumulatedTitle = this._titleControlString.startsWith('#') ? this.selectionTitle : this._titleControlString);
+ this._editingTitle = true;
+ this._keyinput.current && setTimeout(this._keyinput.current.focus);
+ })
+ );
+ }
};
onBackgroundDown = (e: React.PointerEvent) => setupMoveUpEvents(this, e, e => this.onBackgroundMove(false, e), emptyFunction, emptyFunction);
@action
onBackgroundMove = (dragTitle: boolean, e: PointerEvent): boolean => {
- const dragDocView = SelectionManager.Views()[0];
+ const first = SelectionManager.Views()[0];
+ const effectiveAcl = GetEffectiveAcl(first.rootDoc);
+ if (effectiveAcl != AclAdmin && effectiveAcl != AclEdit && effectiveAcl != AclAugment){
+ return false;
+ }
+const dragDocView = SelectionManager.Views()[0];
const containers = new Set<Doc | undefined>();
SelectionManager.Views().forEach(v => containers.add(DocCast(v.rootDoc.embedContainer)));
if (containers.size > 1) return false;
@@ -481,6 +496,8 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
onPointerMove = (e: PointerEvent, down: number[], move: number[]): boolean => {
const first = SelectionManager.Views()[0];
+ const effectiveAcl = GetEffectiveAcl(first.rootDoc);
+ if (!(effectiveAcl == AclAdmin || effectiveAcl == AclEdit || effectiveAcl == AclAugment)) return false;
if (!first) return false;
let thisPt = { x: e.clientX - this._offX, y: e.clientY - this._offY };
var fixedAspect = Doc.NativeAspect(first.layoutDoc);
@@ -746,6 +763,12 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
setTimeout(action(() => (this._showNothing = true)));
return null;
}
+
+ // sharing
+ const docShareMode = HierarchyMapping.get(GetEffectiveAcl(seldocview.rootDoc))!.name
+ const shareMode = StrCast(docShareMode);
+ var shareSymbolIcon = ReverseHierarchyMap.get(shareMode)?.image;
+
// hide the decorations if the parent chooses to hide it or if the document itself hides it
const hideDecorations = seldocview.props.hideDecorations || seldocview.rootDoc.hideDecorations;
const hideResizers = hideDecorations || seldocview.props.hideResizeHandles || seldocview.rootDoc.layout_hideResizeHandles || this._isRounding || this._isRotating;
@@ -769,7 +792,6 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
const collectionAcl = docView.props.docViewPath()?.lastElement() ? GetEffectiveAcl(docView.props.docViewPath().lastElement().rootDoc[DocData]) : AclEdit;
return (docView.rootDoc.stayInCollection && !docView.rootDoc._isTimelineLabel) || (collectionAcl !== AclAdmin && collectionAcl !== AclEdit && GetEffectiveAcl(docView.rootDoc) !== AclAdmin);
});
-
const topBtn = (key: string, icon: string, pointerDown: undefined | ((e: React.PointerEvent) => void), click: undefined | ((e: any) => void), title: string) => (
<Tooltip key={key} title={<div className="dash-tooltip">{title}</div>} placement="top">
<div className={`documentDecorations-${key}Button`} onContextMenu={e => e.preventDefault()} onPointerDown={pointerDown ?? (e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, e => click!(e)))}>
@@ -802,6 +824,27 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
const radiusHandle = (borderRadius / docMax) * maxDist;
const radiusHandleLocation = Math.min(radiusHandle, maxDist);
+ const sharingMenu = docShareMode ? (
+ <div className='documentDecorations-share'
+ onPointerDown={e =>
+ setupMoveUpEvents(
+ this,
+ e,
+ e => this.onBackgroundMove(true, e),
+ returnFalse,
+ action(() => SettingsManager.propertiesWidth =250)
+ )
+ }>
+ <div className={`documentDecorations-share${shareMode}`}>
+ &nbsp;
+ <span>{shareSymbolIcon + ' ' + shareMode}</span>
+ &nbsp;
+ </div>
+ </div>
+ ) : (
+ <div />
+ );
+
const titleArea = this._editingTitle ? (
<input
ref={this._keyinput}
@@ -818,6 +861,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
) : (
<div className="documentDecorations-title" key="title" onPointerDown={this.onTitleDown}>
<span className={`documentDecorations-titleSpan${colorScheme}`}>{`${hideTitle ? '' : this.selectionTitle}`}</span>
+ {sharingMenu}
{!useLock ? null : (
<Tooltip key="lock" title={<div className="dash-tooltip">toggle ability to interact with document</div>} placement="top">
<div className="documentDecorations-lock" style={{ color: seldocview.rootDoc._lockedPosition ? 'red' : undefined }} onPointerDown={this.onLockDown} onContextMenu={e => e.preventDefault()}>
@@ -827,6 +871,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
)}
</div>
);
+
return (
<div className={`documentDecorations${colorScheme}`} style={{ opacity: this._showNothing ? 0.1 : undefined }}>
<div
@@ -860,7 +905,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
{hideDeleteButton ? null : topBtn('close', 'times', undefined, e => this.onCloseClick(true), 'Close')}
{hideResizers || hideDeleteButton ? null : topBtn('minimize', 'window-maximize', undefined, e => this.onCloseClick(undefined), 'Minimize')}
{hideTitle ? null : titleArea}
- {hideOpenButton ? null : topBtn('open', 'external-link-alt', this.onMaximizeDown, undefined, 'Open in Lightbox (ctrl: as new embedding, shift: in new collection)')}
+ {hideOpenButton ? <div /> : topBtn('open', 'external-link-alt', this.onMaximizeDown, undefined, 'Open in Lightbox (ctrl: as alias, shift: in new collection)')}
</div>
{hideResizers ? null : (
<>