From 7c263167cd8b3d8cadbe47a10df2daf01fd91dda Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Fri, 11 Mar 2022 01:57:51 -0800 Subject: [PATCH 1/3] Add recent dictionary to app state --- utils/appState.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/utils/appState.tsx b/utils/appState.tsx index 81d6db31..0a4ed54d 100644 --- a/utils/appState.tsx +++ b/utils/appState.tsx @@ -28,7 +28,11 @@ interface AppState { characters: GridArray }, 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: [] } From 9e3bc95ec80bd34b548659e88155b5081b87499b Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Fri, 11 Mar 2022 02:32:27 -0800 Subject: [PATCH 2/3] Implement recently searched items for weapons and summons --- components/SearchModal/index.tsx | 50 ++++++++++++++++++++++++++++---- public/locales/en/common.json | 1 + public/locales/ja/common.json | 1 + 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/components/SearchModal/index.tsx b/components/SearchModal/index.tsx index 60d5089a..1ab0805d 100644 --- a/components/SearchModal/index.tsx +++ b/components/SearchModal/index.tsx @@ -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() let scrollContainer = React.createRef() + 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,6 +110,27 @@ 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) @@ -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 { sendData(result) }} + onClick={() => { storeRecentResult(result) }} /> }) } @@ -190,7 +228,7 @@ const SearchModal = (props: Props) => { return { sendData(result) }} + onClick={() => { storeRecentResult(result) }} /> }) } @@ -207,7 +245,7 @@ const SearchModal = (props: Props) => { return { sendData(result) }} + onClick={() => { storeRecentResult(result) }} /> }) } diff --git a/public/locales/en/common.json b/public/locales/en/common.json index e03564e6..4ba42722 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -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}}", diff --git a/public/locales/ja/common.json b/public/locales/ja/common.json index baf3cf3f..2b5eb6ab 100644 --- a/public/locales/ja/common.json +++ b/public/locales/ja/common.json @@ -209,6 +209,7 @@ "not_found": "編成はまだ保存していません" }, "search": { + "recent": "最近追加した", "result_count": "{{record_count}}件", "errors": { "start_typing": "{{object}}名を入力してください", From 565956834517e9c92721ffc29df9077a9319558f Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Fri, 11 Mar 2022 02:36:18 -0800 Subject: [PATCH 3/3] Properly clean the modal when selecting an item --- components/SearchModal/index.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/components/SearchModal/index.tsx b/components/SearchModal/index.tsx index 1ab0805d..61d63a82 100644 --- a/components/SearchModal/index.tsx +++ b/components/SearchModal/index.tsx @@ -133,7 +133,7 @@ const SearchModal = (props: Props) => { function sendData(result: Character | Weapon | Summon) { props.send(result, props.fromPosition) - setOpen(false) + openChange() } function receiveFilters(filters: { [key: string]: number[] }) { @@ -256,7 +256,10 @@ const SearchModal = (props: Props) => { function openChange() { if (open) { setQuery('') + setFirstLoad(true) setResults([]) + setRecordCount(0) + setCurrentPage(1) setOpen(false) } else { setOpen(true)