From c3d4b851d81d42256b972a6b8eaa9c9210232953 Mon Sep 17 00:00:00 2001 From: monikahedman Date: Sat, 6 Jul 2019 14:52:53 -0400 Subject: free cookies! --- src/client/views/search/SearchBox.tsx | 77 +++++++++++++++++++++++++++++++---- 1 file changed, 69 insertions(+), 8 deletions(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 1f6835c26..327f9514a 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -26,6 +26,12 @@ export class SearchBox extends React.Component { @observable public _pageNum: number = 0; //temp @observable public _maxNum: number = 10; + @observable private _visibleElements: JSX.Element[] = []; + @observable private _scrollY: number = 0; + + private _isSearch: ("search" | "placeholder" | undefined)[] = []; + private _currentIndex = 0; + private _numResults = 0; static Instance: SearchBox; @@ -90,25 +96,35 @@ export class SearchBox extends React.Component { else { //gets json result into a list of documents that can be used //these are filtered by type - results = await this.getResults(query); + this._currentIndex = 0; + results = await this.getResults(query, 12); } runInAction(() => { this._resultsOpen = true; this._results = results; this._openNoResults = true; + this.resultsScrolled(); }); } @action - getResults = async (query: string) => { - const { docs } = await SearchUtil.Search(query, true); - return FilterBox.Instance.filterDocsByType(docs); + getResults = async (query: string, count: number) => { + let resDocs = []; + while (resDocs.length < count) { + const { docs, numFound } = await SearchUtil.Search(query, true, count === -1 ? undefined : this._currentIndex, count === -1 ? undefined : this._maxNum); + if (numFound !== this._numResults) { + this._numResults = numFound; + } + resDocs.push(...FilterBox.Instance.filterDocsByType(docs)); + this._currentIndex += this._maxNum; + } + return resDocs; } collectionRef = React.createRef(); startDragCollection = async () => { - const results = await this.getResults(FilterBox.Instance.getFinalQuery(this._searchString)); + const results = await this.getResults(FilterBox.Instance.getFinalQuery(this._searchString), -1); const docs = results.map(doc => { const isProto = Doc.GetT(doc, "isPrototype", "boolean", true); if (isProto) { @@ -166,6 +182,50 @@ export class SearchBox extends React.Component { this._results = []; } + resultsScrolled = async (e?: React.UIEvent) => { + let scrollY = e ? e.currentTarget.scrollTop : 0; + let buffer = 4; + let startIndex = Math.floor(Math.max(0, scrollY / 70 - buffer)); + let endIndex = Math.ceil(Math.min(this._numResults - 1, startIndex + (560 / 70) + buffer)); + + runInAction(() => { + if (this._numResults === 0 && this._openNoResults) { + this._visibleElements = [
No Search Results
]; + return; + } + else if (this._visibleElements.length !== this._numResults) { + this._visibleElements = Array(this._numResults); + this._isSearch = Array(this._numResults); + } + }); + + for (let i = 0; i < this._numResults; i++) { + if (i < startIndex || i > endIndex) { + if (this._isSearch[i] !== "placeholder") { + this._isSearch[i] = "placeholder"; + runInAction(() => { + this._visibleElements[i] =
; + }); + } + } + else { + if (this._isSearch[i] !== "search") { + let result: Doc | undefined = undefined; + if (i >= this._results.length) { + this._results.push(...(await this.getResults(this._searchString, 1))); + } + result = this._results[i]; + if (result) { + runInAction(() => { + this._visibleElements[i] = ; + }); + this._isSearch[i] = "search"; + } + } + } + } + } + render() { return (
@@ -178,11 +238,12 @@ export class SearchBox extends React.Component { style={{ width: this._resultsOpen ? "500px" : "100px" }} />
-
- {(this._results.length !== 0) ? ( +
+ {/* {(this._results.length !== 0) ? ( this._results.map(result => ) ) : - this._openNoResults ? (
No Search Results
) : null} + this._openNoResults ? (
No Search Results
) : null} */} + {this._visibleElements}
{/*
-- cgit v1.2.3-70-g09d2 From 6cc2335bc6d318ec780bdaecfbad4e047a7b5ac9 Mon Sep 17 00:00:00 2001 From: monikahedman Date: Mon, 8 Jul 2019 18:49:40 -0400 Subject: end of day 7/8 --- src/client/views/pdf/PDFMenu.tsx | 12 ++-- src/client/views/search/FilterBox.tsx | 2 +- src/client/views/search/SearchBox.tsx | 115 +++++++++++++++++++++++----------- 3 files changed, 86 insertions(+), 43 deletions(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/views/pdf/PDFMenu.tsx b/src/client/views/pdf/PDFMenu.tsx index f93b2e59f..b979a9932 100644 --- a/src/client/views/pdf/PDFMenu.tsx +++ b/src/client/views/pdf/PDFMenu.tsx @@ -242,24 +242,24 @@ export default class PDFMenu extends React.Component { render() { let buttons = this.Status === "pdf" || this.Status === "snippet" ? [ - , - , + , this.Status === "snippet" ? : undefined, - ] : [ - , - , + , + ,
, - , + , ]; return ( diff --git a/src/client/views/search/FilterBox.tsx b/src/client/views/search/FilterBox.tsx index 23a1b31d8..4c74c0413 100644 --- a/src/client/views/search/FilterBox.tsx +++ b/src/client/views/search/FilterBox.tsx @@ -242,7 +242,7 @@ export class FilterBox extends React.Component { let finalDocs: Doc[] = []; docs.forEach(doc => { let layoutresult = Cast(doc.type, "string"); - if (!layoutresult || this._icons.includes(layoutresult)) { + if (layoutresult && this._icons.includes(layoutresult)) { finalDocs.push(doc); } }); diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 327f9514a..430ca3b2e 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -15,6 +15,7 @@ import { Id } from '../../../new_fields/FieldSymbols'; import { SearchUtil } from '../../util/SearchUtil'; import { RouteStore } from '../../../server/RouteStore'; import { FilterBox } from './FilterBox'; +import { start } from 'repl'; @observer export class SearchBox extends React.Component { @@ -31,7 +32,10 @@ export class SearchBox extends React.Component { private _isSearch: ("search" | "placeholder" | undefined)[] = []; private _currentIndex = 0; - private _numResults = 0; + private _numTotalResults = 0; + private _numFilteredResults = 0; + private _startIndex = -1; + private _endIndex = -1; static Instance: SearchBox; @@ -55,15 +59,16 @@ export class SearchBox extends React.Component { onChange(e: React.ChangeEvent) { this._searchString = e.target.value; - if (this._searchString === "") { - this._results = []; - this._openNoResults = false; - } + this._openNoResults = false; + this._results = []; + this._visibleElements = []; + this._currentIndex = 0; + this._numTotalResults = 0; + this._startIndex = -1; + this._endIndex = -1; } - enter = (e: React.KeyboardEvent) => { - if (e.key === "Enter") { this.submitSearch(); } - } + enter = (e: React.KeyboardEvent) => { if (e.key === "Enter") { this.submitSearch(); } } public static async convertDataUri(imageUri: string, returnedFilename: string) { try { @@ -111,13 +116,30 @@ export class SearchBox extends React.Component { @action getResults = async (query: string, count: number) => { let resDocs = []; + // count is total number of documents to be shown (i believe) + console.log(`Count: ${count}`); while (resDocs.length < count) { - const { docs, numFound } = await SearchUtil.Search(query, true, count === -1 ? undefined : this._currentIndex, count === -1 ? undefined : this._maxNum); - if (numFound !== this._numResults) { - this._numResults = numFound; + let index = count === -1 ? undefined : this._currentIndex; + let num = count === -1 ? undefined : Math.min(this._numTotalResults - this._currentIndex + 1, this._maxNum); + // num found has to be the number of docs before filtering happens - this is the total num + const { docs, numFound } = await SearchUtil.Search(query, true, index, num); + // accounts for the fact that there may be fewer documents than the max that are returned + let filteredDocs = FilterBox.Instance.filterDocsByType(docs); + count = Math.min(numFound, count); + // uh what is going on here with the first part? + if (numFound !== this._numTotalResults && this._numTotalResults === 0) { + console.log(`Total: ${numFound}`); + this._numTotalResults = numFound; } - resDocs.push(...FilterBox.Instance.filterDocsByType(docs)); - this._currentIndex += this._maxNum; + + // if (filteredDocs.length < docs.length) { + // this._numResults -= docs.length - filteredDocs.length; + // console.log(`New Total: ${this._numResults}`); + // } + resDocs.push(...filteredDocs); + this._currentIndex += docs.length; + console.log(`ResDocs: ${resDocs.length}`); + console.log(`CurrIndex: ${this._currentIndex}`); } return resDocs; } @@ -171,7 +193,7 @@ export class SearchBox extends React.Component { @action.bound closeSearch = () => { - console.log("closing search"); + console.log("closing search") FilterBox.Instance.closeFilter(); this.closeResults(); } @@ -180,46 +202,67 @@ export class SearchBox extends React.Component { closeResults() { this._resultsOpen = false; this._results = []; + this._visibleElements = []; + this._currentIndex = 0; + this._numTotalResults = 0; + this._startIndex = -1; + this._endIndex = -1; } + @action resultsScrolled = async (e?: React.UIEvent) => { let scrollY = e ? e.currentTarget.scrollTop : 0; let buffer = 4; let startIndex = Math.floor(Math.max(0, scrollY / 70 - buffer)); - let endIndex = Math.ceil(Math.min(this._numResults - 1, startIndex + (560 / 70) + buffer)); + let endIndex = Math.ceil(Math.min(this._numTotalResults - 1, startIndex + (560 / 70) + buffer)); - runInAction(() => { - if (this._numResults === 0 && this._openNoResults) { - this._visibleElements = [
No Search Results
]; - return; - } - else if (this._visibleElements.length !== this._numResults) { - this._visibleElements = Array(this._numResults); - this._isSearch = Array(this._numResults); - } - }); + if (startIndex === this._startIndex && endIndex === this._endIndex) { + return; + } + + console.log(`START: ${startIndex}`); + console.log(`END: ${endIndex}`); + + this._startIndex = startIndex; + this._endIndex = endIndex; + + if (this._numTotalResults === 0 && this._openNoResults) { + this._visibleElements = [
No Search Results
]; + return; + } - for (let i = 0; i < this._numResults; i++) { + else if (this._visibleElements.length !== this._numTotalResults) { + this._visibleElements = Array(this._numTotalResults); + this._isSearch = Array(this._numTotalResults); + } + + for (let i = 0; i < this._numTotalResults; i++) { if (i < startIndex || i > endIndex) { if (this._isSearch[i] !== "placeholder") { this._isSearch[i] = "placeholder"; - runInAction(() => { - this._visibleElements[i] =
; - }); + this._visibleElements[i] =
; } } else { if (this._isSearch[i] !== "search") { let result: Doc | undefined = undefined; if (i >= this._results.length) { - this._results.push(...(await this.getResults(this._searchString, 1))); - } - result = this._results[i]; - if (result) { + let results = await this.getResults(this._searchString, i - this._results.length) runInAction(() => { - this._visibleElements[i] = ; - }); - this._isSearch[i] = "search"; + this._results.push(...results); + result = this._results[i]; + if (result) { + this._visibleElements[i] = ; + this._isSearch[i] = "search"; + } + }) + } + else { + result = this._results[i]; + if (result) { + this._visibleElements[i] = ; + this._isSearch[i] = "search"; + } } } } -- cgit v1.2.3-70-g09d2 From 701509141f793d4c7335771ade8a7b1dae49985a Mon Sep 17 00:00:00 2001 From: monikahedman Date: Wed, 10 Jul 2019 16:14:13 -0400 Subject: bout to do something cray --- src/client/views/search/SearchBox.tsx | 137 ++++++++++++++++++++++++++++++---- 1 file changed, 121 insertions(+), 16 deletions(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 430ca3b2e..296d2ccc8 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { observer } from 'mobx-react'; -import { observable, action, runInAction } from 'mobx'; +import { observable, action, runInAction, flow } from 'mobx'; import "./SearchBox.scss"; import "./FilterBox.scss"; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; @@ -33,9 +33,9 @@ export class SearchBox extends React.Component { private _isSearch: ("search" | "placeholder" | undefined)[] = []; private _currentIndex = 0; private _numTotalResults = 0; - private _numFilteredResults = 0; private _startIndex = -1; private _endIndex = -1; + private _fetchedIndices: number[] = [0]; static Instance: SearchBox; @@ -43,6 +43,7 @@ export class SearchBox extends React.Component { super(props); SearchBox.Instance = this; + this.resultsScrolled = this.resultsScrolled.bind(this); } @action @@ -123,10 +124,13 @@ export class SearchBox extends React.Component { let num = count === -1 ? undefined : Math.min(this._numTotalResults - this._currentIndex + 1, this._maxNum); // num found has to be the number of docs before filtering happens - this is the total num const { docs, numFound } = await SearchUtil.Search(query, true, index, num); - // accounts for the fact that there may be fewer documents than the max that are returned + let filteredDocs = FilterBox.Instance.filterDocsByType(docs); + + // accounts for the fact that there may be fewer documents than the max that are returned count = Math.min(numFound, count); - // uh what is going on here with the first part? + + // happens at the beginning if (numFound !== this._numTotalResults && this._numTotalResults === 0) { console.log(`Total: ${numFound}`); this._numTotalResults = numFound; @@ -137,13 +141,104 @@ export class SearchBox extends React.Component { // console.log(`New Total: ${this._numResults}`); // } resDocs.push(...filteredDocs); + this._currentIndex += docs.length; + console.log(`ResDocs: ${resDocs.length}`); console.log(`CurrIndex: ${this._currentIndex}`); } + console.log(this.getResults2(query, count, [])); return resDocs; } + @action + getResults2 = async (query: string, count: number, docs?: Doc[]) => { + console.log("results 2") + let buffer = 4; + // let goalIndex = this._endIndex + count; + // let bottomBound = Math.floor(goalIndex / 10) * 10; + let tempIndex = this._currentIndex; + let goalNum = this._endIndex + buffer; + let resDocs: Doc[]; + + if (docs) { + resDocs = docs; + } else { + resDocs = []; + } + + // let topBound = bottomBound - 10; + // let unfilteredDocs: Doc[]; + // let unfilteredFound: number; + // means this has already been fetched + // if (this._fetchedIndices.includes(topBound)) { + // return; + // } + + let index = count <= 0 ? undefined : this._currentIndex; + if (index) { + let topBound = Math.ceil(index / 10) * 10; + if (this._fetchedIndices.includes(topBound)) { + return; + } + let startIndex = this._fetchedIndices[this._fetchedIndices.length - 1]; + let endIndex = startIndex + 10; + this._fetchedIndices.push(endIndex); + console.log(this._fetchedIndices) + let prom: Promise = SearchUtil.Search(query, true, index, 10); + + prom.then((res: SearchUtil.DocSearchResult) => { + count = Math.min(res.numFound, count); + console.log(res.docs); + let filteredDocs = FilterBox.Instance.filterDocsByType(res.docs); + + if (res.numFound !== this._numTotalResults && this._numTotalResults === 0) { + this._numTotalResults = res.numFound; + } + + resDocs.push(...filteredDocs); + + tempIndex += res.docs.length; + + if (filteredDocs.length <= count) { + runInAction(() => { + return this.getResults2(query, count - filteredDocs.length, resDocs); + }); + } + else { + return resDocs; + } + console.log(tempIndex); + console.log(resDocs.length); + }) + + } + //this is the upper bound of the last + // let index = this._fetchedIndices[this._fetchedIndices.length - 1]; + // let prom: Promise = SearchUtil.Search(query, true, index, 10); + + // prom.then((res: SearchUtil.DocSearchResult) => { + // // unfilteredDocs = res.docs; + // // unfilteredFound = res.numFound; + + // count = Math.min(res.numFound, count); + // let filteredDocs = FilterBox.Instance.filterDocsByType(res.docs); + + // if (res.numFound !== this._numTotalResults && this._numTotalResults === 0) { + // console.log(`Total: ${res.numFound}`); + // this._numTotalResults = res.numFound; + // } + + // resDocs.push(...filteredDocs); + + // this._currentIndex += res.docs.length; + // }) + + // console.log(prom); + + + } + collectionRef = React.createRef(); startDragCollection = async () => { const results = await this.getResults(FilterBox.Instance.getFinalQuery(this._searchString), -1); @@ -209,8 +304,7 @@ export class SearchBox extends React.Component { this._endIndex = -1; } - @action - resultsScrolled = async (e?: React.UIEvent) => { + resultsScrolled = flow(function* (this: SearchBox, e?: React.UIEvent) { let scrollY = e ? e.currentTarget.scrollTop : 0; let buffer = 4; let startIndex = Math.floor(Math.max(0, scrollY / 70 - buffer)); @@ -222,6 +316,7 @@ export class SearchBox extends React.Component { console.log(`START: ${startIndex}`); console.log(`END: ${endIndex}`); + console.log("_________________________________________________________________________________________________________") this._startIndex = startIndex; this._endIndex = endIndex; @@ -231,12 +326,18 @@ export class SearchBox extends React.Component { return; } + // only hit right at the beginning + // visibleElements is all of the elements (even the ones you can't see) else if (this._visibleElements.length !== this._numTotalResults) { + // undefined until a searchitem is put in there this._visibleElements = Array(this._numTotalResults); + // indicates if things are placeholders this._isSearch = Array(this._numTotalResults); } for (let i = 0; i < this._numTotalResults; i++) { + //if the index is out of the window then put a placeholder in + //should ones that have already been found get set to placeholders? if (i < startIndex || i > endIndex) { if (this._isSearch[i] !== "placeholder") { this._isSearch[i] = "placeholder"; @@ -247,15 +348,19 @@ export class SearchBox extends React.Component { if (this._isSearch[i] !== "search") { let result: Doc | undefined = undefined; if (i >= this._results.length) { - let results = await this.getResults(this._searchString, i - this._results.length) - runInAction(() => { - this._results.push(...results); - result = this._results[i]; - if (result) { - this._visibleElements[i] = ; - this._isSearch[i] = "search"; - } - }) + // _________________________________________________________________________________________________ + let results: Doc[] = yield this.getResults(this._searchString, i + 1 - this._results.length); + if (results.length !== 0) { + runInAction(() => { + this._results.push(...results); + result = this._results[i]; + if (result) { + this._visibleElements[i] = ; + this._isSearch[i] = "search"; + } + }); + } + // _________________________________________________________________________________________________ } else { result = this._results[i]; @@ -267,7 +372,7 @@ export class SearchBox extends React.Component { } } } - } + }); render() { return ( -- cgit v1.2.3-70-g09d2 From a2e762e4a85eca92401394afe7dbc03db5a5b473 Mon Sep 17 00:00:00 2001 From: monikahedman Date: Wed, 10 Jul 2019 18:17:14 -0400 Subject: hate this --- src/client/views/search/SearchBox.tsx | 55 +++++++++++++++-------------------- 1 file changed, 23 insertions(+), 32 deletions(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 296d2ccc8..db6f69ccb 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -65,8 +65,8 @@ export class SearchBox extends React.Component { this._visibleElements = []; this._currentIndex = 0; this._numTotalResults = 0; - this._startIndex = -1; - this._endIndex = -1; + this._startIndex = 0; + this._endIndex = 12; } enter = (e: React.KeyboardEvent) => { if (e.key === "Enter") { this.submitSearch(); } } @@ -144,28 +144,21 @@ export class SearchBox extends React.Component { this._currentIndex += docs.length; - console.log(`ResDocs: ${resDocs.length}`); + // console.log(`ResDocs: ${resDocs.length}`); console.log(`CurrIndex: ${this._currentIndex}`); } - console.log(this.getResults2(query, count, [])); + // console.log(this.getResults2(query, count, [])); return resDocs; } @action - getResults2 = async (query: string, count: number, docs?: Doc[]) => { - console.log("results 2") - let buffer = 4; + getResults2 = async (query: string, count: number, docs: Doc[]) => { + // let buffer = 4; // let goalIndex = this._endIndex + count; // let bottomBound = Math.floor(goalIndex / 10) * 10; - let tempIndex = this._currentIndex; - let goalNum = this._endIndex + buffer; - let resDocs: Doc[]; - - if (docs) { - resDocs = docs; - } else { - resDocs = []; - } + // let tempIndex = this._currentIndex; + // let goalNum = this._endIndex + buffer; + let resDocs: Doc[] = docs; // let topBound = bottomBound - 10; // let unfilteredDocs: Doc[]; @@ -176,10 +169,12 @@ export class SearchBox extends React.Component { // } let index = count <= 0 ? undefined : this._currentIndex; + // let index = this._currentIndex; if (index) { let topBound = Math.ceil(index / 10) * 10; if (this._fetchedIndices.includes(topBound)) { - return; + // console.log("returning NOTHING") + return resDocs; } let startIndex = this._fetchedIndices[this._fetchedIndices.length - 1]; let endIndex = startIndex + 10; @@ -198,21 +193,17 @@ export class SearchBox extends React.Component { resDocs.push(...filteredDocs); - tempIndex += res.docs.length; + this._currentIndex += res.docs.length; - if (filteredDocs.length <= count) { - runInAction(() => { - return this.getResults2(query, count - filteredDocs.length, resDocs); - }); - } - else { - return resDocs; + if (resDocs.length < count) { + return this.getResults2(query, count - resDocs.length, resDocs); + // resDocs = await this.getResults2(query, count - filteredDocs.length, resDocs); } - console.log(tempIndex); - console.log(resDocs.length); - }) + return resDocs; + }) } + return resDocs; //this is the upper bound of the last // let index = this._fetchedIndices[this._fetchedIndices.length - 1]; // let prom: Promise = SearchUtil.Search(query, true, index, 10); @@ -300,8 +291,8 @@ export class SearchBox extends React.Component { this._visibleElements = []; this._currentIndex = 0; this._numTotalResults = 0; - this._startIndex = -1; - this._endIndex = -1; + this._startIndex = 0; + this._endIndex = 12; } resultsScrolled = flow(function* (this: SearchBox, e?: React.UIEvent) { @@ -316,8 +307,6 @@ export class SearchBox extends React.Component { console.log(`START: ${startIndex}`); console.log(`END: ${endIndex}`); - console.log("_________________________________________________________________________________________________________") - this._startIndex = startIndex; this._endIndex = endIndex; @@ -350,6 +339,7 @@ export class SearchBox extends React.Component { if (i >= this._results.length) { // _________________________________________________________________________________________________ let results: Doc[] = yield this.getResults(this._searchString, i + 1 - this._results.length); + console.log(results) if (results.length !== 0) { runInAction(() => { this._results.push(...results); @@ -372,6 +362,7 @@ export class SearchBox extends React.Component { } } } + console.log("_________________________________________________________________________________________________________") }); render() { -- cgit v1.2.3-70-g09d2 From 8888e3aef8658e4100e2fc4bee6b805e7b0feaa9 Mon Sep 17 00:00:00 2001 From: monikahedman Date: Wed, 10 Jul 2019 20:31:57 -0400 Subject: dear god i hate this --- src/client/views/search/SearchBox.tsx | 173 +++++++++++++++++----------------- 1 file changed, 87 insertions(+), 86 deletions(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index db6f69ccb..1980ddaf2 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -39,6 +39,8 @@ export class SearchBox extends React.Component { static Instance: SearchBox; + private _maxSearchIndex: number = 0; + constructor(props: any) { super(props); @@ -65,8 +67,8 @@ export class SearchBox extends React.Component { this._visibleElements = []; this._currentIndex = 0; this._numTotalResults = 0; - this._startIndex = 0; - this._endIndex = 12; + this._startIndex = -1; + this._endIndex = -1; } enter = (e: React.KeyboardEvent) => { if (e.key === "Enter") { this.submitSearch(); } } @@ -114,6 +116,25 @@ export class SearchBox extends React.Component { }); } + getResultsHelp = async (query: string) => { + // docs length = this._results.length --> number of docs that are shown (after filtering) + // stops looking once this._results.length >= maxDisplayIndex + // max search index = number of results looked through in solr (solr index) --> increments of 10 + // max display index = number of documents that SHOULD be shown (should include buffer), this._endIndex + buffer (= 4) + // currentRequest = promise | undefined, if undefined, can run and look for more. If not undefined, then there is a request in progress and it cannot look for more yet + + let buffer = 4; + let maxDisplayIndex: number = this._endIndex + buffer; + let curRequest = undefined; + + + while (this._results.length < maxDisplayIndex) { + if (curRequest === undefined) { + + } + } + } + @action getResults = async (query: string, count: number) => { let resDocs = []; @@ -144,91 +165,72 @@ export class SearchBox extends React.Component { this._currentIndex += docs.length; - // console.log(`ResDocs: ${resDocs.length}`); + console.log(`ResDocs: ${resDocs.length}`); console.log(`CurrIndex: ${this._currentIndex}`); } // console.log(this.getResults2(query, count, [])); return resDocs; } - @action - getResults2 = async (query: string, count: number, docs: Doc[]) => { - // let buffer = 4; - // let goalIndex = this._endIndex + count; - // let bottomBound = Math.floor(goalIndex / 10) * 10; - // let tempIndex = this._currentIndex; - // let goalNum = this._endIndex + buffer; - let resDocs: Doc[] = docs; - - // let topBound = bottomBound - 10; - // let unfilteredDocs: Doc[]; - // let unfilteredFound: number; - // means this has already been fetched - // if (this._fetchedIndices.includes(topBound)) { - // return; - // } - - let index = count <= 0 ? undefined : this._currentIndex; - // let index = this._currentIndex; - if (index) { - let topBound = Math.ceil(index / 10) * 10; - if (this._fetchedIndices.includes(topBound)) { - // console.log("returning NOTHING") - return resDocs; - } - let startIndex = this._fetchedIndices[this._fetchedIndices.length - 1]; - let endIndex = startIndex + 10; - this._fetchedIndices.push(endIndex); - console.log(this._fetchedIndices) - let prom: Promise = SearchUtil.Search(query, true, index, 10); - - prom.then((res: SearchUtil.DocSearchResult) => { - count = Math.min(res.numFound, count); - console.log(res.docs); - let filteredDocs = FilterBox.Instance.filterDocsByType(res.docs); - - if (res.numFound !== this._numTotalResults && this._numTotalResults === 0) { - this._numTotalResults = res.numFound; - } - - resDocs.push(...filteredDocs); - - this._currentIndex += res.docs.length; - - if (resDocs.length < count) { - return this.getResults2(query, count - resDocs.length, resDocs); - // resDocs = await this.getResults2(query, count - filteredDocs.length, resDocs); - } - - return resDocs; - }) - } - return resDocs; - //this is the upper bound of the last - // let index = this._fetchedIndices[this._fetchedIndices.length - 1]; - // let prom: Promise = SearchUtil.Search(query, true, index, 10); - - // prom.then((res: SearchUtil.DocSearchResult) => { - // // unfilteredDocs = res.docs; - // // unfilteredFound = res.numFound; - - // count = Math.min(res.numFound, count); - // let filteredDocs = FilterBox.Instance.filterDocsByType(res.docs); - - // if (res.numFound !== this._numTotalResults && this._numTotalResults === 0) { - // console.log(`Total: ${res.numFound}`); - // this._numTotalResults = res.numFound; - // } - - // resDocs.push(...filteredDocs); - - // this._currentIndex += res.docs.length; - // }) - - // console.log(prom); - - - } + // @action + // getResults2 = async (query: string, count: number, docs: Doc[]) => { + // console.log("results 2") + // let buffer = 4; + // // let goalIndex = this._endIndex + count; + // // let bottomBound = Math.floor(goalIndex / 10) * 10; + // let tempIndex = this._currentIndex; + // let goalNum = this._endIndex + buffer; + // let resDocs: Doc[] = docs; + + // // let topBound = bottomBound - 10; + // // let unfilteredDocs: Doc[]; + // // let unfilteredFound: number; + // // means this has already been fetched + // // if (this._fetchedIndices.includes(topBound)) { + // // return; + // // } + + // let index = count <= 0 ? undefined : this._currentIndex; + // if (index) { + // let topBound = Math.ceil(index / 10) * 10; + // if (this._fetchedIndices.includes(topBound)) { + // return; + // } + // let startIndex = this._fetchedIndices[this._fetchedIndices.length - 1]; + // let endIndex = startIndex + 10; + // this._fetchedIndices.push(endIndex); + // console.log(this._fetchedIndices) + // let prom: Promise = SearchUtil.Search(query, true, index, 10); + + // prom.then((res: SearchUtil.DocSearchResult) => { + // count = Math.min(res.numFound, count); + // console.log(res.docs); + // let filteredDocs = FilterBox.Instance.filterDocsByType(res.docs); + + // if (res.numFound !== this._numTotalResults && this._numTotalResults === 0) { + // this._numTotalResults = res.numFound; + // } + + // resDocs.push(...filteredDocs); + + // this._currentIndex += res.docs.length; + + // if (resDocs.length <= count) { + // runInAction(() => { + // return this.getResults2(query, count, resDocs); + // }); + // } + // else { + // return resDocs; + // } + // // console.log(tempIndex); + // console.log(resDocs.length); + // }) + + // } + + + // } collectionRef = React.createRef(); startDragCollection = async () => { @@ -291,8 +293,8 @@ export class SearchBox extends React.Component { this._visibleElements = []; this._currentIndex = 0; this._numTotalResults = 0; - this._startIndex = 0; - this._endIndex = 12; + this._startIndex = -1; + this._endIndex = -1; } resultsScrolled = flow(function* (this: SearchBox, e?: React.UIEvent) { @@ -304,9 +306,10 @@ export class SearchBox extends React.Component { if (startIndex === this._startIndex && endIndex === this._endIndex) { return; } - + console.log("_________________________________________________________________________________________________________") console.log(`START: ${startIndex}`); console.log(`END: ${endIndex}`); + this._startIndex = startIndex; this._endIndex = endIndex; @@ -339,7 +342,6 @@ export class SearchBox extends React.Component { if (i >= this._results.length) { // _________________________________________________________________________________________________ let results: Doc[] = yield this.getResults(this._searchString, i + 1 - this._results.length); - console.log(results) if (results.length !== 0) { runInAction(() => { this._results.push(...results); @@ -362,7 +364,6 @@ export class SearchBox extends React.Component { } } } - console.log("_________________________________________________________________________________________________________") }); render() { -- cgit v1.2.3-70-g09d2 From 341d173db8f1580f49dc4e9ff429b72d88da16b4 Mon Sep 17 00:00:00 2001 From: monikahedman Date: Thu, 11 Jul 2019 18:01:35 -0400 Subject: end of day 7/11 ho boy we got problems --- src/client/views/search/SearchBox.tsx | 182 +++++++++++++++++++++++----------- 1 file changed, 126 insertions(+), 56 deletions(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 1980ddaf2..0816bb9de 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -40,6 +40,7 @@ export class SearchBox extends React.Component { static Instance: SearchBox; private _maxSearchIndex: number = 0; + private _curRequest: Promise | undefined = undefined; constructor(props: any) { super(props); @@ -69,6 +70,8 @@ export class SearchBox extends React.Component { this._numTotalResults = 0; this._startIndex = -1; this._endIndex = -1; + this._curRequest = undefined; + this._maxSearchIndex = 0; } enter = (e: React.KeyboardEvent) => { if (e.key === "Enter") { this.submitSearch(); } } @@ -97,20 +100,43 @@ export class SearchBox extends React.Component { query = FilterBox.Instance.getFinalQuery(query); + // if (this._curRequest !== undefined) { + // this._curRequest.then(() => { + // this._curRequest = undefined; + // this._results = []; + // }); + // } + + // this._results = []; + //if there is no query there should be no result if (query === "") { - results = []; + // results = []; + return; } else { //gets json result into a list of documents that can be used //these are filtered by type + // this._results = []; this._currentIndex = 0; - results = await this.getResults(query, 12); + this._startIndex = 0; + this._endIndex = 12; + // this._curRequest = undefined; + // if (this._curRequest !== undefined) { + // this._curRequest.then(() => { + // this._curRequest = undefined; + // }); + // } + + this._maxSearchIndex = 0; + + // results = await this.getResultsHelp(query); + await this.getResultsHelp(query); } runInAction(() => { this._resultsOpen = true; - this._results = results; + // this._results = results; this._openNoResults = true; this.resultsScrolled(); }); @@ -123,54 +149,85 @@ export class SearchBox extends React.Component { // max display index = number of documents that SHOULD be shown (should include buffer), this._endIndex + buffer (= 4) // currentRequest = promise | undefined, if undefined, can run and look for more. If not undefined, then there is a request in progress and it cannot look for more yet - let buffer = 4; - let maxDisplayIndex: number = this._endIndex + buffer; - let curRequest = undefined; + // let buffer = 4; + // let maxDisplayIndex: number = this._endIndex + buffer; + console.log(`end index: ${this._endIndex}`) + console.log(this._results.length) + + while (this._results.length < this._endIndex) { + console.log("looping") + if (this._curRequest === undefined) { + //start at max search index, get 10, add 10 to max search index + // const { docs, numFound } = await SearchUtil.Search(query, true, this._maxSearchIndex, 10); + // happens at the beginning + // am i gonna need this? + // if (numFound !== this._numTotalResults && this._numTotalResults === 0) { + // this._numTotalResults = numFound; + // } - while (this._results.length < maxDisplayIndex) { - if (curRequest === undefined) { + this._curRequest = SearchUtil.Search(query, true, this._maxSearchIndex, 10); + this._maxSearchIndex += 10; + this._curRequest.then((res: SearchUtil.DocSearchResult) => { + + // happens at the beginning + if (res.numFound !== this._numTotalResults && this._numTotalResults === 0) { + this._numTotalResults = res.numFound; + } + + let filteredDocs = FilterBox.Instance.filterDocsByType(res.docs); + this._results.push(...filteredDocs); + + console.log(this._results) + this._curRequest = undefined; + console.log("setting to undefined") + }); + + //deals with if there are fewer results than can be scrolled through + // if (this._numTotalResults < this._endIndex) { + // break; + // } } } } - @action - getResults = async (query: string, count: number) => { - let resDocs = []; - // count is total number of documents to be shown (i believe) - console.log(`Count: ${count}`); - while (resDocs.length < count) { - let index = count === -1 ? undefined : this._currentIndex; - let num = count === -1 ? undefined : Math.min(this._numTotalResults - this._currentIndex + 1, this._maxNum); - // num found has to be the number of docs before filtering happens - this is the total num - const { docs, numFound } = await SearchUtil.Search(query, true, index, num); - - let filteredDocs = FilterBox.Instance.filterDocsByType(docs); - - // accounts for the fact that there may be fewer documents than the max that are returned - count = Math.min(numFound, count); - - // happens at the beginning - if (numFound !== this._numTotalResults && this._numTotalResults === 0) { - console.log(`Total: ${numFound}`); - this._numTotalResults = numFound; - } + // @action + // getResults = async (query: string, count: number) => { + // let resDocs = []; + // // count is total number of documents to be shown (i believe) + // console.log(`Count: ${count}`); + // while (resDocs.length < count) { + // let index = count === -1 ? undefined : this._currentIndex; + // let num = count === -1 ? undefined : Math.min(this._numTotalResults - this._currentIndex + 1, this._maxNum); + // // num found has to be the number of docs before filtering happens - this is the total num + // const { docs, numFound } = await SearchUtil.Search(query, true, index, num); + + // let filteredDocs = FilterBox.Instance.filterDocsByType(docs); + + // // accounts for the fact that there may be fewer documents than the max that are returned + // count = Math.min(numFound, count); + + // // happens at the beginning + // if (numFound !== this._numTotalResults && this._numTotalResults === 0) { + // console.log(`Total: ${numFound}`); + // this._numTotalResults = numFound; + // } - // if (filteredDocs.length < docs.length) { - // this._numResults -= docs.length - filteredDocs.length; - // console.log(`New Total: ${this._numResults}`); - // } - resDocs.push(...filteredDocs); + // // if (filteredDocs.length < docs.length) { + // // this._numResults -= docs.length - filteredDocs.length; + // // console.log(`New Total: ${this._numResults}`); + // // } + // resDocs.push(...filteredDocs); - this._currentIndex += docs.length; + // this._currentIndex += docs.length; - console.log(`ResDocs: ${resDocs.length}`); - console.log(`CurrIndex: ${this._currentIndex}`); - } - // console.log(this.getResults2(query, count, [])); - return resDocs; - } + // console.log(`ResDocs: ${resDocs.length}`); + // console.log(`CurrIndex: ${this._currentIndex}`); + // } + // // console.log(this.getResults2(query, count, [])); + // return resDocs; + // } // @action // getResults2 = async (query: string, count: number, docs: Doc[]) => { @@ -234,8 +291,9 @@ export class SearchBox extends React.Component { collectionRef = React.createRef(); startDragCollection = async () => { - const results = await this.getResults(FilterBox.Instance.getFinalQuery(this._searchString), -1); - const docs = results.map(doc => { + // const results = await this.getResults(FilterBox.Instance.getFinalQuery(this._searchString), -1); + await this.getResultsHelp(FilterBox.Instance.getFinalQuery(this._searchString)); + const docs = this._results.map(doc => { const isProto = Doc.GetT(doc, "isPrototype", "boolean", true); if (isProto) { return Doc.MakeDelegate(doc); @@ -295,23 +353,27 @@ export class SearchBox extends React.Component { this._numTotalResults = 0; this._startIndex = -1; this._endIndex = -1; + this._curRequest = undefined; } resultsScrolled = flow(function* (this: SearchBox, e?: React.UIEvent) { + console.log("_________________________________________________________________________________________________________") let scrollY = e ? e.currentTarget.scrollTop : 0; let buffer = 4; + console.log(`start before: ${this._startIndex}`); let startIndex = Math.floor(Math.max(0, scrollY / 70 - buffer)); + console.log(`end before: ${this._endIndex}`); let endIndex = Math.ceil(Math.min(this._numTotalResults - 1, startIndex + (560 / 70) + buffer)); if (startIndex === this._startIndex && endIndex === this._endIndex) { + console.log("returning") return; } - console.log("_________________________________________________________________________________________________________") console.log(`START: ${startIndex}`); console.log(`END: ${endIndex}`); - this._startIndex = startIndex; - this._endIndex = endIndex; + this._startIndex = startIndex === -1 ? 0 : startIndex; + this._endIndex = endIndex === -1 ? 12 : endIndex; if (this._numTotalResults === 0 && this._openNoResults) { this._visibleElements = [
No Search Results
]; @@ -341,17 +403,25 @@ export class SearchBox extends React.Component { let result: Doc | undefined = undefined; if (i >= this._results.length) { // _________________________________________________________________________________________________ - let results: Doc[] = yield this.getResults(this._searchString, i + 1 - this._results.length); - if (results.length !== 0) { - runInAction(() => { - this._results.push(...results); - result = this._results[i]; - if (result) { - this._visibleElements[i] = ; - this._isSearch[i] = "search"; - } - }); + // let results: Doc[] = yield this.getResults(this._searchString, i + 1 - this._results.length); + + // this updates this._results + yield this.getResultsHelp(this._searchString); + result = this._results[i]; + if (result) { + this._visibleElements[i] = ; + this._isSearch[i] = "search"; } + // if (results.length !== 0) { + // runInAction(() => { + // // this._results.push(...results); + // result = this._results[i]; + // if (result) { + // this._visibleElements[i] = ; + // this._isSearch[i] = "search"; + // } + // }); + // } // _________________________________________________________________________________________________ } else { -- cgit v1.2.3-70-g09d2 From e289ffead09b091fdb40aab47ea4d04ae5935455 Mon Sep 17 00:00:00 2001 From: monikahedman Date: Fri, 12 Jul 2019 15:28:34 -0400 Subject: things almost working yeet yeet --- src/client/views/search/SearchBox.tsx | 190 ++++++++++------------------------ 1 file changed, 54 insertions(+), 136 deletions(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 0816bb9de..8e5d317f0 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -16,6 +16,8 @@ import { SearchUtil } from '../../util/SearchUtil'; import { RouteStore } from '../../../server/RouteStore'; import { FilterBox } from './FilterBox'; import { start } from 'repl'; +import { getForkTsCheckerWebpackPluginHooks } from 'fork-ts-checker-webpack-plugin/lib/hooks'; +import { faThumbsDown } from '@fortawesome/free-regular-svg-icons'; @observer export class SearchBox extends React.Component { @@ -32,7 +34,7 @@ export class SearchBox extends React.Component { private _isSearch: ("search" | "placeholder" | undefined)[] = []; private _currentIndex = 0; - private _numTotalResults = 0; + private _numTotalResults = -1; private _startIndex = -1; private _endIndex = -1; private _fetchedIndices: number[] = [0]; @@ -40,7 +42,7 @@ export class SearchBox extends React.Component { static Instance: SearchBox; private _maxSearchIndex: number = 0; - private _curRequest: Promise | undefined = undefined; + private _curRequest?: Promise = undefined; constructor(props: any) { super(props); @@ -67,7 +69,7 @@ export class SearchBox extends React.Component { this._results = []; this._visibleElements = []; this._currentIndex = 0; - this._numTotalResults = 0; + this._numTotalResults = -1; this._startIndex = -1; this._endIndex = -1; this._curRequest = undefined; @@ -121,6 +123,7 @@ export class SearchBox extends React.Component { this._currentIndex = 0; this._startIndex = 0; this._endIndex = 12; + this._results = []; // this._curRequest = undefined; // if (this._curRequest !== undefined) { // this._curRequest.then(() => { @@ -129,6 +132,7 @@ export class SearchBox extends React.Component { // } this._maxSearchIndex = 0; + this._numTotalResults = -1; // results = await this.getResultsHelp(query); await this.getResultsHelp(query); @@ -151,144 +155,58 @@ export class SearchBox extends React.Component { // let buffer = 4; // let maxDisplayIndex: number = this._endIndex + buffer; - console.log(`end index: ${this._endIndex}`) - console.log(this._results.length) + // console.log(`end index: ${this._endIndex}`) + // console.log(this._results.length) + + while (this._results.length < this._endIndex && (this._numTotalResults === -1 || this._maxSearchIndex < this._numTotalResults)) { + console.log("looping"); + //start at max search index, get 10, add 10 to max search index + // const { docs, numFound } = await SearchUtil.Search(query, true, this._maxSearchIndex, 10); + + // happens at the beginning + // am i gonna need this? + // if (numFound !== this._numTotalResults && this._numTotalResults === 0) { + // this._numTotalResults = numFound; + // } - while (this._results.length < this._endIndex) { - console.log("looping") - if (this._curRequest === undefined) { - //start at max search index, get 10, add 10 to max search index - // const { docs, numFound } = await SearchUtil.Search(query, true, this._maxSearchIndex, 10); + let prom: Promise; + if (this._curRequest) { + prom = this._curRequest; + return; + } else { + prom = SearchUtil.Search(query, true, this._maxSearchIndex, 10); + this._maxSearchIndex += 10; + } + prom.then(action((res: SearchUtil.DocSearchResult) => { // happens at the beginning - // am i gonna need this? - // if (numFound !== this._numTotalResults && this._numTotalResults === 0) { - // this._numTotalResults = numFound; - // } + if (res.numFound !== this._numTotalResults && this._numTotalResults === -1) { + this._numTotalResults = res.numFound; + } - this._curRequest = SearchUtil.Search(query, true, this._maxSearchIndex, 10); - this._maxSearchIndex += 10; + let filteredDocs = FilterBox.Instance.filterDocsByType(res.docs); + this._results.push(...filteredDocs); - this._curRequest.then((res: SearchUtil.DocSearchResult) => { + console.log(this._results); + if (prom === this._curRequest) { + this._curRequest = undefined; + } + console.log("setting to undefined"); + })); - // happens at the beginning - if (res.numFound !== this._numTotalResults && this._numTotalResults === 0) { - this._numTotalResults = res.numFound; - } - let filteredDocs = FilterBox.Instance.filterDocsByType(res.docs); - this._results.push(...filteredDocs); - console.log(this._results) - this._curRequest = undefined; - console.log("setting to undefined") - }); + this._curRequest = prom; - //deals with if there are fewer results than can be scrolled through - // if (this._numTotalResults < this._endIndex) { - // break; - // } - } + await prom; + + //deals with if there are fewer results than can be scrolled through + // if (this._numTotalResults < this._endIndex) { + // break; + // } } } - // @action - // getResults = async (query: string, count: number) => { - // let resDocs = []; - // // count is total number of documents to be shown (i believe) - // console.log(`Count: ${count}`); - // while (resDocs.length < count) { - // let index = count === -1 ? undefined : this._currentIndex; - // let num = count === -1 ? undefined : Math.min(this._numTotalResults - this._currentIndex + 1, this._maxNum); - // // num found has to be the number of docs before filtering happens - this is the total num - // const { docs, numFound } = await SearchUtil.Search(query, true, index, num); - - // let filteredDocs = FilterBox.Instance.filterDocsByType(docs); - - // // accounts for the fact that there may be fewer documents than the max that are returned - // count = Math.min(numFound, count); - - // // happens at the beginning - // if (numFound !== this._numTotalResults && this._numTotalResults === 0) { - // console.log(`Total: ${numFound}`); - // this._numTotalResults = numFound; - // } - - // // if (filteredDocs.length < docs.length) { - // // this._numResults -= docs.length - filteredDocs.length; - // // console.log(`New Total: ${this._numResults}`); - // // } - // resDocs.push(...filteredDocs); - - // this._currentIndex += docs.length; - - // console.log(`ResDocs: ${resDocs.length}`); - // console.log(`CurrIndex: ${this._currentIndex}`); - // } - // // console.log(this.getResults2(query, count, [])); - // return resDocs; - // } - - // @action - // getResults2 = async (query: string, count: number, docs: Doc[]) => { - // console.log("results 2") - // let buffer = 4; - // // let goalIndex = this._endIndex + count; - // // let bottomBound = Math.floor(goalIndex / 10) * 10; - // let tempIndex = this._currentIndex; - // let goalNum = this._endIndex + buffer; - // let resDocs: Doc[] = docs; - - // // let topBound = bottomBound - 10; - // // let unfilteredDocs: Doc[]; - // // let unfilteredFound: number; - // // means this has already been fetched - // // if (this._fetchedIndices.includes(topBound)) { - // // return; - // // } - - // let index = count <= 0 ? undefined : this._currentIndex; - // if (index) { - // let topBound = Math.ceil(index / 10) * 10; - // if (this._fetchedIndices.includes(topBound)) { - // return; - // } - // let startIndex = this._fetchedIndices[this._fetchedIndices.length - 1]; - // let endIndex = startIndex + 10; - // this._fetchedIndices.push(endIndex); - // console.log(this._fetchedIndices) - // let prom: Promise = SearchUtil.Search(query, true, index, 10); - - // prom.then((res: SearchUtil.DocSearchResult) => { - // count = Math.min(res.numFound, count); - // console.log(res.docs); - // let filteredDocs = FilterBox.Instance.filterDocsByType(res.docs); - - // if (res.numFound !== this._numTotalResults && this._numTotalResults === 0) { - // this._numTotalResults = res.numFound; - // } - - // resDocs.push(...filteredDocs); - - // this._currentIndex += res.docs.length; - - // if (resDocs.length <= count) { - // runInAction(() => { - // return this.getResults2(query, count, resDocs); - // }); - // } - // else { - // return resDocs; - // } - // // console.log(tempIndex); - // console.log(resDocs.length); - // }) - - // } - - - // } - collectionRef = React.createRef(); startDragCollection = async () => { // const results = await this.getResults(FilterBox.Instance.getFinalQuery(this._searchString), -1); @@ -350,7 +268,7 @@ export class SearchBox extends React.Component { this._results = []; this._visibleElements = []; this._currentIndex = 0; - this._numTotalResults = 0; + this._numTotalResults = -1; this._startIndex = -1; this._endIndex = -1; this._curRequest = undefined; @@ -365,10 +283,10 @@ export class SearchBox extends React.Component { console.log(`end before: ${this._endIndex}`); let endIndex = Math.ceil(Math.min(this._numTotalResults - 1, startIndex + (560 / 70) + buffer)); - if (startIndex === this._startIndex && endIndex === this._endIndex) { - console.log("returning") - return; - } + // if (startIndex === this._startIndex && endIndex === this._endIndex && this._results.length > this._endIndex) { + // console.log("returning") + // return; + // } console.log(`START: ${startIndex}`); console.log(`END: ${endIndex}`); @@ -384,9 +302,9 @@ export class SearchBox extends React.Component { // visibleElements is all of the elements (even the ones you can't see) else if (this._visibleElements.length !== this._numTotalResults) { // undefined until a searchitem is put in there - this._visibleElements = Array(this._numTotalResults); + this._visibleElements = Array(this._numTotalResults === -1 ? 0 : this._numTotalResults); // indicates if things are placeholders - this._isSearch = Array(this._numTotalResults); + this._isSearch = Array(this._numTotalResults === -1 ? 0 : this._numTotalResults); } for (let i = 0; i < this._numTotalResults; i++) { -- cgit v1.2.3-70-g09d2 From 00a9a169679baa011c66b28152ff27dec2532907 Mon Sep 17 00:00:00 2001 From: monikahedman Date: Fri, 12 Jul 2019 18:15:31 -0400 Subject: end of day 7/12 --- src/client/views/search/SearchBox.tsx | 175 +++++++++++----------------------- 1 file changed, 54 insertions(+), 121 deletions(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 8e5d317f0..e5280fe8c 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -30,14 +30,12 @@ export class SearchBox extends React.Component { //temp @observable public _maxNum: number = 10; @observable private _visibleElements: JSX.Element[] = []; - @observable private _scrollY: number = 0; + // @observable private _sc rollY: number = 0; private _isSearch: ("search" | "placeholder" | undefined)[] = []; - private _currentIndex = 0; private _numTotalResults = -1; private _startIndex = -1; private _endIndex = -1; - private _fetchedIndices: number[] = [0]; static Instance: SearchBox; @@ -68,7 +66,6 @@ export class SearchBox extends React.Component { this._openNoResults = false; this._results = []; this._visibleElements = []; - this._currentIndex = 0; this._numTotalResults = -1; this._startIndex = -1; this._endIndex = -1; @@ -97,120 +94,81 @@ export class SearchBox extends React.Component { @action submitSearch = async () => { - let query = this._searchString; // searchbox gets query - let results: Doc[]; - + let query = this._searchString; query = FilterBox.Instance.getFinalQuery(query); - - // if (this._curRequest !== undefined) { - // this._curRequest.then(() => { - // this._curRequest = undefined; - // this._results = []; - // }); - // } - - // this._results = []; + this._results = []; + this._isSearch = []; + this._visibleElements = []; //if there is no query there should be no result if (query === "") { - // results = []; return; } else { - //gets json result into a list of documents that can be used - //these are filtered by type - // this._results = []; - this._currentIndex = 0; this._startIndex = 0; this._endIndex = 12; - this._results = []; - // this._curRequest = undefined; - // if (this._curRequest !== undefined) { - // this._curRequest.then(() => { - // this._curRequest = undefined; - // }); - // } - this._maxSearchIndex = 0; this._numTotalResults = -1; - - // results = await this.getResultsHelp(query); - await this.getResultsHelp(query); + await this.getResults(query); } runInAction(() => { this._resultsOpen = true; - // this._results = results; this._openNoResults = true; this.resultsScrolled(); }); - } - getResultsHelp = async (query: string) => { - // docs length = this._results.length --> number of docs that are shown (after filtering) - // stops looking once this._results.length >= maxDisplayIndex - // max search index = number of results looked through in solr (solr index) --> increments of 10 - // max display index = number of documents that SHOULD be shown (should include buffer), this._endIndex + buffer (= 4) - // currentRequest = promise | undefined, if undefined, can run and look for more. If not undefined, then there is a request in progress and it cannot look for more yet - - // let buffer = 4; - // let maxDisplayIndex: number = this._endIndex + buffer; - // console.log(`end index: ${this._endIndex}`) - // console.log(this._results.length) - - while (this._results.length < this._endIndex && (this._numTotalResults === -1 || this._maxSearchIndex < this._numTotalResults)) { - console.log("looping"); - //start at max search index, get 10, add 10 to max search index - // const { docs, numFound } = await SearchUtil.Search(query, true, this._maxSearchIndex, 10); - - // happens at the beginning - // am i gonna need this? - // if (numFound !== this._numTotalResults && this._numTotalResults === 0) { - // this._numTotalResults = numFound; - // } - - let prom: Promise; - if (this._curRequest) { - prom = this._curRequest; - return; - } else { - prom = SearchUtil.Search(query, true, this._maxSearchIndex, 10); - this._maxSearchIndex += 10; - } - prom.then(action((res: SearchUtil.DocSearchResult) => { + console.log(this._results) + } - // happens at the beginning - if (res.numFound !== this._numTotalResults && this._numTotalResults === -1) { - this._numTotalResults = res.numFound; - } + getResults = async (query: string, all: boolean = false) => { - let filteredDocs = FilterBox.Instance.filterDocsByType(res.docs); - this._results.push(...filteredDocs); + if (all) { + // let { numFound, docs } = await SearchUtil.Search(query, true, this._maxSearchIndex, 100000); + let prom: Promise = SearchUtil.Search(query, true, 0, 100000); - console.log(this._results); - if (prom === this._curRequest) { - this._curRequest = undefined; + prom.then(({ docs, numFound }) => { + this._results = docs; + }) + } + else { + while (this._results.length <= this._endIndex && (this._numTotalResults === -1 || this._maxSearchIndex < this._numTotalResults)) { + + let prom: Promise; + if (this._curRequest) { + prom = this._curRequest; + return; + } else { + prom = SearchUtil.Search(query, true, this._maxSearchIndex, 10); + this._maxSearchIndex += 10; } - console.log("setting to undefined"); - })); + prom.then(action((res: SearchUtil.DocSearchResult) => { + // happens at the beginning + if (res.numFound !== this._numTotalResults && this._numTotalResults === -1) { + this._numTotalResults = res.numFound; + } + let filteredDocs = FilterBox.Instance.filterDocsByType(res.docs); + this._results.push(...filteredDocs); - this._curRequest = prom; + if (prom === this._curRequest) { + this._curRequest = undefined; + } + })); - await prom; + this._curRequest = prom; - //deals with if there are fewer results than can be scrolled through - // if (this._numTotalResults < this._endIndex) { - // break; - // } + await prom; + } } } collectionRef = React.createRef(); startDragCollection = async () => { - // const results = await this.getResults(FilterBox.Instance.getFinalQuery(this._searchString), -1); - await this.getResultsHelp(FilterBox.Instance.getFinalQuery(this._searchString)); + await this.getResults(FilterBox.Instance.getFinalQuery(this._searchString), true); + console.log(this._results) + // if (res !== undefined) { const docs = this._results.map(doc => { const isProto = Doc.GetT(doc, "isPrototype", "boolean", true); if (isProto) { @@ -244,6 +202,7 @@ export class SearchBox extends React.Component { } } return Docs.FreeformDocument(docs, { width: 400, height: 400, panX: 175, panY: 175, backgroundColor: "grey", title: `Search Docs: "${this._searchString}"` }); + // } } @action.bound @@ -257,7 +216,6 @@ export class SearchBox extends React.Component { @action.bound closeSearch = () => { - console.log("closing search") FilterBox.Instance.closeFilter(); this.closeResults(); } @@ -267,7 +225,6 @@ export class SearchBox extends React.Component { this._resultsOpen = false; this._results = []; this._visibleElements = []; - this._currentIndex = 0; this._numTotalResults = -1; this._startIndex = -1; this._endIndex = -1; @@ -275,21 +232,11 @@ export class SearchBox extends React.Component { } resultsScrolled = flow(function* (this: SearchBox, e?: React.UIEvent) { - console.log("_________________________________________________________________________________________________________") let scrollY = e ? e.currentTarget.scrollTop : 0; let buffer = 4; - console.log(`start before: ${this._startIndex}`); let startIndex = Math.floor(Math.max(0, scrollY / 70 - buffer)); - console.log(`end before: ${this._endIndex}`); let endIndex = Math.ceil(Math.min(this._numTotalResults - 1, startIndex + (560 / 70) + buffer)); - // if (startIndex === this._startIndex && endIndex === this._endIndex && this._results.length > this._endIndex) { - // console.log("returning") - // return; - // } - console.log(`START: ${startIndex}`); - console.log(`END: ${endIndex}`); - this._startIndex = startIndex === -1 ? 0 : startIndex; this._endIndex = endIndex === -1 ? 12 : endIndex; @@ -298,6 +245,10 @@ export class SearchBox extends React.Component { return; } + if (this._numTotalResults <= this._maxSearchIndex) { + this._numTotalResults = this._results.length; + } + // only hit right at the beginning // visibleElements is all of the elements (even the ones you can't see) else if (this._visibleElements.length !== this._numTotalResults) { @@ -320,27 +271,12 @@ export class SearchBox extends React.Component { if (this._isSearch[i] !== "search") { let result: Doc | undefined = undefined; if (i >= this._results.length) { - // _________________________________________________________________________________________________ - // let results: Doc[] = yield this.getResults(this._searchString, i + 1 - this._results.length); - - // this updates this._results - yield this.getResultsHelp(this._searchString); - result = this._results[i]; + this.getResults(this._searchString); + if (i < this._results.length) result = this._results[i]; if (result) { this._visibleElements[i] = ; this._isSearch[i] = "search"; } - // if (results.length !== 0) { - // runInAction(() => { - // // this._results.push(...results); - // result = this._results[i]; - // if (result) { - // this._visibleElements[i] = ; - // this._isSearch[i] = "search"; - // } - // }); - // } - // _________________________________________________________________________________________________ } else { result = this._results[i]; @@ -352,6 +288,10 @@ export class SearchBox extends React.Component { } } } + if (this._maxSearchIndex >= this._numTotalResults) { + this._visibleElements.length = this._results.length; + this._isSearch.length = this._results.length; + } }); render() { @@ -367,15 +307,8 @@ export class SearchBox extends React.Component {
- {/* {(this._results.length !== 0) ? ( - this._results.map(result => ) - ) : - this._openNoResults ? (
No Search Results
) : null} */} {this._visibleElements}
- {/*
- -
*/}
); } -- cgit v1.2.3-70-g09d2 From 7cd915c98db61e646ab34184613c1f6364cb620e Mon Sep 17 00:00:00 2001 From: monikahedman Date: Sun, 14 Jul 2019 12:56:11 -0400 Subject: submit button added --- deploy/index.html | 1 - src/client/views/search/SearchBox.scss | 3 +- src/client/views/search/SearchBox.tsx | 1 + src/client/views/search/SearchItem.scss | 56 +++++++++++++++++++-------------- 4 files changed, 35 insertions(+), 26 deletions(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/deploy/index.html b/deploy/index.html index f4a019b71..532b995f8 100644 --- a/deploy/index.html +++ b/deploy/index.html @@ -6,7 +6,6 @@ - diff --git a/src/client/views/search/SearchBox.scss b/src/client/views/search/SearchBox.scss index 2a27bbe62..08d3a65f1 100644 --- a/src/client/views/search/SearchBox.scss +++ b/src/client/views/search/SearchBox.scss @@ -41,11 +41,10 @@ } .searchBox-results { - margin-left: 27px; + margin-right: 142px; top: 300px; display: flex; flex-direction: column; - margin-right: 72px; height: 560px; overflow: hidden; overflow-y: auto; diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 7dcfbe1ef..cddc56a8a 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -176,6 +176,7 @@ export class SearchBox extends React.Component { +
diff --git a/src/client/views/search/SearchItem.scss b/src/client/views/search/SearchItem.scss index fa4c9cb38..04ebf2714 100644 --- a/src/client/views/search/SearchItem.scss +++ b/src/client/views/search/SearchItem.scss @@ -73,34 +73,38 @@ -o-transition: opacity 0.2s ease-in-out; transition: opacity 0.2s ease-in-out; } - } - .link-container.item:hover { - width: 70px; } - .link-container.item:hover .link-count { - opacity: 0; - } + // .link-container.item:hover { + // width: 70px; + // } + + // .link-container.item:hover .link-count { + // opacity: 0; + // } + + // .link-container.item:hover .link-extended { + // opacity: 1; + // } - .link-container.item:hover .link-extended { - opacity: 1; - } - .icon-icons { - width:50px + width: 50px } + .icon-live { - width:175px; + width: 175px; } - .icon-icons, .icon-live { - height:50px; - margin:auto; + .icon-icons, + .icon-live { + height: 50px; + margin: auto; overflow: hidden; + .search-type { display: inline-block; - width:100%; + width: 100%; position: absolute; justify-content: center; align-items: center; @@ -112,10 +116,11 @@ overflow: hidden; img { - width:100% !important; - height:auto !important; + width: 100% !important; + height: auto !important; } } + .search-type:hover+.search-label { opacity: 1; } @@ -134,16 +139,18 @@ } .icon-live:hover { - height:175px; + height: 175px; + .pdfBox-cont { img { - width:100% !important; + width: 100% !important; } } } } + .search-info:hover { - width:60%; + width: 60%; } } } @@ -176,12 +183,15 @@ } } + .search-overview:hover { z-index: 1; } + .collection { - display:flex; + display: flex; } + .collection-item { - width:35px; + width: 35px; } \ No newline at end of file -- cgit v1.2.3-70-g09d2 From b5740401b027c372edb5bbf465f91abfda663705 Mon Sep 17 00:00:00 2001 From: monikahedman Date: Sun, 14 Jul 2019 15:00:47 -0400 Subject: small ui changes done --- src/client/views/search/FilterBox.tsx | 2 +- src/client/views/search/SearchBox.tsx | 2 +- src/client/views/search/SearchItem.scss | 13 +++++++++---- src/client/views/search/SearchItem.tsx | 4 ++-- 4 files changed, 13 insertions(+), 8 deletions(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/views/search/FilterBox.tsx b/src/client/views/search/FilterBox.tsx index c6c18f9b4..58a873ced 100644 --- a/src/client/views/search/FilterBox.tsx +++ b/src/client/views/search/FilterBox.tsx @@ -260,7 +260,7 @@ export class FilterBox extends React.Component { @action.bound handleWordQueryChange = () => { this._basicWordStatus = !this._basicWordStatus; } - @action + @action.bound getBasicWordStatus() { return this._basicWordStatus; } @action.bound diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index cddc56a8a..121abf973 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -170,7 +170,7 @@ export class SearchBox extends React.Component { return (
- + {
{StrCast(this.props.doc.title)}
-
{this.DocumentIcon}
-
{this.props.doc.type}
+
{this.DocumentIcon}
+
{this.props.doc.type ? this.props.doc.type : "Other"}
{this.linkCount}
-- cgit v1.2.3-70-g09d2 From 2575564d70828820521074455383e940d521cca8 Mon Sep 17 00:00:00 2001 From: monikahedman Date: Sun, 14 Jul 2019 16:03:22 -0400 Subject: yeeeee --- src/client/views/search/SearchBox.scss | 3 +- src/client/views/search/SearchBox.tsx | 73 ++++++++++++++-------------------- 2 files changed, 32 insertions(+), 44 deletions(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/views/search/SearchBox.scss b/src/client/views/search/SearchBox.scss index 2a27bbe62..4c78b2682 100644 --- a/src/client/views/search/SearchBox.scss +++ b/src/client/views/search/SearchBox.scss @@ -46,7 +46,8 @@ display: flex; flex-direction: column; margin-right: 72px; - height: 560px; + height: auto; + max-height: 560px; overflow: hidden; overflow-y: auto; diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index e5280fe8c..47f951f42 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -26,11 +26,7 @@ export class SearchBox extends React.Component { @observable private _resultsOpen: boolean = false; @observable private _results: Doc[] = []; @observable private _openNoResults: boolean = false; - @observable public _pageNum: number = 0; - //temp - @observable public _maxNum: number = 10; @observable private _visibleElements: JSX.Element[] = []; - // @observable private _sc rollY: number = 0; private _isSearch: ("search" | "placeholder" | undefined)[] = []; private _numTotalResults = -1; @@ -117,59 +113,50 @@ export class SearchBox extends React.Component { this._openNoResults = true; this.resultsScrolled(); }); + } - console.log(this._results) + getAllResults = async (query: string) => { + return SearchUtil.Search(query, true, 0, 10000000); } - getResults = async (query: string, all: boolean = false) => { + getResults = async (query: string) => { - if (all) { - // let { numFound, docs } = await SearchUtil.Search(query, true, this._maxSearchIndex, 100000); - let prom: Promise = SearchUtil.Search(query, true, 0, 100000); + while (this._results.length <= this._endIndex && (this._numTotalResults === -1 || this._maxSearchIndex < this._numTotalResults)) { - prom.then(({ docs, numFound }) => { - this._results = docs; - }) - } - else { - while (this._results.length <= this._endIndex && (this._numTotalResults === -1 || this._maxSearchIndex < this._numTotalResults)) { - - let prom: Promise; - if (this._curRequest) { - prom = this._curRequest; - return; - } else { - prom = SearchUtil.Search(query, true, this._maxSearchIndex, 10); - this._maxSearchIndex += 10; - } - prom.then(action((res: SearchUtil.DocSearchResult) => { + let prom: Promise; + if (this._curRequest) { + prom = this._curRequest; + return; + } else { + prom = SearchUtil.Search(query, true, this._maxSearchIndex, 10); + this._maxSearchIndex += 10; + } + prom.then(action((res: SearchUtil.DocSearchResult) => { - // happens at the beginning - if (res.numFound !== this._numTotalResults && this._numTotalResults === -1) { - this._numTotalResults = res.numFound; - } + // happens at the beginning + if (res.numFound !== this._numTotalResults && this._numTotalResults === -1) { + this._numTotalResults = res.numFound; + } - let filteredDocs = FilterBox.Instance.filterDocsByType(res.docs); - this._results.push(...filteredDocs); + let filteredDocs = FilterBox.Instance.filterDocsByType(res.docs); + this._results.push(...filteredDocs); - if (prom === this._curRequest) { - this._curRequest = undefined; - } - })); + if (prom === this._curRequest) { + this._curRequest = undefined; + } + })); - this._curRequest = prom; + this._curRequest = prom; - await prom; - } + await prom; } } collectionRef = React.createRef(); startDragCollection = async () => { - await this.getResults(FilterBox.Instance.getFinalQuery(this._searchString), true); - console.log(this._results) - // if (res !== undefined) { - const docs = this._results.map(doc => { + let res = await this.getAllResults(FilterBox.Instance.getFinalQuery(this._searchString)); + // console.log(this._results) + const docs = res.docs.map(doc => { const isProto = Doc.GetT(doc, "isPrototype", "boolean", true); if (isProto) { return Doc.MakeDelegate(doc); @@ -202,7 +189,7 @@ export class SearchBox extends React.Component { } } return Docs.FreeformDocument(docs, { width: 400, height: 400, panX: 175, panY: 175, backgroundColor: "grey", title: `Search Docs: "${this._searchString}"` }); - // } + } @action.bound -- cgit v1.2.3-70-g09d2 From dcb7b3ec59b8458fc074656067b35e9068d5e3de Mon Sep 17 00:00:00 2001 From: monikahedman Date: Sun, 14 Jul 2019 17:08:15 -0400 Subject: fixed --- src/client/views/search/SearchBox.scss | 2 - src/client/views/search/SearchBox.tsx | 342 ++++++++++++++++++++++++++------- 2 files changed, 277 insertions(+), 67 deletions(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/views/search/SearchBox.scss b/src/client/views/search/SearchBox.scss index 4c78b2682..1ec89ed2b 100644 --- a/src/client/views/search/SearchBox.scss +++ b/src/client/views/search/SearchBox.scss @@ -46,9 +46,7 @@ display: flex; flex-direction: column; margin-right: 72px; - height: auto; max-height: 560px; - overflow: hidden; overflow-y: auto; .no-result { diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 5989e49bd..b9ada9677 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -1,26 +1,111 @@ import * as React from 'react'; -import { observer } from 'mobx-react'; -import { observable, action, runInAction, flow } from 'mobx'; + +import { + observer +} + + from 'mobx-react'; + +import { + observable, + action, + runInAction, + flow, + computed +} + + from 'mobx'; import "./SearchBox.scss"; import "./FilterBox.scss"; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { SetupDrag } from '../../util/DragManager'; -import { Docs } from '../../documents/Documents'; -import { NumCast } from '../../../new_fields/Types'; -import { Doc } from '../../../new_fields/Doc'; -import { SearchItem } from './SearchItem'; -import { DocServer } from '../../DocServer'; + +import { + FontAwesomeIcon +} + + from '@fortawesome/react-fontawesome'; + +import { + SetupDrag +} + + from '../../util/DragManager'; + +import { + Docs +} + + from '../../documents/Documents'; + +import { + NumCast +} + + from '../../../new_fields/Types'; + +import { + Doc +} + + from '../../../new_fields/Doc'; + +import { + SearchItem +} + + from './SearchItem'; + +import { + DocServer +} + + from '../../DocServer'; import * as rp from 'request-promise'; -import { Id } from '../../../new_fields/FieldSymbols'; -import { SearchUtil } from '../../util/SearchUtil'; -import { RouteStore } from '../../../server/RouteStore'; -import { FilterBox } from './FilterBox'; -import { start } from 'repl'; -import { getForkTsCheckerWebpackPluginHooks } from 'fork-ts-checker-webpack-plugin/lib/hooks'; -import { faThumbsDown } from '@fortawesome/free-regular-svg-icons'; -@observer -export class SearchBox extends React.Component { +import { + Id +} + + from '../../../new_fields/FieldSymbols'; + +import { + SearchUtil +} + + from '../../util/SearchUtil'; + +import { + RouteStore +} + + from '../../../server/RouteStore'; + +import { + FilterBox +} + + from './FilterBox'; + +import { + start +} + + from 'repl'; + +import { + getForkTsCheckerWebpackPluginHooks +} + + from 'fork-ts-checker-webpack-plugin/lib/hooks'; + +import { + faThumbsDown +} + + from '@fortawesome/free-regular-svg-icons'; +import * as $ from 'jquery'; + + +@observer export class SearchBox extends React.Component { @observable private _searchString: string = ""; @observable private _resultsOpen: boolean = false; @@ -45,18 +130,19 @@ export class SearchBox extends React.Component { this.resultsScrolled = this.resultsScrolled.bind(this); } - @action - getViews = async (doc: Doc) => { + @action getViews = async (doc: Doc) => { const results = await SearchUtil.GetViewsOfDocument(doc); let toReturn: Doc[] = []; + await runInAction(() => { toReturn = results; - }); + } + + ); return toReturn; } - @action.bound - onChange(e: React.ChangeEvent) { + @action.bound onChange(e: React.ChangeEvent) { this._searchString = e.target.value; this._openNoResults = false; @@ -69,27 +155,37 @@ export class SearchBox extends React.Component { this._maxSearchIndex = 0; } - enter = (e: React.KeyboardEvent) => { if (e.key === "Enter") { this.submitSearch(); } } + enter = (e: React.KeyboardEvent) => { + if (e.key === "Enter") { + this.submitSearch(); + } + } public static async convertDataUri(imageUri: string, returnedFilename: string) { try { let posting = DocServer.prepend(RouteStore.dataUriToImage); + const returnedUri = await rp.post(posting, { body: { uri: imageUri, name: returnedFilename - }, + } + + , json: true, - }); + } + + ); return returnedUri; - } catch (e) { + } + + catch (e) { console.log(e); } } - @action - submitSearch = async () => { + @action submitSearch = async () => { let query = this._searchString; query = FilterBox.Instance.getFinalQuery(query); this._results = []; @@ -100,6 +196,7 @@ export class SearchBox extends React.Component { if (query === "") { return; } + else { this._startIndex = 0; this._endIndex = 12; @@ -112,7 +209,9 @@ export class SearchBox extends React.Component { this._resultsOpen = true; this._openNoResults = true; this.resultsScrolled(); - }); + } + + ); } getAllResults = async (query: string) => { @@ -124,13 +223,17 @@ export class SearchBox extends React.Component { while (this._results.length <= this._endIndex && (this._numTotalResults === -1 || this._maxSearchIndex < this._numTotalResults)) { let prom: Promise; + if (this._curRequest) { prom = this._curRequest; return; - } else { + } + + else { prom = SearchUtil.Search(query, true, this._maxSearchIndex, 10); this._maxSearchIndex += 10; } + prom.then(action((res: SearchUtil.DocSearchResult) => { // happens at the beginning @@ -144,7 +247,9 @@ export class SearchBox extends React.Component { if (prom === this._curRequest) { this._curRequest = undefined; } - })); + } + + )); this._curRequest = prom; @@ -153,47 +258,67 @@ export class SearchBox extends React.Component { } collectionRef = React.createRef(); + startDragCollection = async () => { let res = await this.getAllResults(FilterBox.Instance.getFinalQuery(this._searchString)); + let filtered = FilterBox.Instance.filterDocsByType(res.docs); + // console.log(this._results) - const docs = res.docs.map(doc => { + const docs = filtered.map(doc => { const isProto = Doc.GetT(doc, "isPrototype", "boolean", true); + if (isProto) { return Doc.MakeDelegate(doc); - } else { + } + + else { return Doc.MakeAlias(doc); } - }); + } + + ); let x = 0; let y = 0; + for (const doc of docs) { doc.x = x; doc.y = y; const size = 200; const aspect = NumCast(doc.nativeHeight) / NumCast(doc.nativeWidth, 1); + if (aspect > 1) { doc.height = size; doc.width = size / aspect; - } else if (aspect > 0) { + } + + else if (aspect > 0) { doc.width = size; doc.height = size * aspect; - } else { + } + + else { doc.width = size; doc.height = size; } + doc.zoomBasis = 1; x += 250; + if (x > 1000) { x = 0; y += 300; } } - return Docs.Create.FreeformDocument(docs, { width: 400, height: 400, panX: 175, panY: 175, backgroundColor: "grey", title: `Search Docs: "${this._searchString}"` }); + + return Docs.Create.FreeformDocument(docs, { + width: 400, height: 400, panX: 175, panY: 175, backgroundColor: "grey", title: `Search Docs: "${this._searchString}"` + } + + ); } - @action.bound - openSearch(e: React.PointerEvent) { + @action.bound openSearch(e: React.PointerEvent) { e.stopPropagation(); this._openNoResults = false; FilterBox.Instance.closeFilter(); @@ -201,14 +326,12 @@ export class SearchBox extends React.Component { FilterBox.Instance._pointerTime = e.timeStamp; } - @action.bound - closeSearch = () => { + @action.bound closeSearch = () => { FilterBox.Instance.closeFilter(); this.closeResults(); } - @action.bound - closeResults() { + @action.bound closeResults() { this._resultsOpen = false; this._results = []; this._visibleElements = []; @@ -245,59 +368,148 @@ export class SearchBox extends React.Component { this._isSearch = Array(this._numTotalResults === -1 ? 0 : this._numTotalResults); } - for (let i = 0; i < this._numTotalResults; i++) { + for (let i = 0; + i < this._numTotalResults; + + i++) { + //if the index is out of the window then put a placeholder in //should ones that have already been found get set to placeholders? if (i < startIndex || i > endIndex) { if (this._isSearch[i] !== "placeholder") { this._isSearch[i] = "placeholder"; - this._visibleElements[i] =
; + + this._visibleElements[i] =
; } } + else { if (this._isSearch[i] !== "search") { let result: Doc | undefined = undefined; + if (i >= this._results.length) { this.getResults(this._searchString); if (i < this._results.length) result = this._results[i]; + if (result) { - this._visibleElements[i] = ; + this._visibleElements[i] = ; this._isSearch[i] = "search"; } } + else { result = this._results[i]; + if (result) { - this._visibleElements[i] = ; + this._visibleElements[i] = ; this._isSearch[i] = "search"; } } } } } + if (this._maxSearchIndex >= this._numTotalResults) { this._visibleElements.length = this._results.length; this._isSearch.length = this._results.length; } - }); + } + + ); + + @computed get resFull() { + console.log(`res full $ { + this._numTotalResults <=8 + } + + `) return this._numTotalResults <= 8; + } + + @computed get resultHeight() { + return this._numTotalResults * 70; + } render() { - return ( -
-
- - - - - -
-
- {this._visibleElements} -
-
- ); + return (
{ + this._visibleElements + } + +
); } } \ No newline at end of file -- cgit v1.2.3-70-g09d2 From f0e1eae76147d9c70309dcea54f6516622efca0f Mon Sep 17 00:00:00 2001 From: monikahedman Date: Sun, 14 Jul 2019 17:11:03 -0400 Subject: oops --- src/client/views/search/SearchBox.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index b9ada9677..8bf8e3bfa 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -442,11 +442,7 @@ import * as $ from 'jquery'; ); @computed get resFull() { - console.log(`res full $ { - this._numTotalResults <=8 - } - - `) return this._numTotalResults <= 8; + return this._numTotalResults <= 8; } @computed get resultHeight() { -- cgit v1.2.3-70-g09d2 From 44b91eacaab13eebaaa707f42670f01a736c5bba Mon Sep 17 00:00:00 2001 From: monikahedman Date: Sun, 14 Jul 2019 18:12:02 -0400 Subject: small changes --- src/client/views/search/SearchBox.tsx | 335 +++++++-------------------------- src/client/views/search/SearchItem.tsx | 2 +- src/server/Search.ts | 12 ++ 3 files changed, 85 insertions(+), 264 deletions(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 8bf8e3bfa..f5748d494 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -1,111 +1,28 @@ import * as React from 'react'; - -import { - observer -} - - from 'mobx-react'; - -import { - observable, - action, - runInAction, - flow, - computed -} - - from 'mobx'; +import { observer } from 'mobx-react'; +import { observable, action, runInAction, flow, computed } from 'mobx'; import "./SearchBox.scss"; import "./FilterBox.scss"; - -import { - FontAwesomeIcon -} - - from '@fortawesome/react-fontawesome'; - -import { - SetupDrag -} - - from '../../util/DragManager'; - -import { - Docs -} - - from '../../documents/Documents'; - -import { - NumCast -} - - from '../../../new_fields/Types'; - -import { - Doc -} - - from '../../../new_fields/Doc'; - -import { - SearchItem -} - - from './SearchItem'; - -import { - DocServer -} - - from '../../DocServer'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { SetupDrag } from '../../util/DragManager'; +import { Docs } from '../../documents/Documents'; +import { NumCast } from '../../../new_fields/Types'; +import { Doc } from '../../../new_fields/Doc'; +import { SearchItem } from './SearchItem'; +import { DocServer } from '../../DocServer'; import * as rp from 'request-promise'; - -import { - Id -} - - from '../../../new_fields/FieldSymbols'; - -import { - SearchUtil -} - - from '../../util/SearchUtil'; - -import { - RouteStore -} - - from '../../../server/RouteStore'; - -import { - FilterBox -} - - from './FilterBox'; - -import { - start -} - - from 'repl'; - -import { - getForkTsCheckerWebpackPluginHooks -} - - from 'fork-ts-checker-webpack-plugin/lib/hooks'; - -import { - faThumbsDown -} - - from '@fortawesome/free-regular-svg-icons'; +import { Id } from '../../../new_fields/FieldSymbols'; +import { SearchUtil } from '../../util/SearchUtil'; +import { RouteStore } from '../../../server/RouteStore'; +import { FilterBox } from './FilterBox'; +import { start } from 'repl'; +import { getForkTsCheckerWebpackPluginHooks } from 'fork-ts-checker-webpack-plugin/lib/hooks'; +import { faThumbsDown } from '@fortawesome/free-regular-svg-icons'; import * as $ from 'jquery'; -@observer export class SearchBox extends React.Component { +@observer +export class SearchBox extends React.Component { @observable private _searchString: string = ""; @observable private _resultsOpen: boolean = false; @@ -130,19 +47,18 @@ import * as $ from 'jquery'; this.resultsScrolled = this.resultsScrolled.bind(this); } - @action getViews = async (doc: Doc) => { + @action + getViews = async (doc: Doc) => { const results = await SearchUtil.GetViewsOfDocument(doc); let toReturn: Doc[] = []; - await runInAction(() => { toReturn = results; - } - - ); + }); return toReturn; } - @action.bound onChange(e: React.ChangeEvent) { + @action.bound + onChange(e: React.ChangeEvent) { this._searchString = e.target.value; this._openNoResults = false; @@ -155,37 +71,27 @@ import * as $ from 'jquery'; this._maxSearchIndex = 0; } - enter = (e: React.KeyboardEvent) => { - if (e.key === "Enter") { - this.submitSearch(); - } - } + enter = (e: React.KeyboardEvent) => { if (e.key === "Enter") { this.submitSearch(); } } public static async convertDataUri(imageUri: string, returnedFilename: string) { try { let posting = DocServer.prepend(RouteStore.dataUriToImage); - const returnedUri = await rp.post(posting, { body: { uri: imageUri, name: returnedFilename - } - - , + }, json: true, - } - - ); + }); return returnedUri; - } - - catch (e) { + } catch (e) { console.log(e); } } - @action submitSearch = async () => { + @action + submitSearch = async () => { let query = this._searchString; query = FilterBox.Instance.getFinalQuery(query); this._results = []; @@ -196,7 +102,6 @@ import * as $ from 'jquery'; if (query === "") { return; } - else { this._startIndex = 0; this._endIndex = 12; @@ -209,9 +114,7 @@ import * as $ from 'jquery'; this._resultsOpen = true; this._openNoResults = true; this.resultsScrolled(); - } - - ); + }); } getAllResults = async (query: string) => { @@ -223,17 +126,13 @@ import * as $ from 'jquery'; while (this._results.length <= this._endIndex && (this._numTotalResults === -1 || this._maxSearchIndex < this._numTotalResults)) { let prom: Promise; - if (this._curRequest) { prom = this._curRequest; return; - } - - else { + } else { prom = SearchUtil.Search(query, true, this._maxSearchIndex, 10); this._maxSearchIndex += 10; } - prom.then(action((res: SearchUtil.DocSearchResult) => { // happens at the beginning @@ -247,9 +146,7 @@ import * as $ from 'jquery'; if (prom === this._curRequest) { this._curRequest = undefined; } - } - - )); + })); this._curRequest = prom; @@ -258,67 +155,48 @@ import * as $ from 'jquery'; } collectionRef = React.createRef(); - startDragCollection = async () => { let res = await this.getAllResults(FilterBox.Instance.getFinalQuery(this._searchString)); let filtered = FilterBox.Instance.filterDocsByType(res.docs); - // console.log(this._results) const docs = filtered.map(doc => { const isProto = Doc.GetT(doc, "isPrototype", "boolean", true); - if (isProto) { return Doc.MakeDelegate(doc); - } - - else { + } else { return Doc.MakeAlias(doc); } - } - - ); + }); let x = 0; let y = 0; - for (const doc of docs) { doc.x = x; doc.y = y; const size = 200; const aspect = NumCast(doc.nativeHeight) / NumCast(doc.nativeWidth, 1); - if (aspect > 1) { doc.height = size; doc.width = size / aspect; - } - - else if (aspect > 0) { + } else if (aspect > 0) { doc.width = size; doc.height = size * aspect; - } - - else { + } else { doc.width = size; doc.height = size; } - doc.zoomBasis = 1; x += 250; - if (x > 1000) { x = 0; y += 300; } } - - return Docs.Create.FreeformDocument(docs, { - width: 400, height: 400, panX: 175, panY: 175, backgroundColor: "grey", title: `Search Docs: "${this._searchString}"` - } - - ); + return Docs.Create.FreeformDocument(docs, { width: 400, height: 400, panX: 175, panY: 175, backgroundColor: "grey", title: `Search Docs: "${this._searchString}"` }); } - @action.bound openSearch(e: React.PointerEvent) { + @action.bound + openSearch(e: React.PointerEvent) { e.stopPropagation(); this._openNoResults = false; FilterBox.Instance.closeFilter(); @@ -326,12 +204,14 @@ import * as $ from 'jquery'; FilterBox.Instance._pointerTime = e.timeStamp; } - @action.bound closeSearch = () => { + @action.bound + closeSearch = () => { FilterBox.Instance.closeFilter(); this.closeResults(); } - @action.bound closeResults() { + @action.bound + closeResults() { this._resultsOpen = false; this._results = []; this._visibleElements = []; @@ -368,144 +248,73 @@ import * as $ from 'jquery'; this._isSearch = Array(this._numTotalResults === -1 ? 0 : this._numTotalResults); } - for (let i = 0; - i < this._numTotalResults; - - i++) { - + for (let i = 0; i < this._numTotalResults; i++) { //if the index is out of the window then put a placeholder in //should ones that have already been found get set to placeholders? if (i < startIndex || i > endIndex) { if (this._isSearch[i] !== "placeholder") { this._isSearch[i] = "placeholder"; - - this._visibleElements[i] =
; + this._visibleElements[i] =
; } } - else { if (this._isSearch[i] !== "search") { let result: Doc | undefined = undefined; - if (i >= this._results.length) { this.getResults(this._searchString); if (i < this._results.length) result = this._results[i]; - if (result) { - this._visibleElements[i] = ; + this._visibleElements[i] = ; this._isSearch[i] = "search"; } } - else { result = this._results[i]; - if (result) { - this._visibleElements[i] = ; + this._visibleElements[i] = ; this._isSearch[i] = "search"; } } } } } - if (this._maxSearchIndex >= this._numTotalResults) { this._visibleElements.length = this._results.length; this._isSearch.length = this._results.length; } - } + }); - ); - - @computed get resFull() { + @computed + get resFull() { + console.log(this._numTotalResults) return this._numTotalResults <= 8; } - @computed get resultHeight() { + @computed + get resultHeight() { return this._numTotalResults * 70; } render() { - return (
{ - this._visibleElements - } - -
); + return ( +
+
+ + + + + +
+
+ {this._visibleElements} +
+
+ ); } } \ No newline at end of file diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx index cd7e31b20..134c13dc8 100644 --- a/src/client/views/search/SearchItem.tsx +++ b/src/client/views/search/SearchItem.tsx @@ -240,7 +240,7 @@ export class SearchItem extends React.Component {
-
+
{StrCast(this.props.doc.title)}
diff --git a/src/server/Search.ts b/src/server/Search.ts index ffba4ea8e..98f421937 100644 --- a/src/server/Search.ts +++ b/src/server/Search.ts @@ -18,6 +18,18 @@ export class Search { } } + public async updateDocuments(documents: any[]) { + try { + const res = await rp.post(this.url + "dash/update", { + headers: { 'content-type': 'application/json' }, + body: JSON.stringify(documents) + }); + return res; + } catch (e) { + // console.warn("Search error: " + e + document); + } + } + public async search(query: string, start: number = 0, rows: number = 10) { try { const searchResults = JSON.parse(await rp.get(this.url + "dash/select", { -- cgit v1.2.3-70-g09d2 From 29840e571c2f17d0bb346186dd91f1d895684a95 Mon Sep 17 00:00:00 2001 From: monikahedman Date: Sun, 14 Jul 2019 18:15:39 -0400 Subject: fixed no search results --- src/client/views/search/SearchBox.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index f5748d494..bfad9a845 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -230,7 +230,7 @@ export class SearchBox extends React.Component { this._startIndex = startIndex === -1 ? 0 : startIndex; this._endIndex = endIndex === -1 ? 12 : endIndex; - if (this._numTotalResults === 0 && this._openNoResults) { + if ((this._numTotalResults === 0 || this._results.length === 0) && this._openNoResults) { this._visibleElements = [
No Search Results
]; return; } -- cgit v1.2.3-70-g09d2 From 8c80710f241376043e8700ec79277fc039f3a00b Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Sun, 14 Jul 2019 22:19:33 -0400 Subject: Cleaned up imports --- src/client/views/search/SearchBox.tsx | 9 --------- 1 file changed, 9 deletions(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index bfad9a845..67aaa387c 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -15,10 +15,6 @@ import { Id } from '../../../new_fields/FieldSymbols'; import { SearchUtil } from '../../util/SearchUtil'; import { RouteStore } from '../../../server/RouteStore'; import { FilterBox } from './FilterBox'; -import { start } from 'repl'; -import { getForkTsCheckerWebpackPluginHooks } from 'fork-ts-checker-webpack-plugin/lib/hooks'; -import { faThumbsDown } from '@fortawesome/free-regular-svg-icons'; -import * as $ from 'jquery'; @observer @@ -32,7 +28,6 @@ export class SearchBox extends React.Component { private _isSearch: ("search" | "placeholder" | undefined)[] = []; private _numTotalResults = -1; - private _startIndex = -1; private _endIndex = -1; static Instance: SearchBox; @@ -65,7 +60,6 @@ export class SearchBox extends React.Component { this._results = []; this._visibleElements = []; this._numTotalResults = -1; - this._startIndex = -1; this._endIndex = -1; this._curRequest = undefined; this._maxSearchIndex = 0; @@ -103,7 +97,6 @@ export class SearchBox extends React.Component { return; } else { - this._startIndex = 0; this._endIndex = 12; this._maxSearchIndex = 0; this._numTotalResults = -1; @@ -216,7 +209,6 @@ export class SearchBox extends React.Component { this._results = []; this._visibleElements = []; this._numTotalResults = -1; - this._startIndex = -1; this._endIndex = -1; this._curRequest = undefined; } @@ -227,7 +219,6 @@ export class SearchBox extends React.Component { let startIndex = Math.floor(Math.max(0, scrollY / 70 - buffer)); let endIndex = Math.ceil(Math.min(this._numTotalResults - 1, startIndex + (560 / 70) + buffer)); - this._startIndex = startIndex === -1 ? 0 : startIndex; this._endIndex = endIndex === -1 ? 12 : endIndex; if ((this._numTotalResults === 0 || this._results.length === 0) && this._openNoResults) { -- cgit v1.2.3-70-g09d2 From 0f429c53fc3df62a60be1da398740524545357bc Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Sun, 14 Jul 2019 22:27:59 -0400 Subject: Compile errors --- src/client/views/pdf/PDFMenu.tsx | 4 +- src/client/views/pdf/Page.tsx | 2 +- src/client/views/search/Pager.scss | 47 --------------------- src/client/views/search/Pager.tsx | 78 ----------------------------------- src/client/views/search/SearchBox.tsx | 5 ++- 5 files changed, 6 insertions(+), 130 deletions(-) delete mode 100644 src/client/views/search/Pager.scss delete mode 100644 src/client/views/search/Pager.tsx (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/views/pdf/PDFMenu.tsx b/src/client/views/pdf/PDFMenu.tsx index e73b759df..27c2a8f1a 100644 --- a/src/client/views/pdf/PDFMenu.tsx +++ b/src/client/views/pdf/PDFMenu.tsx @@ -18,7 +18,7 @@ export default class PDFMenu extends React.Component { @observable private _transitionDelay: string = ""; - StartDrag: (e: PointerEvent, ele: HTMLDivElement) => void = emptyFunction; + StartDrag: (e: PointerEvent, ele: HTMLElement) => void = emptyFunction; Highlight: (d: Doc | undefined, color: string | undefined) => void = emptyFunction; Delete: () => void = emptyFunction; Snippet: (marquee: { left: number, top: number, width: number, height: number }) => void = emptyFunction; @@ -34,7 +34,7 @@ export default class PDFMenu extends React.Component { private _offsetY: number = 0; private _offsetX: number = 0; private _mainCont: React.RefObject = React.createRef(); - private _commentCont: React.RefObject = React.createRef(); + private _commentCont = React.createRef(); private _snippetButton: React.RefObject = React.createRef(); private _dragging: boolean = false; @observable private _keyValue: string = ""; diff --git a/src/client/views/pdf/Page.tsx b/src/client/views/pdf/Page.tsx index 1e22aca9e..b4a4b5806 100644 --- a/src/client/views/pdf/Page.tsx +++ b/src/client/views/pdf/Page.tsx @@ -152,7 +152,7 @@ export default class Page extends React.Component { * start a drag event and create or put the necessary info into the drag event. */ @action - startDrag = (e: PointerEvent, ele: HTMLDivElement): void => { + startDrag = (e: PointerEvent, ele: HTMLElement): void => { e.preventDefault(); e.stopPropagation(); let thisDoc = this.props.parent.Document; diff --git a/src/client/views/search/Pager.scss b/src/client/views/search/Pager.scss deleted file mode 100644 index 2b9c81b93..000000000 --- a/src/client/views/search/Pager.scss +++ /dev/null @@ -1,47 +0,0 @@ -@import "../globalCssVariables"; - -.search-pager { - background-color: $dark-color; - border-radius: 10px; - width: 500px; - display: flex; - justify-content: center; - // margin-left: 27px; - float: right; - margin-right: 74px; - margin-left: auto; - - // flex-direction: column; - - .search-arrows { - display: flex; - justify-content: center; - margin: 10px; - width: 50%; - - .arrow { - -webkit-transition: all 0.2s ease-in-out; - -moz-transition: all 0.2s ease-in-out; - -o-transition: all 0.2s ease-in-out; - transition: all 0.2s ease-in-out; - - .fontawesome-icon { - color: $light-color; - width: 20px; - height: 20px; - margin-right: 2px; - margin-left: 2px; - // opacity: .7; - } - } - - .pager-title { - text-align: center; - // font-size: 8px; - // margin-bottom: 10px; - color: $light-color; - // padding: 2px; - width: 40%; - } - } -} \ No newline at end of file diff --git a/src/client/views/search/Pager.tsx b/src/client/views/search/Pager.tsx deleted file mode 100644 index 1c62773b1..000000000 --- a/src/client/views/search/Pager.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import * as React from 'react'; -import { observer } from 'mobx-react'; -import { faArrowCircleRight, faArrowCircleLeft } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { library } from '@fortawesome/fontawesome-svg-core'; -import "./Pager.scss"; -import { SearchBox } from './SearchBox'; -import { observable, action } from 'mobx'; -import { FilterBox } from './FilterBox'; - -library.add(faArrowCircleRight); -library.add(faArrowCircleLeft); - -@observer -export class Pager extends React.Component { - - @observable _leftHover: boolean = false; - @observable _rightHover: boolean = false; - - @action - onLeftClick(e: React.PointerEvent) { - FilterBox.Instance._pointerTime = e.timeStamp; - if (SearchBox.Instance._pageNum > 0) { - SearchBox.Instance._pageNum -= 1; - } - } - - @action - onRightClick(e: React.PointerEvent) { - FilterBox.Instance._pointerTime = e.timeStamp; - if (SearchBox.Instance._pageNum + 1 < SearchBox.Instance._maxNum) { - SearchBox.Instance._pageNum += 1; - } - } - - @action.bound - mouseInLeft() { - this._leftHover = true; - } - - @action.bound - mouseOutLeft() { - this._leftHover = false; - } - - @action.bound - mouseInRight() { - this._rightHover = true; - } - - @action.bound - mouseOutRight() { - this._rightHover = false; - } - - render() { - return ( -
-
-
- -
-
- page {SearchBox.Instance._pageNum + 1} of {SearchBox.Instance._maxNum} -
-
- -
-
-
- ); - } - -} \ No newline at end of file diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index c02db528a..e0c5d163e 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -213,7 +213,8 @@ export class SearchBox extends React.Component { this._curRequest = undefined; } - resultsScrolled = flow(function* (this: SearchBox, e?: React.UIEvent) { + @action + resultsScrolled = (e?: React.UIEvent) => { let scrollY = e ? e.currentTarget.scrollTop : 0; let buffer = 4; let startIndex = Math.floor(Math.max(0, scrollY / 70 - buffer)); @@ -273,7 +274,7 @@ export class SearchBox extends React.Component { this._visibleElements.length = this._results.length; this._isSearch.length = this._results.length; } - }); + } @computed get resFull() { -- cgit v1.2.3-70-g09d2 From 756b6590723c307440d7c69f9ad91073ad0f7a24 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Sun, 14 Jul 2019 23:33:35 -0400 Subject: Some search fixes and tweaks --- src/client/util/SerializationHelper.ts | 7 +- src/client/views/search/SearchBox.tsx | 55 +++--- src/client/views/search/SearchItem.scss | 303 ++++++++++++++++---------------- 3 files changed, 187 insertions(+), 178 deletions(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/util/SerializationHelper.ts b/src/client/util/SerializationHelper.ts index 17ae407c4..429fb22d9 100644 --- a/src/client/util/SerializationHelper.ts +++ b/src/client/util/SerializationHelper.ts @@ -1,5 +1,6 @@ import { PropSchema, serialize, deserialize, custom, setDefaultModelSchema, getDefaultModelSchema, primitive, SKIP } from "serializr"; import { Field } from "../../new_fields/Doc"; +import { ClientUtils } from "./ClientUtils"; export namespace SerializationHelper { let serializing: number = 0; @@ -38,7 +39,11 @@ export namespace SerializationHelper { serializing += 1; if (!obj.__type) { - throw Error("No property 'type' found in JSON."); + if (ClientUtils.RELEASE) { + return undefined; + } else { + throw Error("No property 'type' found in JSON."); + } } if (!(obj.__type in serializationTypes)) { diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index e0c5d163e..dc1d35b1c 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -26,6 +26,8 @@ export class SearchBox extends React.Component { @observable private _openNoResults: boolean = false; @observable private _visibleElements: JSX.Element[] = []; + private resultsRef = React.createRef(); + private _isSearch: ("search" | "placeholder" | undefined)[] = []; private _numTotalResults = -1; private _endIndex = -1; @@ -114,37 +116,34 @@ export class SearchBox extends React.Component { return SearchUtil.Search(query, true, 0, 10000000); } - getResults = async (query: string) => { - - while (this._results.length <= this._endIndex && (this._numTotalResults === -1 || this._maxSearchIndex < this._numTotalResults)) { - let prom: Promise; - if (this._curRequest) { - prom = this._curRequest; - return; - } else { - prom = SearchUtil.Search(query, true, this._maxSearchIndex, 10); - this._maxSearchIndex += 10; - } - prom.then(action((res: SearchUtil.DocSearchResult) => { + private lockPromise?: Promise; + getResults = async (query: string) => { + if (this.lockPromise) { + await this.lockPromise; + } + this.lockPromise = new Promise(async res => { + while (this._results.length <= this._endIndex && (this._numTotalResults === -1 || this._maxSearchIndex < this._numTotalResults)) { + this._curRequest = SearchUtil.Search(query, true, this._maxSearchIndex, 10).then(action((res: SearchUtil.DocSearchResult) => { - // happens at the beginning - if (res.numFound !== this._numTotalResults && this._numTotalResults === -1) { - this._numTotalResults = res.numFound; - } + // happens at the beginning + if (res.numFound !== this._numTotalResults && this._numTotalResults === -1) { + this._numTotalResults = res.numFound; + } - let filteredDocs = FilterBox.Instance.filterDocsByType(res.docs); - this._results.push(...filteredDocs); + let filteredDocs = FilterBox.Instance.filterDocsByType(res.docs); + this._results.push(...filteredDocs); - if (prom === this._curRequest) { this._curRequest = undefined; - } - })); - - this._curRequest = prom; + })); + this._maxSearchIndex += 10; - await prom; - } + await this._curRequest; + } + this.resultsScrolled(); + res(); + }); + return this.lockPromise; } collectionRef = React.createRef(); @@ -215,7 +214,7 @@ export class SearchBox extends React.Component { @action resultsScrolled = (e?: React.UIEvent) => { - let scrollY = e ? e.currentTarget.scrollTop : 0; + let scrollY = e ? e.currentTarget.scrollTop : this.resultsRef.current ? this.resultsRef.current.scrollTop : 0; let buffer = 4; let startIndex = Math.floor(Math.max(0, scrollY / 70 - buffer)); let endIndex = Math.ceil(Math.min(this._numTotalResults - 1, startIndex + (560 / 70) + buffer)); @@ -246,7 +245,7 @@ export class SearchBox extends React.Component { if (i < startIndex || i > endIndex) { if (this._isSearch[i] !== "placeholder") { this._isSearch[i] = "placeholder"; - this._visibleElements[i] =
; + this._visibleElements[i] =
Loading...
; } } else { @@ -303,7 +302,7 @@ export class SearchBox extends React.Component {
+ }} ref={this.resultsRef}> {this._visibleElements}
diff --git a/src/client/views/search/SearchItem.scss b/src/client/views/search/SearchItem.scss index 0fb93daad..24dd2eaa3 100644 --- a/src/client/views/search/SearchItem.scss +++ b/src/client/views/search/SearchItem.scss @@ -6,195 +6,200 @@ justify-content: flex-end; height: 70px; z-index: 0; +} - .search-item { - width: 500px; - background: $light-color-secondary; - border-color: $intermediate-color; - border-bottom-style: solid; - padding: 10px; - height: 70px; - z-index: 0; - display: inline-block; - - .main-search-info { - display: flex; - flex-direction: row; - width: 100%; +.searchBox-placeholder, +.search-overview .search-item { + width: 500px; + background: $light-color-secondary; + border-color: $intermediate-color; + border-bottom-style: solid; + padding: 10px; + height: 70px; + z-index: 0; + display: inline-block; - .search-title { - text-transform: uppercase; - text-align: left; - width: 100%; - font-weight: bold; - } + .main-search-info { + display: flex; + flex-direction: row; + width: 100%; - .search-info { + .search-title { + text-transform: uppercase; + text-align: left; + width: 100%; + font-weight: bold; + } + + .search-info { + display: flex; + justify-content: flex-end; + + .link-container.item { + margin-left: auto; + margin-right: auto; + height: 26px; + width: 26px; + border-radius: 13px; + background: $dark-color; + color: $light-color-secondary; display: flex; - justify-content: flex-end; - - .link-container.item { - margin-left: auto; - margin-right: auto; - height: 26px; - width: 26px; - border-radius: 13px; - background: $dark-color; - color: $light-color-secondary; - display: flex; - justify-content: center; - align-items: center; - -webkit-transition: all 0.2s ease-in-out; - -moz-transition: all 0.2s ease-in-out; - -o-transition: all 0.2s ease-in-out; - transition: all 0.2s ease-in-out; - transform-origin: top right; - overflow: hidden; + justify-content: center; + align-items: center; + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; + transform-origin: top right; + overflow: hidden; + position: relative; + + .link-count { + opacity: 1; + position: absolute; + z-index: 1000; + text-align: center; + -webkit-transition: opacity 0.2s ease-in-out; + -moz-transition: opacity 0.2s ease-in-out; + -o-transition: opacity 0.2s ease-in-out; + transition: opacity 0.2s ease-in-out; + } + + .link-extended { + // display: none; + visibility: hidden; + opacity: 0; position: relative; + z-index: 500; + overflow: hidden; + -webkit-transition: opacity 0.2s ease-in-out .2s, visibility 0s linear 0s; + -moz-transition: opacity 0.2s ease-in-out .2s, visibility 0s linear 0s; + -o-transition: opacity 0.2s ease-in-out .2s, visibility 0s linear 0s; + transition: opacity 0.2s ease-in-out .2s, visibility 0s linear 0s; + // transition-delay: 1s; + } - .link-count { - opacity: 1; - position: absolute; - z-index: 1000; - text-align: center; - -webkit-transition: opacity 0.2s ease-in-out; - -moz-transition: opacity 0.2s ease-in-out; - -o-transition: opacity 0.2s ease-in-out; - transition: opacity 0.2s ease-in-out; - } + } - .link-extended { - // display: none; - visibility: hidden; - opacity: 0; - position: relative; - z-index: 500; - overflow: hidden; - -webkit-transition: opacity 0.2s ease-in-out .2s, visibility 0s linear 0s; - -moz-transition: opacity 0.2s ease-in-out .2s, visibility 0s linear 0s; - -o-transition: opacity 0.2s ease-in-out .2s, visibility 0s linear 0s; - transition: opacity 0.2s ease-in-out .2s, visibility 0s linear 0s; - // transition-delay: 1s; - } + .link-container.item:hover { + width: 70px; + } - } + .link-container.item:hover .link-count { + opacity: 0; + } - .link-container.item:hover { - width: 70px; - } + .link-container.item:hover .link-extended { + opacity: 1; + visibility: visible; + // display: inline; + } - .link-container.item:hover .link-count { - opacity: 0; - } + .icon-icons { + width: 50px + } - .link-container.item:hover .link-extended { - opacity: 1; - visibility: visible; - // display: inline; - } + .icon-live { + width: 175px; + } - .icon-icons { - width: 50px - } + .icon-icons, + .icon-live { + height: 50px; + margin: auto; + overflow: hidden; - .icon-live { - width: 175px; + .search-type { + display: inline-block; + width: 100%; + position: absolute; + justify-content: center; + align-items: center; + position: relative; + margin-right: 5px; } - .icon-icons, - .icon-live { - height: 50px; - margin: auto; + .pdfBox-cont { overflow: hidden; - .search-type { - display: inline-block; - width: 100%; - position: absolute; - justify-content: center; - align-items: center; - position: relative; - margin-right: 5px; - } - - .pdfBox-cont { - overflow: hidden; - - img { - width: 100% !important; - height: auto !important; - } + img { + width: 100% !important; + height: auto !important; } + } - .search-type:hover+.search-label { - opacity: 1; - } + .search-type:hover+.search-label { + opacity: 1; + } - .search-label { - font-size: 10; - position: relative; - right: 0px; - text-transform: capitalize; - opacity: 0; - -webkit-transition: opacity 0.2s ease-in-out; - -moz-transition: opacity 0.2s ease-in-out; - -o-transition: opacity 0.2s ease-in-out; - transition: opacity 0.2s ease-in-out; - } + .search-label { + font-size: 10; + position: relative; + right: 0px; + text-transform: capitalize; + opacity: 0; + -webkit-transition: opacity 0.2s ease-in-out; + -moz-transition: opacity 0.2s ease-in-out; + -o-transition: opacity 0.2s ease-in-out; + transition: opacity 0.2s ease-in-out; } + } - .icon-live:hover { - height: 175px; + .icon-live:hover { + height: 175px; - .pdfBox-cont { - img { - width: 100% !important; - } + .pdfBox-cont { + img { + width: 100% !important; } } } - - .search-info:hover { - width: 60%; - } } - } - .search-item:hover~.searchBox-instances, - .searchBox-instances:hover, - .searchBox-instances:active { - opacity: 1; - background: $lighter-alt-accent; - -webkit-transform: scale(1); - -ms-transform: scale(1); - transform: scale(1); + .search-info:hover { + width: 60%; + } } +} - .search-item:hover { - transition: all 0.2s; - background: $lighter-alt-accent; - } +.search-item:hover~.searchBox-instances, +.searchBox-instances:hover, +.searchBox-instances:active { + opacity: 1; + background: $lighter-alt-accent; + -webkit-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); +} - .searchBox-instances { - float: left; - opacity: 1; - width: 150px; - transition: all 0.2s ease; - color: black; - transform-origin: top right; - -webkit-transform: scale(0); - -ms-transform: scale(0); - transform: scale(0); - } +.search-item:hover { + transition: all 0.2s; + background: $lighter-alt-accent; +} +.searchBox-instances { + float: left; + opacity: 1; + width: 150px; + transition: all 0.2s ease; + color: black; + transform-origin: top right; + -webkit-transform: scale(0); + -ms-transform: scale(0); + transform: scale(0); } + .search-overview:hover { z-index: 1; } .searchBox-placeholder { min-height: 70px; + margin-left: 150px; + text-transform: uppercase; + text-align: left; + font-weight: bold; } .collection { -- cgit v1.2.3-70-g09d2 From b72dfe96af4f87fa00e9d64ffded62d0a5ec0ea9 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Mon, 15 Jul 2019 17:20:40 -0400 Subject: Added filter query to search to better support type filtering --- src/client/util/SearchUtil.ts | 22 +++++++++++----------- .../views/collections/ParentDocumentSelector.tsx | 4 ++-- src/client/views/globalCssVariables.scss | 13 ++++++++----- src/client/views/search/FilterBox.tsx | 4 ++++ src/client/views/search/SearchBox.tsx | 11 ++++++++--- src/client/views/search/SearchItem.tsx | 4 ++-- src/server/Search.ts | 3 ++- src/server/index.ts | 4 ++-- 8 files changed, 39 insertions(+), 26 deletions(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts index 674eeb1a8..a3858da9f 100644 --- a/src/client/util/SearchUtil.ts +++ b/src/client/util/SearchUtil.ts @@ -14,11 +14,11 @@ export namespace SearchUtil { numFound: number; } - export function Search(query: string, returnDocs: true, start?: number, count?: number): Promise; - export function Search(query: string, returnDocs: false, start?: number, count?: number): Promise; - export async function Search(query: string, returnDocs: boolean, start?: number, rows?: number) { + export function Search(query: string, filterQuery: string | undefined, returnDocs: true, start?: number, count?: number): Promise; + export function Search(query: string, filterQuery: string | undefined, returnDocs: false, start?: number, count?: number): Promise; + export async function Search(query: string, filterQuery: string | undefined, returnDocs: boolean, start?: number, rows?: number) { const result: IdSearchResult = JSON.parse(await rp.get(DocServer.prepend("/search"), { - qs: { query, start, rows } + qs: { query, filterQuery, start, rows }, })); if (!returnDocs) { return result; @@ -35,31 +35,31 @@ export namespace SearchUtil { const proto = Doc.GetProto(doc); const protoId = proto[Id]; if (returnDocs) { - return (await Search(`proto_i:"${protoId}"`, returnDocs)).docs; + return (await Search("", `proto_i:"${protoId}"`, returnDocs)).docs; } else { - return (await Search(`proto_i:"${protoId}"`, returnDocs)).ids; + return (await Search("", `proto_i:"${protoId}"`, returnDocs)).ids; } // return Search(`{!join from=id to=proto_i}id:${protoId}`, true); } export async function GetViewsOfDocument(doc: Doc): Promise { - const results = await Search(`proto_i:"${doc[Id]}"`, true); + const results = await Search("", `proto_i:"${doc[Id]}"`, true); return results.docs; } export async function GetContextsOfDocument(doc: Doc): Promise<{ contexts: Doc[], aliasContexts: Doc[] }> { - const docContexts = (await Search(`data_l:"${doc[Id]}"`, true)).docs; + const docContexts = (await Search("", `data_l:"${doc[Id]}"`, true)).docs; const aliases = await GetAliasesOfDocument(doc, false); - const aliasContexts = (await Promise.all(aliases.map(doc => Search(`data_l:"${doc}"`, true)))); + const aliasContexts = (await Promise.all(aliases.map(doc => Search("", `data_l:"${doc}"`, true)))); const contexts = { contexts: docContexts, aliasContexts: [] as Doc[] }; aliasContexts.forEach(result => contexts.aliasContexts.push(...result.docs)); return contexts; } export async function GetContextIdsOfDocument(doc: Doc): Promise<{ contexts: string[], aliasContexts: string[] }> { - const docContexts = (await Search(`data_l:"${doc[Id]}"`, false)).ids; + const docContexts = (await Search("", `data_l:"${doc[Id]}"`, false)).ids; const aliases = await GetAliasesOfDocument(doc, false); - const aliasContexts = (await Promise.all(aliases.map(doc => Search(`data_l:"${doc}"`, false)))); + const aliasContexts = (await Promise.all(aliases.map(doc => Search("", `data_l:"${doc}"`, false)))); const contexts = { contexts: docContexts, aliasContexts: [] as string[] }; aliasContexts.forEach(result => contexts.aliasContexts.push(...result.ids)); return contexts; diff --git a/src/client/views/collections/ParentDocumentSelector.tsx b/src/client/views/collections/ParentDocumentSelector.tsx index c0f489cd8..a97aa4f36 100644 --- a/src/client/views/collections/ParentDocumentSelector.tsx +++ b/src/client/views/collections/ParentDocumentSelector.tsx @@ -23,9 +23,9 @@ export class SelectorContextMenu extends React.Component { async fetchDocuments() { let aliases = (await SearchUtil.GetAliasesOfDocument(this.props.Document)).filter(doc => doc !== this.props.Document); - const { docs } = await SearchUtil.Search(`data_l:"${this.props.Document[Id]}"`, true); + const { docs } = await SearchUtil.Search("", `data_l:"${this.props.Document[Id]}"`, true); const map: Map = new Map; - const allDocs = await Promise.all(aliases.map(doc => SearchUtil.Search(`data_l:"${doc[Id]}"`, true).then(result => result.docs))); + const allDocs = await Promise.all(aliases.map(doc => SearchUtil.Search("", `data_l:"${doc[Id]}"`, true).then(result => result.docs))); allDocs.forEach((docs, index) => docs.forEach(doc => map.set(doc, aliases[index]))); docs.forEach(doc => map.delete(doc)); runInAction(() => { diff --git a/src/client/views/globalCssVariables.scss b/src/client/views/globalCssVariables.scss index fec105516..6dffee586 100644 --- a/src/client/views/globalCssVariables.scss +++ b/src/client/views/globalCssVariables.scss @@ -13,23 +13,26 @@ $darker-alt-accent: rgb(178, 206, 248); $intermediate-color: #9c9396; $dark-color: #121721; // fonts -$sans-serif: "Noto Sans", sans-serif; +$sans-serif: "Noto Sans", +sans-serif; // $sans-serif: "Roboto Slab", sans-serif; -$serif: "Crimson Text", serif; +$serif: "Crimson Text", +serif; // misc values $border-radius: 0.3em; // $search-thumnail-size: 175; - // dragged items -$contextMenu-zindex: 1000; // context menu shows up over everything +// dragged items +$contextMenu-zindex: 100000; // context menu shows up over everything $mainTextInput-zindex: 999; // then text input overlay so that it's context menu will appear over decorations, etc $docDecorations-zindex: 998; // then doc decorations appear over everything else $remoteCursors-zindex: 997; // ... not sure what level the remote cursors should go -- is this right? $COLLECTION_BORDER_WIDTH: 1; $MINIMIZED_ICON_SIZE:25; $MAX_ROW_HEIGHT: 44px; -:export { + +:export { contextMenuZindex: $contextMenu-zindex; COLLECTION_BORDER_WIDTH: $COLLECTION_BORDER_WIDTH; MINIMIZED_ICON_SIZE: $MINIMIZED_ICON_SIZE; diff --git a/src/client/views/search/FilterBox.tsx b/src/client/views/search/FilterBox.tsx index 435ca86e3..f11fb008c 100644 --- a/src/client/views/search/FilterBox.tsx +++ b/src/client/views/search/FilterBox.tsx @@ -237,6 +237,10 @@ export class FilterBox extends React.Component { return "+(" + finalColString + ")" + query; } + get filterTypes() { + return this._icons.length === 9 ? undefined : this._icons; + } + @action filterDocsByType(docs: Doc[]) { if (this._icons.length === 9) { diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index dc1d35b1c..1b4427e66 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -67,7 +67,7 @@ export class SearchBox extends React.Component { this._maxSearchIndex = 0; } - enter = (e: React.KeyboardEvent) => { if (e.key === "Enter") { this.submitSearch(); } } + enter = (e: React.KeyboardEvent) => { if (e.key === "Enter") { this.submitSearch(); } }; public static async convertDataUri(imageUri: string, returnedFilename: string) { try { @@ -113,7 +113,12 @@ export class SearchBox extends React.Component { } getAllResults = async (query: string) => { - return SearchUtil.Search(query, true, 0, 10000000); + return SearchUtil.Search(query, this.filterQuery, true, 0, 10000000); + } + + private get filterQuery() { + const types = FilterBox.Instance.filterTypes; + return types && types.map(type => `{!join from=id to=proto_i}type_t:"${type}"`).join(" "); } @@ -124,7 +129,7 @@ export class SearchBox extends React.Component { } this.lockPromise = new Promise(async res => { while (this._results.length <= this._endIndex && (this._numTotalResults === -1 || this._maxSearchIndex < this._numTotalResults)) { - this._curRequest = SearchUtil.Search(query, true, this._maxSearchIndex, 10).then(action((res: SearchUtil.DocSearchResult) => { + this._curRequest = SearchUtil.Search(query, this.filterQuery, true, this._maxSearchIndex, 10).then(action((res: SearchUtil.DocSearchResult) => { // happens at the beginning if (res.numFound !== this._numTotalResults && this._numTotalResults === -1) { diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx index 16ad71d16..e34d101a8 100644 --- a/src/client/views/search/SearchItem.tsx +++ b/src/client/views/search/SearchItem.tsx @@ -51,9 +51,9 @@ export class SelectorContextMenu extends React.Component { async fetchDocuments() { let aliases = (await SearchUtil.GetViewsOfDocument(this.props.doc)).filter(doc => doc !== this.props.doc); - const { docs } = await SearchUtil.Search(`data_l:"${this.props.doc[Id]}"`, true); + const { docs } = await SearchUtil.Search("", `data_l:"${this.props.doc[Id]}"`, true); const map: Map = new Map; - const allDocs = await Promise.all(aliases.map(doc => SearchUtil.Search(`data_l:"${doc[Id]}"`, true).then(result => result.docs))); + const allDocs = await Promise.all(aliases.map(doc => SearchUtil.Search("", `data_l:"${doc[Id]}"`, true).then(result => result.docs))); allDocs.forEach((docs, index) => docs.forEach(doc => map.set(doc, aliases[index]))); docs.forEach(doc => map.delete(doc)); runInAction(() => { diff --git a/src/server/Search.ts b/src/server/Search.ts index 98f421937..fd9cec331 100644 --- a/src/server/Search.ts +++ b/src/server/Search.ts @@ -30,11 +30,12 @@ export class Search { } } - public async search(query: string, start: number = 0, rows: number = 10) { + public async search(query: string, filterQuery: string = "", start: number = 0, rows: number = 10) { try { const searchResults = JSON.parse(await rp.get(this.url + "dash/select", { qs: { q: query, + fq: filterQuery, fl: "id", start, rows, diff --git a/src/server/index.ts b/src/server/index.ts index 58af074aa..1c0dec05b 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -144,12 +144,12 @@ app.get("/pull", (req, res) => // GETTERS app.get("/search", async (req, res) => { - const { query, start, rows } = req.query; + const { query, filterQuery, start, rows } = req.query; if (query === undefined) { res.send([]); return; } - let results = await Search.Instance.search(query, start, rows); + let results = await Search.Instance.search(query, filterQuery, start, rows); res.send(results); }); -- cgit v1.2.3-70-g09d2 From ce8684aae01fb8329b9523737839ee814afeb4a4 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Mon, 15 Jul 2019 17:38:52 -0400 Subject: Search tweak --- src/client/views/search/SearchBox.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 1b4427e66..1f461a4a7 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -118,7 +118,7 @@ export class SearchBox extends React.Component { private get filterQuery() { const types = FilterBox.Instance.filterTypes; - return types && types.map(type => `{!join from=id to=proto_i}type_t:"${type}"`).join(" "); + return types && types.map(type => `({!join from=id to=proto_i}type_t:"${type} AND NOT type_t:*) OR type_t:"${type}"`).join(" "); } -- cgit v1.2.3-70-g09d2 From 9ab19fd503764f40d27769c90b4936ddd39eb750 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Mon, 15 Jul 2019 17:41:15 -0400 Subject: from last --- src/client/views/search/SearchBox.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 1f461a4a7..7bfe0bb13 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -118,7 +118,7 @@ export class SearchBox extends React.Component { private get filterQuery() { const types = FilterBox.Instance.filterTypes; - return types && types.map(type => `({!join from=id to=proto_i}type_t:"${type} AND NOT type_t:*) OR type_t:"${type}"`).join(" "); + return types && types.map(type => `({!join from=id to=proto_i}type_t:"${type}" AND NOT type_t:*) OR type_t:"${type}"`).join(" "); } -- cgit v1.2.3-70-g09d2 From 4c127ddd32b20bc6f1e6fb6b921e06cf3de4f1ca Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Mon, 15 Jul 2019 18:57:02 -0400 Subject: added proto filter to search --- src/client/views/search/SearchBox.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 7bfe0bb13..3830a6d16 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -118,7 +118,7 @@ export class SearchBox extends React.Component { private get filterQuery() { const types = FilterBox.Instance.filterTypes; - return types && types.map(type => `({!join from=id to=proto_i}type_t:"${type}" AND NOT type_t:*) OR type_t:"${type}"`).join(" "); + return "proto_i:*" + (types ? ` AND (${types.map(type => `({!join from=id to=proto_i}type_t:"${type}" AND NOT type_t:*) OR type_t:"${type}"`).join(" ")})` : ""); } -- cgit v1.2.3-70-g09d2 From 533c48010ca668a944962bd61cd65115fc5a6fa6 Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Tue, 16 Jul 2019 12:04:21 -0400 Subject: linter and error fixes --- src/client/documents/Documents.ts | 2 +- src/client/views/InkingControl.tsx | 4 ++-- src/client/views/Main.tsx | 2 +- src/client/views/collections/CollectionDockingView.tsx | 4 ++-- src/client/views/collections/CollectionTreeView.tsx | 2 +- src/client/views/nodes/ImageBox.tsx | 2 +- src/client/views/nodes/VideoBox.tsx | 4 ++-- src/client/views/nodes/WebBox.tsx | 2 +- src/client/views/search/SearchBox.tsx | 2 +- 9 files changed, 12 insertions(+), 12 deletions(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index ada9f3610..177810444 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -98,7 +98,7 @@ export namespace Docs { type LayoutSource = { LayoutString: () => string }; type CollectionLayoutSource = { LayoutString: (fieldStr: string, fieldExt?: string) => string }; - type CollectionViewType = [CollectionLayoutSource, string, string?] + type CollectionViewType = [CollectionLayoutSource, string, string?]; type PrototypeTemplate = { layout: { view: LayoutSource, diff --git a/src/client/views/InkingControl.tsx b/src/client/views/InkingControl.tsx index c7f7bdb66..1910e409b 100644 --- a/src/client/views/InkingControl.tsx +++ b/src/client/views/InkingControl.tsx @@ -1,5 +1,5 @@ import { observable, action, computed, runInAction } from "mobx"; -import { ColorResult } from 'react-color'; +import { ColorState } from 'react-color'; import React = require("react"); import { observer } from "mobx-react"; import "./InkingControl.scss"; @@ -41,7 +41,7 @@ export class InkingControl extends React.Component { } @undoBatch - switchColor = action((color: ColorResult): void => { + switchColor = action((color: ColorState): void => { this._selectedColor = color.hex + (color.rgb.a !== undefined ? this.decimalToHexString(Math.round(color.rgb.a * 255)) : "ff"); if (InkingControl.Instance.selectedTool === InkTool.None) { if (MainOverlayTextBox.Instance.SetColor(color.hex)) return; diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 80399e24b..86578af3e 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -26,7 +26,7 @@ let swapDocs = async () => { } CurrentUserUtils.UserDocument.linkManagerDoc = undefined; } -} +}; (async () => { const info = await CurrentUserUtils.loadCurrentUser(); diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 1069ebbdb..a193ff677 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -301,7 +301,7 @@ export class CollectionDockingView extends React.Component { CollectionDockingView.Instance._ignoreStateChange = JSON.stringify(CollectionDockingView.Instance._goldenLayout.toConfig()); - this.stateChanged() + this.stateChanged(); }, 10); } } @@ -606,7 +606,7 @@ export class DockedFrameRenderer extends React.Component { addDocTab={this.addDocTab} ContainingCollectionView={undefined} zoomToScale={emptyFunction} - getScale={returnOne} /> + getScale={returnOne} />; } @computed get content() { diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 0196fecff..c212cc97c 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -153,7 +153,7 @@ class TreeView extends React.Component { let docList = Cast(this.resolvedDataDoc[this.fieldKey], listSpec(Doc)); let doc = Cast(this.resolvedDataDoc[this.fieldKey], Doc); let isDoc = doc instanceof Doc || docList; - let c + let c; return
this._collapsed = !this._collapsed)} style={{ color: StrCast(this.props.document.color, "black"), opacity: 0.4 }}> {}
; diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 73ae8955d..1df955f1f 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -33,7 +33,7 @@ export const pageSchema = createSchema({ curPage: "number", }); -interface window { +interface Window { MediaRecorder: MediaRecorder; } diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 66844cdd6..e90efb31c 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -108,7 +108,7 @@ export class VideoBox extends DocComponent(VideoD this._youtubeReactionDisposer = reaction(() => [this.props.isSelected(), DocumentDecorations.Instance.Interacting, InkingControl.Instance.selectedTool], () => { let interactive = InkingControl.Instance.selectedTool === InkTool.None && this.props.isSelected() && !DocumentDecorations.Instance.Interacting; this._youtubePlayer.getIframe().style.pointerEvents = interactive ? "all" : "none"; - }, { fireImmediately: true }) + }, { fireImmediately: true }); // let iframe = $(document.getElementById(`${videoid}-player`)!); // iframe.on("load", function () { // iframe.contents().find("head") @@ -120,7 +120,7 @@ export class VideoBox extends DocComponent(VideoD @action onYoutubePlayerStateChange = (event: any) => { console.log("event.data = " + event.data); - this.Playing = event.data == YT.PlayerState.PLAYING; + this.Playing = event.data === YT.PlayerState.PLAYING; if (this._youtubeSeekTo && this.Playing) { this._youtubePlayer.pauseVideo(); this._youtubeSeekTo = false; diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 96b972a1c..f0a9ec6d8 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -19,7 +19,7 @@ export function onYouTubeIframeAPIReady() { }); } // must cast as any to set property on window -const _global = (window /* browser */ || global /* node */) as any +const _global = (window /* browser */ || global /* node */) as any; _global.onYouTubeIframeAPIReady = onYouTubeIframeAPIReady; function onPlayerReady(event: any) { diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 3830a6d16..ec778b346 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -282,7 +282,7 @@ export class SearchBox extends React.Component { @computed get resFull() { - console.log(this._numTotalResults) + console.log(this._numTotalResults); return this._numTotalResults <= 8; } -- cgit v1.2.3-70-g09d2 From 7f6666500f157c5884377d714137426cf05e7569 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Tue, 16 Jul 2019 13:40:20 -0400 Subject: Changed search to display extension documents as the extended documents --- src/client/documents/Documents.ts | 2 +- src/client/views/InkingControl.tsx | 4 ++-- src/client/views/collections/CollectionVideoView.tsx | 2 +- src/client/views/search/SearchBox.tsx | 13 ++++++++----- 4 files changed, 12 insertions(+), 9 deletions(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 177810444..5bbfe1c49 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -235,7 +235,7 @@ export namespace Docs { let title = prototypeId.toUpperCase().replace(upper, `_${upper}`); // synthesize the default options, the type and title from computed values and // whatever options pertain to this specific prototype - let options = { title: title, type: type, ...defaultOptions, ...(template.options || {}) }; + let options = { title: title, type: type, baseProto: true, ...defaultOptions, ...(template.options || {}) }; let primary = layout.view.LayoutString(); let collectionView = layout.collectionView; if (collectionView) { diff --git a/src/client/views/InkingControl.tsx b/src/client/views/InkingControl.tsx index 1910e409b..c7f7bdb66 100644 --- a/src/client/views/InkingControl.tsx +++ b/src/client/views/InkingControl.tsx @@ -1,5 +1,5 @@ import { observable, action, computed, runInAction } from "mobx"; -import { ColorState } from 'react-color'; +import { ColorResult } from 'react-color'; import React = require("react"); import { observer } from "mobx-react"; import "./InkingControl.scss"; @@ -41,7 +41,7 @@ export class InkingControl extends React.Component { } @undoBatch - switchColor = action((color: ColorState): void => { + switchColor = action((color: ColorResult): void => { this._selectedColor = color.hex + (color.rgb.a !== undefined ? this.decimalToHexString(Math.round(color.rgb.a * 255)) : "ff"); if (InkingControl.Instance.selectedTool === InkTool.None) { if (MainOverlayTextBox.Instance.SetColor(color.hex)) return; diff --git a/src/client/views/collections/CollectionVideoView.tsx b/src/client/views/collections/CollectionVideoView.tsx index faf507496..096e7e9d1 100644 --- a/src/client/views/collections/CollectionVideoView.tsx +++ b/src/client/views/collections/CollectionVideoView.tsx @@ -88,7 +88,7 @@ export class CollectionVideoView extends React.Component { canvas.width = 640; canvas.height = 640 * NumCast(this.props.Document.nativeHeight) / NumCast(this.props.Document.nativeWidth); var ctx = canvas.getContext('2d');//draw image to canvas. scale to target dimensions - this._videoBox!.player && ctx && ctx.drawImage(this._videoBox!.player!, 0, 0, canvas.width, canvas.height); + this._videoBox!.player && ctx && ctx.drawImage(this._videoBox!.player, 0, 0, canvas.width, canvas.height); //convert to desired file format var dataUrl = canvas.toDataURL('image/png'); // can also use 'image/png' diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index ec778b346..dc76d1ff4 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -6,7 +6,7 @@ import "./FilterBox.scss"; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { SetupDrag } from '../../util/DragManager'; import { Docs } from '../../documents/Documents'; -import { NumCast } from '../../../new_fields/Types'; +import { NumCast, Cast } from '../../../new_fields/Types'; import { Doc } from '../../../new_fields/Doc'; import { SearchItem } from './SearchItem'; import { DocServer } from '../../DocServer'; @@ -118,7 +118,7 @@ export class SearchBox extends React.Component { private get filterQuery() { const types = FilterBox.Instance.filterTypes; - return "proto_i:*" + (types ? ` AND (${types.map(type => `({!join from=id to=proto_i}type_t:"${type}" AND NOT type_t:*) OR type_t:"${type}"`).join(" ")})` : ""); + return "NOT baseProto_b:true" + (types ? ` AND (${types.map(type => `({!join from=id to=proto_i}type_t:"${type}" AND NOT type_t:*) OR type_t:"${type}"`).join(" ")})` : ""); } @@ -129,15 +129,18 @@ export class SearchBox extends React.Component { } this.lockPromise = new Promise(async res => { while (this._results.length <= this._endIndex && (this._numTotalResults === -1 || this._maxSearchIndex < this._numTotalResults)) { - this._curRequest = SearchUtil.Search(query, this.filterQuery, true, this._maxSearchIndex, 10).then(action((res: SearchUtil.DocSearchResult) => { + this._curRequest = SearchUtil.Search(query, this.filterQuery, true, this._maxSearchIndex, 10).then(action(async (res: SearchUtil.DocSearchResult) => { // happens at the beginning if (res.numFound !== this._numTotalResults && this._numTotalResults === -1) { this._numTotalResults = res.numFound; } - let filteredDocs = FilterBox.Instance.filterDocsByType(res.docs); - this._results.push(...filteredDocs); + const docs = await Promise.all(res.docs.map(doc => Cast(doc.extendsDoc, Doc, doc as any))); + let filteredDocs = FilterBox.Instance.filterDocsByType(docs); + runInAction(() => { + this._results.push(...filteredDocs); + }); this._curRequest = undefined; })); -- cgit v1.2.3-70-g09d2 From 967638b84c15f35bbfb1c464ac8e22916a1a2bc7 Mon Sep 17 00:00:00 2001 From: monikahedman Date: Tue, 16 Jul 2019 14:31:20 -0400 Subject: changes --- src/client/views/search/FilterBox.tsx | 3 +++ src/client/views/search/SearchBox.scss | 4 ++-- src/client/views/search/SearchBox.tsx | 15 +++++++-------- 3 files changed, 12 insertions(+), 10 deletions(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/views/search/FilterBox.tsx b/src/client/views/search/FilterBox.tsx index f11fb008c..757665bcf 100644 --- a/src/client/views/search/FilterBox.tsx +++ b/src/client/views/search/FilterBox.tsx @@ -87,6 +87,9 @@ export class FilterBox extends React.Component { } }); + + let el = acc[i] as HTMLElement; + el.click(); } }); } diff --git a/src/client/views/search/SearchBox.scss b/src/client/views/search/SearchBox.scss index 324ba3063..109b88ac9 100644 --- a/src/client/views/search/SearchBox.scss +++ b/src/client/views/search/SearchBox.scss @@ -41,11 +41,10 @@ } .searchBox-results { - margin-right: 142px; + margin-right: 136px; top: 300px; display: flex; flex-direction: column; - margin-right: 72px; max-height: 560px; overflow: hidden; overflow-y: auto; @@ -60,5 +59,6 @@ text-transform: uppercase; text-align: left; font-weight: bold; + margin-left: 28px; } } \ No newline at end of file diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 3830a6d16..661c9c10b 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -22,6 +22,7 @@ export class SearchBox extends React.Component { @observable private _searchString: string = ""; @observable private _resultsOpen: boolean = false; + @observable private _searchbarOpen: boolean = false; @observable private _results: Doc[] = []; @observable private _openNoResults: boolean = false; @observable private _visibleElements: JSX.Element[] = []; @@ -107,6 +108,7 @@ export class SearchBox extends React.Component { runInAction(() => { this._resultsOpen = true; + this._searchbarOpen = true; this._openNoResults = true; this.resultsScrolled(); }); @@ -198,6 +200,7 @@ export class SearchBox extends React.Component { this._openNoResults = false; FilterBox.Instance.closeFilter(); this._resultsOpen = true; + this._searchbarOpen = true; FilterBox.Instance._pointerTime = e.timeStamp; } @@ -205,6 +208,7 @@ export class SearchBox extends React.Component { closeSearch = () => { FilterBox.Instance.closeFilter(); this.closeResults(); + this._searchbarOpen = false; } @action.bound @@ -281,15 +285,10 @@ export class SearchBox extends React.Component { } @computed - get resFull() { - console.log(this._numTotalResults) - return this._numTotalResults <= 8; - } + get resFull() { return this._numTotalResults <= 8; } @computed - get resultHeight() { - return this._numTotalResults * 70; - } + get resultHeight() { return this._numTotalResults * 70; } render() { return ( @@ -300,7 +299,7 @@ export class SearchBox extends React.Component { + style={{ width: this._searchbarOpen ? "500px" : "100px" }} />
-- cgit v1.2.3-70-g09d2 From 1b5bf295d951858a9d54e95e2ada4882f1a39f40 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Tue, 16 Jul 2019 14:41:18 -0400 Subject: Added start of deleted documents to search --- solr/conf/schema.xml | 1 + src/client/views/search/SearchBox.tsx | 3 +- src/server/GarbageCollector.ts | 87 +++++++++++++++++++++-------------- 3 files changed, 55 insertions(+), 36 deletions(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/solr/conf/schema.xml b/solr/conf/schema.xml index 8610786af..7a21794cb 100644 --- a/solr/conf/schema.xml +++ b/solr/conf/schema.xml @@ -44,6 +44,7 @@ + diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index dc76d1ff4..733e93a62 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -118,7 +118,8 @@ export class SearchBox extends React.Component { private get filterQuery() { const types = FilterBox.Instance.filterTypes; - return "NOT baseProto_b:true" + (types ? ` AND (${types.map(type => `({!join from=id to=proto_i}type_t:"${type}" AND NOT type_t:*) OR type_t:"${type}"`).join(" ")})` : ""); + const includeDeleted = false; + return "NOT baseProto_b:true" + (includeDeleted ? "" : " AND NOT deleted:true") + (types ? ` AND (${types.map(type => `({!join from=id to=proto_i}type_t:"${type}" AND NOT type_t:*) OR type_t:"${type}"`).join(" ")})` : ""); } diff --git a/src/server/GarbageCollector.ts b/src/server/GarbageCollector.ts index 59682e51e..ea5388004 100644 --- a/src/server/GarbageCollector.ts +++ b/src/server/GarbageCollector.ts @@ -59,7 +59,9 @@ function addDoc(doc: any, ids: string[], files: { [name: string]: string[] }) { } } -async function GarbageCollect() { +async function GarbageCollect(full: boolean = true) { + console.log("start GC"); + const start = Date.now(); // await new Promise(res => setTimeout(res, 3000)); const cursor = await Database.Instance.query({}, { userDocumentId: 1 }, 'users'); const users = await cursor.toArray(); @@ -68,7 +70,7 @@ async function GarbageCollect() { const files: { [name: string]: string[] } = {}; while (ids.length) { - const count = Math.min(ids.length, 100); + const count = Math.min(ids.length, 1000); const index = ids.length - count; const fetchIds = ids.splice(index, count).filter(id => !visited.has(id)); if (!fetchIds.length) { @@ -91,43 +93,58 @@ async function GarbageCollect() { cursor.close(); - const toDeleteCursor = await Database.Instance.query({ _id: { $nin: Array.from(visited) } }, { _id: 1 }); + const notToDelete = Array.from(visited); + const toDeleteCursor = await Database.Instance.query({ _id: { $nin: notToDelete } }, { _id: 1 }); const toDelete: string[] = (await toDeleteCursor.toArray()).map(doc => doc._id); toDeleteCursor.close(); - let i = 0; - let deleted = 0; - while (i < toDelete.length) { - const count = Math.min(toDelete.length, 5000); - const toDeleteDocs = toDelete.slice(i, i + count); - i += count; - const result = await Database.Instance.delete({ _id: { $in: toDeleteDocs } }, "newDocuments"); - deleted += result.deletedCount || 0; - } - // const result = await Database.Instance.delete({ _id: { $in: toDelete } }, "newDocuments"); - console.log(`${deleted} documents deleted`); + if (!full) { + await Database.Instance.updateMany({ _id: { $nin: notToDelete } }, { $set: { "deleted": true } }); + await Database.Instance.updateMany({ _id: { $in: notToDelete } }, { $unset: { "deleted": true } }); + console.log(await Search.Instance.updateDocuments( + notToDelete.map(id => ({ + id, deleted: { set: null } + })) + .concat(toDelete.map(id => ({ + id, deleted: { set: true } + }))))); + console.log("Done with partial GC"); + console.log(`Took ${(Date.now() - start) / 1000} seconds`); + } else { + let i = 0; + let deleted = 0; + while (i < toDelete.length) { + const count = Math.min(toDelete.length, 5000); + const toDeleteDocs = toDelete.slice(i, i + count); + i += count; + const result = await Database.Instance.delete({ _id: { $in: toDeleteDocs } }, "newDocuments"); + deleted += result.deletedCount || 0; + } + // const result = await Database.Instance.delete({ _id: { $in: toDelete } }, "newDocuments"); + console.log(`${deleted} documents deleted`); - await Search.Instance.deleteDocuments(toDelete); - console.log("Cleared search documents"); + await Search.Instance.deleteDocuments(toDelete); + console.log("Cleared search documents"); - const folder = "./src/server/public/files/"; - fs.readdir(folder, (_, fileList) => { - const filesToDelete = fileList.filter(file => { - const ext = path.extname(file); - let base = path.basename(file, ext); - const existsInDb = (base in files || (base = base.substring(0, base.length - 2)) in files) && files[base].includes(ext); - return file !== ".gitignore" && !existsInDb; - }); - console.log(`Deleting ${filesToDelete.length} files`); - filesToDelete.forEach(file => { - console.log(`Deleting file ${file}`); - try { - fs.unlinkSync(folder + file); - } catch { - console.warn(`Couldn't delete file ${file}`); - } + const folder = "./src/server/public/files/"; + fs.readdir(folder, (_, fileList) => { + const filesToDelete = fileList.filter(file => { + const ext = path.extname(file); + let base = path.basename(file, ext); + const existsInDb = (base in files || (base = base.substring(0, base.length - 2)) in files) && files[base].includes(ext); + return file !== ".gitignore" && !existsInDb; + }); + console.log(`Deleting ${filesToDelete.length} files`); + filesToDelete.forEach(file => { + console.log(`Deleting file ${file}`); + try { + fs.unlinkSync(folder + file); + } catch { + console.warn(`Couldn't delete file ${file}`); + } + }); + console.log(`Deleted ${filesToDelete.length} files`); }); - console.log(`Deleted ${filesToDelete.length} files`); - }); + } } -GarbageCollect(); +GarbageCollect(false); -- cgit v1.2.3-70-g09d2 From 189bb0ffd14fb0b8db0edbe813efe19f143a30fd Mon Sep 17 00:00:00 2001 From: monikahedman Date: Tue, 16 Jul 2019 14:46:44 -0400 Subject: shes fixed --- src/client/views/search/SearchBox.tsx | 1 + 1 file changed, 1 insertion(+) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 661c9c10b..0b2d792e0 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -94,6 +94,7 @@ export class SearchBox extends React.Component { this._results = []; this._isSearch = []; this._visibleElements = []; + FilterBox.Instance.closeFilter(); //if there is no query there should be no result if (query === "") { -- cgit v1.2.3-70-g09d2 From 6353522fbd8dc961b9c172b15d33af842fdab323 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Tue, 16 Jul 2019 17:03:41 -0400 Subject: Added deduplication of results --- src/client/views/search/SearchBox.tsx | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 04db26aca..cb4aef961 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -24,6 +24,7 @@ export class SearchBox extends React.Component { @observable private _resultsOpen: boolean = false; @observable private _searchbarOpen: boolean = false; @observable private _results: Doc[] = []; + private _resultsSet = new Set(); @observable private _openNoResults: boolean = false; @observable private _visibleElements: JSX.Element[] = []; @@ -61,6 +62,7 @@ export class SearchBox extends React.Component { this._openNoResults = false; this._results = []; + this._resultsSet.clear(); this._visibleElements = []; this._numTotalResults = -1; this._endIndex = -1; @@ -92,6 +94,7 @@ export class SearchBox extends React.Component { let query = this._searchString; query = FilterBox.Instance.getFinalQuery(query); this._results = []; + this._resultsSet.clear(); this._isSearch = []; this._visibleElements = []; @@ -120,7 +123,7 @@ export class SearchBox extends React.Component { private get filterQuery() { const types = FilterBox.Instance.filterTypes; - const includeDeleted = false; + const includeDeleted = FilterBox.Instance.getDataStatus(); return "NOT baseProto_b:true" + (includeDeleted ? "" : " AND NOT deleted:true") + (types ? ` AND (${types.map(type => `({!join from=id to=proto_i}type_t:"${type}" AND NOT type_t:*) OR type_t:"${type}"`).join(" ")})` : ""); } @@ -142,7 +145,13 @@ export class SearchBox extends React.Component { const docs = await Promise.all(res.docs.map(doc => Cast(doc.extendsDoc, Doc, doc as any))); let filteredDocs = FilterBox.Instance.filterDocsByType(docs); runInAction(() => { - this._results.push(...filteredDocs); + // this._results.push(...filteredDocs); + filteredDocs.forEach(doc => { + if (!this._resultsSet.has(doc)) { + this._results.push(doc); + this._resultsSet.add(doc); + } + }); }); this._curRequest = undefined; @@ -219,6 +228,7 @@ export class SearchBox extends React.Component { closeResults() { this._resultsOpen = false; this._results = []; + this._resultsSet.clear(); this._visibleElements = []; this._numTotalResults = -1; this._endIndex = -1; -- cgit v1.2.3-70-g09d2 From 31d2d8e058e0559707da352defd02585a3963353 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Tue, 16 Jul 2019 18:36:51 -0400 Subject: Added more parameters to and refactored search --- src/client/util/SearchUtil.ts | 37 ++++++++++++++-------- .../views/collections/ParentDocumentSelector.tsx | 4 +-- src/client/views/search/SearchBox.tsx | 16 ++++++---- src/client/views/search/SearchItem.scss | 12 ++++--- src/client/views/search/SearchItem.tsx | 10 ++++-- src/server/Search.ts | 12 ++----- src/server/database.ts | 11 +++++++ src/server/index.ts | 7 ++-- src/server/updateProtos.ts | 15 +++++++++ 9 files changed, 83 insertions(+), 41 deletions(-) create mode 100644 src/server/updateProtos.ts (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts index 806746496..abf1a7c32 100644 --- a/src/client/util/SearchUtil.ts +++ b/src/client/util/SearchUtil.ts @@ -4,30 +4,41 @@ import { Doc } from '../../new_fields/Doc'; import { Id } from '../../new_fields/FieldSymbols'; export namespace SearchUtil { + export type HighlightingResult = { [id: string]: { [key: string]: string[] } }; + export interface IdSearchResult { ids: string[]; numFound: number; + highlighting: HighlightingResult | undefined; } export interface DocSearchResult { docs: Doc[]; numFound: number; + highlighting: HighlightingResult | undefined; } - export function Search(query: string, filterQuery: string | undefined, returnDocs: true, start?: number, count?: number): Promise; - export function Search(query: string, filterQuery: string | undefined, returnDocs: false, start?: number, count?: number): Promise; - export async function Search(query: string, filterQuery: string | undefined, returnDocs: boolean, start?: number, rows?: number) { + export interface SearchParams { + hl?: boolean; + "hl.fl"?: string; + start?: number; + rows?: number; + fq?: string; + } + export function Search(query: string, returnDocs: true, options?: SearchParams): Promise; + export function Search(query: string, returnDocs: false, options?: SearchParams): Promise; + export async function Search(query: string, returnDocs: boolean, options: SearchParams = {}) { query = query || "*"; //If we just have a filter query, search for * as the query const result: IdSearchResult = JSON.parse(await rp.get(DocServer.prepend("/search"), { - qs: { query, filterQuery, start, rows }, + qs: { ...options, q: query }, })); if (!returnDocs) { return result; } - const { ids, numFound } = result; + const { ids, numFound, highlighting } = result; const docMap = await DocServer.GetRefFields(ids); const docs = ids.map((id: string) => docMap[id]).filter((doc: any) => doc instanceof Doc); - return { docs, numFound }; + return { docs, numFound, highlighting }; } export async function GetAliasesOfDocument(doc: Doc): Promise; @@ -36,31 +47,31 @@ export namespace SearchUtil { const proto = Doc.GetProto(doc); const protoId = proto[Id]; if (returnDocs) { - return (await Search("", `proto_i:"${protoId}"`, returnDocs)).docs; + return (await Search("", returnDocs, { fq: `proto_i:"${protoId}"` })).docs; } else { - return (await Search("", `proto_i:"${protoId}"`, returnDocs)).ids; + return (await Search("", returnDocs, { fq: `proto_i:"${protoId}"` })).ids; } // return Search(`{!join from=id to=proto_i}id:${protoId}`, true); } export async function GetViewsOfDocument(doc: Doc): Promise { - const results = await Search("", `proto_i:"${doc[Id]}"`, true); + const results = await Search("", true, { fq: `proto_i:"${doc[Id]}"` }); return results.docs; } export async function GetContextsOfDocument(doc: Doc): Promise<{ contexts: Doc[], aliasContexts: Doc[] }> { - const docContexts = (await Search("", `data_l:"${doc[Id]}"`, true)).docs; + const docContexts = (await Search("", true, { fq: `data_l:"${doc[Id]}"` })).docs; const aliases = await GetAliasesOfDocument(doc, false); - const aliasContexts = (await Promise.all(aliases.map(doc => Search("", `data_l:"${doc}"`, true)))); + const aliasContexts = (await Promise.all(aliases.map(doc => Search("", true, { fq: `data_l:"${doc}"` })))); const contexts = { contexts: docContexts, aliasContexts: [] as Doc[] }; aliasContexts.forEach(result => contexts.aliasContexts.push(...result.docs)); return contexts; } export async function GetContextIdsOfDocument(doc: Doc): Promise<{ contexts: string[], aliasContexts: string[] }> { - const docContexts = (await Search("", `data_l:"${doc[Id]}"`, false)).ids; + const docContexts = (await Search("", false, { fq: `data_l:"${doc[Id]}"` })).ids; const aliases = await GetAliasesOfDocument(doc, false); - const aliasContexts = (await Promise.all(aliases.map(doc => Search("", `data_l:"${doc}"`, false)))); + const aliasContexts = (await Promise.all(aliases.map(doc => Search("", false, { fq: `data_l:"${doc}"` })))); const contexts = { contexts: docContexts, aliasContexts: [] as string[] }; aliasContexts.forEach(result => contexts.aliasContexts.push(...result.ids)); return contexts; diff --git a/src/client/views/collections/ParentDocumentSelector.tsx b/src/client/views/collections/ParentDocumentSelector.tsx index a97aa4f36..c3e55d825 100644 --- a/src/client/views/collections/ParentDocumentSelector.tsx +++ b/src/client/views/collections/ParentDocumentSelector.tsx @@ -23,9 +23,9 @@ export class SelectorContextMenu extends React.Component { async fetchDocuments() { let aliases = (await SearchUtil.GetAliasesOfDocument(this.props.Document)).filter(doc => doc !== this.props.Document); - const { docs } = await SearchUtil.Search("", `data_l:"${this.props.Document[Id]}"`, true); + const { docs } = await SearchUtil.Search("", true, { fq: `data_l:"${this.props.Document[Id]}"` }); const map: Map = new Map; - const allDocs = await Promise.all(aliases.map(doc => SearchUtil.Search("", `data_l:"${doc[Id]}"`, true).then(result => result.docs))); + const allDocs = await Promise.all(aliases.map(doc => SearchUtil.Search("", true, { fq: `data_l:"${doc[Id]}"` }).then(result => result.docs))); allDocs.forEach((docs, index) => docs.forEach(doc => map.set(doc, aliases[index]))); docs.forEach(doc => map.delete(doc)); runInAction(() => { diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index d07df7e58..108492e90 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -23,7 +23,7 @@ export class SearchBox extends React.Component { @observable private _searchString: string = ""; @observable private _resultsOpen: boolean = false; @observable private _searchbarOpen: boolean = false; - @observable private _results: Doc[] = []; + @observable private _results: [Doc, string[]][] = []; private _resultsSet = new Set(); @observable private _openNoResults: boolean = false; @observable private _visibleElements: JSX.Element[] = []; @@ -119,7 +119,7 @@ export class SearchBox extends React.Component { } getAllResults = async (query: string) => { - return SearchUtil.Search(query, this.filterQuery, true, 0, 10000000); + return SearchUtil.Search(query, true, { fq: this.filterQuery, start: 0, rows: 10000000 }); } private get filterQuery() { @@ -136,20 +136,22 @@ export class SearchBox extends React.Component { } this.lockPromise = new Promise(async res => { while (this._results.length <= this._endIndex && (this._numTotalResults === -1 || this._maxSearchIndex < this._numTotalResults)) { - this._curRequest = SearchUtil.Search(query, this.filterQuery, true, this._maxSearchIndex, 10).then(action(async (res: SearchUtil.DocSearchResult) => { + this._curRequest = SearchUtil.Search(query, true, { fq: this.filterQuery, start: this._maxSearchIndex, rows: 10, hl: true, "hl.fl": "*" }).then(action(async (res: SearchUtil.DocSearchResult) => { // happens at the beginning if (res.numFound !== this._numTotalResults && this._numTotalResults === -1) { this._numTotalResults = res.numFound; } + const highlighing = res.highlighting || {}; const docs = await Promise.all(res.docs.map(doc => Cast(doc.extendsDoc, Doc, doc as any))); let filteredDocs = FilterBox.Instance.filterDocsByType(docs); runInAction(() => { // this._results.push(...filteredDocs); filteredDocs.forEach(doc => { if (!this._resultsSet.has(doc)) { - this._results.push(doc); + const highlight = highlighing[doc[Id]]; + this._results.push([doc, highlight ? Object.keys(highlight).map(key => key.substring(0, key.length - 2)) : []]); this._resultsSet.add(doc); } }); @@ -274,19 +276,19 @@ export class SearchBox extends React.Component { } else { if (this._isSearch[i] !== "search") { - let result: Doc | undefined = undefined; + let result: [Doc, string[]] | undefined = undefined; if (i >= this._results.length) { this.getResults(this._searchString); if (i < this._results.length) result = this._results[i]; if (result) { - this._visibleElements[i] = ; + this._visibleElements[i] = ; this._isSearch[i] = "search"; } } else { result = this._results[i]; if (result) { - this._visibleElements[i] = ; + this._visibleElements[i] = ; this._isSearch[i] = "search"; } } diff --git a/src/client/views/search/SearchItem.scss b/src/client/views/search/SearchItem.scss index 24dd2eaa3..273d49349 100644 --- a/src/client/views/search/SearchItem.scss +++ b/src/client/views/search/SearchItem.scss @@ -24,11 +24,15 @@ flex-direction: row; width: 100%; - .search-title { - text-transform: uppercase; - text-align: left; + .search-title-container { width: 100%; - font-weight: bold; + + .search-title { + text-transform: uppercase; + text-align: left; + width: 100%; + font-weight: bold; + } } .search-info { diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx index e34d101a8..26f00e03e 100644 --- a/src/client/views/search/SearchItem.tsx +++ b/src/client/views/search/SearchItem.tsx @@ -26,6 +26,7 @@ import { faFile } from '@fortawesome/free-solid-svg-icons'; export interface SearchItemProps { doc: Doc; + highlighting: string[]; } library.add(faCaretUp); @@ -51,9 +52,9 @@ export class SelectorContextMenu extends React.Component { async fetchDocuments() { let aliases = (await SearchUtil.GetViewsOfDocument(this.props.doc)).filter(doc => doc !== this.props.doc); - const { docs } = await SearchUtil.Search("", `data_l:"${this.props.doc[Id]}"`, true); + const { docs } = await SearchUtil.Search("", true, { fq: `data_l:"${this.props.doc[Id]}"` }); const map: Map = new Map; - const allDocs = await Promise.all(aliases.map(doc => SearchUtil.Search("", `data_l:"${doc[Id]}"`, true).then(result => result.docs))); + const allDocs = await Promise.all(aliases.map(doc => SearchUtil.Search("", true, { fq: `data_l:"${doc[Id]}"` }).then(result => result.docs))); allDocs.forEach((docs, index) => docs.forEach(doc => map.set(doc, aliases[index]))); docs.forEach(doc => map.delete(doc)); runInAction(() => { @@ -243,7 +244,10 @@ export class SearchItem extends React.Component { onClick={this.onClick} onPointerDown={this.pointerDown} >
-
{StrCast(this.props.doc.title)}
+
+
{StrCast(this.props.doc.title)}
+
Matched fields: {this.props.highlighting.join(", ")}
+
{this.DocumentIcon}
diff --git a/src/server/Search.ts b/src/server/Search.ts index 69e327d2d..723dc101b 100644 --- a/src/server/Search.ts +++ b/src/server/Search.ts @@ -30,20 +30,14 @@ export class Search { } } - public async search(query: string, filterQuery: string = "", start: number = 0, rows: number = 10) { + public async search(query: any) { try { const searchResults = JSON.parse(await rp.get(this.url + "dash/select", { - qs: { - q: query, - fq: filterQuery, - fl: "id", - start, - rows, - } + qs: query })); const { docs, numFound } = searchResults.response; const ids = docs.map((field: any) => field.id); - return { ids, numFound }; + return { ids, numFound, highlighting: searchResults.highlighting }; } catch { return { ids: [], numFound: -1 }; } diff --git a/src/server/database.ts b/src/server/database.ts index 29a8ffafa..7f5331998 100644 --- a/src/server/database.ts +++ b/src/server/database.ts @@ -140,6 +140,17 @@ export class Database { } } + public updateMany(query: any, update: any, collectionName = "newDocuments") { + if (this.db) { + const db = this.db; + return new Promise(res => db.collection(collectionName).update(query, update, (_, result) => res(result))); + } else { + return new Promise(res => { + this.onConnect.push(() => this.updateMany(query, update, collectionName).then(res)); + }); + } + } + public print() { console.log("db says hi!"); } diff --git a/src/server/index.ts b/src/server/index.ts index 2cca7a35b..ad879093b 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -144,12 +144,13 @@ app.get("/pull", (req, res) => // GETTERS app.get("/search", async (req, res) => { - const { query, filterQuery, start, rows } = req.query; - if (query === undefined) { + const solrQuery: any = {}; + ["q", "fq", "start", "rows", "hl", "hl.fl"].forEach(key => solrQuery[key] = req.query[key]); + if (solrQuery.q === undefined) { res.send([]); return; } - let results = await Search.Instance.search(query, filterQuery, start, rows); + let results = await Search.Instance.search(solrQuery); res.send(results); }); diff --git a/src/server/updateProtos.ts b/src/server/updateProtos.ts new file mode 100644 index 000000000..90490eb45 --- /dev/null +++ b/src/server/updateProtos.ts @@ -0,0 +1,15 @@ +import { Database } from "./database"; + +const protos = + ["text", "histogram", "image", "web", "collection", "kvp", + "video", "audio", "pdf", "icon", "import", "linkdoc"]; + +(async function () { + await Promise.all( + protos.map(protoId => new Promise(res => Database.Instance.update(protoId, { + $set: { "fields.baseProto": true } + }, res))) + ); + + console.log("done"); +})(); \ No newline at end of file -- cgit v1.2.3-70-g09d2 From f0f020501c782a4989fc1dc47031acb40335532c Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Tue, 16 Jul 2019 22:26:18 -0400 Subject: Semi hacky fix for search matched fields with extensionDocs --- src/client/views/search/SearchBox.tsx | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 108492e90..8399605fb 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -24,7 +24,7 @@ export class SearchBox extends React.Component { @observable private _resultsOpen: boolean = false; @observable private _searchbarOpen: boolean = false; @observable private _results: [Doc, string[]][] = []; - private _resultsSet = new Set(); + private _resultsSet = new Map(); @observable private _openNoResults: boolean = false; @observable private _visibleElements: JSX.Element[] = []; @@ -143,16 +143,23 @@ export class SearchBox extends React.Component { this._numTotalResults = res.numFound; } - const highlighing = res.highlighting || {}; + const highlighting = res.highlighting || {}; + const highlightList = res.docs.map(doc => highlighting[doc[Id]]); const docs = await Promise.all(res.docs.map(doc => Cast(doc.extendsDoc, Doc, doc as any))); + const highlights: typeof res.highlighting = {}; + docs.forEach((doc, index) => highlights[doc[Id]] = highlightList[index]); let filteredDocs = FilterBox.Instance.filterDocsByType(docs); runInAction(() => { // this._results.push(...filteredDocs); filteredDocs.forEach(doc => { - if (!this._resultsSet.has(doc)) { - const highlight = highlighing[doc[Id]]; - this._results.push([doc, highlight ? Object.keys(highlight).map(key => key.substring(0, key.length - 2)) : []]); - this._resultsSet.add(doc); + const index = this._resultsSet.get(doc); + const highlight = highlights[doc[Id]]; + const hlights = highlight ? Object.keys(highlight).map(key => key.substring(0, key.length - 2)) : [] + if (index === undefined) { + this._resultsSet.set(doc, this._results.length); + this._results.push([doc, hlights]); + } else { + this._results[index][1].push(...hlights); } }); }); -- cgit v1.2.3-70-g09d2 From de6e2427cf5eed2805432a37b5284a4c8b934e62 Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 17 Jul 2019 12:49:12 -0400 Subject: fixed some search box things. added more to audio annotations. --- package.json | 1 + src/client/views/nodes/ImageBox.tsx | 67 +++++++++++++++++++++++++++++++--- src/client/views/search/SearchBox.tsx | 2 +- src/client/views/search/SearchItem.tsx | 4 +- 4 files changed, 66 insertions(+), 8 deletions(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/package.json b/package.json index 7407a719f..2cec44473 100644 --- a/package.json +++ b/package.json @@ -129,6 +129,7 @@ "font-awesome": "^4.7.0", "formidable": "^1.2.1", "golden-layout": "^1.5.9", + "howler": "^2.1.2", "html-to-image": "^0.1.0", "i": "^0.3.6", "image-data-uri": "^2.0.0", diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 4c5ad7a7d..7c29724a2 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -1,6 +1,6 @@ import { library } from '@fortawesome/fontawesome-svg-core'; -import { faImage } from '@fortawesome/free-solid-svg-icons'; -import { action, observable, computed } from 'mobx'; +import { faImage, faFileAudio } from '@fortawesome/free-solid-svg-icons'; +import { action, observable, computed, runInAction } from 'mobx'; import { observer } from "mobx-react"; import Lightbox from 'react-image-lightbox'; import 'react-image-lightbox/style.css'; // This only needs to be imported once in your app @@ -8,7 +8,7 @@ import { Doc, HeightSym, WidthSym, DocListCast } from '../../../new_fields/Doc'; import { List } from '../../../new_fields/List'; import { createSchema, listSpec, makeInterface } from '../../../new_fields/Schema'; import { Cast, FieldValue, NumCast, StrCast, BoolCast } from '../../../new_fields/Types'; -import { ImageField } from '../../../new_fields/URLField'; +import { ImageField, AudioField } from '../../../new_fields/URLField'; import { Utils } from '../../../Utils'; import { DragManager } from '../../util/DragManager'; import { undoBatch } from '../../util/UndoManager'; @@ -23,11 +23,15 @@ import React = require("react"); import { RouteStore } from '../../../server/RouteStore'; import { Docs } from '../../documents/Documents'; import { DocServer } from '../../DocServer'; +import { Font } from '@react-pdf/renderer'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; var requestImageSize = require('../../util/request-image-size'); var path = require('path'); +const { Howl, Howler } = require('howler'); library.add(faImage); +library.add(faFileAudio); export const pageSchema = createSchema({ @@ -177,10 +181,11 @@ export class ImageBox extends DocComponent(ImageD audioAnnos.push(audioDoc); } }; + runInAction(() => self._audioState = 2); recorder.start(); setTimeout(() => { recorder.stop(); - + runInAction(() => self._audioState = 0); gumStream.getAudioTracks()[0].stop(); }, 5000); }); @@ -272,6 +277,46 @@ export class ImageBox extends DocComponent(ImageD }); } + @observable _audioState = 0; + + @action + onPointerEnter = () => { + let self = this; + let audioAnnos = DocListCast(this.extensionDoc.audioAnnotations); + if (audioAnnos.length && this._audioState === 0) { + audioAnnos.map(anno => anno.data instanceof AudioField && new Howl({ + src: [anno.data.url.href], + autoplay: true, + loop: false, + volume: 0.5, + onend: function () { + runInAction(() => self._audioState = 0); + } + })); + this._audioState = 1; + } + else { + if (this._audioState === 0) { + this._audioState = 1; + new Howl({ + src: ["https://www.kozco.com/tech/piano2-CoolEdit.mp3"], + autoplay: true, + loop: false, + volume: 0.5, + onend: function () { + runInAction(() => self._audioState = 0); + } + }); + } + } + } + + @action + audioDown = () => { + this.recordAudioAnnotation(); + } + + render() { // let transform = this.props.ScreenToLocalTransform().inverse(); let pw = typeof this.props.PanelWidth === "function" ? this.props.PanelWidth() : typeof this.props.PanelWidth === "number" ? (this.props.PanelWidth as any) as number : 50; @@ -282,7 +327,7 @@ export class ImageBox extends DocComponent(ImageD let id = (this.props as any).id; // bcz: used to set id = "isExpander" in templates.tsx let nativeWidth = FieldValue(this.Document.nativeWidth, pw); let nativeHeight = FieldValue(this.Document.nativeHeight, 0); - let paths: string[] = ["http://www.cs.brown.edu/~bcz/noImage.png"]; + let paths: string[] = [window.origin + RouteStore.corsProxy + "/" + "http://www.cs.brown.edu/~bcz/noImage.png"]; // this._curSuffix = ""; // if (w > 20) { Doc.UpdateDocumentExtensionForField(this.dataDoc, this.props.fieldKey); @@ -305,6 +350,7 @@ export class ImageBox extends DocComponent(ImageD return (
(ImageD ref={this._imgRef} onError={this.onError} /> {paths.length > 1 ? this.dots(paths) : (null)} +
+ +
{/* {this.lightbox(paths)} */}
); } diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 8399605fb..16c44225a 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -145,7 +145,7 @@ export class SearchBox extends React.Component { const highlighting = res.highlighting || {}; const highlightList = res.docs.map(doc => highlighting[doc[Id]]); - const docs = await Promise.all(res.docs.map(doc => Cast(doc.extendsDoc, Doc, doc as any))); + const docs = await Promise.all(res.docs.map(async doc => (await Cast(doc.extendsDoc, Doc)) || doc)); const highlights: typeof res.highlighting = {}; docs.forEach((doc, index) => highlights[doc[Id]] = highlightList[index]); let filteredDocs = FilterBox.Instance.filterDocsByType(docs); diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx index 26f00e03e..a995140e2 100644 --- a/src/client/views/search/SearchItem.tsx +++ b/src/client/views/search/SearchItem.tsx @@ -101,8 +101,8 @@ export class SearchItem extends React.Component { 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); - CollectionDockingView.Instance.AddRightSplit(this.props.doc, undefined); + DocumentManager.Instance.jumpToDocument(this.props.doc, false); + // CollectionDockingView.Instance.AddRightSplit(this.props.doc, undefined); } @observable _useIcons = true; @observable _displayDim = 50; -- cgit v1.2.3-70-g09d2 From 5aa6bcdd4e23bb9e9d05181d0dc6b638e45e397b Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Wed, 17 Jul 2019 20:48:14 -0400 Subject: Moved DocServer.prepend and changed how corsProxy works --- src/Utils.ts | 13 +++++ src/client/DocServer.ts | 8 ---- src/client/util/History.ts | 2 +- .../util/Import & Export/DirectoryImportBox.tsx | 4 +- src/client/util/SearchUtil.ts | 3 +- src/client/util/TooltipTextMenu.tsx | 8 ++-- src/client/views/MainView.tsx | 4 +- src/client/views/SearchBox.tsx | 3 +- .../views/collections/CollectionDockingView.tsx | 2 +- src/client/views/collections/CollectionSubView.tsx | 7 +-- src/client/views/nodes/DocumentView.tsx | 4 +- src/client/views/nodes/FormattedTextBox.tsx | 5 +- src/client/views/nodes/ImageBox.tsx | 6 +-- src/client/views/nodes/VideoBox.tsx | 4 +- src/client/views/pdf/PDFViewer.tsx | 55 +++++----------------- src/client/views/search/SearchBox.tsx | 6 +-- src/mobile/ImageUpload.tsx | 5 +- .../authentication/models/current_user_utils.ts | 5 +- src/server/index.ts | 2 +- 19 files changed, 65 insertions(+), 81 deletions(-) (limited to 'src/client/views/search/SearchBox.tsx') diff --git a/src/Utils.ts b/src/Utils.ts index e8a80bdc3..ac6d127cc 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -2,6 +2,7 @@ import v4 = require('uuid/v4'); import v5 = require("uuid/v5"); import { Socket } from 'socket.io'; import { Message } from './server/Message'; +import { RouteStore } from './server/RouteStore'; export class Utils { @@ -27,6 +28,18 @@ export class Utils { return { scale, translateX, translateY }; } + /** + * A convenience method. Prepends the full path (i.e. http://localhost:1050) to the + * requested extension + * @param extension the specified sub-path to append to the window origin + */ + public static prepend(extension: string): string { + return window.location.origin + extension; + } + public static CorsProxy(url: string): string { + return this.prepend(RouteStore.corsProxy + "/") + encodeURIComponent(url); + } + public static CopyText(text: string) { var textArea = document.createElement("textarea"); textArea.value = text; diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts index 6737657c8..8c64d2b2f 100644 --- a/src/client/DocServer.ts +++ b/src/client/DocServer.ts @@ -47,14 +47,6 @@ export namespace DocServer { Utils.AddServerHandler(_socket, MessageStore.DeleteField, respondToDelete); Utils.AddServerHandler(_socket, MessageStore.DeleteFields, respondToDelete); } - /** - * A convenience method. Prepends the full path (i.e. http://localhost:1050) to the - * requested extension - * @param extension the specified sub-path to append to the window origin - */ - export function prepend(extension: string): string { - return window.location.origin + extension; - } function errorFunc(): never { throw new Error("Can't use DocServer without calling init first"); diff --git a/src/client/util/History.ts b/src/client/util/History.ts index cbf5b3fc8..e9ff21b22 100644 --- a/src/client/util/History.ts +++ b/src/client/util/History.ts @@ -129,7 +129,7 @@ export namespace HistoryUtil { function addStringifier(type: string, keys: string[], customStringifier?: (state: ParsedUrl, current: string) => string) { stringifiers[type] = state => { - let path = DocServer.prepend(`/${type}`); + let path = Utils.prepend(`/${type}`); if (customStringifier) { path = customStringifier(state, path); } diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx index c096e9ceb..75b0b52a7 100644 --- a/src/client/util/Import & Export/DirectoryImportBox.tsx +++ b/src/client/util/Import & Export/DirectoryImportBox.tsx @@ -98,12 +98,12 @@ export default class DirectoryImportBox extends React.Component runInAction(() => this.remaining++); - let prom = fetch(DocServer.prepend(RouteStore.upload), { + let prom = fetch(Utils.prepend(RouteStore.upload), { method: 'POST', body: formData }).then(async (res: Response) => { (await res.json()).map(action((file: any) => { - let docPromise = Docs.Get.DocumentFromType(type, DocServer.prepend(file), { nativeWidth: 300, width: 300, title: dropFileName }); + let docPromise = Docs.Get.DocumentFromType(type, Utils.prepend(file), { nativeWidth: 300, width: 300, title: dropFileName }); docPromise.then(doc => { doc && docs.push(doc) && runInAction(() => this.remaining--); }); diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts index abf1a7c32..ee5a83710 100644 --- a/src/client/util/SearchUtil.ts +++ b/src/client/util/SearchUtil.ts @@ -2,6 +2,7 @@ import * as rp from 'request-promise'; import { DocServer } from '../DocServer'; import { Doc } from '../../new_fields/Doc'; import { Id } from '../../new_fields/FieldSymbols'; +import { Utils } from '../../Utils'; export namespace SearchUtil { export type HighlightingResult = { [id: string]: { [key: string]: string[] } }; @@ -29,7 +30,7 @@ export namespace SearchUtil { export function Search(query: string, returnDocs: false, options?: SearchParams): Promise; export async function Search(query: string, returnDocs: boolean, options: SearchParams = {}) { query = query || "*"; //If we just have a filter query, search for * as the query - const result: IdSearchResult = JSON.parse(await rp.get(DocServer.prepend("/search"), { + const result: IdSearchResult = JSON.parse(await rp.get(Utils.prepend("/search"), { qs: { ...options, q: query }, })); if (!returnDocs) { diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index 309d19016..a4c053de2 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -19,7 +19,7 @@ import { CollectionDockingView } from "../views/collections/CollectionDockingVie import { DocumentManager } from "./DocumentManager"; import { Id } from "../../new_fields/FieldSymbols"; import { FormattedTextBoxProps } from "../views/nodes/FormattedTextBox"; -import { SelectionManager } from "./SelectionManager"; +import { Utils } from "../../Utils"; //appears above a selection of text in a RichTextBox to give user options such as Bold, Italics, etc. export class TooltipTextMenu { @@ -213,8 +213,8 @@ export class TooltipTextMenu { let link = node && node.marks.find(m => m.type.name === "link"); if (link) { let href: string = link.attrs.href; - if (href.indexOf(DocServer.prepend("/doc/")) === 0) { - let docid = href.replace(DocServer.prepend("/doc/"), ""); + if (href.indexOf(Utils.prepend("/doc/")) === 0) { + let docid = href.replace(Utils.prepend("/doc/"), ""); DocServer.GetRefField(docid).then(action((f: Opt) => { if (f instanceof Doc) { if (DocumentManager.Instance.getDocumentView(f)) { @@ -254,7 +254,7 @@ export class TooltipTextMenu { if (docView && docView.props.ContainingCollectionView) { proto.sourceContext = docView.props.ContainingCollectionView.props.Document; } - linkDoc instanceof Doc && this.makeLink(DocServer.prepend("/doc/" + linkDoc[Id]), ctrlKey ? "onRight" : "inTab"); + linkDoc instanceof Doc && this.makeLink(Utils.prepend("/doc/" + linkDoc[Id]), ctrlKey ? "onRight" : "inTab"); }), }, hideSource: false diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index ce7369220..94a4835a1 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -16,7 +16,7 @@ import { listSpec } from '../../new_fields/Schema'; import { Cast, FieldValue, NumCast, BoolCast, StrCast } from '../../new_fields/Types'; import { CurrentUserUtils } from '../../server/authentication/models/current_user_utils'; import { RouteStore } from '../../server/RouteStore'; -import { emptyFunction, returnOne, returnTrue } from '../../Utils'; +import { emptyFunction, returnOne, returnTrue, Utils } from '../../Utils'; import { DocServer } from '../DocServer'; import { Docs } from '../documents/Documents'; import { SetupDrag } from '../util/DragManager'; @@ -433,7 +433,7 @@ export class MainView extends React.Component { return [ this.isSearchVisible ?
: null,
-
+
]; } diff --git a/src/client/views/SearchBox.tsx b/src/client/views/SearchBox.tsx index 1b9be841f..33cb63df5 100644 --- a/src/client/views/SearchBox.tsx +++ b/src/client/views/SearchBox.tsx @@ -13,6 +13,7 @@ import { Docs } from '../documents/Documents'; import { SetupDrag } from '../util/DragManager'; import { SearchItem } from './search/SearchItem'; import "./SearchBox.scss"; +import { Utils } from '../../Utils'; library.add(faSearch); library.add(faObjectGroup); @@ -47,7 +48,7 @@ export class SearchBox extends React.Component { @action getResults = async (query: string) => { - let response = await rp.get(DocServer.prepend('/search'), { + let response = await rp.get(Utils.prepend('/search'), { qs: { query } diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index a193ff677..ba7903419 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -465,7 +465,7 @@ export class CollectionDockingView extends React.Component boolean; @@ -164,7 +165,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T) { } else { let path = window.location.origin + "/doc/"; if (text.startsWith(path)) { - let docid = text.replace(DocServer.prepend("/doc/"), "").split("?")[0]; + let docid = text.replace(Utils.prepend("/doc/"), "").split("?")[0]; DocServer.GetRefField(docid).then(f => { if (f instanceof Doc) { if (options.x || options.y) { f.x = options.x; f.y = options.y; } // should be in CollectionFreeFormView @@ -193,7 +194,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T) { if (item.kind === "string" && item.type.indexOf("uri") !== -1) { let str: string; let prom = new Promise(resolve => e.dataTransfer.items[i].getAsString(resolve)) - .then(action((s: string) => rp.head(DocServer.prepend(RouteStore.corsProxy + "/" + (str = s))))) + .then(action((s: string) => rp.head(Utils.CorsProxy(str = s)))) .then(result => { let type = result["content-type"]; if (type) { @@ -219,7 +220,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T) { }).then(async (res: Response) => { (await res.json()).map(action((file: any) => { let full = { ...options, nativeWidth: type.indexOf("video") !== -1 ? 600 : 300, width: 300, title: dropFileName }; - let path = DocServer.prepend(file); + let path = Utils.prepend(file); Docs.Get.DocumentFromType(type, path, full).then(doc => doc && this.props.addDocument(doc)); })); }); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 245dd319d..af1cc079b 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -557,13 +557,13 @@ export class DocumentView extends DocComponent(Docu }); cm.addItem({ description: "Center View", event: () => this.props.focus(this.props.Document, false), icon: "crosshairs" }); cm.addItem({ description: "Zoom to Document", event: () => this.props.focus(this.props.Document, true), icon: "search" }); - cm.addItem({ description: "Copy URL", event: () => Utils.CopyText(DocServer.prepend("/doc/" + this.props.Document[Id])), icon: "link" }); + cm.addItem({ description: "Copy URL", event: () => Utils.CopyText(Utils.prepend("/doc/" + this.props.Document[Id])), icon: "link" }); cm.addItem({ description: "Copy ID", event: () => Utils.CopyText(this.props.Document[Id]), icon: "fingerprint" }); cm.addItem({ description: "Delete", event: this.deleteClicked, icon: "trash" }); type User = { email: string, userDocumentId: string }; let usersMenu: ContextMenuProps[] = []; try { - let stuff = await rp.get(DocServer.prepend(RouteStore.getUsers)); + let stuff = await rp.get(Utils.prepend(RouteStore.getUsers)); const users: User[] = JSON.parse(stuff); usersMenu = users.filter(({ email }) => email !== CurrentUserUtils.email).map(({ email, userDocumentId }) => ({ description: email, event: async () => { diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 066cc40e2..99801ecff 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -35,6 +35,7 @@ import "./FormattedTextBox.scss"; import React = require("react"); import { DateField } from '../../../new_fields/DateField'; import { thisExpression } from 'babel-types'; +import { Utils } from '../../../Utils'; library.add(faEdit); library.add(faSmile); @@ -311,8 +312,8 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe href = parent.childNodes[0].href ? parent.childNodes[0].href : parent.href; } if (href) { - if (href.indexOf(DocServer.prepend("/doc/")) === 0) { - this._linkClicked = href.replace(DocServer.prepend("/doc/"), "").split("?")[0]; + if (href.indexOf(Utils.prepend("/doc/")) === 0) { + this._linkClicked = href.replace(Utils.prepend("/doc/"), "").split("?")[0]; if (this._linkClicked) { DocServer.GetRefField(this._linkClicked).then(async linkDoc => { if (linkDoc instanceof Doc) { diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index ebe3732e6..4ffd265d7 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -165,12 +165,12 @@ export class ImageBox extends DocComponent(ImageD recorder.ondataavailable = async function (e: any) { const formData = new FormData(); formData.append("file", e.data); - const res = await fetch(DocServer.prepend(RouteStore.upload), { + const res = await fetch(Utils.prepend(RouteStore.upload), { method: 'POST', body: formData }); const files = await res.json(); - const url = DocServer.prepend(files[0]); + const url = Utils.prepend(files[0]); // upload to server with known URL let audioDoc = Docs.Create.AudioDocument(url, { title: "audio test", x: NumCast(self.props.Document.x), y: NumCast(self.props.Document.y), width: 200, height: 32 }); audioDoc.embed = true; @@ -327,7 +327,7 @@ export class ImageBox extends DocComponent(ImageD let id = (this.props as any).id; // bcz: used to set id = "isExpander" in templates.tsx let nativeWidth = FieldValue(this.Document.nativeWidth, pw); let nativeHeight = FieldValue(this.Document.nativeHeight, 0); - let paths: string[] = [window.origin + RouteStore.corsProxy + "/" + "http://www.cs.brown.edu/~bcz/noImage.png"]; + let paths: string[] = [Utils.CorsProxy("http://www.cs.brown.edu/~bcz/noImage.png")]; // this._curSuffix = ""; // if (w > 20) { Doc.UpdateDocumentExtensionForField(this.dataDoc, this.props.fieldKey); diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 8b8e500c4..0f2d18f6b 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -122,7 +122,7 @@ export class VideoBox extends DocComponent(VideoD public static async convertDataUri(imageUri: string, returnedFilename: string) { try { - let posting = DocServer.prepend(RouteStore.dataUriToImage); + let posting = Utils.prepend(RouteStore.dataUriToImage); const returnedUri = await rp.post(posting, { body: { uri: imageUri, @@ -164,7 +164,7 @@ export class VideoBox extends DocComponent(VideoD let filename = encodeURIComponent("snapshot" + this.props.Document.title + "_" + this.props.Document.curPage).replace(/\./g, ""); VideoBox.convertDataUri(dataUrl, filename).then(returnedFilename => { if (returnedFilename) { - let url = DocServer.prepend(returnedFilename); + let url = Utils.prepend(returnedFilename); let imageSummary = Docs.Create.ImageDocument(url, { x: NumCast(this.props.Document.x) + width, y: NumCast(this.props.Document.y), width: 150, height: height / width * 150, title: "--snapshot" + NumCast(this.props.Document.curPage) + " image-" diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 699a1ffd7..b7ded7e06 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -4,23 +4,18 @@ import * as Pdfjs from "pdfjs-dist"; import "pdfjs-dist/web/pdf_viewer.css"; import * as rp from "request-promise"; import { Dictionary } from "typescript-collections"; -import { Doc, DocListCast, HeightSym, Opt, WidthSym } from "../../../new_fields/Doc"; +import { Doc, DocListCast, Opt } from "../../../new_fields/Doc"; import { Id } from "../../../new_fields/FieldSymbols"; import { List } from "../../../new_fields/List"; -import { BoolCast, Cast, NumCast, StrCast, FieldValue } from "../../../new_fields/Types"; -import { emptyFunction } from "../../../Utils"; -import { DocServer } from "../../DocServer"; -import { Docs, DocUtils, DocumentOptions } from "../../documents/Documents"; -import { DocumentManager } from "../../util/DocumentManager"; +import { Cast, NumCast, StrCast } from "../../../new_fields/Types"; +import { emptyFunction, Utils } from "../../../Utils"; +import { Docs, DocUtils } from "../../documents/Documents"; import { DragManager } from "../../util/DragManager"; -import { DocumentView } from "../nodes/DocumentView"; -import { PDFBox, handleBackspace } from "../nodes/PDFBox"; +import { PDFBox } from "../nodes/PDFBox"; import Page from "./Page"; import "./PDFViewer.scss"; import React = require("react"); -import PDFMenu from "./PDFMenu"; -import { UndoManager } from "../../util/UndoManager"; -import { CompileScript, CompiledScript, CompileResult } from "../../util/Scripting"; +import { CompileScript, CompileResult } from "../../util/Scripting"; import { ScriptField } from "../../../new_fields/ScriptField"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import Annotation from "./Annotation"; @@ -90,16 +85,12 @@ export class Viewer extends React.Component { private _annotationReactionDisposer?: IReactionDisposer; private _dropDisposer?: DragManager.DragDropDisposer; private _filterReactionDisposer?: IReactionDisposer; - private _activeReactionDisposer?: IReactionDisposer; private _viewer: React.RefObject; private _mainCont: React.RefObject; private _pdfViewer: any; // private _textContent: Pdfjs.TextContent[] = []; private _pdfFindController: any; private _searchString: string = ""; - private _rendered: boolean = false; - private _pageIndex: number = -1; - private _matchIndex: number = 0; constructor(props: IViewerProps) { super(props); @@ -135,23 +126,6 @@ export class Viewer extends React.Component { }, { fireImmediately: true }); - this._activeReactionDisposer = reaction( - () => this.props.parent.props.active(), - () => { - runInAction(() => { - if (!this.props.parent.props.active()) { - this._searching = false; - this._pdfFindController = null; - if (this._viewer.current) { - let cns = this._viewer.current.childNodes; - for (let i = cns.length - 1; i >= 0; i--) { - cns.item(i).remove(); - } - } - } - }); - } - ); if (this.props.parent.props.ContainingCollectionView) { this._filterReactionDisposer = reaction( @@ -346,7 +320,7 @@ export class Viewer extends React.Component { this._isPage[page] = "image"; const address = this.props.url; try { - let res = JSON.parse(await rp.get(DocServer.prepend(`/thumbnail${address.substring("files/".length, address.length - ".pdf".length)}-${page + 1}.PNG`))); + let res = JSON.parse(await rp.get(Utils.prepend(`/thumbnail${address.substring("files/".length, address.length - ".pdf".length)}-${page + 1}.PNG`))); runInAction(() => this._visibleElements[page] = ); @@ -476,7 +450,6 @@ export class Viewer extends React.Component { phraseSearch: true, query: searchString }); - this._rendered = true; }); container.addEventListener("pagerendered", () => { console.log("rendered"); @@ -488,7 +461,6 @@ export class Viewer extends React.Component { phraseSearch: true, query: searchString }); - this._rendered = true; }); } } @@ -563,7 +535,6 @@ export class Viewer extends React.Component { }); container.addEventListener("pagerendered", () => { console.log("rendered"); - this._rendered = true; }); this._pdfViewer.setDocument(this.props.pdf); this._pdfFindController = new PDFJSViewer.PDFFindController(this._pdfViewer); @@ -703,17 +674,17 @@ class SimpleLinkService { externalLinkRel: any = null; pdf: any = null; - navigateTo(dest: any) { } + navigateTo() { } - getDestinationHash(dest: any) { return "#"; } + getDestinationHash() { return "#"; } - getAnchorUrl(hash: any) { return "#"; } + getAnchorUrl() { return "#"; } - setHash(hash: any) { } + setHash() { } - executeNamedAction(action: any) { } + executeNamedAction() { } - cachePageRef(pageNum: any, pageRef: any) { } + cachePageRef() { } get pagesCount() { return this.pdf ? this.pdf.numPages : 0; diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 16c44225a..2214ac8af 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -9,12 +9,12 @@ import { Docs } from '../../documents/Documents'; import { NumCast, Cast } from '../../../new_fields/Types'; import { Doc } from '../../../new_fields/Doc'; import { SearchItem } from './SearchItem'; -import { DocServer } from '../../DocServer'; import * as rp from 'request-promise'; import { Id } from '../../../new_fields/FieldSymbols'; import { SearchUtil } from '../../util/SearchUtil'; import { RouteStore } from '../../../server/RouteStore'; import { FilterBox } from './FilterBox'; +import { Utils } from '../../../Utils'; @observer @@ -74,7 +74,7 @@ export class SearchBox extends React.Component { public static async convertDataUri(imageUri: string, returnedFilename: string) { try { - let posting = DocServer.prepend(RouteStore.dataUriToImage); + let posting = Utils.prepend(RouteStore.dataUriToImage); const returnedUri = await rp.post(posting, { body: { uri: imageUri, @@ -154,7 +154,7 @@ export class SearchBox extends React.Component { filteredDocs.forEach(doc => { const index = this._resultsSet.get(doc); const highlight = highlights[doc[Id]]; - const hlights = highlight ? Object.keys(highlight).map(key => key.substring(0, key.length - 2)) : [] + const hlights = highlight ? Object.keys(highlight).map(key => key.substring(0, key.length - 2)) : []; if (index === undefined) { this._resultsSet.set(doc, this._results.length); this._results.push([doc, hlights]); diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx index a8f94b746..33a615cbf 100644 --- a/src/mobile/ImageUpload.tsx +++ b/src/mobile/ImageUpload.tsx @@ -11,6 +11,7 @@ import { listSpec } from '../new_fields/Schema'; import { List } from '../new_fields/List'; import { observer } from 'mobx-react'; import { observable } from 'mobx'; +import { Utils } from '../Utils'; @@ -57,7 +58,7 @@ class Uploader extends React.Component { this.status = "getting user document"; - const res = await rp.get(DocServer.prepend(RouteStore.getUserDocumentId)); + const res = await rp.get(Utils.prepend(RouteStore.getUserDocumentId)); if (!res) { throw new Error("No user id returned"); } @@ -104,6 +105,8 @@ class Uploader extends React.Component { } +DocServer.init(window.location.protocol, window.location.hostname, 4321, "image upload"); + ReactDOM.render(( ), diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index e796ccb43..1c52a3f11 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -12,6 +12,7 @@ import { List } from "../../../new_fields/List"; import { listSpec } from "../../../new_fields/Schema"; import { Cast, FieldValue, StrCast } from "../../../new_fields/Types"; import { RouteStore } from "../../RouteStore"; +import { Utils } from "../../../Utils"; export class CurrentUserUtils { private static curr_email: string; @@ -74,7 +75,7 @@ export class CurrentUserUtils { } public static loadCurrentUser() { - return rp.get(DocServer.prepend(RouteStore.getCurrUser)).then(response => { + return rp.get(Utils.prepend(RouteStore.getCurrUser)).then(response => { if (response) { const result: { id: string, email: string } = JSON.parse(response); return result; @@ -87,7 +88,7 @@ export class CurrentUserUtils { public static async loadUserDocument({ id, email }: { id: string, email: string }) { this.curr_id = id; this.curr_email = email; - await rp.get(DocServer.prepend(RouteStore.getUserDocumentId)).then(id => { + await rp.get(Utils.prepend(RouteStore.getUserDocumentId)).then(id => { if (id) { return DocServer.GetRefField(id).then(async field => { if (field instanceof Doc) { diff --git a/src/server/index.ts b/src/server/index.ts index b3859aa4f..6b4e59bfc 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -417,7 +417,7 @@ app.get(RouteStore.reset, getReset); app.post(RouteStore.reset, postReset); app.use(RouteStore.corsProxy, (req, res) => - req.pipe(request(req.url.substring(1))).pipe(res)); + req.pipe(request(decodeURIComponent(req.url.substring(1)))).pipe(res)); app.get(RouteStore.delete, (req, res) => { if (release) { -- cgit v1.2.3-70-g09d2