From e4c21e8552ac57c33e60253cebe53cc74c8236f5 Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Mon, 25 Nov 2024 16:03:29 -0500 Subject: [PATCH] refactor: remove unused TUI components --- app/cli/dexmodel/dexmodel.go | 165 ------------------ app/cli/tui.go | 44 ----- app/cli/txmodel/txmodel.go | 322 ----------------------------------- cmd/sonrd/main.go | 3 - 4 files changed, 534 deletions(-) delete mode 100644 app/cli/dexmodel/dexmodel.go delete mode 100644 app/cli/tui.go delete mode 100644 app/cli/txmodel/txmodel.go diff --git a/app/cli/dexmodel/dexmodel.go b/app/cli/dexmodel/dexmodel.go deleted file mode 100644 index c6a77a8d8..000000000 --- a/app/cli/dexmodel/dexmodel.go +++ /dev/null @@ -1,165 +0,0 @@ -package dexmodel - -import ( - "fmt" - "time" - - "github.com/charmbracelet/bubbles/table" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" - "github.com/spf13/cobra" -) - -var ( - subtle = lipgloss.AdaptiveColor{Light: "#D9DCCF", Dark: "#383838"} - highlight = lipgloss.AdaptiveColor{Light: "#874BFD", Dark: "#7D56F4"} - special = lipgloss.AdaptiveColor{Light: "#43BF6D", Dark: "#73F59F"} - - titleStyle = lipgloss.NewStyle(). - MarginLeft(1). - MarginRight(5). - Padding(0, 1). - Italic(true). - Foreground(lipgloss.Color("#FFF7DB")). - SetString("Cosmos Block Explorer") - - infoStyle = lipgloss.NewStyle(). - BorderStyle(lipgloss.NormalBorder()). - BorderTop(true). - BorderForeground(subtle) -) - -type model struct { - blocks []string - transactionTable table.Model - stats map[string]string - width int - height int -} - -func initialModel() model { - columns := []table.Column{ - {Title: "Hash", Width: 10}, - {Title: "Type", Width: 15}, - {Title: "Height", Width: 10}, - {Title: "Time", Width: 20}, - } - - rows := []table.Row{ - {"abc123", "Transfer", "1000", time.Now().Format(time.RFC3339)}, - {"def456", "Delegate", "999", time.Now().Add(-1 * time.Minute).Format(time.RFC3339)}, - {"ghi789", "Vote", "998", time.Now().Add(-2 * time.Minute).Format(time.RFC3339)}, - } - - t := table.New( - table.WithColumns(columns), - table.WithRows(rows), - table.WithFocused(true), - table.WithHeight(7), - ) - - s := table.DefaultStyles() - s.Header = s.Header. - BorderStyle(lipgloss.NormalBorder()). - BorderForeground(lipgloss.Color("240")). - BorderBottom(true). - Bold(false) - s.Selected = s.Selected. - Foreground(lipgloss.Color("229")). - Background(lipgloss.Color("57")). - Bold(false) - t.SetStyles(s) - - return model{ - blocks: []string{"Block 1", "Block 2", "Block 3"}, - transactionTable: t, - stats: map[string]string{ - "Latest Block": "1000", - "Validators": "100", - "Bonded Tokens": "1,000,000", - }, - } -} - -func (m model) Init() tea.Cmd { - return tick -} - -func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - var cmd tea.Cmd - switch msg := msg.(type) { - case tea.KeyMsg: - switch msg.String() { - case "q", "ctrl+c": - return m, tea.Quit - case "enter": - return m, tea.Batch( - tea.Printf("Selected transaction: %s", m.transactionTable.SelectedRow()[0]), - ) - } - case tea.WindowSizeMsg: - m.height = msg.Height - m.width = msg.Width - case tickMsg: - // Update data here - m.blocks = append([]string{"New Block"}, m.blocks...) - if len(m.blocks) > 5 { - m.blocks = m.blocks[:5] - } - - // Add a new transaction to the table - newRow := table.Row{ - fmt.Sprintf("tx%d", time.Now().Unix()), - "NewTxType", - fmt.Sprintf("%d", 1000+len(m.transactionTable.Rows())), - time.Now().Format(time.RFC3339), - } - m.transactionTable.SetRows(append([]table.Row{newRow}, m.transactionTable.Rows()...)) - if len(m.transactionTable.Rows()) > 10 { - m.transactionTable.SetRows(m.transactionTable.Rows()[:10]) - } - - return m, tick - } - m.transactionTable, cmd = m.transactionTable.Update(msg) - return m, cmd -} - -func (m model) View() string { - s := titleStyle.Render("Cosmos Block Explorer") - s += "\n\n" - - // Blocks - s += lipgloss.NewStyle().Bold(true).Render("Recent Blocks") + "\n" - for _, block := range m.blocks { - s += "• " + block + "\n" - } - s += "\n" - - // Transactions - s += lipgloss.NewStyle().Bold(true).Render("Recent Transactions") + "\n" - s += m.transactionTable.View() + "\n\n" - - // Stats - s += lipgloss.NewStyle().Bold(true).Render("Network Statistics") + "\n" - for key, value := range m.stats { - s += fmt.Sprintf("%s: %s\n", key, value) - } - - return s -} - -type tickMsg time.Time - -func tick() tea.Msg { - time.Sleep(time.Second) - return tickMsg{} -} - -func RunExplorerTUI(cmd *cobra.Command, args []string) error { - p := tea.NewProgram(initialModel(), tea.WithAltScreen()) - if _, err := p.Run(); err != nil { - return fmt.Errorf("error running explorer: %v", err) - } - return nil -} diff --git a/app/cli/tui.go b/app/cli/tui.go deleted file mode 100644 index b5305baff..000000000 --- a/app/cli/tui.go +++ /dev/null @@ -1,44 +0,0 @@ -package cli - -import ( - "fmt" - - "github.com/cosmos/cosmos-sdk/codec" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - "github.com/onsonr/sonr/app/cli/dexmodel" - "github.com/onsonr/sonr/app/cli/txmodel" - "github.com/spf13/cobra" -) - -func NewBuildTxnTUICmd() *cobra.Command { - return &cobra.Command{ - Use: "dash", - Short: "TUI for managing the local Sonr validator node", - RunE: func(cmd *cobra.Command, args []string) error { - txBody, err := txmodel.RunBuildTxnTUI() - if err != nil { - return err - } - - interfaceRegistry := codectypes.NewInterfaceRegistry() - marshaler := codec.NewProtoCodec(interfaceRegistry) - jsonBytes, err := marshaler.MarshalJSON(txBody) - if err != nil { - return fmt.Errorf("failed to marshal tx body: %w", err) - } - - fmt.Println("Generated Protobuf Message (JSON format):") - fmt.Println(string(jsonBytes)) - - return nil - }, - } -} - -func NewExplorerTUICmd() *cobra.Command { - return &cobra.Command{ - Use: "cosmos-explorer", - Short: "A terminal-based Cosmos blockchain explorer", - RunE: dexmodel.RunExplorerTUI, - } -} diff --git a/app/cli/txmodel/txmodel.go b/app/cli/txmodel/txmodel.go deleted file mode 100644 index 4c493ad24..000000000 --- a/app/cli/txmodel/txmodel.go +++ /dev/null @@ -1,322 +0,0 @@ -package txmodel - -import ( - "fmt" - "strings" - - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/huh" - "github.com/charmbracelet/lipgloss" - "github.com/cosmos/cosmos-sdk/codec" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/tx" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" -) - -const maxWidth = 100 - -var ( - red = lipgloss.AdaptiveColor{Light: "#FE5F86", Dark: "#FE5F86"} - indigo = lipgloss.AdaptiveColor{Light: "#5A56E0", Dark: "#7571F9"} - green = lipgloss.AdaptiveColor{Light: "#02BA84", Dark: "#02BF87"} -) - -type Styles struct { - Base, - HeaderText, - Status, - StatusHeader, - Highlight, - ErrorHeaderText, - Help lipgloss.Style -} - -func NewStyles(lg *lipgloss.Renderer) *Styles { - s := Styles{} - s.Base = lg.NewStyle(). - Padding(1, 2, 0, 1) - s.HeaderText = lg.NewStyle(). - Foreground(indigo). - Bold(true). - Padding(0, 1, 0, 1) - s.Status = lg.NewStyle(). - Border(lipgloss.RoundedBorder()). - BorderForeground(indigo). - PaddingLeft(1). - MarginTop(1) - s.StatusHeader = lg.NewStyle(). - Foreground(green). - Bold(true) - s.Highlight = lg.NewStyle(). - Foreground(lipgloss.Color("212")) - s.ErrorHeaderText = s.HeaderText. - Foreground(red) - s.Help = lg.NewStyle(). - Foreground(lipgloss.Color("240")) - return &s -} - -type state int - -const ( - statusNormal state = iota - stateDone -) - -type Model struct { - state state - lg *lipgloss.Renderer - styles *Styles - form *huh.Form - width int - message *tx.TxBody -} - -func NewModel() Model { - m := Model{width: maxWidth} - m.lg = lipgloss.DefaultRenderer() - m.styles = NewStyles(m.lg) - - m.form = huh.NewForm( - huh.NewGroup( - huh.NewInput(). - Key("from"). - Title("From Address"). - Placeholder("cosmos1..."). - Validate(func(s string) error { - if !strings.HasPrefix(s, "cosmos1") { - return fmt.Errorf("invalid address format") - } - return nil - }), - - huh.NewInput(). - Key("to"). - Title("To Address"). - Placeholder("cosmos1..."). - Validate(func(s string) error { - if !strings.HasPrefix(s, "cosmos1") { - return fmt.Errorf("invalid address format") - } - return nil - }), - - huh.NewInput(). - Key("amount"). - Title("Amount"). - Placeholder("100"). - Validate(func(s string) error { - if _, err := sdk.ParseCoinNormalized(s + "atom"); err != nil { - return fmt.Errorf("invalid coin amount") - } - return nil - }), - - huh.NewSelect[string](). - Key("denom"). - Title("Denom"). - Options(huh.NewOptions("atom", "osmo", "usnr", "snr")...), - - huh.NewInput(). - Key("memo"). - Title("Memo"). - Placeholder("Optional"), - - huh.NewConfirm(). - Key("done"). - Title("Ready to convert?"). - Validate(func(v bool) error { - if !v { - return fmt.Errorf("Please confirm when you're ready to convert") - } - return nil - }). - Affirmative("Yes, convert!"). - Negative("Not yet"), - ), - ). - WithWidth(60). - WithShowHelp(false). - WithShowErrors(false) - - return m -} - -func (m Model) Init() tea.Cmd { - return m.form.Init() -} - -func min(x, y int) int { - if x > y { - return y - } - return x -} - -func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - switch msg := msg.(type) { - case tea.WindowSizeMsg: - m.width = min(msg.Width, maxWidth) - m.styles.Base.GetHorizontalFrameSize() - case tea.KeyMsg: - switch msg.String() { - case "esc", "ctrl+c", "q": - return m, tea.Quit - } - } - - var cmds []tea.Cmd - - form, cmd := m.form.Update(msg) - if f, ok := form.(*huh.Form); ok { - m.form = f - cmds = append(cmds, cmd) - } - - if m.form.State == huh.StateCompleted { - m.buildMessage() - cmds = append(cmds, tea.Quit) - } - - return m, tea.Batch(cmds...) -} - -func (m Model) View() string { - s := m.styles - - switch m.form.State { - case huh.StateCompleted: - pklCode := m.generatePkl() - messageView := m.getMessageView() - var b strings.Builder - fmt.Fprintf(&b, "Final Tx:\n\n%s\n\n%s", pklCode, messageView) - return s.Status.Margin(0, 1).Padding(1, 2).Width(80).Render(b.String()) + "\n\n" - default: - var schemaType string - if m.form.GetString("schemaType") != "" { - schemaType = "Schema Type: " + m.form.GetString("schemaType") - } - - v := strings.TrimSuffix(m.form.View(), "\n\n") - form := m.lg.NewStyle().Margin(1, 0).Render(v) - - var status string - { - preview := "(Preview will appear here)" - if m.form.GetString("schema") != "" { - preview = m.generatePkl() - } - - const statusWidth = 40 - statusMarginLeft := m.width - statusWidth - lipgloss.Width(form) - s.Status.GetMarginRight() - status = s.Status. - Height(lipgloss.Height(form)). - Width(statusWidth). - MarginLeft(statusMarginLeft). - Render(s.StatusHeader.Render("Pkl Preview") + "\n" + - schemaType + "\n\n" + - preview) - } - - errors := m.form.Errors() - header := m.appBoundaryView("Sonr TX Builder") - if len(errors) > 0 { - header = m.appErrorBoundaryView(m.errorView()) - } - body := lipgloss.JoinHorizontal(lipgloss.Top, form, status) - - footer := m.appBoundaryView(m.form.Help().ShortHelpView(m.form.KeyBinds())) - if len(errors) > 0 { - footer = m.appErrorBoundaryView("") - } - - return s.Base.Render(header + "\n" + body + "\n\n" + footer) - } -} - -func (m Model) errorView() string { - var s string - for _, err := range m.form.Errors() { - s += err.Error() - } - return s -} - -func (m Model) appBoundaryView(text string) string { - return lipgloss.PlaceHorizontal( - m.width, - lipgloss.Left, - m.styles.HeaderText.Render(text), - lipgloss.WithWhitespaceChars("="), - lipgloss.WithWhitespaceForeground(indigo), - ) -} - -func (m Model) appErrorBoundaryView(text string) string { - return lipgloss.PlaceHorizontal( - m.width, - lipgloss.Left, - m.styles.ErrorHeaderText.Render(text), - lipgloss.WithWhitespaceChars("="), - lipgloss.WithWhitespaceForeground(red), - ) -} - -func (m Model) generatePkl() string { - schemaType := m.form.GetString("schemaType") - schema := m.form.GetString("schema") - - // This is a placeholder for the actual conversion logic - // In a real implementation, you would parse the schema and generate Pkl code - return fmt.Sprintf("// Converted from %s\n\nclass ConvertedSchema {\n // TODO: Implement conversion from %s\n // Original schema:\n /*\n%s\n */\n}", schemaType, schemaType, schema) -} - -func (m *Model) buildMessage() { - from := m.form.GetString("from") - to := m.form.GetString("to") - amount := m.form.GetString("amount") - denom := m.form.GetString("denom") - memo := m.form.GetString("memo") - - coin, _ := sdk.ParseCoinNormalized(fmt.Sprintf("%s%s", amount, denom)) - sendMsg := &banktypes.MsgSend{ - FromAddress: from, - ToAddress: to, - Amount: sdk.NewCoins(coin), - } - - anyMsg, _ := codectypes.NewAnyWithValue(sendMsg) - m.message = &tx.TxBody{ - Messages: []*codectypes.Any{anyMsg}, - Memo: memo, - } -} - -func (m Model) getMessageView() string { - if m.message == nil { - return "Current Message: None" - } - - interfaceRegistry := codectypes.NewInterfaceRegistry() - marshaler := codec.NewProtoCodec(interfaceRegistry) - jsonBytes, _ := marshaler.MarshalJSON(m.message) - - return fmt.Sprintf("Current Message:\n%s", string(jsonBytes)) -} - -func RunBuildTxnTUI() (*tx.TxBody, error) { - m := NewModel() - p := tea.NewProgram(m) - - finalModel, err := p.Run() - if err != nil { - return nil, fmt.Errorf("failed to run program: %w", err) - } - - finalM, ok := finalModel.(Model) - if !ok || finalM.message == nil { - return nil, fmt.Errorf("form not completed") - } - - return finalM.message, nil -} diff --git a/cmd/sonrd/main.go b/cmd/sonrd/main.go index d3f50eab5..7080ac6d8 100644 --- a/cmd/sonrd/main.go +++ b/cmd/sonrd/main.go @@ -8,13 +8,10 @@ import ( _ "github.com/joho/godotenv/autoload" "github.com/onsonr/sonr/app" - "github.com/onsonr/sonr/app/cli" ) func main() { rootCmd := NewRootCmd() - rootCmd.AddCommand(cli.NewBuildTxnTUICmd()) - rootCmd.AddCommand(cli.NewExplorerTUICmd()) if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil { log.NewLogger(rootCmd.OutOrStderr()).Error("failure when running app", "err", err)