separate domain listing into its own model
This commit is contained in:
parent
04ebd05a8f
commit
ef2dbcede5
5 changed files with 162 additions and 76 deletions
|
|
@ -7,6 +7,7 @@ type Page int
|
||||||
const (
|
const (
|
||||||
PageLogin Page = iota
|
PageLogin Page = iota
|
||||||
PageMenu
|
PageMenu
|
||||||
|
PageListDomains
|
||||||
)
|
)
|
||||||
|
|
||||||
type SwitchPageMsg struct {
|
type SwitchPageMsg struct {
|
||||||
|
|
@ -17,4 +18,7 @@ type SessionReadyMsg struct {
|
||||||
Client *porkbun.Client
|
Client *porkbun.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ListDomainsMsg struct {
|
||||||
|
}
|
||||||
|
|
||||||
type ErrorMsg error
|
type ErrorMsg error
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import (
|
||||||
|
|
||||||
"git.juancwu.dev/juancwu/porkbacon/internal/config"
|
"git.juancwu.dev/juancwu/porkbacon/internal/config"
|
||||||
"git.juancwu.dev/juancwu/porkbacon/internal/ui/messages"
|
"git.juancwu.dev/juancwu/porkbacon/internal/ui/messages"
|
||||||
|
"git.juancwu.dev/juancwu/porkbacon/internal/ui/pages/listdomains"
|
||||||
"git.juancwu.dev/juancwu/porkbacon/internal/ui/pages/login"
|
"git.juancwu.dev/juancwu/porkbacon/internal/ui/pages/login"
|
||||||
"git.juancwu.dev/juancwu/porkbacon/internal/ui/pages/menu"
|
"git.juancwu.dev/juancwu/porkbacon/internal/ui/pages/menu"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
|
|
@ -15,6 +16,7 @@ type MainModel struct {
|
||||||
currentPage messages.Page
|
currentPage messages.Page
|
||||||
login *login.Model
|
login *login.Model
|
||||||
menu *menu.Model
|
menu *menu.Model
|
||||||
|
listDomains *listdomains.Model
|
||||||
isMenuInit bool
|
isMenuInit bool
|
||||||
width int
|
width int
|
||||||
height int
|
height int
|
||||||
|
|
@ -42,6 +44,10 @@ func (m MainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
var cmds []tea.Cmd
|
var cmds []tea.Cmd
|
||||||
|
|
||||||
switch msg := msg.(type) {
|
switch msg := msg.(type) {
|
||||||
|
case tea.KeyMsg:
|
||||||
|
if msg.String() == "ctrl+c" {
|
||||||
|
return m, tea.Quit
|
||||||
|
}
|
||||||
case tea.WindowSizeMsg:
|
case tea.WindowSizeMsg:
|
||||||
m.width = msg.Width
|
m.width = msg.Width
|
||||||
m.height = msg.Height
|
m.height = msg.Height
|
||||||
|
|
@ -50,13 +56,16 @@ func (m MainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
return m, nil
|
return m, nil
|
||||||
case messages.SessionReadyMsg:
|
case messages.SessionReadyMsg:
|
||||||
m.menu = menu.New(msg.Client)
|
m.menu = menu.New(msg.Client)
|
||||||
|
m.listDomains = listdomains.New(msg.Client)
|
||||||
if m.width > 0 && m.height > 0 {
|
if m.width > 0 && m.height > 0 {
|
||||||
newMenu, _ := m.menu.Update(tea.WindowSizeMsg{Width: m.width, Height: m.height})
|
newMenu, _ := m.menu.Update(tea.WindowSizeMsg{Width: m.width, Height: m.height})
|
||||||
m.menu = newMenu.(*menu.Model)
|
m.menu = newMenu.(*menu.Model)
|
||||||
}
|
}
|
||||||
m.currentPage = messages.PageMenu
|
m.currentPage = messages.PageMenu
|
||||||
m.isMenuInit = true
|
m.isMenuInit = true
|
||||||
return m, m.menu.Init()
|
return m, tea.Batch(m.menu.Init(), m.listDomains.Init())
|
||||||
|
case messages.ListDomainsMsg:
|
||||||
|
m.currentPage = messages.PageListDomains
|
||||||
}
|
}
|
||||||
|
|
||||||
switch m.currentPage {
|
switch m.currentPage {
|
||||||
|
|
@ -68,6 +77,10 @@ func (m MainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
var newMenu tea.Model
|
var newMenu tea.Model
|
||||||
newMenu, cmd = m.menu.Update(msg)
|
newMenu, cmd = m.menu.Update(msg)
|
||||||
m.menu = newMenu.(*menu.Model)
|
m.menu = newMenu.(*menu.Model)
|
||||||
|
case messages.PageListDomains:
|
||||||
|
var newModel tea.Model
|
||||||
|
newModel, cmd = m.listDomains.Update(msg)
|
||||||
|
m.listDomains = newModel.(*listdomains.Model)
|
||||||
}
|
}
|
||||||
cmds = append(cmds, cmd)
|
cmds = append(cmds, cmd)
|
||||||
|
|
||||||
|
|
@ -80,6 +93,8 @@ func (m MainModel) View() string {
|
||||||
return m.login.View()
|
return m.login.View()
|
||||||
case messages.PageMenu:
|
case messages.PageMenu:
|
||||||
return m.menu.View()
|
return m.menu.View()
|
||||||
|
case messages.PageListDomains:
|
||||||
|
return m.listDomains.View()
|
||||||
default:
|
default:
|
||||||
return "Unknown Page"
|
return "Unknown Page"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
140
internal/ui/pages/listdomains/model.go
Normal file
140
internal/ui/pages/listdomains/model.go
Normal file
|
|
@ -0,0 +1,140 @@
|
||||||
|
package listdomains
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"git.juancwu.dev/juancwu/porkbacon/internal/porkbun"
|
||||||
|
"git.juancwu.dev/juancwu/porkbacon/internal/ui/messages"
|
||||||
|
"github.com/charmbracelet/bubbles/paginator"
|
||||||
|
"github.com/charmbracelet/bubbles/spinner"
|
||||||
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
|
"github.com/charmbracelet/lipgloss"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Model struct {
|
||||||
|
loading bool
|
||||||
|
client *porkbun.Client
|
||||||
|
domains []string
|
||||||
|
paginator paginator.Model
|
||||||
|
spinner spinner.Model
|
||||||
|
stderr string
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(client *porkbun.Client) *Model {
|
||||||
|
p := paginator.New()
|
||||||
|
p.Type = paginator.Dots
|
||||||
|
p.PerPage = 1
|
||||||
|
p.ActiveDot = lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{Light: "235", Dark: "252"}).Render("•")
|
||||||
|
p.InactiveDot = lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{Light: "250", Dark: "238"}).Render("•")
|
||||||
|
|
||||||
|
s := spinner.New()
|
||||||
|
s.Spinner = spinner.Dot
|
||||||
|
s.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("205"))
|
||||||
|
|
||||||
|
return &Model{
|
||||||
|
loading: false,
|
||||||
|
client: client,
|
||||||
|
domains: nil,
|
||||||
|
paginator: p,
|
||||||
|
spinner: s,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Model) Init() tea.Cmd {
|
||||||
|
return m.spinner.Tick
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
|
var cmd tea.Cmd
|
||||||
|
|
||||||
|
switch msg := msg.(type) {
|
||||||
|
case tea.KeyMsg:
|
||||||
|
if !m.loading && msg.String() == "esc" {
|
||||||
|
return m, func() tea.Msg {
|
||||||
|
m.loading = false
|
||||||
|
m.domains = nil
|
||||||
|
m.client = nil
|
||||||
|
return messages.SwitchPageMsg{Page: messages.PageMenu}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(m.domains) > 0 {
|
||||||
|
m.paginator, cmd = m.paginator.Update(msg)
|
||||||
|
return m, cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
case messages.ListDomainsMsg:
|
||||||
|
m.loading = true
|
||||||
|
m.domains = nil
|
||||||
|
return m, tea.Batch(listDomains(m.client), m.spinner.Tick)
|
||||||
|
|
||||||
|
case *porkbun.DomainListAllResponse:
|
||||||
|
m.loading = false
|
||||||
|
for _, domain := range msg.Domains {
|
||||||
|
m.domains = append(m.domains, renderDomain(&domain))
|
||||||
|
}
|
||||||
|
m.paginator.SetTotalPages(len(m.domains))
|
||||||
|
m.paginator.Page = 0
|
||||||
|
|
||||||
|
case messages.ErrorMsg:
|
||||||
|
m.stderr = fmt.Sprintf("Error: %v", msg)
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.loading {
|
||||||
|
m.spinner, cmd = m.spinner.Update(msg)
|
||||||
|
return m, tea.Batch(cmd, m.spinner.Tick)
|
||||||
|
}
|
||||||
|
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Model) View() string {
|
||||||
|
if m.stderr != "" {
|
||||||
|
return fmt.Sprintf("%s\n\n(Press ctrl+c to quit)", m.stderr)
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.loading {
|
||||||
|
return fmt.Sprintf("\n\n %s Loading... press ctl+c to quit\n\n", m.spinner.View())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(m.domains) > 0 {
|
||||||
|
return fmt.Sprintf("%s\n\n%s\n\n(Press Esc to go back, arrows to navigate)", m.domains[m.paginator.Page], m.paginator.View())
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Uhh.. This is awkward... Press Esc to go back."
|
||||||
|
}
|
||||||
|
|
||||||
|
func listDomains(client *porkbun.Client) tea.Cmd {
|
||||||
|
return func() tea.Msg {
|
||||||
|
resp, err := client.DomainListAll(0, true)
|
||||||
|
if err != nil {
|
||||||
|
return messages.ErrorMsg(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func renderDomain(item *porkbun.Domain) string {
|
||||||
|
var b strings.Builder
|
||||||
|
b.WriteString("Domain: " + item.Domain + "\n")
|
||||||
|
b.WriteString("Status: " + item.Status + "\n")
|
||||||
|
b.WriteString("Create Date: " + item.CreateDate + "\n")
|
||||||
|
b.WriteString("Expire Date: " + item.ExpireDate + "\n")
|
||||||
|
b.WriteString("Security Lock: " + item.SecurityLock + "\n")
|
||||||
|
b.WriteString("Whois Privacy: " + item.WhoIsPrivacy + "\n")
|
||||||
|
b.WriteString(fmt.Sprintln("Auto Renew:", item.AutoRenew))
|
||||||
|
b.WriteString(fmt.Sprintln("Not Local:", item.NotLocal))
|
||||||
|
if len(item.Labels) > 0 {
|
||||||
|
b.WriteString("Labels:\n")
|
||||||
|
}
|
||||||
|
for i, label := range item.Labels {
|
||||||
|
b.WriteString("=> " + label.Title)
|
||||||
|
if i < len(item.Labels)-1 {
|
||||||
|
b.WriteString("\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b.String()
|
||||||
|
}
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
package menu
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"git.juancwu.dev/juancwu/porkbacon/internal/porkbun"
|
|
||||||
)
|
|
||||||
|
|
||||||
func renderDomainItem(item *porkbun.Domain) string {
|
|
||||||
var b strings.Builder
|
|
||||||
b.WriteString("Domain: " + item.Domain + "\n")
|
|
||||||
b.WriteString("Status: " + item.Status + "\n")
|
|
||||||
b.WriteString("Create Date: " + item.CreateDate + "\n")
|
|
||||||
b.WriteString("Expire Date: " + item.ExpireDate + "\n")
|
|
||||||
b.WriteString("Security Lock: " + item.SecurityLock + "\n")
|
|
||||||
b.WriteString("Whois Privacy: " + item.WhoIsPrivacy + "\n")
|
|
||||||
b.WriteString(fmt.Sprintln("Auto Renew:", item.AutoRenew))
|
|
||||||
b.WriteString(fmt.Sprintln("Not Local:", item.NotLocal))
|
|
||||||
if len(item.Labels) > 0 {
|
|
||||||
b.WriteString("Labels:\n")
|
|
||||||
}
|
|
||||||
for i, label := range item.Labels {
|
|
||||||
b.WriteString("=> " + label.Title)
|
|
||||||
if i < len(item.Labels)-1 {
|
|
||||||
b.WriteString("\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return b.String()
|
|
||||||
}
|
|
||||||
|
|
@ -17,11 +17,6 @@ type pingResultMsg struct {
|
||||||
IP string
|
IP string
|
||||||
}
|
}
|
||||||
|
|
||||||
type domainListMsg struct {
|
|
||||||
Status string
|
|
||||||
Domains []string
|
|
||||||
}
|
|
||||||
|
|
||||||
type dnsRecordListMsg struct {
|
type dnsRecordListMsg struct {
|
||||||
Status string
|
Status string
|
||||||
Records []string
|
Records []string
|
||||||
|
|
@ -58,7 +53,6 @@ type Model struct {
|
||||||
textInput textinput.Model
|
textInput textinput.Model
|
||||||
loading bool
|
loading bool
|
||||||
state uint8
|
state uint8
|
||||||
domains []string
|
|
||||||
records []string
|
records []string
|
||||||
client *porkbun.Client
|
client *porkbun.Client
|
||||||
err error
|
err error
|
||||||
|
|
@ -159,16 +153,6 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(m.domains) > 0 {
|
|
||||||
var cmd tea.Cmd
|
|
||||||
m.paginator, cmd = m.paginator.Update(msg)
|
|
||||||
if msg.String() == "esc" {
|
|
||||||
m.domains = nil
|
|
||||||
return m, nil
|
|
||||||
}
|
|
||||||
return m, cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(m.records) > 0 {
|
if len(m.records) > 0 {
|
||||||
var cmd tea.Cmd
|
var cmd tea.Cmd
|
||||||
m.paginator, cmd = m.paginator.Update(msg)
|
m.paginator, cmd = m.paginator.Update(msg)
|
||||||
|
|
@ -191,15 +175,6 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
m.paginator.PerPage = 1
|
m.paginator.PerPage = 1
|
||||||
m.paginator.SetTotalPages(len(msg.Records))
|
m.paginator.SetTotalPages(len(msg.Records))
|
||||||
m.paginator.Page = 0
|
m.paginator.Page = 0
|
||||||
m.domains = msg.Records
|
|
||||||
return m, nil
|
|
||||||
|
|
||||||
case domainListMsg:
|
|
||||||
m.loading = false
|
|
||||||
m.paginator.PerPage = 1
|
|
||||||
m.paginator.SetTotalPages(len(msg.Domains))
|
|
||||||
m.paginator.Page = 0
|
|
||||||
m.domains = msg.Domains
|
|
||||||
return m, nil
|
return m, nil
|
||||||
|
|
||||||
case pingResultMsg:
|
case pingResultMsg:
|
||||||
|
|
@ -238,10 +213,6 @@ func (m *Model) View() string {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(m.domains) > 0 {
|
|
||||||
return fmt.Sprintf("%s\n\n%s\n\n(Press Esc to go back, arrows to navigate)", m.domains[m.paginator.Page], m.paginator.View())
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(m.records) > 0 {
|
if len(m.records) > 0 {
|
||||||
return fmt.Sprintf("%s\n\n%s\n\n(Press Esc to go back, arrows to navigate)", m.records[m.paginator.Page], m.paginator.View())
|
return fmt.Sprintf("%s\n\n%s\n\n(Press Esc to go back, arrows to navigate)", m.records[m.paginator.Page], m.paginator.View())
|
||||||
}
|
}
|
||||||
|
|
@ -256,23 +227,9 @@ func (m *Model) handleSelection(i menuItem) (tea.Model, tea.Cmd) {
|
||||||
m.textInput.Focus()
|
m.textInput.Focus()
|
||||||
return m, textinput.Blink
|
return m, textinput.Blink
|
||||||
case domainListAll:
|
case domainListAll:
|
||||||
m.loading = true
|
return m, func() tea.Msg {
|
||||||
cmd := func() tea.Msg {
|
return messages.ListDomainsMsg{}
|
||||||
resp, err := m.client.DomainListAll(0, true)
|
|
||||||
if err != nil {
|
|
||||||
return messages.ErrorMsg(err)
|
|
||||||
}
|
}
|
||||||
var domains []string
|
|
||||||
for _, domain := range resp.Domains {
|
|
||||||
view := renderDomainItem(&domain)
|
|
||||||
domains = append(domains, view)
|
|
||||||
}
|
|
||||||
return domainListMsg{
|
|
||||||
Status: resp.Status,
|
|
||||||
Domains: domains,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return m, tea.Batch(cmd, m.spinner.Tick)
|
|
||||||
case utilPing:
|
case utilPing:
|
||||||
m.loading = true
|
m.loading = true
|
||||||
cmd := func() tea.Msg {
|
cmd := func() tea.Msg {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue