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