|
5 | 5 | </script> |
6 | 6 |
|
7 | 7 | <script lang="ts"> |
8 | | - import { run } from 'svelte/legacy'; |
9 | | -
|
10 | | - import { page } from '$app/stores'; |
11 | 8 | import { goto } from '$app/navigation'; |
12 | 9 | import ModCard from '$lib/components/mod-grid/mod-card.svelte'; |
13 | 10 | import { |
|
17 | 14 | isSortOrderId, |
18 | 15 | sortOrderParamName, |
19 | 16 | } from '$lib/helpers/mod-sorting'; |
20 | | - import { onMount } from 'svelte'; |
21 | 17 | import TagsSelector from '../tags-selector.svelte'; |
22 | 18 | import { modTagParamName } from '$lib/helpers/get-mod-tags'; |
23 | 19 | import { modExcludeTagParamName } from '$lib/helpers/get-mod-tags'; |
24 | 20 | import type { Mod } from '$lib/helpers/api/get-mod-list'; |
25 | 21 | import CheckboxInput from '../checkbox-input.svelte'; |
| 22 | + import { page } from '$app/state'; |
| 23 | + import { onMount } from 'svelte'; |
26 | 24 |
|
27 | 25 | interface Props { |
28 | 26 | mods?: Mod[]; |
|
44 | 42 |
|
45 | 43 | let selectedSortOrderId: SortOrderId = $state(defaultSortOrder); |
46 | 44 | let filter = $state(''); |
47 | | - let filteredMods: Mod[] = $state(mods); |
| 45 | +
|
| 46 | + const anyIncludes = (term: string, list: (string | undefined)[]) => { |
| 47 | + if (!term) return true; |
| 48 | +
|
| 49 | + for (const listItem of list) { |
| 50 | + if (!listItem) continue; |
| 51 | +
|
| 52 | + if (cleanUpText(listItem).includes(cleanUpText(term))) return true; |
| 53 | + } |
| 54 | + return false; |
| 55 | + }; |
| 56 | +
|
| 57 | + const filteredMods = $derived( |
| 58 | + sortModList(mods, selectedSortOrderId).filter((mod: Mod) => { |
| 59 | + const containsBlockedTag = mod.tags.findIndex((tag) => tagBlockList.includes(tag)) != -1; |
| 60 | + const containsAllowedTag = |
| 61 | + tagAllowList.length == 0 || mod.tags.findIndex((tag) => tagAllowList.includes(tag)) != -1; |
| 62 | +
|
| 63 | + return ( |
| 64 | + containsAllowedTag && |
| 65 | + !containsBlockedTag && |
| 66 | + anyIncludes(filter, [ |
| 67 | + mod.author, |
| 68 | + mod.description, |
| 69 | + mod.name, |
| 70 | + mod.repo, |
| 71 | + mod.uniqueName, |
| 72 | + mod.authorDisplay, |
| 73 | + ...mod.tags, |
| 74 | + ]) |
| 75 | + ); |
| 76 | + }) |
| 77 | + ); |
48 | 78 | let tagStates: TagStates = $state({}); |
49 | | - let selectedTagCount = $state(0); |
50 | 79 | let showDetails = $state(false); |
51 | 80 |
|
52 | 81 | const tags = $derived( |
|
57 | 86 | if (isSortOrderId(sortOrderId)) { |
58 | 87 | selectedSortOrderId = sortOrderId; |
59 | 88 |
|
60 | | - const url = new URL($page.url); |
| 89 | + const url = new URL(page.url); |
61 | 90 | url.searchParams.set(sortOrderParamName, sortOrderId); |
62 | 91 | goto(url.href); |
63 | 92 | } |
|
70 | 99 | .normalize('NFD') // Decompose combined graphemes (è => e + ̀) |
71 | 100 | .replace(/[\u0300-\u036f]/g, ''); // Remove the diacritic part (è => e) |
72 | 101 |
|
73 | | - const anyIncludes = (term: string, list: (string | undefined)[]) => { |
74 | | - if (!term) return true; |
75 | | -
|
76 | | - for (const listItem of list) { |
77 | | - if (!listItem) continue; |
78 | | -
|
79 | | - if (cleanUpText(listItem).includes(cleanUpText(term))) return true; |
80 | | - } |
81 | | - return false; |
82 | | - }; |
83 | | -
|
84 | 102 | const onToggleTag = (tag: string) => { |
85 | 103 | let toggledTag = tagStates[tag]; |
86 | 104 |
|
|
102 | 120 | tagAllowList = []; |
103 | 121 | tagBlockList = []; |
104 | 122 |
|
105 | | - const url = new URL($page.url); |
| 123 | + const url = new URL(page.url); |
106 | 124 | url.searchParams.delete(modTagParamName); |
107 | 125 | url.searchParams.delete(modExcludeTagParamName); |
108 | 126 | for (const [tagName, tagValue] of Object.entries(tagStates)) { |
|
118 | 136 | }; |
119 | 137 |
|
120 | 138 | const onClearTags = () => { |
121 | | - const url = new URL($page.url); |
| 139 | + const url = new URL(page.url); |
122 | 140 | url.searchParams.delete(modTagParamName); |
123 | 141 | url.searchParams.delete(modExcludeTagParamName); |
124 | 142 | goto(url.href); |
125 | 143 | }; |
126 | 144 |
|
127 | | - run(() => { |
128 | | - if (!import.meta.env.SSR) { |
129 | | - const sortOrderParam = $page.url.searchParams.get(sortOrderParamName) || ''; |
130 | | - if (isSortOrderId(sortOrderParam)) { |
131 | | - selectedSortOrderId = sortOrderParam; |
132 | | - } |
133 | | -
|
134 | | - tagStates = {}; |
135 | | - tagAllowList = []; |
136 | | - tagBlockList = []; |
137 | | - const tagParams = $page.url.searchParams.getAll(modTagParamName); |
138 | | - for (const tagParam of tagParams) { |
139 | | - tagStates[tagParam] = 'included'; |
140 | | - tagAllowList.push(tagParam); |
141 | | - } |
142 | | - const excludedTagParams = $page.url.searchParams.getAll(modExcludeTagParamName); |
143 | | - for (const tagParam of excludedTagParams) { |
144 | | - tagStates[tagParam] = 'excluded'; |
145 | | - tagBlockList.push(tagParam); |
146 | | - } |
| 145 | + onMount(() => { |
| 146 | + const sortOrderParam = page.url.searchParams.get(sortOrderParamName) || ''; |
| 147 | + if (isSortOrderId(sortOrderParam)) { |
| 148 | + selectedSortOrderId = sortOrderParam; |
147 | 149 | } |
148 | | - }); |
149 | | - run(() => { |
150 | | - const filterMod = (mod: Mod) => { |
151 | | - const containsBlockedTag = mod.tags.findIndex((tag) => tagBlockList.includes(tag)) != -1; |
152 | | - const containsAllowedTag = |
153 | | - tagAllowList.length == 0 || mod.tags.findIndex((tag) => tagAllowList.includes(tag)) != -1; |
154 | 150 |
|
155 | | - return ( |
156 | | - containsAllowedTag && |
157 | | - !containsBlockedTag && |
158 | | - anyIncludes(filter, [ |
159 | | - mod.author, |
160 | | - mod.description, |
161 | | - mod.name, |
162 | | - mod.repo, |
163 | | - mod.uniqueName, |
164 | | - mod.authorDisplay, |
165 | | - ...mod.tags, |
166 | | - ]) |
167 | | - ); |
168 | | - }; |
169 | | -
|
170 | | - filteredMods = sortModList(mods, selectedSortOrderId).filter(filterMod); |
171 | | - }); |
172 | | - run(() => { |
173 | | - selectedTagCount = tags.filter((tag) => tagStates[tag]).length; |
| 151 | + tagStates = {}; |
| 152 | + tagAllowList = []; |
| 153 | + tagBlockList = []; |
| 154 | + const tagParams = page.url.searchParams.getAll(modTagParamName); |
| 155 | + for (const tagParam of tagParams) { |
| 156 | + tagStates[tagParam] = 'included'; |
| 157 | + tagAllowList.push(tagParam); |
| 158 | + } |
| 159 | + const excludedTagParams = page.url.searchParams.getAll(modExcludeTagParamName); |
| 160 | + for (const tagParam of excludedTagParams) { |
| 161 | + tagStates[tagParam] = 'excluded'; |
| 162 | + tagBlockList.push(tagParam); |
| 163 | + } |
174 | 164 | }); |
175 | 165 |
|
176 | 166 | function getHideDlc(): boolean { |
|
197 | 187 | Sort by: {sortOrders[selectedSortOrderId].title} |
198 | 188 | </option> |
199 | 189 | {#each Object.entries(sortOrders) as [sortOrderId, sortOrder]} |
200 | | - <option value={sortOrderId}>{sortOrder.title}</option> |
| 190 | + {#if sortOrderId !== selectedSortOrderId} |
| 191 | + <option value={sortOrderId}>{sortOrder.title}</option> |
| 192 | + {/if} |
201 | 193 | {/each} |
202 | 194 | </select> |
203 | 195 | <div class="relative flex"> |
|
0 commit comments