diff options
| author | Kyren223 <Kyren223@proton.me> | 2024-12-19 17:03:18 +0200 |
|---|---|---|
| committer | Kyren223 <Kyren223@proton.me> | 2024-12-19 17:03:18 +0200 |
| commit | ff032e5e0769cb33fa9075838b2cac3398e725f8 (patch) | |
| tree | 11c3b78c03539873474fb02aae59e3da49d35159 /internal/client/ui | |
| parent | f58c860d5549046f592790989df1c47bc9c2c1a1 (diff) | |
Implemented client-side message sending
Diffstat (limited to 'internal/client/ui')
| -rw-r--r-- | internal/client/ui/core/chat/chat.go | 57 | ||||
| -rw-r--r-- | internal/client/ui/core/core.go | 5 | ||||
| -rw-r--r-- | internal/client/ui/core/frequencylist/frequencylist.go | 6 | ||||
| -rw-r--r-- | internal/client/ui/viminput/viminput.go | 78 |
4 files changed, 124 insertions, 22 deletions
diff --git a/internal/client/ui/core/chat/chat.go b/internal/client/ui/core/chat/chat.go index 8600f46..c41c313 100644 --- a/internal/client/ui/core/chat/chat.go +++ b/internal/client/ui/core/chat/chat.go @@ -7,8 +7,12 @@ import ( tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" + "github.com/kyren223/eko/internal/client/gateway" "github.com/kyren223/eko/internal/client/ui/colors" + "github.com/kyren223/eko/internal/client/ui/core/state" "github.com/kyren223/eko/internal/client/ui/viminput" + "github.com/kyren223/eko/internal/packet" + "github.com/kyren223/eko/pkg/snowflake" ) var ( @@ -28,6 +32,10 @@ type Model struct { vi viminput.Model focus bool locked bool + + networkIndex int // Note this might be invalid, rely on frequencyIndex + receiverIndex *int + frequencyIndex *int } func New() Model { @@ -126,12 +134,17 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { } if m.locked { - InNormal := m.vi.Mode() == viminput.NormalMode - if key, ok := msg.(tea.KeyMsg); ok && InNormal { - if key.String() == "q" { + if key, ok := msg.(tea.KeyMsg); ok { + InNormal := m.vi.Mode() == viminput.NormalMode + if key.String() == "q" && InNormal { m.locked = false return m, nil } + + if key.Type == tea.KeyEnter { + cmd := m.sendMessage() + return m, cmd + } } var cmd tea.Cmd @@ -165,3 +178,41 @@ func (m *Model) Blur() { func (m Model) Locked() bool { return m.locked } + +func (m *Model) sendMessage() tea.Cmd { + message := m.vi.String() + if len(message) > MaxCharCount { + return nil + } + if len(strings.TrimSpace(message)) == 0 { + return nil + } + + m.vi.Reset() + + var receiverId *snowflake.ID = nil + if m.receiverIndex != nil { + // TODO: do nothing for now, until trusted friends are implemented + } + + var frequencyId *snowflake.ID = nil + if m.frequencyIndex != nil { + network := state.State.Networks[m.networkIndex] + frequencyId = &network.Frequencies[*m.frequencyIndex].ID + } + + return gateway.Send(&packet.SendMessage{ + ReceiverID: receiverId, + FrequencyID: frequencyId, + Content: message, + }) +} + +func (m *Model) SetNetworkIndex(networkIndex int) { + m.networkIndex = networkIndex +} + +func (m *Model) Set(receiverIndex, frequencyIndex *int) { + m.receiverIndex = receiverIndex + m.frequencyIndex = frequencyIndex +} diff --git a/internal/client/ui/core/core.go b/internal/client/ui/core/core.go index 5d87294..5115274 100644 --- a/internal/client/ui/core/core.go +++ b/internal/client/ui/core/core.go @@ -288,9 +288,12 @@ func (m *Model) updateConnected(msg tea.Msg) tea.Cmd { switch m.focus { case FocusNetworkList: m.networkList, cmd = m.networkList.Update(msg) - m.frequencyList.Set(m.networkList.Index()) + m.frequencyList.SetNetworkIndex(m.networkList.Index()) + m.chat.SetNetworkIndex(m.networkList.Index()) case FocusFrequencyList: m.frequencyList, cmd = m.frequencyList.Update(msg) + index := m.frequencyList.Index() + m.chat.Set(nil, &index) case FocusChat: m.chat, cmd = m.chat.Update(msg) } diff --git a/internal/client/ui/core/frequencylist/frequencylist.go b/internal/client/ui/core/frequencylist/frequencylist.go index 3b7f800..c00b8cd 100644 --- a/internal/client/ui/core/frequencylist/frequencylist.go +++ b/internal/client/ui/core/frequencylist/frequencylist.go @@ -148,7 +148,7 @@ func (m Model) Swap(dir int) (Model, tea.Cmd) { return m, cmd } -func (m *Model) Set(index int) { +func (m *Model) SetNetworkIndex(index int) { m.networkIndex = index } @@ -162,3 +162,7 @@ func (m Model) Network() *packet.FullNetwork { } return &state.State.Networks[m.networkIndex] } + +func (m *Model) Index() int { + return m.index +} diff --git a/internal/client/ui/viminput/viminput.go b/internal/client/ui/viminput/viminput.go index 5bc2314..4e2a079 100644 --- a/internal/client/ui/viminput/viminput.go +++ b/internal/client/ui/viminput/viminput.go @@ -504,6 +504,10 @@ func (m *Model) handleNormalModeKeys(key tea.KeyMsg) { case "p": paste := m.Paste() + if paste == "" { + return + } + newline := paste[len(paste)-1] == '\n' if newline { paste = paste[:len(paste)-1] @@ -561,6 +565,10 @@ func (m *Model) handleNormalModeKeys(key tea.KeyMsg) { } case "P": paste := m.Paste() + if paste == "" { + return + } + newline := paste[len(paste)-1] == '\n' if newline { paste = paste[:len(paste)-1] @@ -626,20 +634,27 @@ func (m *Model) handleInsertModeKeys(key tea.KeyMsg) { return } - if key.Type == tea.KeyEnter { - line := m.lines[m.cursorLine] - after := line[m.cursorColumn:] - m.lines[m.cursorLine] = line[:m.cursorColumn] - - var newline []rune - newline = append(newline, after...) - m.lines = slices.Insert(m.lines, m.cursorLine+1, newline) - - m.SetCursorLine(m.cursorLine + 1) - m.SetCursorColumn(0) + // Note: commented out because enter is used to send a message + // even in insert mode, an alternative that discord uses is + // to use Shift+Enter for this functionality but unfortunately + // this is not supported in bubbletea (probably due to terminal limitations) + // If there is a way to add this for Shift+Enter please notify me + // at Kyren223@proton.me - return - } + // if key.Type == tea.KeyEnter { + // line := m.lines[m.cursorLine] + // after := line[m.cursorColumn:] + // m.lines[m.cursorLine] = line[:m.cursorColumn] + // + // var newline []rune + // newline = append(newline, after...) + // m.lines = slices.Insert(m.lines, m.cursorLine+1, newline) + // + // m.SetCursorLine(m.cursorLine + 1) + // m.SetCursorColumn(0) + // + // return + // } keyStr := key.String() length := len(keyStr) @@ -1759,13 +1774,13 @@ func (m *Model) handleVisualModeKeys(key tea.KeyMsg) { } if motion == "p" || motion == "P" { - copyPaste := m.Paste() + copyOfPaste := m.Paste() m.Yank(paste) key.Runes[0] = 'P' // In visual it should always use backwards P m.handleNormalModeKeys(key) if motion == "p" { - m.Yank(copyPaste) // Restore + m.Yank(copyOfPaste) // Restore } // Note: we don't restore for "P" because we use it like // <leader>p (we paste over and keep what we had) @@ -1872,14 +1887,14 @@ func (m *Model) handleVisualLineModeKeys(key tea.KeyMsg) { m.SetCursorColumn(0) } - copyPaste := m.Paste() + copyOfPaste := m.Paste() m.Yank(paste) key.Runes[0] = 'p' // In visual line it should always use forward p // This is bcz we are pasting on a blank line m.handleNormalModeKeys(key) if motion == "p" { - m.Yank(copyPaste) // Restore + m.Yank(copyOfPaste) // Restore } // Note: we don't restore for "P" because we use it like // <leader>p (we paste over and keep what we had) @@ -1994,3 +2009,32 @@ func (m *Model) Count() int { } return sum + len(m.lines) - 1 } + +func (m *Model) String() string { + var builder strings.Builder + for _, line := range m.lines { + builder.WriteString(string(line)) + builder.WriteByte('\n') + } + message := builder.String() + message = message[:len(message)-1] // strip last \n + return message +} + +func (m *Model) Reset() { + m.lines = [][]rune{[]rune("")} + m.undoStack = []State{{[][]rune{[]rune("")}, 0, 0}} + m.redoStack = []State{} + m.cursorLine = 0 + m.cursorColumn = 0 + m.goalColumn = InvalidGoal + m.count = NoCount + m.pending = NullChar + m.gmod = false + m.fchar = NullChar + m.fmod = NullChar + m.tlast = false + m.imod = false + m.amod = false + m.offset = 0 +} |
