Skip to content

Commit

Permalink
FW-6329, FW-6336 replace loading with loadorerror part 1 (#722)
Browse files Browse the repository at this point in the history
* Switch CategoriesBrowser and include parentTitle in search

* Switch CharacterCrud

* Switch CategoryCrud

* Remove need for Loading in DashboardContainer

* Make Dashboard FV logo a link

* Switch Languages

* Switch DashboardEntries

* Switch DashboardGalleries

* Reduce duplication in infinite scroll hooks

* Switch DashboardJoinList

* Access infinite scroll props directly

* Pass whole response in Dictionary and Search

* Switch DictionaryList and DictionaryGrid

* Switch Galleries

* Switch Parachute

* Switch PhraseScrambler

* Switch Wordsy

* Switch Immersion

* Switch SongsAndStories

* Switch WidgetWOTD

* Opting for a more discreet error message for WOTD

* Switch WidgetBrowser

* FW-6336 Fix video thumbnails in Selector and remove inconsistent thumbnail property

* Remove some renaming of query return properties
  • Loading branch information
gmcauliffe authored Dec 13, 2024
1 parent 99e3c46 commit e33a4e8
Show file tree
Hide file tree
Showing 81 changed files with 874 additions and 1,289 deletions.
1 change: 0 additions & 1 deletion src/common/dataAdaptors/mediaAdaptors.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export const mediaSearchAdaptor = ({ type, data }) => {
downloadLink: data?.original?.path || '',
height: data?.original?.height,
width: data?.original?.width,
thumbnail: data?.small?.path,
}
default:
return { ...data, message: 'NOT a media document' }
Expand Down
18 changes: 1 addition & 17 deletions src/common/dataAdaptors/searchResponseAdaptors.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,7 @@ import { storySummaryAdaptor } from 'common/dataAdaptors/storyAdaptors'
import { songSummaryAdaptor } from 'common/dataAdaptors/songAdaptors'
import { mediaSearchAdaptor } from 'common/dataAdaptors/mediaAdaptors'

export function searchResponseAdaptor(response) {
return pagesDataAdaptor(response.pages)
}

const pagesDataAdaptor = (pages) =>
pages.map((page, index) => singlePageDataAdaptor(page, index))

const singlePageDataAdaptor = (page, index) => {
const formattedEntries = page?.results?.map((result) => resultAdaptor(result))
return {
...page,
pageNumber: index + 1,
results: formattedEntries,
}
}

const resultAdaptor = (result) => {
export function searchResultAdaptor(result) {
const baseObject = {
id: result?.entry?.id,
title: result?.entry?.title,
Expand Down
56 changes: 55 additions & 1 deletion src/common/dataHooks/useGamesSearch.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ import {
GAMES,
SORT,
HAS_UNRECOGNIZED_CHARS,
TYPE_PHRASE,
MINWORDS,
WORDSY,
} from 'common/constants'
import { getOrthographyPattern } from 'components/Game/Wordsy/Utils/helpers'

export function useParachuteSearch({ perPage, kids }) {
const { sitename } = useParams()
Expand Down Expand Up @@ -42,7 +46,6 @@ export function useParachuteSearch({ perPage, kids }) {
searchParams: searchParamString,
perPage,
}),
...{ enabled: !!sitename },
})

const getPuzzles = () => {
Expand Down Expand Up @@ -76,3 +79,54 @@ export function useParachuteSearch({ perPage, kids }) {
puzzles: getPuzzles(),
}
}

export function usePhraseScramblerSearch({ kids }) {
const { sitename } = useParams()
const _searchParams = new URLSearchParams({
[TYPES]: TYPE_PHRASE,
[GAMES]: true,
[HAS_TRANSLATION]: true,
[SORT]: 'random',
[MINWORDS]: 2,
})
if (kids) {
_searchParams.append(KIDS, kids)
}

const queryResponse = useQuery({
queryKey: [SEARCH, sitename],
queryFn: () =>
api.search.get({
sitename,
searchParams: _searchParams.toString(),
pageParam: 1,
perPage: 1, // Fetching one phrase at a time
}),
})
return queryResponse
}

export function useWordsySearch({ kids }) {
const { sitename } = useParams()
const _searchParams = new URLSearchParams()
if (kids) {
_searchParams.append(KIDS, kids)
}

const queryResponse = useQuery({
queryKey: [WORDSY, sitename],
queryFn: () =>
api.gameContent.getWordsyConfig({
sitename,
searchParams: _searchParams.toString(),
}),
})

const languageConfig = {
orthography: queryResponse?.data?.orthography,
orthographyPattern: getOrthographyPattern(queryResponse?.data?.orthography),
words: queryResponse?.data?.words,
validGuesses: queryResponse?.data?.validGuesses,
}
return { ...queryResponse, languageConfig }
}
24 changes: 19 additions & 5 deletions src/common/dataHooks/useInfiniteScroll.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ import { useInfiniteQuery } from '@tanstack/react-query'

// FPCC
import useIntersectionObserver from 'common/hooks/useIntersectionObserver'
import { useSiteStore } from 'context/SiteContext'

/**
* Calls API and provides results and infinite scroll info.
*/
function useInfiniteScroll({ queryKey, queryFn, resultAdaptor }) {
const { site } = useSiteStore()

function useInfiniteScroll({
queryKey,
queryFn,
enabled = true,
resultAdaptor,
}) {
const pagesDataAdaptor = (pages) =>
pages.map((page, index) => singlePageDataAdaptor(page, index))

Expand All @@ -29,18 +31,29 @@ function useInfiniteScroll({ queryKey, queryFn, resultAdaptor }) {
const response = useInfiniteQuery({
queryKey,
queryFn,
enabled: !!site?.sitename,
enabled,
getNextPageParam: (currentPage) => currentPage.next,
select: (responseData) => ({
pages: pagesDataAdaptor(responseData.pages),
pageParams: responseData.pageParams,
}),
})

const getLoadLabel = () => {
if (response?.isFetchingNextPage) {
return 'Loading more...'
}
if (response?.hasNextPage) {
return 'Load more'
}
return 'End of results.'
}

const infiniteScroll = {
fetchNextPage: response?.fetchNextPage,
hasNextPage: response?.hasNextPage,
isFetchingNextPage: response?.isFetchingNextPage,
loadLabel: getLoadLabel(),
}

const loadRef = useRef(null)
Expand All @@ -53,6 +66,7 @@ function useInfiniteScroll({ queryKey, queryFn, resultAdaptor }) {
return {
...response,
infiniteScroll,
loadLabel: getLoadLabel(),
loadRef,
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/common/dataHooks/useJoinRequests.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { useSiteStore } from 'context/SiteContext'
export function useJoinRequests() {
const { site } = useSiteStore()

const response = useInfiniteScroll({
const infiniteQueryResponse = useInfiniteScroll({
queryKey: [JOIN_REQUESTS, site?.sitename],
queryFn: ({ pageParam = 1 }) =>
api.joinRequests.getAll({
Expand All @@ -20,7 +20,7 @@ export function useJoinRequests() {
}),
})

return response
return infiniteQueryResponse
}

export function useJoinRequestCreate(options = {}) {
Expand Down
14 changes: 5 additions & 9 deletions src/common/dataHooks/useMediaSearch.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ function useMediaSearch({ type, searchSharedMedia }) {
enabled: searchSharedMedia,
})

const response = searchSharedMedia
const infiniteQueryResponse = searchSharedMedia
? sharedMediaSearchResponse
: siteSearchResponse

Expand All @@ -67,21 +67,17 @@ function useMediaSearch({ type, searchSharedMedia }) {
}

useEffect(() => {
if (!currentFile && response?.data?.pages?.[0]?.results) {
const firstFile = response?.data?.pages?.[0]?.results?.[0]
if (!currentFile && infiniteQueryResponse?.data?.pages?.[0]?.results) {
const firstFile = infiniteQueryResponse?.data?.pages?.[0]?.results?.[0]
setCurrentFile(firstFile)
}
}, [currentFile, response?.data, type])
}, [currentFile, infiniteQueryResponse?.data, type])

return {
...infiniteQueryResponse,
handleSearchSubmit,
handleSearchSubmitWithUrlSync,
handleTextFieldChange,
infiniteScroll: response?.infiniteScroll,
isLoadingEntries: response?.isLoading,
loadLabel: response?.infiniteScroll?.loadLabel,
loadRef: response?.loadRef,
media: response?.data,
searchValue: searchInputValue,
currentFile,
setCurrentFile,
Expand Down
27 changes: 5 additions & 22 deletions src/common/dataHooks/useSearchAllSitesLoader.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,26 @@
import { useInfiniteQuery } from '@tanstack/react-query'
import PropTypes from 'prop-types'

// FPCC
import useLoader from 'common/hooks/useLoader'
import useInfiniteScroll from 'common/dataHooks/useInfiniteScroll'
import api from 'services/api'
import { SEARCH } from 'common/constants'
import { searchResponseAdaptor } from 'common/dataAdaptors'
import { searchResultAdaptor } from 'common/dataAdaptors'

/**
* Calls search API and provides search results and infinite scroll info.
*/
function useSearchAllSitesLoader({ enabled, searchParams }) {
const searchParamString = searchParams.toString()

// Fetch search results
const response = useInfiniteQuery({
const infiniteQueryResponse = useInfiniteScroll({
queryKey: [SEARCH, 'cross-site', searchParamString],
queryFn: ({ pageParam = 1 }) =>
api.search.getFVWideSearch({
searchParams: searchParamString,
pageParam,
}),
getNextPageParam: (currentPage) => currentPage.next,
enabled: !!enabled,
refetchOnWindowFocus: false,
refetchOnReconnect: false,
select: (responseData) => ({
pages: searchResponseAdaptor(responseData),
pageParams: responseData.pageParams,
}),
resultAdaptor: searchResultAdaptor,
})

const { infiniteScroll, loadRef } = useLoader({ response })

return {
...response,
infiniteScroll,
loadRef,
}
return infiniteQueryResponse
}

// PROPTYPES
Expand Down
27 changes: 5 additions & 22 deletions src/common/dataHooks/useSearchLoader.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,24 @@
import { useInfiniteQuery } from '@tanstack/react-query'
import { useParams } from 'react-router-dom'
import PropTypes from 'prop-types'

// FPCC
import useLoader from 'common/hooks/useLoader'
import useInfiniteScroll from 'common/dataHooks/useInfiniteScroll'
import api from 'services/api'
import { SEARCH } from 'common/constants'
import { searchResponseAdaptor } from 'common/dataAdaptors'
import { searchResultAdaptor } from 'common/dataAdaptors'

/**
* Calls search API and provides search results and infinite scroll info.
*/
function useSearchLoader({ searchParams }) {
const { sitename } = useParams()
const searchParamString = searchParams.toString()

// Fetch search results
const response = useInfiniteQuery({
const infiniteQueryResponse = useInfiniteScroll({
queryKey: [SEARCH, sitename, searchParamString],
queryFn: ({ pageParam = 1 }) =>
api.search.get({ sitename, searchParams: searchParamString, pageParam }),
getNextPageParam: (currentPage) => currentPage.next,
refetchOnWindowFocus: false,
refetchOnReconnect: false,
select: (responseData) => ({
pages: searchResponseAdaptor(responseData),
pageParams: responseData.pageParams,
}),
resultAdaptor: searchResultAdaptor,
})

const { infiniteScroll, loadRef } = useLoader({ response })

return {
...response,
infiniteScroll,
loadRef,
}
return infiniteQueryResponse
}

// PROPTYPES
Expand Down
44 changes: 0 additions & 44 deletions src/common/hooks/useLoader.js

This file was deleted.

4 changes: 0 additions & 4 deletions src/components/ByAlphabet/ByAlphabetContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,12 @@ import SiteDocHead from 'components/SiteDocHead'

function ByAlphabetContainer({ kids = null }) {
const {
actions,
characterQueryResponse,
currentCharacter,
searchType,
setSearchType,
entryLabel,
searchInfiniteQueryResponse,
moreActions,
selectedTab,
sitename,
tabs,
Expand All @@ -28,15 +26,13 @@ function ByAlphabetContainer({ kids = null }) {
description={`Dictionary entries that start with ${currentCharacter?.title}.`}
/>
<ByAlphabetPresentation
actions={actions}
characters={characterQueryResponse?.data?.characters || []}
currentCharacter={currentCharacter}
searchType={searchType}
setSearchType={setSearchType}
entryLabel={entryLabel}
searchInfiniteQueryResponse={searchInfiniteQueryResponse}
kids={kids}
moreActions={moreActions}
selectedTab={selectedTab}
sitename={sitename}
tabs={tabs}
Expand Down
Loading

0 comments on commit e33a4e8

Please sign in to comment.