From dae21ddddb000f7937448420c1e1fbfaa9348225 Mon Sep 17 00:00:00 2001 From: Baraa Al-Masri Date: Sat, 8 Jun 2024 15:57:11 +0300 Subject: [PATCH 01/26] fix(router): add query on refresh --- app/static/js/router.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/static/js/router.js b/app/static/js/router.js index d220767..b07b1cc 100644 --- a/app/static/js/router.js +++ b/app/static/js/router.js @@ -34,7 +34,9 @@ window.addEventListener("load", () => { */ async function updateMainContent(path) { Utils.showLoading(); - await fetch(path + "?no_layout=true") + const query = new URLSearchParams(location.search); + query.set("no_layout", "true"); + await fetch(path + "?" + query.toString()) .then((res) => res.text()) .then((page) => { mainContentsEl.innerHTML = page; From 25870b3c8b78cf932d2645e21970b5a97afe25ce Mon Sep 17 00:00:00 2001 From: Baraa Al-Masri Date: Sat, 8 Jun 2024 16:41:56 +0300 Subject: [PATCH 02/26] chore(requests): add another check for mobile --- app/handlers/handler.go | 3 ++- app/static/js/utils.js | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/app/handlers/handler.go b/app/handlers/handler.go index 785332e..0ea9339 100644 --- a/app/handlers/handler.go +++ b/app/handlers/handler.go @@ -148,7 +148,8 @@ func (a *Handler) authenticate(r *http.Request) (entities.Profile, error) { } func isMobile(r *http.Request) bool { - return strings.Contains(strings.ToLower(r.Header.Get("User-Agent")), "mobile") + return strings.Contains(strings.ToLower(r.Header.Get("User-Agent")), "mobile") || + strings.Contains(strings.ToLower(r.Header.Get("X-Is-Mobile")), "true") } func getTheme(r *http.Request) string { diff --git a/app/static/js/utils.js b/app/static/js/utils.js index 8d53827..41a73c6 100644 --- a/app/static/js/utils.js +++ b/app/static/js/utils.js @@ -53,6 +53,26 @@ function copyTextToClipboard(text) { textArea.hidden = true; } +let isMobile = window.innerWidth < 768; + +/** + * @param {EventTarget} e + */ +window.addEventListener("resize", (e) => { + if (e.target.innerWidth < 768 && !isMobile) { + isMobile = true; + (function (send) { + XMLHttpRequest.prototype.send = function (data) { + this.setRequestHeader("X-Is-Mobile", isMobile); + send.apply(this, data); + }; + })(XMLHttpRequest.prototype.send); + } + if (e.target.innerWidth > 768 && isMobile) { + isMobile = false; + } +}); + window.Utils = { showLoading, hideLoading, From 3d05ceb7002c5971ab1c9a4f5afdc3f81bfd6060 Mon Sep 17 00:00:00 2001 From: Baraa Al-Masri Date: Sat, 8 Jun 2024 17:05:40 +0300 Subject: [PATCH 03/26] chore(router): replace `fetch` with `htmx.ajax` --- app/static/js/router.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/static/js/router.js b/app/static/js/router.js index b07b1cc..d25e8b6 100644 --- a/app/static/js/router.js +++ b/app/static/js/router.js @@ -36,10 +36,10 @@ async function updateMainContent(path) { Utils.showLoading(); const query = new URLSearchParams(location.search); query.set("no_layout", "true"); - await fetch(path + "?" + query.toString()) - .then((res) => res.text()) - .then((page) => { - mainContentsEl.innerHTML = page; + htmx + .ajax("GET", path + "?" + query.toString(), { + target: "#main-contents", + swap: "innerHTML", }) .catch(() => { window.location.reload(); From 21cf452abd0b4ec68b4b14fe799ae59951e1f30c Mon Sep 17 00:00:00 2001 From: Baraa Al-Masri Date: Sat, 8 Jun 2024 17:26:16 +0300 Subject: [PATCH 04/26] feat(animation): add into view animation --- app/static/css/style.css | 33 +++++++++++++++++++++++- app/views/components/menus/popover.templ | 2 +- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/app/static/css/style.css b/app/static/css/style.css index b528de3..7430d75 100644 --- a/app/static/css/style.css +++ b/app/static/css/style.css @@ -2,6 +2,38 @@ @tailwind components; @tailwind utilities; +:root { + --animation-duration: 0.4s; +} + +.animate-in { + animation: animate-down calc(var(--animation-duration) -0.1s) ease-in-out; +} + +main { + animation: animate-up calc(var(--animation-duration) -0.1s) ease-in-out; +} + +@keyframes animate-down { + 0% { + transform: translateY(-10px); + } + + 100% { + transform: translateY(0px); + } +} + +@keyframes animate-up { + 0% { + transform: translateY(10px); + } + + 100% { + transform: translateY(0px); + } +} + html, body { overscroll-behavior-y: none; @@ -16,7 +48,6 @@ table { } * { - --animation-duration: 0.4s; -webkit-transition: all var(--animation-duration), background-color var(--animation-duration), diff --git a/app/views/components/menus/popover.templ b/app/views/components/menus/popover.templ index 7f688e3..039d457 100644 --- a/app/views/components/menus/popover.templ +++ b/app/views/components/menus/popover.templ @@ -21,7 +21,7 @@ templ Popover(id, title string, button, child templ.Component) { id={ fmt.Sprintf("popover-%s", id) } class={ "hidden", "absolute", "z-50", "top-[45px]", "right-[0px]", - "shadow-md", "min-w-[150px]", + "shadow-md", "min-w-[150px]", "animate-in", } > @child From 4245b9eb345f3c12c228bc361b745192ae807954 Mon Sep 17 00:00:00 2001 From: Baraa Al-Masri Date: Sat, 8 Jun 2024 17:28:50 +0300 Subject: [PATCH 05/26] chore(requests): add another check for mobile --- app/static/js/utils.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/app/static/js/utils.js b/app/static/js/utils.js index 41a73c6..51a2124 100644 --- a/app/static/js/utils.js +++ b/app/static/js/utils.js @@ -55,21 +55,28 @@ function copyTextToClipboard(text) { let isMobile = window.innerWidth < 768; +function setIsMobileHeader() { + (function (send) { + XMLHttpRequest.prototype.send = function (data) { + this.setRequestHeader("X-Is-Mobile", isMobile); + send.apply(this, data); + }; + })(XMLHttpRequest.prototype.send); +} + /** * @param {EventTarget} e */ window.addEventListener("resize", (e) => { if (e.target.innerWidth < 768 && !isMobile) { isMobile = true; - (function (send) { - XMLHttpRequest.prototype.send = function (data) { - this.setRequestHeader("X-Is-Mobile", isMobile); - send.apply(this, data); - }; - })(XMLHttpRequest.prototype.send); + setIsMobileHeader(); + window.location.reload(); } if (e.target.innerWidth > 768 && isMobile) { isMobile = false; + setIsMobileHeader(); + window.location.reload(); } }); From dc2377720d4d431eea462a401ba80594265df430 Mon Sep 17 00:00:00 2001 From: Baraa Al-Masri Date: Sat, 8 Jun 2024 17:37:55 +0300 Subject: [PATCH 06/26] chore(idk): idk --- app/static/js/utils.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/static/js/utils.js b/app/static/js/utils.js index 51a2124..fbbcd66 100644 --- a/app/static/js/utils.js +++ b/app/static/js/utils.js @@ -64,6 +64,10 @@ function setIsMobileHeader() { })(XMLHttpRequest.prototype.send); } +(() => { + setIsMobileHeader(); +})(); + /** * @param {EventTarget} e */ From cc57c439f3829d645b539643419d89318adcdb9b Mon Sep 17 00:00:00 2001 From: Baraa Al-Masri Date: Sat, 8 Jun 2024 22:46:39 +0300 Subject: [PATCH 07/26] fix(themeswitch): unique id for desktop and mobile --- app/views/components/themeswitch/themeswitch.templ | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/views/components/themeswitch/themeswitch.templ b/app/views/components/themeswitch/themeswitch.templ index 38d4719..364b5fc 100644 --- a/app/views/components/themeswitch/themeswitch.templ +++ b/app/views/components/themeswitch/themeswitch.templ @@ -1,6 +1,8 @@ package themeswitch import "dankmuzikk/views/components/menus" +import "fmt" +import "math/rand" var themes = []struct { displayName string @@ -21,7 +23,7 @@ var themes = []struct { } templ ThemeSwitch() { - @menus.Popover("theme-switcher", "Change theme", themeSwitchButton(), themeSwitch()) + @menus.Popover("theme-switcher-"+fmt.Sprint(rand.Int()), "Change theme", themeSwitchButton(), themeSwitch()) } templ themeSwitch() { From 337bc575de5dd16b3e6a6818acaeff446a904aa9 Mon Sep 17 00:00:00 2001 From: Baraa Al-Masri Date: Sat, 8 Jun 2024 23:10:54 +0300 Subject: [PATCH 08/26] refactor(header): merge mobile and desktop headers --- app/views/components/header/header.templ | 83 ++++++++++-------------- 1 file changed, 33 insertions(+), 50 deletions(-) diff --git a/app/views/components/header/header.templ b/app/views/components/header/header.templ index fe46773..1d604fc 100644 --- a/app/views/components/header/header.templ +++ b/app/views/components/header/header.templ @@ -20,40 +20,43 @@ templ homeLinkContainer() { } -templ mobileHeader() { -
-
- @navlink.ImageRouteLink("/about", "About", icons.About()) -
- DankMuzikk Logo -

DankMuzikk

+templ Header() { +
+
+
+ @navlink.JustLink("/", "Home", homeLinkContainer()) +
+
+ @navlink.JustLink("/about", "About", icons.About()) +
+ DankMuzikk Logo +

DankMuzikk

+
+ @themeswitch.ThemeSwitch()
- @themeswitch.ThemeSwitch() -
-
- @search.Search()
-
-} - -templ desktopHeader() { -
- @navlink.LinkContainer("/", "Home", homeLinkContainer()) -
+
@search.Search()
-
+
@themeswitch.ThemeSwitch()
-
-} - -templ Header() { -
- // mobiles are usually shitty at rendering, so this prevents mobiles from rendering two blocks and choosing one using CSS. - if isMobile, ok := ctx.Value("is-mobile").(bool); ok && isMobile { - @mobileHeader() - } else { -
- @desktopHeader() -
- -
- @mobileHeader() -
- }
// script is being used here, so it doesn't render twice on desktops and break shit. From 2304bb06d4d7b840afac88c8c5d8d3e1703459e4 Mon Sep 17 00:00:00 2001 From: Baraa Al-Masri Date: Sun, 9 Jun 2024 14:02:13 +0300 Subject: [PATCH 19/26] feat(handlers): add playlist and song getters --- app/cmd/server/server.go | 2 ++ app/handlers/apis/playlist.go | 22 ++++++++++++++++++++++ app/handlers/apis/songs.go | 18 ++++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/app/cmd/server/server.go b/app/cmd/server/server.go index da6cc3f..f6ee178 100644 --- a/app/cmd/server/server.go +++ b/app/cmd/server/server.go @@ -101,11 +101,13 @@ func StartServer(staticFS embed.FS) error { apisHandler.HandleFunc("GET /logout", apis.HandleLogout) apisHandler.HandleFunc("GET /search-suggestion", apis.HandleSearchSuggestions) apisHandler.HandleFunc("GET /song", gHandler.OptionalAuthApi(songApi.HandlePlaySong)) + apisHandler.HandleFunc("GET /song/single", gHandler.OptionalAuthApi(songApi.HandleGetSong)) apisHandler.HandleFunc("PUT /song/playlist", gHandler.AuthApi(playlistsApi.HandleToggleSongInPlaylist)) apisHandler.HandleFunc("PUT /song/playlist/plays", gHandler.AuthApi(songApi.HandleIncrementSongPlaysInPlaylist)) apisHandler.HandleFunc("PUT /song/playlist/upvote", gHandler.AuthApi(songApi.HandleUpvoteSongPlaysInPlaylist)) apisHandler.HandleFunc("PUT /song/playlist/downvote", gHandler.AuthApi(songApi.HandleDownvoteSongPlaysInPlaylist)) apisHandler.HandleFunc("GET /playlist/all", gHandler.AuthApi(playlistsApi.HandleGetPlaylistsForPopover)) + apisHandler.HandleFunc("GET /playlist", gHandler.AuthApi(playlistsApi.HandleGetPlaylist)) apisHandler.HandleFunc("POST /playlist", gHandler.AuthApi(playlistsApi.HandleCreatePlaylist)) apisHandler.HandleFunc("PUT /playlist/public", gHandler.AuthApi(playlistsApi.HandleTogglePublicPlaylist)) apisHandler.HandleFunc("PUT /playlist/join", gHandler.AuthApi(playlistsApi.HandleToggleJoinPlaylist)) diff --git a/app/handlers/apis/playlist.go b/app/handlers/apis/playlist.go index 21a1714..3354fb5 100644 --- a/app/handlers/apis/playlist.go +++ b/app/handlers/apis/playlist.go @@ -140,6 +140,28 @@ func (p *playlistApi) HandleToggleJoinPlaylist(w http.ResponseWriter, r *http.Re } } +func (p *playlistApi) HandleGetPlaylist(w http.ResponseWriter, r *http.Request) { + profileId, profileIdCorrect := r.Context().Value(handlers.ProfileIdKey).(uint) + if !profileIdCorrect { + w.Write([]byte("🤷‍♂️")) + return + } + + playlistId := r.URL.Query().Get("playlist-id") + if playlistId == "" { + w.WriteHeader(http.StatusBadRequest) + return + } + + playlist, _, err := p.service.Get(playlistId, profileId) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + log.Errorln(err) + return + } + _ = json.NewEncoder(w).Encode(playlist) +} + func (p *playlistApi) HandleDeletePlaylist(w http.ResponseWriter, r *http.Request) { profileId, profileIdCorrect := r.Context().Value(handlers.ProfileIdKey).(uint) if !profileIdCorrect { diff --git a/app/handlers/apis/songs.go b/app/handlers/apis/songs.go index 5d68448..2fbb301 100644 --- a/app/handlers/apis/songs.go +++ b/app/handlers/apis/songs.go @@ -6,6 +6,7 @@ import ( "dankmuzikk/services/history" "dankmuzikk/services/playlists/songs" "dankmuzikk/services/youtube/download" + "encoding/json" "fmt" "net/http" ) @@ -130,3 +131,20 @@ func (s *songDownloadHandler) HandlePlaySong(w http.ResponseWriter, r *http.Requ return } } + +func (s *songDownloadHandler) HandleGetSong(w http.ResponseWriter, r *http.Request) { + id := r.URL.Query().Get("id") + if id == "" { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte("missing song's yt id")) + return + } + + song, err := s.songsService.GetSong(id) + if err != nil { + log.Errorln(err) + w.WriteHeader(http.StatusInternalServerError) + return + } + _ = json.NewEncoder(w).Encode(song) +} From f333ea381994e0de59ce5c758a93d1bda608c846 Mon Sep 17 00:00:00 2001 From: Baraa Al-Masri Date: Sun, 9 Jun 2024 14:02:56 +0300 Subject: [PATCH 20/26] chore(lazyload): lazy load songs and playlists --- app/static/js/player.js | 58 ++++++++++++++++++++++++++++ app/views/components/song/song.templ | 22 +++++------ app/views/pages/playlist.templ | 6 +-- 3 files changed, 72 insertions(+), 14 deletions(-) diff --git a/app/static/js/player.js b/app/static/js/player.js index 4c28746..4a4c151 100644 --- a/app/static/js/player.js +++ b/app/static/js/player.js @@ -631,6 +631,24 @@ async function playSingleSong(song) { await playSong(song); } +/** + * @param {string} songYtId + */ +async function playSingleSongId(songYtId) { + Utils.showLoading(); + const song = await fetch(`/api/song/single?id=${songYtId}`) + .then((res) => res.json()) + .then((s) => s) + .catch((err) => { + console.error(err); + }) + .finally(() => { + Utils.hideLoading(); + }); + + await playSingleSong(song); +} + /** * @param {Song} song */ @@ -647,6 +665,24 @@ async function playSingleSongNext(song) { alert(`Playing ${song.title} next!`); } +/** + * @param {string} songYtId + */ +async function playSingleSongNextId(songYtId) { + Utils.showLoading(); + const song = await fetch(`/api/song/single?id=${songYtId}`) + .then((res) => res.json()) + .then((s) => s) + .catch((err) => { + console.error(err); + }) + .finally(() => { + Utils.hideLoading(); + }); + + await playSingleSongNext(song); +} + /** * @param {Playlist} playlist */ @@ -722,6 +758,25 @@ async function playSongFromPlaylist(songYtId, playlist) { await playSong(songToPlay); } +/** + * @param {string} songYtId + * @param {string} playlistPubId + */ +async function playSongFromPlaylistId(songYtId, playlistPubId) { + Utils.showLoading(); + const playlist = await fetch(`/api/playlist?playlist-id=${playlistPubId}`) + .then((res) => res.json()) + .then((p) => p) + .catch((err) => { + console.error(err); + }) + .finally(() => { + Utils.hideLoading(); + }); + + await playSongFromPlaylist(songYtId, playlist); +} + /** * @param {Song} song */ @@ -975,8 +1030,11 @@ window.Player.downloadSongToDevice = downloadSongToDevice; window.Player.showPlayer = show; window.Player.hidePlayer = hide; window.Player.playSingleSong = playSingleSong; +window.Player.playSingleSongId = playSingleSongId; window.Player.playSingleSongNext = playSingleSongNext; +window.Player.playSingleSongNextId = playSingleSongNextId; window.Player.playSongFromPlaylist = playSongFromPlaylist; +window.Player.playSongFromPlaylistId = playSongFromPlaylistId; window.Player.playPlaylistNext = playPlaylistNext; window.Player.removeSongFromPlaylist = removeSongFromPlaylist; window.Player.addSongToQueue = appendSongToCurrentQueue; diff --git a/app/views/components/song/song.templ b/app/views/components/song/song.templ index 32aaf82..e083587 100644 --- a/app/views/components/song/song.templ +++ b/app/views/components/song/song.templ @@ -23,9 +23,9 @@ templ Song(s entities.Song, additionalData []string, additionalOptions []templ.C

@icons.AddToQueue() Play next @@ -163,16 +163,16 @@ script addSongToQueue(song entities.Song) { window.Player.addSongToQueue(song); } -script playSong(song entities.Song) { - window.Player.playSingleSong(song); +script playSong(songYtId string) { + window.Player.playSingleSongId(songYtId); } -script playSongFromPlaylist(songId string, playlist entities.Playlist) { - window.Player.playSongFromPlaylist(songId, playlist) +script playSongFromPlaylist(songId, playlistPubId string) { + window.Player.playSongFromPlaylistId(songId, playlistPubId) } -script playSongNext(song entities.Song) { - Player.playSingleSongNext(song) +script playSongNext(songYtId string) { + Player.playSingleSongNextId(songYtId) } script shareSong(songYtId string) { diff --git a/app/views/pages/playlist.templ b/app/views/pages/playlist.templ index 5bd8bc5..067dcb7 100644 --- a/app/views/pages/playlist.templ +++ b/app/views/pages/playlist.templ @@ -47,7 +47,7 @@ templ playlistHeader(pl entities.Playlist) { id="play-playlist-button" type="button" title="Play playlist" - onClick={ playSongFromPlaylist(pl.Songs[0].YtId, pl) } + onClick={ playSongFromPlaylist(pl.Songs[0].YtId, pl.PublicId) } > @icons.PlayPlaylist() @@ -172,6 +172,6 @@ script copyLink(isPublic bool) { } } -script playSongFromPlaylist(songId string, playlist entities.Playlist) { - window.Player.playSongFromPlaylist(songId, playlist) +script playSongFromPlaylist(songId, playlistPubId string) { + window.Player.playSongFromPlaylistId(songId, playlistPubId) } From da3c9da94f8b72659ed4528951006c1b9f3079a1 Mon Sep 17 00:00:00 2001 From: Baraa Al-Masri Date: Sun, 9 Jun 2024 14:10:39 +0300 Subject: [PATCH 21/26] feat(lazyload): add song to queue --- app/static/js/player.js | 19 +++++++++++++++++++ app/views/components/song/song.templ | 6 +++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/app/static/js/player.js b/app/static/js/player.js index 4a4c151..4e1f8a5 100644 --- a/app/static/js/player.js +++ b/app/static/js/player.js @@ -790,6 +790,24 @@ function appendSongToCurrentQueue(song) { alert(`Added ${song.title} to the queue!`); } +/** + * @param {string} songYtId + */ +async function appendSongToCurrentQueueId(songYtId) { + Utils.showLoading(); + const song = await fetch(`/api/song/single?id=${songYtId}`) + .then((res) => res.json()) + .then((s) => s) + .catch((err) => { + console.error(err); + }) + .finally(() => { + Utils.hideLoading(); + }); + + appendSongToCurrentQueue(song); +} + function addSongToPlaylist() { throw new Error("not implemented!"); } @@ -1038,6 +1056,7 @@ window.Player.playSongFromPlaylistId = playSongFromPlaylistId; window.Player.playPlaylistNext = playPlaylistNext; window.Player.removeSongFromPlaylist = removeSongFromPlaylist; window.Player.addSongToQueue = appendSongToCurrentQueue; +window.Player.addSongToQueueId = appendSongToCurrentQueueId; window.Player.appendPlaylistToCurrentQueue = appendPlaylistToCurrentQueue; window.Player.stopMuzikk = stopMuzikk; window.Player.expand = () => expand(); diff --git a/app/views/components/song/song.templ b/app/views/components/song/song.templ index e083587..250374f 100644 --- a/app/views/components/song/song.templ +++ b/app/views/components/song/song.templ @@ -119,7 +119,7 @@ templ options(song entities.Song, additionalOptions []templ.Component) { } title="Add song to queue" type="button" - onClick={ addSongToQueue(song) } + onClick={ addSongToQueue(song.YtId) } > @icons.AddToQueue() Add to queue @@ -159,8 +159,8 @@ script downloadSong(songYtId, songTitle string) { Player.downloadSongToDevice(songYtId, songTitle) } -script addSongToQueue(song entities.Song) { - window.Player.addSongToQueue(song); +script addSongToQueue(songYtId string) { + window.Player.addSongToQueueId(songYtId); } script playSong(songYtId string) { From a48154fe5f5046c9ecaf233aff230864b9ffa740 Mon Sep 17 00:00:00 2001 From: Baraa Al-Masri Date: Sun, 9 Jun 2024 14:15:46 +0300 Subject: [PATCH 22/26] feat(lazyload): add playlist to queue --- app/static/js/player.js | 19 +++++++++++++++++++ app/views/components/playlist/options.templ | 6 +++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/app/static/js/player.js b/app/static/js/player.js index 4e1f8a5..f715de4 100644 --- a/app/static/js/player.js +++ b/app/static/js/player.js @@ -723,6 +723,24 @@ async function appendPlaylistToCurrentQueue(playlist) { alert(`Playing ${playlist.title} next!`); } +/** + * @param {string} playlistPubId + */ +async function appendPlaylistToCurrentQueueId(playlistPubId) { + Utils.showLoading(); + const playlist = await fetch(`/api/playlist?playlist-id=${playlistPubId}`) + .then((res) => res.json()) + .then((p) => p) + .catch((err) => { + console.error(err); + }) + .finally(() => { + Utils.hideLoading(); + }); + + await appendPlaylistToCurrentQueue(playlist); +} + /** * @param {string} songYtId * @param {Playlist} playlist @@ -1058,6 +1076,7 @@ window.Player.removeSongFromPlaylist = removeSongFromPlaylist; window.Player.addSongToQueue = appendSongToCurrentQueue; window.Player.addSongToQueueId = appendSongToCurrentQueueId; window.Player.appendPlaylistToCurrentQueue = appendPlaylistToCurrentQueue; +window.Player.appendPlaylistToCurrentQueueId = appendPlaylistToCurrentQueueId; window.Player.stopMuzikk = stopMuzikk; window.Player.expand = () => expand(); window.Player.collapse = () => collapse(); diff --git a/app/views/components/playlist/options.templ b/app/views/components/playlist/options.templ index 3ba519b..47b1adf 100644 --- a/app/views/components/playlist/options.templ +++ b/app/views/components/playlist/options.templ @@ -46,7 +46,7 @@ templ playlistOptions(playlist entities.Playlist) { } title="Add to queue" type="button" - onClick={ addToQueue(playlist) } + onClick={ addToQueue(playlist.PublicId) } > @icons.AddToQueue() Add to queue @@ -144,8 +144,8 @@ script playPlaylistNext(pl entities.Playlist) { Player.playPlaylistNext(pl) } -script addToQueue(pl entities.Playlist) { - Player.appendPlaylistToCurrentQueue(pl) +script addToQueue(plPubId string) { + Player.appendPlaylistToCurrentQueueId(plPubId) } script copyLink(isPublic bool, plPubId string) { From fce697494cc3cae762cd94389b2504b6f5f3ec5b Mon Sep 17 00:00:00 2001 From: Baraa Al-Masri Date: Sun, 9 Jun 2024 14:20:36 +0300 Subject: [PATCH 23/26] feat(lazyload): play playlist next --- app/static/js/player.js | 19 +++++++++++++++++++ app/views/components/playlist/options.templ | 6 +++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/app/static/js/player.js b/app/static/js/player.js index f715de4..807751b 100644 --- a/app/static/js/player.js +++ b/app/static/js/player.js @@ -706,6 +706,24 @@ async function playPlaylistNext(playlist) { alert(`Playing ${playlist.title} next!`); } +/** + * @param {string} playlistPubId + */ +async function playPlaylistNextId(playlistPubId) { + Utils.showLoading(); + const playlist = await fetch(`/api/playlist?playlist-id=${playlistPubId}`) + .then((res) => res.json()) + .then((p) => p) + .catch((err) => { + console.error(err); + }) + .finally(() => { + Utils.hideLoading(); + }); + + await playPlaylistNext(playlist); +} + /** * @param {Playlist} playlist */ @@ -1072,6 +1090,7 @@ window.Player.playSingleSongNextId = playSingleSongNextId; window.Player.playSongFromPlaylist = playSongFromPlaylist; window.Player.playSongFromPlaylistId = playSongFromPlaylistId; window.Player.playPlaylistNext = playPlaylistNext; +window.Player.playPlaylistNextId = playPlaylistNextId; window.Player.removeSongFromPlaylist = removeSongFromPlaylist; window.Player.addSongToQueue = appendSongToCurrentQueue; window.Player.addSongToQueueId = appendSongToCurrentQueueId; diff --git a/app/views/components/playlist/options.templ b/app/views/components/playlist/options.templ index 47b1adf..9a62fb6 100644 --- a/app/views/components/playlist/options.templ +++ b/app/views/components/playlist/options.templ @@ -58,7 +58,7 @@ templ playlistOptions(playlist entities.Playlist) { } title="Play next" type="button" - onClick={ playPlaylistNext(playlist) } + onClick={ playPlaylistNext(playlist.PublicId) } > @icons.AddToQueue() Play next @@ -140,8 +140,8 @@ templ publicPlaylistToggle(publicId string, isPublic bool) {

} -script playPlaylistNext(pl entities.Playlist) { - Player.playPlaylistNext(pl) +script playPlaylistNext(plPubId string) { + Player.playPlaylistNextId(plPubId) } script addToQueue(plPubId string) { From b4f2c49716adfcf7d7860206b3820e12a9633baa Mon Sep 17 00:00:00 2001 From: Baraa Al-Masri Date: Sun, 9 Jun 2024 14:27:17 +0300 Subject: [PATCH 24/26] chore(player): remove duplicates --- app/static/js/player.js | 104 +++++++++++++++------------------------- 1 file changed, 38 insertions(+), 66 deletions(-) diff --git a/app/static/js/player.js b/app/static/js/player.js index 807751b..1dfc73e 100644 --- a/app/static/js/player.js +++ b/app/static/js/player.js @@ -617,6 +617,38 @@ async function playSong(song) { await updateSongPlays(); } +/** + * @param {string} songYtId + */ +async function fetchSongMeta(songYtId) { + Utils.showLoading(); + return await fetch(`/api/song/single?id=${songYtId}`) + .then((res) => res.json()) + .then((s) => s) + .catch((err) => { + console.error(err); + }) + .finally(() => { + Utils.hideLoading(); + }); +} + +/** + * @param {string} playlistPubId + */ +async function fetchPlaylistMeta(playlistPubId) { + Utils.showLoading(); + return await fetch(`/api/playlist?playlist-id=${playlistPubId}`) + .then((res) => res.json()) + .then((p) => p) + .catch((err) => { + console.error(err); + }) + .finally(() => { + Utils.hideLoading(); + }); +} + /** * @param {Song} song */ @@ -635,17 +667,7 @@ async function playSingleSong(song) { * @param {string} songYtId */ async function playSingleSongId(songYtId) { - Utils.showLoading(); - const song = await fetch(`/api/song/single?id=${songYtId}`) - .then((res) => res.json()) - .then((s) => s) - .catch((err) => { - console.error(err); - }) - .finally(() => { - Utils.hideLoading(); - }); - + const song = await fetchSongMeta(songYtId); await playSingleSong(song); } @@ -669,17 +691,7 @@ async function playSingleSongNext(song) { * @param {string} songYtId */ async function playSingleSongNextId(songYtId) { - Utils.showLoading(); - const song = await fetch(`/api/song/single?id=${songYtId}`) - .then((res) => res.json()) - .then((s) => s) - .catch((err) => { - console.error(err); - }) - .finally(() => { - Utils.hideLoading(); - }); - + const song = await fetchSongMeta(songYtId); await playSingleSongNext(song); } @@ -710,17 +722,7 @@ async function playPlaylistNext(playlist) { * @param {string} playlistPubId */ async function playPlaylistNextId(playlistPubId) { - Utils.showLoading(); - const playlist = await fetch(`/api/playlist?playlist-id=${playlistPubId}`) - .then((res) => res.json()) - .then((p) => p) - .catch((err) => { - console.error(err); - }) - .finally(() => { - Utils.hideLoading(); - }); - + const playlist = await fetchPlaylistMeta(playlistPubId); await playPlaylistNext(playlist); } @@ -745,17 +747,7 @@ async function appendPlaylistToCurrentQueue(playlist) { * @param {string} playlistPubId */ async function appendPlaylistToCurrentQueueId(playlistPubId) { - Utils.showLoading(); - const playlist = await fetch(`/api/playlist?playlist-id=${playlistPubId}`) - .then((res) => res.json()) - .then((p) => p) - .catch((err) => { - console.error(err); - }) - .finally(() => { - Utils.hideLoading(); - }); - + const playlist = await fetchPlaylistMeta(playlistPubId); await appendPlaylistToCurrentQueue(playlist); } @@ -799,17 +791,7 @@ async function playSongFromPlaylist(songYtId, playlist) { * @param {string} playlistPubId */ async function playSongFromPlaylistId(songYtId, playlistPubId) { - Utils.showLoading(); - const playlist = await fetch(`/api/playlist?playlist-id=${playlistPubId}`) - .then((res) => res.json()) - .then((p) => p) - .catch((err) => { - console.error(err); - }) - .finally(() => { - Utils.hideLoading(); - }); - + const playlist = await fetchPlaylistMeta(playlistPubId); await playSongFromPlaylist(songYtId, playlist); } @@ -830,17 +812,7 @@ function appendSongToCurrentQueue(song) { * @param {string} songYtId */ async function appendSongToCurrentQueueId(songYtId) { - Utils.showLoading(); - const song = await fetch(`/api/song/single?id=${songYtId}`) - .then((res) => res.json()) - .then((s) => s) - .catch((err) => { - console.error(err); - }) - .finally(() => { - Utils.hideLoading(); - }); - + const song = await fetchSongMeta(songYtId); appendSongToCurrentQueue(song); } From f07db1b8f5e6844e04dd997076725971a934c35a Mon Sep 17 00:00:00 2001 From: Baraa Al-Masri Date: Sun, 9 Jun 2024 14:34:24 +0300 Subject: [PATCH 25/26] feat(lazyload): play playlist icon --- app/views/icons/icons_loader.templ | 1 + app/views/icons/play_playlist.templ | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/app/views/icons/icons_loader.templ b/app/views/icons/icons_loader.templ index 5384d88..c55b6ed 100644 --- a/app/views/icons/icons_loader.templ +++ b/app/views/icons/icons_loader.templ @@ -9,6 +9,7 @@ templ IconsLoader() { @downloadIconLoader() @optionsIconLoader() @playlistIconLoader() + @playPlaylistIconLoader() @shareLinkIconLoader() @trashIconLoader() } diff --git a/app/views/icons/play_playlist.templ b/app/views/icons/play_playlist.templ index d786ba5..4245fe2 100644 --- a/app/views/icons/play_playlist.templ +++ b/app/views/icons/play_playlist.templ @@ -1,8 +1,16 @@ package icons templ PlayPlaylist() { - - - + + + +} + +templ playPlaylistIconLoader() { + + + + + } From 9949daeabee3b071d1055c9b7f034e4f16bba213 Mon Sep 17 00:00:00 2001 From: Baraa Al-Masri Date: Sun, 9 Jun 2024 14:41:08 +0300 Subject: [PATCH 26/26] feat(lazyload): vote icons --- app/views/components/song/vote.templ | 11 +++-------- app/views/icons/downvote.templ | 15 +++++++++++++++ app/views/icons/icons_loader.templ | 2 ++ app/views/icons/upvote.templ | 15 +++++++++++++++ 4 files changed, 35 insertions(+), 8 deletions(-) create mode 100644 app/views/icons/downvote.templ create mode 100644 app/views/icons/upvote.templ diff --git a/app/views/components/song/vote.templ b/app/views/components/song/vote.templ index af5b211..cf42252 100644 --- a/app/views/components/song/vote.templ +++ b/app/views/components/song/vote.templ @@ -1,6 +1,7 @@ package song import "fmt" +import "dankmuzikk/views/icons" templ Vote(songId, playlistId string, votes int) {

Votes

@@ -30,10 +31,7 @@ templ Vote(songId, playlistId string, votes int) { ), } > - // dv - - - + @icons.DownvoteEmpty() { fmt.Sprint(votes) }
} diff --git a/app/views/icons/downvote.templ b/app/views/icons/downvote.templ new file mode 100644 index 0000000..8ecb564 --- /dev/null +++ b/app/views/icons/downvote.templ @@ -0,0 +1,15 @@ +package icons + +templ DownvoteEmpty() { + + + +} + +templ downvoteEmptyIconLoader() { + + + + + +} diff --git a/app/views/icons/icons_loader.templ b/app/views/icons/icons_loader.templ index c55b6ed..a5d1687 100644 --- a/app/views/icons/icons_loader.templ +++ b/app/views/icons/icons_loader.templ @@ -7,9 +7,11 @@ templ IconsLoader() { @addToQueueIconLoader() @ui.CheckedCheckboxIconLoader() @downloadIconLoader() + @downvoteEmptyIconLoader() @optionsIconLoader() @playlistIconLoader() @playPlaylistIconLoader() @shareLinkIconLoader() @trashIconLoader() + @upvoteEmptyIconLoader() } diff --git a/app/views/icons/upvote.templ b/app/views/icons/upvote.templ new file mode 100644 index 0000000..fb95e71 --- /dev/null +++ b/app/views/icons/upvote.templ @@ -0,0 +1,15 @@ +package icons + +templ UpvoteEmpty() { + + + +} + +templ upvoteEmptyIconLoader() { + + + + + +}