Hi, I started using senpai a long time ago and so far it is a very nice client. And so, I started adding some QOL improvements to it I would like to see upstream. Feedback welcome! Cheers. Ferass El Hafidi (7): irc: Show away status irc: show oper class commands: add some aliases app: show who changed the topic session: don't ignore rplHelpstart Show kick reason and sender session: remove "The user" part from whois app.go | 28 ++++++++++++++++++++- commands.go | 27 ++++++++++++++++++++ irc/events.go | 9 +++++++ irc/session.go | 67 +++++++++++++++++++++++++++++++------------------- 4 files changed, 105 insertions(+), 26 deletions(-) -- 2.45.1
Hi, Thanks for your patches :-) Applied partially. - irc: Show away status -> No because shown on every message to an AWAY user - irc: show oper class -> OK - commands: add some aliases -> No, I've added some basic ones to mirror Discord commands, but would like to stop there. Maybe in the future there will be some kind of command hook to let you create more - app: show who changed the topic -> Already applied - session: don't ignore rplHelpstart -> OK - Show kick reason and sender -> Keeping this for later - session: remove "The user" part from whois -> OK To git.sr.ht:~delthas/senpai ce85ab5..0588fd5 master -> master
Copy & paste the following snippet into your terminal to import this patchset into git:
curl -s https://lists.sr.ht/~delthas/senpai-dev/patches/52934/mbox | git am -3Learn more about email & git
From what I can tell this is mostly only used in /WHOIS and not sent when a user becomes "away". Signed-off-by: Ferass El Hafidi <vitali64pmemail@protonmail.com> --- irc/session.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/irc/session.go b/irc/session.go index b65aee8..801ce97 100644 --- a/irc/session.go +++ b/irc/session.go @@ -1466,7 +1466,14 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er case errMonlistisfull: // silence monlist full error, we don't care because we do it best-effort case rplAway: - // we display user away status, we don't care about automatic AWAY replies + var nick, text string + if err := msg.ParseParams(nil, &nick, &text); err != nil { + return nil, err + } + return InfoEvent{ + Prefix: "User", + Message: fmt.Sprintf("The user %s is away: %s", nick, text), + }, nil case rplYourhost, rplCreated: // useless conection messages case rplAdminme: -- 2.45.1
Signed-off-by: Ferass El Hafidi <vitali64pmemail@protonmail.com> --- irc/session.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/irc/session.go b/irc/session.go index 801ce97..5c4a16e 100644 --- a/irc/session.go +++ b/irc/session.go @@ -1654,13 +1654,13 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er Message: fmt.Sprintf("The user %s is connected through the server %s (%s)", nick, server, serverInfo), }, nil case rplWhoisoperator: - var nick string - if err := msg.ParseParams(nil, &nick); err != nil { + var nick, opertype string + if err := msg.ParseParams(nil, &nick, &opertype); err != nil { return nil, err } return InfoEvent{ Prefix: "User", - Message: fmt.Sprintf("The user %s is an operator of this server", nick), + Message: fmt.Sprintf("The user %s %s", nick, opertype), }, nil case rplWhowasuser: var nick, username, host, realname string -- 2.45.1
Signed-off-by: Ferass El Hafidi <vitali64pmemail@protonmail.com> --- commands.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/commands.go b/commands.go index 908a813..1113c35 100644 --- a/commands.go +++ b/commands.go @@ -257,6 +257,14 @@ func init() { Desc: "mark yourself as back from being away", Handle: commandDoBack, }, + "BANHAMMER": { + Desc: "send a banhammer to the current channel ▬▬▬▬▬▬▬▋ Ò╭╮Ó", + Handle: commandDoBanhammer, + }, + "COOL": { + Desc: "send a cool person to the current channel (⌐■_■)", + Handle: commandDoCool, + }, "SHRUG": { Desc: "send a shrug to the current channel ¯\\_(ツ)_/¯", Handle: commandDoShrug, @@ -265,6 +273,10 @@ func init() { Desc: "send a tableflip to the current channel (╯°□°)╯︵ ┻━┻", Handle: commandDoTableFlip, }, + "TABLEUNFLIP": { + Desc: "send a tableunflip to the current channel ┬─┬ノ(º_ºノ)", + Handle: commandDoTableUnflip, + }, "VERSION": { AllowHome: true, MaxArgs: 1, @@ -939,6 +951,16 @@ func commandSendMessage(app *App, target string, content string) error { return nil } +func commandDoBanhammer(app *App, args []string) (err error) { + _, buffer := app.win.CurrentBuffer() + return commandSendMessage(app, buffer, `▬▬▬▬▬▬▬▋ Ò╭╮Ó`) +} + +func commandDoCool(app *App, args []string) (err error) { + _, buffer := app.win.CurrentBuffer() + return commandSendMessage(app, buffer, `(⌐■_■)`) +} + func commandDoShrug(app *App, args []string) (err error) { _, buffer := app.win.CurrentBuffer() return commandSendMessage(app, buffer, `¯\_(ツ)_/¯`) @@ -949,6 +971,11 @@ func commandDoTableFlip(app *App, args []string) (err error) { return commandSendMessage(app, buffer, `(╯°□°)╯︵ ┻━┻`) } +func commandDoTableUnflip(app *App, args []string) (err error) { + _, buffer := app.win.CurrentBuffer() + return commandSendMessage(app, buffer, `┬─┬ノ(º_ºノ)`) +} + func (app *App) handleInput(buffer, content string) error { confirmed := content == app.lastConfirm app.lastConfirm = content -- 2.45.1
Signed-off-by: Ferass El Hafidi <vitali64pmemail@protonmail.com> --- app.go | 3 ++- irc/events.go | 1 + irc/session.go | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app.go b/app.go index c57d48b..72d2985 100644 --- a/app.go +++ b/app.go @@ -1361,7 +1361,8 @@ func (app *App) formatEvent(ev irc.Event) ui.Line { } case irc.TopicChangeEvent: topic := ui.IRCString(ev.Topic).String() - body := fmt.Sprintf("Topic changed to: %s", topic) + topic_sender := ui.IRCString(ev.User).String() + body := fmt.Sprintf("Topic set by %s to: %s", topic_sender, topic) return ui.Line{ At: ev.Time, Head: "--", diff --git a/irc/events.go b/irc/events.go index aaf3953..8b61367 100644 --- a/irc/events.go +++ b/irc/events.go @@ -65,6 +65,7 @@ type UserOfflineEvent struct { } type TopicChangeEvent struct { + User string Channel string Topic string Time time.Time diff --git a/irc/session.go b/irc/session.go index 5c4a16e..085c88e 100644 --- a/irc/session.go +++ b/irc/session.go @@ -1137,6 +1137,7 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er if playback { return TopicChangeEvent{ + User: msg.Prefix.Name, Channel: channel, Topic: topic, Time: msg.TimeOrNow(), @@ -1151,6 +1152,7 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er c.TopicTime = msg.TimeOrNow() s.channels[channelCf] = c return TopicChangeEvent{ + User: c.TopicWho.Name, Channel: c.Name, Topic: c.Topic, Time: msg.TimeOrNow(), -- 2.45.1
It isn't really a delimiter, it shows the command syntax of the command you need help in, like so: :irc.test 704 f_ wallops :/WALLOPS :<message> # <- rplHelpstart :irc.test 705 f_ wallops : :irc.test 705 f_ wallops :Sends a message to all +w users. :irc.test 705 f_ wallops : :irc.test 706 f_ wallops :End of /HELPOP. Signed-off-by: Ferass El Hafidi <vitali64pmemail@protonmail.com> --- irc/session.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/irc/session.go b/irc/session.go index 085c88e..184fa3f 100644 --- a/irc/session.go +++ b/irc/session.go @@ -1502,7 +1502,7 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er // useless whois delimiter case rplEndofinfo: // useless info delimiter - case rplHelpstart, rplEndofhelp: + case rplEndofhelp: // useless help delimiter case rplStatscommands: var command, count string @@ -1920,7 +1920,7 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er Prefix: "User", Message: fmt.Sprintf("The user %s %s", nick, text), }, nil - case rplHelptxt: + case rplHelpstart, rplHelptxt: var text string if err := msg.ParseParams(nil, nil, &text); err != nil { return nil, err -- 2.45.1
Signed-off-by: Ferass El Hafidi <vitali64pmemail@protonmail.com> --- app.go | 25 +++++++++++++++++++++++++ irc/events.go | 8 ++++++++ irc/session.go | 16 ++++++++++++---- 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/app.go b/app.go index 72d2985..ae7d642 100644 --- a/app.go +++ b/app.go @@ -923,6 +923,12 @@ func (app *App) handleIRCEvent(netID string, ev interface{}) { } line := app.formatEvent(ev) app.win.AddLine(netID, ev.Channel, line) + case irc.UserKickEvent: + if !app.cfg.StatusEnabled { + break + } + line := app.formatEvent(ev) + app.win.AddLine(netID, ev.Channel, line) case irc.UserQuitEvent: if !app.cfg.StatusEnabled { break @@ -1327,6 +1333,25 @@ func (app *App) formatEvent(ev irc.Event) ui.Line { Data: []irc.Event{ev}, Readable: true, } + case irc.UserKickEvent: + var body ui.StyledStringBuilder + body.Grow(len(ev.User) + 1) + body.SetStyle(tcell.StyleDefault.Foreground(app.cfg.Colors.Status)) + body.WriteString(ev.User) + body.WriteString(" got kicked by ") + body.WriteString(ev.Sender) + body.WriteString(" (") + body.WriteString(ev.Reason) + body.WriteString(")") + return ui.Line{ + At: ev.Time, + Head: "Kick --", + HeadColor: app.cfg.Colors.Status, + Body: body.StyledString(), + Mergeable: false, + Data: []irc.Event{ev}, + Readable: true, + } case irc.UserPartEvent: var body ui.StyledStringBuilder body.Grow(len(ev.User) + 1) diff --git a/irc/events.go b/irc/events.go index 8b61367..91624d2 100644 --- a/irc/events.go +++ b/irc/events.go @@ -50,6 +50,14 @@ type UserPartEvent struct { Time time.Time } +type UserKickEvent struct { + Sender string + User string + Channel string + Reason string + Time time.Time +} + type UserQuitEvent struct { User string Channels []string diff --git a/irc/session.go b/irc/session.go index 184fa3f..f17a5db 100644 --- a/irc/session.go +++ b/irc/session.go @@ -926,15 +926,21 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er } } case "KICK": - var channel, nick string - if err := msg.ParseParams(&channel, &nick); err != nil { + if msg.Prefix == nil { + return nil, errMissingPrefix + } + + var channel, nick, reason string + if err := msg.ParseParams(&channel, &nick, &reason); err != nil { return nil, err } if playback { - return UserPartEvent{ + return UserKickEvent{ + Sender: msg.Prefix.Name, User: nick, Channel: channel, + Reason: reason, Time: msg.TimeOrNow(), }, nil } @@ -957,9 +963,11 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er delete(c.Members, u) s.cleanUser(u) s.typings.Done(channelCf, nickCf) - return UserPartEvent{ + return UserKickEvent{ + Sender: msg.Prefix.Name, User: nick, Channel: c.Name, + Reason: reason, Time: msg.TimeOrNow(), }, nil } -- 2.45.1
Signed-off-by: Ferass El Hafidi <vitali64pmemail@protonmail.com> --- irc/session.go | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/irc/session.go b/irc/session.go index f17a5db..e45d77b 100644 --- a/irc/session.go +++ b/irc/session.go @@ -1482,7 +1482,7 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er } return InfoEvent{ Prefix: "User", - Message: fmt.Sprintf("The user %s is away: %s", nick, text), + Message: fmt.Sprintf("%s is away: %s", nick, text), }, nil case rplYourhost, rplCreated: // useless conection messages @@ -1626,7 +1626,7 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er } return InfoEvent{ Prefix: "User", - Message: fmt.Sprintf("The user %s %s", nick, text), + Message: fmt.Sprintf("%s %s", nick, text), }, nil case rplUnaway: return InfoEvent{ @@ -1643,7 +1643,7 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er } return InfoEvent{ Prefix: "User", - Message: fmt.Sprintf("The user %s has identified and is registered to the server", nick), + Message: fmt.Sprintf("%s has identified and is registered to the server", nick), }, nil case rplWhoisuser: var nick, username, host, realname string @@ -1652,7 +1652,7 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er } return InfoEvent{ Prefix: "User", - Message: fmt.Sprintf("The user %s has username %s and host %s (mask %s!%s@%s); their realname is %s", nick, username, host, nick, username, host, realname), + Message: fmt.Sprintf("%s has username %s and host %s (mask %s!%s@%s); their realname is %s", nick, username, host, nick, username, host, realname), }, nil case rplWhoisserver: var nick, server, serverInfo string @@ -1661,7 +1661,7 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er } return InfoEvent{ Prefix: "User", - Message: fmt.Sprintf("The user %s is connected through the server %s (%s)", nick, server, serverInfo), + Message: fmt.Sprintf("%s is connected through the server %s (%s)", nick, server, serverInfo), }, nil case rplWhoisoperator: var nick, opertype string @@ -1670,7 +1670,7 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er } return InfoEvent{ Prefix: "User", - Message: fmt.Sprintf("The user %s %s", nick, opertype), + Message: fmt.Sprintf("%s %s", nick, opertype), }, nil case rplWhowasuser: var nick, username, host, realname string @@ -1679,7 +1679,7 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er } return InfoEvent{ Prefix: "User", - Message: fmt.Sprintf("The user %s was last seen with username %s and host %s (mask %s!%s@%s); their realname was %s", nick, username, host, nick, username, host, realname), + Message: fmt.Sprintf("%s was last seen with username %s and host %s (mask %s!%s@%s); their realname was %s", nick, username, host, nick, username, host, realname), }, nil case rplWhoisidle: var nick, idleText, signonText string @@ -1696,7 +1696,7 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er } idle := (time.Duration(idleSeconds) * time.Second).String() t := time.Unix(signon, 0) - text := fmt.Sprintf("The user %s was idle for %s; they signed-on on %s", nick, idle, t.Local().Format("January 2 at 15:04")) + text := fmt.Sprintf("%s was idle for %s; they signed-on on %s", nick, idle, t.Local().Format("January 2 at 15:04")) return InfoEvent{ Prefix: "User", Message: text, @@ -1708,7 +1708,7 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er } return InfoEvent{ Prefix: "User", - Message: fmt.Sprintf("The user %s has joined channels: %s", nick, text), + Message: fmt.Sprintf("%s has joined channels: %s", nick, text), }, nil case rplWhoisspecial: var nick, text string @@ -1717,7 +1717,7 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er } return InfoEvent{ Prefix: "User", - Message: fmt.Sprintf("The user %s is also: %s", nick, text), + Message: fmt.Sprintf("%s is also: %s", nick, text), }, nil case rplList: var channel, count, topic string @@ -1763,12 +1763,12 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er if nick != account { return InfoEvent{ Prefix: "User", - Message: fmt.Sprintf("The user %s is authenticated as %s", nick, account), + Message: fmt.Sprintf("%s is authenticated as %s", nick, account), }, nil } else { return InfoEvent{ Prefix: "User", - Message: fmt.Sprintf("The user %s is authenticated", nick), + Message: fmt.Sprintf("%s is authenticated", nick), }, nil } case rplInvitelist, rplInvexlist: @@ -1799,7 +1799,7 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er } return InfoEvent{ Prefix: "User", - Message: fmt.Sprintf("The user %s %s", nick, text), + Message: fmt.Sprintf("%s %s", nick, text), }, nil } else if len(msg.Params) >= 4 { var nick string @@ -1808,7 +1808,7 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er } return InfoEvent{ Prefix: "User", - Message: fmt.Sprintf("The user %s is actually using the host %s", nick, msg.Params[len(msg.Params)-2]), + Message: fmt.Sprintf("%s is actually using the host %s", nick, msg.Params[len(msg.Params)-2]), }, nil } case rplExceptlist: @@ -1892,7 +1892,7 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er } return InfoEvent{ Prefix: "User", - Message: fmt.Sprintf("The user %s %s", nick, text), + Message: fmt.Sprintf("%s %s", nick, text), }, nil case rplWhoismodes: var nick, text string @@ -1901,7 +1901,7 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er } return InfoEvent{ Prefix: "User", - Message: fmt.Sprintf("The user %s %s", nick, text), + Message: fmt.Sprintf("%s %s", nick, text), }, nil case rplYoureoper: var text string @@ -1926,7 +1926,7 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er } return InfoEvent{ Prefix: "User", - Message: fmt.Sprintf("The user %s %s", nick, text), + Message: fmt.Sprintf("%s %s", nick, text), }, nil case rplHelpstart, rplHelptxt: var text string -- 2.45.1
delthas <delthas@dille.cc>Hi, Thanks for your patches :-) Applied partially. - irc: Show away status -> No because shown on every message to an AWAY user - irc: show oper class -> OK - commands: add some aliases -> No, I've added some basic ones to mirror Discord commands, but would like to stop there. Maybe in the future there will be some kind of command hook to let you create more - app: show who changed the topic -> Already applied - session: don't ignore rplHelpstart -> OK - Show kick reason and sender -> Keeping this for later - session: remove "The user" part from whois -> OK To git.sr.ht:~delthas/senpai ce85ab5..0588fd5 master -> master