~delthas/senpai-dev

Various patches for senpai v1 APPLIED

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
Export patchset (mbox)
How do I use this?

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 -3
Learn more about email & git

[PATCH 1/7] irc: Show away status Export this patch

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

[PATCH 2/7] irc: show oper class Export this patch

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

[PATCH 3/7] commands: add some aliases Export this patch

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

[PATCH 4/7] app: show who changed the topic Export this patch

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

[PATCH 5/7] session: don't ignore rplHelpstart Export this patch

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

[PATCH 6/7] Show kick reason and sender Export this patch

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

[PATCH 7/7] session: remove "The user" part from whois Export this patch

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
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