1package cmd
2
3import (
4 "fmt"
5 "strings"
6
7 "github.com/spf13/cobra"
8
9 "github.com/bnema/dumber/assets"
10 "github.com/bnema/dumber/internal/application/usecase"
11 "github.com/bnema/dumber/internal/infrastructure/desktop"
12 "github.com/bnema/dumber/internal/infrastructure/env"
13)
14
15var setupCmd = &cobra.Command{
16 Use: "setup",
17 Short: "Setup desktop integration",
18 Long: `Setup dumber's integration with the desktop environment.
19
20Subcommands:
21 install - Install desktop file to ~/.local/share/applications/
22 default - Set dumber as the default web browser`,
23}
24
25var setupInstallCmd = &cobra.Command{
26 Use: "install",
27 Short: "Install desktop file",
28 Long: `Install the dumber.desktop file to the user's applications directory.
29
30This registers dumber with the desktop environment, making it appear in
31application menus and available as a browser choice.
32
33Location: $XDG_DATA_HOME/applications/dumber.desktop
34 (typically ~/.local/share/applications/dumber.desktop)
35
36This command is idempotent - safe to run multiple times.`,
37 RunE: runSetupInstall,
38}
39
40var setupDefaultCmd = &cobra.Command{
41 Use: "default",
42 Short: "Set dumber as default browser",
43 Long: `Set dumber as the default web browser using xdg-settings.
44
45This makes dumber handle http:// and https:// links from other applications.
46
47Requires the desktop file to be installed first (run 'dumber setup install').
48
49This command is idempotent - safe to run multiple times.`,
50 RunE: runSetupDefault,
51}
52
53func init() {
54 rootCmd.AddCommand(setupCmd)
55 setupCmd.AddCommand(setupInstallCmd)
56 setupCmd.AddCommand(setupDefaultCmd)
57}
58
59func runSetupInstall(_ *cobra.Command, _ []string) error {
60 cliApp := GetApp()
61 if cliApp == nil {
62 return fmt.Errorf("app not initialized")
63 }
64
65 theme := cliApp.Theme
66
67 // Check if installed via package manager
68 switch {
69 case env.IsFlatpak():
70 fmt.Printf("%s Desktop integration already handled by Flatpak\n",
71 theme.SuccessStyle.Render("\u2713"))
72 fmt.Println()
73 fmt.Println(theme.Subtle.Render("Run 'dumber setup default' to set as default browser"))
74 return nil
75 case env.IsPacman():
76 fmt.Printf("%s Desktop integration already handled by AUR package\n",
77 theme.SuccessStyle.Render("\u2713"))
78 fmt.Println()
79 fmt.Println(theme.Subtle.Render("Run 'dumber setup default' to set as default browser"))
80 return nil
81 }
82
83 adapter := desktop.New()
84 uc := usecase.NewInstallDesktopUseCase(adapter)
85
86 input := usecase.InstallDesktopInput{
87 IconData: assets.LogoSVG,
88 }
89
90 result, err := uc.Execute(cliApp.Ctx(), input)
91 if err != nil {
92 fmt.Printf("%s %s\n", theme.ErrorStyle.Render("\u2717"), err.Error())
93 return err
94 }
95
96 // Desktop file status
97 if result.WasDesktopExisting {
98 fmt.Printf("%s Desktop file updated at %s\n",
99 theme.SuccessStyle.Render("\u2713"),
100 theme.Highlight.Render(result.DesktopPath))
101 } else {
102 fmt.Printf("%s Desktop file installed to %s\n",
103 theme.SuccessStyle.Render("\u2713"),
104 theme.Highlight.Render(result.DesktopPath))
105 }
106
107 // Icon status
108 if result.IconPath != "" {
109 if result.WasIconExisting {
110 fmt.Printf("%s Icon updated at %s\n",
111 theme.SuccessStyle.Render("\u2713"),
112 theme.Highlight.Render(result.IconPath))
113 } else {
114 fmt.Printf("%s Icon installed to %s\n",
115 theme.SuccessStyle.Render("\u2713"),
116 theme.Highlight.Render(result.IconPath))
117 }
118 }
119
120 fmt.Println()
121 fmt.Println(theme.Subtle.Render("Run 'dumber setup default' to set as default browser"))
122
123 return nil
124}
125
126func runSetupDefault(_ *cobra.Command, _ []string) error {
127 cliApp := GetApp()
128 if cliApp == nil {
129 return fmt.Errorf("app not initialized")
130 }
131
132 theme := cliApp.Theme
133 adapter := desktop.New()
134 uc := usecase.NewSetDefaultBrowserUseCase(adapter)
135
136 result, err := uc.Execute(cliApp.Ctx())
137 if err != nil {
138 errMsg := err.Error()
139 fmt.Printf("%s %s\n", theme.ErrorStyle.Render("\u2717"), errMsg)
140 if strings.Contains(errMsg, "desktop file not installed") {
141 fmt.Println()
142 fmt.Println(theme.Subtle.Render("Hint: Run 'dumber setup install' first"))
143 }
144 return err
145 }
146
147 if result.WasAlreadyDefault {
148 fmt.Printf("%s Dumber is already the default browser\n",
149 theme.SuccessStyle.Render("\u2713"))
150 } else {
151 fmt.Printf("%s Dumber is now the default browser\n",
152 theme.SuccessStyle.Render("\u2713"))
153 }
154
155 return nil
156}