v0.23.2 bfd5eb4

folders.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// FolderHandlers handles folder-related messages from the homepage.
14type FolderHandlers struct {
15	favoritesUC *usecase.ManageFavoritesUseCase
16}
17
18// NewFolderHandlers creates a new FolderHandlers instance.
19func NewFolderHandlers(favoritesUC *usecase.ManageFavoritesUseCase) *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
71		if req.Icon != nil && *req.Icon != "" {
72			folder.Icon = *req.Icon
73		}
74
75		return NewSuccessResponse(req.RequestID, folder), nil
76	})
77}
78
79// deleteFolderRequest is the payload for folder_delete messages.
80type deleteFolderRequest struct {
81	RequestID string `json:"requestId"`
82	ID        int64  `json:"id"`
83}
84
85// HandleDelete handles folder_delete messages.
86func (h *FolderHandlers) HandleDelete() webkit.MessageHandler {
87	return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
88		log := logging.FromContext(ctx)
89
90		var req deleteFolderRequest
91		if err := json.Unmarshal(payload, &req); err != nil {
92			return NewErrorResponse("", err), nil
93		}
94
95		log.Debug().
96			Str("request_id", req.RequestID).
97			Int64("id", req.ID).
98			Msg("handling folder_delete")
99
100		if err := h.favoritesUC.DeleteFolder(ctx, entity.FolderID(req.ID)); err != nil {
101			return NewErrorResponse(req.RequestID, err), nil
102		}
103
104		return NewSuccessResponse(req.RequestID, nil), nil
105	})
106}
107
108// updateFolderRequest is the payload for folder_update messages.
109type updateFolderRequest struct {
110	RequestID string  `json:"requestId"`
111	ID        int64   `json:"id"`
112	Name      string  `json:"name"`
113	Icon      *string `json:"icon"`
114}
115
116// HandleUpdate handles folder_update messages.
117// NOTE: This requires UpdateFolder() method to be added to ManageFavoritesUseCase.
118func (h *FolderHandlers) HandleUpdate() webkit.MessageHandler {
119	return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
120		log := logging.FromContext(ctx)
121
122		var req updateFolderRequest
123		if err := json.Unmarshal(payload, &req); err != nil {
124			return NewErrorResponse("", err), nil
125		}
126
127		log.Debug().
128			Str("request_id", req.RequestID).
129			Int64("id", req.ID).
130			Str("name", req.Name).
131			Msg("handling folder_update")
132
133		icon := ""
134		if req.Icon != nil {
135			icon = *req.Icon
136		}
137
138		if err := h.favoritesUC.UpdateFolder(ctx, entity.FolderID(req.ID), req.Name, icon); err != nil {
139			return NewErrorResponse(req.RequestID, err), nil
140		}
141
142		return NewSuccessResponse(req.RequestID, nil), nil
143	})
144}

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