Skip to content

Commit 0ef5b43

Browse files
committed
fix recent songs stuck in loading state after filtering by category
Removes re-fetching on `useState` and calls it explicitly when loading a new page or changing the category. Fixes #87
1 parent f9a031e commit 0ef5b43

2 files changed

Lines changed: 60 additions & 72 deletions

File tree

apps/frontend/src/modules/browse/components/HomePageComponent.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import { CategoryButtonGroup } from './client/CategoryButton';
2121
import { useFeaturedSongsProvider } from './client/context/FeaturedSongs.context';
2222
import {
2323
useRecentSongsProvider,
24-
useRecentSongsPageLoader,
2524
useRecentSongsCategoriesLoader,
2625
} from './client/context/RecentSongs.context';
2726
import LoadMoreButton from './client/LoadMoreButton';
@@ -31,7 +30,6 @@ import SongCardGroup from './SongCardGroup';
3130

3231
export const HomePageComponent = () => {
3332
// Initialize sync hooks for proper effect handling
34-
useRecentSongsPageLoader();
3533
useRecentSongsCategoriesLoader();
3634

3735
const { featuredSongsPage, timespan } = useFeaturedSongsProvider();

apps/frontend/src/modules/browse/components/client/context/RecentSongs.context.tsx

Lines changed: 60 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -43,38 +43,8 @@ function injectAdSlots(
4343
return songsWithAds;
4444
}
4545

46-
export const useRecentSongsStore = create<RecentSongsStore>((set, get) => ({
47-
// Initial state
48-
recentSongs: [],
49-
recentError: '',
50-
isLoading: false,
51-
hasMore: true,
52-
selectedCategory: '',
53-
categories: {},
54-
page: 1,
55-
56-
// Actions
57-
initialize: (initialRecentSongs) => {
58-
set({
59-
recentSongs: injectAdSlots(initialRecentSongs),
60-
page: 1,
61-
hasMore: true,
62-
recentError: '',
63-
});
64-
},
65-
66-
fetchCategories: async () => {
67-
try {
68-
const response = await axiosInstance.get<Record<string, number>>(
69-
'/song/categories',
70-
);
71-
set({ categories: response.data });
72-
} catch (error) {
73-
set({ categories: {} });
74-
}
75-
},
76-
77-
fetchRecentSongs: async () => {
46+
export const useRecentSongsStore = create<RecentSongsStore>((set, get) => {
47+
const fetchRecentSongs = async () => {
7848
const { page, selectedCategory } = get();
7949
set({ isLoading: true });
8050

@@ -114,46 +84,66 @@ export const useRecentSongsStore = create<RecentSongsStore>((set, get) => ({
11484
} finally {
11585
set({ isLoading: false });
11686
}
117-
},
118-
119-
setSelectedCategory: (category) => {
120-
set({
121-
selectedCategory: category,
122-
page: 1,
123-
recentSongs: Array(pageSize).fill(null),
124-
hasMore: true,
125-
});
126-
},
127-
128-
increasePageRecent: async () => {
129-
const { isLoading, recentError, hasMore, recentSongs } = get();
130-
131-
if (isLoading || recentError || !hasMore) {
132-
return;
133-
}
87+
};
88+
89+
return {
90+
// Initial state
91+
recentSongs: [],
92+
recentError: '',
93+
isLoading: false,
94+
hasMore: true,
95+
selectedCategory: '',
96+
categories: {},
97+
page: 1, // Start from page 1 since it's loaded server-side
98+
99+
// Actions
100+
initialize: (initialRecentSongs) => {
101+
set({
102+
recentSongs: injectAdSlots(initialRecentSongs),
103+
page: 1,
104+
hasMore: true,
105+
recentError: '',
106+
});
107+
},
108+
109+
fetchCategories: async () => {
110+
try {
111+
const response = await axiosInstance.get<Record<string, number>>(
112+
'/song/categories',
113+
);
114+
set({ categories: response.data });
115+
} catch (error) {
116+
set({ categories: {} });
117+
}
118+
},
134119

135-
set({
136-
recentSongs: [...recentSongs, ...Array(pageSize).fill(null)],
137-
page: get().page + 1,
138-
});
139-
},
140-
}));
141-
142-
// Hook to sync page changes with fetchRecentSongs
143-
export const useRecentSongsPageLoader = () => {
144-
const page = useRecentSongsStore((state) => state.page);
145-
const selectedCategory = useRecentSongsStore(
146-
(state) => state.selectedCategory,
147-
);
148-
const fetchRecentSongs = useRecentSongsStore(
149-
(state) => state.fetchRecentSongs,
150-
);
120+
fetchRecentSongs: fetchRecentSongs,
151121

152-
useEffect(() => {
153-
if (page === 1) return; // Skip fetching page 1 as it's already loaded initially
154-
fetchRecentSongs();
155-
}, [page, selectedCategory, fetchRecentSongs]);
156-
};
122+
setSelectedCategory: (category) => {
123+
set({
124+
selectedCategory: category,
125+
page: 1, // Fetch from the first page when category changes
126+
recentSongs: Array(pageSize).fill(null),
127+
hasMore: true,
128+
});
129+
fetchRecentSongs();
130+
},
131+
132+
increasePageRecent: async () => {
133+
const { isLoading, recentError, hasMore, recentSongs } = get();
134+
135+
if (isLoading || recentError || !hasMore) {
136+
return;
137+
}
138+
139+
set({
140+
recentSongs: [...recentSongs, ...Array(pageSize).fill(null)],
141+
page: get().page + 1,
142+
});
143+
fetchRecentSongs();
144+
},
145+
};
146+
});
157147

158148
// Hook to fetch categories on mount
159149
export const useRecentSongsCategoriesLoader = () => {

0 commit comments

Comments
 (0)