Skip to content

Commit 0498f6c

Browse files
fix: albums page reactivity loops (#24046)
1 parent 24e5dab commit 0498f6c

File tree

1 file changed

+23
-42
lines changed

1 file changed

+23
-42
lines changed

web/src/lib/components/album-page/albums-list.svelte

Lines changed: 23 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
import { groupBy } from 'lodash-es';
3434
import { onMount, type Snippet } from 'svelte';
3535
import { t } from 'svelte-i18n';
36-
import { run } from 'svelte/legacy';
3736
3837
interface Props {
3938
ownedAlbums?: AlbumResponseDto[];
@@ -128,63 +127,45 @@
128127
},
129128
};
130129
131-
let albums: AlbumResponseDto[] = $state([]);
132-
let filteredAlbums: AlbumResponseDto[] = $state([]);
133-
let groupedAlbums: AlbumGroup[] = $state([]);
134-
135-
let albumGroupOption: string = $state(AlbumGroupBy.None);
136-
137-
let contextMenuPosition: ContextMenuPosition = $state({ x: 0, y: 0 });
138-
let selectedAlbum: AlbumResponseDto | undefined = $state();
139-
let isOpen = $state(false);
140-
141-
// Step 1: Filter between Owned and Shared albums, or both.
142-
run(() => {
130+
let albums = $derived.by(() => {
143131
switch (userSettings.filter) {
144132
case AlbumFilter.Owned: {
145-
albums = ownedAlbums;
146-
break;
133+
return ownedAlbums;
147134
}
148135
case AlbumFilter.Shared: {
149-
albums = sharedAlbums;
150-
break;
136+
return sharedAlbums;
151137
}
152138
default: {
153-
const userId = $user.id;
154-
const nonOwnedAlbums = sharedAlbums.filter((album) => album.ownerId !== userId);
155-
albums = nonOwnedAlbums.length > 0 ? ownedAlbums.concat(nonOwnedAlbums) : ownedAlbums;
139+
const nonOwnedAlbums = sharedAlbums.filter((album) => album.ownerId !== $user.id);
140+
return nonOwnedAlbums.length > 0 ? ownedAlbums.concat(nonOwnedAlbums) : ownedAlbums;
156141
}
157142
}
158143
});
159-
160-
// Step 2: Filter using the given search query.
161-
run(() => {
162-
if (searchQuery) {
163-
const searchAlbumNormalized = normalizeSearchString(searchQuery);
164-
165-
filteredAlbums = albums.filter((album) => {
166-
return normalizeSearchString(album.albumName).includes(searchAlbumNormalized);
167-
});
168-
} else {
169-
filteredAlbums = albums;
170-
}
171-
});
172-
173-
// Step 3: Group albums.
174-
run(() => {
175-
albumGroupOption = getSelectedAlbumGroupOption(userSettings);
144+
const normalizedSearchQuery = $derived(normalizeSearchString(searchQuery));
145+
let filteredAlbums = $derived(
146+
normalizedSearchQuery
147+
? albums.filter(({ albumName }) => normalizeSearchString(albumName).includes(normalizedSearchQuery))
148+
: albums,
149+
);
150+
151+
let albumGroupOption = $derived(getSelectedAlbumGroupOption(userSettings));
152+
let groupedAlbums = $derived.by(() => {
176153
const groupFunc = groupOptions[albumGroupOption] ?? groupOptions[AlbumGroupBy.None];
177-
groupedAlbums = groupFunc(stringToSortOrder(userSettings.groupOrder), filteredAlbums);
178-
});
154+
const groupedAlbums = groupFunc(stringToSortOrder(userSettings.groupOrder), filteredAlbums);
179155
180-
// Step 4: Sort albums amongst each group.
181-
run(() => {
182-
groupedAlbums = groupedAlbums.map((group) => ({
156+
return groupedAlbums.map((group) => ({
183157
id: group.id,
184158
name: group.name,
185159
albums: sortAlbums(group.albums, { sortBy: userSettings.sortBy, orderBy: userSettings.sortOrder }),
186160
}));
161+
});
162+
163+
let contextMenuPosition: ContextMenuPosition = $state({ x: 0, y: 0 });
164+
let selectedAlbum: AlbumResponseDto | undefined = $state();
165+
let isOpen = $state(false);
187166
167+
// TODO get rid of this
168+
$effect(() => {
188169
albumGroupIds = groupedAlbums.map(({ id }) => id);
189170
});
190171

0 commit comments

Comments
 (0)