Skip to content

Commit 1a975a6

Browse files
feat: implemented caching for analysisgamelist + profile page game list
1 parent eb58a6e commit 1a975a6

2 files changed

Lines changed: 238 additions & 88 deletions

File tree

src/components/Analysis/AnalysisGameList.tsx

Lines changed: 117 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,30 @@ export const AnalysisGameList: React.FC<AnalysisGameListProps> = ({
5858
const [localHandGames, setLocalHandGames] = useState(analysisHandList)
5959
const [localBrainGames, setLocalBrainGames] = useState(analysisBrainList)
6060

61+
const [fetchedCache, setFetchedCache] = useState<{
62+
[key: string]: { [page: number]: boolean }
63+
}>({
64+
play: {},
65+
hand: {},
66+
brain: {},
67+
pgn: {},
68+
tournament: {},
69+
})
70+
71+
const [totalPagesCache, setTotalPagesCache] = useState<{
72+
[key: string]: number
73+
}>({})
74+
75+
const [currentPagePerTab, setCurrentPagePerTab] = useState<{
76+
[key: string]: number
77+
}>({
78+
play: 1,
79+
hand: 1,
80+
brain: 1,
81+
pgn: 1,
82+
tournament: 1,
83+
})
84+
6185
const listKeys = useMemo(() => {
6286
return analysisTournamentList
6387
? Array.from(analysisTournamentList.keys()).sort(
@@ -95,56 +119,104 @@ export const AnalysisGameList: React.FC<AnalysisGameListProps> = ({
95119

96120
useEffect(() => {
97121
if (selected !== 'tournament' && selected !== 'pgn') {
98-
setLoading(true)
99-
getAnalysisGameList(selected, currentPage).then((data) => {
100-
const parse = (
101-
game: {
102-
game_id: string
103-
maia_name: string
104-
result: string
105-
player_color: 'white' | 'black'
106-
},
107-
type: string,
108-
) => {
109-
const raw = game.maia_name.replace('_kdd_', ' ')
110-
const maia = raw.charAt(0).toUpperCase() + raw.slice(1)
122+
const isAlreadyFetched = fetchedCache[selected]?.[currentPage]
123+
124+
if (!isAlreadyFetched) {
125+
setLoading(true)
126+
127+
setFetchedCache((prev) => ({
128+
...prev,
129+
[selected]: { ...prev[selected], [currentPage]: true },
130+
}))
131+
132+
getAnalysisGameList(selected, currentPage)
133+
.then((data) => {
134+
const parse = (
135+
game: {
136+
game_id: string
137+
maia_name: string
138+
result: string
139+
player_color: 'white' | 'black'
140+
},
141+
type: string,
142+
) => {
143+
const raw = game.maia_name.replace('_kdd_', ' ')
144+
const maia = raw.charAt(0).toUpperCase() + raw.slice(1)
145+
146+
return {
147+
id: game.game_id,
148+
label:
149+
game.player_color === 'white'
150+
? `You vs. ${maia}`
151+
: `${maia} vs. You`,
152+
result: game.result,
153+
type,
154+
}
155+
}
111156

112-
return {
113-
id: game.game_id,
114-
label:
115-
game.player_color === 'white'
116-
? `You vs. ${maia}`
117-
: `${maia} vs. You`,
118-
result: game.result,
119-
type,
120-
}
121-
}
157+
const parsedGames = data.games.map((game: GameData) =>
158+
parse(game, selected),
159+
)
160+
const calculatedTotalPages = Math.ceil(data.total / 100)
122161

123-
if (selected === 'play') {
124-
setLocalPlayGames(
125-
data.games.map((game: GameData) => parse(game, 'play')),
126-
)
127-
} else if (selected === 'hand') {
128-
setLocalHandGames(
129-
data.games.map((game: GameData) => parse(game, 'hand')),
130-
)
131-
} else if (selected === 'brain') {
132-
setLocalBrainGames(
133-
data.games.map((game: GameData) => parse(game, 'brain')),
134-
)
135-
}
136-
setTotalPages(Math.ceil(data.total / 100))
137-
setLoading(false)
138-
})
162+
setTotalPagesCache((prev) => ({
163+
...prev,
164+
[selected]: calculatedTotalPages,
165+
}))
166+
167+
if (selected === 'play') {
168+
setLocalPlayGames((prev) =>
169+
currentPage === 1 ? parsedGames : [...prev, ...parsedGames],
170+
)
171+
} else if (selected === 'hand') {
172+
setLocalHandGames((prev) =>
173+
currentPage === 1 ? parsedGames : [...prev, ...parsedGames],
174+
)
175+
} else if (selected === 'brain') {
176+
setLocalBrainGames((prev) =>
177+
currentPage === 1 ? parsedGames : [...prev, ...parsedGames],
178+
)
179+
}
180+
setLoading(false)
181+
})
182+
.catch(() => {
183+
setFetchedCache((prev) => {
184+
const newCache = { ...prev }
185+
delete newCache[selected][currentPage]
186+
return newCache
187+
})
188+
setLoading(false)
189+
})
190+
}
191+
}
192+
}, [selected, currentPage, fetchedCache])
193+
194+
useEffect(() => {
195+
if (totalPagesCache[selected]) {
196+
setTotalPages(totalPagesCache[selected])
197+
} else if (selected === 'pgn' || selected === 'tournament') {
198+
setTotalPages(1)
139199
}
140-
}, [selected, currentPage])
200+
201+
setCurrentPage(currentPagePerTab[selected])
202+
}, [selected, totalPagesCache, currentPagePerTab])
141203

142204
const handlePageChange = (newPage: number) => {
143205
if (newPage >= 1 && newPage <= totalPages) {
144206
setCurrentPage(newPage)
207+
setCurrentPagePerTab((prev) => ({
208+
...prev,
209+
[selected]: newPage,
210+
}))
145211
}
146212
}
147213

214+
const handleTabChange = (
215+
newTab: 'tournament' | 'play' | 'hand' | 'brain' | 'pgn',
216+
) => {
217+
setSelected(newTab)
218+
}
219+
148220
return analysisTournamentList ? (
149221
<div className="flex h-full flex-col items-start justify-start overflow-hidden bg-background-1 md:rounded">
150222
<div className="flex h-full w-full flex-col">
@@ -153,31 +225,31 @@ export const AnalysisGameList: React.FC<AnalysisGameListProps> = ({
153225
label="Play"
154226
name="play"
155227
selected={selected}
156-
setSelected={setSelected}
228+
setSelected={handleTabChange}
157229
/>
158230
<Header
159231
label="Hand"
160232
name="hand"
161233
selected={selected}
162-
setSelected={setSelected}
234+
setSelected={handleTabChange}
163235
/>
164236
<Header
165237
label="Brain"
166238
name="brain"
167239
selected={selected}
168-
setSelected={setSelected}
240+
setSelected={handleTabChange}
169241
/>
170242
<Header
171243
label="Lichess"
172244
name="pgn"
173245
selected={selected}
174-
setSelected={setSelected}
246+
setSelected={handleTabChange}
175247
/>
176248
<Header
177249
label="WC"
178250
name="tournament"
179251
selected={selected}
180-
setSelected={setSelected}
252+
setSelected={handleTabChange}
181253
/>
182254
</div>
183255
<div className="red-scrollbar flex h-full flex-col overflow-y-scroll">

0 commit comments

Comments
 (0)