aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2024-09-18 23:51:55 -0400
committerbobzel <zzzman@gmail.com>2024-09-18 23:51:55 -0400
commit7b51ab828d127c157bf1560c5ea1bdccf8353e06 (patch)
tree003894a171780a43765b4d69a221e77675c3c1f0
parentcc09a9e9015bbcbeec68ccdc574b5250d35a4e8f (diff)
switched icontags to use regular tags list instead of metadata fields. changed tagsView to show # for tags, @ for metadata, and no prefix for icons
-rw-r--r--src/client/views/TagsView.tsx50
-rw-r--r--src/client/views/nodes/IconTagBox.tsx7
-rw-r--r--src/client/views/nodes/formattedText/RichTextRules.ts2
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}&nbsp;</b>
+ <b style={{ fontSize: 'smaller' }}>{'@' + metadata}&nbsp;</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)