1package homepage
2
3import (
4 "context"
5 "encoding/json"
6
7 "github.com/bnema/dumber/internal/application/port"
8 "github.com/bnema/dumber/internal/domain/entity"
9 "github.com/bnema/dumber/internal/infrastructure/webkit"
10 "github.com/bnema/dumber/internal/logging"
11)
12
13// FolderHandlers handles folder-related messages from the homepage.
14type FolderHandlers struct {
15 favoritesUC port.HomepageFavorites
16}
17
18// NewFolderHandlers creates a new FolderHandlers instance.
19func NewFolderHandlers(favoritesUC port.HomepageFavorites) *FolderHandlers {
20 return &FolderHandlers{favoritesUC: favoritesUC}
21}
22
23// HandleList handles folder_list messages.
24func (h *FolderHandlers) HandleList() webkit.MessageHandler {
25 return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
26 log := logging.FromContext(ctx)
27
28 requestID := ParseRequestID(payload)
29
30 log.Debug().
31 Str("request_id", requestID).
32 Msg("handling folder_list")
33
34 folders, err := h.favoritesUC.GetAllFolders(ctx)
35 if err != nil {
36 return NewErrorResponse(requestID, err), nil
37 }
38
39 return NewSuccessResponse(requestID, folders), nil
40 })
41}
42
43// createFolderRequest is the payload for folder_create messages.
44type createFolderRequest struct {
45 RequestID string `json:"requestId"`
46 Name string `json:"name"`
47 Icon *string `json:"icon"`
48}
49
50// HandleCreate handles folder_create messages.
51func (h *FolderHandlers) HandleCreate() webkit.MessageHandler {
52 return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
53 log := logging.FromContext(ctx)
54
55 var req createFolderRequest
56 if err := json.Unmarshal(payload, &req); err != nil {
57 return NewErrorResponse("", err), nil
58 }
59
60 log.Debug().
61 Str("request_id", req.RequestID).
62 Str("name", req.Name).
63 Msg("handling folder_create")
64
65 folder, err := h.favoritesUC.CreateFolder(ctx, req.Name, nil)
66 if err != nil {
67 return NewErrorResponse(req.RequestID, err), nil
68 }
69
70 // Set icon if provided and persist it
71 if req.Icon != nil && *req.Icon != "" {
72 folder.Icon = *req.Icon
73 if err := h.favoritesUC.UpdateFolder(ctx, folder.ID, folder.Name, folder.Icon); err != nil {
74 return NewErrorResponse(req.RequestID, err), nil
75 }
76 }
77
78 return NewSuccessResponse(req.RequestID, folder), nil
79 })
80}
81
82// deleteFolderRequest is the payload for folder_delete messages.
83type deleteFolderRequest struct {
84 RequestID string `json:"requestId"`
85 ID int64 `json:"id"`
86}
87
88// HandleDelete handles folder_delete messages.
89func (h *FolderHandlers) HandleDelete() webkit.MessageHandler {
90 return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
91 log := logging.FromContext(ctx)
92
93 var req deleteFolderRequest
94 if err := json.Unmarshal(payload, &req); err != nil {
95 return NewErrorResponse("", err), nil
96 }
97
98 log.Debug().
99 Str("request_id", req.RequestID).
100 Int64("id", req.ID).
101 Msg("handling folder_delete")
102
103 if err := h.favoritesUC.DeleteFolder(ctx, entity.FolderID(req.ID)); err != nil {
104 return NewErrorResponse(req.RequestID, err), nil
105 }
106
107 return NewSuccessResponse(req.RequestID, nil), nil
108 })
109}
110
111// updateFolderRequest is the payload for folder_update messages.
112type updateFolderRequest struct {
113 RequestID string `json:"requestId"`
114 ID int64 `json:"id"`
115 Name string `json:"name"`
116 Icon *string `json:"icon"`
117}
118
119// HandleUpdate handles folder_update messages.
120// It delegates to the port.HomepageFavorites interface's UpdateFolder method.
121func (h *FolderHandlers) HandleUpdate() webkit.MessageHandler {
122 return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
123 log := logging.FromContext(ctx)
124
125 var req updateFolderRequest
126 if err := json.Unmarshal(payload, &req); err != nil {
127 return NewErrorResponse("", err), nil
128 }
129
130 log.Debug().
131 Str("request_id", req.RequestID).
132 Int64("id", req.ID).
133 Str("name", req.Name).
134 Msg("handling folder_update")
135
136 icon := ""
137 if req.Icon != nil {
138 icon = *req.Icon
139 }
140
141 if err := h.favoritesUC.UpdateFolder(ctx, entity.FolderID(req.ID), req.Name, icon); err != nil {
142 return NewErrorResponse(req.RequestID, err), nil
143 }
144
145 return NewSuccessResponse(req.RequestID, nil), nil
146 })
147}