Merge pull request #28 from jedmund/search-recents

Add recent searches
This commit is contained in:
Justin Edmund 2022-03-11 02:37:24 -08:00 committed by GitHub
commit b30d56ecc3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 60 additions and 9 deletions

View file

@ -1,4 +1,5 @@
import React, { useEffect, useRef, useState } from 'react'
import { useCookies } from 'react-cookie'
import { useRouter } from 'next/router'
import { useSnapshot } from 'valtio'
import { useTranslation } from 'react-i18next'
@ -19,6 +20,7 @@ import SummonResult from '~components/SummonResult'
import './index.scss'
import CrossIcon from '~public/icons/Cross.svg'
import cloneDeep from 'lodash.clonedeep'
interface Props {
send: (object: Character | Weapon | Summon, position: number) => any
@ -29,16 +31,23 @@ interface Props {
}
const SearchModal = (props: Props) => {
let { grid } = useSnapshot(appState)
// Set up snapshot of app state
let { grid, search } = useSnapshot(appState)
// Set up router
const router = useRouter()
const locale = router.locale
// Set up translation
const { t } = useTranslation('common')
// Set up cookies
const [cookies, setCookies] = useCookies()
let searchInput = React.createRef<HTMLInputElement>()
let scrollContainer = React.createRef<HTMLDivElement>()
const [firstLoad, setFirstLoad] = useState(true)
const [objects, setObjects] = useState<{[id: number]: GridCharacter | GridWeapon | GridSummon}>()
const [filters, setFilters] = useState<{ [key: string]: number[] }>()
const [open, setOpen] = useState(false)
@ -101,9 +110,30 @@ const SearchModal = (props: Props) => {
setResults([...results, ...list])
}
function storeRecentResult(result: Character | Weapon | Summon) {
const key = `recent_${props.object}`
let recents: Character[] | Weapon[] | Summon[] = []
if (props.object === "weapons") {
recents = cloneDeep(cookies[key] as Weapon[])
if (!recents.find(item => item.granblue_id === result.granblue_id)) {
recents.unshift(result as Weapon)
}
} else if (props.object === "summons") {
recents = cloneDeep(cookies[key] as Summon[])
if (!recents.find(item => item.granblue_id === result.granblue_id)) {
recents.unshift(result as Summon)
}
}
if (recents.length > 5) recents.pop()
setCookies(`recent_${props.object}`, recents, { path: '/' })
sendData(result)
}
function sendData(result: Character | Weapon | Summon) {
props.send(result, props.fromPosition)
setOpen(false)
openChange()
}
function receiveFilters(filters: { [key: string]: number[] }) {
@ -123,9 +153,17 @@ const SearchModal = (props: Props) => {
useEffect(() => {
// Filters changed
const key = `recent_${props.object}`
if (open) {
setCurrentPage(1)
fetchResults({ replace: true })
if (firstLoad && cookies[key].length > 0) {
setResults(cookies[key])
setRecordCount(cookies[key].length)
setFirstLoad(false)
} else {
setCurrentPage(1)
fetchResults({ replace: true })
}
}
}, [filters])
@ -173,7 +211,7 @@ const SearchModal = (props: Props) => {
return <WeaponResult
key={result.id}
data={result}
onClick={() => { sendData(result) }}
onClick={() => { storeRecentResult(result) }}
/>
})
}
@ -190,7 +228,7 @@ const SearchModal = (props: Props) => {
return <SummonResult
key={result.id}
data={result}
onClick={() => { sendData(result) }}
onClick={() => { storeRecentResult(result) }}
/>
})
}
@ -207,7 +245,7 @@ const SearchModal = (props: Props) => {
return <CharacterResult
key={result.id}
data={result}
onClick={() => { sendData(result) }}
onClick={() => { storeRecentResult(result) }}
/>
})
}
@ -218,7 +256,10 @@ const SearchModal = (props: Props) => {
function openChange() {
if (open) {
setQuery('')
setFirstLoad(true)
setResults([])
setRecordCount(0)
setCurrentPage(1)
setOpen(false)
} else {
setOpen(true)

View file

@ -208,6 +208,7 @@
"not_found": "You haven't saved any teams"
},
"search": {
"recent": "Recently added",
"result_count": "{{record_count}} results",
"errors": {
"start_typing": "Start typing the name of a {{object}}",

View file

@ -209,6 +209,7 @@
"not_found": "編成はまだ保存していません"
},
"search": {
"recent": "最近追加した",
"result_count": "{{record_count}}件",
"errors": {
"start_typing": "{{object}}名を入力してください",

View file

@ -28,7 +28,11 @@ interface AppState {
characters: GridArray<GridCharacter>
},
search: {
sourceItem: GridCharacter | GridWeapon | GridSummon | undefined
recents: {
characters: Character[]
weapons: Weapon[]
summons: Summon[]
}
},
raids: Raid[]
}
@ -59,7 +63,11 @@ export const initialAppState: AppState = {
characters: {}
},
search: {
sourceItem: undefined
recents: {
characters: [],
weapons: [],
summons: []
}
},
raids: []
}