aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/PropertiesView.tsx
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2023-04-05 22:44:03 -0400
committerbobzel <zzzman@gmail.com>2023-04-05 22:44:03 -0400
commit9b41da1af16b982ee8ac2fc09f2f8b5d67eac9fb (patch)
treebc3f57cd5b31fd453d272c925f6d5b728ab63bae /src/client/views/PropertiesView.tsx
parent9dae453967183b294bf4f7444b948023a1d52d39 (diff)
parent8f7e99641f84ad15f34ba9e4a60b664ac93d2e5d (diff)
Merge branch 'master' into data-visualization-view-naafi
Diffstat (limited to 'src/client/views/PropertiesView.tsx')
-rw-r--r--src/client/views/PropertiesView.tsx653
1 files changed, 363 insertions, 290 deletions
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index ef0e057dc..fbc7d7696 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -1,13 +1,13 @@
import React = require('react');
import { IconLookup } from '@fortawesome/fontawesome-svg-core';
-import { faAnchor, faArrowRight } from '@fortawesome/free-solid-svg-icons';
+import { faAnchor, faArrowRight, faWindowMaximize } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Checkbox, Tooltip } from '@material-ui/core';
import { intersection } from 'lodash';
-import { action, autorun, computed, Lambda, observable } from 'mobx';
+import { action, computed, Lambda, observable } from 'mobx';
import { observer } from 'mobx-react';
import { ColorState, SketchPicker } from 'react-color';
-import { AclAdmin, AclAugment, AclEdit, AclPrivate, AclReadonly, AclSelfEdit, AclSym, AclUnset, DataSym, Doc, Field, HeightSym, NumListCast, Opt, StrListCast, WidthSym } from '../../fields/Doc';
+import { AclAdmin, AclSym, DataSym, Doc, Field, HeightSym, HierarchyMapping, NumListCast, Opt, StrListCast, WidthSym } from '../../fields/Doc';
import { Id } from '../../fields/FieldSymbols';
import { InkField } from '../../fields/InkField';
import { List } from '../../fields/List';
@@ -15,7 +15,7 @@ import { ComputedField } from '../../fields/ScriptField';
import { Cast, DocCast, NumCast, StrCast } from '../../fields/Types';
import { denormalizeEmail, GetEffectiveAcl, SharingPermissions } from '../../fields/util';
import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents } from '../../Utils';
-import { CollectionViewType, DocumentType } from '../documents/DocumentTypes';
+import { DocumentType } from '../documents/DocumentTypes';
import { DocumentManager } from '../util/DocumentManager';
import { LinkManager } from '../util/LinkManager';
import { SelectionManager } from '../util/SelectionManager';
@@ -23,11 +23,12 @@ import { SharingManager } from '../util/SharingManager';
import { Transform } from '../util/Transform';
import { undoBatch, UndoManager } from '../util/UndoManager';
import { EditableView } from './EditableView';
+import { FilterPanel } from './FilterPanel';
+import { Colors } from './global/globalEnums';
import { InkStrokeProperties } from './InkStrokeProperties';
-import { DocumentView, StyleProviderFunc } from './nodes/DocumentView';
-import { FilterBox } from './nodes/FilterBox';
+import { DocumentView, OpenWhere, StyleProviderFunc } from './nodes/DocumentView';
import { KeyValueBox } from './nodes/KeyValueBox';
-import { PresBox } from './nodes/trails';
+import { PresBox, PresEffect, PresEffectDirection } from './nodes/trails';
import { PropertiesButtons } from './PropertiesButtons';
import { PropertiesDocBacklinksSelector } from './PropertiesDocBacklinksSelector';
import { PropertiesDocContextSelector } from './PropertiesDocContextSelector';
@@ -42,7 +43,7 @@ interface PropertiesViewProps {
width: number;
height: number;
styleProvider?: StyleProviderFunc;
- addDocTab: (doc: Doc, where: string) => boolean;
+ addDocTab: (doc: Doc, where: OpenWhere) => boolean;
}
@observer
@@ -58,7 +59,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
}
@computed get selectedDocumentView() {
if (SelectionManager.Views().length) return SelectionManager.Views()[0];
- if (PresBox.Instance?._selectedArray.size) return DocumentManager.Instance.getDocumentView(PresBox.Instance.rootDoc);
+ if (PresBox.Instance?.selectedArray.size) return DocumentManager.Instance.getDocumentView(PresBox.Instance.rootDoc);
return undefined;
}
@computed get isPres(): boolean {
@@ -75,13 +76,13 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
@observable openOptions: boolean = true;
@observable openSharing: boolean = true;
- @observable openFields: boolean = true;
+ @observable openFields: boolean = false;
@observable openLayout: boolean = false;
@observable openContexts: boolean = true;
@observable openLinks: boolean = true;
@observable openAppearance: boolean = true;
@observable openTransform: boolean = true;
- @observable openFilters: boolean = true; // should be false
+ @observable openFilters: boolean = false;
/**
* autorun to set up the filter doc of a collection if that collection has been selected and the filters panel is open
@@ -93,18 +94,18 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
@observable layoutDocAcls: boolean = false;
//Pres Trails booleans:
- @observable openPresTransitions: boolean = false;
+ @observable openPresTransitions: boolean = true;
@observable openPresProgressivize: boolean = false;
+ @observable openPresVisibilityAndDuration: boolean = false;
@observable openAddSlide: boolean = false;
@observable openSlideOptions: boolean = false;
@observable inOptions: boolean = false;
@observable _controlButton: boolean = false;
- @observable _lock: boolean = false;
componentDidMount() {
this.selectedDocListenerDisposer?.();
- this.selectedDocListenerDisposer = autorun(() => this.openFilters && this.selectedDoc && this.checkFilterDoc());
+ // this.selectedDocListenerDisposer = autorun(() => this.openFilters && this.selectedDoc && this.checkFilterDoc());
}
componentWillUnmount() {
@@ -115,12 +116,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
return this.selectedDoc?.type === DocumentType.INK;
}
- rtfWidth = () => {
- return !this.selectedDoc ? 0 : Math.min(this.selectedDoc?.[WidthSym](), this.props.width - 20);
- };
- rtfHeight = () => {
- return !this.selectedDoc ? 0 : this.rtfWidth() <= this.selectedDoc?.[WidthSym]() ? Math.min(this.selectedDoc?.[HeightSym](), this.MAX_EMBED_HEIGHT) : this.MAX_EMBED_HEIGHT;
- };
+ rtfWidth = () => (!this.selectedDoc ? 0 : Math.min(this.selectedDoc?.[WidthSym](), this.props.width - 20));
+ rtfHeight = () => (!this.selectedDoc ? 0 : this.rtfWidth() <= this.selectedDoc?.[WidthSym]() ? Math.min(this.selectedDoc?.[HeightSym](), this.MAX_EMBED_HEIGHT) : this.MAX_EMBED_HEIGHT);
@action
docWidth = () => {
@@ -147,7 +144,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
: layoutDoc._fitWidth
? !Doc.NativeHeight(this.dataDoc)
? NumCast(this.props.height)
- : Math.min((this.docWidth() * NumCast(layoutDoc.scrollHeight, Doc.NativeHeight(layoutDoc))) / Doc.NativeWidth(layoutDoc) || NumCast(this.props.height))
+ : Math.min((this.docWidth() * Doc.NativeHeight(layoutDoc)) / Doc.NativeWidth(layoutDoc) || NumCast(this.props.height))
: NumCast(layoutDoc._height) || 50
)
);
@@ -310,7 +307,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
}
@computed get links() {
- return !this.selectedDoc ? null : <PropertiesDocBacklinksSelector Document={this.selectedDoc} hideTitle={true} addDocTab={this.props.addDocTab} />;
+ const selAnchor = this.selectedDocumentView?.anchorViewDoc ?? LinkManager.currentLinkAnchor ?? this.selectedDoc;
+ return !selAnchor ? null : <PropertiesDocBacklinksSelector Document={selAnchor} hideTitle={true} addDocTab={this.props.addDocTab} />;
}
@computed get layoutPreview() {
@@ -338,7 +336,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
NativeHeight={layoutDoc.type === DocumentType.RTF ? this.rtfHeight : undefined}
PanelWidth={panelWidth}
PanelHeight={panelHeight}
- focus={returnFalse}
+ focus={emptyFunction}
ScreenToLocalTransform={this.getTransform}
docFilters={returnEmptyFilter}
docRangeFilters={returnEmptyFilter}
@@ -367,7 +365,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
*/
@undoBatch
changePermissions = (e: any, user: string) => {
- const docs = SelectionManager.Views().length < 2 ? (this.selectedDoc ? [this.selectedDoc] : []) : SelectionManager.Views().map(docView => docView.props.Document);
+ const docs = (SelectionManager.Views().length < 2 ? [this.selectedDoc] : SelectionManager.Views().map(dv => dv.props.Document)).filter(doc => doc).map(doc => (this.layoutDocAcls ? doc : DocCast(doc)[DataSym]));
SharingManager.Instance.shareFromPropertiesSidebar(user, e.currentTarget.value as SharingPermissions, docs);
};
@@ -377,7 +375,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
getPermissionsSelect(user: string, permission: string) {
const dropdownValues: string[] = Object.values(SharingPermissions);
if (permission === '-multiple-') dropdownValues.unshift(permission);
- if (user === 'Override') dropdownValues.unshift('None');
+ if (user !== 'Override') dropdownValues.splice(dropdownValues.indexOf(SharingPermissions.Unset), 1);
return (
<select className="permissions-select" value={permission} onChange={e => this.changePermissions(e, user)}>
{dropdownValues
@@ -410,7 +408,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
*/
@computed get expansionIcon() {
return (
- <Tooltip title={<div className="dash-tooltip">{'Show more permissions'}</div>}>
+ <Tooltip title={<div className="dash-tooltip">Show more permissions</div>}>
<div
className="expansion-button"
onPointerDown={() => {
@@ -452,16 +450,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
* @returns the sharing and permissions panel.
*/
@computed get sharingTable() {
- const AclMap = new Map<symbol, string>([
- [AclUnset, 'None'],
- [AclPrivate, SharingPermissions.None],
- [AclReadonly, SharingPermissions.View],
- [AclAugment, SharingPermissions.Augment],
- [AclSelfEdit, SharingPermissions.SelfEdit],
- [AclEdit, SharingPermissions.Edit],
- [AclAdmin, SharingPermissions.Admin],
- ]);
-
// all selected docs
const docs =
SelectionManager.Views().length < 2 ? [this.layoutDocAcls ? this.selectedDoc : this.selectedDoc?.[DataSym]] : SelectionManager.Views().map(docView => (this.layoutDocAcls ? docView.props.Document : docView.props.Document[DataSym]));
@@ -473,7 +461,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
const showAdmin = effectiveAcls.every(acl => acl === AclAdmin);
// users in common between all docs
- const commonKeys: string[] = intersection(...docs.map(doc => (this.layoutDocAcls ? doc?.[AclSym] && Object.keys(doc[AclSym]) : doc?.[DataSym][AclSym] && Object.keys(doc[DataSym][AclSym]))));
+ const commonKeys: string[] = intersection(...docs.map(doc => doc?.[AclSym] && Object.keys(doc[AclSym]).filter(key => key !== 'acl-Me')));
const tableEntries = [];
@@ -481,9 +469,9 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
if (commonKeys.length) {
for (const key of commonKeys) {
const name = denormalizeEmail(key.substring(4));
- const uniform = docs.every(doc => (this.layoutDocAcls ? doc?.[AclSym]?.[key] === docs[0]?.[AclSym]?.[key] : doc?.[DataSym]?.[AclSym]?.[key] === docs[0]?.[DataSym]?.[AclSym]?.[key]));
+ const uniform = docs.every(doc => doc?.[AclSym]?.[key] === docs[0]?.[AclSym]?.[key]);
if (name !== Doc.CurrentUserEmail && name !== target.author && name !== 'Public' && name !== 'Override' /* && sidebarUsersDisplayed![name] !== false*/) {
- tableEntries.push(this.sharingItem(name, showAdmin, uniform ? AclMap.get(this.layoutDocAcls ? target[AclSym][key] : target[DataSym][AclSym][key])! : '-multiple-'));
+ tableEntries.push(this.sharingItem(name, showAdmin, uniform ? HierarchyMapping.get(target[AclSym][key])!.name : '-multiple-'));
}
}
}
@@ -491,11 +479,16 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
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('Public', showAdmin, docs.filter(doc => doc).every(doc => doc['acl-Public'] === docs[0]['acl-Public']) ? AclMap.get(target[AclSym]?.['acl-Public']) || SharingPermissions.None : '-multiple-'));
+ if (ownerSame) tableEntries.unshift(this.sharingItem(StrCast(target.author), showAdmin, 'Owner'));
+ tableEntries.unshift(this.sharingItem('Public', showAdmin, docs.filter(doc => doc).every(doc => doc['acl-Public'] === target['acl-Public']) ? target['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)
+ this.sharingItem(
+ 'Me',
+ showAdmin,
+ docs.filter(doc => doc).every(doc => doc.author === Doc.CurrentUserEmail) ? 'Owner' : effectiveAcls.every(acl => acl === effectiveAcls[0]) ? HierarchyMapping.get(effectiveAcls[0])!.name : '-multiple-',
+ !ownerSame
+ )
);
- if (ownerSame) tableEntries.unshift(this.sharingItem(StrCast(target.author), showAdmin, 'Owner'));
return <div className="propertiesView-sharingTable">{tableEntries}</div>;
}
@@ -592,16 +585,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
<FontAwesomeIcon icon="bezier-curve" color="white" size="lg" />
</div>
</Tooltip>
- <Tooltip title={<div className="dash-tooltip">{InkStrokeProperties.Instance._lock ? 'Unlock ratio' : 'Lock ratio'}</div>}>
- <div className="inking-button-lock" onPointerDown={action(() => (InkStrokeProperties.Instance._lock = !InkStrokeProperties.Instance._lock))}>
- <FontAwesomeIcon icon={InkStrokeProperties.Instance._lock ? 'lock' : 'unlock'} color="white" size="lg" />
- </div>
- </Tooltip>
- <Tooltip title={<div className="dash-tooltip">{'Rotate 90˚'}</div>}>
- <div className="inking-button-rotate" onPointerDown={action(() => this.rotate(Math.PI / 2))}>
- <FontAwesomeIcon icon="undo" color="white" size="lg" />
- </div>
- </Tooltip>
</div>
);
}
@@ -650,9 +633,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
@action
upDownButtons = (dirs: string, field: string) => {
switch (field) {
- case 'rot':
- this.rotate(dirs === 'up' ? 0.1 : -0.1);
- break;
case 'Xps':
this.selectedDoc && (this.selectedDoc.x = NumCast(this.selectedDoc?.x) + (dirs === 'up' ? 10 : -10));
break;
@@ -668,7 +648,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
const oldX = NumCast(this.selectedDoc?.x);
const oldY = NumCast(this.selectedDoc?.y);
this.selectedDoc && (this.selectedDoc._width = oldWidth + (dirs === 'up' ? 10 : -10));
- InkStrokeProperties.Instance._lock && this.selectedDoc && (this.selectedDoc._height = (NumCast(this.selectedDoc?._width) / oldWidth) * NumCast(this.selectedDoc?._height));
const doc = this.selectedDoc;
if (doc?.type === DocumentType.INK && doc.x && doc.y && doc._height && doc._width) {
const ink = Cast(doc.data, InkField)?.inkData;
@@ -690,7 +669,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
const oX = NumCast(this.selectedDoc?.x);
const oY = NumCast(this.selectedDoc?.y);
this.selectedDoc && (this.selectedDoc._height = oHeight + (dirs === 'up' ? 10 : -10));
- InkStrokeProperties.Instance._lock && this.selectedDoc && (this.selectedDoc._width = (NumCast(this.selectedDoc?._height) / oHeight) * NumCast(this.selectedDoc?._width));
const docu = this.selectedDoc;
if (docu?.type === DocumentType.INK && docu.x && docu.y && docu._height && docu._width) {
const ink = Cast(docu.data, InkField)?.inkData;
@@ -710,11 +688,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
};
getField(key: string) {
- //if (this.selectedDoc) {
return Field.toString(this.selectedDoc?.[key] as Field);
- // } else {
- // return undefined as Opt<string>;
- // }
}
@computed get shapeXps() {
@@ -723,9 +697,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
@computed get shapeYps() {
return this.getField('y');
}
- @computed get shapeRot() {
- return this.getField('rotation');
- }
@computed get shapeHgt() {
return this.getField('_height');
}
@@ -738,18 +709,11 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
set shapeYps(value) {
this.selectedDoc && (this.selectedDoc.y = Number(value));
}
- set shapeRot(value) {
- this.selectedDoc && (this.selectedDoc.rotation = Number(value));
- }
set shapeWid(value) {
- const oldWidth = NumCast(this.selectedDoc?._width);
this.selectedDoc && (this.selectedDoc._width = Number(value));
- InkStrokeProperties.Instance._lock && this.selectedDoc && (this.selectedDoc._height = (NumCast(this.selectedDoc?._width) * NumCast(this.selectedDoc?._height)) / oldWidth);
}
set shapeHgt(value) {
- const oldHeight = NumCast(this.selectedDoc?._height);
this.selectedDoc && (this.selectedDoc._height = Number(value));
- InkStrokeProperties.Instance._lock && this.selectedDoc && (this.selectedDoc._width = (NumCast(this.selectedDoc?._height) * NumCast(this.selectedDoc?._width)) / oldHeight);
}
@computed get hgtInput() {
@@ -796,30 +760,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
'Y:'
);
}
- @computed get rotInput() {
- return this.inputBoxDuo(
- 'rot',
- this.shapeRot,
- (val: string) => {
- if (!isNaN(Number(val))) {
- this.rotate(Number(val) - Number(this.shapeRot));
- this.shapeRot = val;
- }
- return true;
- },
- '∠:',
- 'rot',
- this.shapeRot,
- (val: string) => {
- if (!isNaN(Number(val))) {
- this.rotate(Number(val) - Number(this.shapeRot));
- this.shapeRot = val;
- }
- return true;
- },
- ''
- );
- }
@observable private _fillBtn = false;
@observable private _lineBtn = false;
@@ -1086,10 +1026,9 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
@computed get transformEditor() {
return (
<div className="transform-editor">
- {this.controlPointsButton}
+ {this.isInk ? this.controlPointsButton : null}
{this.hgtInput}
{this.XpsInput}
- {this.rotInput}
</div>
);
}
@@ -1144,29 +1083,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
}
/**
- * Checks if a currentFilter (FilterDoc) exists on the current collection (if the Properties Panel + Filters submenu are open).
- * If it doesn't exist, it creates it.
- */
- checkFilterDoc() {
- if (!this.selectedDoc?.currentFilter) this.selectedDoc!.currentFilter = FilterBox.createFilterDoc();
- }
-
- /**
- * Creates a new currentFilter for this.filterDoc,
- */
- createNewFilterDoc = () => {
- if (this.selectedDoc) {
- const currentDocFilters = this.selectedDoc._docFilters;
- const currentDocRangeFilters = this.selectedDoc._docRangeFilters;
- this.selectedDoc._docFilters = new List<string>();
- this.selectedDoc._docRangeFilters = new List<string>();
- (this.selectedDoc.currentFilter as Doc)._docFiltersList = currentDocFilters;
- (this.selectedDoc.currentFilter as Doc)._docRangeFiltersList = currentDocRangeFilters;
- this.selectedDoc.currentFilter = FilterBox.createFilterDoc();
- }
- };
-
- /**
* Updates this.filterDoc's currentFilter and saves the docFilters on the currentFilter
*/
updateFilterDoc = (doc: Doc) => {
@@ -1191,7 +1107,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
};
@computed get filtersSubMenu() {
- return !(this.selectedDoc?.currentFilter instanceof Doc) ? null : (
+ return (
<div className="propertiesView-filters">
<div className="propertiesView-filters-title" onPointerDown={action(() => (this.openFilters = !this.openFilters))} style={{ backgroundColor: this.openFilters ? 'black' : '' }}>
Filters
@@ -1200,35 +1116,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
</div>
</div>
{!this.openFilters ? null : (
- <div className="propertiesView-filters-content" style={{ height: this.selectedDoc.currentFilter[HeightSym]() + 15 }}>
- <DocumentView
- Document={this.selectedDoc.currentFilter}
- DataDoc={undefined}
- addDocument={undefined}
- addDocTab={returnFalse}
- pinToPres={emptyFunction}
- rootSelected={returnTrue}
- removeDocument={returnFalse}
- ScreenToLocalTransform={this.getTransform}
- PanelWidth={() => this.props.width}
- PanelHeight={this.selectedDoc.currentFilter[HeightSym]}
- renderDepth={0}
- scriptContext={this.selectedDoc.currentFilter}
- focus={emptyFunction}
- styleProvider={DefaultStyleProvider}
- isContentActive={returnTrue}
- whenChildContentsActiveChanged={emptyFunction}
- bringToFront={emptyFunction}
- docFilters={returnEmptyFilter}
- docRangeFilters={returnEmptyFilter}
- searchFilterDocs={returnEmptyDoclist}
- ContainingCollectionView={undefined}
- ContainingCollectionDoc={undefined}
- createNewFilterDoc={this.createNewFilterDoc}
- updateFilterDoc={this.updateFilterDoc}
- docViewPath={returnEmptyDoclist}
- dontCenter="y"
- />
+ <div className="propertiesView-filters-content" style={{ position: 'relative', height: 'auto' }}>
+ <FilterPanel rootDoc={this.selectedDoc ?? Doc.ActiveDashboard!} />
</div>
)}
</div>
@@ -1250,17 +1139,15 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
</div>
)}
- {this.isInk ? (
- <div className="propertiesView-transform">
- <div className="propertiesView-transform-title" onPointerDown={action(() => (this.openTransform = !this.openTransform))} style={{ backgroundColor: this.openTransform ? 'black' : '' }}>
- Transform
- <div className="propertiesView-transform-title-icon">
- <FontAwesomeIcon icon={this.openTransform ? 'caret-down' : 'caret-right'} size="lg" color="white" />
- </div>
+ <div className="propertiesView-transform">
+ <div className="propertiesView-transform-title" onPointerDown={action(() => (this.openTransform = !this.openTransform))} style={{ backgroundColor: this.openTransform ? 'black' : '' }}>
+ Transform
+ <div className="propertiesView-transform-title-icon">
+ <FontAwesomeIcon icon={this.openTransform ? 'caret-down' : 'caret-right'} size="lg" color="white" />
</div>
- {this.openTransform ? <div className="propertiesView-transform-content">{this.transformEditor}</div> : null}
</div>
- ) : null}
+ {this.openTransform ? <div className="propertiesView-transform-content">{this.transformEditor}</div> : null}
+ </div>
</>
);
}
@@ -1327,8 +1214,12 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
);
}
- @observable description = Field.toString(LinkManager.currentLink?.description as any as Field);
- @observable relationship = StrCast(LinkManager.currentLink?.linkRelationship);
+ @computed get description() {
+ return Field.toString(LinkManager.currentLink?.description as any as Field);
+ }
+ @computed get relationship() {
+ return StrCast(LinkManager.currentLink?.linkRelationship);
+ }
@observable private relationshipButtonColor: string = '';
// @action
@@ -1338,8 +1229,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
@undoBatch
handleDescriptionChange = action((value: string) => {
if (LinkManager.currentLink && this.selectedDoc) {
- this.selectedDoc.description = value;
- this.description = value;
+ this.setDescripValue(value);
return true;
}
});
@@ -1347,8 +1237,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
@undoBatch
handleLinkRelationshipChange = action((value: string) => {
if (LinkManager.currentLink && this.selectedDoc) {
- this.selectedDoc.linkRelationship = value;
- this.relationship = value;
+ this.setLinkRelationshipValue(value);
return true;
}
});
@@ -1404,19 +1293,34 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
});
@undoBatch
- changeFollowBehavior = action((follow: string) => {
- if (LinkManager.currentLink && this.selectedDoc) {
- this.selectedDoc.followLinkLocation = follow;
- return true;
- }
- });
+ changeFollowBehavior = action((follow: Opt<string>) => this.sourceAnchor && (this.sourceAnchor.followLinkLocation = follow));
+
+ @undoBatch
+ changeAnimationBehavior = action((behavior: string) => this.sourceAnchor && (this.sourceAnchor.followLinkAnimEffect = behavior));
+
+ @undoBatch
+ changeEffectDirection = action((effect: PresEffectDirection) => this.sourceAnchor && (this.sourceAnchor.followLinkAnimDirection = effect));
+
+ animationDirection = (direction: PresEffectDirection, icon: string, gridColumn: number, gridRow: number, opts: object) => {
+ const lanch = this.sourceAnchor;
+ const color = lanch?.followLinkAnimDirection === direction || (direction === PresEffectDirection.Center && !lanch?.followLinkAnimDirection) ? Colors.MEDIUM_BLUE : '';
+ return (
+ <Tooltip title={<div className="dash-tooltip">{direction}</div>}>
+ <div
+ style={{ ...opts, border: direction === PresEffectDirection.Center ? `solid 2px ${color}` : undefined, borderRadius: '20%', cursor: 'pointer', gridColumn, gridRow, justifySelf: 'center', background: color, color: 'black' }}
+ onClick={() => this.changeEffectDirection(direction)}>
+ {icon ? <FontAwesomeIcon icon={icon as any} /> : null}
+ </div>
+ </Tooltip>
+ );
+ };
onSelectOutDesc = () => {
this.setDescripValue(this.description);
document.getElementById('link_description_input')?.blur();
};
- onDescriptionKey = (e: React.KeyboardEvent<HTMLInputElement>) => {
+ onDescriptionKey = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
if (e.key === 'Enter') {
this.setDescripValue(this.description);
document.getElementById('link_description_input')?.blur();
@@ -1435,19 +1339,37 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
}
};
- toggleAnchor = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoBatch(action(() => this.selectedDoc && (this.selectedDoc.linkAutoMove = !this.selectedDoc.linkAutoMove))));
+ toggleLinkProp = (e: React.PointerEvent, prop: string) => {
+ setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoBatch(action(() => LinkManager.currentLink && (LinkManager.currentLink[prop] = !LinkManager.currentLink[prop]))));
};
- toggleArrow = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoBatch(action(() => this.selectedDoc && (this.selectedDoc.displayArrow = !this.selectedDoc.displayArrow))));
- };
+ @computed get destinationAnchor() {
+ const ldoc = LinkManager.currentLink;
+ const lanch = this.selectedDocumentView?.anchorViewDoc ?? LinkManager.currentLinkAnchor;
+ if (ldoc && lanch) return LinkManager.getOppositeAnchor(ldoc, lanch) ?? lanch;
+ return ldoc ? DocCast(ldoc.anchor2) : ldoc;
+ }
- toggleZoomToTarget1 = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoBatch(action(() => this.selectedDoc && (DocCast(this.selectedDoc.anchor1).followLinkZoom = !DocCast(this.selectedDoc.anchor1).followLinkZoom))));
- };
- toggleZoomToTarget2 = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e, returnFalse, emptyFunction, undoBatch(action(() => this.selectedDoc && (DocCast(this.selectedDoc.anchor2).followLinkZoom = !DocCast(this.selectedDoc.anchor2).followLinkZoom))));
+ @computed get sourceAnchor() {
+ const selAnchor = this.selectedDocumentView?.anchorViewDoc ?? LinkManager.currentLinkAnchor;
+
+ return selAnchor ?? (LinkManager.currentLink && this.destinationAnchor ? LinkManager.getOppositeAnchor(LinkManager.currentLink, this.destinationAnchor) : LinkManager.currentLink);
+ }
+
+ toggleAnchorProp = (e: React.PointerEvent, prop: string, anchor?: Doc, value: any = true, ovalue: any = false, cb: (val: any) => any = val => val) => {
+ anchor &&
+ setupMoveUpEvents(
+ this,
+ e,
+ returnFalse,
+ emptyFunction,
+ undoBatch(
+ action(() => {
+ anchor[prop] = anchor[prop] === value ? ovalue : value;
+ this.selectedDoc && cb(anchor[prop]);
+ })
+ )
+ );
};
@computed
@@ -1469,19 +1391,28 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
@computed
get editDescription() {
return (
- <input
- autoComplete={'off'}
+ <textarea
+ autoComplete="off"
+ style={{ textAlign: 'left' }}
id="link_description_input"
value={StrCast(this.selectedDoc?.description)}
onKeyDown={this.onDescriptionKey}
onBlur={this.onSelectOutDesc}
onChange={e => this.handleDescriptionChange(e.currentTarget.value)}
className="text"
- type="text"
/>
);
}
+ // Converts seconds to ms and updates presTransition
+ setZoom = (number: String, change?: number) => {
+ let scale = Number(number) / 100;
+ if (change) scale += change;
+ if (scale < 0.01) scale = 0.01;
+ if (scale > 1) scale = 1;
+ this.sourceAnchor && (this.sourceAnchor.followLinkZoomScale = scale);
+ };
+
/**
* Handles adding and removing members from the sharing panel
*/
@@ -1495,6 +1426,10 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
render() {
const isNovice = Doc.noviceMode;
+ const zoom = Number((NumCast(this.sourceAnchor?.followLinkZoomScale, 1) * 100).toPrecision(3));
+ const targZoom = this.sourceAnchor?.followLinkZoom;
+ const indent = 30;
+ const hasSelectedAnchor = LinkManager.Links(this.sourceAnchor).includes(LinkManager.currentLink!);
if (!this.selectedDoc && !this.isPres) {
return (
<div className="propertiesView" style={{ width: this.props.width }}>
@@ -1504,81 +1439,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
</div>
);
} else {
- if (this.selectedDoc && this.isLink) {
- return (
- <div className="propertiesView">
- <div className="propertiesView-title">Linking</div>
- <div className="propertiesView-section">
- <p className="propertiesView-label">Information</p>
- <div className="propertiesView-input first">
- <p>Link Relationship</p>
- {this.editRelationship}
- </div>
- <div className="propertiesView-input">
- <p>Description</p>
- {this.editDescription}
- </div>
- </div>
- <div className="propertiesView-section">
- <p className="propertiesView-label">Behavior</p>
- <div className="propertiesView-input inline first">
- <p>Follow</p>
- <select name="selectList" id="selectList" onChange={e => this.changeFollowBehavior(e.currentTarget.value)} value={StrCast(this.selectedDoc.followLinkLocation, 'default')}>
- <option value="default">Default</option>
- <option value="add:left">Open in new left pane</option>
- <option value="add:right">Open in new right pane</option>
- <option value="replace:left">Replace left tab</option>
- <option value="replace:right">Replace right tab</option>
- <option value="fullScreen">Open full screen</option>
- <option value="add">Open in new tab</option>
- <option value="replace">Replace current tab</option>
- {this.selectedDoc.linksToAnnotation ? <option value="openExternal">Open in external page</option> : null}
- </select>
- </div>
- <div className="propertiesView-input inline">
- <p>Auto-move anchor</p>
- <button
- style={{ background: this.selectedDoc.hidden ? 'gray' : !this.selectedDoc.linkAutoMove ? '' : '#4476f7', borderRadius: 3 }}
- onPointerDown={this.toggleAnchor}
- onClick={e => e.stopPropagation()}
- className="propertiesButton">
- <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
- </button>
- </div>
- <div className="propertiesView-input inline">
- <p>Display arrow</p>
- <button
- style={{ background: this.selectedDoc.hidden ? 'gray' : !this.selectedDoc.displayArrow ? '' : '#4476f7', borderRadius: 3 }}
- onPointerDown={this.toggleArrow}
- onClick={e => e.stopPropagation()}
- className="propertiesButton">
- <FontAwesomeIcon className="fa-icon" icon={faArrowRight as IconLookup} size="lg" />
- </button>
- </div>
- <div className="propertiesView-input inline">
- <p>Zoom to target</p>
- <button
- style={{ background: this.selectedDoc.hidden ? 'gray' : !Cast(this.selectedDoc.anchor1, Doc, null).followLinkZoom ? '' : '#4476f7', borderRadius: 3 }}
- onPointerDown={this.toggleZoomToTarget1}
- onClick={e => e.stopPropagation()}
- className="propertiesButton">
- <FontAwesomeIcon className="fa-icon" icon={faArrowRight as IconLookup} size="lg" />
- </button>
- </div>
- <div className="propertiesView-input inline">
- <p>Zoom to source</p>
- <button
- style={{ background: this.selectedDoc.hidden ? 'gray' : !Cast(this.selectedDoc.anchor2, Doc, null).followLinkZoom ? '' : '#4476f7', borderRadius: 3 }}
- onPointerDown={this.toggleZoomToTarget2}
- onClick={e => e.stopPropagation()}
- className="propertiesButton">
- <FontAwesomeIcon className="fa-icon" icon={faArrowRight as IconLookup} size="lg" />
- </button>
- </div>
- </div>
- </div>
- );
- }
if (this.selectedDoc && !this.isPres) {
return (
<div
@@ -1596,6 +1456,218 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
{this.contextsSubMenu}
{this.linksSubMenu}
+ {!this.selectedDoc || !LinkManager.currentLink || (!hasSelectedAnchor && this.selectedDoc !== LinkManager.currentLink) ? null : (
+ <>
+ <div className="propertiesView-section" style={{ background: 'darkgray' }}>
+ <div className="propertiesView-input first" style={{ display: 'grid', gridTemplateColumns: '84px auto' }}>
+ <p>Relationship</p>
+ {this.editRelationship}
+ </div>
+ <div className="propertiesView-input" style={{ display: 'grid', gridTemplateColumns: '84px auto' }}>
+ <p>Description</p>
+ {this.editDescription}
+ </div>
+ <div className="propertiesView-input inline">
+ <p>Show link</p>
+ <button
+ style={{ background: !LinkManager.currentLink?.linkDisplay ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => this.toggleLinkProp(e, 'linkDisplay')}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faArrowRight as IconLookup} size="lg" />
+ </button>
+ </div>
+ <div className="propertiesView-input inline" style={{ marginLeft: 10 }}>
+ <p>Auto-move anchors</p>
+ <button
+ style={{ background: !LinkManager.currentLink?.linkAutoMove ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => this.toggleLinkProp(e, 'linkAutoMove')}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+ </button>
+ </div>
+ <div className="propertiesView-input inline" style={{ marginLeft: 10 }}>
+ <p>Display arrow</p>
+ <button
+ style={{ background: !LinkManager.currentLink?.linkDisplayArrow ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => this.toggleLinkProp(e, 'linkDisplayArrow')}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faArrowRight as IconLookup} size="lg" />
+ </button>
+ </div>
+ </div>
+ {!hasSelectedAnchor ? null : (
+ <div className="propertiesView-section">
+ <div className="propertiesView-input inline first" style={{ display: 'grid', gridTemplateColumns: '84px calc(100% - 84px)' }}>
+ <p>Follow by</p>
+ <select onChange={e => this.changeFollowBehavior(e.currentTarget.value === 'Default' ? undefined : e.currentTarget.value)} value={Cast(this.sourceAnchor?.followLinkLocation, 'string', null)}>
+ <option value={undefined}>Default</option>
+ <option value={OpenWhere.addLeft}>Opening in new left pane</option>
+ <option value={OpenWhere.addRight}>Opening in new right pane</option>
+ <option value={OpenWhere.replaceLeft}>Replacing left tab</option>
+ <option value={OpenWhere.replaceRight}>Replacing right tab</option>
+ <option value={OpenWhere.fullScreen}>Overlaying current tab</option>
+ <option value={OpenWhere.lightbox}>Opening in lightbox</option>
+ <option value={OpenWhere.add}>Opening in new tab</option>
+ <option value={OpenWhere.replace}>Replacing current tab</option>
+ <option value={OpenWhere.inParent}>Opening in same collection</option>
+ {LinkManager.currentLink?.linksToAnnotation ? <option value="openExternal">Open in external page</option> : null}
+ </select>
+ </div>
+ <div className="propertiesView-input inline first" style={{ display: 'grid', gridTemplateColumns: '84px calc(100% - 134px) 50px' }}>
+ <p>Animation</p>
+ <select style={{ width: '100%', gridColumn: 2 }} onChange={e => this.changeAnimationBehavior(e.currentTarget.value)} value={StrCast(this.sourceAnchor?.followLinkAnimEffect, 'default')}>
+ <option value="default">Default</option>
+ {[PresEffect.None, PresEffect.Zoom, PresEffect.Lightspeed, PresEffect.Fade, PresEffect.Flip, PresEffect.Rotate, PresEffect.Bounce, PresEffect.Roll].map(effect => (
+ <option value={effect.toString()}>{effect.toString()}</option>
+ ))}
+ </select>
+ <div className="effectDirection" style={{ marginLeft: '10px', display: 'grid', width: 40, height: 36, gridColumn: 3, gridTemplateRows: '12px 12px 12px' }}>
+ {this.animationDirection(PresEffectDirection.Left, 'angle-right', 1, 2, {})}
+ {this.animationDirection(PresEffectDirection.Right, 'angle-left', 3, 2, {})}
+ {this.animationDirection(PresEffectDirection.Top, 'angle-down', 2, 1, {})}
+ {this.animationDirection(PresEffectDirection.Bottom, 'angle-up', 2, 3, {})}
+ {this.animationDirection(PresEffectDirection.Center, '', 2, 2, { width: 10, height: 10, alignSelf: 'center' })}
+ </div>
+ </div>
+ {PresBox.inputter(
+ '0.1',
+ '0.1',
+ '10',
+ NumCast(this.sourceAnchor?.followLinkTransitionTime) / 1000,
+ true,
+ (val: string) => PresBox.SetTransitionTime(val, (timeInMS: number) => this.sourceAnchor && (this.sourceAnchor.followLinkTransitionTime = timeInMS)),
+ indent
+ )}{' '}
+ <div
+ className={'slider-headers'}
+ style={{
+ display: 'grid',
+ justifyContent: 'space-between',
+ width: `calc(100% - ${indent * 2}px)`,
+ marginLeft: indent,
+ marginRight: indent,
+ gridTemplateColumns: 'auto auto',
+ borderTop: 'solid',
+ }}>
+ <div className="slider-text">Fast</div>
+ <div className="slider-text">Slow</div>
+ </div>{' '}
+ <div className="propertiesView-input inline">
+ <p>Play Target Audio</p>
+ <button
+ style={{ background: !this.sourceAnchor?.followLinkAudio ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => this.toggleAnchorProp(e, 'followLinkAudio', this.sourceAnchor)}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+ </button>
+ </div>
+ <div className="propertiesView-input inline">
+ <p>Zoom Text Selections</p>
+ <button
+ style={{ background: !this.sourceAnchor?.followLinkZoomText ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => this.toggleAnchorProp(e, 'followLinkZoomText', this.sourceAnchor)}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+ </button>
+ </div>
+ <div className="propertiesView-input inline">
+ <p>Toggle Follow to Outer Context</p>
+ <button
+ style={{ background: !this.sourceAnchor?.followLinkToOuterContext ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => this.toggleAnchorProp(e, 'followLinkToOuterContext', this.sourceAnchor)}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faWindowMaximize as IconLookup} size="lg" />
+ </button>
+ </div>
+ <div className="propertiesView-input inline">
+ <p>Toggle Target (Show/Hide)</p>
+ <button
+ style={{ background: !this.sourceAnchor?.followLinkToggle ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => this.toggleAnchorProp(e, 'followLinkToggle', this.sourceAnchor)}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+ </button>
+ </div>
+ <div className="propertiesView-input inline">
+ <p>Ease Transitions</p>
+ <button
+ style={{ background: this.sourceAnchor?.followLinkEase === 'linear' ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => this.toggleAnchorProp(e, 'followLinkEase', this.sourceAnchor, 'ease', 'linear')}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+ </button>
+ </div>
+ <div className="propertiesView-input inline">
+ <p>Capture Offset to Target</p>
+ <button
+ style={{ background: this.sourceAnchor?.followLinkXoffset === undefined ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => {
+ this.toggleAnchorProp(e, 'followLinkXoffset', this.sourceAnchor, NumCast(this.destinationAnchor?.x) - NumCast(this.sourceAnchor?.x), undefined);
+ this.toggleAnchorProp(e, 'followLinkYoffset', this.sourceAnchor, NumCast(this.destinationAnchor?.y) - NumCast(this.sourceAnchor?.y), undefined);
+ }}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+ </button>
+ </div>
+ <div className="propertiesView-input inline">
+ <p>Center Target (no zoom)</p>
+ <button
+ style={{ background: this.sourceAnchor?.followLinkZoom ? '' : '#4476f7', borderRadius: 3 }}
+ onPointerDown={e => this.toggleAnchorProp(e, 'followLinkZoom', this.sourceAnchor)}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+ </button>
+ </div>
+ <div className="propertiesView-input inline" style={{ display: 'grid', gridTemplateColumns: '78px calc(100% - 108px) 50px' }}>
+ <p>Zoom %</p>
+ <div className="ribbon-property" style={{ display: !targZoom ? 'none' : 'inline-flex' }}>
+ <input className="presBox-input" style={{ width: '100%' }} type="number" value={zoom} />
+ <div className="ribbon-propertyUpDown" style={{ display: 'flex', flexDirection: 'column' }}>
+ <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setZoom(String(zoom), 0.1))}>
+ <FontAwesomeIcon icon={'caret-up'} />
+ </div>
+ <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setZoom(String(zoom), -0.1))}>
+ <FontAwesomeIcon icon={'caret-down'} />
+ </div>
+ </div>
+ </div>
+ <button
+ style={{ background: !targZoom || this.sourceAnchor?.followLinkZoomScale === 0 ? '' : '#4476f7', borderRadius: 3, gridColumn: 3 }}
+ onPointerDown={e => this.toggleAnchorProp(e, 'followLinkZoom', this.sourceAnchor)}
+ onClick={e => e.stopPropagation()}
+ className="propertiesButton">
+ <FontAwesomeIcon className="fa-icon" icon={faArrowRight as IconLookup} size="lg" />
+ </button>
+ </div>
+ {!targZoom ? null : PresBox.inputter('0', '1', '100', zoom, true, this.setZoom, 30)}
+ <div
+ className={'slider-headers'}
+ style={{
+ display: !targZoom ? 'none' : 'grid',
+ justifyContent: 'space-between',
+ width: `calc(100% - ${indent * 2}px)`,
+ marginLeft: indent,
+ marginRight: indent,
+ gridTemplateColumns: 'auto auto',
+ borderTop: 'solid',
+ }}>
+ <div className="slider-text">0%</div>
+ <div className="slider-text">100%</div>
+ </div>{' '}
+ </div>
+ )}
+ </>
+ )}
{this.inkSubMenu}
@@ -1612,11 +1684,10 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
);
}
if (this.isPres) {
- const selectedItem: boolean = PresBox.Instance?._selectedArray.size > 0;
- const type = PresBox.Instance.activeItem?.type;
- const viewType = PresBox.Instance.activeItem?._viewType;
- const pannable: boolean = (type === DocumentType.COL && viewType === CollectionViewType.Freeform) || type === DocumentType.IMG;
- const scrollable: boolean = type === DocumentType.PDF || type === DocumentType.WEB || type === DocumentType.RTF || viewType === CollectionViewType.Stacking || viewType === CollectionViewType.NoteTaking;
+ const selectedItem: boolean = PresBox.Instance?.selectedArray.size > 0;
+ const type = [DocumentType.AUDIO, DocumentType.VID].includes(DocCast(PresBox.Instance.activeItem?.annotationOn)?.type as any as DocumentType)
+ ? (DocCast(PresBox.Instance.activeItem?.annotationOn)?.type as any as DocumentType)
+ : PresBox.targetRenderedDoc(PresBox.Instance.activeItem)?.type;
return (
<div className="propertiesView" style={{ width: this.props.width }}>
<div className="propertiesView-title" style={{ width: this.props.width }}>
@@ -1625,18 +1696,13 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
<div className="propertiesView-name" style={{ borderBottom: 0 }}>
{this.editableTitle}
<div className="propertiesView-presSelected">
- <div className="propertiesView-selectedCount">{PresBox.Instance?._selectedArray.size} selected</div>
+ <div className="propertiesView-selectedCount">{PresBox.Instance?.selectedArray.size} selected</div>
<div className="propertiesView-selectedList">{PresBox.Instance?.listOfSelected}</div>
</div>
</div>
{!selectedItem ? null : (
<div className="propertiesView-presTrails">
- <div
- className="propertiesView-presTrails-title"
- onPointerDown={action(() => {
- this.openPresTransitions = !this.openPresTransitions;
- })}
- style={{ backgroundColor: this.openPresTransitions ? 'black' : '' }}>
+ <div className="propertiesView-presTrails-title" onPointerDown={action(() => (this.openPresTransitions = !this.openPresTransitions))} style={{ backgroundColor: this.openPresTransitions ? 'black' : '' }}>
&nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={'rocket'} /> &nbsp; Transitions
<div className="propertiesView-presTrails-title-icon">
<FontAwesomeIcon icon={this.openPresTransitions ? 'caret-down' : 'caret-right'} size="lg" color="white" />
@@ -1645,27 +1711,34 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
{this.openPresTransitions ? <div className="propertiesView-presTrails-content">{PresBox.Instance.transitionDropdown}</div> : null}
</div>
)}
- {/* {!selectedItem || type === DocumentType.VID || type === DocumentType.AUDIO ? (null) : <div className="propertiesView-presTrails">
- <div className="propertiesView-presTrails-title"
- onPointerDown={action(() => this.openPresProgressivize = !this.openPresProgressivize)}
- style={{ backgroundColor: this.openPresProgressivize ? "black" : "" }}>
- &nbsp; <FontAwesomeIcon style={{ alignSelf: "center" }} icon={"tasks"} /> &nbsp; Progressivize
- <div className="propertiesView-presTrails-title-icon">
- <FontAwesomeIcon icon={this.openPresProgressivize ? "caret-down" : "caret-right"} size="lg" color="white" />
- </div>
- </div>
- {this.openPresProgressivize ? <div className="propertiesView-presTrails-content">
- {PresBox.Instance.progressivizeDropdown}
- </div> : null}
- </div>} */}
- {!selectedItem || (type !== DocumentType.VID && type !== DocumentType.AUDIO) ? null : (
+ {!selectedItem ? null : (
<div className="propertiesView-presTrails">
<div
className="propertiesView-presTrails-title"
- onPointerDown={action(() => {
- this.openSlideOptions = !this.openSlideOptions;
- })}
- style={{ backgroundColor: this.openSlideOptions ? 'black' : '' }}>
+ onPointerDown={action(() => (this.openPresVisibilityAndDuration = !this.openPresVisibilityAndDuration))}
+ style={{ backgroundColor: this.openPresTransitions ? 'black' : '' }}>
+ &nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={'rocket'} /> &nbsp; Visibilty
+ <div className="propertiesView-presTrails-title-icon">
+ <FontAwesomeIcon icon={this.openPresVisibilityAndDuration ? 'caret-down' : 'caret-right'} size="lg" color="white" />
+ </div>
+ </div>
+ {this.openPresVisibilityAndDuration ? <div className="propertiesView-presTrails-content">{PresBox.Instance.visibiltyDurationDropdown}</div> : null}
+ </div>
+ )}
+ {!selectedItem ? null : (
+ <div className="propertiesView-presTrails">
+ <div className="propertiesView-presTrails-title" onPointerDown={action(() => (this.openPresProgressivize = !this.openPresProgressivize))} style={{ backgroundColor: this.openPresTransitions ? 'black' : '' }}>
+ &nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={'rocket'} /> &nbsp; Progressivize
+ <div className="propertiesView-presTrails-title-icon">
+ <FontAwesomeIcon icon={this.openPresProgressivize ? 'caret-down' : 'caret-right'} size="lg" color="white" />
+ </div>
+ </div>
+ {this.openPresProgressivize ? <div className="propertiesView-presTrails-content">{PresBox.Instance.progressivizeDropdown}</div> : null}
+ </div>
+ )}
+ {!selectedItem || (type !== DocumentType.VID && type !== DocumentType.AUDIO) ? null : (
+ <div className="propertiesView-presTrails">
+ <div className="propertiesView-presTrails-title" onPointerDown={action(() => (this.openSlideOptions = !this.openSlideOptions))} style={{ backgroundColor: this.openSlideOptions ? 'black' : '' }}>
&nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={type === DocumentType.AUDIO ? 'file-audio' : 'file-video'} /> &nbsp; {type === DocumentType.AUDIO ? 'Audio Options' : 'Video Options'}
<div className="propertiesView-presTrails-title-icon">
<FontAwesomeIcon icon={this.openSlideOptions ? 'caret-down' : 'caret-right'} size="lg" color="white" />