diff options
Diffstat (limited to 'src/client')
-rw-r--r-- | src/client/views/TagsView.tsx | 50 | ||||
-rw-r--r-- | src/client/views/nodes/IconTagBox.tsx | 7 | ||||
-rw-r--r-- | src/client/views/nodes/formattedText/RichTextRules.ts | 2 |
3 files changed, 36 insertions, 23 deletions
diff --git a/src/client/views/TagsView.tsx b/src/client/views/TagsView.tsx index a678d5580..5a47be705 100644 --- a/src/client/views/TagsView.tsx +++ b/src/client/views/TagsView.tsx @@ -9,7 +9,7 @@ import { emptyFunction } from '../../Utils'; import { Doc, DocListCast, Field, Opt, StrListCast } from '../../fields/Doc'; import { DocData } from '../../fields/DocSymbols'; import { List } from '../../fields/List'; -import { DocCast, StrCast } from '../../fields/Types'; +import { DocCast, NumCast, StrCast } from '../../fields/Types'; import { DocumentType } from '../documents/DocumentTypes'; import { DragManager } from '../util/DragManager'; import { SnappingManager } from '../util/SnappingManager'; @@ -28,8 +28,8 @@ import { IconTagBox } from './nodes/IconTagBox'; * the user can drag them off in order to display a collection of all documents that share the tag value. * * The tags that are added using the panel are the same as the #tags that can entered in a text Doc. - * Note that tags starting with #@ display a metadata key/value pair instead of the tag itself. - * e.g., '#@author' shows the document author + * Note that tags starting with @ display a metadata key/value pair instead of the tag itself. + * e.g., '@author' shows the document author * */ @@ -83,6 +83,9 @@ export class TagItem extends ObservableReactComponent<TagItemProps> { */ public static allDocsWithTag = (tag: string) => DocListCast(TagItem.findTagCollectionDoc(tag)?.[DocData].docs); + public static docHasTag = (doc: Doc, tag: string) => { + return StrListCast(doc.tags).includes(tag); + }; /** * Adds a tag to the metadata of this document and adds the Doc to the corresponding tag collection Doc (or creates it) * @param tag tag string @@ -214,13 +217,12 @@ export class TagItem extends ObservableReactComponent<TagItemProps> { render() { this._props.tagDoc && setTimeout(() => this._props.docs.forEach(doc => TagItem.addTagToDoc(doc, this._props.tag))); // bcz: hack to make sure that Docs are added to their tag Doc collection since metadata can get set anywhere without a guard triggering an add to the collection - const tag = this._props.tag.replace(/^#/, ''); - const metadata = tag.startsWith('@') ? tag.replace(/^@/, '') : ''; + const metadata = this._props.tag.startsWith('@') ? this._props.tag.replace(/^@/, '') : ''; return ( <div className={'tagItem' + (!this._props.tagDoc ? ' faceItem' : '')} onClick={this._props.setToEditing} onPointerDown={this.handleDragStart} ref={this._ref}> {metadata ? ( <span> - <b style={{ fontSize: 'smaller' }}>{tag} </b> + <b style={{ fontSize: 'smaller' }}>{'@' + metadata} </b> {typeof this.doc[metadata] === 'boolean' ? ( <input type="checkbox" @@ -234,7 +236,7 @@ export class TagItem extends ObservableReactComponent<TagItemProps> { )} </span> ) : ( - tag + this._props.tag )} {this.props.showRemoveUI && this._props.tagDoc && ( <IconButton @@ -285,8 +287,14 @@ export class TagsView extends ObservableReactComponent<TagViewProps> { return this._props.Views.lastElement(); } + // x: 1 => 1/vs 0 => 1 1/(vs - (1-x)*(vs-1)) @computed get currentScale() { - return this._props.Views.length > 1 ? 1 : Math.max(1, 1 / this.View.screenToLocalScale()); + if (this._props.Views.length > 1) return 1; + const x = NumCast(this.View.Document.height) / this.View.screenToContentsTransform().Scale / 80; + const xscale = x >= 1 ? 0 : 1 / (1 + x * (this.View.screenToLocalScale() - 1)); //docheight / this.View.screenToContentsTransform().Scale / 35 / this.View.screenToLocalScale() - ; + const y = NumCast(this.View.Document.width) / this.View.screenToContentsTransform().Scale / 200; + const yscale = y >= 1 ? 0 : 1 / (1 + y * (this.View.screenToLocalScale() - 1)); //docheight / this.View.screenToContentsTransform().Scale / 35 / this.View.screenToLocalScale() - ; + return Math.max(xscale, yscale, 1 / this.View.screenToLocalScale()); } @computed get isEditing() { return this._isEditing && (this._props.Views.length > 1 || (DocumentView.Selected().length === 1 && DocumentView.Selected().includes(this.View))); @@ -313,7 +321,7 @@ export class TagsView extends ObservableReactComponent<TagViewProps> { const submittedLabel = tag.trim().replace(/^#/, '').split(':'); if (submittedLabel[0]) { this._props.Views.forEach(view => { - TagItem.addTagToDoc(view.Document, '#' + submittedLabel[0]); + TagItem.addTagToDoc(view.Document, (submittedLabel[0].startsWith('@') ? '' : '#') + submittedLabel[0]); if (submittedLabel.length > 1) Doc.SetField(view.Document, submittedLabel[0].replace(/^@/, ''), ':' + submittedLabel[1]); }); } @@ -357,16 +365,18 @@ export class TagsView extends ObservableReactComponent<TagViewProps> { <IconButton style={{ width: '8px' }} tooltip="Close Menu" onPointerDown={() => this.setToEditing(!this._isEditing)} icon={<FontAwesomeIcon icon={this._isEditing ? 'chevron-up' : 'chevron-down'} size="sm" />} /> )} <IconTagBox Views={this._props.Views} IsEditing={this._isEditing} /> - {Array.from(tagsList).map((tag, i) => ( - <TagItem - key={i} - docs={this._props.Views.map(view => view.Document)} - tag={tag} - tagDoc={TagItem.findTagCollectionDoc(tag) ?? TagItem.createTagCollectionDoc(tag)} - setToEditing={this.setToEditing} - showRemoveUI={this.isEditing} - /> - ))} + {Array.from(tagsList) + .filter(tag => tag.startsWith('#') || tag.startsWith('@')) + .map((tag, i) => ( + <TagItem + key={i} + docs={this._props.Views.map(view => view.Document)} + tag={tag} + tagDoc={TagItem.findTagCollectionDoc(tag) ?? TagItem.createTagCollectionDoc(tag)} + setToEditing={this.setToEditing} + showRemoveUI={this.isEditing} + /> + ))} {Array.from(facesList).map((tag, i) => ( <TagItem key={i} docs={this._props.Views.map(view => view.Document)} tag={tag} tagDoc={undefined} setToEditing={this.setToEditing} showRemoveUI={this.isEditing} /> ))} @@ -390,7 +400,7 @@ export class TagsView extends ObservableReactComponent<TagViewProps> { /> </div> <div className="tagsView-suggestions-box"> - {TagItem.AllTagCollectionDocs.map(doc => { + {TagItem.AllTagCollectionDocs.filter(doc => StrCast(doc.title).startsWith('#') || StrCast(doc.title).startsWith('@')).map(doc => { const tag = StrCast(doc.title); return ( <Button diff --git a/src/client/views/nodes/IconTagBox.tsx b/src/client/views/nodes/IconTagBox.tsx index 3d021fd73..ea1c3591a 100644 --- a/src/client/views/nodes/IconTagBox.tsx +++ b/src/client/views/nodes/IconTagBox.tsx @@ -14,6 +14,7 @@ import { ObservableReactComponent } from '../ObservableReactComponent'; import { PropertiesView } from '../PropertiesView'; import { DocumentView } from './DocumentView'; import './IconTagBox.scss'; +import { TagItem } from '../TagsView'; export interface IconTagProps { Views: DocumentView[]; @@ -55,6 +56,8 @@ export class IconTagBox extends ObservableReactComponent<IconTagProps> { */ setIconTag = undoable((icon: string, state: boolean) => { this._props.Views.forEach(view => { + state && TagItem.addTagToDoc(view.dataDoc, icon); + !state && TagItem.removeTagFromDoc(view.dataDoc, icon); view.dataDoc[icon] = state; }); }, 'toggle card tag'); @@ -66,7 +69,7 @@ export class IconTagBox extends ObservableReactComponent<IconTagProps> { * @returns */ getButtonIcon = (doc: Doc, icon: IconProp): JSX.Element => { - const isActive = doc[icon.toString()]; + const isActive = TagItem.docHasTag(doc, icon.toString()); // doc[icon.toString()]; const color = isActive ? '#4476f7' : '#323232'; return <FontAwesomeIcon icon={icon} style={{ color, height: '20px', width: '20px' }} />; @@ -91,7 +94,7 @@ export class IconTagBox extends ObservableReactComponent<IconTagProps> { key={i} type="button" onClick={() => { - const state = this.View.Document[iconMap(i).toString()]; + const state = TagItem.docHasTag(this.View.Document, iconMap(i).toString()); // this.View.Document[iconMap(i).toString()]; this.setIconTag(iconMap(i), !state); }}> {this.getButtonIcon(this.View.Document, iconMap(i))} diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts index 0ef67b4be..f58434906 100644 --- a/src/client/views/nodes/formattedText/RichTextRules.ts +++ b/src/client/views/nodes/formattedText/RichTextRules.ts @@ -406,7 +406,7 @@ export class RichTextRules { this.Document[DocData].tags = new List<string>(tags); this.Document._layout_showTags = true; } - const fieldView = state.schema.nodes.dashField.create({ fieldKey: '#' + tag }); + const fieldView = state.schema.nodes.dashField.create({ fieldKey: tag.startsWith('@') ? tag.replace(/^@/, '') : '#' + tag }); return state.tr .setSelection(new TextSelection(state.doc.resolve(start), state.doc.resolve(end))) .replaceSelectionWith(fieldView, true) |