Skip to content

Commit 9606007

Browse files
committed
Merge branch 'develop' of github.com:OpenNBS/NoteBlockWorld into develop
2 parents 5e033f5 + 312909a commit 9606007

File tree

21 files changed

+161
-244
lines changed

21 files changed

+161
-244
lines changed

apps/backend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
"esm": "^3.2.25",
4949
"express": "^5.2.1",
5050
"mongoose": "^9.0.1",
51-
"multer": "2.0.2",
51+
"multer": "2.1.1",
5252
"nanoid": "^5.1.6",
5353
"passport": "^0.7.0",
5454
"passport-github": "^1.1.0",

apps/backend/src/song/song.controller.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,6 @@ export class SongController {
105105
): Promise<PageDto<SongPreviewDto>> {
106106
// Handle random sort
107107
if (query.sort === SongSortType.RANDOM) {
108-
if (query.limit && (query.limit < 1 || query.limit > 10)) {
109-
throw new BadRequestException(
110-
'Limit must be between 1 and 10 for random sort',
111-
);
112-
}
113108
const data = await this.songService.getRandomSongs(
114109
query.limit ?? 1,
115110
query.category,
Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,61 @@
11
---
22
title: 'You can now search for songs in Note Block World!'
3-
date: '2025-12-31'
3+
date: '2026-02-18'
44
author: 'Bentroen'
55
authorImage: 'bentroen.png'
66
image: '/img/blog/song-search.webp'
77
tags: ['updates']
88
---
99

10-
**That's right:** the (delayed) Christmas present you have been asking for since forever has just arrived! **Song search has been released to everyone in Note Block World, starting now!**
10+
**That's right:** the feature you ALL have been asking for since the beginning of the website has just arrived! **Song search has been released to everyone in Note Block World, starting now.** 🔍
1111

12-
This was simply our most requested feature, and we're glad to finally be able to unveil it to you!
12+
This was simply our **most requested feature**, and we're glad to finally be able to unveil it to you!
13+
14+
---
1315

1416
## List of changes
1517

1618
- Added a search bar on the page's navbar!
1719
- The results page includes:
1820
- Total number of results returned
19-
- Sorting by recent, popular, duration, play count and note count
21+
- Sorting by **recent, **popular**, **duration**, **play count** and **note count\*\*
2022
- Ordering (ascending, descending)
2123
- Many more filtering options coming right next!
2224

23-
We'd like to thank [tomast1337](https://github.com/tomast1337) for a significant portion of the implementation, as well as our Discord community for providing valuable feedback, and even developing some alternatives (such as the **awesome** [Note Block World Finder](https://nbw.flwc.cc/)) to fill in the gap while the official solution wasn't out!
25+
### Bugfixes and improvements
2426

25-
We hope you enjoy the update, and the search feature makes it ever easier to find creations you like on Note Block World!
27+
- Added a translucent, glass-like effect on the navbar!
28+
- Fixed icons looking huge during page load, before settling in place. We've had an... \*_ahem_\*- _alignment_ session with the icons and they will behave now.
29+
- Fixed unformatted Markdown showing on blog post previews.
30+
- The navbar becomes scrollable if its contents are too large to fit the screen. (This will be replaced by a proper responsive design soon!)
31+
- Fixed song preview cards being huge when there weren't enough entries to fill an entire column.
32+
- Mouse hover areas for the popup and the hover effect are now the same on the navbar buttons.
33+
34+
---
35+
36+
We'd like to thank [tomast1337](https://github.com/tomast1337) for a significant portion of the implementation, as well as our Discord community for providing valuable feedback — and even developing some alternatives (such as the **awesome** [Note Block World Finder](https://nbw.flwc.cc/)) to fill in the gap while the official solution wasn't out!
2637

27-
As always, report bugs to us in [Discord](https://discord.gg/note-block-world-608692895179997252) or in our [GitHub](https://github.com/OpenNBS/NoteBlockWorld/issues/new/choose) page. We'd like to make the website the best it can be, and we count on your support to help us achieve this goal!
38+
As always, report bugs to us in [Discord](https://discord.gg/note-block-world-608692895179997252) or in our [GitHub](https://github.com/OpenNBS/NoteBlockWorld/issues/new/choose) page. We'd like to make the website the best it can be, and we count on **your support** to help us achieve this goal!
39+
40+
We hope you enjoy the update, and the search feature makes it ever easier to find creations you like on Note Block World!
2841

2942
## Up next
3043

31-
Search is just a small step in our plan to become **the world's largest public, open repository of note block creations.** Although this is a very small feature, some important refactoring is underway to pave the way for even more advanced features:
44+
Search is just a small step in our plan to become **the world's largest public, open repository of note block creations.** Although this is a tiny feature, some important refactoring is underway to pave the way for even more advanced features:
3245

3346
- In-browser song playback!
3447
- Advanced search filtering!
3548
- User profiles!
49+
- ...and much, much more!
3650

37-
You can expect these features to start rolling out in the next few months. Stay tuned — there's much more to come in 2026!
51+
You can expect these features to start rolling out in the next few months. Stay tuned — there's much more to come this year!
3852

3953
## Wrapping up
4054

41-
This year couldn't have been more amazing. We've reached over **two thousand songs** uploaded to Note Block World, and held our **second community-wide [collaboration event](http://localhost:3000/blog/maestro's-musical-masterpieces)** with the creators of [M.A.E.S.T.R.O.](https://noteblock.world/blog/maestro), which had over **30 submissions** spanning **over 90 minutes of music!** And there was even time for a bonus feature before closing off this year! 🎁
55+
The year of 2025 couldn't have been more amazing. Thanks to **your** engagement and support, we've reached over **two thousand songs** uploaded to Note Block World, and held our **second community-wide [collaboration event](/blog/maestro's-musical-masterpieces)** with the creators of [M.A.E.S.T.R.O.](/blog/maestro), which got over **30 submissions** spanning **over 90 minutes of music!**
4256

43-
Thank you to everyone who visited the website, shared music with their friends, submitted their own creations, or even [donated](https://opencollective.com/opennbs/donate/profile) to help us keep the website running. **Our community is at the core of everything we do, and the reason why we're excited to keep working on cool things everyday!**
57+
Thank you to everyone who visited the website, shared music with their friends, submitted their own creations, or even [donated](https://opencollective.com/opennbs/donate) to help us keep the website running. **Our community is at the core of everything we do, and the reason why we're excited to keep working on cool things everyday!**
4458

45-
We wish everyone an **incredible 2026**, full of achievements and amazing moments. We'll certainly work hard to make sure it is a wonderful year for Note Block World — especially as it will mark **Note Block Studio's 15th Anniversary!** Stay tuned for the many cool things we're planning to celebrate this remarkable moment in the history of note blocks.
59+
We wish everyone an **incredible 2026**, full of achievements and amazing moments. We'll certainly work hard to make sure it is a wonderful year for Note Block World — especially as **Note Block Studio will turn 15 years old!** Stay tuned for the many cool things we're planning to celebrate this remarkable moment in the history of note blocks.
4660

47-
**Happy New Year!** See y'all in the next one! :fireworks: :wave_tone1:
61+
See y'all in the next one! 🎆👋

apps/frontend/src/app/(content)/(info)/about/about.mdx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,16 @@ Note Block World is made possible by our amazing community of note block enthusi
3030

3131
<Image
3232
unoptimized
33-
src='https://opencollective.com/opennbs/backers.svg?width=900'
33+
src='https://opencollective.com/opennbs/backers.svg?width=800'
3434
alt='Backers'
35-
width={900}
36-
height={900}
35+
width={800}
36+
height={800}
3737
/>
3838

3939
<Image
4040
unoptimized
41-
src='https://opencollective.com/opennbs/sponsors.svg?width=900'
41+
src='https://opencollective.com/opennbs/sponsors.svg?width=800'
4242
alt='Sponsors'
43-
width={900}
44-
height={900}
43+
width={800}
44+
height={800}
4545
/>

apps/frontend/src/app/(content)/(info)/blog/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ const BlogPageComponent = ({ posts }: { posts: PostType[] }) => {
4141
href={`/blog/${post.id}`}
4242
className='w-full h-full p-4 rounded-md bg-zinc-800/50 hover:bg-zinc-700/80 transition-all duration-200'
4343
>
44-
<article key={i} className='flex flex-col'>
44+
<article key={i} className='flex flex-col h-full'>
4545
<Image
4646
src={post.image || '/img/post.png'}
4747
width={480}

apps/frontend/src/app/(content)/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ async function fetchRecentSongs() {
1010
const response = await axiosInstance.get<PageDto<SongPreviewDto>>('/song', {
1111
params: {
1212
page: 1, // TODO: fix constants
13-
limit: 16, // TODO: change 'limit' parameter to 'skip' and load 12 songs initially, then load 8 more songs on each pagination
13+
limit: 11, // TODO: change 'limit' parameter to 'skip' and load 12 songs initially, then load 8 more songs on each pagination
1414
sort: 'recent',
1515
order: 'desc',
1616
},

apps/frontend/src/modules/browse/WelcomeBanner.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export const WelcomeBanner = () => {
7171
</Link>
7272
{' • '}
7373
<Link
74-
href='https://opencollective.com/opennbs/donate/profile'
74+
href='https://opencollective.com/opennbs/donate'
7575
className='text-blue-400 hover:text-blue-300'
7676
>
7777
Donate

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export const HomePageComponent = () => {
8787
</div>
8888
<div className='h-6' />
8989
<SongCardGroup data-test='recent-songs'>
90-
{(recentSongs || []).map((song, i) =>
90+
{recentSongs.map((song, i) =>
9191
// TODO: currently null = skeleton, undefined = ad slot. There must be a more robust system to indicate this.
9292
song === undefined ? (
9393
<SongCardAdSlot key={i} />

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ const SongDataDisplay = ({ song }: { song: SongPreviewDtoType | null }) => {
4141
</div>
4242
<div className='flex flex-row justify-between items-center gap-4 px-4'>
4343
{/* Song author */}
44-
<p className='text-sm text-zinc-400 flex-1'>
44+
<p className='text-sm text-zinc-400 flex-1 text-pretty leading-tight'>
4545
{!song ? (
4646
<Skeleton />
4747
) : (

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

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type { PageDto, SongPreviewDtoType } from '@nbw/database';
77
import axiosInstance from '@web/lib/axios';
88

99
interface RecentSongsState {
10-
recentSongs: (SongPreviewDtoType | null)[];
10+
recentSongs: (SongPreviewDtoType | null | undefined)[];
1111
recentError: string;
1212
isLoading: boolean;
1313
hasMore: boolean;
@@ -28,6 +28,20 @@ type RecentSongsStore = RecentSongsState & RecentSongsActions;
2828

2929
const adCount = 1;
3030
const pageSize = 12;
31+
const fetchCount = pageSize - adCount;
32+
33+
function injectAdSlots(
34+
songs: SongPreviewDtoType[],
35+
): Array<SongPreviewDtoType | undefined> {
36+
const songsWithAds: Array<SongPreviewDtoType | undefined> = [...songs];
37+
38+
for (let i = 0; i < adCount; i++) {
39+
const adPosition = Math.floor(Math.random() * (songsWithAds.length + 1));
40+
songsWithAds.splice(adPosition, 0, undefined);
41+
}
42+
43+
return songsWithAds;
44+
}
3145

3246
export const useRecentSongsStore = create<RecentSongsStore>((set, get) => ({
3347
// Initial state
@@ -37,16 +51,13 @@ export const useRecentSongsStore = create<RecentSongsStore>((set, get) => ({
3751
hasMore: true,
3852
selectedCategory: '',
3953
categories: {},
40-
page: 0,
54+
page: 1,
4155

4256
// Actions
4357
initialize: (initialRecentSongs) => {
44-
// If no initial songs, set page to 1 to trigger fetch
45-
// Otherwise, keep page at 0 since we already have the first page of data
46-
const initialPage = initialRecentSongs.length === 0 ? 1 : 0;
4758
set({
48-
recentSongs: initialRecentSongs,
49-
page: initialPage,
59+
recentSongs: injectAdSlots(initialRecentSongs),
60+
page: 1,
5061
hasMore: true,
5162
recentError: '',
5263
});
@@ -68,8 +79,6 @@ export const useRecentSongsStore = create<RecentSongsStore>((set, get) => ({
6879
set({ isLoading: true });
6980

7081
try {
71-
const fetchCount = pageSize - adCount;
72-
7382
const params: Record<string, any> = {
7483
page,
7584
limit: fetchCount, // TODO: fix constants
@@ -86,20 +95,15 @@ export const useRecentSongsStore = create<RecentSongsStore>((set, get) => ({
8695
{ params },
8796
);
8897

89-
const newSongs: Array<SongPreviewDtoType | undefined> =
90-
response.data.content;
91-
92-
for (let i = 0; i < adCount; i++) {
93-
const adPosition = Math.floor(Math.random() * newSongs.length) + 1;
94-
newSongs.splice(adPosition, 0, undefined);
95-
}
98+
const fetchedSongs = response.data.content;
99+
const newSongs = injectAdSlots(fetchedSongs);
96100

97101
set((state) => ({
98102
recentSongs: [
99103
...state.recentSongs.filter((song) => song !== null),
100-
...response.data.content,
104+
...newSongs,
101105
],
102-
hasMore: response.data.content.length >= fetchCount,
106+
hasMore: fetchedSongs.length >= fetchCount,
103107
recentError: '',
104108
}));
105109
} catch (error) {
@@ -116,7 +120,7 @@ export const useRecentSongsStore = create<RecentSongsStore>((set, get) => ({
116120
set({
117121
selectedCategory: category,
118122
page: 1,
119-
recentSongs: Array(12).fill(null),
123+
recentSongs: Array(pageSize).fill(null),
120124
hasMore: true,
121125
});
122126
},
@@ -129,7 +133,7 @@ export const useRecentSongsStore = create<RecentSongsStore>((set, get) => ({
129133
}
130134

131135
set({
132-
recentSongs: [...recentSongs, ...Array(12).fill(null)],
136+
recentSongs: [...recentSongs, ...Array(pageSize).fill(null)],
133137
page: get().page + 1,
134138
});
135139
},
@@ -146,7 +150,7 @@ export const useRecentSongsPageLoader = () => {
146150
);
147151

148152
useEffect(() => {
149-
if (page === 0) return;
153+
if (page === 1) return; // Skip fetching page 1 as it's already loaded initially
150154
fetchRecentSongs();
151155
}, [page, selectedCategory, fetchRecentSongs]);
152156
};

0 commit comments

Comments
 (0)