diff options
| author | bobzel <zzzman@gmail.com> | 2024-05-08 21:03:08 -0400 |
|---|---|---|
| committer | bobzel <zzzman@gmail.com> | 2024-05-08 21:03:08 -0400 |
| commit | b858bd3cad81da41e63b9f8e807e41421ca4aa34 (patch) | |
| tree | 99355f0595194e136494d50c527c859209935191 /src/client/views/newlightbox | |
| parent | b8907e69160d97d919fcd83eb86d60e3634205ca (diff) | |
lots of api cleanup and cycle removal
Diffstat (limited to 'src/client/views/newlightbox')
5 files changed, 112 insertions, 144 deletions
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 ( - <div className={`newLightboxButtonMenu-container`}> + <div className="newLightboxButtonMenu-container"> <div className="newLightboxView-navBtn" title="toggle fit width" onClick={e => { e.stopPropagation(); NewLightboxView.LightboxDoc!._fitWidth = !NewLightboxView.LightboxDoc!._fitWidth; - }}></div> + }} + /> <div className="newLightboxView-tabBtn" title="open in tab" @@ -27,7 +30,8 @@ export const ButtonMenu = (props: IButtonMenu) => { CollectionDockingView.AddSplit(NewLightboxView.LightboxDoc || NewLightboxView.LightboxDoc!, OpenWhereMod.none); DocumentView.DeselectAll(); NewLightboxView.SetNewLightboxDoc(undefined); - }}></div> + }} + /> <div className="newLightboxView-penBtn" title="toggle pen annotation" @@ -35,7 +39,8 @@ export const ButtonMenu = (props: IButtonMenu) => { onClick={e => { e.stopPropagation(); Doc.ActiveTool = Doc.ActiveTool === InkTool.Pen ? InkTool.None : InkTool.Pen; - }}></div> + }} + /> <div className="newLightboxView-exploreBtn" title="toggle explore mode to navigate among documents only" @@ -43,7 +48,8 @@ export const ButtonMenu = (props: IButtonMenu) => { onClick={action(e => { e.stopPropagation(); SnappingManager.SetExploreMode(!SnappingManager.ExploreMode); - })}></div> + })} + /> </div> ); -}; +} 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 ( - <div className={`exploreView-container`}> + <div className="exploreView-container"> {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 ( - <div className={`exploreView-doc`} onClick={() => {}} style={{ top: `calc(50% + ${y}%)`, left: `calc(50% + ${x}%)` }}> + <div className="exploreView-doc" onClick={() => {}} style={{ top: `calc(50% + ${y}%)`, left: `calc(50% + ${x}%)` }}> {rec.title} </div> ); - } else return null; + } + return null; })} - <div className={`exploreView-doc`} style={{ top: `calc(50% + ${0}%)`, left: `calc(50% + ${0}%)`, background: '#073763', color: 'white' }}> + <div className="exploreView-doc" style={{ top: `calc(50% + ${0}%)`, left: `calc(50% + ${0}%)`, background: '#073763', color: 'white' }}> {StrCast(NewLightboxView.LightboxDoc?.title)} </div> </div> ); -}; +} 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<Doc | undefined>(LightboxView.LightboxDoc); + const [doc, setDoc] = React.useState<Doc | undefined>(DocumentView.LightboxDoc()); const [editing, setEditing] = React.useState<boolean>(false); const [title, setTitle] = React.useState<JSX.Element | null>(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<boolean>(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<LightboxViewProps> { 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<LightboxViewProps> { 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<LightboxViewProps> { 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<LightboxViewProps> { @computed get documentView() { - if (!LightboxView.LightboxDoc) return null; + const lightboxDoc = DocumentView.LightboxDoc(); + if (!lightboxDoc) return null; return ( <GestureOverlay isActive> <DocumentView ref={action((r: DocumentView | null) => { 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<LightboxViewProps> { newLightboxWidth = () => this.props.PanelWidth - 420; newLightboxHeight = () => this.props.PanelHeight - 140; newLightboxScreenToLocal = () => new Transform(-this.leftBorder, -this.topBorder, 1); - navBtn = (left: Opt<string | number>, bottom: Opt<number>, top: number, icon: string, display: () => string, click: (e: React.MouseEvent) => void, color?: string) => ( - <div - className="newLightboxView-navBtn-frame" - style={{ - display: display(), - left, - width: bottom !== undefined ? undefined : Math.min(this.props.PanelWidth / 4, this.props.maxBorder[0]), - bottom, - }}> - <div className="newLightboxView-navBtn" title={color} style={{ top, color: color ? 'red' : 'white', background: color ? 'white' : undefined }} onClick={click}> - <div style={{ height: 10 }}>{color}</div> - <FontAwesomeIcon icon={icon as any} size="3x" /> - </div> - </div> - ); 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 : ( <div className="newLightboxView-frame" onPointerDown={e => { @@ -376,7 +340,7 @@ export class NewLightboxTourBtn extends React.Component<NewLightboxTourBtnProps> 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<boolean>(true); const [showMore, setShowMore] = React.useState<boolean>(false); const [keywordsLoc, setKeywordsLoc] = React.useState<string[]>([]); @@ -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<string>(kw); + lightboxDoc.keywords = new List<string>(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 ( <div - className={`recommendationlist-container`} + className="recommendationlist-container" onPointerDown={e => { e.stopPropagation(); }}> - <div className={`header`}> - <div className={`title`}>Recommendations</div> + <div className="header"> + <div className="title">Recommendations</div> {NewLightboxView.LightboxDoc && ( <div style={{ fontSize: 10 }}> 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. </div> )} - <div className={`lb-label`}>Keywords</div> + <div className="lb-label">Keywords</div> {loadingKeywords ? ( - <div className={`keywords`}> + <div className="keywords"> <div className={`keyword ${loadingKeywords && 'loading'}`} /> <div className={`keyword ${loadingKeywords && 'loading'}`} /> <div className={`keyword ${loadingKeywords && 'loading'}`} /> <div className={`keyword ${loadingKeywords && 'loading'}`} /> </div> ) : ( - <div className={`keywords`}> + <div className="keywords"> {keywordsLoc && - keywordsLoc.map((word, ind) => { - return ( - <div className={`keyword`}> - {word} - <IconButton - type={Type.PRIM} - size={Size.XSMALL} - color={Colors.DARK_GRAY} - icon={<GrClose />} - onClick={() => { - let kw = keywordsLoc; - kw.splice(ind); - NewLightboxView.SetKeywords(kw); - }} - /> - </div> - ); - })} + keywordsLoc.map((word, ind) => ( + <div className="keyword"> + {word} + <IconButton + type={Type.PRIM} + size={Size.XSMALL} + color={Colors.DARK_GRAY} + icon={<GrClose />} + onClick={() => { + const kw = keywordsLoc; + kw.splice(ind); + NewLightboxView.SetKeywords(kw); + }} + /> + </div> + ))} </div> )} {!showMore ? ( <div - className={`lb-caret`} + className="lb-caret" onClick={() => { setShowMore(true); }}> More <FaCaretDown /> </div> ) : ( - <div className={`more`}> + <div className="more"> <div - className={`lb-caret`} + className="lb-caret" onClick={() => { setShowMore(false); }}> Less <FaCaretUp /> </div> - <div className={`lb-label`}>Type</div> - <div className={`lb-label`}>Sources</div> + <div className="lb-label">Type</div> + <div className="lb-label">Sources</div> </div> )} </div> - <div className={`recommendations`}> - {recs && - recs.map((rec: IRecommendation) => { - return <Recommendation {...rec} />; - })} - </div> + <div className="recommendations">{recs && recs.map((rec: IRecommendation) => <Recommendation {...rec} />)}</div> </div> ); -}; +} |
