From b858bd3cad81da41e63b9f8e807e41421ca4aa34 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 8 May 2024 21:03:08 -0400 Subject: lots of api cleanup and cycle removal --- .../views/newlightbox/ButtonMenu/ButtonMenu.tsx | 22 ++-- .../views/newlightbox/ExploreView/ExploreView.tsx | 30 ++--- .../views/newlightbox/Header/LightboxHeader.tsx | 8 +- src/client/views/newlightbox/NewLightboxView.tsx | 62 ++-------- .../RecommendationList/RecommendationList.tsx | 134 ++++++++++----------- 5 files changed, 112 insertions(+), 144 deletions(-) (limited to 'src/client/views/newlightbox') diff --git a/src/client/views/newlightbox/ButtonMenu/ButtonMenu.tsx b/src/client/views/newlightbox/ButtonMenu/ButtonMenu.tsx index e48e993cf..3eb99f47a 100644 --- a/src/client/views/newlightbox/ButtonMenu/ButtonMenu.tsx +++ b/src/client/views/newlightbox/ButtonMenu/ButtonMenu.tsx @@ -1,24 +1,27 @@ +/* eslint-disable jsx-a11y/no-static-element-interactions */ +/* eslint-disable jsx-a11y/click-events-have-key-events */ import { action } from 'mobx'; import * as React from 'react'; import { Doc } from '../../../../fields/Doc'; import { InkTool } from '../../../../fields/InkField'; import { SnappingManager } from '../../../util/SnappingManager'; import { CollectionDockingView } from '../../collections/CollectionDockingView'; +import { DocumentView } from '../../nodes/DocumentView'; import { OpenWhereMod } from '../../nodes/OpenWhere'; import { NewLightboxView } from '../NewLightboxView'; import './ButtonMenu.scss'; -import { IButtonMenu } from './utils'; -export const ButtonMenu = (props: IButtonMenu) => { +export function ButtonMenu() { return ( -
+
{ e.stopPropagation(); NewLightboxView.LightboxDoc!._fitWidth = !NewLightboxView.LightboxDoc!._fitWidth; - }}>
+ }} + />
{ CollectionDockingView.AddSplit(NewLightboxView.LightboxDoc || NewLightboxView.LightboxDoc!, OpenWhereMod.none); DocumentView.DeselectAll(); NewLightboxView.SetNewLightboxDoc(undefined); - }}>
+ }} + />
{ onClick={e => { e.stopPropagation(); Doc.ActiveTool = Doc.ActiveTool === InkTool.Pen ? InkTool.None : InkTool.Pen; - }}>
+ }} + />
{ onClick={action(e => { e.stopPropagation(); SnappingManager.SetExploreMode(!SnappingManager.ExploreMode); - })}>
+ })} + />
); -}; +} diff --git a/src/client/views/newlightbox/ExploreView/ExploreView.tsx b/src/client/views/newlightbox/ExploreView/ExploreView.tsx index a1d6375c4..f8c07cc43 100644 --- a/src/client/views/newlightbox/ExploreView/ExploreView.tsx +++ b/src/client/views/newlightbox/ExploreView/ExploreView.tsx @@ -1,32 +1,34 @@ -import './ExploreView.scss'; -import { IBounds, IExploreView, emptyBounds } from './utils'; -import { IRecommendation } from '../components'; +/* eslint-disable jsx-a11y/no-static-element-interactions */ +/* eslint-disable jsx-a11y/click-events-have-key-events */ import * as React from 'react'; -import { NewLightboxView } from '../NewLightboxView'; import { StrCast } from '../../../../fields/Types'; +import { NewLightboxView } from '../NewLightboxView'; +import './ExploreView.scss'; +import { IExploreView, emptyBounds } from './utils'; -export const ExploreView = (props: IExploreView) => { +export function ExploreView(props: IExploreView) { const { recs, bounds = emptyBounds } = props; return ( -
+
{recs && recs.map(rec => { - const x_bound: number = Math.max(Math.abs(bounds.max_x), Math.abs(bounds.min_x)); - const y_bound: number = Math.max(Math.abs(bounds.max_y), Math.abs(bounds.min_y)); + const xBound: number = Math.max(Math.abs(bounds.max_x), Math.abs(bounds.min_x)); + const yBound: number = Math.max(Math.abs(bounds.max_y), Math.abs(bounds.min_y)); if (rec.embedding) { - const x = (rec.embedding.x / x_bound) * 50; - const y = (rec.embedding.y / y_bound) * 50; + const x = (rec.embedding.x / xBound) * 50; + const y = (rec.embedding.y / yBound) * 50; return ( -
{}} style={{ top: `calc(50% + ${y}%)`, left: `calc(50% + ${x}%)` }}> +
{}} style={{ top: `calc(50% + ${y}%)`, left: `calc(50% + ${x}%)` }}> {rec.title}
); - } else return null; + } + return null; })} -
+
{StrCast(NewLightboxView.LightboxDoc?.title)}
); -}; +} diff --git a/src/client/views/newlightbox/Header/LightboxHeader.tsx b/src/client/views/newlightbox/Header/LightboxHeader.tsx index 51bfaa4e5..882d28fba 100644 --- a/src/client/views/newlightbox/Header/LightboxHeader.tsx +++ b/src/client/views/newlightbox/Header/LightboxHeader.tsx @@ -4,8 +4,8 @@ import { BsBookmark, BsBookmarkFill } from 'react-icons/bs'; import { MdTravelExplore } from 'react-icons/md'; import { Doc } from '../../../../fields/Doc'; import { StrCast } from '../../../../fields/Types'; -import { LightboxView } from '../../LightboxView'; import { Colors } from '../../global/globalEnums'; +import { DocumentView } from '../../nodes/DocumentView'; import { NewLightboxView } from '../NewLightboxView'; import { EditableText } from '../components/EditableText'; import { getType } from '../utils'; @@ -14,11 +14,11 @@ import { INewLightboxHeader } from './utils'; export function NewLightboxHeader(props: INewLightboxHeader) { const { height = 100, width } = props; - const [doc, setDoc] = React.useState(LightboxView.LightboxDoc); + const [doc, setDoc] = React.useState(DocumentView.LightboxDoc()); const [editing, setEditing] = React.useState(false); const [title, setTitle] = React.useState(null); React.useEffect(() => { - const lbDoc = LightboxView.LightboxDoc; + const lbDoc = DocumentView.LightboxDoc(); setDoc(lbDoc); if (lbDoc) { setTitle( @@ -32,7 +32,7 @@ export function NewLightboxHeader(props: INewLightboxHeader) { /> ); } - }, [LightboxView.LightboxDoc]); + }, [DocumentView.LightboxDoc()]); const [saved, setSaved] = React.useState(false); diff --git a/src/client/views/newlightbox/NewLightboxView.tsx b/src/client/views/newlightbox/NewLightboxView.tsx index 558ce7e38..c86ddb745 100644 --- a/src/client/views/newlightbox/NewLightboxView.tsx +++ b/src/client/views/newlightbox/NewLightboxView.tsx @@ -1,6 +1,5 @@ /* eslint-disable jsx-a11y/no-static-element-interactions */ /* eslint-disable jsx-a11y/click-events-have-key-events */ -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; @@ -12,7 +11,6 @@ import { Cast, NumCast, StrCast, toList } from '../../../fields/Types'; import { SnappingManager } from '../../util/SnappingManager'; import { Transform } from '../../util/Transform'; import { GestureOverlay } from '../GestureOverlay'; -import { LightboxView } from '../LightboxView'; import { DefaultStyleProvider } from '../StyleProvider'; import { DocumentView } from '../nodes/DocumentView'; import { OpenWhere } from '../nodes/OpenWhere'; @@ -108,7 +106,7 @@ export class NewLightboxView extends React.Component { DocumentView.CurrentlyPlaying?.forEach(dv => dv.ComponentView?.Pause?.()); // DocumentView.PinDoc(doc, { hidePresBox: true }); this._history ? this._history.push({ doc, target }) : (this._history = [{ doc, target }]); - if (doc !== LightboxView.LightboxDoc) { + if (doc !== DocumentView.LightboxDoc()) { this._savedState = { layout_fieldKey: StrCast(doc.layout_fieldKey), panX: Cast(doc.freeform_panX, 'number', null), @@ -151,11 +149,12 @@ export class NewLightboxView extends React.Component { if (NewLightboxView._history?.lastElement().target !== target) NewLightboxView._history?.push({ doc, target }); } else if (!target && NewLightboxView.path.length) { const saved = NewLightboxView._savedState; - if (LightboxView.LightboxDoc && saved) { - LightboxView.LightboxDoc._freeform_panX = saved.panX; - LightboxView.LightboxDoc._freeform_panY = saved.panY; - LightboxView.LightboxDoc._freeform_scale = saved.scale; - LightboxView.LightboxDoc._layout_scrollTop = saved.scrollTop; + const lightboxDoc = DocumentView.LightboxDoc(); + if (lightboxDoc && saved) { + lightboxDoc._freeform_panX = saved.panX; + lightboxDoc._freeform_panY = saved.panY; + lightboxDoc._freeform_scale = saved.scale; + lightboxDoc._layout_scrollTop = saved.scrollTop; } const pop = NewLightboxView.path.pop(); if (pop) { @@ -176,7 +175,7 @@ export class NewLightboxView extends React.Component { NewLightboxView.SetNewLightboxDoc(undefined); return; } - const { doc, target } = NewLightboxView._history?.lastElement(); + const { doc, target } = NewLightboxView._history?.lastElement() ?? { doc: undefined, target: undefined }; const docView = DocumentView.getLightboxDocumentView(target || doc); if (docView) { NewLightboxView._docTarget = target; @@ -248,14 +247,15 @@ export class NewLightboxView extends React.Component { @computed get documentView() { - if (!LightboxView.LightboxDoc) return null; + const lightboxDoc = DocumentView.LightboxDoc(); + if (!lightboxDoc) return null; return ( { NewLightboxView._docView = r !== null ? r : undefined; })} - Document={LightboxView.LightboxDoc} + Document={lightboxDoc} PanelWidth={this.newLightboxWidth} PanelHeight={this.newLightboxHeight} LayoutTemplate={NewLightboxView.LightboxDocTemplate} @@ -281,50 +281,14 @@ export class NewLightboxView extends React.Component { newLightboxWidth = () => this.props.PanelWidth - 420; newLightboxHeight = () => this.props.PanelHeight - 140; newLightboxScreenToLocal = () => new Transform(-this.leftBorder, -this.topBorder, 1); - navBtn = (left: Opt, bottom: Opt, top: number, icon: string, display: () => string, click: (e: React.MouseEvent) => void, color?: string) => ( -
-
-
{color}
- -
-
- ); docFilters = () => NewLightboxView._docFilters || []; - @action - stepInto = () => { - NewLightboxView.path.push({ - doc: LightboxView.LightboxDoc, - target: NewLightboxView._docTarget, - future: NewLightboxView._future, - history: NewLightboxView._history, - saved: NewLightboxView._savedState, - }); - const coll = NewLightboxView._docTarget; - if (coll) { - const fieldKey = Doc.LayoutFieldKey(coll); - const contents = [...DocListCast(coll[fieldKey]), ...DocListCast(coll[fieldKey + '_annotations'])]; - const links = Doc.Links(coll) - .map(link => Doc.getOppositeAnchor(link, coll)) - .filter(doc => doc) - .map(doc => doc!); - NewLightboxView.SetNewLightboxDoc(coll, undefined, contents.length ? contents : links); - } - }; - future = () => NewLightboxView._future; render() { const newLightboxHeaderHeight = 100; let downx = 0; let downy = 0; - return !LightboxView.LightboxDoc ? null : ( + return !DocumentView.LightboxDoc() ? null : (
{ @@ -376,7 +340,7 @@ export class NewLightboxTourBtn extends React.Component 0, 0, 'chevron-down', - () => (LightboxView.LightboxDoc /* && this.props.future()?.length */ ? '' : 'none'), + () => (DocumentView.LightboxDoc() /* && this.props.future()?.length */ ? '' : 'none'), e => { e.stopPropagation(); this.props.stepInto(); diff --git a/src/client/views/newlightbox/RecommendationList/RecommendationList.tsx b/src/client/views/newlightbox/RecommendationList/RecommendationList.tsx index 1d502b73f..dc3339cd3 100644 --- a/src/client/views/newlightbox/RecommendationList/RecommendationList.tsx +++ b/src/client/views/newlightbox/RecommendationList/RecommendationList.tsx @@ -1,3 +1,7 @@ +/* eslint-disable react/jsx-props-no-spreading */ +/* eslint-disable jsx-a11y/no-static-element-interactions */ +/* eslint-disable jsx-a11y/click-events-have-key-events */ +/* eslint-disable guard-for-in */ import { IconButton, Size, Type } from 'browndash-components'; import * as React from 'react'; import { FaCaretDown, FaCaretUp } from 'react-icons/fa'; @@ -5,17 +9,15 @@ import { GrClose } from 'react-icons/gr'; import { DocListCast, StrListCast } from '../../../../fields/Doc'; import { List } from '../../../../fields/List'; import { StrCast } from '../../../../fields/Types'; -import { LightboxView } from '../../LightboxView'; import { Colors } from '../../global/globalEnums'; +import { DocumentView } from '../../nodes/DocumentView'; import { IBounds } from '../ExploreView/utils'; import { NewLightboxView } from '../NewLightboxView'; import { IRecommendation, Recommendation } from '../components'; import { IDocRequest, fetchKeywords, fetchRecommendations } from '../utils'; import './RecommendationList.scss'; -import { IRecommendationList } from './utils'; -export const RecommendationList = (props: IRecommendationList) => { - const { loading, keywords } = props; +export function RecommendationList() { const [loadingKeywords, setLoadingKeywords] = React.useState(true); const [showMore, setShowMore] = React.useState(false); const [keywordsLoc, setKeywordsLoc] = React.useState([]); @@ -25,21 +27,22 @@ export const RecommendationList = (props: IRecommendationList) => { React.useEffect(() => { const getKeywords = async () => { - let text = StrCast(LightboxView.LightboxDoc?.text); + const text = StrCast(DocumentView.LightboxDoc()?.text); console.log('[1] fetching keywords'); const response = await fetchKeywords(text, 5, true); console.log('[2] response:', response); const kw = response.keywords; console.log(kw); NewLightboxView.SetKeywords(kw); - if (LightboxView.LightboxDoc) { + const lightboxDoc = DocumentView.LightboxDoc(); + if (lightboxDoc) { console.log('setting keywords on doc'); - LightboxView.LightboxDoc.keywords = new List(kw); + lightboxDoc.keywords = new List(kw); setKeywordsLoc(NewLightboxView.Keywords); } setLoadingKeywords(false); }; - let keywordsList = StrListCast(LightboxView.LightboxDoc!.keywords); + const keywordsList = StrListCast(DocumentView.LightboxDoc()!.keywords); if (!keywordsList || keywordsList.length < 2) { setLoadingKeywords(true); getKeywords(); @@ -57,14 +60,14 @@ export const RecommendationList = (props: IRecommendationList) => { console.log('fetching recommendations'); let query = 'undefined'; if (keywordsLoc) query = keywordsLoc.join(','); - let src = StrCast(NewLightboxView.LightboxDoc?.text); - let dashDocs: IDocRequest[] = []; + const src = StrCast(NewLightboxView.LightboxDoc?.text); + const dashDocs: IDocRequest[] = []; // get linked docs - let linkedDocs = DocListCast(NewLightboxView.LightboxDoc?.links); + const linkedDocs = DocListCast(NewLightboxView.LightboxDoc?.links); console.log('linked docs', linkedDocs); // get context docs (docs that are also in the collection) - // let contextDocs: Doc[] = DocListCast(DocCast(LightboxView.LightboxDoc?.context).data) - // let docId = LightboxView.LightboxDoc && LightboxView.LightboxDoc[Id] + // let contextDocs: Doc[] = DocListCast(DocCast(DocumentView.LightboxDoc()?.context).data) + // let docId = DocumentView.LightboxDoc() && DocumentView.LightboxDoc()[Id] // console.log("context docs", contextDocs) // contextDocs.forEach((doc: Doc) => { // if (docId !== doc[Id]){ @@ -79,10 +82,8 @@ export const RecommendationList = (props: IRecommendationList) => { console.log('dash docs', dashDocs); if (query !== undefined) { const response = await fetchRecommendations(src, query, [], true); - const num_recs = response.num_recommendations; - const recs = response.recommendations; - const keywords = response.keywords; - const response_bounds: IBounds = { + const theRecs = response.recommendations; + const responseBounds: IBounds = { max_x: response.max_x, max_y: response.max_y, min_x: response.min_x, @@ -93,22 +94,23 @@ export const RecommendationList = (props: IRecommendationList) => { // setKeywordsLoc(NewLightboxView.Keywords); // } // console.log(response_bounds) - NewLightboxView.SetBounds(response_bounds); + NewLightboxView.SetBounds(responseBounds); const recommendations: IRecommendation[] = []; - for (const key in recs) { + // eslint-disable-next-line no-restricted-syntax + for (const key in theRecs) { console.log(key); - const title = recs[key].title; - const url = recs[key].url; - const type = recs[key].type; - const text = recs[key].text; - const transcript = recs[key].transcript; - const previewUrl = recs[key].previewUrl; - const embedding = recs[key].embedding; - const distance = recs[key].distance; - const source = recs[key].source; - const related_concepts = recs[key].related_concepts; - const docId = recs[key].doc_id; - related_concepts.length >= 1 && + const { title } = theRecs[key]; + const { url } = theRecs[key]; + const { type } = theRecs[key]; + const { text } = theRecs[key]; + const { transcript } = theRecs[key]; + const { previewUrl } = theRecs[key]; + const { embedding } = theRecs[key]; + const { distance } = theRecs[key]; + const { source } = theRecs[key]; + const { related_concepts: relatedConcepts } = theRecs[key]; + const docId = theRecs[key].doc_id; + relatedConcepts.length >= 1 && recommendations.push({ title: title, data: url, @@ -119,14 +121,15 @@ export const RecommendationList = (props: IRecommendationList) => { embedding: embedding, distance: Math.round(distance * 100) / 100, source: source, - related_concepts: related_concepts, + related_concepts: relatedConcepts, docId: docId, }); } recommendations.sort((a, b) => { if (a.distance && b.distance) { return a.distance - b.distance; - } else return 0; + } + return 0; }); console.log('[rec]: ', recommendations); NewLightboxView.SetRecs(recommendations); @@ -138,12 +141,12 @@ export const RecommendationList = (props: IRecommendationList) => { return (
{ e.stopPropagation(); }}> -
-
Recommendations
+
+
Recommendations
{NewLightboxView.LightboxDoc && (
The recommendations are produced based on the text in the document{' '} @@ -153,65 +156,58 @@ export const RecommendationList = (props: IRecommendationList) => { . The following keywords are used to fetch the recommendations.
)} -
Keywords
+
Keywords
{loadingKeywords ? ( -
+
) : ( -
+
{keywordsLoc && - keywordsLoc.map((word, ind) => { - return ( -
- {word} - } - onClick={() => { - let kw = keywordsLoc; - kw.splice(ind); - NewLightboxView.SetKeywords(kw); - }} - /> -
- ); - })} + keywordsLoc.map((word, ind) => ( +
+ {word} + } + onClick={() => { + const kw = keywordsLoc; + kw.splice(ind); + NewLightboxView.SetKeywords(kw); + }} + /> +
+ ))}
)} {!showMore ? (
{ setShowMore(true); }}> More
) : ( -
+
{ setShowMore(false); }}> Less
-
Type
-
Sources
+
Type
+
Sources
)}
-
- {recs && - recs.map((rec: IRecommendation) => { - return ; - })} -
+
{recs && recs.map((rec: IRecommendation) => )}
); -}; +} -- cgit v1.2.3-70-g09d2