@@ -5,7 +5,11 @@ import (
55 "encoding/json"
66 "encoding/xml"
77 "fmt"
8+ lenspb "github.com/devgianlu/go-librespot/proto/spotify/lens"
9+ signalpb "github.com/devgianlu/go-librespot/proto/spotify/playlist/signal"
10+ playlist4pb "github.com/devgianlu/go-librespot/proto/spotify/playlist4"
811 "io"
12+ "net/url"
913 "strconv"
1014 "strings"
1115 "sync"
@@ -305,12 +309,54 @@ func (p *AppPlayer) handlePlayerCommand(req dealer.RequestPayload) error {
305309 return nil
306310 }
307311
312+ p .state .player .ContextUrl = req .Command .Context .Url
308313 p .state .player .ContextRestrictions = req .Command .Context .Restrictions
309- if p .state .player .ContextMetadata == nil {
310- p .state .player .ContextMetadata = map [string ]string {}
311- }
312- for k , v := range req .Command .Context .Metadata {
313- p .state .player .ContextMetadata [k ] = v
314+ p .state .player .ContextMetadata = req .Command .Context .Metadata
315+
316+ if strings .HasPrefix (req .Command .Context .Url , "context://" ) {
317+ parts := strings .Split (req .Command .Context .Url , "?" )
318+ if len (parts ) > 1 {
319+ query , err := url .ParseQuery (parts [1 ])
320+ if err != nil {
321+ return fmt .Errorf ("failed to parse context URL query: %w" , err )
322+ }
323+
324+ applyLenses := query ["spotify-apply-lenses" ]
325+ if len (applyLenses ) > 0 {
326+ if len (applyLenses ) > 1 {
327+ log .Warnf ("ignoring multiple spotify-apply-lenses: %v" , applyLenses )
328+ }
329+
330+ lensBytes , err := proto .Marshal (& lenspb.Lens {Identifier : applyLenses [0 ]})
331+ if err != nil {
332+ return fmt .Errorf ("failed to marshal lens: %w" , err )
333+ }
334+
335+ resp , err := p .sess .Spclient ().PlaylistSignals (
336+ librespot .SpotifyIdFromUri (p .state .player .ContextUri ),
337+ & playlist4pb.ListSignals {
338+ BaseRevision : nil , // FIXME?
339+ EmittedSignals : []* signalpb.Signal {{
340+ Identifier : "reset" ,
341+ Data : lensBytes ,
342+ }},
343+ },
344+ applyLenses ,
345+ )
346+ if err != nil {
347+ return fmt .Errorf ("failed to list playlist signals: %w" , err )
348+ }
349+
350+ if p .state .player .ContextMetadata == nil {
351+ p .state .player .ContextMetadata = make (map [string ]string )
352+ }
353+ for _ , attr := range resp .Attributes .FormatAttributes {
354+ p .state .player .ContextMetadata [* attr .Key ] = * attr .Value
355+ }
356+
357+ p .state .tracks .ApplySelectedListContent (resp )
358+ }
359+ }
314360 }
315361
316362 p .updateState ()
0 commit comments