From 54564f397db03e7e10db764947dd05b533e0d87b Mon Sep 17 00:00:00 2001 From: Kyren223 Date: Sun, 24 Nov 2024 00:16:23 +0200 Subject: Started working on netwrok creation popup --- internal/client/ui/auth/auth.go | 4 +- internal/client/ui/auth/field/field.go | 148 --------------------- internal/client/ui/core/core.go | 42 +++++- .../ui/core/networkcreation/networkcreation.go | 81 +++++++++++ internal/client/ui/core/networks/networks.go | 91 +++++++++++++ internal/client/ui/field/field.go | 148 +++++++++++++++++++++ internal/client/ui/networks/networks.go | 91 ------------- internal/server/api/api.go | 2 +- 8 files changed, 357 insertions(+), 250 deletions(-) delete mode 100644 internal/client/ui/auth/field/field.go create mode 100644 internal/client/ui/core/networkcreation/networkcreation.go create mode 100644 internal/client/ui/core/networks/networks.go create mode 100644 internal/client/ui/field/field.go delete mode 100644 internal/client/ui/networks/networks.go (limited to 'internal') diff --git a/internal/client/ui/auth/auth.go b/internal/client/ui/auth/auth.go index 2656b76..903bb2a 100644 --- a/internal/client/ui/auth/auth.go +++ b/internal/client/ui/auth/auth.go @@ -18,7 +18,7 @@ import ( "github.com/kyren223/eko/internal/client/config" "github.com/kyren223/eko/internal/client/ui" - authfield "github.com/kyren223/eko/internal/client/ui/auth/field" + authfield "github.com/kyren223/eko/internal/client/ui/field" "github.com/kyren223/eko/internal/client/ui/choicepopup" "github.com/kyren223/eko/internal/client/ui/core" "github.com/kyren223/eko/pkg/assert" @@ -471,7 +471,6 @@ func (m *Model) Signup() tea.Cmd { return nil } - return ui.Transition(core.New(privKey, username)) } @@ -577,4 +576,3 @@ func expandPath(path string) string { } return path } - diff --git a/internal/client/ui/auth/field/field.go b/internal/client/ui/auth/field/field.go deleted file mode 100644 index dca4203..0000000 --- a/internal/client/ui/auth/field/field.go +++ /dev/null @@ -1,148 +0,0 @@ -package field - -import ( - "github.com/charmbracelet/bubbles/textinput" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" - - "github.com/kyren223/eko/internal/client/ui" -) - -type Model struct { - Input textinput.Model - Header string - Visisble bool - width int - - reveal bool - revealIcon string - concealIcon string - icon string - - FocusedStyle lipgloss.Style - BlurredStyle lipgloss.Style - FocusedTextStyle lipgloss.Style - BlurredTextStyle lipgloss.Style - ErrorStyle lipgloss.Style - HeaderStyle lipgloss.Style -} - -func New(width int) Model { - input := textinput.New() - input.Prompt = "" - input.Width = width - - m := Model{ - width: width, - Visisble: true, - Input: input, - } - - m.Blur() - m.SetRevealed(true) - - return m -} - -func (m Model) Init() tea.Cmd { - return nil -} - -func (m Model) View() string { - if !m.Visisble { - return "" - } - - - style := m.BlurredStyle - if m.Input.Focused() { - style = m.FocusedStyle - } - - header := m.HeaderStyle.Render(m.Header) - if m.Input.Err != nil { - error := m.Input.Err.Error() - style = style.BorderForeground(m.ErrorStyle.GetForeground()) - header = lipgloss.NewStyle(). - MaxWidth(m.width). - Render(header + m.ErrorStyle.Render(" - "+error)) - } - - field := ui.AddBorderHeader(header, 1, style, m.Input.View()+m.icon) - return field -} - -func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { - if !m.Visisble { - return m, nil - } - - var cmd tea.Cmd - m.Input, cmd = m.Input.Update(msg) - return m, cmd -} - -func (m *Model) Focus() tea.Cmd { - m.Input.PromptStyle = m.FocusedTextStyle - m.Input.TextStyle = m.FocusedTextStyle - return m.Input.Focus() -} - -func (m *Model) Blur() { - m.Input.Blur() - m.Input.PromptStyle = m.BlurredTextStyle - m.Input.TextStyle = m.BlurredTextStyle -} - -func (m *Model) SetWidth(width int) { - m.width = width - m.recalculateWidth() -} - -func (m Model) Width() int { - return m.width -} - -func (m *Model) SetRevealed(revealed bool) { - m.reveal = revealed - if m.reveal { - m.Input.EchoMode = textinput.EchoNormal - m.icon = m.revealIcon - } else { - m.Input.EchoMode = textinput.EchoPassword - m.icon = m.concealIcon - } - m.recalculateWidth() -} - -func (m Model) Revealed() bool { - return m.reveal -} - -func (m *Model) SetRevealIcon(icon string) { - m.revealIcon = icon - if m.reveal { - m.icon = icon - } - m.recalculateWidth() -} - -func (m Model) RevealIcon() string { - return m.revealIcon -} - -func (m *Model) SetConcealIcon(icon string) { - m.concealIcon = icon - if !m.reveal { - m.icon = icon - } - m.recalculateWidth() -} - -func (m Model) ConcealIcon() string { - return m.concealIcon -} - -func (m *Model) recalculateWidth() { - m.Input.Width = m.width - lipgloss.Width(m.icon) -} diff --git a/internal/client/ui/core/core.go b/internal/client/ui/core/core.go index bbc8576..5fb8e7b 100644 --- a/internal/client/ui/core/core.go +++ b/internal/client/ui/core/core.go @@ -8,10 +8,12 @@ import ( "github.com/charmbracelet/bubbles/spinner" "github.com/charmbracelet/bubbles/timer" tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" "github.com/kyren223/eko/internal/client/gateway" "github.com/kyren223/eko/internal/client/ui" + "github.com/kyren223/eko/internal/client/ui/core/networkcreation" + "github.com/kyren223/eko/internal/client/ui/core/networks" "github.com/kyren223/eko/internal/client/ui/loadscreen" - "github.com/kyren223/eko/internal/client/ui/networks" "github.com/kyren223/eko/pkg/snowflake" ) @@ -27,25 +29,26 @@ type Model struct { name string privKey ed25519.PrivateKey + networks networks.Model loading loadscreen.Model - timeout time.Duration timer timer.Model + timeout time.Duration connected bool id snowflake.ID - networks networks.Model + networkCreationPopup *networkcreation.Model } func New(privKey ed25519.PrivateKey, name string) Model { return Model{ name: name, privKey: privKey, + networks: networks.New(), loading: loadscreen.New(connectingToServer), - timeout: initialTimeout, timer: newTimer(initialTimeout), + timeout: initialTimeout, connected: false, - networks: networks.New(), } } @@ -58,7 +61,22 @@ func (m Model) View() string { return m.loading.View() } - return m.networks.View() + result := m.networks.View() + + result = lipgloss.Place( + ui.Width, ui.Height, + lipgloss.Left, lipgloss.Top, + result, + ) + + if m.networkCreationPopup != nil { + popup := m.networkCreationPopup.View() + x := (ui.Width - lipgloss.Width(popup)) / 2 + y := (ui.Height - lipgloss.Height(popup)) / 2 + result = ui.PlaceOverlay(x, y, popup, result) + } + + return result } func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { @@ -101,7 +119,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { } } - switch msg.(type) { + switch msg := msg.(type) { case gateway.ConnectionLost: m.connected = false m.timeout = initialTimeout @@ -109,6 +127,16 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case ui.QuitMsg: gateway.Disconnect() + + case tea.KeyMsg: + key := msg.Type + switch key { + case tea.KeyCtrlN: + if m.networkCreationPopup == nil { + popup := networkcreation.New() + m.networkCreationPopup = &popup + } + } } return m, nil diff --git a/internal/client/ui/core/networkcreation/networkcreation.go b/internal/client/ui/core/networkcreation/networkcreation.go new file mode 100644 index 0000000..d41c734 --- /dev/null +++ b/internal/client/ui/core/networkcreation/networkcreation.go @@ -0,0 +1,81 @@ +package networkcreation + +import ( + "github.com/charmbracelet/bubbles/textinput" + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" + "github.com/kyren223/eko/internal/client/ui/field" +) + +var ( + style = lipgloss.NewStyle().Border(lipgloss.ThickBorder()) + + focusedStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#5874FF")) + + fieldBlurredStyle = lipgloss.NewStyle(). + PaddingLeft(1). + Border(lipgloss.RoundedBorder()). + BorderForeground(lipgloss.Color("#007E8A")) + fieldFocusedStyle = fieldBlurredStyle.BorderForeground(focusedStyle.GetForeground()).Border(lipgloss.ThickBorder()) + + headerStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#54D7A9")) + + iconStyle = lipgloss.NewStyle().Border(lipgloss.ThickBorder(), false, false, true, false) +) + +type Model struct { + Width int + Height int + + name field.Model + icon textinput.Model + color textinput.Model + + Style lipgloss.Style +} + +func New() Model { + name := field.New(30) + name.Header = "Network Name" + name.HeaderStyle = headerStyle + name.FocusedStyle = fieldFocusedStyle + name.BlurredStyle = fieldBlurredStyle + name.Focus() + + icon := textinput.New() + icon.Prompt = "" + icon.Placeholder = "ic" + + color := textinput.New() + color.Prompt = "" + color.Placeholder = "000000" + + return Model{ + Width: 50, + Height: 10, + name: name, + icon: icon, + color: color, + Style: style, + } +} + +func (m Model) Init() tea.Cmd { + return nil +} + +func (m Model) View() string { + name := m.name.View() + + iconText := lipgloss.JoinHorizontal(lipgloss.Top, "icon: ", iconStyle.Render(m.icon.View())) + iconColor := lipgloss.JoinHorizontal(lipgloss.Top, "# ", iconStyle.Render(m.color.View())) + icon := lipgloss.JoinHorizontal(lipgloss.Top, iconText, " ", iconColor) + + content := lipgloss.JoinVertical(lipgloss.Left, name, "\n", icon) + popup := lipgloss.NewStyle().Width(m.Width).Height(m.Height).Render(content) + return m.Style.Render(popup) +} + +func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + return m, nil +} diff --git a/internal/client/ui/core/networks/networks.go b/internal/client/ui/core/networks/networks.go new file mode 100644 index 0000000..05f8b27 --- /dev/null +++ b/internal/client/ui/core/networks/networks.go @@ -0,0 +1,91 @@ +package networks + +import ( + "strings" + + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" + "github.com/kyren223/eko/internal/client/ui" + "github.com/kyren223/eko/internal/data" +) + +var ( + style = lipgloss.NewStyle().Border(lipgloss.ThickBorder(), true, false) + networkStyle = lipgloss.NewStyle().Width(6).Height(3).PaddingTop(1).Margin(0, 1, 1). + Align(lipgloss.Center). + Foreground(lipgloss.Color("#ffbf00")).Background(lipgloss.Color("#4a3d5c")). + Border(lipgloss.ThickBorder(), false, false) + networks = []string{ + "󰜈 ", + " ", + "Kr", + " ", + // "Test", + // "██████\n██████\n██████", + // " ▄▄▄▄ \n █ █ \n ▀▀▀▀ ", + // " \n 󰜈 \n ", + // "Hmm", + // "Another", + } + + reverse = lipgloss.NewStyle().Foreground(lipgloss.Color("#20999D")) + // Render("") + + label1 = lipgloss.NewStyle(). + Background(lipgloss.Color("#20999D")).Foreground(lipgloss.Color("#000000")). + Padding(0, 1). + Bold(true). + Render("󰜈") + label2 = reverse.Render("") + label1 + reverse.Render("") + label3 = "" + label4 = lipgloss.NewStyle(). + Foreground(lipgloss.Color("#20999D")). + Bold(true). + Render("󰜈") + + name = lipgloss.NewStyle(). + Bold(true). + Render("Kyren223") + user = lipgloss.JoinHorizontal(lipgloss.Center, label4, " ", name) +) + +type Model struct { + networks []string + a data.Network +} + +func New() Model { + return Model{ + networks: networks, + } +} + +func (m Model) Init() tea.Cmd { + return nil +} + +func (m Model) View() string { + // border := lipgloss.ThickBorder() + var builder strings.Builder + + // top := strings.Repeat(border.Top, 6) + // builder.WriteString(fmt.Sprintf("%s%s%s\n", border.TopLeft, top, border.TopRight)) + builder.WriteString("\n") + for _, network := range m.networks { + builder.WriteString(networkStyle.Render(network) + "\n") + + } + // bottom := strings.Repeat(border.Bottom, 6) + // builder.WriteString(fmt.Sprintf("\n%s%s%s", border.BottomLeft, bottom, border.BottomRight)) + + result := builder.String() + + sep := lipgloss.NewStyle().Border(lipgloss.ThickBorder(), false, true, false, false).Height(ui.Height).Width(0) + result = lipgloss.JoinHorizontal(lipgloss.Top, result, sep.Render("")) + + return result + user +} + +func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { + return m, nil +} diff --git a/internal/client/ui/field/field.go b/internal/client/ui/field/field.go new file mode 100644 index 0000000..dca4203 --- /dev/null +++ b/internal/client/ui/field/field.go @@ -0,0 +1,148 @@ +package field + +import ( + "github.com/charmbracelet/bubbles/textinput" + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" + + "github.com/kyren223/eko/internal/client/ui" +) + +type Model struct { + Input textinput.Model + Header string + Visisble bool + width int + + reveal bool + revealIcon string + concealIcon string + icon string + + FocusedStyle lipgloss.Style + BlurredStyle lipgloss.Style + FocusedTextStyle lipgloss.Style + BlurredTextStyle lipgloss.Style + ErrorStyle lipgloss.Style + HeaderStyle lipgloss.Style +} + +func New(width int) Model { + input := textinput.New() + input.Prompt = "" + input.Width = width + + m := Model{ + width: width, + Visisble: true, + Input: input, + } + + m.Blur() + m.SetRevealed(true) + + return m +} + +func (m Model) Init() tea.Cmd { + return nil +} + +func (m Model) View() string { + if !m.Visisble { + return "" + } + + + style := m.BlurredStyle + if m.Input.Focused() { + style = m.FocusedStyle + } + + header := m.HeaderStyle.Render(m.Header) + if m.Input.Err != nil { + error := m.Input.Err.Error() + style = style.BorderForeground(m.ErrorStyle.GetForeground()) + header = lipgloss.NewStyle(). + MaxWidth(m.width). + Render(header + m.ErrorStyle.Render(" - "+error)) + } + + field := ui.AddBorderHeader(header, 1, style, m.Input.View()+m.icon) + return field +} + +func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { + if !m.Visisble { + return m, nil + } + + var cmd tea.Cmd + m.Input, cmd = m.Input.Update(msg) + return m, cmd +} + +func (m *Model) Focus() tea.Cmd { + m.Input.PromptStyle = m.FocusedTextStyle + m.Input.TextStyle = m.FocusedTextStyle + return m.Input.Focus() +} + +func (m *Model) Blur() { + m.Input.Blur() + m.Input.PromptStyle = m.BlurredTextStyle + m.Input.TextStyle = m.BlurredTextStyle +} + +func (m *Model) SetWidth(width int) { + m.width = width + m.recalculateWidth() +} + +func (m Model) Width() int { + return m.width +} + +func (m *Model) SetRevealed(revealed bool) { + m.reveal = revealed + if m.reveal { + m.Input.EchoMode = textinput.EchoNormal + m.icon = m.revealIcon + } else { + m.Input.EchoMode = textinput.EchoPassword + m.icon = m.concealIcon + } + m.recalculateWidth() +} + +func (m Model) Revealed() bool { + return m.reveal +} + +func (m *Model) SetRevealIcon(icon string) { + m.revealIcon = icon + if m.reveal { + m.icon = icon + } + m.recalculateWidth() +} + +func (m Model) RevealIcon() string { + return m.revealIcon +} + +func (m *Model) SetConcealIcon(icon string) { + m.concealIcon = icon + if !m.reveal { + m.icon = icon + } + m.recalculateWidth() +} + +func (m Model) ConcealIcon() string { + return m.concealIcon +} + +func (m *Model) recalculateWidth() { + m.Input.Width = m.width - lipgloss.Width(m.icon) +} diff --git a/internal/client/ui/networks/networks.go b/internal/client/ui/networks/networks.go deleted file mode 100644 index 05f8b27..0000000 --- a/internal/client/ui/networks/networks.go +++ /dev/null @@ -1,91 +0,0 @@ -package networks - -import ( - "strings" - - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" - "github.com/kyren223/eko/internal/client/ui" - "github.com/kyren223/eko/internal/data" -) - -var ( - style = lipgloss.NewStyle().Border(lipgloss.ThickBorder(), true, false) - networkStyle = lipgloss.NewStyle().Width(6).Height(3).PaddingTop(1).Margin(0, 1, 1). - Align(lipgloss.Center). - Foreground(lipgloss.Color("#ffbf00")).Background(lipgloss.Color("#4a3d5c")). - Border(lipgloss.ThickBorder(), false, false) - networks = []string{ - "󰜈 ", - " ", - "Kr", - " ", - // "Test", - // "██████\n██████\n██████", - // " ▄▄▄▄ \n █ █ \n ▀▀▀▀ ", - // " \n 󰜈 \n ", - // "Hmm", - // "Another", - } - - reverse = lipgloss.NewStyle().Foreground(lipgloss.Color("#20999D")) - // Render("") - - label1 = lipgloss.NewStyle(). - Background(lipgloss.Color("#20999D")).Foreground(lipgloss.Color("#000000")). - Padding(0, 1). - Bold(true). - Render("󰜈") - label2 = reverse.Render("") + label1 + reverse.Render("") - label3 = "" - label4 = lipgloss.NewStyle(). - Foreground(lipgloss.Color("#20999D")). - Bold(true). - Render("󰜈") - - name = lipgloss.NewStyle(). - Bold(true). - Render("Kyren223") - user = lipgloss.JoinHorizontal(lipgloss.Center, label4, " ", name) -) - -type Model struct { - networks []string - a data.Network -} - -func New() Model { - return Model{ - networks: networks, - } -} - -func (m Model) Init() tea.Cmd { - return nil -} - -func (m Model) View() string { - // border := lipgloss.ThickBorder() - var builder strings.Builder - - // top := strings.Repeat(border.Top, 6) - // builder.WriteString(fmt.Sprintf("%s%s%s\n", border.TopLeft, top, border.TopRight)) - builder.WriteString("\n") - for _, network := range m.networks { - builder.WriteString(networkStyle.Render(network) + "\n") - - } - // bottom := strings.Repeat(border.Bottom, 6) - // builder.WriteString(fmt.Sprintf("\n%s%s%s", border.BottomLeft, bottom, border.BottomRight)) - - result := builder.String() - - sep := lipgloss.NewStyle().Border(lipgloss.ThickBorder(), false, true, false, false).Height(ui.Height).Width(0) - result = lipgloss.JoinHorizontal(lipgloss.Top, result, sep.Render("")) - - return result + user -} - -func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { - return m, nil -} diff --git a/internal/server/api/api.go b/internal/server/api/api.go index f932fbb..1dc74d2 100644 --- a/internal/server/api/api.go +++ b/internal/server/api/api.go @@ -48,7 +48,7 @@ func SendMessage(ctx context.Context, request *packet.SendMessage) packet.Payloa func GetMessages(ctx context.Context, request *packet.GetMessagesRange) packet.Payload { queries := data.New(db) - messages, err := queries.ListMessages(ctx) + messages, err := queries.GetFrequencyMessages(ctx, request.FrequencyID) if err != nil { log.Println("database error when retrieving messages:", err) return &packet.ErrorMessage{Error: "internal server error"} -- cgit v1.3.1