|
82 | 82 | </div> |
83 | 83 | <div class="rom-list-layout__content"> |
84 | 84 | <div class="rom-list-layout__content-list"> |
85 | | - <slot :filtered-roms="filteredRoms" :loading="romStore.loading"></slot> |
| 85 | + <slot |
| 86 | + :filtered-roms="filteredRoms.roms" |
| 87 | + :filtered-size="filteredRoms.size" |
| 88 | + :total-roms="sortedRoms.length" |
| 89 | + :loading="romStore.loading" |
| 90 | + ></slot> |
86 | 91 | </div> |
87 | 92 | <div class="rom-list-layout__content-detail"> |
88 | 93 | <slot name="rom-details"></slot> |
@@ -156,44 +161,60 @@ const filterRegions = computed(() => { |
156 | 161 | .sort((a, b) => a.label.localeCompare(b.label)); |
157 | 162 | }); |
158 | 163 |
|
| 164 | +const romsForMode = computed(() => { |
| 165 | + if (props.mode === 'favorites') { |
| 166 | + return romStore.roms.filter((rom) => rom.favorite); |
| 167 | + } |
| 168 | +
|
| 169 | + if (props.mode === 'system' && props.system) { |
| 170 | + return romStore.roms.filter((rom) => rom.system === props.system); |
| 171 | + } |
| 172 | +
|
| 173 | + if (props.mode === 'tag') { |
| 174 | + const tag = props.tag; |
| 175 | + if (!tag) return romStore.roms; |
| 176 | + return romStore.roms.filter((rom) => (rom.tags || []).includes(tag)); |
| 177 | + } |
| 178 | +
|
| 179 | + return romStore.roms; |
| 180 | +}); |
| 181 | +
|
| 182 | +// TODO: Consider doing sort in the database query instead. |
159 | 183 | const sortedRoms = computed(() => { |
160 | | - return [...romStore.roms].sort((a, b) => a.displayName.localeCompare(b.displayName)); |
| 184 | + return [...romsForMode.value].sort((a, b) => a.displayName.localeCompare(b.displayName)); |
161 | 185 | }); |
162 | 186 |
|
163 | 187 | const filteredRoms = computed(() => { |
164 | 188 | const query = searchQuery.value.toLowerCase().trim(); |
165 | 189 | const selectedRegions = filterByRegion.value; |
166 | | - const selectedSystems = props.mode === 'system' ? [props.system] : filterBySystem.value; |
167 | | - const filterTag = props.mode === 'tag' ? props.tag : null; |
| 190 | + const selectedSystems = filterBySystem.value; |
| 191 | + let size = 0; |
168 | 192 |
|
169 | | - return sortedRoms.value.filter((rom) => { |
170 | | - const { displayName, system, region, tags = [] } = rom; |
| 193 | + const roms = sortedRoms.value.filter((rom) => { |
| 194 | + const { displayName, system, region } = rom; |
171 | 195 |
|
172 | 196 | const hasSystemMatch = |
173 | 197 | !selectedSystems?.length || selectedSystems.some((value) => value === system); |
174 | 198 | const hasRegionMatch = |
175 | 199 | !selectedRegions?.length || selectedRegions.some((value) => value === region); |
176 | 200 | const hasQueryMatch = !query || displayName.toLowerCase().includes(query); |
177 | | -
|
178 | | - const hasTagMatch = !filterTag || (tags && tags.includes(filterTag)); |
179 | | - const hasFavoritesMatch = props.mode === 'favorites' ? rom.favorite : true; |
180 | 201 | const hasRAMatch = |
181 | 202 | !filterByRA.value || |
182 | 203 | (filterByRA.value === 'has-achievements' && (rom.numAchievements ?? 0) > 0) || |
183 | 204 | (filterByRA.value === 'no-achievements' && |
184 | 205 | rom.verified && |
185 | 206 | (rom.numAchievements ?? 0) === 0) || |
186 | 207 | (filterByRA.value === 'unverified' && !rom.verified); |
| 208 | + const shouldInclude = hasSystemMatch && hasRegionMatch && hasQueryMatch && hasRAMatch; |
187 | 209 |
|
188 | | - return ( |
189 | | - hasSystemMatch && |
190 | | - hasRegionMatch && |
191 | | - hasQueryMatch && |
192 | | - hasTagMatch && |
193 | | - hasRAMatch && |
194 | | - hasFavoritesMatch |
195 | | - ); |
| 210 | + if (shouldInclude) { |
| 211 | + size += rom.size ?? 0; |
| 212 | + } |
| 213 | +
|
| 214 | + return shouldInclude; |
196 | 215 | }); |
| 216 | +
|
| 217 | + return { roms, size }; |
197 | 218 | }); |
198 | 219 |
|
199 | 220 | function toggleFilters() { |
|
0 commit comments