From ff0e201e0273adbbaa54213c56f372a7ee11b5d1 Mon Sep 17 00:00:00 2001 From: IllusionMan1212 Date: Fri, 15 Aug 2025 21:34:04 +0200 Subject: [PATCH] feat: support sending and receiving direct messages from other users --- irc/handler/handler.go | 22 ++++++++++++---- irc/handler/slash.go | 57 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 73 insertions(+), 6 deletions(-) diff --git a/irc/handler/handler.go b/irc/handler/handler.go index 4b6f074..385f035 100644 --- a/irc/handler/handler.go +++ b/irc/handler/handler.go @@ -61,21 +61,33 @@ func handlePing(msg irc.Message, client *irc.Client) { } func handlePrivMsg(msg irc.Message, client *irc.Client) { - nick := strings.SplitN(msg.Source, "!", 2)[0] - channels := strings.Split(msg.Parameters[0], ",") + source := strings.ToLower(strings.SplitN(msg.Source, "!", 2)[0]) + targets := strings.Split(msg.Parameters[0], ",") msgContent := msg.Parameters[1] - privMsg := fmt.Sprintf("%s: %s", nick, msgContent) + privMsg := fmt.Sprintf("%s: %s", source, msgContent) msgOpts := irc.MsgFmtOpts{ WithTimestamp: true, } - for _, channel := range channels { +targetsLoop: + for _, target := range targets { for i, c := range client.Channels { - if c.Name == channel { + if c.Name == target || c.Name == source { client.Channels[i].AppendMsg(msg.Timestamp, privMsg, msgOpts) + continue targetsLoop } } + + if target == client.Nickname { + newChannel := irc.Channel{ + Name: source, + Users: map[string]irc.User{source: {}}, + } + + newChannel.AppendMsg(msg.Timestamp, privMsg, msgOpts) + client.Channels = append(client.Channels, newChannel) + } } } diff --git a/irc/handler/slash.go b/irc/handler/slash.go index 9a5073d..17ffc2f 100644 --- a/irc/handler/slash.go +++ b/irc/handler/slash.go @@ -17,7 +17,9 @@ package handler import ( + "fmt" "strings" + "time" tea "github.com/charmbracelet/bubbletea" "github.com/illusionman1212/gorc/cmds" @@ -25,10 +27,61 @@ import ( "github.com/illusionman1212/gorc/irc/commands" ) +func handleSlashPrivMsg(params []string, client *irc.Client) tea.Cmd { + var batchedCmds []tea.Cmd + + if len(params) < 2 { + client.SendCommand(commands.PRIVMSG, params...) + return nil + } + + target := strings.ToLower(params[0]) + + msgOpts := irc.MsgFmtOpts{ + WithTimestamp: true, + } + now := time.Now() + timestamp := fmt.Sprintf("[%02d:%02d]", now.Hour(), now.Minute()) + msg := fmt.Sprintf("%s: %s", client.Nickname, strings.Join(params[1:], " ")) + + for i, c := range client.Channels { + if c.Name == target { + client.ActiveChannelIndex = i + client.ActiveChannel = target + + client.Channels[i].AppendMsg(timestamp, msg, msgOpts) + + client.SendCommand(commands.PRIVMSG, params...) + return cmds.SwitchChannels + } + } + + // If we're messaging a user and their "channel" wasn't found in the previous loop, then create it and append it + if target[0] != '#' && target[0] != '&' { + newChannel := irc.Channel{ + Name: target, + Users: map[string]irc.User{target: {}}, + } + + newChannel.AppendMsg(timestamp, msg, msgOpts) + + client.ActiveChannelIndex = len(client.Channels) + client.ActiveChannel = target + + client.Channels = append(client.Channels, newChannel) + batchedCmds = append(batchedCmds, cmds.UpdateTabBar) + } + + client.SendCommand(commands.PRIVMSG, params...) + batchedCmds = append(batchedCmds, cmds.SwitchChannels) + + return tea.Batch(batchedCmds...) +} + func handleSlashJoin(params []string, client *irc.Client) tea.Cmd { channel := "" if len(params) > 0 { - channel = params[0] + channel = strings.ToLower(params[0]) } for i, c := range client.Channels { @@ -52,6 +105,8 @@ func HandleSlashCommand(msg string, client *irc.Client) tea.Cmd { } switch command { + case commands.PRIVMSG: + return handleSlashPrivMsg(params, client) case commands.JOIN: return handleSlashJoin(params, client) case commands.QUIT: