feat: integrate ConnectionManager into Handler struct

Add WebSocket ConnectionManager to Handler:
- Add connManager field to Handler struct
- Update NewHandler to accept ConnectionManager parameter
- Update SetupRoutes to pass ConnectionManager through
- Import sync package with alias to avoid conflicts

This enables progress handlers to broadcast updates via WebSocket.
This commit is contained in:
2026-01-30 21:47:56 -05:00
parent c9ec222945
commit 4681fb474e
2 changed files with 22 additions and 5 deletions
+6 -3
View File
@@ -3,6 +3,7 @@ package handlers
import ( import (
"bookmann/internal/database" "bookmann/internal/database"
"bookmann/internal/services" "bookmann/internal/services"
wsync "bookmann/internal/sync"
"context" "context"
"fmt" "fmt"
"net/http" "net/http"
@@ -31,9 +32,10 @@ type Handler struct {
watchModeCtx context.Context watchModeCtx context.Context
watchModeCancel context.CancelFunc watchModeCancel context.CancelFunc
watchingLibraries map[string]bool watchingLibraries map[string]bool
connManager *wsync.ConnectionManager
} }
func NewHandler(db *database.Queries) *Handler { func NewHandler(db *database.Queries, connManager *wsync.ConnectionManager) *Handler {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
worker := services.NewWorker(3) worker := services.NewWorker(3)
scheduler := services.NewScheduler(worker, db) scheduler := services.NewScheduler(worker, db)
@@ -50,6 +52,7 @@ func NewHandler(db *database.Queries) *Handler {
watchModeCtx: watchCtx, watchModeCtx: watchCtx,
watchModeCancel: watchCancel, watchModeCancel: watchCancel,
watchingLibraries: make(map[string]bool), watchingLibraries: make(map[string]bool),
connManager: connManager,
} }
} }
@@ -64,8 +67,8 @@ func parseDate(dateStr string) time.Time {
return time.Time{} return time.Time{}
} }
func SetupRoutes(g *echo.Group, db *database.Queries) *Handler { func SetupRoutes(g *echo.Group, db *database.Queries, connManager *wsync.ConnectionManager) *Handler {
h := NewHandler(db) h := NewHandler(db, connManager)
// Media item routes (all authenticated users) // Media item routes (all authenticated users)
g.GET("/media-items", h.ListMediaItems) g.GET("/media-items", h.ListMediaItems)
+16 -2
View File
@@ -2,7 +2,7 @@ package handlers
import ( import (
"bookmann/internal/database" "bookmann/internal/database"
"bookmann/internal/sync" wsync "bookmann/internal/sync"
"context" "context"
"net/http" "net/http"
"strconv" "strconv"
@@ -118,7 +118,7 @@ func (h *Handler) UpdateUniversalProgress(c echo.Context) error {
if req.Location.Percentage != nil { if req.Location.Percentage != nil {
percentage = *req.Location.Percentage percentage = *req.Location.Percentage
} else if req.Location.Page != nil && req.Location.TotalPages != nil { } else if req.Location.Page != nil && req.Location.TotalPages != nil {
percentage = sync.PageToPercentage(*req.Location.Page, *req.Location.TotalPages) percentage = wsync.PageToPercentage(*req.Location.Page, *req.Location.TotalPages)
} }
currentPage := 0 currentPage := 0
@@ -171,6 +171,20 @@ func (h *Handler) UpdateUniversalProgress(c echo.Context) error {
return echo.NewHTTPError(http.StatusInternalServerError, "failed to update progress") return echo.NewHTTPError(http.StatusInternalServerError, "failed to update progress")
} }
// Broadcast progress update to all connected WebSocket clients
deviceName := "Web"
deviceType := "web"
if req.DeviceMetadata.DeviceType != "" {
deviceType = req.DeviceMetadata.DeviceType
deviceName = req.DeviceMetadata.DeviceType
}
h.connManager.BroadcastProgressUpdate(mediaItemID, percentage, wsync.SourceDevice{
ID: uuid.UUID(user.ID.Bytes).String(),
Name: deviceName,
Type: deviceType,
})
return c.JSON(http.StatusOK, map[string]interface{}{ return c.JSON(http.StatusOK, map[string]interface{}{
"sync_status": "success", "sync_status": "success",
"progress_updated": true, "progress_updated": true,