11import { downloadQuestionsAsText , downloadBonusesAsCSV , downloadTossupsAsCSV , downloadQuestionsAsJSON } from './download.js' ;
2-
32import api from '../scripts/api/index.js' ;
43import star from '../scripts/auth/star.js' ;
54import TossupCard from '../scripts/components/TossupCard.min.js' ;
65import BonusCard from '../scripts/components/BonusCard.min.js' ;
76import CategoryModal from '../scripts/components/CategoryModal.min.js' ;
87import DifficultyDropdown from '../scripts/components/DifficultyDropdown.min.js' ;
98import Star from '../scripts/components/Star.min.js' ;
10- import CategoryManager from '../../quizbowl/category-manager.js' ;
119import { getDropdownValues } from '../scripts/utilities/dropdown-checklist.js' ;
10+ import CategoryManager from '../../quizbowl/category-manager.js' ;
1211import insertTokensIntoHTML from '../../quizbowl/insert-tokens-into-html.js' ;
1312
1413const starredTossupIds = new Set ( await star . getStarredTossupIds ( ) ) ;
1514const starredBonusIds = new Set ( await star . getStarredBonusIds ( ) ) ;
1615
16+ const fontSize = window . localStorage . getItem ( 'database-font-size' ) === 'true' ? ( window . localStorage . getItem ( 'font-size' ) ?? 16 ) : 16 ;
1717const paginationShiftLength = window . screen . width > 992 ? 10 : 5 ;
1818
1919const categoryManager = new CategoryManager ( ) ;
2020
21+ function arrayBetween ( start , end ) {
22+ return Array ( end - start ) . fill ( ) . map ( ( _ , idx ) => start + idx ) ;
23+ }
24+
2125function getMatchIndices ( clean , regex ) {
2226 const iterator = clean . matchAll ( regex ) ;
2327 const starts = [ ] ;
@@ -89,18 +93,22 @@ function QueryForm () {
8993 const [ tossupCount , setTossupCount ] = React . useState ( 0 ) ;
9094 const [ bonusCount , setBonusCount ] = React . useState ( 0 ) ;
9195
92- const [ maxReturnLength , setMaxReturnLength ] = React . useState ( '' ) ;
93- const [ queryString , setQueryString ] = React . useState ( '' ) ;
94- const [ questionType , setQuestionType ] = React . useState ( 'all' ) ;
95- const [ searchType , setSearchType ] = React . useState ( 'all' ) ;
96- const [ minYear , setMinYear ] = React . useState ( '' ) ;
97- const [ maxYear , setMaxYear ] = React . useState ( '' ) ;
98-
99- const [ regex , setRegex ] = React . useState ( false ) ;
100- const [ ignoreWordOrder , setIgnoreWordOrder ] = React . useState ( false ) ;
101- const [ exactPhrase , setExactPhrase ] = React . useState ( false ) ;
102- const [ caseSensitive , setCaseSensitive ] = React . useState ( false ) ;
103- const [ powermarkOnly , setPowermarkOnly ] = React . useState ( false ) ;
96+ // query form
97+ const initialParams = new window . URLSearchParams ( window . location . search ) ;
98+ const [ queryString , setQueryString ] = React . useState ( initialParams . get ( 'queryString' ) ?? '' ) ;
99+ const [ maxReturnLength , setMaxReturnLength ] = React . useState ( initialParams . get ( 'maxReturnLength' ) ?? '' ) ;
100+ const [ setName , setSetName ] = React . useState ( initialParams . get ( 'setName' ) ?? '' ) ;
101+ const [ searchType , setSearchType ] = React . useState ( initialParams . get ( 'searchType' ) ?? 'all' ) ;
102+ const [ questionType , setQuestionType ] = React . useState ( initialParams . get ( 'questionType' ) ?? 'all' ) ;
103+ const [ minYear , setMinYear ] = React . useState ( initialParams . get ( 'minYear' ) ?? '' ) ;
104+ const [ maxYear , setMaxYear ] = React . useState ( initialParams . get ( 'maxYear' ) ?? '' ) ;
105+
106+ // toggleable options
107+ const [ regex , setRegex ] = React . useState ( initialParams . get ( 'regex' ) === 'true' ) ;
108+ const [ ignoreWordOrder , setIgnoreWordOrder ] = React . useState ( initialParams . get ( 'ignoreWordOrder' ) === 'true' ) ;
109+ const [ exactPhrase , setExactPhrase ] = React . useState ( initialParams . get ( 'exactPhrase' ) === 'true' ) ;
110+ const [ caseSensitive , setCaseSensitive ] = React . useState ( initialParams . get ( 'caseSensitive' ) === 'true' ) ;
111+ const [ powermarkOnly , setPowermarkOnly ] = React . useState ( initialParams . get ( 'powermarkOnly' ) === 'true' ) ;
104112 const [ hideAnswerlines , setHideAnswerlines ] = React . useState ( false ) ;
105113 const [ hideCardFooters , setHideCardFooters ] = React . useState ( false ) ;
106114
@@ -110,87 +118,67 @@ function QueryForm () {
110118 let [ bonusPaginationNumber , setBonusPaginationNumber ] = React . useState ( 1 ) ;
111119 const [ tossupPaginationLength , setTossupPaginationLength ] = React . useState ( 1 ) ;
112120 const [ bonusPaginationLength , setBonusPaginationLength ] = React . useState ( 1 ) ;
121+ // paginationShift is one less than the first pagination number selectable
122+ // so if the options are 11, 12, ..., 19, 20, then paginationShift=10
123+ // if the options are 86, 87, ..., 89, 90, then paginationShift=85
113124 const [ tossupPaginationShift , setTossupPaginationShift ] = React . useState ( 0 ) ;
114125 const [ bonusPaginationShift , setBonusPaginationShift ] = React . useState ( 0 ) ;
115126
116127 const [ queryTime , setQueryTime ] = React . useState ( 0 ) ;
117128
118- const fontSize = window . localStorage . getItem ( 'database-font-size' ) === 'true' ? ( window . localStorage . getItem ( 'font-size' ) ?? 16 ) : 16 ;
119-
120- function arrayBetween ( start , end ) {
121- return Array ( end - start ) . fill ( ) . map ( ( _ , idx ) => start + idx ) ;
122- }
123-
124129 function getMaxPagination ( ) {
125130 return Math . floor ( 10000 / ( maxReturnLength || 25 ) ) ;
126131 }
127132
128- function handleTossupPaginationClick ( event , value ) {
133+ /**
134+ *
135+ * @param {"tossup" | "bonus" } type - The type of question to handle pagination for.
136+ */
137+ function handlePaginationClick ( event , value , type ) {
129138 event . preventDefault ( ) ;
130-
131- switch ( value ) {
132- case 'first' :
133- tossupPaginationNumber = 1 ;
134- break ;
135- case 'previous' :
136- tossupPaginationNumber = Math . max ( 1 , tossupPaginationNumber - 1 ) ;
137- break ;
138- case 'next' :
139- tossupPaginationNumber = Math . min ( tossupPaginationLength , tossupPaginationNumber + 1 , getMaxPagination ( ) ) ;
140- break ;
141- case 'last' :
142- tossupPaginationNumber = Math . min ( tossupPaginationLength , getMaxPagination ( ) ) ;
143- break ;
144- default :
145- tossupPaginationNumber = value ;
146- break ;
139+ let paginationNumber = type === 'tossup' ? tossupPaginationNumber : bonusPaginationNumber ;
140+ const valueToNumber = {
141+ first : 1 ,
142+ previous : Math . max ( 1 , paginationNumber - 1 ) ,
143+ next : Math . min ( type === 'tossup' ? tossupPaginationLength : bonusPaginationLength , paginationNumber + 1 , getMaxPagination ( ) ) ,
144+ last : Math . min ( type === 'tossup' ? tossupPaginationLength : bonusPaginationLength , getMaxPagination ( ) )
145+ } ;
146+ if ( value in valueToNumber ) {
147+ paginationNumber = valueToNumber [ value ] ;
148+ } else {
149+ paginationNumber = value ;
147150 }
148151
149- setTossupPaginationNumber ( tossupPaginationNumber ) ;
150- setTossupPaginationShift ( paginationShiftLength * Math . floor ( ( tossupPaginationNumber - 1 ) / paginationShiftLength ) ) ;
152+ const paginationShift = paginationShiftLength * Math . floor ( ( paginationNumber - 1 ) / paginationShiftLength ) ;
153+ if ( type === 'tossup' ) {
154+ tossupPaginationNumber = paginationNumber ;
155+ setTossupPaginationNumber ( paginationNumber ) ;
156+ setTossupPaginationShift ( paginationShift ) ;
157+ } else {
158+ bonusPaginationNumber = paginationNumber ;
159+ setBonusPaginationNumber ( paginationNumber ) ;
160+ setBonusPaginationShift ( paginationShift ) ;
161+ }
151162 handleSubmit ( event , false , true ) ;
152163
153164 window . scrollTo ( {
154- top : document . getElementById ( ' tossups') . offsetTop - 100 ,
165+ top : document . getElementById ( type === 'tossup' ? ' tossups' : 'bonuses ') . offsetTop - 100 ,
155166 behavior : 'smooth'
156167 } ) ;
157168 }
158169
159- function handleBonusPaginationClick ( event , value ) {
160- event . preventDefault ( ) ;
161-
162- switch ( value ) {
163- case 'first' :
164- bonusPaginationNumber = 1 ;
165- break ;
166- case 'previous' :
167- bonusPaginationNumber = Math . max ( 1 , bonusPaginationNumber - 1 ) ;
168- break ;
169- case 'next' :
170- bonusPaginationNumber = Math . min ( bonusPaginationLength , bonusPaginationNumber + 1 , getMaxPagination ( ) ) ;
171- break ;
172- case 'last' :
173- bonusPaginationNumber = Math . min ( bonusPaginationLength , getMaxPagination ( ) ) ;
174- break ;
175- default :
176- bonusPaginationNumber = value ;
177- break ;
178- }
179-
180- setBonusPaginationNumber ( bonusPaginationNumber ) ;
181- setBonusPaginationShift ( paginationShiftLength * Math . floor ( ( bonusPaginationNumber - 1 ) / paginationShiftLength ) ) ;
182- handleSubmit ( event , false , true ) ;
170+ function handleTossupPaginationClick ( event , value ) {
171+ return handlePaginationClick ( event , value , 'tossup' ) ;
172+ }
183173
184- window . scrollTo ( {
185- top : document . getElementById ( 'bonuses' ) . offsetTop - 100 ,
186- behavior : 'smooth'
187- } ) ;
174+ function handleBonusPaginationClick ( event , value ) {
175+ return handlePaginationClick ( event , value , 'bonus' ) ;
188176 }
189177
190- function handleSubmit ( event , randomize = false , paginationUpdate = false ) {
191- const startTime = performance . now ( ) ;
178+ function handleSubmit ( event = null , randomize = false , paginationUpdate = false ) {
179+ const startTime = window . performance . now ( ) ;
192180
193- event . preventDefault ( ) ;
181+ event ? .preventDefault ( ) ;
194182 setCurrentlySearching ( true ) ;
195183
196184 if ( randomize || ! paginationUpdate ) {
@@ -213,7 +201,7 @@ function QueryForm () {
213201 regex,
214202 ignoreWordOrder,
215203 searchType,
216- setName : document . getElementById ( 'set-name' ) . value ,
204+ setName,
217205 tossupPagination : tossupPaginationNumber === 1 ? '' : tossupPaginationNumber ,
218206 bonusPagination : bonusPaginationNumber === 1 ? '' : bonusPaginationNumber ,
219207 minYear,
@@ -233,7 +221,7 @@ function QueryForm () {
233221 } )
234222 ) ;
235223
236- const params = new URLSearchParams ( filteredParams ) ;
224+ const params = new window . URLSearchParams ( filteredParams ) ;
237225
238226 fetch ( `/api/query?${ params } ` )
239227 . then ( response => {
@@ -284,7 +272,7 @@ function QueryForm () {
284272 setTossupPaginationShift ( paginationShiftLength * Math . floor ( ( tossupPaginationNumber - 1 ) / paginationShiftLength ) ) ;
285273 setBonusPaginationShift ( paginationShiftLength * Math . floor ( ( bonusPaginationNumber - 1 ) / paginationShiftLength ) ) ;
286274
287- const endTime = performance . now ( ) ;
275+ const endTime = window . performance . now ( ) ;
288276 const timeElapsed = ( ( endTime - startTime ) / 1000 ) . toFixed ( 2 ) ;
289277 setQueryTime ( timeElapsed ) ;
290278
@@ -316,14 +304,6 @@ function QueryForm () {
316304 }
317305
318306 React . useEffect ( ( ) => {
319- document . getElementById ( 'report-question-submit' ) . addEventListener ( 'click' , function ( ) {
320- api . reportQuestion (
321- document . getElementById ( 'report-question-id' ) . value ,
322- document . getElementById ( 'report-question-reason' ) . value ,
323- document . getElementById ( 'report-question-description' ) . value
324- ) ;
325- } ) ;
326-
327307 window . addEventListener ( 'popstate' , event => {
328308 if ( event . state === null ) {
329309 setTossupCount ( 0 ) ;
@@ -370,6 +350,8 @@ function QueryForm () {
370350 } ) ;
371351
372352 document . getElementById ( 'set-list' ) . innerHTML = api . getSetList ( ) . map ( setName => `<option>${ setName } </option>` ) . join ( '' ) ;
353+
354+ if ( window . location . search !== '' ) { handleSubmit ( ) ; }
373355 } , [ ] ) ;
374356
375357 return (
@@ -389,7 +371,7 @@ function QueryForm () {
389371 < input type = 'number' className = 'form-control' id = 'max-return-length' placeholder = '# to Display' value = { maxReturnLength } onChange = { event => { setMaxReturnLength ( event . target . value ) ; } } />
390372 </ div >
391373 < div className = 'input-group col-12 col-xl-6 mb-2' >
392- < input type = 'text' className = 'form-control' id = 'set-name' placeholder = 'Set Name' list = 'set-list' />
374+ < input type = 'text' className = 'form-control' id = 'set-name' placeholder = 'Set Name' list = 'set-list' value = { setName } onChange = { event => { setSetName ( event . target . value ) ; } } />
393375 < datalist id = 'set-list' />
394376 < button type = 'button' className = 'btn btn-danger' id = 'category-select-button' data-bs-toggle = 'modal' data-bs-target = '#category-modal' > Categories</ button >
395377 </ div >
@@ -582,3 +564,11 @@ function QueryForm () {
582564
583565const root = ReactDOM . createRoot ( document . getElementById ( 'root' ) ) ;
584566root . render ( < QueryForm /> ) ;
567+
568+ document . getElementById ( 'report-question-submit' ) . addEventListener ( 'click' , function ( ) {
569+ api . reportQuestion (
570+ document . getElementById ( 'report-question-id' ) . value ,
571+ document . getElementById ( 'report-question-reason' ) . value ,
572+ document . getElementById ( 'report-question-description' ) . value
573+ ) ;
574+ } ) ;
0 commit comments