diff options
Diffstat (limited to 'src/client/views/PropertiesView.tsx')
| -rw-r--r-- | src/client/views/PropertiesView.tsx | 380 |
1 files changed, 205 insertions, 175 deletions
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 82ab54787..04a948a27 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -3,14 +3,12 @@ import { IconLookup } from '@fortawesome/fontawesome-svg-core'; import { faAnchor, faArrowRight, faWindowMaximize } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Checkbox, Tooltip } from '@material-ui/core'; -import { Button, Colors, EditableText, IconButton, NumberInput, Size, Slider, Type } from 'browndash-components'; +import { Colors, EditableText, IconButton, NumberInput, Size, Slider, Type } from 'browndash-components'; import { concat } from 'lodash'; -import { Lambda, action, computed, observable } from 'mobx'; +import { action, computed, IReactionDisposer, observable, reaction, trace } from 'mobx'; import { observer } from 'mobx-react'; import { ColorState, SketchPicker } from 'react-color'; import * as Icons from 'react-icons/bs'; //{BsCollectionFill, BsFillFileEarmarkImageFill} from "react-icons/bs" -import { GrCircleInformation } from 'react-icons/gr'; -import { Utils, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents } from '../../Utils'; import { Doc, DocListCast, Field, FieldResult, HierarchyMapping, NumListCast, Opt, ReverseHierarchyMap, StrListCast } from '../../fields/Doc'; import { AclAdmin, DocAcl, DocData, Height, Width } from '../../fields/DocSymbols'; import { Id } from '../../fields/FieldSymbols'; @@ -18,31 +16,29 @@ import { InkField } from '../../fields/InkField'; import { List } from '../../fields/List'; import { ComputedField } from '../../fields/ScriptField'; import { Cast, DocCast, NumCast, StrCast } from '../../fields/Types'; -import { GetEffectiveAcl, SharingPermissions, normalizeEmail } from '../../fields/util'; -import { DocumentType } from '../documents/DocumentTypes'; +import { GetEffectiveAcl, normalizeEmail, SharingPermissions } from '../../fields/util'; +import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents, Utils } from '../../Utils'; +import { CollectionViewType, DocumentType } from '../documents/DocumentTypes'; import { DocumentManager } from '../util/DocumentManager'; import { GroupManager } from '../util/GroupManager'; import { LinkManager } from '../util/LinkManager'; import { SelectionManager } from '../util/SelectionManager'; +import { SettingsManager } from '../util/SettingsManager'; import { SharingManager } from '../util/SharingManager'; import { Transform } from '../util/Transform'; -import { UndoManager, undoBatch, undoable } from '../util/UndoManager'; +import { undoable, undoBatch, UndoManager } from '../util/UndoManager'; import { EditableView } from './EditableView'; import { FilterPanel } from './FilterPanel'; import { InkStrokeProperties } from './InkStrokeProperties'; +import { DocumentView, OpenWhere, StyleProviderFunc } from './nodes/DocumentView'; +import { KeyValueBox } from './nodes/KeyValueBox'; +import { PresBox, PresEffect, PresEffectDirection } from './nodes/trails'; import { PropertiesButtons } from './PropertiesButtons'; import { PropertiesDocBacklinksSelector } from './PropertiesDocBacklinksSelector'; import { PropertiesDocContextSelector } from './PropertiesDocContextSelector'; import { PropertiesSection } from './PropertiesSection'; import './PropertiesView.scss'; import { DefaultStyleProvider } from './StyleProvider'; -import { DocumentView, OpenWhere, StyleProviderFunc } from './nodes/DocumentView'; -import { KeyValueBox } from './nodes/KeyValueBox'; -import { PresBox, PresEffect, PresEffectDirection } from './nodes/trails'; -import { SettingsManager } from '../util/SettingsManager'; -const higflyout = require('@hig/flyout'); -export const { anchorPoints } = higflyout; -export const Flyout = higflyout.default; const _global = (window /* browser */ || global) /* node */ as any; interface PropertiesViewProps { @@ -56,6 +52,12 @@ interface PropertiesViewProps { export class PropertiesView extends React.Component<PropertiesViewProps> { private _widthUndo?: UndoManager.Batch; + public static Instance: PropertiesView | undefined; + constructor(props: any) { + super(props); + PropertiesView.Instance = this; + } + @computed get MAX_EMBED_HEIGHT() { return 200; } @@ -79,6 +81,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { } @observable layoutFields: boolean = false; + @observable layoutDocAcls: boolean = false; @observable openOptions: boolean = true; @observable openSharing: boolean = true; @@ -90,15 +93,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { @observable openTransform: boolean = true; @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 - */ - private selectedDocListenerDisposer: Opt<Lambda>; - - // @observable selectedUser: string = ""; - // @observable addButtonPressed: boolean = false; - @observable layoutDocAcls: boolean = false; - //Pres Trails booleans: @observable openPresTransitions: boolean = true; @observable openPresProgressivize: boolean = false; @@ -108,19 +102,29 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { @observable inOptions: boolean = false; @observable _controlButton: boolean = false; + private _disposers: { [name: string]: IReactionDisposer } = {}; componentDidMount() { - this.selectedDocListenerDisposer?.(); - // this.selectedDocListenerDisposer = autorun(() => this.openFilters && this.selectedDoc && this.checkFilterDoc()); + this._disposers.link = reaction( + () => LinkManager.currentLink, + link => { + link && this.CloseAll(); + link && (this.openLinks = true); + }, + { fireImmediately: true } + ); } componentWillUnmount() { - this.selectedDocListenerDisposer?.(); + Object.values(this._disposers).forEach(disposer => disposer?.()); } @computed get isInk() { return this.selectedDoc?.type === DocumentType.INK; } + @computed get isStack() { + return [CollectionViewType.Stacking, CollectionViewType.NoteTaking].includes(this.selectedDoc?.type_collection as any); + } rtfWidth = () => (!this.selectedDoc ? 0 : Math.min(this.selectedDoc?.[Width](), this.props.width - 20)); rtfHeight = () => (!this.selectedDoc ? 0 : this.rtfWidth() <= this.selectedDoc?.[Width]() ? Math.min(this.selectedDoc?.[Height](), this.MAX_EMBED_HEIGHT) : this.MAX_EMBED_HEIGHT); @@ -191,7 +195,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { }); rows.push( - <div className="propertiesView-field" key="newKeyValue" style={{ marginTop: '3px', backgroundColor: 'white', textAlign: 'center' }}> + <div className="propertiesView-field" key="newKeyValue" style={{ marginTop: '3px', backgroundColor: SettingsManager.userBackgroundColor, textAlign: 'center' }}> <EditableView key="editableView" oneLine contents={'add key:value or #tags'} height={13} fontSize={10} GetValue={() => ''} SetValue={this.setKeyValue} /> </div> ); @@ -367,7 +371,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { <IconButton icon={<FontAwesomeIcon icon={'ellipsis-h'} />} size={Size.XSMALL} - color={StrCast(Doc.UserDoc().userColor)} + color={SettingsManager.userColor} onClick={action(() => { if (this.selectedDocumentView || this.selectedDoc) { SharingManager.Instance.open(this.selectedDocumentView?.props.Document === this.selectedDoc ? this.selectedDocumentView : undefined, this.selectedDoc); @@ -517,7 +521,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { <div> <br></br> Individuals with Access to this Document </div> - <div className="propertiesView-sharingTable" style={{ background: StrCast(Doc.UserDoc().userBackgroundColor), color: StrCast(Doc.UserDoc().userColor) }}> + <div className="propertiesView-sharingTable" style={{ background: SettingsManager.userBackgroundColor, color: SettingsManager.userColor }}> {<div> {individualTableEntries}</div>} </div> {groupTableEntries.length > 0 ? ( @@ -525,7 +529,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { <div> <br></br> Groups with Access to this Document </div> - <div className="propertiesView-sharingTable" style={{ background: StrCast(Doc.UserDoc().userBackgroundColor), color: StrCast(Doc.UserDoc().userColor) }}> + <div className="propertiesView-sharingTable" style={{ background: SettingsManager.userBackgroundColor, color: SettingsManager.userColor }}> {<div> {groupTableEntries}</div>} </div> </div> @@ -545,22 +549,42 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { toggleCheckbox = () => (this.layoutFields = !this.layoutFields); @computed get color() { - return StrCast(Doc.UserDoc().userColor); + return SettingsManager.userColor; } @computed get backgroundColor() { - return StrCast(Doc.UserDoc().userBackgroundColor); + return SettingsManager.userBackgroundColor; } @computed get variantColor() { - return StrCast(Doc.UserDoc().userVariantColor); + return SettingsManager.userVariantColor; } @computed get editableTitle() { const titles = new Set<string>(); - const title = Array.from(titles.keys()).length > 1 ? '--multiple selected--' : StrCast(this.selectedDoc?.title); SelectionManager.Views().forEach(dv => titles.add(StrCast(dv.rootDoc.title))); - return <EditableText val={title} setVal={this.setTitle} color={this.color} type={Type.SEC} formLabel={'Title'} fillWidth />; + const title = Array.from(titles.keys()).length > 1 ? '--multiple selected--' : StrCast(this.selectedDoc?.title); + return ( + <div> + <EditableText val={title} setVal={this.setTitle} color={this.color} type={Type.SEC} formLabel={'Title'} fillWidth /> + {LinkManager.currentLinkAnchor ? ( + <p className="propertiesView-titleExtender"> + <> + <b>Anchor:</b> + {LinkManager.currentLinkAnchor.title} + </> + </p> + ) : null} + {LinkManager.currentLink?.title ? ( + <p className="propertiesView-titleExtender"> + <> + <b>Link:</b> + {LinkManager.currentLink.title} + </> + </p> + ) : null} + </div> + ); } @computed get currentType() { @@ -570,7 +594,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { return ( <div> - <div className="propertiesView-wordType">Type</div> + Type + {/* <div className = "propertiesView-wordType">Type</div> */} <div className="currentType"> <div className="currentType-icon">{this.currentComponent}</div> @@ -586,9 +611,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { if (iconName) { const Icon = Icons[iconName as keyof typeof Icons]; return <Icon />; - } else { - return <Icons.BsFillCollectionFill />; } + return <Icons.BsFillCollectionFill />; } @undoBatch @@ -673,7 +697,14 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { marginLeft: title === '∠:' ? '39px' : '', }}> <div className="inputBox-title"> {title} </div> - <input className="inputBox-input" type="text" value={value} onChange={e => setter(e.target.value)} onKeyPress={e => e.stopPropagation()} /> + <input + className="inputBox-input" + type="text" + value={value} + style={{ color: SettingsManager.userColor, backgroundColor: SettingsManager.userBackgroundColor }} + onChange={e => setter(e.target.value)} + onKeyPress={e => e.stopPropagation()} + /> <div className="inputBox-button"> <div className="inputBox-button-up" key="up2" onPointerDown={undoBatch(action(() => this.upDownButtons('up', key)))}> <FontAwesomeIcon icon="caret-up" size="sm" /> @@ -752,39 +783,39 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { } @computed get shapeXps() { - return this.getField('x'); + return NumCast(this.selectedDoc?.x); } @computed get shapeYps() { - return this.getField('y'); + return NumCast(this.selectedDoc?.y); } @computed get shapeHgt() { - return this.getField('_height'); + return NumCast(this.selectedDoc?._height); } @computed get shapeWid() { - return this.getField('_width'); + return NumCast(this.selectedDoc?._width); } set shapeXps(value) { - this.selectedDoc && (this.selectedDoc.x = Number(value)); + this.selectedDoc && (this.selectedDoc.x = Math.round(value * 100) / 100); } set shapeYps(value) { - this.selectedDoc && (this.selectedDoc.y = Number(value)); + this.selectedDoc && (this.selectedDoc.y = Math.round(value * 100) / 100); } set shapeWid(value) { - this.selectedDoc && (this.selectedDoc._width = Number(value)); + this.selectedDoc && (this.selectedDoc._width = Math.round(value * 100) / 100); } set shapeHgt(value) { - this.selectedDoc && (this.selectedDoc._height = Number(value)); + this.selectedDoc && (this.selectedDoc._height = Math.round(value * 100) / 100); } @computed get hgtInput() { return this.inputBoxDuo( 'hgt', this.shapeHgt, - undoable((val: string) => !isNaN(Number(val)) && (this.shapeHgt = val), 'set height'), + undoable((val: string) => !isNaN(Number(val)) && (this.shapeHgt = +val), 'set height'), 'H:', 'wid', this.shapeWid, - undoable((val: string) => !isNaN(Number(val)) && (this.shapeWid = val), 'set width'), + undoable((val: string) => !isNaN(Number(val)) && (this.shapeWid = +val), 'set width'), 'W:' ); } @@ -792,11 +823,11 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { return this.inputBoxDuo( 'Xps', this.shapeXps, - undoable((val: string) => val !== '0' && !isNaN(Number(val)) && (this.shapeXps = val), 'set x coord'), + undoable((val: string) => val !== '0' && !isNaN(Number(val)) && (this.shapeXps = +val), 'set x coord'), 'X:', 'Yps', this.shapeYps, - undoable((val: string) => val !== '0' && !isNaN(Number(val)) && (this.shapeYps = val), 'set y coord'), + undoable((val: string) => val !== '0' && !isNaN(Number(val)) && (this.shapeYps = +val), 'set y coord'), 'Y:' ); } @@ -930,7 +961,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { regInput = (key: string, value: any, setter: (val: string) => {}) => { return ( <div className="inputBox"> - <input className="inputBox-input" type="text" value={value} onChange={e => setter(e.target.value)} /> + <input className="inputBox-input" type="text" value={value} style={{ color: SettingsManager.userColor, backgroundColor: SettingsManager.userBackgroundColor }} onChange={e => setter(e.target.value)} /> <div className="inputBox-button"> <div className="inputBox-button-up" key="up2" onPointerDown={undoBatch(action(() => this.upDownButtons('up', key)))}> <FontAwesomeIcon icon="caret-up" size="sm" /> @@ -944,7 +975,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { }; @action - onDoubleClick = () => { + CloseAll = () => { this.openContexts = false; this.openLinks = false; this.openOptions = false; @@ -966,6 +997,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { <input className="width-range" type="range" + style={{ color: SettingsManager.userColor, backgroundColor: SettingsManager.userBackgroundColor }} defaultValue={Number(this.widthStk)} min={1} max={100} @@ -990,6 +1022,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { className="width-range" type="range" defaultValue={this.markScal} + style={{ color: SettingsManager.userColor, backgroundColor: SettingsManager.userBackgroundColor }} min={0} max={10} onChange={action(e => (this.markScal = +e.target.value))} @@ -1034,11 +1067,31 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { ); } - getNumber = (label: string, unit: string, min: number, max: number, number: number, setNumber: any) => { + _sliderBatch: UndoManager.Batch | undefined; + setFinalNumber = () => { + this._sliderBatch?.end(); + }; + getNumber = (label: string, unit: string, min: number, max: number, number: number, setNumber: any, autorange?: number, autorangeMinVal?: number) => { return ( - <div> + <div key={label + this.selectedDoc?.title}> <NumberInput formLabel={label} formLabelPlacement={'left'} type={Type.SEC} unit={unit} fillWidth color={this.color} number={number} setNumber={setNumber} min={min} max={max} /> - <Slider multithumb={false} color={this.color} size={Size.XSMALL} min={min} max={max} unit={unit} number={number} setNumber={setNumber} fillWidth /> + <Slider + key={label} + onPointerDown={e => (this._sliderBatch = UndoManager.StartBatch('slider ' + label))} + multithumb={false} + color={this.color} + size={Size.XSMALL} + min={min} + max={max} + autorangeMinVal={autorangeMinVal} + autorange={autorange} + number={number} + unit={unit} + decimals={1} + setFinalNumber={this.setFinalNumber} + setNumber={setNumber} + fillWidth + /> </div> ); }; @@ -1046,81 +1099,43 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { @computed get transformEditor() { return ( <div className="transform-editor"> + {!this.isStack ? null : this.getNumber('Gap', ' px', 0, 200, NumCast(this.selectedDoc!.gridGap), (val: number) => !isNaN(val) && (this.selectedDoc!.gridGap = val))} + {!this.isStack ? null : this.getNumber('xMargin', ' px', 0, 500, NumCast(this.selectedDoc!.xMargin), (val: number) => !isNaN(val) && (this.selectedDoc!.xMargin = val))} {this.isInk ? this.controlPointsButton : null} - {this.getNumber( - 'Height', - ' px', - 0, - 1000, - Number(this.shapeHgt), - undoable((val: string) => !isNaN(Number(val)) && (this.shapeHgt = val), 'set height') - )} - {this.getNumber( - 'Width', - ' px', - 0, - 1000, - Number(this.shapeWid), - undoable((val: string) => !isNaN(Number(val)) && (this.shapeWid = val), 'set width') - )} - {this.getNumber( - 'X Coordinate', - ' px', - -2000, - 2000, - Number(this.shapeXps), - undoable((val: string) => !isNaN(Number(val)) && (this.shapeXps = val), 'set x coord') - )} - {this.getNumber( - 'Y Coordinate', - ' px', - -2000, - 2000, - Number(this.shapeYps), - undoable((val: string) => !isNaN(Number(val)) && (this.shapeYps = val), 'set y coord') - )} + {this.getNumber('Width', ' px', 0, Math.max(1000, this.shapeWid), this.shapeWid, (val: number) => !isNaN(val) && (this.shapeWid = val), 1000, 1)} + {this.getNumber('Height', ' px', 0, Math.max(1000, this.shapeHgt), this.shapeHgt, (val: number) => !isNaN(val) && (this.shapeHgt = val), 1000, 1)} + {this.getNumber('X', ' px', this.shapeXps - 500, this.shapeXps + 500, this.shapeXps, (val: number) => !isNaN(val) && (this.shapeXps = val), 1000)} + {this.getNumber('Y', ' px', this.shapeYps - 500, this.shapeYps + 500, this.shapeYps, (val: number) => !isNaN(val) && (this.shapeYps = val), 1000)} </div> ); } @computed get optionsSubMenu() { return ( - <PropertiesSection - title="Options" - content={<PropertiesButtons />} - inSection={this.inOptions} - isOpen={this.openOptions} - setInSection={bool => (this.inOptions = bool)} - setIsOpen={bool => (this.openOptions = bool)} - onDoubleClick={() => this.onDoubleClick()} - /> + <PropertiesSection title="Options" inSection={this.inOptions} isOpen={this.openOptions} setInSection={bool => (this.inOptions = bool)} setIsOpen={bool => (this.openOptions = bool)} onDoubleClick={this.CloseAll}> + <PropertiesButtons /> + </PropertiesSection> ); } @computed get sharingSubMenu() { return ( - <PropertiesSection - title="Sharing & Permissions" - content={ - <> - {/* <div className="propertiesView-buttonContainer"> */} - <div className="propertiesView-acls-checkbox"> - Layout Permissions - <Checkbox color="primary" onChange={action(() => (this.layoutDocAcls = !this.layoutDocAcls))} checked={this.layoutDocAcls} /> - </div> - {/* <Tooltip title={<><div className="dash-tooltip">{"Re-distribute sharing settings"}</div></>}> - <button onPointerDown={() => SharingManager.Instance.distributeOverCollection(this.selectedDoc!)}> - <FontAwesomeIcon icon="redo-alt" size="1x" /> - </button> + <PropertiesSection title="Sharing and Permissions" isOpen={this.openSharing} setIsOpen={bool => (this.openSharing = bool)} onDoubleClick={() => this.CloseAll()}> + <> + {/* <div className="propertiesView-buttonContainer"> */} + <div className="propertiesView-acls-checkbox"> + Layout Permissions + <Checkbox color="primary" onChange={action(() => (this.layoutDocAcls = !this.layoutDocAcls))} checked={this.layoutDocAcls} /> + </div> + {/* <Tooltip title={<><div className="dash-tooltip">{"Re-distribute sharing settings"}</div></>}> + <button onPointerDown={() => SharingManager.Instance.distributeOverCollection(this.selectedDoc!)}> + <FontAwesomeIcon icon="redo-alt" size="1x" /> + </button> </Tooltip> */} - {/* </div> */} - {this.sharingTable} - </> - } - isOpen={this.openSharing} - setIsOpen={bool => (this.openSharing = bool)} - onDoubleClick={() => this.onDoubleClick()} - /> + {/* </div> */} + {this.sharingTable} + </> + </PropertiesSection> ); } @@ -1150,17 +1165,11 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { @computed get filtersSubMenu() { return ( - <PropertiesSection - title="Filters" - content={ - <div className="propertiesView-content filters" style={{ position: 'relative', height: 'auto' }}> - <FilterPanel rootDoc={this.selectedDoc ?? Doc.ActiveDashboard!} /> - </div> - } - isOpen={this.openFilters} - setIsOpen={bool => (this.openFilters = bool)} - onDoubleClick={() => this.onDoubleClick()} - /> + <PropertiesSection title="Filters" isOpen={this.openFilters} setIsOpen={bool => (this.openFilters = bool)} onDoubleClick={() => this.CloseAll()}> + <div className="propertiesView-content filters" style={{ position: 'relative', height: 'auto' }}> + <FilterPanel rootDoc={this.selectedDoc ?? Doc.ActiveDashboard!} /> + </div> + </PropertiesSection> ); } @@ -1169,42 +1178,46 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { return ( <> - <PropertiesSection title="Appearance" content={this.isInk ? this.appearanceEditor : null} isOpen={this.openAppearance} setIsOpen={bool => (this.openAppearance = bool)} onDoubleClick={() => this.onDoubleClick()} /> - <PropertiesSection title="Transform" content={this.transformEditor} isOpen={this.openTransform} setIsOpen={bool => (this.openTransform = bool)} onDoubleClick={() => this.onDoubleClick()} /> + <PropertiesSection title="Appearance" isOpen={this.openAppearance} setIsOpen={bool => (this.openAppearance = bool)} onDoubleClick={() => this.CloseAll()}> + {this.isInk ? this.appearanceEditor : null} + </PropertiesSection> + <PropertiesSection title="Transform" isOpen={this.openTransform} setIsOpen={bool => (this.openTransform = bool)} onDoubleClick={() => this.CloseAll()}> + {this.transformEditor} + </PropertiesSection> </> ); } @computed get fieldsSubMenu() { return ( - <PropertiesSection - title="Fields & Tags" - content={<div className="propertiesView-content fields">{Doc.noviceMode ? this.noviceFields : this.expandedField}</div>} - isOpen={this.openFields} - setIsOpen={bool => (this.openFields = bool)} - onDoubleClick={() => this.onDoubleClick()} - /> + <PropertiesSection title="Fields & Tags" isOpen={this.openFields} setIsOpen={bool => (this.openFields = bool)} onDoubleClick={() => this.CloseAll()}> + <div className="propertiesView-content fields">{Doc.noviceMode ? this.noviceFields : this.expandedField}</div> + </PropertiesSection> ); } @computed get contextsSubMenu() { return ( - <PropertiesSection - title="Other Contexts" - content={this.contextCount > 0 ? this.contexts : 'There are no other contexts.'} - isOpen={this.openContexts} - setIsOpen={bool => (this.openContexts = bool)} - onDoubleClick={() => this.onDoubleClick()} - /> + <PropertiesSection title="Other Contexts" isOpen={this.openContexts} setIsOpen={bool => (this.openContexts = bool)} onDoubleClick={() => this.CloseAll()}> + {this.contextCount > 0 ? this.contexts : 'There are no other contexts.'} + </PropertiesSection> ); } @computed get linksSubMenu() { - return <PropertiesSection title="Linked To" content={this.linkCount > 0 ? this.links : 'There are no current links.'} isOpen={this.openLinks} setIsOpen={bool => (this.openLinks = bool)} onDoubleClick={() => this.onDoubleClick()} />; + return ( + <PropertiesSection title="Linked To" isOpen={this.openLinks} setIsOpen={bool => (this.openLinks = bool)} onDoubleClick={this.CloseAll}> + {this.linkCount > 0 ? this.links : 'There are no current links.'} + </PropertiesSection> + ); } @computed get layoutSubMenu() { - return <PropertiesSection title="Layout" content={this.layoutPreview} isOpen={this.openLayout} setIsOpen={bool => (this.openLayout = bool)} onDoubleClick={() => this.onDoubleClick()} />; + return ( + <PropertiesSection title="Layout" isOpen={this.openLayout} setIsOpen={bool => (this.openLayout = bool)} onDoubleClick={this.CloseAll}> + {this.layoutPreview} + </PropertiesSection> + ); } @computed get description() { @@ -1314,10 +1327,10 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { }; onDescriptionKey = (e: React.KeyboardEvent<HTMLTextAreaElement>) => { - if (e.key === 'Enter') { - this.setDescripValue(this.description); - document.getElementById('link_description_input')?.blur(); - } + // if (e.key === 'Enter') { + // this.setDescripValue(this.description); + // document.getElementById('link_description_input')?.blur(); + // } }; onSelectOutRelationship = () => { @@ -1369,6 +1382,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { get editRelationship() { return ( <input + style={{ color: SettingsManager.userColor, backgroundColor: SettingsManager.userBackgroundColor }} autoComplete={'off'} id="link_relationship_input" value={StrCast(LinkManager.currentLink?.link_relationship)} @@ -1386,7 +1400,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { return ( <textarea autoComplete="off" - style={{ textAlign: 'left' }} + style={{ textAlign: 'left', color: SettingsManager.userColor, backgroundColor: SettingsManager.userBackgroundColor }} id="link_description_input" value={StrCast(LinkManager.currentLink?.link_description)} onKeyDown={this.onDescriptionKey} @@ -1414,7 +1428,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { return ( <> - <div className="propertiesView-section" style={{ background: 'darkgray' }}> + <div className="propertiesView-section"> <div className="propertiesView-input first" style={{ display: 'grid', gridTemplateColumns: '84px auto' }}> <p>Relationship</p> {this.editRelationship} @@ -1458,7 +1472,10 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { <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)}> + <select + style={{ color: SettingsManager.userColor, backgroundColor: SettingsManager.userBackgroundColor }} + 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> @@ -1473,7 +1490,10 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { </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')}> + <select + style={{ width: '100%', gridColumn: 2, color: SettingsManager.userColor, backgroundColor: SettingsManager.userBackgroundColor }} + 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 key={effect.toString()} value={effect.toString()}> @@ -1523,6 +1543,16 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { </button> </div> <div className="propertiesView-input inline"> + <p>Play Target Video</p> + <button + style={{ background: !this.sourceAnchor?.followLinkVideo ? '' : '#4476f7', borderRadius: 3 }} + onPointerDown={e => this.toggleAnchorProp(e, 'followLinkVideo', 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 }} @@ -1588,7 +1618,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { <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%' }} readOnly={true} type="number" value={zoom} /> + <input className="presBox-input" style={{ width: '100%', color: SettingsManager.userColor, backgroundColor: SettingsManager.userBackgroundColor }} readOnly={true} 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'} /> @@ -1655,30 +1685,30 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { <div className="propertiesView" style={{ - background: StrCast(Doc.UserDoc().userBackgroundColor), - color: StrCast(Doc.UserDoc().userColor), + background: SettingsManager.userBackgroundColor, + color: SettingsManager.userColor, width: this.props.width, minWidth: this.props.width, }}> <div className="propertiesView-propAndInfoGrouping"> <div className="propertiesView-title" style={{ width: this.props.width }}> Properties - </div> - <div className="propertiesView-info" onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/')}> - <GrCircleInformation />{' '} + <div className="propertiesView-info" onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/properties')}> + <IconButton icon={<FontAwesomeIcon icon="info-circle" />} color={SettingsManager.userColor} /> + </div> </div> </div> <div className="propertiesView-name">{this.editableTitle}</div> <div className="propertiesView-type"> {this.currentType} </div> - {this.contextsSubMenu} + {this.optionsSubMenu} {this.linksSubMenu} - {!this.selectedDoc || !LinkManager.currentLink || (!hasSelectedAnchor && this.selectedDoc !== LinkManager.currentLink) ? null : this.linkProperties} + {!LinkManager.currentLink || !this.openLinks ? null : this.linkProperties} {this.inkSubMenu} - {this.optionsSubMenu} + {this.contextsSubMenu} {this.fieldsSubMenu} {isNovice ? null : this.sharingSubMenu} - {isNovice ? null : this.filtersSubMenu} + {this.filtersSubMenu} {isNovice ? null : this.layoutSubMenu} </div> ); @@ -1706,8 +1736,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { className="propertiesView-presentationTrails-title" onPointerDown={action(() => (this.openPresTransitions = !this.openPresTransitions))} style={{ - color: SettingsManager.Instance.userColor, - backgroundColor: this.openPresTransitions ? SettingsManager.Instance.userVariantColor : SettingsManager.Instance.userBackgroundColor, + color: SettingsManager.userColor, + backgroundColor: this.openPresTransitions ? SettingsManager.userVariantColor : SettingsManager.userBackgroundColor, }}> <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={'rocket'} /> Transitions <div className="propertiesView-presentationTrails-title-icon"> @@ -1723,15 +1753,15 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { className="propertiesView-presentationTrails-title" onPointerDown={action(() => (this.openPresVisibilityAndDuration = !this.openPresVisibilityAndDuration))} style={{ - color: SettingsManager.Instance.userColor, - backgroundColor: this.openPresVisibilityAndDuration ? SettingsManager.Instance.userVariantColor : SettingsManager.Instance.userBackgroundColor, + color: SettingsManager.userColor, + backgroundColor: this.openPresVisibilityAndDuration ? SettingsManager.userVariantColor : SettingsManager.userBackgroundColor, }}> - <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={'rocket'} /> Visibilty + <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={'rocket'} /> Visibility <div className="propertiesView-presentationTrails-title-icon"> <FontAwesomeIcon icon={this.openPresVisibilityAndDuration ? 'caret-down' : 'caret-right'} size="lg" /> </div> </div> - {this.openPresVisibilityAndDuration ? <div className="propertiesView-presentationTrails-content">{PresBox.Instance.visibiltyDurationDropdown}</div> : null} + {this.openPresVisibilityAndDuration ? <div className="propertiesView-presentationTrails-content">{PresBox.Instance.visibilityDurationDropdown}</div> : null} </div> )} {!selectedItem ? null : ( @@ -1740,8 +1770,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { className="propertiesView-presentationTrails-title" onPointerDown={action(() => (this.openPresProgressivize = !this.openPresProgressivize))} style={{ - color: SettingsManager.Instance.userColor, - backgroundColor: this.openPresProgressivize ? SettingsManager.Instance.userVariantColor : SettingsManager.Instance.userBackgroundColor, + color: SettingsManager.userColor, + backgroundColor: this.openPresProgressivize ? SettingsManager.userVariantColor : SettingsManager.userBackgroundColor, }}> <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={'rocket'} /> Progressivize <div className="propertiesView-presentationTrails-title-icon"> @@ -1757,8 +1787,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { className="propertiesView-presentationTrails-title" onPointerDown={action(() => (this.openSlideOptions = !this.openSlideOptions))} style={{ - color: SettingsManager.Instance.userColor, - backgroundColor: this.openSlideOptions ? SettingsManager.Instance.userVariantColor : SettingsManager.Instance.userBackgroundColor, + color: SettingsManager.userColor, + backgroundColor: this.openSlideOptions ? SettingsManager.userVariantColor : SettingsManager.userBackgroundColor, }}> <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={type === DocumentType.AUDIO ? 'file-audio' : 'file-video'} /> {type === DocumentType.AUDIO ? 'Audio Options' : 'Video Options'} <div className="propertiesView-presentationTrails-title-icon"> |
