Spotify Link-Through & Navidrome Logo Overlay #15
@@ -25,10 +25,10 @@ import (
|
||||
|
||||
// Configuration keys
|
||||
const (
|
||||
clientIDKey = "clientid"
|
||||
usersKey = "users"
|
||||
activityNameKey = "activityname"
|
||||
navLogoOverlayKey = "navlogooverlay"
|
||||
clientIDKey = "clientid"
|
||||
usersKey = "users"
|
||||
activityNameKey = "activityname"
|
||||
spotifyLinksKey = "spotifylinks"
|
||||
)
|
||||
|
||||
// navidromeLogoURL is the small overlay image shown in the bottom-right of the album art.
|
||||
@@ -162,16 +162,15 @@ func (p *discordPlugin) NowPlaying(input scrobbler.NowPlayingRequest) error {
|
||||
activityName = input.Track.Artist
|
||||
}
|
||||
|
||||
// Navidrome logo overlay: shown by default; disabled only when explicitly set to "false"
|
||||
navLogoOption, _ := pdk.GetConfig(navLogoOverlayKey)
|
||||
smallImage, smallText := "", ""
|
||||
if navLogoOption != "false" {
|
||||
smallImage = navidromeLogoURL
|
||||
smallText = "Navidrome"
|
||||
// Resolve Spotify URLs if enabled
|
||||
var spotifyURL, artistSearchURL string
|
||||
spotifyLinksOption, _ := pdk.GetConfig(spotifyLinksKey)
|
||||
if spotifyLinksOption == "true" {
|
||||
spotifyURL = resolveSpotifyURL(input.Track)
|
||||
artistSearchURL = spotifySearch(input.Track.Artist)
|
||||
}
|
||||
|
||||
// Send activity update
|
||||
spotifyURL := resolveSpotifyURL(input.Track)
|
||||
if err := rpc.sendActivity(clientID, input.Username, userToken, activity{
|
||||
Application: clientID,
|
||||
Name: activityName,
|
||||
@@ -179,7 +178,7 @@ func (p *discordPlugin) NowPlaying(input scrobbler.NowPlayingRequest) error {
|
||||
Details: input.Track.Title,
|
||||
DetailsURL: spotifyURL,
|
||||
State: input.Track.Artist,
|
||||
StateURL: spotifySearch(input.Track.Artist),
|
||||
StateURL: artistSearchURL,
|
||||
StatusDisplayType: 2,
|
||||
Timestamps: activityTimestamps{
|
||||
Start: startTime,
|
||||
@@ -189,8 +188,8 @@ func (p *discordPlugin) NowPlaying(input scrobbler.NowPlayingRequest) error {
|
||||
LargeImage: getImageURL(input.Username, input.Track.ID),
|
||||
LargeText: input.Track.Album,
|
||||
LargeURL: spotifyURL,
|
||||
SmallImage: smallImage,
|
||||
SmallText: smallText,
|
||||
SmallImage: navidromeLogoURL,
|
||||
SmallText: "Navidrome",
|
||||
},
|
||||
}); err != nil {
|
||||
return fmt.Errorf("%w: failed to send activity: %v", scrobbler.ScrobblerErrorRetryLater, err)
|
||||
|
||||
+7
-7
@@ -121,7 +121,7 @@ var _ = Describe("discordPlugin", func() {
|
||||
pdk.PDKMock.On("GetConfig", usersKey).Return(`[{"username":"testuser","token":"test-token"}]`, true)
|
||||
pdk.PDKMock.On("GetConfig", uguuEnabledKey).Return("", false)
|
||||
pdk.PDKMock.On("GetConfig", activityNameKey).Return("", false)
|
||||
pdk.PDKMock.On("GetConfig", navLogoOverlayKey).Return("", false)
|
||||
pdk.PDKMock.On("GetConfig", spotifyLinksKey).Return("", false)
|
||||
|
||||
// Connect mocks (isConnected check via heartbeat)
|
||||
host.CacheMock.On("GetInt", "discord.seq.testuser").Return(int64(0), false, errors.New("not found"))
|
||||
@@ -142,15 +142,15 @@ var _ = Describe("discordPlugin", func() {
|
||||
// Cancel existing clear schedule (may or may not exist)
|
||||
host.SchedulerMock.On("CancelSchedule", "testuser-clear").Return(nil)
|
||||
|
||||
// Cache mocks (Spotify URL resolution + Discord image processing)
|
||||
// Cache mocks (Discord image processing)
|
||||
host.CacheMock.On("GetString", mock.Anything).Return("", false, nil)
|
||||
host.CacheMock.On("SetString", mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
||||
host.ArtworkMock.On("GetTrackUrl", "track1", int32(300)).Return("https://example.com/art.jpg", nil)
|
||||
|
||||
// Mock HTTP POST requests (ListenBrainz + Discord external assets API)
|
||||
// Mock HTTP POST requests (Discord external assets API)
|
||||
postReq := &pdk.HTTPRequest{}
|
||||
pdk.PDKMock.On("NewHTTPRequest", pdk.MethodPost, mock.Anything).Return(postReq)
|
||||
pdk.PDKMock.On("Send", postReq).Return(pdk.NewStubHTTPResponse(200, nil, []byte(`[{"spotify_track_ids":[]}]`)))
|
||||
pdk.PDKMock.On("Send", postReq).Return(pdk.NewStubHTTPResponse(200, nil, []byte(`{}`)))
|
||||
|
||||
// Schedule clear activity callback
|
||||
host.SchedulerMock.On("ScheduleOneTime", mock.Anything, payloadClearActivity, "testuser-clear").Return("testuser-clear", nil)
|
||||
@@ -175,7 +175,7 @@ var _ = Describe("discordPlugin", func() {
|
||||
pdk.PDKMock.On("GetConfig", usersKey).Return(`[{"username":"testuser","token":"test-token"}]`, true)
|
||||
pdk.PDKMock.On("GetConfig", uguuEnabledKey).Return("", false)
|
||||
pdk.PDKMock.On("GetConfig", activityNameKey).Return(configValue, configExists)
|
||||
pdk.PDKMock.On("GetConfig", navLogoOverlayKey).Return("", false)
|
||||
pdk.PDKMock.On("GetConfig", spotifyLinksKey).Return("", false)
|
||||
|
||||
// Connect mocks
|
||||
host.CacheMock.On("GetInt", "discord.seq.testuser").Return(int64(0), false, errors.New("not found"))
|
||||
@@ -195,13 +195,13 @@ var _ = Describe("discordPlugin", func() {
|
||||
host.SchedulerMock.On("ScheduleRecurring", mock.Anything, payloadHeartbeat, "testuser").Return("testuser", nil)
|
||||
host.SchedulerMock.On("CancelSchedule", "testuser-clear").Return(nil)
|
||||
|
||||
// Cache mocks (Spotify URL resolution + Discord image processing)
|
||||
// Cache mocks (Discord image processing)
|
||||
host.CacheMock.On("GetString", mock.Anything).Return("", false, nil)
|
||||
host.CacheMock.On("SetString", mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
||||
host.ArtworkMock.On("GetTrackUrl", "track1", int32(300)).Return("https://example.com/art.jpg", nil)
|
||||
postReq := &pdk.HTTPRequest{}
|
||||
pdk.PDKMock.On("NewHTTPRequest", pdk.MethodPost, mock.Anything).Return(postReq)
|
||||
pdk.PDKMock.On("Send", postReq).Return(pdk.NewStubHTTPResponse(200, nil, []byte(`[{"spotify_track_ids":[]}]`)))
|
||||
pdk.PDKMock.On("Send", postReq).Return(pdk.NewStubHTTPResponse(200, nil, []byte(`{}`)))
|
||||
host.SchedulerMock.On("ScheduleOneTime", mock.Anything, payloadClearActivity, "testuser-clear").Return("testuser-clear", nil)
|
||||
|
||||
err := plugin.NowPlaying(scrobbler.NowPlayingRequest{
|
||||
|
||||
+5
-5
@@ -65,11 +65,11 @@
|
||||
"title": "Upload artwork to uguu.se (enable if Navidrome is not publicly accessible)",
|
||||
"default": false
|
||||
},
|
||||
"navlogooverlay": {
|
||||
"spotifylinks": {
|
||||
"type": "boolean",
|
||||
"title": "Show Navidrome logo overlay on album art",
|
||||
"description": "Displays the Navidrome logo as a small overlay in the corner of the album artwork in Discord",
|
||||
"default": true
|
||||
"title": "Enable Spotify link-through",
|
||||
"description": "When enabled, clicking the track title or album art in Discord opens the corresponding Spotify page",
|
||||
"default": false
|
||||
},
|
||||
"users": {
|
||||
"type": "array",
|
||||
@@ -124,7 +124,7 @@
|
||||
},
|
||||
{
|
||||
"type": "Control",
|
||||
"scope": "#/properties/navlogooverlay"
|
||||
"scope": "#/properties/spotifylinks"
|
||||
},
|
||||
{
|
||||
"type": "Control",
|
||||
|
||||
Reference in New Issue
Block a user