diff options
| author | bob <bcz@cs.brown.edu> | 2019-08-01 15:05:38 -0400 |
|---|---|---|
| committer | bob <bcz@cs.brown.edu> | 2019-08-01 15:05:38 -0400 |
| commit | ff5fbd1206a065eabab917def7d83337a0442cab (patch) | |
| tree | 07c2f86558f9255b9e5a69e032287b8d0539dbd5 /src/client/views/search/SearchItem.tsx | |
| parent | 49faa4e76f91fed04bb1923d81dd23d57a157a63 (diff) | |
| parent | 6f3d4a7015e15e0523fc194f7f911f6d45259165 (diff) | |
Merge branch 'master' into grouping
Diffstat (limited to 'src/client/views/search/SearchItem.tsx')
| -rw-r--r-- | src/client/views/search/SearchItem.tsx | 122 |
1 files changed, 113 insertions, 9 deletions
diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx index 562594210..0390359b3 100644 --- a/src/client/views/search/SearchItem.tsx +++ b/src/client/views/search/SearchItem.tsx @@ -21,11 +21,18 @@ import { DocumentView } from "../nodes/DocumentView"; import { SearchBox } from "./SearchBox"; import "./SearchItem.scss"; import "./SelectorContextMenu.scss"; +import { RichTextField } from "../../../new_fields/RichTextField"; +import { FormattedTextBox } from "../nodes/FormattedTextBox"; +import { MarqueeView } from "../collections/collectionFreeForm/MarqueeView"; +import { SelectionManager } from "../../util/SelectionManager"; +import { ObjectField } from "../../../new_fields/ObjectField"; import { ContextMenu } from "../ContextMenu"; import { faFile } from '@fortawesome/free-solid-svg-icons'; +import { DocServer } from "../../DocServer"; export interface SearchItemProps { doc: Doc; + query?: string; highlighting: string[]; } @@ -86,7 +93,7 @@ export class SelectorContextMenu extends React.Component<SearchItemProps> { SetupDrag(item, () => doc.col, undefined, undefined, undefined, undefined, () => SearchBox.Instance.closeSearch())}> <FontAwesomeIcon icon={faStickyNote} /> </div> - <a className="title" onClick={this.getOnClick(doc)}>{doc.col.title}</a> + <a onClick={this.getOnClick(doc)}>{doc.col.title}</a> </div>; })} </div> @@ -94,27 +101,115 @@ export class SelectorContextMenu extends React.Component<SearchItemProps> { } } +export interface LinkMenuProps { + doc1: Doc; + doc2: Doc; +} + +@observer +export class LinkContextMenu extends React.Component<LinkMenuProps> { + + highlightDoc = (doc: Doc) => { + return () => { + doc.libraryBrush = true; + }; + } + + unHighlightDoc = (doc: Doc) => { + return () => { + doc.libraryBrush = false; + }; + } + + getOnClick(col: Doc) { + return () => { + CollectionDockingView.Instance.AddRightSplit(col, undefined); + }; + } + + render() { + return ( + <div className="parents"> + <p className="contexts">Anchors:</p> + <div className="collection"><a onMouseEnter={this.highlightDoc(this.props.doc1)} onMouseLeave={this.unHighlightDoc(this.props.doc1)} onClick={this.getOnClick(this.props.doc1)}>Doc 1: {this.props.doc2.title}</a></div> + <div><a onMouseEnter={this.highlightDoc(this.props.doc2)} onMouseLeave={this.unHighlightDoc(this.props.doc2)} onClick={this.getOnClick(this.props.doc2)}>Doc 2: {this.props.doc1.title}</a></div> + </div> + ) + } + +} + @observer export class SearchItem extends React.Component<SearchItemProps> { @observable _selected: boolean = false; + private _previewDoc?: Doc; onClick = () => { // I dont think this is the best functionality because clicking the name of the collection does that. Change it back if you'd like DocumentManager.Instance.jumpToDocument(this.props.doc, false); + if (this.props.doc.data instanceof RichTextField) { + this.highlightTextBox(this.props.doc); + } // CollectionDockingView.Instance.AddRightSplit(this.props.doc, undefined); } @observable _useIcons = true; @observable _displayDim = 50; - @computed - public get DocumentIcon() { + highlightTextBox = (doc: Doc) => { + if (this.props.query) { + const fieldkey = 'search_string'; + if (Object.keys(doc).indexOf(fieldkey) === -1) { + doc.search_string = this.props.query; + } + else { + doc.search_string = undefined; + } + + } + } + + fitToBox = () => { + let bounds = Doc.ComputeContentBounds([this.props.doc]); + return [(bounds.x + bounds.r) / 2, (bounds.y + bounds.b) / 2, Number(SEARCH_THUMBNAIL_SIZE) / Math.max((bounds.b - bounds.y), (bounds.r - bounds.x)), this._displayDim]; + } + + componentWillUnmount() { + if (this._previewDoc) { + DocServer.DeleteDocument(this._previewDoc[Id]); + } + } + + + //@computed + @action + public DocumentIcon() { + let layoutresult = StrCast(this.props.doc.type); if (!this._useIcons) { + let renderDoc = this.props.doc; + //let box: number[] = []; + if (layoutresult.indexOf(DocumentType.COL) !== -1) { + renderDoc = Doc.MakeDelegate(renderDoc); + let bounds = DocListCast(renderDoc.data).reduce((bounds, doc) => { + var [sptX, sptY] = [NumCast(doc.x), NumCast(doc.y)]; + let [bptX, bptY] = [sptX + doc[WidthSym](), sptY + doc[HeightSym]()]; + return { + x: Math.min(sptX, bounds.x), y: Math.min(sptY, bounds.y), + r: Math.max(bptX, bounds.r), b: Math.max(bptY, bounds.b) + }; + }, { x: Number.MAX_VALUE, y: Number.MAX_VALUE, r: Number.MIN_VALUE, b: Number.MIN_VALUE }); + let box = () => [(bounds.x + bounds.r) / 2, (bounds.y + bounds.b) / 2, Number(SEARCH_THUMBNAIL_SIZE) / (bounds.r - bounds.x), this._displayDim]; + } let returnXDimension = () => this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE); let returnYDimension = () => this._displayDim; - let scale = () => returnXDimension() / NumCast(this.props.doc.nativeWidth, returnXDimension()); - return <div - onPointerDown={action(() => { this._useIcons = !this._useIcons; this._displayDim = this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE); })} + let scale = () => returnXDimension() / NumCast(renderDoc.nativeWidth, returnXDimension()); + let newRenderDoc = Doc.MakeDelegate(renderDoc); /// newRenderDoc -> renderDoc -> render"data"Doc -> TextProt + this._previewDoc = newRenderDoc; + const docview = <div + onPointerDown={action(() => { + this._useIcons = !this._useIcons; + this._displayDim = this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE); + })} onPointerEnter={action(() => this._displayDim = this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE))} onPointerLeave={action(() => this._displayDim = 50)} > <DocumentView @@ -138,9 +233,15 @@ export class SearchItem extends React.Component<SearchItemProps> { ContentScaling={scale} /> </div>; + const data = renderDoc.data; + if (data instanceof ObjectField) newRenderDoc.data = ObjectField.MakeCopy(data); + newRenderDoc.preview = true; + newRenderDoc.search_string = this.props.query; + return docview; + } + if (this._previewDoc) { + DocServer.DeleteDocument(this._previewDoc[Id]); } - - let layoutresult = StrCast(this.props.doc.type); let button = layoutresult.indexOf(DocumentType.PDF) !== -1 ? faFilePdf : layoutresult.indexOf(DocumentType.IMG) !== -1 ? faImage : layoutresult.indexOf(DocumentType.TEXT) !== -1 ? faStickyNote : @@ -239,6 +340,8 @@ export class SearchItem extends React.Component<SearchItemProps> { } render() { + const doc1 = Cast(this.props.doc.anchor1, Doc); + const doc2 = Cast(this.props.doc.anchor2, Doc); return ( <div className="search-overview" onPointerDown={this.pointerDown} onContextMenu={this.onContextMenu}> <div className="search-item" onPointerEnter={this.highlightDoc} onPointerLeave={this.unHighlightDoc} id="result" @@ -262,7 +365,8 @@ export class SearchItem extends React.Component<SearchItemProps> { </div> </div> <div className="searchBox-instances"> - <SelectorContextMenu {...this.props} /> + {(doc1 instanceof Doc && doc2 instanceof Doc) ? this.props.doc.type === DocumentType.LINK ? <LinkContextMenu doc1={doc1} doc2={doc2} /> : + <SelectorContextMenu {...this.props} /> : null} </div> </div> ); |
