mirror of
https://git.maid.zone/stuff/soundcloak.git
synced 2025-12-10 13:49:39 +05:00
preference to dynamically load comments and small fixes
This commit is contained in:
@@ -134,6 +134,7 @@ func defaultPreferences() {
|
|||||||
DefaultPreferences.ShowAudio = &False
|
DefaultPreferences.ShowAudio = &False
|
||||||
|
|
||||||
DefaultPreferences.SearchSuggestions = &False
|
DefaultPreferences.SearchSuggestions = &False
|
||||||
|
DefaultPreferences.DynamicLoadComments = &False
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadDefaultPreferences(loaded Preferences) {
|
func loadDefaultPreferences(loaded Preferences) {
|
||||||
@@ -216,6 +217,12 @@ func loadDefaultPreferences(loaded Preferences) {
|
|||||||
} else {
|
} else {
|
||||||
DefaultPreferences.SearchSuggestions = &False
|
DefaultPreferences.SearchSuggestions = &False
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if loaded.DynamicLoadComments != nil {
|
||||||
|
DefaultPreferences.DynamicLoadComments = loaded.DynamicLoadComments
|
||||||
|
} else {
|
||||||
|
DefaultPreferences.DynamicLoadComments = &False
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func boolean(in string) bool {
|
func boolean(in string) bool {
|
||||||
@@ -240,7 +247,7 @@ func fromEnv() error {
|
|||||||
env = os.Getenv("DEFAULT_PREFERENCES")
|
env = os.Getenv("DEFAULT_PREFERENCES")
|
||||||
if env != "" {
|
if env != "" {
|
||||||
var p Preferences
|
var p Preferences
|
||||||
err := json.Unmarshal([]byte(env), &p)
|
err := json.Unmarshal(S2b(env), &p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return wrappedError{err, "DEFAULT_PREFERENCES"}
|
return wrappedError{err, "DEFAULT_PREFERENCES"}
|
||||||
}
|
}
|
||||||
@@ -383,7 +390,7 @@ func fromEnv() error {
|
|||||||
env = os.Getenv("TRUSTED_PROXIES")
|
env = os.Getenv("TRUSTED_PROXIES")
|
||||||
if env != "" {
|
if env != "" {
|
||||||
var p []string
|
var p []string
|
||||||
err := json.Unmarshal([]byte(env), &p)
|
err := json.Unmarshal(S2b(env), &p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return wrappedError{err, "TRUSTED_PROXIES"}
|
return wrappedError{err, "TRUSTED_PROXIES"}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package cfg
|
package cfg
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
// seems soundcloud has 4 of these (i1, i2, i3, i4)
|
// seems soundcloud has 4 of these (i1, i2, i3, i4)
|
||||||
// they point to the same ip from my observations, and they all serve the same files
|
// they point to the same ip from my observations, and they all serve the same files
|
||||||
const ImageCDN = "i1.sndcdn.com"
|
const ImageCDN = "i1.sndcdn.com"
|
||||||
@@ -67,4 +69,14 @@ type Preferences struct {
|
|||||||
ShowAudio *bool // display audio (aac, opus, mpeg etc) under track player
|
ShowAudio *bool // display audio (aac, opus, mpeg etc) under track player
|
||||||
|
|
||||||
SearchSuggestions *bool // load search suggestions on main page
|
SearchSuggestions *bool // load search suggestions on main page
|
||||||
|
|
||||||
|
DynamicLoadComments *bool // dynamic comments loader without leaving track page
|
||||||
|
}
|
||||||
|
|
||||||
|
func B2s(b []byte) string {
|
||||||
|
return unsafe.String(unsafe.SliceData(b), len(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
func S2b(s string) []byte {
|
||||||
|
return unsafe.Slice(unsafe.StringData(s), len(s))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,13 +59,17 @@ func Defaults(dst *cfg.Preferences) {
|
|||||||
if dst.SearchSuggestions == nil {
|
if dst.SearchSuggestions == nil {
|
||||||
dst.SearchSuggestions = cfg.DefaultPreferences.SearchSuggestions
|
dst.SearchSuggestions = cfg.DefaultPreferences.SearchSuggestions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if dst.DynamicLoadComments == nil {
|
||||||
|
dst.DynamicLoadComments = cfg.DefaultPreferences.DynamicLoadComments
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Get(c fiber.Ctx) (cfg.Preferences, error) {
|
func Get(c fiber.Ctx) (cfg.Preferences, error) {
|
||||||
rawprefs := c.Cookies("prefs", "{}")
|
rawprefs := c.Cookies("prefs", "{}")
|
||||||
var p cfg.Preferences
|
var p cfg.Preferences
|
||||||
|
|
||||||
err := json.Unmarshal([]byte(rawprefs), &p)
|
err := json.Unmarshal(cfg.S2b(rawprefs), &p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return p, err
|
return p, err
|
||||||
}
|
}
|
||||||
@@ -87,6 +91,7 @@ type PrefsForm struct {
|
|||||||
DownloadAudio string
|
DownloadAudio string
|
||||||
ShowAudio string
|
ShowAudio string
|
||||||
SearchSuggestions string
|
SearchSuggestions string
|
||||||
|
DynamicLoadComments string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Export struct {
|
type Export struct {
|
||||||
@@ -178,6 +183,12 @@ func Load(r *fiber.App) {
|
|||||||
old.SearchSuggestions = &cfg.False
|
old.SearchSuggestions = &cfg.False
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if p.DynamicLoadComments == "on" {
|
||||||
|
old.DynamicLoadComments = &cfg.True
|
||||||
|
} else {
|
||||||
|
old.DynamicLoadComments = &cfg.False
|
||||||
|
}
|
||||||
|
|
||||||
old.Player = &p.Player
|
old.Player = &p.Player
|
||||||
|
|
||||||
data, err := json.Marshal(old)
|
data, err := json.Marshal(old)
|
||||||
@@ -187,7 +198,7 @@ func Load(r *fiber.App) {
|
|||||||
|
|
||||||
c.Cookie(&fiber.Cookie{
|
c.Cookie(&fiber.Cookie{
|
||||||
Name: "prefs",
|
Name: "prefs",
|
||||||
Value: string(data),
|
Value: cfg.B2s(data),
|
||||||
Expires: time.Now().Add(400 * 24 * time.Hour),
|
Expires: time.Now().Add(400 * 24 * time.Hour),
|
||||||
HTTPOnly: true,
|
HTTPOnly: true,
|
||||||
SameSite: "strict",
|
SameSite: "strict",
|
||||||
@@ -251,7 +262,7 @@ func Load(r *fiber.App) {
|
|||||||
|
|
||||||
c.Cookie(&fiber.Cookie{
|
c.Cookie(&fiber.Cookie{
|
||||||
Name: "prefs",
|
Name: "prefs",
|
||||||
Value: string(data),
|
Value: cfg.B2s(data),
|
||||||
Expires: time.Now().Add(400 * 24 * time.Hour),
|
Expires: time.Now().Add(400 * 24 * time.Hour),
|
||||||
HTTPOnly: true,
|
HTTPOnly: true,
|
||||||
SameSite: "strict",
|
SameSite: "strict",
|
||||||
|
|||||||
@@ -24,15 +24,15 @@ func Load(r *fiber.App) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
r.Get("/_/proxy/images", func(c fiber.Ctx) error {
|
r.Get("/_/proxy/images", func(c fiber.Ctx) error {
|
||||||
url := c.Query("url")
|
url := c.RequestCtx().QueryArgs().Peek("url")
|
||||||
if url == "" {
|
if len(url) == 0 {
|
||||||
return fiber.ErrBadRequest
|
return fiber.ErrBadRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
parsed := fasthttp.AcquireURI()
|
parsed := fasthttp.AcquireURI()
|
||||||
defer fasthttp.ReleaseURI(parsed)
|
defer fasthttp.ReleaseURI(parsed)
|
||||||
|
|
||||||
err := parsed.Parse(nil, []byte(url))
|
err := parsed.Parse(nil, url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,15 +13,15 @@ import (
|
|||||||
|
|
||||||
func Load(r *fiber.App) {
|
func Load(r *fiber.App) {
|
||||||
r.Get("/_/proxy/streams", func(c fiber.Ctx) error {
|
r.Get("/_/proxy/streams", func(c fiber.Ctx) error {
|
||||||
ur := c.Query("url")
|
ur := c.RequestCtx().QueryArgs().Peek("url")
|
||||||
if ur == "" {
|
if len(ur) == 0 {
|
||||||
return fiber.ErrBadRequest
|
return fiber.ErrBadRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
parsed := fasthttp.AcquireURI()
|
parsed := fasthttp.AcquireURI()
|
||||||
defer fasthttp.ReleaseURI(parsed)
|
defer fasthttp.ReleaseURI(parsed)
|
||||||
|
|
||||||
err := parsed.Parse(nil, []byte(ur))
|
err := parsed.Parse(nil, ur)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -52,15 +52,15 @@ func Load(r *fiber.App) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
r.Get("/_/proxy/streams/aac", func(c fiber.Ctx) error {
|
r.Get("/_/proxy/streams/aac", func(c fiber.Ctx) error {
|
||||||
ur := c.Query("url")
|
ur := c.RequestCtx().QueryArgs().Peek("url")
|
||||||
if ur == "" {
|
if len(ur) == 0 {
|
||||||
return fiber.ErrBadRequest
|
return fiber.ErrBadRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
parsed := fasthttp.AcquireURI()
|
parsed := fasthttp.AcquireURI()
|
||||||
defer fasthttp.ReleaseURI(parsed)
|
defer fasthttp.ReleaseURI(parsed)
|
||||||
|
|
||||||
err := parsed.Parse(nil, []byte(ur))
|
err := parsed.Parse(nil, ur)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -90,15 +90,15 @@ func Load(r *fiber.App) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
r.Get("/_/proxy/streams/playlist", func(c fiber.Ctx) error {
|
r.Get("/_/proxy/streams/playlist", func(c fiber.Ctx) error {
|
||||||
ur := c.Query("url")
|
ur := c.RequestCtx().QueryArgs().Peek("url")
|
||||||
if ur == "" {
|
if len(ur) == 0 {
|
||||||
return fiber.ErrBadRequest
|
return fiber.ErrBadRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
parsed := fasthttp.AcquireURI()
|
parsed := fasthttp.AcquireURI()
|
||||||
defer fasthttp.ReleaseURI(parsed)
|
defer fasthttp.ReleaseURI(parsed)
|
||||||
|
|
||||||
err := parsed.Parse(nil, []byte(ur))
|
err := parsed.Parse(nil, ur)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -127,13 +127,13 @@ func Load(r *fiber.App) {
|
|||||||
data = resp.Body()
|
data = resp.Body()
|
||||||
}
|
}
|
||||||
|
|
||||||
var sp = bytes.Split(data, []byte("\n"))
|
var sp = bytes.Split(data, []byte{'\n'})
|
||||||
for i, l := range sp {
|
for i, l := range sp {
|
||||||
if len(l) == 0 || l[0] == '#' {
|
if len(l) == 0 || l[0] == '#' {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
l = []byte("/_/proxy/streams?url=" + url.QueryEscape(string(l)))
|
l = []byte("/_/proxy/streams?url=" + url.QueryEscape(cfg.B2s(l)))
|
||||||
sp[i] = l
|
sp[i] = l
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,15 +141,15 @@ func Load(r *fiber.App) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
r.Get("/_/proxy/streams/playlist/aac", func(c fiber.Ctx) error {
|
r.Get("/_/proxy/streams/playlist/aac", func(c fiber.Ctx) error {
|
||||||
ur := c.Query("url")
|
ur := c.RequestCtx().QueryArgs().Peek("url")
|
||||||
if ur == "" {
|
if len(ur) == 0 {
|
||||||
return fiber.ErrBadRequest
|
return fiber.ErrBadRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
parsed := fasthttp.AcquireURI()
|
parsed := fasthttp.AcquireURI()
|
||||||
defer fasthttp.ReleaseURI(parsed)
|
defer fasthttp.ReleaseURI(parsed)
|
||||||
|
|
||||||
err := parsed.Parse(nil, []byte(ur))
|
err := parsed.Parse(nil, ur)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -186,14 +186,14 @@ func Load(r *fiber.App) {
|
|||||||
|
|
||||||
if l[0] == '#' {
|
if l[0] == '#' {
|
||||||
if bytes.HasPrefix(l, []byte(`#EXT-X-MAP:URI="`)) {
|
if bytes.HasPrefix(l, []byte(`#EXT-X-MAP:URI="`)) {
|
||||||
l = []byte(`#EXT-X-MAP:URI="/_/proxy/streams/aac?url=` + url.QueryEscape(string(l[16:len(l)-1])) + `"`)
|
l = []byte(`#EXT-X-MAP:URI="/_/proxy/streams/aac?url=` + url.QueryEscape(cfg.B2s(l[16:len(l)-1])) + `"`)
|
||||||
sp[i] = l
|
sp[i] = l
|
||||||
}
|
}
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
l = []byte("/_/proxy/streams/aac?url=" + url.QueryEscape(string(l)))
|
l = []byte("/_/proxy/streams/aac?url=" + url.QueryEscape(cfg.B2s(l)))
|
||||||
sp[i] = l
|
sp[i] = l
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ func Load(r *fiber.App) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var isDownload = c.Query("metadata") == "true"
|
var isDownload = string(c.RequestCtx().QueryArgs().Peek("metadata")) == "true"
|
||||||
var quality *string
|
var quality *string
|
||||||
if isDownload {
|
if isDownload {
|
||||||
quality = p.DownloadAudio
|
quality = p.DownloadAudio
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ func GetClientID() (string, error) {
|
|||||||
data = resp.Body()
|
data = resp.Body()
|
||||||
}
|
}
|
||||||
|
|
||||||
m, _ := verRegex.FindStringMatch(string(data))
|
m, _ := verRegex.FindStringMatch(cfg.B2s(data))
|
||||||
if m == nil {
|
if m == nil {
|
||||||
return "", ErrVersionNotFound
|
return "", ErrVersionNotFound
|
||||||
}
|
}
|
||||||
@@ -160,7 +160,7 @@ func GetClientID() (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if experimental_GetClientID {
|
if experimental_GetClientID {
|
||||||
m, _ = scriptRegex.FindStringMatch(string(data))
|
m, _ = scriptRegex.FindStringMatch(cfg.B2s(data))
|
||||||
if m != nil {
|
if m != nil {
|
||||||
g = m.GroupByNumber(1)
|
g = m.GroupByNumber(1)
|
||||||
if g != nil {
|
if g != nil {
|
||||||
@@ -175,7 +175,7 @@ func GetClientID() (string, error) {
|
|||||||
data = resp.Body()
|
data = resp.Body()
|
||||||
}
|
}
|
||||||
|
|
||||||
m, _ = clientIdRegex.FindStringMatch(string(data))
|
m, _ = clientIdRegex.FindStringMatch(cfg.B2s(data))
|
||||||
if m != nil {
|
if m != nil {
|
||||||
g = m.GroupByNumber(1)
|
g = m.GroupByNumber(1)
|
||||||
if g != nil {
|
if g != nil {
|
||||||
@@ -192,7 +192,7 @@ func GetClientID() (string, error) {
|
|||||||
ch := make(chan string, 1)
|
ch := make(chan string, 1)
|
||||||
wg := &sync.WaitGroup{}
|
wg := &sync.WaitGroup{}
|
||||||
done := false
|
done := false
|
||||||
m, _ = scriptsRegex.FindStringMatch(string(data))
|
m, _ = scriptsRegex.FindStringMatch(cfg.B2s(data))
|
||||||
for m != nil {
|
for m != nil {
|
||||||
g = m.GroupByNumber(1)
|
g = m.GroupByNumber(1)
|
||||||
if g != nil {
|
if g != nil {
|
||||||
|
|||||||
41
main.go
41
main.go
@@ -260,7 +260,7 @@ Disallow: /`)
|
|||||||
|
|
||||||
//fmt.Println(c.Hostname(), c.Protocol(), c.IPs())
|
//fmt.Println(c.Hostname(), c.Protocol(), c.IPs())
|
||||||
|
|
||||||
u, err := url.Parse(string(loc))
|
u, err := url.Parse(cfg.B2s(loc))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -771,8 +771,45 @@ Disallow: /`)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var downloadAudio *string
|
||||||
|
if cfg.Restream {
|
||||||
|
_, audio := track.Media.SelectCompatible(*prefs.DownloadAudio, true)
|
||||||
|
downloadAudio = &audio
|
||||||
|
}
|
||||||
|
|
||||||
c.Set("Content-Type", "text/html")
|
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, comments), templates.TrackHeader(prefs, track, true)).Render(c.RequestCtx(), c)
|
return templates.Base(track.Title+" by "+track.Author.Username, templates.Track(prefs, track, stream, displayErr, string(c.RequestCtx().QueryArgs().Peek("autoplay")) == "true", playlist, nextTrack, c.Query("volume"), mode, audio, downloadAudio, comments), templates.TrackHeader(prefs, track, true)).Render(c.RequestCtx(), c)
|
||||||
|
})
|
||||||
|
|
||||||
|
app.Get("/_/partials/comments/:id", func(c fiber.Ctx) error {
|
||||||
|
id := c.Params("id")
|
||||||
|
if id == "" {
|
||||||
|
return fiber.ErrBadRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
pagination := c.RequestCtx().QueryArgs().Peek("pagination")
|
||||||
|
if len(pagination) == 0 {
|
||||||
|
return fiber.ErrBadRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
prefs, err := preferences.Get(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
t := sc.Track{ID: json.Number(id)}
|
||||||
|
comm, err := t.GetComments("", prefs, cfg.B2s(pagination))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if comm.Next != "" {
|
||||||
|
c.Set("next", "?pagination="+url.QueryEscape(strings.Split(comm.Next, "/comments")[1]))
|
||||||
|
} else {
|
||||||
|
c.Set("next", "done")
|
||||||
|
}
|
||||||
|
|
||||||
|
return templates.Comments(comm).Render(c.RequestCtx(), c)
|
||||||
})
|
})
|
||||||
|
|
||||||
app.Get("/:user", func(c fiber.Ctx) error {
|
app.Get("/:user", func(c fiber.Ctx) error {
|
||||||
|
|||||||
25
static/assets/comments.js
Normal file
25
static/assets/comments.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
var comm = document.getElementById('comments');
|
||||||
|
function comments(self) {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('GET', '/_/partials/comments/'+self.getAttribute('data-id')+self.getAttribute('href'), true);
|
||||||
|
xhr.onerror = function(e) {
|
||||||
|
alert('Something went wrong. Check console');
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
xhr.onload = function() {
|
||||||
|
if (xhr.status != 200) {
|
||||||
|
alert(xhr.responseText);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
comm.innerHTML += xhr.responseText;
|
||||||
|
var next = xhr.getResponseHeader('next');
|
||||||
|
if (next == 'done') {
|
||||||
|
self.remove();
|
||||||
|
} else {
|
||||||
|
self.setAttribute('href', next);
|
||||||
|
}
|
||||||
|
self.textContent = 'more comments';
|
||||||
|
}
|
||||||
|
xhr.send();
|
||||||
|
}
|
||||||
@@ -65,7 +65,7 @@ templ Preferences(prefs cfg.Preferences) {
|
|||||||
<label>
|
<label>
|
||||||
Autoplay next track in playlists:
|
Autoplay next track in playlists:
|
||||||
@checkbox("AutoplayNextTrack", *prefs.AutoplayNextTrack)
|
@checkbox("AutoplayNextTrack", *prefs.AutoplayNextTrack)
|
||||||
(requires JS)
|
(requires JS; you need to allow autoplay from this domain!!)
|
||||||
</label>
|
</label>
|
||||||
if *prefs.AutoplayNextTrack {
|
if *prefs.AutoplayNextTrack {
|
||||||
<label>
|
<label>
|
||||||
@@ -81,6 +81,11 @@ templ Preferences(prefs cfg.Preferences) {
|
|||||||
@checkbox("SearchSuggestions", *prefs.SearchSuggestions)
|
@checkbox("SearchSuggestions", *prefs.SearchSuggestions)
|
||||||
(requires JS)
|
(requires JS)
|
||||||
</label>
|
</label>
|
||||||
|
<label>
|
||||||
|
Dynamically load comments:
|
||||||
|
@checkbox("DynamicLoadComments", *prefs.DynamicLoadComments)
|
||||||
|
(requires JS)
|
||||||
|
</label>
|
||||||
<label>
|
<label>
|
||||||
Player:
|
Player:
|
||||||
@sel("Player", []option{
|
@sel("Player", []option{
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ templ TrackItem(track *sc.Track, showUsername bool, overrideHref string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
templ Track(prefs cfg.Preferences, t sc.Track, stream string, displayErr string, autoplay bool, playlist *sc.Playlist, nextTrack *sc.Track, volume string, mode string, audio string, comments *sc.Paginated[*sc.Comment]) {
|
templ Track(prefs cfg.Preferences, t sc.Track, stream string, displayErr string, autoplay bool, playlist *sc.Playlist, nextTrack *sc.Track, volume string, mode string, audio string, downloadAudio *string, comments *sc.Paginated[*sc.Comment]) {
|
||||||
if t.Artwork != "" {
|
if t.Artwork != "" {
|
||||||
<img src={ t.Artwork } width="300px"/>
|
<img src={ t.Artwork } width="300px"/>
|
||||||
}
|
}
|
||||||
@@ -153,7 +153,7 @@ templ Track(prefs cfg.Preferences, t sc.Track, stream string, displayErr string,
|
|||||||
@TrackPlayer(prefs, t, stream, displayErr, autoplay, nextTrack, playlist, volume, mode, audio)
|
@TrackPlayer(prefs, t, stream, displayErr, autoplay, nextTrack, playlist, volume, mode, audio)
|
||||||
if cfg.Restream {
|
if cfg.Restream {
|
||||||
<div style="display: flex; margin-bottom: 1rem;">
|
<div style="display: flex; margin-bottom: 1rem;">
|
||||||
<a class="btn" href={ templ.SafeURL("/_/restream" + t.Href() + "?metadata=true") } download={ t.Permalink + "." + toExt(audio) }>download</a>
|
<a class="btn" href={ templ.SafeURL("/_/restream" + t.Href() + "?metadata=true") } download={ t.Permalink + "." + toExt(*downloadAudio) }>download</a>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
if t.Genre != "" {
|
if t.Genre != "" {
|
||||||
@@ -197,9 +197,36 @@ templ Track(prefs cfg.Preferences, t sc.Track, stream string, displayErr string,
|
|||||||
if t.TagList != "" {
|
if t.TagList != "" {
|
||||||
<p>Tags: { strings.Join(sc.TagListParser(t.TagList), ", ") }</p>
|
<p>Tags: { strings.Join(sc.TagListParser(t.TagList), ", ") }</p>
|
||||||
}
|
}
|
||||||
if comments != nil {
|
|
||||||
<h1>Comments</h1>
|
<h1>Comments</h1>
|
||||||
|
if *prefs.DynamicLoadComments {
|
||||||
|
if comments != nil {
|
||||||
|
<div id="comments">
|
||||||
|
@Comments(comments)
|
||||||
|
</div>
|
||||||
|
<script async src="/_/static/comments.js"></script>
|
||||||
|
if comments.Next != "" {
|
||||||
|
<a class="btn" href={ templ.SafeURL("?pagination=" + url.QueryEscape(strings.Split(comments.Next, "/comments")[1])) } rel="noreferrer" onclick="event.preventDefault(); comments(this)" data-id={ string(t.ID) }>more comments</a>
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
<div id="comments"></div>
|
||||||
|
<script async src="/_/static/comments.js"></script>
|
||||||
|
<a class="btn" href="?pagination=%3Flimit%3D20%26threaded%3D1" data-id={ string(t.ID) } onclick="event.preventDefault(); comments(this)">load comments</a>
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if comments != nil {
|
||||||
<div>
|
<div>
|
||||||
|
@Comments(comments)
|
||||||
|
</div>
|
||||||
|
if comments.Next != "" {
|
||||||
|
<a class="btn" href={ templ.SafeURL("?pagination=" + url.QueryEscape(strings.Split(comments.Next, "/comments")[1])) } rel="noreferrer">more comments</a>
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
<a class="btn" href="?pagination=%3Flimit%3D20%26threaded%3D1">load comments</a>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
templ Comments(comments *sc.Paginated[*sc.Comment]) {
|
||||||
for _, c := range comments.Collection {
|
for _, c := range comments.Collection {
|
||||||
<div class="listing">
|
<div class="listing">
|
||||||
if c.Author.Avatar != "" {
|
if c.Author.Avatar != "" {
|
||||||
@@ -213,10 +240,6 @@ templ Track(prefs cfg.Preferences, t sc.Track, stream string, displayErr string,
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
|
||||||
} else {
|
|
||||||
<a class="btn" href="?pagination=%3Flimit%3D20%26threaded%3D1">load comments</a>
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
templ TrackEmbed(prefs cfg.Preferences, t sc.Track, stream string, displayErr string) {
|
templ TrackEmbed(prefs cfg.Preferences, t sc.Track, stream string, displayErr string) {
|
||||||
|
|||||||
Reference in New Issue
Block a user