4672 Commits

Author SHA1 Message Date
Rob Emery
660df92e78
Merge 28127b6c1b51f89d52adbff4f0babad11bf8c1f7 into ddab0da207525b521b23d898275e5cec59166eb5 2026-02-20 19:57:41 -08:00
Deluan
ddab0da207 docs: update commit message format in CONTRIBUTING.md
Signed-off-by: Deluan <deluan@navidrome.org>
2026-02-20 11:00:34 -05:00
Deluan Quintão
08a71320ea
fix(ui): make toggle switches visible in Gruvbox Dark theme (#5063) (#5064)
The secondary color (#3c3836) matches the panel/table cell background,
making checked MuiSwitch thumbs invisible. Add MuiSwitch override using
Gruvbox cyan (#458588), consistent with existing interactive elements.
2026-02-18 15:38:20 -05:00
Raphael Catolino
44a5482493
fix(ui): activity Indicator switching constantly between online/offline (#5054)
When using HTTP2, setting the writeTimeout too low causes the channel to
close before the keepAlive event has a chance of beeing sent.

Signed-off-by: rca <raphael.catolino@gmail.com>
Co-authored-by: Deluan Quintão <deluan@navidrome.org>
2026-02-17 14:47:20 -05:00
Deluan
5fa8356b31 chore(deps): bump golangci-lint to v2.10.0 and suppress new gosec false positives
Bump golangci-lint from v2.9.0 to v2.10.0, which includes a newer gosec
with additional taint-analysis rules (G117, G703, G704, G705) and a
stricter G101 check. Added inline //nolint:gosec comments to suppress
21 false positives across 19 files: struct fields flagged as secrets
(G117), w.Write calls flagged as XSS (G705), HTTP client calls flagged
as SSRF (G704), os.Stat/os.ReadFile/os.Remove flagged as path traversal
(G703), and a sort mapping flagged as hardcoded credentials (G101).

Signed-off-by: Deluan <deluan@navidrome.org>
2026-02-17 09:28:42 -05:00
Deluan Quintão
cad9cdc53e
fix(scanner): preserve created_at when moving songs between libraries (#5055)
* fix: preserve created_at when moving songs between libraries (#5050)

When songs are moved between libraries, their creation date was being
reset to the current time, causing them to incorrectly appear in
"Recently Added". Three changes fix this:

1. Add hash:"ignore" to AlbumID in MediaFile struct so that Equals()
   works for cross-library moves (AlbumID includes library prefix,
   making hashes always differ between libraries)

2. Preserve album created_at in moveMatched() via CopyAttributes,
   matching the pattern already used in persistAlbum() for
   within-library album ID changes

3. Only set CreatedAt in Put() when it's zero (new files), and
   explicitly copy missing.CreatedAt to the target in moveMatched()
   as defense-in-depth for the INSERT code path

* test: add regression tests for created_at preservation (#5050)

Add tests covering the three aspects of the fix:
- Scanner: moveMatched preserves missing track's created_at
- Scanner: CopyAttributes called for album created_at on album change
- Scanner: CopyAttributes not called when album ID stays the same
- Persistence: Put sets CreatedAt to now for new files with zero value
- Persistence: Put preserves non-zero CreatedAt on insert
- Persistence: Put does not reset CreatedAt on update

Also adds CopyAttributes to MockAlbumRepo for test support.

* test: verify album created_at is updated in cross-library move test (#5050)

Added end-to-end assertion in the cross-library move test to verify that
the new album's CreatedAt field is actually set to the original value after
CopyAttributes runs, not just that the method was called. This strengthens
the test by confirming the mock correctly propagates the timestamp.
2026-02-17 08:37:05 -05:00
Deluan
b774133cd1 chore(deps): update go-sqlite3 to v1.14.34 and pocketbase/dbx to v1.12.0
Signed-off-by: Deluan <deluan@navidrome.org>
2026-02-17 08:35:02 -05:00
Alanna
a20d56c137
fix(ui): prevent "Play Next" restarting play at top of queue (#5049)
Set playIndex when rebuilding the queue in reducePlayNext so the music
player library knows which track is currently playing. Without this, the
library's loadNewAudioLists defaults playIndex to 0, causing playback to
restart from the top of the queue on rapid "Play Next" actions.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 08:34:24 -05:00
Deluan
b64d8ad334 fix(server): return 404 instead of 500 for non-existent playlists
The native API endpoints GET /playlist/{id}/tracks and
GET /playlist/{id}/tracks/{id} were panicking with a nil pointer
dereference (resulting in a 500) when the playlist did not exist.
This happened because Tracks() returns nil for missing playlists,
and the nil repository was passed directly to the rest handler.
Extracted a shared playlistTracksHandler that checks for nil and
returns 404 early. Added tests covering both the error and happy paths.
2026-02-15 22:39:27 -05:00
Rob Emery
28127b6c1b go mod tidy 2026-02-15 19:38:06 +00:00
Rob Emery
c2068c6025 go mod tidy 2026-02-15 19:31:35 +00:00
Rob Emery
3636c3a513 Only the Artists collection requires a library id? 2026-02-15 19:30:55 +00:00
Rob Emery
9922847447 Fixing screwups during rebase 2026-02-15 19:30:53 +00:00
Rob Emery
4e0d6a4306 Should be an info, not warn 2026-02-15 19:29:43 +00:00
Rob Emery
c8938da42d Signature changed 2026-02-15 19:29:26 +00:00
Rob Emery
0ccb2989fa go tidy 2026-02-15 19:29:26 +00:00
Rob Emery
d4431cfbde Re-implementing the genre artists/tracks, as it looks like we can
push enough restrictions into the repo to get this out. I would
prefer to be able to do some sort of group-by for the
"get artists by genre" path though
2026-02-15 19:29:26 +00:00
Rob Emery
4a51608d38 Adding queries that should return the rough shape we want for refernce, if
we want want to implement this
2026-02-15 19:29:26 +00:00
Rob Emery
198d748b41 Artist for a given Genre doesn't work now, IIRC I remember there being
some chatter in #dev about it
2026-02-15 19:29:26 +00:00
Rob Emery
60b2bc4149 It seems not right for calling ParentID() to be messing with
o.Path?
2026-02-15 19:29:26 +00:00
Rob Emery
15c4943373 Renaming to make the difference more obvious during refactoring 2026-02-15 19:29:26 +00:00
Rob Emery
103a0603c5 I can't see a way within most implementations to get the client to
specify the size of artwork, so I'll const it for now
2026-02-15 19:29:26 +00:00
Rob Emery
a54c3eb4cf Renaming "object" to make it more obvious it's part of the CDS 2026-02-15 19:29:26 +00:00
Rob Emery
34ccd8cf20 This isn't and shouldn't be used 2026-02-15 19:29:26 +00:00
Rob Emery
ede4acf914 Pretty sure we only require the audio and images types here 2026-02-15 19:29:26 +00:00
Rob Emery
9c068f56be regenerated after merge 2026-02-15 19:29:26 +00:00
Rob Emery
d36e13f024 Regen wire 2026-02-15 19:29:26 +00:00
Rob Emery
a0ef9c5573 BFR has removed a few functions 2026-02-15 19:29:26 +00:00
Rob Emery
bb0cd6df9e Format 2026-02-15 19:29:26 +00:00
Rob Emery
7d94f2bf42 Placeholder sizes and real file sizes where known 2026-02-15 19:29:26 +00:00
Rob Emery
9164d59071 Another else done 2026-02-15 19:29:26 +00:00
Rob Emery
91479ee483 Removing elses where they're not needed etc 2026-02-15 19:29:26 +00:00
Rob Emery
56baf82a4d Fixing playlist tracks, we also don't need the tracks on the end
of the regex because they will link to /s/trackid instead
2026-02-15 19:29:26 +00:00
Rob Emery
883d65de14 Formatting 2026-02-15 19:29:24 +00:00
Rob Emery
335251384f 10 seconds not 10 ..very short periods of time 2026-02-15 19:28:55 +00:00
Rob Emery
2696eaee64 Refactoring a bit 2026-02-15 19:28:55 +00:00
Rob Emery
ea2942b73b More linting 2026-02-15 19:28:55 +00:00
Rob Emery
bc38481a75 Tidying up lints all over the place 2026-02-15 19:28:55 +00:00
Rob Emery
e9c4fa7892 Implementing recently added 2026-02-15 19:28:55 +00:00
Rob Emery
c6dd9732e5 Fixing artwork urls 2026-02-15 19:28:55 +00:00
Rob Emery
f7dbad2570 Redirecting away from raw file paths to stream endpoints 2026-02-15 19:28:55 +00:00
Rob Emery
dff87dc8ce Doesn't work, but barebones 2026-02-15 19:28:55 +00:00
Rob Emery
0ee848edfe Moving direct file access under /r/f/ so we can add /r/s/ for streaming 2026-02-15 19:28:55 +00:00
Rob Emery
ac04ea3834 Bit of a tidy up of objects and stuff 2026-02-15 19:28:55 +00:00
Rob Emery
0a6e04cc75 Date now set 2026-02-15 19:28:55 +00:00
Rob Emery
4449ee2952 Fixing the parent path, the path to the resource would only work if
the filename was passed as the path, but we want to use the streaming
methods, so we'll have to come up with something else
2026-02-15 19:28:55 +00:00
Rob Emery
1dd36fd685 cleaning out 2026-02-15 19:28:55 +00:00
Rob Emery
2c926106eb o.Path is always the current urlpath, so we can use that instead of
reassembling
2026-02-15 19:28:55 +00:00
Rob Emery
99dfaf307d Outputting a track object with metadata, we should use the trackid in the ID rather
than the title
2026-02-15 19:28:55 +00:00
Rob Emery
657d2e6e65 Now returns all tracks for a given genre by a given artist 2026-02-15 19:28:55 +00:00