diff --git a/lib/sc/track.go b/lib/sc/track.go index b4dfcd5..372fe02 100644 --- a/lib/sc/track.go +++ b/lib/sc/track.go @@ -481,3 +481,57 @@ func RecentTracks(cid string, prefs cfg.Preferences, args string) (*Paginated[*T return &p, nil } + +func (t *Track) GetRelated(cid string, prefs cfg.Preferences, args string) (*Paginated[*Track], error) { + p := Paginated[*Track]{ + Next: "https://" + api + "/tracks/" + string(t.ID) + "/related" + args, + } + + err := p.Proceed(cid, true) + if err != nil { + return nil, err + } + + for _, t := range p.Collection { + t.Fix(false, false) + t.Postfix(prefs, false) + } + + return &p, nil +} + +func (t *Track) GetPlaylists(cid string, prefs cfg.Preferences, args string) (*Paginated[*Playlist], error) { + p := Paginated[*Playlist]{ + Next: "https://" + api + "/tracks/" + string(t.ID) + "/playlists_without_albums" + args, + } + + err := p.Proceed(cid, true) + if err != nil { + return nil, err + } + + for _, p := range p.Collection { + p.Fix("", false, false) + p.Postfix(prefs, false, false) + } + + return &p, nil +} + +func (t *Track) GetAlbums(cid string, prefs cfg.Preferences, args string) (*Paginated[*Playlist], error) { + p := Paginated[*Playlist]{ + Next: "https://" + api + "/tracks/" + string(t.ID) + "/albums" + args, + } + + err := p.Proceed(cid, true) + if err != nil { + return nil, err + } + + for _, p := range p.Collection { + p.Fix("", false, false) + p.Postfix(prefs, false, false) + } + + return &p, nil +} diff --git a/main.go b/main.go index e7a69f1..f481974 100644 --- a/main.go +++ b/main.go @@ -325,6 +325,11 @@ func main() { preferences.Load(app) + // Currently, /:user is the tracks page + app.Get("/:user/tracks", func(c *fiber.Ctx) error { + return c.Redirect("/" + c.Params("user")) + }) + app.Get("/:user/sets", func(c *fiber.Ctx) error { prefs, err := preferences.Get(c) if err != nil { @@ -612,7 +617,7 @@ func main() { } c.Set("Content-Type", "text/html") - return templates.Base(track.Title+" by "+track.Author.Username, templates.Track(prefs, track, stream, displayErr, c.Query("autoplay") == "true", playlist, nextTrack, c.Query("volume"), mode, audio), templates.TrackHeader(prefs, track)).Render(context.Background(), c) + return templates.Base(track.Title+" by "+track.Author.Username, templates.Track(prefs, track, stream, displayErr, c.Query("autoplay") == "true", playlist, nextTrack, c.Query("volume"), mode, audio), templates.TrackHeader(prefs, track, true)).Render(context.Background(), c) }) app.Get("/:user", func(c *fiber.Ctx) error { @@ -711,5 +716,90 @@ func main() { return templates.Base(user.Username, templates.UserRelated(prefs, user, r), templates.UserHeader(user)).Render(context.Background(), c) }) + // I'd like to make this "related" but keeping it "recommended" to have the same url as soundcloud + app.Get("/:user/:track/recommended", func(c *fiber.Ctx) error { + prefs, err := preferences.Get(c) + if err != nil { + return err + } + + cid, err := sc.GetClientID() + if err != nil { + return err + } + + track, err := sc.GetTrack(cid, c.Params("user")+"/"+c.Params("track")) + if err != nil { + log.Printf("error getting %s from %s (related): %s\n", c.Params("track"), c.Params("user"), err) + return err + } + track.Postfix(prefs, true) + + r, err := track.GetRelated(cid, prefs, c.Query("pagination", "?limit=20")) + if err != nil { + log.Printf("error getting %s from %s related tracks: %s\n", c.Params("track"), c.Params("user"), err) + return err + } + + c.Set("Content-Type", "text/html") + return templates.Base(track.Title+" by "+track.Author.Username, templates.RelatedTracks(track, r), templates.TrackHeader(prefs, track, false)).Render(context.Background(), c) + }) + + app.Get("/:user/:track/sets", func(c *fiber.Ctx) error { + prefs, err := preferences.Get(c) + if err != nil { + return err + } + + cid, err := sc.GetClientID() + if err != nil { + return err + } + + track, err := sc.GetTrack(cid, c.Params("user")+"/"+c.Params("track")) + if err != nil { + log.Printf("error getting %s from %s (sets): %s\n", c.Params("track"), c.Params("user"), err) + return err + } + track.Postfix(prefs, true) + + p, err := track.GetPlaylists(cid, prefs, c.Query("pagination", "?limit=20")) + if err != nil { + log.Printf("error getting %s from %s sets: %s\n", c.Params("track"), c.Params("user"), err) + return err + } + + c.Set("Content-Type", "text/html") + return templates.Base(track.Title+" by "+track.Author.Username, templates.TrackInPlaylists(track, p), templates.TrackHeader(prefs, track, false)).Render(context.Background(), c) + }) + + app.Get("/:user/:track/albums", func(c *fiber.Ctx) error { + prefs, err := preferences.Get(c) + if err != nil { + return err + } + + cid, err := sc.GetClientID() + if err != nil { + return err + } + + track, err := sc.GetTrack(cid, c.Params("user")+"/"+c.Params("track")) + if err != nil { + log.Printf("error getting %s from %s (albums): %s\n", c.Params("track"), c.Params("user"), err) + return err + } + track.Postfix(prefs, true) + + p, err := track.GetAlbums(cid, prefs, c.Query("pagination", "?limit=20")) + if err != nil { + log.Printf("error getting %s from %s albums: %s\n", c.Params("track"), c.Params("user"), err) + return err + } + + c.Set("Content-Type", "text/html") + return templates.Base(track.Title+" by "+track.Author.Username, templates.TrackInAlbums(track, p), templates.TrackHeader(prefs, track, false)).Render(context.Background(), c) + }) + log.Fatal(app.Listen(cfg.Addr)) } diff --git a/templates/track.templ b/templates/track.templ index 6504254..fdec964 100644 --- a/templates/track.templ +++ b/templates/track.templ @@ -10,24 +10,40 @@ import ( func toExt(audio string) string { switch audio { - case cfg.AudioAAC: - return "m4a" - case cfg.AudioOpus: - return "ogg" - case cfg.AudioMP3: - return "mp3" + case cfg.AudioAAC: + return "m4a" + case cfg.AudioOpus: + return "ogg" + case cfg.AudioMP3: + return "mp3" } return "" } -templ TrackHeader(prefs cfg.Preferences, t sc.Track) { +templ TrackButtons(current string, track sc.Track) { +
Only a 30-second snippet is available.
} - if *prefs.ShowAudio {{ t.Genre }
+{ t.Genre }
} if playlist != nil {{ strconv.FormatInt(t.Likes, 10) } likes
@@ -212,3 +233,60 @@ templ SearchTracks(p *sc.Paginated[*sc.Track]) { } } } + +templ RelatedTracks(t sc.Track, p *sc.Paginated[*sc.Track]) { + if t.Artwork != "" { +no more results
+ } else { + for _, track := range p.Collection { + @TrackItem(track, true, "") + } + if p.Next != "" { + more tracks + } + } +} + +templ TrackInAlbums(t sc.Track, p *sc.Paginated[*sc.Playlist]) { + if t.Artwork != "" { +no more albums
+ } else { + for _, playlist := range p.Collection { + @PlaylistItem(playlist, true) + } + if p.Next != "" { + more albums + } + } +} + +templ TrackInPlaylists(t sc.Track, p *sc.Paginated[*sc.Playlist]) { + if t.Artwork != "" { +no more playlists
+ } else { + for _, playlist := range p.Collection { + @PlaylistItem(playlist, true) + } + if p.Next != "" { + more playlists + } + } +} diff --git a/templates/user.templ b/templates/user.templ index a1e576a..8201da2 100644 --- a/templates/user.templ +++ b/templates/user.templ @@ -83,7 +83,7 @@ type btn struct { templ UserButtons(current string, user string) {