main 5041353

setup_desktop.go RawHistoryFolder

1package usecase
2
3import (
4	"context"
5
6	"github.com/bnema/dumber/internal/application/port"
7	"github.com/bnema/dumber/internal/logging"
8)
9
10// InstallDesktopInput contains the input for the install operation.
11type InstallDesktopInput struct {
12	IconData []byte
13}
14
15// InstallDesktopUseCase installs the desktop file for system integration.
16type InstallDesktopUseCase struct {
17	desktop port.DesktopIntegration
18}
19
20// NewInstallDesktopUseCase creates a new InstallDesktopUseCase.
21func NewInstallDesktopUseCase(desktop port.DesktopIntegration) *InstallDesktopUseCase {
22	return &InstallDesktopUseCase{desktop: desktop}
23}
24
25// InstallDesktopOutput contains the result of the install operation.
26type InstallDesktopOutput struct {
27	DesktopPath        string
28	IconPath           string
29	WasDesktopExisting bool
30	WasIconExisting    bool
31}
32
33// Execute installs the desktop file and icon.
34func (uc *InstallDesktopUseCase) Execute(ctx context.Context, input InstallDesktopInput) (*InstallDesktopOutput, error) {
35	log := logging.FromContext(ctx)
36
37	// Check current status first
38	status, err := uc.desktop.GetStatus(ctx)
39	if err != nil {
40		return nil, err
41	}
42
43	output := &InstallDesktopOutput{
44		WasDesktopExisting: status.DesktopFileInstalled,
45		WasIconExisting:    status.IconInstalled,
46	}
47
48	// Install desktop file
49	desktopPath, err := uc.desktop.InstallDesktopFile(ctx)
50	if err != nil {
51		return nil, err
52	}
53	output.DesktopPath = desktopPath
54
55	// Install icon if data provided
56	if len(input.IconData) > 0 {
57		iconPath, err := uc.desktop.InstallIcon(ctx, input.IconData)
58		if err != nil {
59			return nil, err
60		}
61		output.IconPath = iconPath
62	}
63
64	log.Info().
65		Str("desktop_path", output.DesktopPath).
66		Str("icon_path", output.IconPath).
67		Bool("was_desktop_existing", output.WasDesktopExisting).
68		Bool("was_icon_existing", output.WasIconExisting).
69		Msg("desktop install complete")
70
71	return output, nil
72}
73
74// SetDefaultBrowserUseCase sets dumber as the default web browser.
75type SetDefaultBrowserUseCase struct {
76	desktop port.DesktopIntegration
77}
78
79// NewSetDefaultBrowserUseCase creates a new SetDefaultBrowserUseCase.
80func NewSetDefaultBrowserUseCase(desktop port.DesktopIntegration) *SetDefaultBrowserUseCase {
81	return &SetDefaultBrowserUseCase{desktop: desktop}
82}
83
84// SetDefaultOutput contains the result of the set-default operation.
85type SetDefaultOutput struct {
86	WasAlreadyDefault bool
87}
88
89// Execute sets dumber as the default browser.
90func (uc *SetDefaultBrowserUseCase) Execute(ctx context.Context) (*SetDefaultOutput, error) {
91	log := logging.FromContext(ctx)
92
93	// Check current status
94	status, err := uc.desktop.GetStatus(ctx)
95	if err != nil {
96		return nil, err
97	}
98
99	if status.IsDefaultBrowser {
100		log.Debug().Msg("dumber is already default browser")
101		return &SetDefaultOutput{WasAlreadyDefault: true}, nil
102	}
103
104	// Set as default
105	if err := uc.desktop.SetAsDefaultBrowser(ctx); err != nil {
106		return nil, err
107	}
108
109	return &SetDefaultOutput{WasAlreadyDefault: false}, nil
110}
111
112// RemoveDesktopUseCase removes desktop integration files.
113type RemoveDesktopUseCase struct {
114	desktop port.DesktopIntegration
115}
116
117// NewRemoveDesktopUseCase creates a new RemoveDesktopUseCase.
118func NewRemoveDesktopUseCase(desktop port.DesktopIntegration) *RemoveDesktopUseCase {
119	return &RemoveDesktopUseCase{desktop: desktop}
120}
121
122// RemoveDesktopOutput contains the result of the remove operation.
123type RemoveDesktopOutput struct {
124	WasDesktopInstalled bool
125	WasIconInstalled    bool
126	WasDefault          bool
127	RemovedDesktopPath  string
128	RemovedIconPath     string
129}
130
131// Execute removes desktop integration.
132func (uc *RemoveDesktopUseCase) Execute(ctx context.Context) (*RemoveDesktopOutput, error) {
133	log := logging.FromContext(ctx)
134
135	// Check current status
136	status, err := uc.desktop.GetStatus(ctx)
137	if err != nil {
138		return nil, err
139	}
140
141	output := &RemoveDesktopOutput{
142		WasDesktopInstalled: status.DesktopFileInstalled,
143		WasIconInstalled:    status.IconInstalled,
144		WasDefault:          status.IsDefaultBrowser,
145		RemovedDesktopPath:  status.DesktopFilePath,
146		RemovedIconPath:     status.IconFilePath,
147	}
148
149	// Unset as default browser first (if applicable)
150	if status.IsDefaultBrowser {
151		if err := uc.desktop.UnsetAsDefaultBrowser(ctx); err != nil {
152			log.Warn().Err(err).Msg("failed to unset default browser")
153		}
154	}
155
156	// Remove desktop file
157	if err := uc.desktop.RemoveDesktopFile(ctx); err != nil {
158		return nil, err
159	}
160
161	// Remove icon file
162	if err := uc.desktop.RemoveIcon(ctx); err != nil {
163		return nil, err
164	}
165
166	log.Info().
167		Bool("was_desktop_installed", output.WasDesktopInstalled).
168		Bool("was_icon_installed", output.WasIconInstalled).
169		Bool("was_default", output.WasDefault).
170		Msg("desktop integration removed")
171
172	return output, nil
173}

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