Skip to content

Commit

Permalink
Merge pull request #71 from mbaraa/refactor/lazy-load-heavy-data
Browse files Browse the repository at this point in the history
Refactor: Lazy Load Heavy Data
  • Loading branch information
mbaraa authored Jun 9, 2024
2 parents 92131e2 + 9949dae commit 2b01135
Show file tree
Hide file tree
Showing 22 changed files with 323 additions and 76 deletions.
2 changes: 2 additions & 0 deletions app/cmd/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
22 changes: 22 additions & 0 deletions app/handlers/apis/playlist.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
18 changes: 18 additions & 0 deletions app/handlers/apis/songs.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"dankmuzikk/services/history"
"dankmuzikk/services/playlists/songs"
"dankmuzikk/services/youtube/download"
"encoding/json"
"fmt"
"net/http"
)
Expand Down Expand Up @@ -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)
}
87 changes: 87 additions & 0 deletions app/static/js/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand All @@ -631,6 +663,14 @@ async function playSingleSong(song) {
await playSong(song);
}

/**
* @param {string} songYtId
*/
async function playSingleSongId(songYtId) {
const song = await fetchSongMeta(songYtId);
await playSingleSong(song);
}

/**
* @param {Song} song
*/
Expand All @@ -647,6 +687,14 @@ async function playSingleSongNext(song) {
alert(`Playing ${song.title} next!`);
}

/**
* @param {string} songYtId
*/
async function playSingleSongNextId(songYtId) {
const song = await fetchSongMeta(songYtId);
await playSingleSongNext(song);
}

/**
* @param {Playlist} playlist
*/
Expand All @@ -670,6 +718,14 @@ async function playPlaylistNext(playlist) {
alert(`Playing ${playlist.title} next!`);
}

/**
* @param {string} playlistPubId
*/
async function playPlaylistNextId(playlistPubId) {
const playlist = await fetchPlaylistMeta(playlistPubId);
await playPlaylistNext(playlist);
}

/**
* @param {Playlist} playlist
*/
Expand All @@ -687,6 +743,14 @@ async function appendPlaylistToCurrentQueue(playlist) {
alert(`Playing ${playlist.title} next!`);
}

/**
* @param {string} playlistPubId
*/
async function appendPlaylistToCurrentQueueId(playlistPubId) {
const playlist = await fetchPlaylistMeta(playlistPubId);
await appendPlaylistToCurrentQueue(playlist);
}

/**
* @param {string} songYtId
* @param {Playlist} playlist
Expand Down Expand Up @@ -722,6 +786,15 @@ async function playSongFromPlaylist(songYtId, playlist) {
await playSong(songToPlay);
}

/**
* @param {string} songYtId
* @param {string} playlistPubId
*/
async function playSongFromPlaylistId(songYtId, playlistPubId) {
const playlist = await fetchPlaylistMeta(playlistPubId);
await playSongFromPlaylist(songYtId, playlist);
}

/**
* @param {Song} song
*/
Expand All @@ -735,6 +808,14 @@ function appendSongToCurrentQueue(song) {
alert(`Added ${song.title} to the queue!`);
}

/**
* @param {string} songYtId
*/
async function appendSongToCurrentQueueId(songYtId) {
const song = await fetchSongMeta(songYtId);
appendSongToCurrentQueue(song);
}

function addSongToPlaylist() {
throw new Error("not implemented!");
}
Expand Down Expand Up @@ -975,12 +1056,18 @@ 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.playPlaylistNextId = playPlaylistNextId;
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();
20 changes: 7 additions & 13 deletions app/views/components/playlist/options.templ
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ templ playlistOptions(playlist entities.Playlist) {
}
title="Add to queue"
type="button"
onClick={ addToQueue(playlist) }
onClick={ addToQueue(playlist.PublicId) }
>
@icons.AddToQueue()
<span>Add to queue</span>
Expand All @@ -58,7 +58,7 @@ templ playlistOptions(playlist entities.Playlist) {
}
title="Play next"
type="button"
onClick={ playPlaylistNext(playlist) }
onClick={ playPlaylistNext(playlist.PublicId) }
>
@icons.AddToQueue()
<span>Play next</span>
Expand Down Expand Up @@ -91,13 +91,7 @@ templ playlistOptions(playlist entities.Playlist) {
),
}
>
<svg class={ "hover:stroke-white" } width="30" height="34" viewBox="0 0 30 34" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.6129 14.8387V24.5161" stroke="var(--secondary-color)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M18.0647 14.8387V24.5161" stroke="var(--secondary-color)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M1.93555 8.38712H27.742" stroke="var(--secondary-color)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M5.16125 8.38712H14.8387H24.5161V26.129C24.5161 28.8015 22.3498 30.9678 19.6774 30.9678H9.99996C7.32763 30.9678 5.16125 28.8015 5.16125 26.129V8.38712Z" stroke="var(--secondary-color)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M10 5.16128C10 3.37971 11.4442 1.93547 13.2258 1.93547H16.4516C18.2332 1.93547 19.6774 3.37971 19.6774 5.16128V8.38708H10V5.16128Z" stroke="var(--secondary-color)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
</svg>
@icons.Trash()
<span>Delete playlist</span>
</button>
}
Expand Down Expand Up @@ -146,12 +140,12 @@ templ publicPlaylistToggle(publicId string, isPublic bool) {
</div>
}

script playPlaylistNext(pl entities.Playlist) {
Player.playPlaylistNext(pl)
script playPlaylistNext(plPubId string) {
Player.playPlaylistNextId(plPubId)
}

script addToQueue(pl entities.Playlist) {
Player.appendPlaylistToCurrentQueue(pl)
script addToQueue(plPubId string) {
Player.appendPlaylistToCurrentQueueId(plPubId)
}

script copyLink(isPublic bool, plPubId string) {
Expand Down
15 changes: 6 additions & 9 deletions app/views/components/song/remove_song.templ
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package song

import "dankmuzikk/entities"
import "dankmuzikk/models"
import (
"dankmuzikk/entities"
"dankmuzikk/models"
"dankmuzikk/views/icons"
)

templ RemoveSong(song entities.Song, playlistId string) {
if perm, ok := ctx.Value("playlist-permission").(models.PlaylistPermissions); ok && (perm & models.JoinerPermission) != 0 {
Expand All @@ -14,13 +17,7 @@ templ RemoveSong(song entities.Song, playlistId string) {
type="button"
onClick={ removeSongFromPlaylist(song.YtId, playlistId) }
>
<svg class={ "hover:stroke-white" } width="30" height="34" viewBox="0 0 30 34" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.6129 14.8387V24.5161" stroke="var(--secondary-color)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M18.0647 14.8387V24.5161" stroke="var(--secondary-color)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M1.93555 8.38712H27.742" stroke="var(--secondary-color)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M5.16125 8.38712H14.8387H24.5161V26.129C24.5161 28.8015 22.3498 30.9678 19.6774 30.9678H9.99996C7.32763 30.9678 5.16125 28.8015 5.16125 26.129V8.38712Z" stroke="var(--secondary-color)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M10 5.16128C10 3.37971 11.4442 1.93547 13.2258 1.93547H16.4516C18.2332 1.93547 19.6774 3.37971 19.6774 5.16128V8.38708H10V5.16128Z" stroke="var(--secondary-color)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
</svg>
@icons.Trash()
<span>Remove from playlist</span>
</button>
}
Expand Down
28 changes: 14 additions & 14 deletions app/views/components/song/song.templ
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ templ Song(s entities.Song, additionalData []string, additionalOptions []templ.C
<div
class={ "w-[80px]", "h-[80px]", "md:w-[70px]", "md:h-[70px]", "relative", "cursor-pointer" }
if playlist.PublicId != "" {
onClick={ playSongFromPlaylist(s.YtId, playlist) }
onClick={ playSongFromPlaylist(s.YtId, playlist.PublicId) }
} else {
onClick={ playSong(s) }
onClick={ playSong(s.YtId) }
}
>
<div
Expand All @@ -52,9 +52,9 @@ templ Song(s entities.Song, additionalData []string, additionalOptions []templ.C
<div
class={ "w-full", "h-full", "flex", "gap-y-3", "items-start", "flex-col", "font-Ubuntu", "text-secondary", "cursor-pointer" }
if playlist.PublicId != "" {
onClick={ playSongFromPlaylist(s.YtId, playlist) }
onClick={ playSongFromPlaylist(s.YtId, playlist.PublicId) }
} else {
onClick={ playSong(s) }
onClick={ playSong(s.YtId) }
}
>
<h3
Expand Down Expand Up @@ -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()
<span>Add to queue</span>
Expand All @@ -131,7 +131,7 @@ templ options(song entities.Song, additionalOptions []templ.Component) {
}
title="Play next"
type="button"
onClick={ playSongNext(song) }
onClick={ playSongNext(song.YtId) }
>
@icons.AddToQueue()
<span>Play next</span>
Expand Down Expand Up @@ -159,20 +159,20 @@ 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(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) {
Expand Down
Loading

0 comments on commit 2b01135

Please sign in to comment.