Refactor video thumbnail handling to support multiple next videos and improve data structure
All checks were successful
Build / build (push) Successful in 5m52s

This commit is contained in:
Sebastiaan de Schaetzen 2025-06-17 18:53:05 +02:00
parent 371b3be5fd
commit 81af56e5c7
2 changed files with 27 additions and 15 deletions

View File

@ -53,7 +53,7 @@
aspect-ratio: 16/9; aspect-ratio: 16/9;
width: 20vw; width: 20vw;
transition: width 0.3s ease, box-shadow 0.3s ease, left 0.3s ease; transition: width 0.3s ease, box-shadow 0.3s ease, left 0.3s ease;
transform: translate(-50%, 0); transform: translate(-50%, -50%);
position: fixed; position: fixed;
} }
@ -313,17 +313,19 @@
* @param append Set to true if this thumbnail should be appended to the video container, false if it should be prepended. * @param append Set to true if this thumbnail should be appended to the video container, false if it should be prepended.
*/ */
function createVideoThumbnailElement(data, selected, append) { function createVideoThumbnailElement(data, selected, append) {
let container = $(`<span></span>`);
let thumbnail = $(`<img src="${data.thumbnail}" class="video-thumbnail" alt="Video Thumbnail" tabindex="0">`)[0]; let thumbnail = $(`<img src="${data.thumbnail}" class="video-thumbnail" alt="Video Thumbnail" tabindex="0">`)[0];
container.append(thumbnail)
let index; let index;
if (append) { if (append) {
$("#video-container").append(thumbnail); $("#video-container").append(container);
index = videoInfo.length; index = videoInfo.length;
videoInfo.push({ videoInfo.push({
thumbnail, thumbnail,
data data
}) })
} else { } else {
$("#video-container").prepend(thumbnail); $("#video-container").prepend(container);
index = 0; index = 0;
videoInfo.unshift({ videoInfo.unshift({
thumbnail, thumbnail,
@ -441,10 +443,8 @@
$.getJSON("/api/homepage", function(data) { $.getJSON("/api/homepage", function(data) {
createVideoThumbnailElement(data.currentVideo, true, true); createVideoThumbnailElement(data.currentVideo, true, true);
for (let i = 0; i < 10; i++) for (let i = 0; i < data.nextVideos.length; i++)
createVideoThumbnailElement(data.nextVideo, false, true); createVideoThumbnailElement(data.nextVideos[i], false, true);
for (let i = 0; i < 10; i++)
createVideoThumbnailElement(data.nextVideo, false, false);
// currentVideo = data.currentVideo; // currentVideo = data.currentVideo;
// nextVideo = data.nextVideo; // nextVideo = data.nextVideo;
// $("#current-thumb").attr("src", currentVideo.thumbnail); // $("#current-thumb").attr("src", currentVideo.thumbnail);

View File

@ -58,24 +58,36 @@ type VideoModel struct {
} }
type HomePageModel struct { type HomePageModel struct {
CurrentVideo VideoModel `json:"currentVideo"` Current VideoModel `json:"currentVideo"`
NextVideo VideoModel `json:"nextVideo"` Next []VideoModel `json:"nextVideos"`
Previous []VideoModel `json:"previousVideos"`
} }
func (a *App) homePage(c *gin.Context) { func (a *App) homePage(c *gin.Context) {
model := HomePageModel{} model := HomePageModel{}
errCurrent := a.db.Query("SELECT id, thumbnail FROM videos WHERE (watch_state IS NULL OR watch_state != 'watched') ORDER BY upload_date, episode LIMIT 1"). errCurrent := a.db.Query("SELECT id, thumbnail FROM videos WHERE (watch_state IS NULL OR watch_state != 'watched') ORDER BY upload_date, episode LIMIT 1").
ScanSingle(&model.CurrentVideo.ID, &model.CurrentVideo.Thumbnail) ScanSingle(&model.Current.ID, &model.Current.Thumbnail)
errNext := a.db.Query("SELECT id, thumbnail FROM videos WHERE (watch_state IS NULL OR watch_state != 'watched') ORDER BY upload_date, episode LIMIT 1 OFFSET 1").
ScanSingle(&model.NextVideo.ID, &model.NextVideo.Thumbnail) var errNext, errPrevious error
if err := cmp.Or(errCurrent, errNext); err != nil { for row := range a.db.Query("SELECT id, thumbnail FROM videos WHERE (watch_state IS NULL OR watch_state != 'watched') ORDER BY upload_date, episode LIMIT 3 OFFSET 1").Range(&errNext) {
video := VideoModel{}
err := row.Scan(&video.ID, &video.Thumbnail)
if err != nil {
log.Printf("Failed to scan next video: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to retrieve next videos"})
return
}
video.URL = fmt.Sprintf("/stream/%d", video.ID)
model.Next = append(model.Next, video)
}
if err := cmp.Or(errCurrent, errNext, errPrevious); err != nil {
log.Printf("Failed to retrieve videos: %v", err) log.Printf("Failed to retrieve videos: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to retrieve videos"}) c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to retrieve videos"})
return return
} }
model.CurrentVideo.URL = fmt.Sprintf("/stream/%d", model.CurrentVideo.ID) model.Current.URL = fmt.Sprintf("/stream/%d", model.Current.ID)
model.NextVideo.URL = fmt.Sprintf("/stream/%d", model.CurrentVideo.ID)
c.JSON(200, model) c.JSON(200, model)
} }