Skip to content

Commit

Permalink
Merge pull request #50 from mbaraa/feat/history-pagination
Browse files Browse the repository at this point in the history
Feat: History pagination
  • Loading branch information
mbaraa authored May 26, 2024
2 parents c7f3645 + cc7d141 commit fbf075d
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 22 deletions.
2 changes: 2 additions & 0 deletions cmd/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ func StartServer(staticFS embed.FS) error {
googleLoginApi := apis.NewGoogleLoginApi(login.NewGoogleLoginService(accountRepo, profileRepo, otpRepo, jwtUtil))
songDownloadApi := apis.NewDownloadHandler(downloadService, songsService, historyService)
playlistsApi := apis.NewPlaylistApi(playlistsService, songsService)
historyApi := apis.NewHistoryApi(historyService)

apisHandler := http.NewServeMux()
apisHandler.HandleFunc("POST /login/email", emailLoginApi.HandleEmailLogin)
Expand All @@ -104,6 +105,7 @@ func StartServer(staticFS embed.FS) error {
apisHandler.HandleFunc("DELETE /playlist", gHandler.AuthApi(playlistsApi.HandleDeletePlaylist))
apisHandler.HandleFunc("PUT /toggle-song-in-playlist", gHandler.AuthApi(playlistsApi.HandleToggleSongInPlaylist))
apisHandler.HandleFunc("PUT /increment-song-plays", gHandler.AuthApi(songDownloadApi.HandleIncrementSongPlaysInPlaylist))
apisHandler.HandleFunc("GET /history/{page}", gHandler.AuthApi(historyApi.HandleGetMoreHistoryItems))

applicationHandler := http.NewServeMux()
applicationHandler.Handle("/", pagesHandler)
Expand Down
59 changes: 59 additions & 0 deletions handlers/apis/history.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package apis

import (
"bytes"
"dankmuzikk/entities"
"dankmuzikk/handlers"
"dankmuzikk/log"
"dankmuzikk/services/history"
"dankmuzikk/views/components/song"
"fmt"
"net/http"
"strconv"
)

type historyApi struct {
service *history.Service
}

func NewHistoryApi(service *history.Service) *historyApi {
return &historyApi{service}
}

func (h *historyApi) HandleGetMoreHistoryItems(w http.ResponseWriter, r *http.Request) {
profileId, profileIdCorrect := r.Context().Value(handlers.ProfileIdKey).(uint)
if !profileIdCorrect {
w.WriteHeader(http.StatusUnauthorized)
return
}
page, err := strconv.Atoi(r.PathValue("page"))
if err != nil {
page = 2
}
if page <= 0 {
page *= -1
}
recentPlays, err := h.service.Get(profileId, uint(page))
if err != nil {
log.Errorln(err)
}

outBuf := bytes.NewBuffer([]byte{})
for _, s := range recentPlays {
song.Song(s, []string{"Played " + s.AddedAt}, nil, entities.Playlist{}).
Render(r.Context(), outBuf)
}

outBuf.WriteString(fmt.Sprintf(`<div
class="h-[10px] mb-[20px]"
hx-get="/api/history/%d"
hx-swap="outerHTML"
hx-trigger="intersect"
data-hx-revealed="true"
data-loading-target="#history-loading"
data-loading-class-remove="hidden"
data-loading-path="/api/history/%d"
></div>`, page+1, page+1))

_, _ = w.Write(outBuf.Bytes())
}
2 changes: 1 addition & 1 deletion handlers/pages/pages.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func (p *pagesHandler) HandleHomePage(w http.ResponseWriter, r *http.Request) {
var err error
profileId, profileIdCorrect := r.Context().Value(handlers.ProfileIdKey).(uint)
if profileIdCorrect {
recentPlays, err = p.historyService.Get(profileId)
recentPlays, err = p.historyService.Get(profileId, 1)
if err != nil {
log.Errorln(err)
}
Expand Down
11 changes: 8 additions & 3 deletions services/history/history.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"dankmuzikk/db"
"dankmuzikk/entities"
"dankmuzikk/models"
"fmt"
"time"
)

Expand Down Expand Up @@ -31,14 +32,18 @@ func (h *Service) AddSongToHistory(songYtId string, profileId uint) error {
})
}

func (h *Service) Get(profileId uint) ([]entities.Song, error) {
gigaQuery := `SELECT yt_id, title, artist, thumbnail_url, duration, h.created_at
func (h *Service) Get(profileId, page uint) ([]entities.Song, error) {
gigaQuery := fmt.Sprintf(
`SELECT yt_id, title, artist, thumbnail_url, duration, h.created_at
FROM
histories h JOIN songs
ON
songs.id = h.song_id
WHERE h.profile_id = ?
ORDER BY h.created_at DESC;`
ORDER BY h.created_at DESC
LIMIT %d,%d;`,
(page-1)*20, page*20,
)

rows, err := h.repo.
GetDB().
Expand Down
24 changes: 20 additions & 4 deletions views/components/song/song.templ
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import (
"fmt"
)

templ Song(s entities.Song, additionalData []string, additionalOptions []templ.Component, onClick templ.ComponentScript, hideId ...bool) {
templ Song(s entities.Song, additionalData []string, additionalOptions []templ.Component, playlist entities.Playlist) {
<div
if hideId != nil && len(hideId) == 1 && !hideId[0] {
if playlist.PublicId != "" {
id={ "song-" + s.YtId }
}
class={
Expand All @@ -21,7 +21,11 @@ templ Song(s entities.Song, additionalData []string, additionalOptions []templ.C
<!-- thumbnail and duration -->
<div
class={ "w-[80px]", "h-[80px]", "md:w-[120px]", "md:h-[120px]", "relative", "cursor-pointer" }
onClick={ onClick }
if playlist.PublicId != "" {
onClick={ playSongFromPlaylist(s.YtId, playlist) }
} else {
onClick={ playSong(s) }
}
>
<div
class={
Expand All @@ -39,7 +43,11 @@ templ Song(s entities.Song, additionalData []string, additionalOptions []templ.C
<div class={ "w-[165px]", "md:w-[330px]", "lg:min-w-[450px]", "xl:min-w-[650px]" }>
<div
class={ "w-full", "h-full", "flex", "gap-y-3", "items-center", "flex-col", "font-Ubuntu", "text-secondary", "cursor-pointer" }
onClick={ onClick }
if playlist.PublicId != "" {
onClick={ playSongFromPlaylist(s.YtId, playlist) }
} else {
onClick={ playSong(s) }
}
>
<h3
class={ "w-full", "text-lg", "md:text-xl", "font-bold", "overflow-hidden", "text-nowrap", "text-ellipsis" }
Expand Down Expand Up @@ -109,3 +117,11 @@ script downloadSong(songYtId, songTitle string) {
script addSongToQueue(song entities.Song) {
window.Player.addSongToQueue(song);
}

script playSong(song entities.Song) {
window.Player.playSingleSong(song);
}

script playSongFromPlaylist(songId string, playlist entities.Playlist) {
window.Player.playSongFromPlaylist(songId, playlist)
}
15 changes: 14 additions & 1 deletion views/pages/index.templ
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,20 @@ templ historyContent(recentPlays []entities.Song) {
}
>
for _, s := range recentPlays {
@song.Song(s, []string{"Played " + s.AddedAt}, nil, playSong(s), true)
@song.Song(s, []string{"Played " + s.AddedAt}, nil, entities.Playlist{})
}
<div
class={ "h-[10px]", "mb-[20px]" }
hx-get="/api/history/2"
hx-swap="outerHTML"
hx-trigger="intersect"
data-hx-revealed="true"
data-loading-target="#history-loading"
data-loading-class-remove="hidden"
data-loading-path="/api/history/2"
></div>
<div id="history-loading" class={ "hidden", "w-full", "flex", "justify-center" }>
<div class={ "loader", "!h-20", "!w-20" }></div>
</div>
</div>
}
14 changes: 6 additions & 8 deletions views/pages/playlist.templ
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@ templ playlistContent(pl entities.Playlist) {
s,
[]string{},
[]templ.Component{songOptionsMobile(s), removeSong(s, pl.PublicId)},
playSongFromPlaylist(s.YtId, pl),
false,
pl,
)
} else {
@song.Song(
Expand All @@ -83,8 +82,7 @@ templ playlistContent(pl entities.Playlist) {
"Added on " + s.AddedAt,
},
[]templ.Component{removeSong(s, pl.PublicId)},
playSongFromPlaylist(s.YtId, pl),
false,
pl,
)
}
}
Expand Down Expand Up @@ -190,10 +188,6 @@ func playedTimes(times int) string {
}
}

script playSongFromPlaylist(songId string, playlist entities.Playlist) {
window.Player.playSongFromPlaylist(songId, playlist)
}

script removeSongFromPlaylist(songId, playlistId string) {
Player.removeSongFromPlaylist(songId, playlistId);
}
Expand All @@ -212,3 +206,7 @@ script copyLink(pubId string, isPublic bool) {
alert("Playlist's links was copied!\nMake sure to make it public before sharing the link 😁")
}
}

script playSongFromPlaylist(songId string, playlist entities.Playlist) {
window.Player.playSongFromPlaylist(songId, playlist)
}
6 changes: 1 addition & 5 deletions views/pages/search_results.templ
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,7 @@ templ searchContent(results []entities.Song, playlists []entities.Playlist, song
}
>
for idx, res := range results {
@song.Song(res, nil, []templ.Component{playlist.PlaylistsPopup(idx, res.YtId, playlists, songsInPlaylists)}, playSong(res), true)
@song.Song(res, nil, []templ.Component{playlist.PlaylistsPopup(idx, res.YtId, playlists, songsInPlaylists)}, entities.Playlist{})
}
</div>
}

script playSong(song entities.Song) {
window.Player.playSingleSong(song);
}

0 comments on commit fbf075d

Please sign in to comment.