aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/PropertiesButtons.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/PropertiesButtons.tsx')
-rw-r--r--src/client/views/PropertiesButtons.tsx212
1 files changed, 96 insertions, 116 deletions
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 517a80d63..edf6df2b9 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -1,3 +1,6 @@
+/* eslint-disable jsx-a11y/no-static-element-interactions */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
+/* eslint-disable react/no-unused-class-component-methods */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Dropdown, DropdownType, IListItemProps, Toggle, ToggleType, Type } from 'browndash-components';
import { action, computed, observable } from 'mobx';
@@ -12,98 +15,47 @@ import { MdClosedCaption, MdClosedCaptionDisabled, MdGridOff, MdGridOn, MdSubtit
import { RxWidth } from 'react-icons/rx';
import { TbEditCircle, TbEditCircleOff, TbHandOff, TbHandStop, TbHighlight, TbHighlightOff } from 'react-icons/tb';
import { TfiBarChart } from 'react-icons/tfi';
-import { Doc, DocListCast, Opt } from '../../fields/Doc';
+import { Doc, Opt } from '../../fields/Doc';
import { DocData } from '../../fields/DocSymbols';
import { ScriptField } from '../../fields/ScriptField';
import { BoolCast, ScriptCast } from '../../fields/Types';
import { ImageField } from '../../fields/URLField';
+import { DocUtils, IsFollowLinkScript } from '../documents/DocUtils';
import { CollectionViewType, DocumentType } from '../documents/DocumentTypes';
-import { DocUtils } from '../documents/Documents';
-import { IsFollowLinkScript } from '../util/LinkFollower';
-import { LinkManager } from '../util/LinkManager';
-import { SelectionManager } from '../util/SelectionManager';
import { SettingsManager } from '../util/SettingsManager';
import { undoBatch, undoable } from '../util/UndoManager';
import { InkingStroke } from './InkingStroke';
import './PropertiesButtons.scss';
import { Colors } from './global/globalEnums';
-import { DocumentView, OpenWhere } from './nodes/DocumentView';
+import { DocumentView } from './nodes/DocumentView';
+import { OpenWhere } from './nodes/OpenWhere';
import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
@observer
export class PropertiesButtons extends React.Component<{}, {}> {
+ // eslint-disable-next-line no-use-before-define
@observable public static Instance: PropertiesButtons;
@computed get selectedDoc() {
- return SelectionManager.SelectedSchemaDoc || SelectionManager.Views.lastElement()?.Document;
+ return DocumentView.SelectedSchemaDoc() || DocumentView.Selected().lastElement()?.Document;
}
@computed get selectedLayoutDoc() {
- return SelectionManager.SelectedSchemaDoc || SelectionManager.Views.lastElement()?.layoutDoc;
+ return DocumentView.SelectedSchemaDoc() || DocumentView.Selected().lastElement()?.layoutDoc;
}
@computed get selectedTabView() {
- return !SelectionManager.SelectedSchemaDoc && SelectionManager.Views.lastElement()?.topMost;
- }
-
- propertyToggleBtn = (label: (on?: any) => string, property: string, tooltip: (on?: any) => string, icon: (on?: any) => any, onClick?: (dv: Opt<DocumentView>, doc: Doc, property: string) => void, useUserDoc?: boolean) => {
- const targetDoc = useUserDoc ? Doc.UserDoc() : this.selectedLayoutDoc;
- const onPropToggle = (dv: Opt<DocumentView>, doc: Doc, prop: string) => ((dv?.layoutDoc || doc)[prop] = (dv?.layoutDoc || doc)[prop] ? false : true);
- return !targetDoc ? null : (
- <Toggle
- toggleStatus={BoolCast(targetDoc[property])}
- tooltip={tooltip(BoolCast(targetDoc[property]))}
- text={label(targetDoc?.[property])}
- color={SettingsManager.userColor}
- icon={icon(targetDoc?.[property] as any)}
- iconPlacement="left"
- align="flex-start"
- fillWidth={true}
- toggleType={ToggleType.BUTTON}
- onClick={undoable(() => {
- if (SelectionManager.Views.length > 1) {
- SelectionManager.Views.forEach(dv => (onClick ?? onPropToggle)(dv, dv.Document, property));
- } else if (targetDoc) (onClick ?? onPropToggle)(undefined, targetDoc, property);
- }, property)}
- />
- );
- };
-
- // this implments a container pattern by marking the targetDoc (collection) as a lightbox
- // that always fits its contents to its container and that hides all other documents when
- // a link is followed that targets a 'lightbox' destination
- @computed get isLightboxButton() {
- return this.propertyToggleBtn(
- on => 'Lightbox',
- 'isLightbox',
- on => `${on ? 'Set' : 'Remove'} lightbox flag`,
- on => 'window-restore',
- onClick => {
- SelectionManager.Views.forEach(dv => {
- const containerDoc = dv.Document;
- //containerDoc.followAllLinks =
- // containerDoc.noShadow =
- // containerDoc.layout_disableBrushing =
- // containerDoc._forceActive =
- //containerDoc._freeform_fitContentsToBox =
- containerDoc._isLightbox = !containerDoc._isLightbox;
- //containerDoc._xPadding = containerDoc._yPadding = containerDoc._isLightbox ? 10 : undefined;
- const containerContents = DocListCast(dv.dataDoc[Doc.LayoutFieldKey(containerDoc)]);
- //dv.Docuemnt.onClick = ScriptField.MakeScript('{this.data = undefined; documentView.select(false)}', { documentView: 'any' });
- containerContents.forEach(doc => LinkManager.Links(doc).forEach(link => (link.link_displayLine = false)));
- });
- }
- );
+ return !DocumentView.SelectedSchemaDoc() && DocumentView.Selected().lastElement()?.topMost;
}
@computed get titleButton() {
return this.propertyToggleBtn(
- on => (!on ? 'SHOW TITLE' : this.selectedDoc?.['_layout_showTitle'] === 'title:hover' ? 'HIDE TITLE' : 'HOVER TITLE'),
+ on => (!on ? 'SHOW TITLE' : this.selectedDoc?._layout_showTitle === 'title:hover' ? 'HIDE TITLE' : 'HOVER TITLE'),
'_layout_showTitle',
- on => 'Switch between title styles',
+ () => 'Switch between title styles',
on => (on ? <MdSubtitlesOff /> : <MdSubtitles />), // {currentIcon}, //(on ? <MdSubtitles/> :) , //,'text-width', on ? <MdSubtitles/> : <MdSubtitlesOff/>,
(dv, doc) => {
const tdoc = dv?.Document || doc;
const newtitle = !tdoc._layout_showTitle ? 'title' : tdoc._layout_showTitle === 'title' ? 'title:hover' : '';
- tdoc._layout_showTitle = newtitle ? newtitle : undefined;
+ tdoc._layout_showTitle = newtitle || undefined;
}
);
}
@@ -119,7 +71,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
}
@computed get maskButton() {
- //highlight text while going down and reading through
+ // highlight text while going down and reading through
return this.propertyToggleBtn(
on => (on ? 'PLAIN INK' : 'HIGHLIGHTER MASK'),
'stroke_isInkMask',
@@ -132,10 +84,10 @@ export class PropertiesButtons extends React.Component<{}, {}> {
@computed get hideImageButton() {
// put in developer -- can trace on top of object and drawing is still there
return this.propertyToggleBtn(
- on => (on ? 'SHOW BACKGROUND IMAGE' : 'HIDE BACKGROUND IMAGE'), //'Background',
+ on => (on ? 'SHOW BACKGROUND IMAGE' : 'HIDE BACKGROUND IMAGE'), // 'Background',
'_hideImage',
on => (on ? 'Show Image' : 'Show Background'),
- on => (on ? <BiShow /> : <BiHide />) //'portrait'
+ on => (on ? <BiShow /> : <BiHide />) // 'portrait'
);
}
@@ -144,35 +96,35 @@ export class PropertiesButtons extends React.Component<{}, {}> {
on => (on ? 'DISABLE CLUSTERS' : 'HIGHLIGHT CLUSTERS'),
'_freeform_useClusters',
on => `${on ? 'Hide' : 'Show'} clusters`,
- on => <FaBraille />
+ () => <FaBraille />
);
}
@computed get panButton() {
return this.propertyToggleBtn(
- on => (on ? 'ENABLE PANNING' : 'DISABLE PANNING'), //'Lock\xA0View',
+ on => (on ? 'ENABLE PANNING' : 'DISABLE PANNING'), // 'Lock\xA0View',
'_lockedTransform',
on => `${on ? 'Unlock' : 'Lock'} panning of view`,
- on => (on ? <TbHandStop /> : <TbHandOff />) //'lock'
+ on => (on ? <TbHandStop /> : <TbHandOff />) // 'lock'
);
}
@computed get forceActiveButton() {
- //select text
+ // select text
return this.propertyToggleBtn(
on => (on ? 'SELECT TO INTERACT' : 'ALWAYS INTERACTIVE'),
'_forceActive',
on => `${on ? 'Document must be selected to interact with its contents' : 'Contents always active (respond to click/drag events)'} `,
- on => <MdTouchApp /> // 'eye'
+ () => <MdTouchApp /> // 'eye'
);
}
@computed get verticalAlignButton() {
- //select text
+ // select text
return this.propertyToggleBtn(
on => (on ? 'ALIGN TOP' : 'ALIGN CENTER'),
'_layout_centered',
on => `${on ? 'Text is aligned with top of document' : 'Text is aligned with center of document'} `,
- on => <MdTouchApp /> // 'eye'
+ () => <MdTouchApp /> // 'eye'
);
}
@@ -181,9 +133,9 @@ export class PropertiesButtons extends React.Component<{}, {}> {
on => (on ? 'DISABLE FLASHCARD' : 'ENABLE FLASHCARD'),
'layout_textPainted',
on => `${on ? 'Flashcard enabled' : 'Flashcard disabled'} `,
- on => <MdTouchApp />,
+ () => <MdTouchApp />,
(dv, doc) => {
- const on = doc.onPaint ? true : false;
+ const on = !!doc.onPaint;
doc[DocData].onPaint = on ? undefined : ScriptField.MakeScript(`toggleDetail(documentView, "textPainted")`, { documentView: 'any' });
doc[DocData].layout_textPainted = on ? undefined : `<ComparisonBox {...props} fieldKey={'${dv?.LayoutFieldKey ?? 'text'}'}/>`;
}
@@ -192,10 +144,10 @@ export class PropertiesButtons extends React.Component<{}, {}> {
@computed get fitContentButton() {
return this.propertyToggleBtn(
- on => (on ? 'PREVIOUS VIEW' : 'VIEW ALL'), //'View All',
+ on => (on ? 'PREVIOUS VIEW' : 'VIEW ALL'), // 'View All',
'_freeform_fitContentsToBox',
on => `${on ? "Don't" : 'Do'} fit content to container visible area`,
- on => (on ? <CiGrid31 /> : <BsGrid3X3GapFill />) //'object-group'
+ on => (on ? <CiGrid31 /> : <BsGrid3X3GapFill />) // 'object-group'
);
}
@@ -209,7 +161,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
// on => `${on ? 'Set' : 'Remove'} lightbox flag`,
// on => 'window-restore',
// onClick => {
- // SelectionManager.Views.forEach(dv => {
+ // DocumentView.Selected().forEach(dv => {
// const containerDoc = dv.Document;
// //containerDoc.followAllLinks =
// // containerDoc.noShadow =
@@ -228,7 +180,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
@computed get layout_fitWidthButton() {
return this.propertyToggleBtn(
- on => (on ? 'SCALED VIEW' : 'READING VIEW'), //'Fit\xA0Width',
+ on => (on ? 'SCALED VIEW' : 'READING VIEW'), // 'Fit\xA0Width',
'_layout_fitWidth',
on =>
on
@@ -240,12 +192,14 @@ export class PropertiesButtons extends React.Component<{}, {}> {
@computed get captionButton() {
return this.propertyToggleBtn(
- //DEVELOPER
- on => (on ? 'HIDE CAPTION' : 'SHOW CAPTION'), //'Caption',
+ // DEVELOPER
+ on => (on ? 'HIDE CAPTION' : 'SHOW CAPTION'), // 'Caption',
'_layout_showCaption',
on => `${on ? 'Hide' : 'Show'} caption footer`,
- on => (on ? <MdClosedCaptionDisabled /> : <MdClosedCaption />), //'closed-captioning',
- (dv, doc) => ((dv?.Document || doc)._layout_showCaption = (dv?.Document || doc)._layout_showCaption === undefined ? 'caption' : undefined)
+ on => (on ? <MdClosedCaptionDisabled /> : <MdClosedCaption />), // 'closed-captioning',
+ (dv, doc) => {
+ (dv?.Document || doc)._layout_showCaption = (dv?.Document || doc)._layout_showCaption === undefined ? 'caption' : undefined;
+ }
);
}
@@ -256,7 +210,9 @@ export class PropertiesButtons extends React.Component<{}, {}> {
'_chromeHidden',
on => `${on ? 'Show' : 'Hide'} editing UI`,
on => (on ? <TbEditCircle /> : <TbEditCircleOff />), // 'edit',
- (dv, doc) => ((dv?.Document || doc)._chromeHidden = !(dv?.Document || doc)._chromeHidden)
+ (dv, doc) => {
+ (dv?.Document || doc)._chromeHidden = !(dv?.Document || doc)._chromeHidden;
+ }
);
}
@@ -265,8 +221,8 @@ export class PropertiesButtons extends React.Component<{}, {}> {
return this.propertyToggleBtn(
on => (on ? 'AUTO\xA0SIZE' : 'FIXED SIZE'),
'_layout_autoHeight',
- on => `Automatical vertical sizing to show all content`,
- on => <FontAwesomeIcon icon="arrows-alt-v" size="lg" />
+ () => `Automatical vertical sizing to show all content`,
+ () => <FontAwesomeIcon icon="arrows-alt-v" size="lg" />
);
}
@@ -274,8 +230,8 @@ export class PropertiesButtons extends React.Component<{}, {}> {
return this.propertyToggleBtn(
on => (on ? 'HIDE GRID' : 'DISPLAY GRID'),
'_freeform_backgroundGrid',
- on => `Display background grid in collection`,
- on => (on ? <MdGridOff /> : <MdGridOn />) //'border-all'
+ () => `Display background grid in collection`,
+ on => (on ? <MdGridOff /> : <MdGridOn />) // 'border-all'
);
}
@@ -317,8 +273,8 @@ export class PropertiesButtons extends React.Component<{}, {}> {
return this.propertyToggleBtn(
on => (on ? 'HIDE SNAP LINES' : 'SHOW SNAP LINES'),
'freeform_snapLines',
- on => `Display snapping lines when objects are dragged`,
- on => <TfiBarChart />, //'th',
+ () => `Display snapping lines when objects are dragged`,
+ () => <TfiBarChart />, // 'th',
undefined
);
}
@@ -361,18 +317,20 @@ export class PropertiesButtons extends React.Component<{}, {}> {
@undoBatch
handlePerspectiveChange = (e: any) => {
this.selectedDoc && (this.selectedDoc._type_collection = e.target.value);
- SelectionManager.Views.forEach(docView => (docView.layoutDoc._type_collection = e.target.value));
+ DocumentView.Selected().forEach(docView => {
+ docView.layoutDoc._type_collection = e.target.value;
+ });
};
@computed get onClickVal() {
const linkButton = IsFollowLinkScript(this.selectedDoc.onClick);
const followLoc = this.selectedDoc._followLinkLocation;
- const linkedToLightboxView = () => LinkManager.Links(this.selectedDoc).some(link => LinkManager.getOppositeAnchor(link, this.selectedDoc)?._isLightbox);
+ const linkedToLightboxView = () => Doc.Links(this.selectedDoc).some(link => Doc.getOppositeAnchor(link, this.selectedDoc)?._isLightbox);
if (followLoc === OpenWhere.lightbox && !linkedToLightboxView()) return 'linkInPlace';
- else if (linkButton && followLoc === OpenWhere.addRight) return 'linkOnRight';
- else if (linkButton && this.selectedDoc._followLinkLocation === OpenWhere.lightbox && linkedToLightboxView()) return 'enterPortal';
- else if (ScriptCast(this.selectedDoc.onClick)?.script.originalScript.includes('toggleDetail')) return 'toggleDetail';
- else return 'nothing';
+ if (linkButton && followLoc === OpenWhere.addRight) return 'linkOnRight';
+ if (linkButton && this.selectedDoc._followLinkLocation === OpenWhere.lightbox && linkedToLightboxView()) return 'enterPortal';
+ if (ScriptCast(this.selectedDoc.onClick)?.script.originalScript.includes('toggleDetail')) return 'toggleDetail';
+ return 'nothing';
}
@computed
@@ -385,20 +343,18 @@ export class PropertiesButtons extends React.Component<{}, {}> {
['linkOnRight', 'Open Link on Right'],
];
- const items: IListItemProps[] = buttonList.map(value => {
- return {
- text: value[1],
- val: value[1],
- };
- });
+ const items: IListItemProps[] = buttonList.map(value => ({
+ text: value[1],
+ val: value[1],
+ }));
return !this.selectedDoc ? null : (
<Dropdown
- tooltip={'Choose onClick behavior'}
+ tooltip="Choose onClick behavior"
items={items}
- closeOnSelect={true}
+ closeOnSelect
selectedVal={this.onClickVal}
setSelectedVal={val => this.handleOptionChange(val as string)}
- title={'Choose onClick behaviour'}
+ title="Choose onClick behaviour"
color={SettingsManager.userColor}
dropdownType={DropdownType.SELECT}
type={Type.SEC}
@@ -422,7 +378,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
@undoBatch
@action
handleOptionChange = (onClick: string) => {
- SelectionManager.Views.forEach(docView => {
+ DocumentView.Selected().forEach(docView => {
const linkButton = IsFollowLinkScript(docView.Document.onClick);
docView.noOnClick();
switch (onClick) {
@@ -440,16 +396,11 @@ export class PropertiesButtons extends React.Component<{}, {}> {
docView.toggleFollowLink(false, false);
docView.Document.followLinkLocation = linkButton ? OpenWhere.addRight : undefined;
break;
+ default:
}
});
};
- @undoBatch
- editOnClickScript = () => {
- if (SelectionManager.Views.length) SelectionManager.Views.forEach(dv => DocUtils.makeCustomViewClicked(dv.Document, undefined, 'onClick'));
- else this.selectedDoc && DocUtils.makeCustomViewClicked(this.selectedDoc, undefined, 'onClick');
- };
-
@computed
get onClickFlyout() {
const buttonList = [
@@ -463,7 +414,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
const click = () => this.handleOptionChange(value[0]);
const linkButton = IsFollowLinkScript(this.selectedDoc.onClick);
const followLoc = this.selectedDoc._followLinkLocation;
- const linkedToLightboxView = () => LinkManager.Links(this.selectedDoc).some(link => LinkManager.getOppositeAnchor(link, this.selectedDoc)?._isLightbox);
+ const linkedToLightboxView = () => Doc.Links(this.selectedDoc).some(link => Doc.getOppositeAnchor(link, this.selectedDoc)?._isLightbox);
let active = false;
// prettier-ignore
@@ -473,6 +424,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
case 'enterPortal': active = linkButton && this.selectedDoc._followLinkLocation === OpenWhere.lightbox && linkedToLightboxView(); break;
case 'toggleDetail':active = ScriptCast(this.selectedDoc.onClick)?.script.originalScript.includes('toggleDetail'); break;
case 'nothing': active = !linkButton && this.selectedDoc.onClick === undefined;break;
+ default:
}
return (
<div className="list-item" key={`${value}`} style={{ backgroundColor: active ? Colors.LIGHT_BLUE : undefined }} onClick={click}>
@@ -494,10 +446,40 @@ export class PropertiesButtons extends React.Component<{}, {}> {
</div>
);
}
+ @undoBatch
+ editOnClickScript = () => {
+ if (DocumentView.Selected().length) DocumentView.Selected().forEach(dv => DocUtils.makeCustomViewClicked(dv.Document, undefined, 'onClick'));
+ else this.selectedDoc && DocUtils.makeCustomViewClicked(this.selectedDoc, undefined, 'onClick');
+ };
+
+ propertyToggleBtn = (label: (on?: any) => string, property: string, tooltip: (on?: any) => string, icon: (on?: any) => any, onClick?: (dv: Opt<DocumentView>, doc: Doc, property: string) => void, useUserDoc?: boolean) => {
+ const targetDoc = useUserDoc ? Doc.UserDoc() : this.selectedLayoutDoc;
+ const onPropToggle = (dv: Opt<DocumentView>, doc: Doc, prop: string) => {
+ (dv?.layoutDoc || doc)[prop] = !(dv?.layoutDoc || doc)[prop];
+ };
+ return !targetDoc ? null : (
+ <Toggle
+ toggleStatus={BoolCast(targetDoc[property])}
+ tooltip={tooltip(BoolCast(targetDoc[property]))}
+ text={label(targetDoc?.[property])}
+ color={SettingsManager.userColor}
+ icon={icon(targetDoc?.[property] as any)}
+ iconPlacement="left"
+ align="flex-start"
+ fillWidth
+ toggleType={ToggleType.BUTTON}
+ onClick={undoable(() => {
+ if (DocumentView.Selected().length > 1) {
+ DocumentView.Selected().forEach(dv => (onClick ?? onPropToggle)(dv, dv.Document, property));
+ } else if (targetDoc) (onClick ?? onPropToggle)(undefined, targetDoc, property);
+ }, property)}
+ />
+ );
+ };
render() {
const layoutField = this.selectedDoc?.[Doc.LayoutFieldKey(this.selectedDoc)];
- const isText = SelectionManager.Views.lastElement()?.ComponentView instanceof FormattedTextBox;
+ const isText = DocumentView.Selected().lastElement()?.ComponentView instanceof FormattedTextBox;
const isInk = this.selectedDoc?.layout_isSvg;
const isImage = layoutField instanceof ImageField;
const isMap = this.selectedDoc?.type === DocumentType.MAP;
@@ -505,11 +487,9 @@ export class PropertiesButtons extends React.Component<{}, {}> {
const isStacking = [CollectionViewType.Stacking, CollectionViewType.Masonry, CollectionViewType.NoteTaking].includes(this.selectedDoc?._type_collection as any);
const isFreeForm = this.selectedDoc?._type_collection === CollectionViewType.Freeform;
const isTree = this.selectedDoc?._type_collection === CollectionViewType.Tree;
- const isTabView = this.selectedTabView;
const toggle = (ele: JSX.Element | null, style?: React.CSSProperties) => (
<div className="propertiesButtons-button" style={style}>
- {' '}
- {ele}{' '}
+ {ele}
</div>
);
const isNovice = Doc.noviceMode;