aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes')
-rw-r--r--src/client/views/nodes/DocumentView.tsx5
-rw-r--r--src/client/views/nodes/FieldView.tsx4
-rw-r--r--src/client/views/nodes/FontIconBox/FontIconBox.tsx2
-rw-r--r--src/client/views/nodes/IconTagBox.scss26
-rw-r--r--src/client/views/nodes/IconTagBox.tsx118
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx1
-rw-r--r--src/client/views/nodes/formattedText/RichTextRules.ts2
7 files changed, 154 insertions, 4 deletions
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 4c357cf45..758e70508 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -67,6 +67,7 @@ export interface DocumentViewProps extends FieldViewSharedProps {
hideCaptions?: boolean;
contentPointerEvents?: Property.PointerEvents | undefined; // pointer events allowed for content of a document view. eg. set to "none" in menuSidebar for sharedDocs so that you can select a document, but not interact with its contents
dontCenter?: 'x' | 'y' | 'xy';
+ showTags?: boolean;
childHideDecorationTitle?: boolean;
childHideResizeHandles?: boolean;
childDragAction?: dropActionType; // allows child documents to be dragged out of collection without holding the embedKey or dragging the doc decorations title bar.
@@ -1126,6 +1127,10 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
@observable public static CurrentlyPlaying: DocumentView[] = []; // audio or video media views that are currently playing
@observable public TagPanelHeight = 0;
+ @computed get showTags() {
+ return this.Document._layout_showTags || this._props.showTags;
+ }
+
@computed private get shouldNotScale() {
return (this.layout_fitWidth && !this.nativeWidth) || this.ComponentView?.isUnstyledView?.();
}
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index c269c7bcb..683edba16 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable react/no-unused-prop-types */
-/* eslint-disable react/require-default-props */
import { Property } from 'csstype';
import { computed } from 'mobx';
import { observer } from 'mobx-react';
@@ -21,6 +19,7 @@ export type FocusFuncType = (doc: Doc, options: FocusViewOptions) => Opt<number>
// eslint-disable-next-line no-use-before-define
export type StyleProviderFuncType = (
doc: Opt<Doc>,
+ // eslint-disable-next-line no-use-before-define
props: Opt<FieldViewProps>,
property: string
) =>
@@ -65,6 +64,7 @@ export interface FieldViewSharedProps {
containerViewPath?: () => DocumentView[];
fitContentsToBox?: () => boolean; // used by freeformview to fit its contents to its panel. corresponds to _freeform_fitContentsToBox property on a Document
isGroupActive?: () => string | undefined; // is this document part of a group that is active
+ // eslint-disable-next-line no-use-before-define
setContentViewBox?: (view: ViewBoxInterface<FieldViewProps>) => void; // called by rendered field's viewBox so that DocumentView can make direct calls to the viewBox
PanelWidth: () => number;
PanelHeight: () => number;
diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
index 7a09ad9e2..f53a7d163 100644
--- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
@@ -192,7 +192,7 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
} else {
text = script?.script.run({ this: this.Document, value: '', _readOnly_: true }).result as string;
// text = StrCast((RichTextMenu.Instance?.TextView?.EditorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily);
- getStyle = (val: string) => ({ fontFamily: val });
+ if (this.Document.title === 'Font') getStyle = (val: string) => ({ fontFamily: val }); // bcz: major hack to style the font dropdown items --- needs to become part of the dropdown's metadata
}
// Get items to place into the list
diff --git a/src/client/views/nodes/IconTagBox.scss b/src/client/views/nodes/IconTagBox.scss
new file mode 100644
index 000000000..90cc06092
--- /dev/null
+++ b/src/client/views/nodes/IconTagBox.scss
@@ -0,0 +1,26 @@
+@import '../global/globalCssVariables.module.scss';
+
+.card-button-container {
+ display: flex;
+ position: relative;
+ pointer-events: none;
+ background-color: rgb(218, 218, 218);
+ border-radius: 50px;
+ align-items: center;
+ gap: 5px;
+ padding-left: 5px;
+ padding-right: 5px;
+ padding-top: 2px;
+ padding-bottom: 2px;
+
+ button {
+ pointer-events: auto;
+ width: 20px;
+ height: 20px;
+ margin: auto;
+ padding: 0;
+ border-radius: 50%;
+ background-color: $dark-gray;
+ background-color: transparent;
+ }
+}
diff --git a/src/client/views/nodes/IconTagBox.tsx b/src/client/views/nodes/IconTagBox.tsx
new file mode 100644
index 000000000..70992e28a
--- /dev/null
+++ b/src/client/views/nodes/IconTagBox.tsx
@@ -0,0 +1,118 @@
+import { IconProp } from '@fortawesome/fontawesome-svg-core';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { Tooltip } from '@mui/material';
+import { computed } from 'mobx';
+import { observer } from 'mobx-react';
+import React from 'react';
+import { emptyFunction, numberRange } from '../../../Utils';
+import { Doc, StrListCast } from '../../../fields/Doc';
+import { StrCast } from '../../../fields/Types';
+import { SnappingManager } from '../../util/SnappingManager';
+import { undoable } from '../../util/UndoManager';
+import { MainView } from '../MainView';
+import { ObservableReactComponent } from '../ObservableReactComponent';
+import { PropertiesView } from '../PropertiesView';
+import { DocumentView } from './DocumentView';
+import './IconTagBox.scss';
+import { TagItem } from '../TagsView';
+import { returnFalse, setupMoveUpEvents } from '../../../ClientUtils';
+
+export interface IconTagProps {
+ Views: DocumentView[];
+ IsEditing: boolean;
+}
+
+/**
+ * Renders the icon tags that rest under the document. The icons rendered are determined by the values of
+ * each icon in the userdoc.
+ */
+@observer
+export class IconTagBox extends ObservableReactComponent<IconTagProps> {
+ constructor(props: IconTagProps) {
+ super(props);
+ }
+
+ @computed get View() {
+ return this._props.Views.lastElement();
+ }
+ @computed get currentScale() {
+ return this.View?.screenToLocalScale();
+ }
+
+ /**
+ * Opens the filter panel in the properties menu
+ */
+
+ openHotKeyMenu = () => {
+ SnappingManager.PropertiesWidth < 5 && SnappingManager.SetPropertiesWidth(0);
+ SnappingManager.SetPropertiesWidth(MainView.Instance.propertiesWidth() < 15 ? 250 : 0);
+
+ PropertiesView.Instance.CloseAll();
+ PropertiesView.Instance.openFilters = true;
+ };
+
+ /**
+ * @param buttonID
+ * @param doc
+ */
+ 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');
+
+ /**
+ * Determines whether or not the given icon is active depending on the doc's data
+ * @param doc
+ * @param icon
+ * @returns
+ */
+ getButtonIcon = (doc: Doc, icon: IconProp): JSX.Element => {
+ 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' }} />;
+ };
+
+ /**
+ * Renders the buttons to customize sorting depending on which group the card belongs to and the amount of total groups
+ */
+ render() {
+ const amButtons = StrListCast(Doc.UserDoc().myFilterHotKeyTitles).length + 1;
+
+ const keys = StrListCast(Doc.UserDoc().myFilterHotKeyTitles);
+
+ const iconMap = (buttonID: number) => {
+ return StrCast(Doc.UserDoc()[keys[buttonID]]) as IconProp;
+ };
+ const buttons = numberRange(amButtons - 1)
+ .filter(i => this._props.IsEditing || this.View.Document[iconMap(i).toString()] || (DocumentView.Selected.length === 1 && this.View.IsSelected))
+ .map(i => (
+ <Tooltip key={i} title={<div className="dash-tooltip">Click to add/remove this card from the {iconMap(i).toString()} group</div>}>
+ <button
+ key={i}
+ type="button"
+ onPointerDown={e =>
+ setupMoveUpEvents(this, e, returnFalse, emptyFunction, clickEv => {
+ const state = TagItem.docHasTag(this.View.Document, iconMap(i).toString()); // this.View.Document[iconMap(i).toString()];
+ this.setIconTag(iconMap(i), !state);
+ clickEv.stopPropagation();
+ })
+ }>
+ {this.getButtonIcon(this.View.Document, iconMap(i))}
+ </button>
+ </Tooltip>
+ ));
+ return !buttons.length ? null : (
+ <div
+ className="card-button-container"
+ style={{
+ fontSize: '50px',
+ }}>
+ {buttons}
+ </div>
+ );
+ }
+}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 7287e2b9f..1ccc6e502 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -275,6 +275,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB
ele.append(contents);
}
this._selectionHTML = ele?.innerHTML;
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (e) {
/* empty */
}
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)