diff options
| author | srichman333 <sarah_n_richman@brown.edu> | 2023-06-14 17:23:23 -0400 |
|---|---|---|
| committer | srichman333 <sarah_n_richman@brown.edu> | 2023-06-14 17:23:23 -0400 |
| commit | f0474c18d092f4db49255a1e92d7f052b7398897 (patch) | |
| tree | 1e26ccaf42dec4d99904e2eddb36dff6f3b55948 /src/client/views/PropertiesView.tsx | |
| parent | 20d217d825891cf29a432a048d1f8e7bc04d062a (diff) | |
| parent | bf1198fbe73847087b1ec8e00a43306816b3508a (diff) | |
Merge branch 'master' into collaboration-sarah
Diffstat (limited to 'src/client/views/PropertiesView.tsx')
| -rw-r--r-- | src/client/views/PropertiesView.tsx | 399 |
1 files changed, 160 insertions, 239 deletions
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index fb21c2db2..b6699c3bf 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -6,7 +6,7 @@ import { Checkbox, Tooltip } from '@material-ui/core'; import { action, computed, Lambda, observable } from 'mobx'; import { observer } from 'mobx-react'; import { ColorState, SketchPicker } from 'react-color'; -import { AclAdmin, DataSym, Doc, Field, FieldResult, HeightSym, NumListCast, Opt, StrListCast, WidthSym } from '../../fields/Doc'; +import { AclAdmin, AclSym, DataSym, Doc, Field, FieldResult, HeightSym, HierarchyMapping, NumListCast, Opt, StrListCast, WidthSym } from '../../fields/Doc'; import { Id } from '../../fields/FieldSymbols'; import { InkField } from '../../fields/InkField'; import { List } from '../../fields/List'; @@ -20,7 +20,7 @@ import { LinkManager } from '../util/LinkManager'; import { SelectionManager } from '../util/SelectionManager'; import { SharingManager } from '../util/SharingManager'; import { Transform } from '../util/Transform'; -import { undoBatch, UndoManager } from '../util/UndoManager'; +import { undoable, undoBatch, UndoManager } from '../util/UndoManager'; import { EditableView } from './EditableView'; import { FilterPanel } from './FilterPanel'; import { Colors } from './global/globalEnums'; @@ -68,7 +68,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { return this.selectedDoc?.type === DocumentType.LINK; } @computed get dataDoc() { - return this.selectedDoc?.[DataSym]; + return this.selectedDoc?.[DocData]; } @observable layoutFields: boolean = false; @@ -115,19 +115,18 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { return this.selectedDoc?.type === DocumentType.INK; } - 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); + 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); @action docWidth = () => { if (this.selectedDoc) { const layoutDoc = this.selectedDoc; - const aspect = Doc.NativeAspect(layoutDoc, undefined, !layoutDoc._fitWidth); - if (aspect) return Math.min(layoutDoc[WidthSym](), Math.min(this.MAX_EMBED_HEIGHT * aspect, this.props.width - 20)); - return Doc.NativeWidth(layoutDoc) ? Math.min(layoutDoc[WidthSym](), this.props.width - 20) : this.props.width - 20; - } else { - return 0; + const aspect = Doc.NativeAspect(layoutDoc, undefined, !layoutDoc._layout_fitWidth); + if (aspect) return Math.min(layoutDoc[Width](), Math.min(this.MAX_EMBED_HEIGHT * aspect, this.props.width - 20)); + return Doc.NativeWidth(layoutDoc) ? Math.min(layoutDoc[Width](), this.props.width - 20) : this.props.width - 20; } + return 0; }; @action @@ -140,7 +139,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { this.MAX_EMBED_HEIGHT, Doc.NativeAspect(layoutDoc, undefined, true) ? this.docWidth() / Doc.NativeAspect(layoutDoc, undefined, true) - : layoutDoc._fitWidth + : layoutDoc._layout_fitWidth ? !Doc.NativeHeight(this.dataDoc) ? NumCast(this.props.height) : Math.min((this.docWidth() * Doc.NativeHeight(layoutDoc)) / Doc.NativeWidth(layoutDoc) || NumCast(this.props.height)) @@ -198,13 +197,13 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { } @computed get noviceFields() { - const noviceReqFields = ['author', 'creationDate', 'tags', '_curPage']; - return this.editableFields(key => key.indexOf('lastModified') !== -1 || (key[0] === key[0].toUpperCase() && !key.startsWith('acl')), noviceReqFields); + const noviceReqFields = ['author', 'author_date', 'tags', '_layout_curPage']; + return this.editableFields(key => key.indexOf('modificationDate') !== -1 || (key[0] === key[0].toUpperCase() && !key.startsWith('acl')), noviceReqFields); } @undoBatch setKeyValue = (value: string) => { - const docs = SelectionManager.Views().length < 2 && this.selectedDoc ? [this.layoutFields ? Doc.Layout(this.selectedDoc) : this.dataDoc] : SelectionManager.Views().map(dv => (this.layoutFields ? dv.layoutDoc : dv.dataDoc)); + const docs = SelectionManager.Views().length < 2 && this.selectedDoc ? [this.layoutFields ? Doc.Layout(this.selectedDoc) : this.dataDoc!] : SelectionManager.Views().map(dv => (this.layoutFields ? dv.layoutDoc : dv.dataDoc)); docs.forEach(doc => { if (value.indexOf(':') !== -1) { const newVal = value[0].toUpperCase() + value.substring(1, value.length); @@ -219,7 +218,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { const tags = StrListCast(doc.tags); if (!tags.includes(value)) { tags.push(value); - doc[DataSym].tags = tags.length ? new List<string>(tags) : undefined; + doc[DocData].tags = tags.length ? new List<string>(tags) : undefined; } return true; } @@ -275,8 +274,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { PanelHeight={panelHeight} focus={emptyFunction} ScreenToLocalTransform={this.getTransform} - docFilters={returnEmptyFilter} - docRangeFilters={returnEmptyFilter} + childFilters={returnEmptyFilter} + childFiltersByRanges={returnEmptyFilter} searchFilterDocs={returnEmptyDoclist} addDocument={returnFalse} moveDocument={undefined} @@ -300,7 +299,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { */ @undoBatch changePermissions = (e: any, user: string) => { - 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])); + 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)[DocData])); SharingManager.Instance.shareFromPropertiesSidebar(user, e.currentTarget.value as SharingPermissions, docs); }; @@ -436,7 +435,9 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { return null; } // all selected docs - const docs = SelectionManager.Views().length < 2 ? [this.layoutDocAcls ? docToUse : docToUse?.[DataSym]] : SelectionManager.Views().map(docView => (this.layoutDocAcls ? docView.props.Document : docView.props.Document[DataSym])); + 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])); + const target = docs[0]; // const effectiveAcls = GetEffectiveAcl(target); @@ -445,17 +446,18 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { const showAdmin = curUserAcl == 'Admin' || curUserAcl == 'Owner' // users in common between all docs - // const commonKeys: string[] = intersection(...docs.map(doc => doc?.[AclSym] && Object.keys(doc[AclSym]).filter(key => key !== 'acl-Me'))); - // const ownerSame = Doc.CurrentUserEmail !== target.author && docs.filter(doc => doc).every(doc => doc.author === docs[0].author); + const commonKeys: string[] = intersection(...docs.map(doc => doc?.[AclSym] && Object.keys(doc[AclSym]).filter(key => key !== 'acl-Me'))); + const tableEntries = []; const usersAdded: string[] = []; // all shared users being added - organized by denormalized email - SharingManager.Instance.users.forEach(eachUser => { - var userOnDashboard = true; - var permission = StrCast(target[`acl-${normalizeEmail(eachUser.user.email)}`]); - if (Doc.ActiveDashboard) { - if (Doc.ActiveDashboard['acl-' + normalizeEmail(eachUser.user.email)] == '' || Doc.ActiveDashboard['acl-' + normalizeEmail(eachUser.user.email)] == undefined) { - userOnDashboard = false; + // DocCastAsync(Doc.UserDoc().sidebarUsersDisplayed).then(sidebarUsersDisplayed => { + if (commonKeys.length) { + for (const key of commonKeys) { + const name = denormalizeEmail(key.substring(4)); + 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 ? HierarchyMapping.get(target[AclSym][key])!.name : '-multiple-')); } } if (userOnDashboard && !usersAdded.includes(eachUser.user.email) && eachUser.user.email != 'Public' && eachUser.user.email != target.author) { @@ -464,11 +466,19 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { } }); - usersAdded.sort(this.sortUsers); - usersAdded.map(userEmail => { - const permission = StrCast(target[`acl-${normalizeEmail(userEmail)}`]); - tableEntries.unshift(this.sharingItem(userEmail, showAdmin, permission, false)); // adds each user - }); + 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-")); + 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]) ? HierarchyMapping.get(effectiveAcls[0])!.name : '-multiple-', + !ownerSame + ) + ); // add current user var userEmail = Doc.CurrentUserEmail; @@ -500,9 +510,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { } @action - toggleCheckbox = () => { - this.layoutFields = !this.layoutFields; - }; + toggleCheckbox = () => (this.layoutFields = !this.layoutFields); @computed get editableTitle() { const titles = new Set<string>(); @@ -600,17 +608,7 @@ 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} 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" color="white" size="sm" /> @@ -634,55 +632,50 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { @action upDownButtons = (dirs: string, field: string) => { + const selDoc = this.selectedDoc; + if (!selDoc) return; + //prettier-ignore switch (field) { - case 'Xps': - this.selectedDoc && (this.selectedDoc.x = NumCast(this.selectedDoc?.x) + (dirs === 'up' ? 10 : -10)); - break; - case 'Yps': - this.selectedDoc && (this.selectedDoc.y = NumCast(this.selectedDoc?.y) + (dirs === 'up' ? 10 : -10)); - break; - case 'stk': - this.selectedDoc && (this.selectedDoc.strokeWidth = NumCast(this.selectedDoc?.strokeWidth) + (dirs === 'up' ? 0.1 : -0.1)); - break; + case 'Xps': selDoc.x = NumCast(this.selectedDoc?.x) + (dirs === 'up' ? 10 : -10); break; + case 'Yps': selDoc.y = NumCast(this.selectedDoc?.y) + (dirs === 'up' ? 10 : -10); break; + case 'stk': selDoc.stroke_width = NumCast(this.selectedDoc?.stroke_width) + (dirs === 'up' ? 0.1 : -0.1); break; case 'wid': - const oldWidth = NumCast(this.selectedDoc?._width); - const oldHeight = NumCast(this.selectedDoc?._height); - const oldX = NumCast(this.selectedDoc?.x); - const oldY = NumCast(this.selectedDoc?.y); - this.selectedDoc && (this.selectedDoc._width = oldWidth + (dirs === 'up' ? 10 : -10)); - const doc = this.selectedDoc; - if (doc?.type === DocumentType.INK && doc.x && doc.y && doc._height && doc._width) { - const ink = Cast(doc.data, InkField)?.inkData; + const oldWidth = NumCast(selDoc._width); + const oldHeight = NumCast(selDoc._height); + const oldX = NumCast(selDoc.x); + const oldY = NumCast(selDoc.y); + selDoc._width = oldWidth + (dirs === 'up' ? 10 : -10); + if (selDoc.type === DocumentType.INK && selDoc.x && selDoc.y && selDoc._height && selDoc._width) { + const ink = Cast(selDoc.data, InkField)?.inkData; if (ink) { const newPoints: { X: number; Y: number }[] = []; for (var j = 0; j < ink.length; j++) { // (new x — oldx) + (oldxpoint * newWidt)/oldWidth - const newX = NumCast(doc.x) - oldX + (ink[j].X * NumCast(doc._width)) / oldWidth; - const newY = NumCast(doc.y) - oldY + (ink[j].Y * NumCast(doc._height)) / oldHeight; + const newX = NumCast(selDoc.x) - oldX + (ink[j].X * NumCast(selDoc._width)) / oldWidth; + const newY = NumCast(selDoc.y) - oldY + (ink[j].Y * NumCast(selDoc._height)) / oldHeight; newPoints.push({ X: newX, Y: newY }); } - doc.data = new InkField(newPoints); + selDoc.data = new InkField(newPoints); } } break; case 'hgt': - const oWidth = NumCast(this.selectedDoc?._width); - const oHeight = NumCast(this.selectedDoc?._height); - const oX = NumCast(this.selectedDoc?.x); - const oY = NumCast(this.selectedDoc?.y); - this.selectedDoc && (this.selectedDoc._height = oHeight + (dirs === 'up' ? 10 : -10)); - const docu = this.selectedDoc; - if (docu?.type === DocumentType.INK && docu.x && docu.y && docu._height && docu._width) { - const ink = Cast(docu.data, InkField)?.inkData; + const oWidth = NumCast(selDoc._width); + const oHeight = NumCast(selDoc._height); + const oX = NumCast(selDoc.x); + const oY = NumCast(selDoc.y); + selDoc._height = oHeight + (dirs === 'up' ? 10 : -10); + if (selDoc.type === DocumentType.INK && selDoc.x && selDoc.y && selDoc._height && selDoc._width) { + const ink = Cast(selDoc.data, InkField)?.inkData; if (ink) { const newPoints: { X: number; Y: number }[] = []; for (var j = 0; j < ink.length; j++) { // (new x — oldx) + (oldxpoint * newWidt)/oldWidth - const newX = NumCast(docu.x) - oX + (ink[j].X * NumCast(docu._width)) / oWidth; - const newY = NumCast(docu.y) - oY + (ink[j].Y * NumCast(docu._height)) / oHeight; + const newX = NumCast(selDoc.x) - oX + (ink[j].X * NumCast(selDoc._width)) / oWidth; + const newY = NumCast(selDoc.y) - oY + (ink[j].Y * NumCast(selDoc._height)) / oHeight; newPoints.push({ X: newX, Y: newY }); } - docu.data = new InkField(newPoints); + selDoc.data = new InkField(newPoints); } } break; @@ -722,21 +715,11 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { return this.inputBoxDuo( 'hgt', this.shapeHgt, - (val: string) => { - if (!isNaN(Number(val))) { - this.shapeHgt = val; - } - return true; - }, + undoable((val: string) => !isNaN(Number(val)) && (this.shapeHgt = val), 'set height'), 'H:', 'wid', this.shapeWid, - (val: string) => { - if (!isNaN(Number(val))) { - this.shapeWid = val; - } - return true; - }, + undoable((val: string) => !isNaN(Number(val)) && (this.shapeWid = val), 'set width'), 'W:' ); } @@ -744,21 +727,11 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { return this.inputBoxDuo( 'Xps', this.shapeXps, - (val: string) => { - if (val !== '0' && !isNaN(Number(val))) { - this.shapeXps = val; - } - return true; - }, + undoable((val: string) => val !== '0' && !isNaN(Number(val)) && (this.shapeXps = val), 'set x coord'), 'X:', 'Yps', this.shapeYps, - (val: string) => { - if (val !== '0' && !isNaN(Number(val))) { - this.shapeYps = val; - } - return true; - }, + undoable((val: string) => val !== '0' && !isNaN(Number(val)) && (this.shapeYps = val), 'set y coord'), 'Y:' ); } @@ -766,36 +739,24 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { @observable private _fillBtn = false; @observable private _lineBtn = false; - private _lastFill = '#D0021B'; - private _lastLine = '#D0021B'; private _lastDash: any = '2'; @computed get colorFil() { - const ccol = this.getField('fillColor') || ''; - ccol && (this._lastFill = ccol); - return ccol; + return StrCast(this.selectedDoc?.fillColor); } @computed get colorStk() { - const ccol = this.getField('color') || ''; - ccol && (this._lastLine = ccol); - return ccol; + return StrCast(this.selectedDoc?.color); } set colorFil(value) { - value && (this._lastFill = value); this.selectedDoc && (this.selectedDoc.fillColor = value ? value : undefined); } set colorStk(value) { - value && (this._lastLine = value); this.selectedDoc && (this.selectedDoc.color = value ? value : undefined); } - colorButton(value: string, type: string, setter: () => {}) { - // return <div className="properties-flyout" onPointerEnter={e => this.changeScrolling(false)} - // onPointerLeave={e => this.changeScrolling(true)}> - // <Flyout anchorPoint={anchorPoints.LEFT_TOP} - // content={type === "fill" ? this.fillPicker : this.linePicker}> + colorButton(value: string, type: string, setter: () => void) { return ( - <div className="color-button" key="color" onPointerDown={undoBatch(action(e => setter()))}> + <div className="color-button" key="color" onPointerDown={action(e => setter())}> <div className="color-button-preview" style={{ @@ -808,31 +769,17 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { {value === '' || value === 'transparent' ? <p style={{ fontSize: 25, color: 'red', marginTop: -14 }}>☒</p> : ''} </div> ); - // </Flyout> - // </div>; } - @undoBatch - @action - switchStk = (color: ColorState) => { - const val = String(color.hex); - this.colorStk = val; - return true; - }; - @undoBatch - @action - switchFil = (color: ColorState) => { - const val = String(color.hex); - this.colorFil = val; - return true; - }; - - colorPicker(setter: (color: string) => {}, type: string) { + colorPicker(color: string, setter: (color: string) => void) { return ( <SketchPicker - onChange={type === 'stk' ? this.switchStk : this.switchFil} + onChange={undoable( + action((color: ColorState) => setter(color.hex)), + 'set stroke color property' + )} presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF', '#f1efeb', 'transparent']} - color={type === 'stk' ? this.colorStk : this.colorFil} + color={color} /> ); } @@ -841,22 +788,20 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { return this.colorButton(this.colorFil, 'fill', () => { this._fillBtn = !this._fillBtn; this._lineBtn = false; - return true; }); } @computed get lineButton() { return this.colorButton(this.colorStk, 'line', () => { this._lineBtn = !this._lineBtn; this._fillBtn = false; - return true; }); } @computed get fillPicker() { - return this.colorPicker((color: string) => (this.colorFil = color), 'fil'); + return this.colorPicker(this.colorFil, (color: string) => (this.colorFil = color)); } @computed get linePicker() { - return this.colorPicker((color: string) => (this.colorStk = color), 'stk'); + return this.colorPicker(this.colorStk, (color: string) => (this.colorStk = color)); } @computed get strokeAndFill() { @@ -878,49 +823,36 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { ); } - @computed get solidStk() { - return this.selectedDoc?.color && (!this.selectedDoc?.strokeDash || this.selectedDoc?.strokeDash === '0') ? true : false; - } @computed get dashdStk() { - return this.selectedDoc?.strokeDash || ''; - } - @computed get unStrokd() { - return this.selectedDoc?.color ? true : false; + return this.selectedDoc?.stroke_dash || ''; } @computed get widthStk() { - return this.getField('strokeWidth') || '1'; + return this.getField('stroke_width') || '1'; } @computed get markScal() { - return Number(this.getField('strokeMakerScale') || '1'); + return Number(this.getField('stroke_markerScale') || '1'); } @computed get markHead() { - return this.getField('strokeStartMarker') || ''; + return this.getField('stroke_startMarker') || ''; } @computed get markTail() { - return this.getField('strokeEndMarker') || ''; - } - set solidStk(value) { - this.dashdStk = ''; - this.unStrokd = !value; + return this.getField('stroke_endMarker') || ''; } set dashdStk(value) { - value && (this._lastDash = value) && (this.unStrokd = false); - this.selectedDoc && (this.selectedDoc.strokeDash = value ? this._lastDash : undefined); + value && (this._lastDash = value); + this.selectedDoc && (this.selectedDoc.stroke_dash = value ? this._lastDash : undefined); } set markScal(value) { - this.selectedDoc && (this.selectedDoc.strokeMarkerScale = Number(value)); + this.selectedDoc && (this.selectedDoc.stroke_markerScale = Number(value)); } set widthStk(value) { - this.selectedDoc && (this.selectedDoc.strokeWidth = Number(value)); - } - set unStrokd(value) { - this.colorStk = value ? '' : this._lastLine; + this.selectedDoc && (this.selectedDoc.stroke_width = Number(value)); } set markHead(value) { - this.selectedDoc && (this.selectedDoc.strokeStartMarker = value); + this.selectedDoc && (this.selectedDoc.stroke_startMarker = value); } set markTail(value) { - this.selectedDoc && (this.selectedDoc.strokeEndMarker = value); + this.selectedDoc && (this.selectedDoc.stroke_endMarker = value); } @computed get stkInput() { @@ -1086,26 +1018,26 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { } /** - * Updates this.filterDoc's currentFilter and saves the docFilters on the currentFilter + * Updates this.filterDoc's currentFilter and saves the childFilters on the currentFilter */ updateFilterDoc = (doc: Doc) => { if (this.selectedDoc) { if (doc === this.selectedDoc.currentFilter) return; // causes problems if you try to reapply the same doc - const savedDocFilters = doc._docFiltersList; - const currentDocFilters = this.selectedDoc._docFilters; - this.selectedDoc._docFilters = new List<string>(); - (this.selectedDoc.currentFilter as Doc)._docFiltersList = currentDocFilters; + const savedDocFilters = doc._childFiltersList; + const currentDocFilters = this.selectedDoc._childFilters; + this.selectedDoc._childFilters = new List<string>(); + (this.selectedDoc.currentFilter as Doc)._childFiltersList = currentDocFilters; this.selectedDoc.currentFilter = doc; - doc._docFiltersList = new List<string>(); - this.selectedDoc._docFilters = savedDocFilters; + doc._childFiltersList = new List<string>(); + this.selectedDoc._childFilters = savedDocFilters; - const savedDocRangeFilters = doc._docRangeFiltersList; - const currentDocRangeFilters = this.selectedDoc._docRangeFilters; - this.selectedDoc._docRangeFilters = new List<string>(); - (this.selectedDoc.currentFilter as Doc)._docRangeFiltersList = currentDocRangeFilters; + const savedDocRangeFilters = doc._childFiltersByRangesList; + const currentDocRangeFilters = this.selectedDoc._childFiltersByRanges; + this.selectedDoc._childFiltersByRanges = new List<string>(); + (this.selectedDoc.currentFilter as Doc)._childFiltersByRangesList = currentDocRangeFilters; this.selectedDoc.currentFilter = doc; - doc._docRangeFiltersList = new List<string>(); - this.selectedDoc._docRangeFilters = savedDocRangeFilters; + doc._childFiltersByRangesList = new List<string>(); + this.selectedDoc._childFiltersByRanges = savedDocRangeFilters; } }; @@ -1218,50 +1150,51 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { } @computed get description() { - return Field.toString(LinkManager.currentLink?.description as any as Field); + return Field.toString(LinkManager.currentLink?.link_description as any as Field); } @computed get relationship() { - return StrCast(LinkManager.currentLink?.linkRelationship); + return StrCast(LinkManager.currentLink?.link_relationship); } @observable private relationshipButtonColor: string = ''; // @action - // handleDescriptionChange = (e: React.ChangeEvent<HTMLInputElement>) => { this.description = e.target.value; } - // handleRelationshipChange = (e: React.ChangeEvent<HTMLInputElement>) => { this.relationship = e.target.value; } + // handleDescriptionChange = (e: React.ChangeEvent<HTMLInputElement>) => { this.link_description = e.target.value; } + // handleRelationshipChange = (e: React.ChangeEvent<HTMLInputElement>) => { this.link_relationship = e.target.value; } - @undoBatch - handleDescriptionChange = action((value: string) => { - if (LinkManager.currentLink && this.selectedDoc) { - this.setDescripValue(value); - return true; - } - }); - - @undoBatch - handleLinkRelationshipChange = action((value: string) => { - if (LinkManager.currentLink && this.selectedDoc) { - this.setLinkRelationshipValue(value); - return true; - } - }); + handleDescriptionChange = undoable( + action((value: string) => { + if (LinkManager.currentLink && this.selectedDoc) { + this.setDescripValue(value); + } + }), + 'change link description' + ); + + handlelinkRelationshipChange = undoable( + action((value: string) => { + if (LinkManager.currentLink && this.selectedDoc) { + this.setlinkRelationshipValue(value); + } + }), + 'change link relationship' + ); @undoBatch setDescripValue = action((value: string) => { if (LinkManager.currentLink) { - Doc.GetProto(LinkManager.currentLink).description = value; - return true; + Doc.GetProto(LinkManager.currentLink).link_description = value; } }); @undoBatch - setLinkRelationshipValue = action((value: string) => { + setlinkRelationshipValue = action((value: string) => { if (LinkManager.currentLink) { - const prevRelationship = LinkManager.currentLink.linkRelationship as string; - LinkManager.currentLink.linkRelationship = value; - Doc.GetProto(LinkManager.currentLink).linkRelationship = value; - const linkRelationshipList = StrListCast(Doc.UserDoc().linkRelationshipList); - const linkRelationshipSizes = NumListCast(Doc.UserDoc().linkRelationshipSizes); - const linkColorList = StrListCast(Doc.UserDoc().linkColorList); + const prevRelationship = StrCast(LinkManager.currentLink.link_relationship); + LinkManager.currentLink.link_relationship = value; + Doc.GetProto(LinkManager.currentLink).link_relationship = value; + const linkRelationshipList = StrListCast(Doc.UserDoc().link_relationshipList); + const linkRelationshipSizes = NumListCast(Doc.UserDoc().link_relationshipSizes); + const linkColorList = StrListCast(Doc.UserDoc().link_ColorList); // if the relationship does not exist in the list, add it and a corresponding unique randomly generated color if (!linkRelationshipList?.includes(value)) { @@ -1295,8 +1228,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { } }); - @undoBatch - changeFollowBehavior = action((follow: Opt<string>) => this.sourceAnchor && (this.sourceAnchor.followLinkLocation = follow)); + changeFollowBehavior = undoable((loc: Opt<string>) => this.sourceAnchor && (this.sourceAnchor.followLinkLocation = loc), 'change follow behavior'); @undoBatch changeAnimationBehavior = action((behavior: string) => this.sourceAnchor && (this.sourceAnchor.followLinkAnimEffect = behavior)); @@ -1331,13 +1263,13 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { }; onSelectOutRelationship = () => { - this.setLinkRelationshipValue(this.relationship); + this.setlinkRelationshipValue(this.relationship); document.getElementById('link_relationship_input')?.blur(); }; onRelationshipKey = (e: React.KeyboardEvent<HTMLInputElement>) => { if (e.key === 'Enter') { - this.setLinkRelationshipValue(this.relationship); + this.setlinkRelationshipValue(this.relationship); document.getElementById('link_relationship_input')?.blur(); } }; @@ -1350,7 +1282,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { 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; + return ldoc ? DocCast(ldoc.link_anchor_2) : ldoc; } @computed get sourceAnchor() { @@ -1381,10 +1313,10 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { <input autoComplete={'off'} id="link_relationship_input" - value={StrCast(this.selectedDoc?.linkRelationship)} + value={StrCast(LinkManager.currentLink?.link_relationship)} onKeyDown={this.onRelationshipKey} onBlur={this.onSelectOutRelationship} - onChange={e => this.handleLinkRelationshipChange(e.currentTarget.value)} + onChange={e => this.handlelinkRelationshipChange(e.currentTarget.value)} className="text" type="text" /> @@ -1398,7 +1330,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { autoComplete="off" style={{ textAlign: 'left' }} id="link_description_input" - value={StrCast(this.selectedDoc?.description)} + value={StrCast(LinkManager.currentLink?.link_description)} onKeyDown={this.onDescriptionKey} onBlur={this.onSelectOutDesc} onChange={e => this.handleDescriptionChange(e.currentTarget.value)} @@ -1473,8 +1405,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { <div className="propertiesView-input inline"> <p>Show link</p> <button - style={{ background: !LinkManager.currentLink?.linkDisplay ? '' : '#4476f7', borderRadius: 3 }} - onPointerDown={e => this.toggleLinkProp(e, 'linkDisplay')} + style={{ background: !LinkManager.currentLink?.link_displayLine ? '' : '#4476f7', borderRadius: 3 }} + onPointerDown={e => this.toggleLinkProp(e, 'link_displayLine')} onClick={e => e.stopPropagation()} className="propertiesButton"> <FontAwesomeIcon className="fa-icon" icon={faArrowRight as IconLookup} size="lg" /> @@ -1483,8 +1415,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { <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')} + style={{ background: !LinkManager.currentLink?.link_autoMoveAnchors ? '' : '#4476f7', borderRadius: 3 }} + onPointerDown={e => this.toggleLinkProp(e, 'link_autoMoveAnchors')} onClick={e => e.stopPropagation()} className="propertiesButton"> <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" /> @@ -1493,8 +1425,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { <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')} + style={{ background: !LinkManager.currentLink?.link_displayArrow ? '' : '#4476f7', borderRadius: 3 }} + onPointerDown={e => this.toggleLinkProp(e, 'link_displayArrow')} onClick={e => e.stopPropagation()} className="propertiesButton"> <FontAwesomeIcon className="fa-icon" icon={faArrowRight as IconLookup} size="lg" /> @@ -1524,7 +1456,9 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { <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> + <option key={effect.toString()} 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' }}> @@ -1634,7 +1568,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%' }} type="number" value={zoom} /> + <input className="presBox-input" style={{ width: '100%' }} 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'} /> @@ -1686,8 +1620,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { </div> ); } - if (this.isPres) { - const selectedItem: boolean = PresBox.Instance?.selectedArray.size > 0; + if (this.isPres && PresBox.Instance) { + 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; @@ -1699,8 +1633,8 @@ 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-selectedList">{PresBox.Instance?.listOfSelected}</div> + <div className="propertiesView-selectedCount">{PresBox.Instance.selectedArray.size} selected</div> + <div className="propertiesView-selectedList">{PresBox.Instance.listOfSelected}</div> </div> </div> {!selectedItem ? null : ( @@ -1750,19 +1684,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { {this.openSlideOptions ? <div className="propertiesView-presTrails-content">{PresBox.Instance.mediaOptionsDropdown}</div> : null} </div> )} - {/* <div className="propertiesView-presTrails"> - <div className="propertiesView-presTrails-title" - onPointerDown={action(() => { this.openAddSlide = !this.openAddSlide; })} - style={{ backgroundColor: this.openAddSlide ? "black" : "" }}> - <FontAwesomeIcon icon={"plus"} /> Add new slide - <div className="propertiesView-presTrails-title-icon"> - <FontAwesomeIcon icon={this.openAddSlide ? "caret-down" : "caret-right"} size="lg" color="white" /> - </div> - </div> - {this.openAddSlide ? <div className="propertiesView-presTrails-content"> - {PresBox.Instance.newDocumentDropdown} - </div> : null} - </div> */} </div> ); } |
