1package handlers
2
3import (
4 "context"
5 "encoding/json"
6 "fmt"
7 "unicode/utf8"
8
9 "github.com/bnema/dumber/internal/application/port"
10 "github.com/bnema/dumber/internal/infrastructure/handlers/homepage"
11 "github.com/bnema/dumber/internal/logging"
12)
13
14// AccentKeyHandler is implemented by the InsertAccentUseCase to receive
15// key press/release events forwarded from WebView JS via the message bridge.
16//
17// Deprecated: use port.AccentKeyHandler instead. This alias is kept for compatibility.
18type AccentKeyHandler = port.AccentKeyHandler
19
20// RegisterAll registers all message handlers with the router.
21// The router can be any engine's message router that implements port.WebUIHandlerRouter.
22func RegisterAll(ctx context.Context, router port.WebUIHandlerRouter, deps port.HandlerDependencies) error {
23 // Homepage handlers (history, favorites, folders, tags)
24 if deps.HistoryUC != nil && deps.FavoritesUC != nil {
25 if err := homepage.RegisterHandlers(ctx, router, homepage.Config{
26 HistoryUC: deps.HistoryUC,
27 FavoritesUC: deps.FavoritesUC,
28 }); err != nil {
29 return err
30 }
31 }
32
33 // Configuration handlers
34 if deps.SaveConfig != nil {
35 if err := RegisterConfigHandlers(ctx, router, deps.SaveConfig); err != nil {
36 return err
37 }
38 }
39
40 // Keybindings handlers (always available)
41 if deps.KeybindingsGetter == nil {
42 return fmt.Errorf("KeybindingsGetter is required")
43 }
44 kbHandler := NewKeybindingsHandler(
45 deps.KeybindingsGetter,
46 deps.KeybindingSetter,
47 deps.KeybindingResetter,
48 deps.AllKeybindingsResetter,
49 )
50 if err := RegisterKeybindingsHandlers(ctx, router, kbHandler); err != nil {
51 return err
52 }
53
54 // Clipboard handlers (for auto-copy on selection feature)
55 if deps.ClipboardTextOrchestrator != nil {
56 if err := RegisterClipboardHandlers(ctx, router, deps.ClipboardTextOrchestrator); err != nil {
57 return err
58 }
59 }
60
61 return nil
62}
63
64// RegisterAccentHandlers registers accent key press/release handlers with the router.
65// Must be called after the AccentKeyHandler is initialized (i.e., after initAccentPicker).
66func RegisterAccentHandlers(_ context.Context, router port.WebUIHandlerRouter, handler AccentKeyHandler) error {
67 if router == nil {
68 return fmt.Errorf("RegisterAccentHandlers: router must not be nil")
69 }
70 if handler == nil {
71 return fmt.Errorf("RegisterAccentHandlers: handler must not be nil")
72 }
73
74 if err := router.RegisterHandler("accent_key_press", port.WebUIMessageHandlerFunc(
75 func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
76 var p struct {
77 Char string `json:"char"`
78 Shift bool `json:"shift"`
79 }
80 if err := json.Unmarshal(payload, &p); err != nil {
81 return nil, err
82 }
83 if r, _ := utf8.DecodeRuneInString(p.Char); r != utf8.RuneError && utf8.RuneCountInString(p.Char) == 1 {
84 handler.OnKeyPressed(ctx, r, p.Shift)
85 } else {
86 logging.FromContext(ctx).Debug().Str("char", p.Char).Msg("ignoring invalid accent_key_press char")
87 }
88 return nil, nil
89 },
90 )); err != nil {
91 return err
92 }
93
94 if err := router.RegisterHandler("accent_key_release", port.WebUIMessageHandlerFunc(
95 func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
96 var p struct {
97 Char string `json:"char"`
98 }
99 if err := json.Unmarshal(payload, &p); err != nil {
100 return nil, err
101 }
102 if r, _ := utf8.DecodeRuneInString(p.Char); r != utf8.RuneError && utf8.RuneCountInString(p.Char) == 1 {
103 handler.OnKeyReleased(ctx, r)
104 } else {
105 logging.FromContext(ctx).Debug().Str("char", p.Char).Msg("ignoring invalid accent_key_release char")
106 }
107 return nil, nil
108 },
109 )); err != nil {
110 return err
111 }
112
113 return nil
114}