diff options
Diffstat (limited to 'src/client/views/nodes')
| -rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 5 | ||||
| -rw-r--r-- | src/client/views/nodes/FieldView.tsx | 4 | ||||
| -rw-r--r-- | src/client/views/nodes/FontIconBox/FontIconBox.tsx | 2 | ||||
| -rw-r--r-- | src/client/views/nodes/IconTagBox.scss | 26 | ||||
| -rw-r--r-- | src/client/views/nodes/IconTagBox.tsx | 118 | ||||
| -rw-r--r-- | src/client/views/nodes/formattedText/FormattedTextBox.tsx | 1 | ||||
| -rw-r--r-- | src/client/views/nodes/formattedText/RichTextRules.ts | 2 |
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) |
