v0.27.2 5960dd8

favorites.go RawHistoryFolder

1package homepage
2
3import (
4	"context"
5	"encoding/json"
6
7	"github.com/bnema/dumber/internal/application/usecase"
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// FavoritesHandlers handles favorite-related messages from the homepage.
14type FavoritesHandlers struct {
15	favoritesUC *usecase.ManageFavoritesUseCase
16}
17
18// NewFavoritesHandlers creates a new FavoritesHandlers instance.
19func NewFavoritesHandlers(favoritesUC *usecase.ManageFavoritesUseCase) *FavoritesHandlers {
20	return &FavoritesHandlers{favoritesUC: favoritesUC}
21}
22
23// HandleList handles favorite_list messages.
24func (h *FavoritesHandlers) 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 favorite_list")
33
34		favorites, err := h.favoritesUC.GetAll(ctx)
35		if err != nil {
36			return NewErrorResponse(requestID, err), nil
37		}
38
39		return NewSuccessResponse(requestID, favorites), nil
40	})
41}
42
43// setShortcutRequest is the payload for favorite_set_shortcut messages.
44type setShortcutRequest struct {
45	RequestID   string `json:"requestId"`
46	FavoriteID  int64  `json:"favorite_id"`
47	ShortcutKey *int   `json:"shortcut_key"` // 1-9 or null to remove
48}
49
50// HandleSetShortcut handles favorite_set_shortcut messages.
51func (h *FavoritesHandlers) HandleSetShortcut() 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 setShortcutRequest
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			Int64("favorite_id", req.FavoriteID).
63			Msg("handling favorite_set_shortcut")
64
65		if err := h.favoritesUC.SetShortcut(ctx, entity.FavoriteID(req.FavoriteID), req.ShortcutKey); err != nil {
66			return NewErrorResponse(req.RequestID, err), nil
67		}
68
69		return NewSuccessResponse(req.RequestID, nil), nil
70	})
71}
72
73// getByShortcutRequest is the payload for favorite_get_by_shortcut messages.
74type getByShortcutRequest struct {
75	RequestID   string `json:"requestId"`
76	ShortcutKey int    `json:"shortcut_key"`
77}
78
79// HandleGetByShortcut handles favorite_get_by_shortcut messages.
80func (h *FavoritesHandlers) HandleGetByShortcut() webkit.MessageHandler {
81	return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
82		log := logging.FromContext(ctx)
83
84		var req getByShortcutRequest
85		if err := json.Unmarshal(payload, &req); err != nil {
86			return NewErrorResponse("", err), nil
87		}
88
89		log.Debug().
90			Str("request_id", req.RequestID).
91			Int("shortcut_key", req.ShortcutKey).
92			Msg("handling favorite_get_by_shortcut")
93
94		favorite, err := h.favoritesUC.GetByShortcut(ctx, req.ShortcutKey)
95		if err != nil {
96			return NewErrorResponse(req.RequestID, err), nil
97		}
98
99		return NewSuccessResponse(req.RequestID, favorite), nil
100	})
101}
102
103// setFolderRequest is the payload for favorite_set_folder messages.
104type setFolderRequest struct {
105	RequestID  string `json:"requestId"`
106	FavoriteID int64  `json:"favorite_id"`
107	FolderID   *int64 `json:"folder_id"` // null to move to root
108}
109
110// HandleSetFolder handles favorite_set_folder messages.
111func (h *FavoritesHandlers) HandleSetFolder() webkit.MessageHandler {
112	return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
113		log := logging.FromContext(ctx)
114
115		var req setFolderRequest
116		if err := json.Unmarshal(payload, &req); err != nil {
117			return NewErrorResponse("", err), nil
118		}
119
120		log.Debug().
121			Str("request_id", req.RequestID).
122			Int64("favorite_id", req.FavoriteID).
123			Msg("handling favorite_set_folder")
124
125		var folderID *entity.FolderID
126		if req.FolderID != nil {
127			id := entity.FolderID(*req.FolderID)
128			folderID = &id
129		}
130
131		if err := h.favoritesUC.Move(ctx, entity.FavoriteID(req.FavoriteID), folderID); err != nil {
132			return NewErrorResponse(req.RequestID, err), nil
133		}
134
135		return NewSuccessResponse(req.RequestID, nil), nil
136	})
137}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close