diff --git a/cmd/tui/model.go b/cmd/tui/model.go index 37e5403..c705231 100644 --- a/cmd/tui/model.go +++ b/cmd/tui/model.go @@ -101,6 +101,7 @@ type Model struct { // User View showUserView bool viewUser *UserNode + pokeID uint16 // Target ID for pending poke } // addLog adds a message to the log panel @@ -588,6 +589,13 @@ func (m *Model) handleUserViewKeys(msg tea.KeyMsg) (tea.Model, tea.Cmd) { m.focus = FocusChannels m.showUserView = false + case "1": + // Initiate Poke: set target, clear input, and focus it + m.pokeID = u.ID + m.focus = FocusInput + m.inputText = "" + m.addLog("Write poke message for %s and press Enter...", u.Nickname) + case "2": // Toggle mute for this user _, muted := m.audioPlayer.GetUserSettings(u.ID) @@ -656,11 +664,27 @@ func (m *Model) handleInputKeys(msg tea.KeyMsg) (tea.Model, tea.Cmd) { switch msg.String() { case "enter": if m.inputText != "" && m.client != nil { - m.client.SendChannelMessage(m.inputText) + if m.pokeID != 0 { + err := m.client.Poke(m.pokeID, m.inputText) + if err != nil { + m.addLog("Error poking client %d: %v", m.pokeID, err) + } else { + m.addLog("Poke sent!") + } + m.pokeID = 0 + m.focus = FocusUserView + } else { + m.client.SendChannelMessage(m.inputText) + } m.inputText = "" } case "esc": - m.focus = FocusChannels + if m.pokeID != 0 { + m.pokeID = 0 + m.focus = FocusUserView + } else { + m.focus = FocusChannels + } m.inputText = "" case "backspace": if len(m.inputText) > 0 { @@ -794,7 +818,11 @@ func (m *Model) View() string { } // Input - inputContent := "> " + m.inputText + prompt := "> " + if m.pokeID != 0 { + prompt = "[Poke Message] > " + } + inputContent := prompt + m.inputText if m.focus == FocusInput { inputStyle = inputStyle.BorderForeground(lipgloss.Color("212")) inputContent += "█" @@ -1062,7 +1090,7 @@ func (m *Model) renderUserView() string { fmt.Sprintf("%s %s", labelStyle.Render("Local Mute:"), muteStr), "", "--- Menu ---", - "1. Poke (Not Impl)", + "1. Poke", "2. Toggle Local Mute", "+/-: Adjust Volume", "", diff --git a/pkg/ts3client/commands.go b/pkg/ts3client/commands.go index b2c74b6..b11500a 100644 --- a/pkg/ts3client/commands.go +++ b/pkg/ts3client/commands.go @@ -235,6 +235,19 @@ func (c *Client) KickFromServer(clientID uint16, reason string) error { return c.internal.SendCommand(cmd) } +// Poke sends a poke message to a specific client +func (c *Client) Poke(clientID uint16, message string) error { + if c.internal == nil { + return fmt.Errorf("not connected") + } + + cmd := protocol.NewCommand("clientpoke") + cmd.AddParam("clid", fmt.Sprintf("%d", clientID)) + cmd.AddParam("msg", message) + + return c.internal.SendCommand(cmd) +} + // ============================================================================= // Info Methods // =============================================================================