announcement_handler.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package handler
  2. import (
  3. "strconv"
  4. "strings"
  5. "github.com/Wei-Shaw/sub2api/internal/handler/dto"
  6. "github.com/Wei-Shaw/sub2api/internal/pkg/response"
  7. middleware2 "github.com/Wei-Shaw/sub2api/internal/server/middleware"
  8. "github.com/Wei-Shaw/sub2api/internal/service"
  9. "github.com/gin-gonic/gin"
  10. )
  11. // AnnouncementHandler handles user announcement operations
  12. type AnnouncementHandler struct {
  13. announcementService *service.AnnouncementService
  14. }
  15. // NewAnnouncementHandler creates a new user announcement handler
  16. func NewAnnouncementHandler(announcementService *service.AnnouncementService) *AnnouncementHandler {
  17. return &AnnouncementHandler{
  18. announcementService: announcementService,
  19. }
  20. }
  21. // List handles listing announcements visible to current user
  22. // GET /api/v1/announcements
  23. func (h *AnnouncementHandler) List(c *gin.Context) {
  24. subject, ok := middleware2.GetAuthSubjectFromContext(c)
  25. if !ok {
  26. response.Unauthorized(c, "User not found in context")
  27. return
  28. }
  29. unreadOnly := parseBoolQuery(c.Query("unread_only"))
  30. items, err := h.announcementService.ListForUser(c.Request.Context(), subject.UserID, unreadOnly)
  31. if err != nil {
  32. response.ErrorFrom(c, err)
  33. return
  34. }
  35. out := make([]dto.UserAnnouncement, 0, len(items))
  36. for i := range items {
  37. out = append(out, *dto.UserAnnouncementFromService(&items[i]))
  38. }
  39. response.Success(c, out)
  40. }
  41. // MarkRead marks an announcement as read for current user
  42. // POST /api/v1/announcements/:id/read
  43. func (h *AnnouncementHandler) MarkRead(c *gin.Context) {
  44. subject, ok := middleware2.GetAuthSubjectFromContext(c)
  45. if !ok {
  46. response.Unauthorized(c, "User not found in context")
  47. return
  48. }
  49. announcementID, err := strconv.ParseInt(c.Param("id"), 10, 64)
  50. if err != nil || announcementID <= 0 {
  51. response.BadRequest(c, "Invalid announcement ID")
  52. return
  53. }
  54. if err := h.announcementService.MarkRead(c.Request.Context(), subject.UserID, announcementID); err != nil {
  55. response.ErrorFrom(c, err)
  56. return
  57. }
  58. response.Success(c, gin.H{"message": "ok"})
  59. }
  60. func parseBoolQuery(v string) bool {
  61. switch strings.TrimSpace(strings.ToLower(v)) {
  62. case "1", "true", "yes", "y", "on":
  63. return true
  64. default:
  65. return false
  66. }
  67. }