Skip to content

Commit

Permalink
feat: add a hotkey for copying the custom domain to the clipboard (#385)
Browse files Browse the repository at this point in the history
  • Loading branch information
purpleclay authored Oct 14, 2023
1 parent 2271025 commit 7b8c27e
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 19 deletions.
1 change: 1 addition & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ func awsConfig(opts *globalOptions) (aws.Config, error) {
if opts.awsRegion != "" {
optsFn = append(optsFn, config.WithRegion(opts.awsRegion))
}
optsFn = append(optsFn, config.WithEC2IMDSEndpoint("http://localhost:1338"))

return config.LoadDefaultConfig(context.Background(), optsFn...)
}
Expand Down
10 changes: 8 additions & 2 deletions internal/tui/keymap/keymap.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,19 @@ var (
key.WithKeys("/"),
key.WithHelp("/", "filter"),
)

Escape = key.NewBinding(
key.WithKeys("esc"),
key.WithHelp("esc", "back"),
)

Quit = key.NewBinding(
key.WithKeys("ctrl+c"),
key.WithHelp("ctrl+c", "quit"),
key.WithKeys("q", "ctrl+c"),
key.WithHelp("q / ctrl+c", "quit"),
)

Copy = key.NewBinding(
key.WithKeys("c"),
key.WithHelp("c", "copy dns"),
)
)
6 changes: 6 additions & 0 deletions internal/tui/message/messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,9 @@ type RefreshKeymapMsg struct{}
func RefreshKeyMapCmd() tea.Msg {
return RefreshKeymapMsg{}
}

// ClipboardStatusMsg should be sent to update the message within the
// clipboard status panel
type ClipboardStatusMsg struct {
Status string
}
66 changes: 49 additions & 17 deletions internal/tui/pages/dashboard/dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@ import (
"context"
"fmt"
"strings"
"time"

"github.com/charmbracelet/bubbles/key"
"github.com/charmbracelet/bubbles/stopwatch"
"github.com/charmbracelet/bubbles/viewport"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/muesli/termenv"
"github.com/purpleclay/dns53/internal/imds"
"github.com/purpleclay/dns53/internal/r53"
"github.com/purpleclay/dns53/internal/tui/components/errorpanel"
Expand All @@ -49,27 +51,31 @@ type Options struct {
Client *r53.Client
Metadata imds.Metadata
DomainName string
Output *termenv.Output
}

type Model struct {
viewport viewport.Model
options Options
domainName string
selected r53.PrivateHostedZone
connected bool
elapsed stopwatch.Model
errorPanel errorpanel.Model
errorRaised bool
styles *Styles
viewport viewport.Model
options Options
domainName string
clipboardStatus string
clipboardTimeout stopwatch.Model
selected r53.PrivateHostedZone
connected bool
elapsed stopwatch.Model
errorPanel errorpanel.Model
errorRaised bool
styles *Styles
}

func New(opts Options) Model {
return Model{
viewport: viewport.New(0, 0),
options: opts,
elapsed: stopwatch.New(),
errorPanel: errorpanel.New(),
styles: DefaultStyles(),
clipboardTimeout: stopwatch.NewWithInterval(time.Second * 2),
viewport: viewport.New(0, 0),
options: opts,
elapsed: stopwatch.New(),
errorPanel: errorpanel.New(),
styles: DefaultStyles(),
}
}

Expand All @@ -92,9 +98,17 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case r53AssociatedMsg:
m.connected = true
cmds = append(cmds, m.elapsed.Start())

// Request the keymap to be refreshed, as the DNS is now resolved
cmds = append(cmds, message.RefreshKeyMapCmd)
case message.ErrorMsg:
m.errorPanel = m.errorPanel.RaiseError(msg.Reason, msg.Cause)
m.errorRaised = true
case stopwatch.TickMsg:
if msg.ID == m.clipboardTimeout.ID() {
m.clipboardStatus = ""
cmds = append(cmds, m.clipboardTimeout.Stop())
}
case tea.KeyMsg:
switch {
case key.Matches(msg, keymap.Quit):
Expand All @@ -107,12 +121,23 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {

m.options.Client.DisassociateRecord(context.Background(), record)
}
case key.Matches(msg, keymap.Copy):
m.options.Output.Copy(m.domainName)
m.clipboardStatus = "(copied to clipboard)"

// Trigger the timer to clear the clipboard message
cmds = append(cmds, m.clipboardTimeout.Reset(), m.clipboardTimeout.Start())
}
}

if m.connected {
m.elapsed, cmd = m.elapsed.Update(msg)
cmds = append(cmds, cmd)

if m.clipboardTimeout.Running() {
m.clipboardTimeout, cmd = m.clipboardTimeout.Update(msg)
cmds = append(cmds, cmd)
}
}

return m, tea.Batch(cmds...)
Expand Down Expand Up @@ -151,7 +176,11 @@ func (m Model) View() string {

dnsData := lipgloss.JoinVertical(
lipgloss.Top,
fmt.Sprintf(dashboardLine+" [A]", m.styles.SecondaryLabel.Render("Record:"), m.styles.Spacing, m.styles.Highlight.Render(m.domainName)),
fmt.Sprintf(dashboardLine+" [A] %s",
m.styles.SecondaryLabel.Render("Record:"),
m.styles.Spacing,
m.styles.Highlight.Render(m.domainName),
m.styles.Feint.Render(m.clipboardStatus)),
fmt.Sprintf(dashboardLine, m.styles.SecondaryLabel.Render("Status:"), m.styles.Spacing, status),
)

Expand Down Expand Up @@ -182,9 +211,12 @@ func (m Model) View() string {
}

func (m Model) ShortHelp() []key.Binding {
return []key.Binding{
keymap.Quit,
bindings := []key.Binding{keymap.Quit}
if m.connected {
bindings = append(bindings, keymap.Copy)
}

return bindings
}

func (m Model) FullHelp() [][]key.Binding {
Expand Down
2 changes: 2 additions & 0 deletions internal/tui/pages/dashboard/style.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type Styles struct {
PendingStatus lipgloss.Style
ActiveStatus lipgloss.Style
Highlight lipgloss.Style
Feint lipgloss.Style
}

func DefaultStyles() *Styles {
Expand Down Expand Up @@ -68,5 +69,6 @@ func DefaultStyles() *Styles {

s.Highlight = theme.HightlightTextStyle.Copy().Bold(true)

s.Feint = theme.VeryFeintTextStyle.Copy()
return s
}
6 changes: 6 additions & 0 deletions internal/tui/ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@ SOFTWARE.
package tui

import (
"os"

"github.com/charmbracelet/bubbles/key"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/muesli/termenv"
"github.com/purpleclay/dns53/internal/tui/components"
"github.com/purpleclay/dns53/internal/tui/components/footer"
"github.com/purpleclay/dns53/internal/tui/components/header"
Expand All @@ -52,6 +55,8 @@ type UI struct {
}

func New(opts Options) UI {
output := termenv.NewOutput(os.Stderr)

pages := []pages.Model{
wizard.New(wizard.Options{
Client: opts.R53Client,
Expand All @@ -63,6 +68,7 @@ func New(opts Options) UI {
Client: opts.R53Client,
Metadata: opts.EC2Metadata,
DomainName: opts.DomainName,
Output: output,
}),
}

Expand Down

0 comments on commit 7b8c27e

Please sign in to comment.