@@ -26,18 +26,20 @@ import { SearchWritingResultsSkeleton } from "./SearchWritingResultsSkeleton.js"
2626import { SearchHorizontalDivider } from "./SearchHorizontalDivider.js"
2727import { useSearchContext } from "./SearchContext.js"
2828
29- type PageHit = TopicPageHit | ProfileHit
29+ type TopicOrProfileHit = TopicPageHit | ProfileHit
3030
31- function isPageHit ( hit : FlatArticleHit | PageHit ) : hit is PageHit {
31+ function isTopicOrProfileHit (
32+ hit : FlatArticleHit | TopicOrProfileHit
33+ ) : hit is TopicOrProfileHit {
3234 return (
3335 hit . type === OwidGdocType . TopicPage ||
3436 hit . type === OwidGdocType . LinearTopicPage ||
3537 hit . type === OwidGdocType . Profile
3638 )
3739}
3840
39- function renderPageHit (
40- hit : PageHit ,
41+ function renderTopicOrProfileHit (
42+ hit : TopicOrProfileHit ,
4143 index : number ,
4244 hasLargeTopic : boolean ,
4345 analytics : ReturnType < typeof useSearchContext > [ "analytics" ]
@@ -84,7 +86,7 @@ function SingleColumnResults({
8486} ) {
8587 const { analytics } = useSearchContext ( )
8688
87- const allHits : ( FlatArticleHit | PageHit ) [ ] = [
89+ const allHits : ( FlatArticleHit | TopicOrProfileHit ) [ ] = [
8890 ...profiles ,
8991 ..._ . zip ( articlePages , topicPages ) . flatMap (
9092 ( [ articlePage , topicPage ] ) => [
@@ -96,8 +98,13 @@ function SingleColumnResults({
9698 return (
9799 < div className = "search-writing-results__single-column" >
98100 { allHits . map ( ( hit , index ) => {
99- if ( isPageHit ( hit ) ) {
100- return renderPageHit ( hit , index , hasLargeTopic , analytics )
101+ if ( isTopicOrProfileHit ( hit ) ) {
102+ return renderTopicOrProfileHit (
103+ hit ,
104+ index ,
105+ hasLargeTopic ,
106+ analytics
107+ )
101108 } else {
102109 return (
103110 < SearchFlatArticleHit
@@ -131,13 +138,17 @@ function MultiColumnResults({
131138 const { analytics } = useSearchContext ( )
132139
133140 // Profiles appear before topic pages in the tiles
134- const allPageHits : PageHit [ ] = [ ...profiles , ...topics ]
141+ const allTopicOrProfileHits : TopicOrProfileHit [ ] = [ ...profiles , ...topics ]
135142
136143 // Calculate interleaved layout: 4 topics for every 5 articles (ratio
137144 // maintained proportionally).
138145 const interleavedCount = Math . round ( ( articles . length * 4 ) / 5 )
139- const interleavedPageHits = allPageHits . slice ( 0 , interleavedCount )
140- const remainingPageHits = allPageHits . slice ( interleavedCount )
146+ const interleavedTopicOrProfileHits = allTopicOrProfileHits . slice (
147+ 0 ,
148+ interleavedCount
149+ )
150+ const remainingTopicOrProfileHits =
151+ allTopicOrProfileHits . slice ( interleavedCount )
141152 return (
142153 < div className = "search-writing-results__grid" >
143154 { articles . length > 0 && (
@@ -156,19 +167,24 @@ function MultiColumnResults({
156167 ) ) }
157168 </ div >
158169 ) }
159- { interleavedPageHits . length > 0 && (
170+ { interleavedTopicOrProfileHits . length > 0 && (
160171 < div className = "search-writing-results__topics" >
161- { interleavedPageHits . map ( ( hit , index ) =>
162- renderPageHit ( hit , index , hasLargeTopic , analytics )
172+ { interleavedTopicOrProfileHits . map ( ( hit , index ) =>
173+ renderTopicOrProfileHit (
174+ hit ,
175+ index ,
176+ hasLargeTopic ,
177+ analytics
178+ )
163179 ) }
164180 </ div >
165181 ) }
166- { remainingPageHits . length > 0 && (
182+ { remainingTopicOrProfileHits . length > 0 && (
167183 < div className = "search-writing-results__overflow" >
168- { remainingPageHits . map ( ( hit , index ) =>
169- renderPageHit (
184+ { remainingTopicOrProfileHits . map ( ( hit , index ) =>
185+ renderTopicOrProfileHit (
170186 hit ,
171- interleavedPageHits . length + index ,
187+ interleavedTopicOrProfileHits . length + index ,
172188 hasLargeTopic ,
173189 analytics
174190 )
@@ -196,11 +212,13 @@ export const SearchWritingResults = ({
196212 queryFn : ( liteSearchClient , state , offset , length ) => {
197213 return queryProfiles ( liteSearchClient , state , offset , length )
198214 } ,
199- firstPageSize : 4 ,
215+ firstPageSize : 2 ,
200216 laterPageSize : 4 ,
201217 enabled : showProfiles ,
202218 } )
203219
220+ const profileSlots = Math . min ( profilesQuery . totalResults , 2 )
221+
204222 const articlesQuery = useInfiniteSearchOffset <
205223 SearchFlatArticleResponse ,
206224 FlatArticleHit
@@ -209,11 +227,16 @@ export const SearchWritingResults = ({
209227 queryFn : ( liteSearchClient , state , offset , length ) => {
210228 return queryArticles ( liteSearchClient , state , offset , length )
211229 } ,
212- firstPageSize : 2 ,
230+ firstPageSize : 4 - profileSlots ,
213231 laterPageSize : 6 ,
214232 } )
215233
216234 const noArticles = articlesQuery . totalResults === 0
235+ const articleSlots = Math . min ( articlesQuery . totalResults , 4 - profileSlots )
236+ const topicFirstPageSize = 6 - profileSlots - articleSlots
237+
238+ const dependenciesLoaded =
239+ ! articlesQuery . isLoading && ( ! showProfiles || ! profilesQuery . isLoading )
217240
218241 const topicsQuery = useInfiniteSearchOffset <
219242 SearchTopicPageResponse ,
@@ -223,9 +246,9 @@ export const SearchWritingResults = ({
223246 queryFn : ( liteSearchClient , state , offset , length ) => {
224247 return queryTopicPages ( liteSearchClient , state , offset , length )
225248 } ,
226- firstPageSize : noArticles ? 6 : 2 ,
249+ firstPageSize : topicFirstPageSize ,
227250 laterPageSize : noArticles ? 6 : 4 ,
228- enabled : hasTopicPages && ! articlesQuery . isLoading ,
251+ enabled : hasTopicPages && dependenciesLoaded ,
229252 } )
230253
231254 const hasLargeTopic = topicsQuery . totalResults === 1
0 commit comments