Skip to content

Commit

Permalink
perf improvements to My Library (#504)
Browse files Browse the repository at this point in the history
Closes #493
  • Loading branch information
andrew-codes authored Aug 18, 2024
2 parents a8ae87a + 9f9a373 commit 553da89
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 75 deletions.
69 changes: 28 additions & 41 deletions apps/playnite-web/src/api/client/state/librarySlice.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import { createSelector, createSlice } from '@reduxjs/toolkit'
import _ from 'lodash'
import And from '../../../domain/filters/And'
import NoFilter from '../../../domain/filters/NoFilter'
import MatchFeature from '../../../domain/filters/playnite/MatchFeature'

const { keyBy, memoize, merge } = _
const { keyBy, merge } = _

const initialState: {
activeNameFilters: string | null
Expand All @@ -20,18 +17,6 @@ const initialState: {
platformFilterValues: {},
}

const noFilter = new NoFilter()

const getNameFilter = memoize((state: typeof initialState) =>
!state.activeNameFilters ? {} : { name: state.activeNameFilters },
)

const getFeatureFilter = memoize((state: typeof initialState) => {
return state.activeFeatureFilters.length === 0
? noFilter
: new And(...state.activeFeatureFilters.map((id) => new MatchFeature(id)))
})

const alphabeticalOrder = (a: { name: string }, b: { name: string }) => {
return a.name.localeCompare(b.name)
}
Expand All @@ -40,30 +25,33 @@ const slice = createSlice({
name: 'library',
initialState,
selectors: {
getFilter: createSelector(
[getNameFilter, getFeatureFilter],
(nameFilter, featureFilter) => merge({}, nameFilter),
getFilterValues: createSelector(
(state) => state,
(state) => ({
nameFilter: state.activeNameFilters ?? '',
featureFilter:
state.activeFeatureFilters.map(
(id) => state.featureFilterValues[id],
) ?? [],
platformFilter:
state.activePlatformFilters.map(
(id) => state.platformFilterValues[id],
) ?? [],
}),
),
getAllPossibleFilterValues: createSelector(
(state) => state,
(state) => {
return Object.entries(state).reduce((acc, [key, value]) => {
if (key.endsWith('FilterValues')) {
acc[key.replace('FilterValues', '')] = Object.values(
value as Record<string, { id: string; name: string }>,
).sort(alphabeticalOrder)
}
return acc
}, {})
},
),
getFilterValues: (state) => ({
nameFilter: state.activeNameFilters ?? '',
featureFilter:
state.activeFeatureFilters.map((id) => state.featureFilterValues[id]) ??
[],
platformFilter:
state.activePlatformFilters.map(
(id) => state.platformFilterValues[id],
) ?? [],
}),
getAllPossibleFilterValues: (state) => {
return Object.entries(state).reduce((acc, [key, value]) => {
if (key.endsWith('FilterValues')) {
acc[key.replace('FilterValues', '')] = Object.values(
value as Record<string, { id: string; name: string }>,
).sort(alphabeticalOrder)
}
return acc
}, {})
},
},
reducers: {
setFilterTypeValues(state, action) {
Expand Down Expand Up @@ -91,5 +79,4 @@ const slice = createSlice({
export const { reducer } = slice
export const { setFilterTypeValues, setSelectedFilter, activateFilters } =
slice.actions
export const { getAllPossibleFilterValues, getFilter, getFilterValues } =
slice.selectors
export const { getAllPossibleFilterValues, getFilterValues } = slice.selectors
2 changes: 1 addition & 1 deletion apps/playnite-web/src/routes/_index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ function Index() {
setGame(game)
setRightDrawerOpen(true)
}, [])
const { data, loading, refetch, error } = usePlaylists()
const { data, loading, error } = usePlaylists()
const playlists = data?.playlists

return (
Expand Down
42 changes: 9 additions & 33 deletions apps/playnite-web/src/routes/browse.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,11 @@ import { FilterAlt } from '@mui/icons-material'
import { Button, styled } from '@mui/material'
import type { LoaderFunctionArgs } from '@remix-run/node'
import { json } from '@remix-run/node'
import {
Outlet,
useLoaderData,
useLocation,
useNavigate,
} from '@remix-run/react'
import { useCallback, useEffect, useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { Outlet, useLocation, useNavigate } from '@remix-run/react'
import { useCallback, useState } from 'react'
import { useSelector } from 'react-redux'
import { Game } from '../../.generated/types.generated'
import {
getFilter,
setFilterTypeValues,
} from '../api/client/state/librarySlice'
import { getFilterValues } from '../api/client/state/librarySlice'
import getGameApi from '../api/game/index.server'
import Filters from '../components/Filters'
import IconButton from '../components/IconButton'
Expand Down Expand Up @@ -66,32 +58,16 @@ const All_Games_Query = gql`
}
`
function Browse() {
const { filterValues } = (useLoaderData() || {}) as unknown as {
filterValues:
| {
feature: { id: string; name: string }[]
}
| undefined
}

const filter = useSelector(getFilter)
const { loading, data, error, refetch } = useQuery(All_Games_Query)
useEffect(() => {
refetch({ filter })
}, [filter])
const { nameFilter } = useSelector(getFilterValues)
const { loading, data, error } = useQuery(All_Games_Query, {
variables: { filter: { name: nameFilter } },
})

const games = !loading ? data?.games : []
const games = !loading ? (data?.games ?? []) : []
if (error) {
console.error(error, data)
}

const dispatch = useDispatch()
useEffect(() => {
Object.entries(filterValues ?? {}).forEach(([key, value]) => {
dispatch(setFilterTypeValues({ filterTypeName: key, values: value }))
})
}, [filterValues])

const [trigger] = useNavigateInGrid()
const handleScrollTop = (evt) => {
trigger(0, 0)
Expand Down

0 comments on commit 553da89

Please sign in to comment.