diff options
Diffstat (limited to 'src/client')
-rw-r--r-- | src/client/views/MainView.tsx | 4 | ||||
-rw-r--r-- | src/client/views/collections/CollectionCardDeckView.tsx | 78 | ||||
-rw-r--r-- | src/client/views/global/globalScripts.ts | 28 | ||||
-rw-r--r-- | src/client/views/nodes/FontIconBox/FontIconBox.tsx | 2 | ||||
-rw-r--r-- | src/client/views/nodes/IconTagBox.tsx | 120 |
5 files changed, 98 insertions, 134 deletions
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 74a788d94..8b8f85dfb 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -87,7 +87,7 @@ export class MainView extends ObservableReactComponent<object> { @observable private _windowWidth: number = 0; @observable private _windowHeight: number = 0; - @observable _dashUIWidth: number = 0; // width of entire main dashboard region including left menu buttons and properties panel (but not including the dashboard selector button row) + @observable private _dashUIWidth: number = 0; // width of entire main dashboard region including left menu buttons and properties panel (but not including the dashboard selector button row) @observable private _dashUIHeight: number = 0; // height of entire main dashboard region including top menu buttons @observable private _panelContent: string = 'none'; @observable private _sidebarContent: Doc = Doc.MyLeftSidebarPanel; @@ -549,7 +549,7 @@ export class MainView extends ObservableReactComponent<object> { fa.faCloud, fa.faBolt, fa.faLightbulb, - fa.faX + fa.faX, ] ); } diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx index bb932b8b2..c029d17c6 100644 --- a/src/client/views/collections/CollectionCardDeckView.tsx +++ b/src/client/views/collections/CollectionCardDeckView.tsx @@ -1,7 +1,7 @@ -import { IReactionDisposer, ObservableMap, action, computed, makeObservable, observable, reaction } from 'mobx'; +import { IReactionDisposer, ObservableMap, action, computed, makeObservable, observable, reaction, trace } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { ClientUtils, returnFalse, returnZero } from '../../../ClientUtils'; +import { ClientUtils, DashColor, returnFalse, returnZero } from '../../../ClientUtils'; import { emptyFunction } from '../../../Utils'; import { Doc, StrListCast } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; @@ -18,13 +18,11 @@ import { StyleProp } from '../StyleProp'; import { DocumentView } from '../nodes/DocumentView'; import { GPTPopup, GPTPopupMode } from '../pdf/GPTPopup/GPTPopup'; import './CollectionCardDeckView.scss'; -import { CollectionSubView } from './CollectionSubView'; +import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView'; import { dropActionType } from '../../util/DropActionTypes'; import { DocCast } from '../../../fields/Types'; import { SelectionManager } from '../../util/SelectionManager'; - - enum cardSortings { Time = 'time', Type = 'type', @@ -36,9 +34,9 @@ enum cardSortings { } /** - * New view type specifically for studying more dynamically. Allows you to reorder docs however you see fit, easily + * New view type specifically for studying more dynamically. Allows you to reorder docs however you see fit, easily * sort and filter using presets, and customize your experience with chat gpt. - * + * * This file contains code as to how the docs are to be rendered (there place geographically and also in regards to sorting), * and callback functions for the gpt popup */ @@ -57,7 +55,6 @@ export class CollectionCardView extends CollectionSubView() { @observable _isACardBeingDragged: boolean = false; @observable overIndex: number = -1; - static imageUrlToBase64 = async (imageUrl: string): Promise<string> => { try { const response = await fetch(imageUrl); @@ -75,7 +72,7 @@ export class CollectionCardView extends CollectionSubView() { } }; - constructor(props: any) { + constructor(props: SubCollectionViewProps) { super(props); makeObservable(this); this.setRegenerateCallback(); @@ -84,9 +81,7 @@ export class CollectionCardView extends CollectionSubView() { /** * Callback to ensure gpt's text versions of the child docs are updated */ - setRegenerateCallback = () => { - GPTPopup.Instance.setRegenerateCallback(this.childPairStringListAndUpdateSortDesc); - } + setRegenerateCallback = () => GPTPopup.Instance.setRegenerateCallback(this.childPairStringListAndUpdateSortDesc); /** * update's gpt's doc-text list and initializes callbacks @@ -99,7 +94,7 @@ export class CollectionCardView extends CollectionSubView() { GPTPopup.Instance.onQuizRandom = () => this.quizMode(); }; - componentDidMount(): void { + componentDidMount() { this.Document.childFilters_boolean = 'OR'; this.childDocsWithoutLinks.forEach(c => { c[DocData].showIconTags = true; @@ -112,7 +107,7 @@ export class CollectionCardView extends CollectionSubView() { if (isVis) { this.openChatPopup(); } else { - this.Document.cardSort = (this.cardSort === cardSortings.Chat) ? '' : this.Document.cardSort; + this.Document.cardSort = this.cardSort === cardSortings.Chat ? '' : this.Document.cardSort; } } ); @@ -148,13 +143,13 @@ export class CollectionCardView extends CollectionSubView() { } /** - * When in quiz mode, randomly selects a document + * When in quiz mode, randomly selects a document */ quizMode = () => { const randomIndex = Math.floor(Math.random() * this.childDocs.length); SelectionManager.DeselectAll(); DocumentView.SelectView(DocumentView.getDocumentView(this.childDocs[randomIndex]), false); - } + }; /** * Number of rows of cards to be rendered @@ -163,7 +158,6 @@ export class CollectionCardView extends CollectionSubView() { return Math.ceil(this.sortedDocs.length / 10); } - @action setHoveredNodeIndex = (index: number) => { if (!DocumentView.SelectedDocs().includes(this.childDocs[index])) { @@ -289,7 +283,7 @@ export class CollectionCardView extends CollectionSubView() { /** * Resets all the doc dragging vairables once a card is dropped - * @param e + * @param e * @param de drop event * @returns true if a card has been dropped, falls if not */ @@ -301,13 +295,12 @@ export class CollectionCardView extends CollectionSubView() { return true; } return false; - }, '' ); + }, ''); - get sortedDocs() { + @computed get sortedDocs() { return this.sort(this.childDocsWithoutLinks, this.cardSort, BoolCast(this.Document.cardSort_isDesc), this._docDraggedIndex); } - /** * Used to determine how to sort cards based on tags. The lestmost tags are given lower values while cards to the right are * given higher values. Decimals are used to determine placement for cards with multiple tags @@ -345,7 +338,7 @@ export class CollectionCardView extends CollectionSubView() { // Convert the result to a number and return return Number(numberString); - } + }; /** * Called in the sortedDocsType method. Compares the cards' value in regards to the desired sort type-- earlier cards are move to the @@ -355,31 +348,27 @@ export class CollectionCardView extends CollectionSubView() { * @param isDesc * @returns */ - @action sort = (docs: Doc[], sortType: cardSortings, isDesc: boolean, dragIndex: number) => { + sort = (docs: Doc[], sortType: cardSortings, isDesc: boolean, dragIndex: number) => { docs.sort((docA, docB) => { const [typeA, typeB] = (() => { switch (sortType) { case cardSortings.Time: return [DateCast(docA.author_date)?.date ?? Date.now(), DateCast(docB.author_date)?.date ?? Date.now()]; case cardSortings.Color: - return [ClientUtils.hexToHsv(StrCast(docA.backgroundColor)), ClientUtils.hexToHsv(StrCast(docB.backgroundColor))]; + const d1 = DashColor(StrCast(docA.backgroundColor)); + const d2 = DashColor(StrCast(docB.backgroundColor)); + return [d1.hsv().hue(), d2.hsv().hue()]; case cardSortings.Tag: return [this.tagValue(docA) ?? 9999, this.tagValue(docB) ?? 9999]; case cardSortings.Chat: return [NumCast(docA.chatIndex) ?? 9999, NumCast(docB.chatIndex) ?? 9999]; - default: return [StrCast(docA.type), StrCast(docB.type)]; } })(); const out = typeA < typeB ? -1 : typeA > typeB ? 1 : 0; - - if (isDesc) { - return out; - } - - return -out; + return isDesc ? out : -out; }); if (dragIndex != -1) { const draggedDoc = DragManager.docsBeingDragged[0]; @@ -389,12 +378,11 @@ export class CollectionCardView extends CollectionSubView() { docs.splice(dragIndex, 0, draggedDoc); } - return docs; + return [...docs]; // need to spread docs into a new object list since sort() modifies the incoming list which confuses mobx caching }; displayDoc = (doc: Doc, screenToLocalTransform: () => Transform) => ( <DocumentView - // eslint-disable-next-line react/jsx-props-no-spreading {...this._props} ref={action((r: DocumentView) => r?.ContentDiv && this._docRefs.set(doc, r))} Document={doc} @@ -514,12 +502,11 @@ export class CollectionCardView extends CollectionSubView() { }; /** - * Processes gpt's output depending on the type of question the user asked. Converts gpt's string output to + * Processes gpt's output depending on the type of question the user asked. Converts gpt's string output to * usable code * @param gptOutput */ - @action - + @action processGptOutput = undoable((gptOutput: string, questionType: string, tag?: string) => { // Split the string into individual list items const listItems = gptOutput.split('======').filter(item => item.trim() !== ''); @@ -530,11 +517,10 @@ export class CollectionCardView extends CollectionSubView() { }); } - if (questionType ==='6'){ - this.Document.cardSort = 'chat' + if (questionType === '6') { + this.Document.cardSort = 'chat'; } - listItems.forEach((item, index) => { const normalizedItem = item.trim(); // find the corresponding Doc in the textToDoc map @@ -578,7 +564,6 @@ export class CollectionCardView extends CollectionSubView() { }); }, ''); - /** * Opens up the chat popup and starts the process for smart sorting. */ @@ -586,13 +571,13 @@ export class CollectionCardView extends CollectionSubView() { GPTPopup.Instance.setVisible(true); GPTPopup.Instance.setMode(GPTPopupMode.CARD); GPTPopup.Instance.setCardsDoneLoading(true); // Set dataDoneLoading to true after data is loaded - await this.childPairStringListAndUpdateSortDesc() + await this.childPairStringListAndUpdateSortDesc(); }; /** * Actually renders all the cards */ - renderCards = () => { + renderCards = (sortedDocs: Doc[]) => { const anySelected = this.childDocs.some(doc => DocumentView.SelectedDocs().includes(doc)); const isEmpty = this.childDocsWithoutLinks.length === 0; const isDesc = BoolCast(this.Document.cardSort_isDesc); @@ -606,12 +591,11 @@ export class CollectionCardView extends CollectionSubView() { } // Map sorted documents to their rendered components - return this.sortedDocs.map((doc, index) => { - const realIndex = this.sortedDocs.indexOf(doc); + return sortedDocs.map((doc, index) => { + const realIndex = sortedDocs.indexOf(doc); const calcRowIndex = this.overflowIndexCalc(realIndex); const amCards = this.overflowAmCardsCalc(realIndex); const isSelected = DocumentView.SelectedDocs().includes(doc); - const isDragging = DragManager.docsBeingDragged.includes(doc); const childScreenToLocal = () => { this._forceChildXf; @@ -625,7 +609,7 @@ export class CollectionCardView extends CollectionSubView() { const translateIfSelected = () => { const indexInRow = index % this._maxRowCount; const rowIndex = Math.trunc(index / this._maxRowCount); - const rowCenterIndex = Math.min(this._maxRowCount, this.sortedDocs.length - rowIndex * this._maxRowCount) / 2; + const rowCenterIndex = Math.min(this._maxRowCount, sortedDocs.length - rowIndex * this._maxRowCount) / 2; return (rowCenterIndex - indexInRow) * 100 - 50; }; return ( @@ -680,7 +664,7 @@ export class CollectionCardView extends CollectionSubView() { gridAutoRows: `${100 / this.numRows}%`, }} onMouseLeave={() => this.setHoveredNodeIndex(-1)}> - {this.renderCards()} + {this.renderCards(this.sortedDocs)} </div> </div> ); diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts index 65bd524fe..99bd537b1 100644 --- a/src/client/views/global/globalScripts.ts +++ b/src/client/views/global/globalScripts.ts @@ -283,23 +283,21 @@ ScriptingGlobals.add(function handleTags(value?: any, checkResult?: boolean) { return StrListCast(selected._childFilters).some(filter => filter.includes(attr)); } - if (checkResult) { - return value=== 'opts' ? PropertiesView.Instance?.openFilters : isAttrFiltered(value) - } + if (checkResult) { + return value === 'opts' ? PropertiesView.Instance?.openFilters : isAttrFiltered(value); + } - if (value != 'opts'){ - isAttrFiltered(value) ? Doc.setDocFilter(selected, value, true, 'remove') : Doc.setDocFilter(selected, value, true, 'match'); - } - else { - SnappingManager.PropertiesWidth < 5 && SnappingManager.SetPropertiesWidth(0); - SnappingManager.SetPropertiesWidth(MainView.Instance.propertiesWidth() < 15 ? Math.min(MainView.Instance._dashUIWidth - 50, 250) : 0); - PropertiesView.Instance?.CloseAll() - PropertiesView.Instance.openFilters = true - } + if (value != 'opts') { + isAttrFiltered(value) ? Doc.setDocFilter(selected, value, true, 'remove') : Doc.setDocFilter(selected, value, true, 'match'); + } else { + SnappingManager.PropertiesWidth < 5 && SnappingManager.SetPropertiesWidth(0); + SnappingManager.SetPropertiesWidth(MainView.Instance.propertiesWidth() < 15 ? 250 : 0); + PropertiesView.Instance?.CloseAll(); + PropertiesView.Instance.openFilters = true; + } - - return undefined; - }, ''); + return undefined; +}, ''); // eslint-disable-next-line prefer-arrow-callback ScriptingGlobals.add(function setFontAttr(attr: 'font' | 'fontColor' | 'highlight' | 'fontSize' | 'alignment', value: string | number, checkResult?: boolean) { diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx index 0fe112634..7feb17df1 100644 --- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx @@ -157,7 +157,7 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() { let noviceList: string[] = []; let text: string | undefined; - let getStyle: (val: string) => { [key: string]: string } = () => ({}); + const getStyle: (val: string) => { [key: string]: string } = () => ({}); let icon: IconProp = 'caret-down'; const isViewDropdown = script?.script.originalScript.startsWith('{ return setView'); if (isViewDropdown) { diff --git a/src/client/views/nodes/IconTagBox.tsx b/src/client/views/nodes/IconTagBox.tsx index 370ce51d1..e6c0961ed 100644 --- a/src/client/views/nodes/IconTagBox.tsx +++ b/src/client/views/nodes/IconTagBox.tsx @@ -1,31 +1,30 @@ -import React from "react"; -import { observer } from "mobx-react"; -import { computed } from "mobx"; -import { ObservableReactComponent } from "../ObservableReactComponent"; -import { NumCast } from "../../../fields/Types"; -import { Doc } from "../../../fields/Doc"; -import { numberRange } from "../../../Utils"; -import { Tooltip } from "@mui/material"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { undoable } from "../../util/UndoManager"; -import { BoolCast } from "../../../fields/Types"; -import { DocCast } from "../../../fields/Types"; +import React from 'react'; +import { observer } from 'mobx-react'; +import { computed } from 'mobx'; +import { ObservableReactComponent } from '../ObservableReactComponent'; +import { NumCast } from '../../../fields/Types'; +import { Doc } from '../../../fields/Doc'; +import { numberRange } from '../../../Utils'; +import { Tooltip } from '@mui/material'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { undoable } from '../../util/UndoManager'; +import { BoolCast } from '../../../fields/Types'; +import { DocCast } from '../../../fields/Types'; import './IconTagBox.scss'; -import {DocData } from '../../../fields/DocSymbols'; -import { StrListCast } from "../../../fields/Doc"; -import { StrCast } from "../../../fields/Types"; -import { CollectionViewType } from "../../documents/DocumentTypes"; -import { SnappingManager } from "../../util/SnappingManager"; -import { MainView } from "../MainView"; -import { PropertiesView } from "../PropertiesView"; - +import { DocData } from '../../../fields/DocSymbols'; +import { StrListCast } from '../../../fields/Doc'; +import { StrCast } from '../../../fields/Types'; +import { CollectionViewType } from '../../documents/DocumentTypes'; +import { SnappingManager } from '../../util/SnappingManager'; +import { MainView } from '../MainView'; +import { PropertiesView } from '../PropertiesView'; export interface IconTagProps { doc: Doc; } /** - * Renders the icon tags that rest under the document. The icons rendered are determined by the values of + * Renders the icon tags that rest under the document. The icons rendered are determined by the values of * each icon in the userdoc. */ @observer @@ -33,7 +32,6 @@ export class IconTagBox extends ObservableReactComponent<IconTagProps> { @computed get currentScale() { return NumCast((this._props.doc.embedContainer as Doc)?._freeform_scale, 1); - } constructor(props: any) { @@ -41,10 +39,9 @@ export class IconTagBox extends ObservableReactComponent<IconTagProps> { } componentDidUpdate(prevProps: Readonly<IconTagProps>): void { - this._props.doc[DocData].tagHeight = 36*this.currentScale; + this._props.doc[DocData].tagHeight = 36 * this.currentScale; } - /** * Renders the buttons to customize sorting depending on which group the card belongs to and the amount of total groups * @param doc @@ -52,36 +49,32 @@ export class IconTagBox extends ObservableReactComponent<IconTagProps> { * @returns */ renderButtons = (doc: Doc): JSX.Element | null => { - const amButtons = (StrListCast(Doc.UserDoc().myFilterHotKeyTitles).length) + 1 + const amButtons = StrListCast(Doc.UserDoc().myFilterHotKeyTitles).length + 1; - const keys = StrListCast(Doc.UserDoc().myFilterHotKeyTitles) - - const totalWidth = (amButtons -1) * 35 + (amButtons -1) * 2 * 5 + 6; + const keys = StrListCast(Doc.UserDoc().myFilterHotKeyTitles); - const iconMap = (buttonID: number) => { - return StrCast(Doc.UserDoc()[keys[buttonID]]) + const totalWidth = (amButtons - 1) * 35 + (amButtons - 1) * 2 * 5 + 6; + const iconMap = (buttonID: number) => { + return StrCast(Doc.UserDoc()[keys[buttonID]]); }; - const isCard = DocCast(this._props.doc.embedContainer).type_collection === CollectionViewType.Card - - + const isCard = DocCast(this._props.doc.embedContainer).type_collection === CollectionViewType.Card; return ( <div - className="card-button-container" - style={{ - transformOrigin: 'top left', - transform: `scale(${ isCard ? 2 : 0.6 / this.currentScale}) - translateY(${doc[DocData].showLabels ? ((NumCast(doc[DocData].keywordHeight)*(1-this.currentScale))) : 0}px) + className="card-button-container" + style={{ + transformOrigin: 'top left', + transform: `scale(${isCard ? 2 : 0.6 / this.currentScale}) + translateY(${doc[DocData].showLabels ? NumCast(doc[DocData].keywordHeight) * (1 - this.currentScale) : 0}px) `, - width: `${totalWidth}px`, - fontSize: '50px' - }} - > - {numberRange(amButtons-1).map(i => ( + width: `${totalWidth}px`, + fontSize: '50px', + }}> + {numberRange(amButtons - 1).map(i => ( <Tooltip key={i} title={<div className="dash-tooltip">Click to add/remove this card from the {iconMap(i)} group</div>}> - <button key = {i} type="button" onClick={() => this.toggleButton(doc, iconMap(i) )}> + <button key={i} type="button" onClick={() => this.toggleButton(doc, iconMap(i))}> {this.getButtonIcon(doc, iconMap(i))} </button> </Tooltip> @@ -96,47 +89,36 @@ export class IconTagBox extends ObservableReactComponent<IconTagProps> { openHotKeyMenu = () => { SnappingManager.PropertiesWidth < 5 && SnappingManager.SetPropertiesWidth(0); - SnappingManager.SetPropertiesWidth(MainView.Instance.propertiesWidth() < 15 ? Math.min(MainView.Instance._dashUIWidth - 50, 250) : 0); + SnappingManager.SetPropertiesWidth(MainView.Instance.propertiesWidth() < 15 ? 250 : 0); - PropertiesView.Instance.CloseAll() - PropertiesView.Instance.openFilters = true - } + PropertiesView.Instance.CloseAll(); + PropertiesView.Instance.openFilters = true; + }; - /** + /** * Toggles the buttons between on and off when creating custom sort groupings/changing those created by gpt * @param childPairIndex * @param buttonID * @param doc */ - toggleButton = undoable((doc: Doc, icon: string) => { - BoolCast(doc[icon]) ? doc[icon] = false : doc[icon] = true - + toggleButton = undoable((doc: Doc, icon: string) => { + BoolCast(doc[icon]) ? (doc[icon] = false) : (doc[icon] = true); }, 'toggle card tag'); - /** * Determines whether or not the given icon is active depending on the doc's data - * @param doc - * @param icon - * @returns + * @param doc + * @param icon + * @returns */ getButtonIcon = (doc: Doc, icon: any): JSX.Element => { - const isActive = doc[icon] + const isActive = doc[icon]; const color = isActive ? '#4476f7' : '#323232'; - return <FontAwesomeIcon icon={icon} style={{ color , height: '30px', width: '30px'}} />; + return <FontAwesomeIcon icon={icon} style={{ color, height: '30px', width: '30px' }} />; }; - render (){ - return ( - <> - {this.renderButtons(this._props.doc)} - - </> - ) - + render() { + return <>{this.renderButtons(this._props.doc)}</>; } - } - - |