diff options
| author | Paul Buetow <paul@buetow.org> | 2026-05-02 22:08:46 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-05-02 22:10:28 +0300 |
| commit | e391bea837f9740aa8b303dedb6f87c09abd4201 (patch) | |
| tree | 737ddbf8c58cd2b7acd0fb160494d9184e2c1983 /internal/api | |
| parent | e898357da954acb561a0a88b4443da52f774ce36 (diff) | |
fix detached playback and scan progress
Diffstat (limited to 'internal/api')
| -rw-r--r-- | internal/api/handlers.go | 4 | ||||
| -rw-r--r-- | internal/api/handlers_admin.go | 7 | ||||
| -rw-r--r-- | internal/api/handlers_test.go | 27 | ||||
| -rw-r--r-- | internal/api/server.go | 2 |
4 files changed, 27 insertions, 13 deletions
diff --git a/internal/api/handlers.go b/internal/api/handlers.go index 41c4197..0436247 100644 --- a/internal/api/handlers.go +++ b/internal/api/handlers.go @@ -103,6 +103,10 @@ func (s *Server) serveBootstrap(w http.ResponseWriter, r *http.Request) { s.serveFile(w, r, "bootstrap.html") } +func (s *Server) serveDetach(w http.ResponseWriter, r *http.Request) { + s.serveFile(w, r, "detach.html") +} + // ------------------------------------------------------------------ // File serving helpers // ------------------------------------------------------------------ diff --git a/internal/api/handlers_admin.go b/internal/api/handlers_admin.go index 246a466..e9935d4 100644 --- a/internal/api/handlers_admin.go +++ b/internal/api/handlers_admin.go @@ -33,6 +33,13 @@ func (s *Server) handleRescan(w http.ResponseWriter, r *http.Request) { writeJSON(w, http.StatusOK, map[string]string{"status": "ok"}) } +func (s *Server) handleScanProgress(w http.ResponseWriter, r *http.Request) { + if !requireService(w, s.adminSvc) { + return + } + writeJSON(w, http.StatusOK, s.adminSvc.ScanProgress(r.Context())) +} + func (s *Server) handleListUsers(w http.ResponseWriter, r *http.Request) { if !requireService(w, s.adminSvc) { return diff --git a/internal/api/handlers_test.go b/internal/api/handlers_test.go index 2201897..0003b88 100644 --- a/internal/api/handlers_test.go +++ b/internal/api/handlers_test.go @@ -679,8 +679,8 @@ func TestServer_MediaList(t *testing.T) { }, { name: "with query params", - query: "?set_id=1&type=video&search=foo&tags=bar,baz&favorites=true&min_duration=10&max_duration=100&sort=name&limit=5&offset=10", - filter: repository.MediaFilter{SetID: intPtr(1), Type: (*model.MediaType)(func() *string { s := "video"; return &s }()), Search: "foo", Tags: []string{"bar", "baz"}, Favorites: true, MinDuration: floatPtr(10), MaxDuration: floatPtr(100), Sort: "name", Limit: 5, Offset: 10}, + query: "?set_id=1&type=video&search=foo&tags=bar,baz&favorites=true&min_duration=10&max_duration=100&sort=name&limit=5&offset=10", + filter: repository.MediaFilter{SetID: intPtr(1), Type: (*model.MediaType)(func() *string { s := "video"; return &s }()), Search: "foo", Tags: []string{"bar", "baz"}, Favorites: true, MinDuration: floatPtr(10), MaxDuration: floatPtr(100), Sort: "name", Limit: 5, Offset: 10}, listResult: []model.Media{}, wantCode: http.StatusOK, }, @@ -716,14 +716,14 @@ func TestServer_MediaList(t *testing.T) { func TestServer_MediaDetail(t *testing.T) { tests := []struct { - name string - id string - result *service.MediaDetail - err error - wantCode int - wantMedia bool - wantResumeFrom float64 - wantProgressNil bool + name string + id string + result *service.MediaDetail + err error + wantCode int + wantMedia bool + wantResumeFrom float64 + wantProgressNil bool }{ { name: "ok with progress", @@ -762,8 +762,8 @@ func TestServer_MediaDetail(t *testing.T) { return } var resp struct { - Media *model.Media `json:"media"` - Progress *model.PlaybackProgress `json:"progress"` + Media *model.Media `json:"media"` + Progress *model.PlaybackProgress `json:"progress"` } if err := json.Unmarshal(rr.Body.Bytes(), &resp); err != nil { t.Fatalf("unmarshal detail: %v", err) @@ -1083,7 +1083,7 @@ func TestServer_Shares(t *testing.T) { }, GetSharedMediaFunc: func(ctx context.Context, token string) (*service.GetSharedMediaResult, error) { return &service.GetSharedMediaResult{ - Media: &service.SharedMediaView{ID: 1, FileName: "x.mp4", Type: model.MediaTypeVideo, Duration: 120}, + Media: &service.SharedMediaView{ID: 1, FileName: "x.mp4", Type: model.MediaTypeVideo, Duration: 120}, StreamURL: "/s/abc/stream", ThumbURL: "/s/abc/thumbnail", }, nil @@ -1190,6 +1190,7 @@ func TestServer_AdminRoutes(t *testing.T) { }{ {"list trash", "GET", "/api/admin/trash", "", http.StatusOK}, {"rescan", "POST", "/api/admin/rescan", "", http.StatusOK}, + {"scan progress", "GET", "/api/admin/scan-progress", "", http.StatusOK}, {"list users", "GET", "/api/admin/users", "", http.StatusOK}, {"create user", "POST", "/api/admin/users", `{"username":"bob","password":"pass","is_admin":false}`, http.StatusOK}, {"delete user", "DELETE", "/api/admin/users/2", "", http.StatusOK}, diff --git a/internal/api/server.go b/internal/api/server.go index 4d18d76..11518df 100644 --- a/internal/api/server.go +++ b/internal/api/server.go @@ -107,6 +107,7 @@ func (s *Server) routes() { s.mux.Handle("/bootstrap.html", http.HandlerFunc(s.serveBootstrap)) s.mux.Handle("/", s.mw.RequireSession(http.HandlerFunc(s.serveIndex))) s.mux.Handle("GET /index.html", s.mw.RequireSession(http.HandlerFunc(s.serveIndex))) + s.mux.Handle("GET /detach.html", s.mw.RequireSession(http.HandlerFunc(s.serveDetach))) // Session-required routes s.mux.Handle("POST /api/logout", s.mw.RequireSession(http.HandlerFunc(s.handleLogout))) @@ -148,6 +149,7 @@ func (s *Server) routes() { // Admin routes s.mux.Handle("GET /api/admin/trash", s.mw.RequireSession(s.mw.RequireAdmin(http.HandlerFunc(s.handleListTrash)))) s.mux.Handle("POST /api/admin/rescan", s.mw.RequireSession(s.mw.RequireAdmin(http.HandlerFunc(s.handleRescan)))) + s.mux.Handle("GET /api/admin/scan-progress", s.mw.RequireSession(s.mw.RequireAdmin(http.HandlerFunc(s.handleScanProgress)))) s.mux.Handle("GET /api/admin/users", s.mw.RequireSession(s.mw.RequireAdmin(http.HandlerFunc(s.handleListUsers)))) s.mux.Handle("POST /api/admin/users", s.mw.RequireSession(s.mw.RequireAdmin(http.HandlerFunc(s.handleCreateUser)))) s.mux.Handle("DELETE /api/admin/users/{id}", s.mw.RequireSession(s.mw.RequireAdmin(http.HandlerFunc(s.handleDeleteUser)))) |
