videos_pages.go
5072 bytes
1package ytrssil
2
3import (
4 "fmt"
5 "net/http"
6 "strconv"
7
8 "github.com/gin-gonic/gin"
9 datastar "github.com/starfederation/datastar-go/datastar"
10
11 "github.com/TheEdgeOfRage/ytrssil-api/models"
12 "github.com/TheEdgeOfRage/ytrssil-api/pages"
13)
14
15func (srv server) NewVideosPage(c *gin.Context) {
16 videos, err := srv.handler.GetNewVideos(c.Request.Context(), true)
17 if err != nil {
18 returnErr(c, http.StatusInternalServerError, err)
19 return
20 }
21
22 c.Render(http.StatusOK, pages.TemplRenderer{
23 Ctx: c.Request.Context(),
24 Component: pages.NewVideosPage(videos),
25 })
26}
27
28func (srv server) WatchedVideosPage(c *gin.Context) {
29 page := 1
30 if pageParam := c.Query("page"); pageParam != "" {
31 if parsedPage, err := strconv.Atoi(pageParam); err == nil && parsedPage > 0 {
32 page = parsedPage
33 }
34 }
35
36 videos, err := srv.handler.GetWatchedVideos(c.Request.Context(), true, page)
37 if err != nil {
38 returnErr(c, http.StatusInternalServerError, err)
39 return
40 }
41
42 c.Render(http.StatusOK, pages.TemplRenderer{
43 Ctx: c.Request.Context(),
44 Component: pages.WatchedVideosPage(videos, page),
45 })
46}
47
48func (srv server) FetchVideosPage(c *gin.Context) {
49 err := srv.handler.FetchVideos(c.Request.Context())
50 if err != nil {
51 returnErr(c, http.StatusInternalServerError, err)
52 return
53 }
54
55 sse := newSSE(c)
56 sse.ExecuteScript(`window.location.reload()`)
57}
58
59func (srv server) MarkVideoAsWatchedPage(c *gin.Context) {
60 videoID := c.Param("video_id")
61 err := srv.handler.MarkVideoAsWatched(c.Request.Context(), videoID)
62 if err != nil {
63 returnErr(c, http.StatusInternalServerError, err)
64 return
65 }
66
67 sse := newSSE(c)
68 sse.ExecuteScript(fmt.Sprintf(`animateRemove("#video-card-%s")`, videoID))
69}
70
71func (srv server) MarkVideoAsUnwatchedPage(c *gin.Context) {
72 videoID := c.Param("video_id")
73 err := srv.handler.MarkVideoAsUnwatched(c.Request.Context(), videoID)
74 if err != nil {
75 returnErr(c, http.StatusInternalServerError, err)
76 return
77 }
78
79 sse := newSSE(c)
80 sse.ExecuteScript(fmt.Sprintf(`animateRemove("#video-card-%s")`, videoID))
81}
82
83func (srv server) SetVideoProgressPage(c *gin.Context) {
84 var signals struct {
85 Progress string `json:"progress"`
86 }
87 if err := datastar.ReadSignals(c.Request, &signals); err != nil {
88 returnErr(c, http.StatusBadRequest, err)
89 return
90 }
91 if signals.Progress == "" {
92 returnMsg(c, http.StatusBadRequest, "missing progress")
93 return
94 }
95
96 video, err := srv.handler.SetVideoProgress(c.Request.Context(), c.Param("video_id"), signals.Progress)
97 if err != nil {
98 returnErr(c, http.StatusInternalServerError, err)
99 return
100 }
101
102 sse := newSSE(c)
103 sse.PatchElementTempl(pages.VideoCard(*video))
104}
105
106func (srv server) AddVideoPage(c *gin.Context) {
107 var signals struct {
108 VideoID string `json:"videoID"`
109 }
110 if err := datastar.ReadSignals(c.Request, &signals); err != nil {
111 sse := newSSE(c)
112 sse.ExecuteScript(fmt.Sprintf(`showFormError("add-video-modal", %q)`, err.Error()))
113 return
114 }
115 if signals.VideoID == "" {
116 sse := newSSE(c)
117 sse.ExecuteScript(`showFormError("add-video-modal", "missing video ID")`)
118 return
119 }
120
121 err := srv.handler.AddCustomVideo(c.Request.Context(), signals.VideoID)
122 if err != nil {
123 sse := newSSE(c)
124 sse.ExecuteScript(fmt.Sprintf(`showFormError("add-video-modal", %q)`, err.Error()))
125 return
126 }
127
128 sse := newSSE(c)
129 sse.ExecuteScript(`bootstrap.Modal.getInstance(document.getElementById("add-video-modal")).hide(); location.reload()`)
130}
131
132func (srv server) DownloadVideoPage(c *gin.Context) {
133 videoID := c.Param("video_id")
134 resolution := c.PostForm("format")
135
136 err := srv.handler.DownloadVideo(c.Request.Context(), videoID, resolution)
137 if err != nil {
138 returnErr(c, http.StatusInternalServerError, err)
139 return
140 }
141
142 videos, err := srv.handler.GetNewVideos(c.Request.Context(), true)
143 if err != nil {
144 returnErr(c, http.StatusInternalServerError, err)
145 return
146 }
147
148 var targetVideo *models.Video
149 for _, v := range videos {
150 if v.ID == videoID {
151 targetVideo = &v
152 break
153 }
154 }
155
156 if targetVideo == nil {
157 returnErr(c, http.StatusNotFound, fmt.Errorf("video not found"))
158 return
159 }
160
161 c.Render(http.StatusOK, pages.TemplRenderer{
162 Ctx: c.Request.Context(),
163 Component: pages.VideoCard(*targetVideo),
164 })
165}
166
167func (srv server) GetVideoCardPage(c *gin.Context) {
168 videoID := c.Param("video_id")
169
170 videos, err := srv.handler.GetNewVideos(c.Request.Context(), true)
171 if err != nil {
172 returnErr(c, http.StatusInternalServerError, err)
173 return
174 }
175
176 var targetVideo *models.Video
177 for _, v := range videos {
178 if v.ID == videoID {
179 targetVideo = &v
180 break
181 }
182 }
183
184 if targetVideo == nil {
185 returnErr(c, http.StatusNotFound, fmt.Errorf("video not found"))
186 return
187 }
188
189 sse := newSSE(c)
190 sse.PatchElementTempl(pages.VideoCard(*targetVideo))
191}
192
193func (srv server) ServeVideoFilePage(c *gin.Context) {
194 videoID := c.Param("video_id")
195
196 filePath, filename, err := srv.handler.ServeVideoFile(c.Request.Context(), videoID)
197 if err != nil {
198 returnErr(c, http.StatusNotFound, err)
199 return
200 }
201
202 c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%q", filename))
203 c.File(filePath)
204}