ghdash.go

 1// Package ghdash provides a dialog component for embedding gh-dash in the TUI.
 2package ghdash
 3
 4import (
 5	"context"
 6	"fmt"
 7	"image/color"
 8	"os"
 9
10	"github.com/charmbracelet/crush/internal/terminal"
11	"github.com/charmbracelet/crush/internal/tui/components/dialogs"
12	"github.com/charmbracelet/crush/internal/tui/components/dialogs/termdialog"
13	"github.com/charmbracelet/crush/internal/tui/styles"
14)
15
16// DialogID is the unique identifier for the gh-dash dialog.
17const DialogID dialogs.DialogID = "ghdash"
18
19// NewDialog creates a new gh-dash dialog. The context controls the lifetime
20// of the gh-dash process - when cancelled, the process will be killed.
21func NewDialog(ctx context.Context, workingDir string) *termdialog.Dialog {
22	configFile := createThemedConfig()
23
24	cmd := terminal.PrepareCmd(
25		ctx,
26		"gh",
27		[]string{"dash", "--config", configFile},
28		workingDir,
29		nil,
30	)
31
32	return termdialog.New(termdialog.Config{
33		ID:         DialogID,
34		Title:      "GitHub Dashboard",
35		LoadingMsg: "Starting gh-dash...",
36		Term:       terminal.New(terminal.Config{Context: ctx, Cmd: cmd}),
37		QuitHint:   "q to close",
38		OnClose: func() {
39			if configFile != "" {
40				_ = os.Remove(configFile)
41			}
42		},
43	})
44}
45
46// colorToHex converts a color.Color to a hex string.
47func colorToHex(c color.Color) string {
48	r, g, b, _ := c.RGBA()
49	return fmt.Sprintf("#%02x%02x%02x", r>>8, g>>8, b>>8)
50}
51
52// createThemedConfig creates a temporary gh-dash config file with Crush theme.
53func createThemedConfig() string {
54	t := styles.CurrentTheme()
55
56	config := fmt.Sprintf(`theme:
57  colors:
58    text:
59      primary: "%s"
60      secondary: "%s"
61      inverted: "%s"
62      faint: "%s"
63      warning: "%s"
64      success: "%s"
65      error: "%s"
66    background:
67      selected: "%s"
68    border:
69      primary: "%s"
70      secondary: "%s"
71      faint: "%s"
72`,
73		colorToHex(t.FgBase),
74		colorToHex(t.FgMuted),
75		colorToHex(t.FgSelected),
76		colorToHex(t.FgSubtle),
77		colorToHex(t.Warning),
78		colorToHex(t.Success),
79		colorToHex(t.Error),
80		colorToHex(t.Primary),
81		colorToHex(t.BorderFocus),
82		colorToHex(t.FgMuted),
83		colorToHex(t.BgSubtle),
84	)
85
86	f, err := os.CreateTemp("", "crush-ghdash-*.yml")
87	if err != nil {
88		return ""
89	}
90	defer f.Close()
91
92	_, _ = f.WriteString(config)
93	return f.Name()
94}