Skip to content

Commit

Permalink
Ensure prefixcontext/suffixcontent shown for all lines in a multi-lin…
Browse files Browse the repository at this point in the history
…e message (#483)

* Ensure prefixcontext/suffixcontent shown for all lines in a multi-line message

* Make showing context for multi-line messages configurable

* Fix to handle empty lines now that we're splitting elsewhere

* Restore changes to MsgSpoofUser() and Spoof() per review

* Allow overriding max. line length

* Fix to correctly add message thread context

* Refactor and remove duplicate code per review
  • Loading branch information
hloeung authored Nov 1, 2022
1 parent 89525b9 commit db8eb23
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 107 deletions.
9 changes: 0 additions & 9 deletions bridge/mattermost/mattermost.go
Original file line number Diff line number Diff line change
Expand Up @@ -844,16 +844,7 @@ func (m *Mattermost) handleWsActionPost(rmsg *model.WebSocketEvent) {
dmchannel = name
}

codeBlock := false
for _, msg := range msgs {
if msg == "```" {
codeBlock = !codeBlock
}
// skip empty lines for anything not part of a code block.
if !codeBlock && msg == "" {
continue
}

switch {
// DirectMessage
case channelType == "D":
Expand Down
9 changes: 0 additions & 9 deletions bridge/mattermost6/mattermost.go
Original file line number Diff line number Diff line change
Expand Up @@ -854,16 +854,7 @@ func (m *Mattermost) handleWsActionPost(rmsg *model.WebSocketEvent) {
dmchannel = name
}

codeBlock := false
for _, msg := range msgs {
if strings.HasPrefix(msg, "```") || strings.Contains(msg, "\n```") {
codeBlock = !codeBlock
}
// skip empty lines for anything not part of a code block.
if !codeBlock {
msg = strings.ReplaceAll(msg, "\n\n", "\n")
}

switch {
// DirectMessage
case channelType == "D":
Expand Down
2 changes: 2 additions & 0 deletions matterircd.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ SuffixContext = false
#ThreadContext = "mattermost"
# Similar to the above, but also show the message post IDs in addition to the parent thread ID.
#ThreadContext = "mattermost+post"
#Show Context for multi-line messages and only show it at the end.
ShowContextMulti = false

#This will show (mention yournick) after a message if it contains one of the words configured
#in your mattermost "word that trigger mentions" notifications.
Expand Down
28 changes: 20 additions & 8 deletions mm-go-irckit/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ type Channel interface {
String() string

// Spoof message
SpoofMessage(from string, text string)
SpoofMessage(from string, text string, maxlen ...int)

// Spoof notice
SpoofNotice(from string, text string)
SpoofNotice(from string, text string, maxlen ...int)

IsPrivate() bool
}
Expand Down Expand Up @@ -440,8 +440,12 @@ func (ch *channel) Len() int {
return len(ch.usersIdx)
}

func (ch *channel) Spoof(from string, text string, cmd string) {
text = wordwrap.String(text, 440)
func (ch *channel) Spoof(from string, text string, cmd string, maxlen ...int) {
if len(maxlen) == 0 {
text = wordwrap.String(text, 440)
} else {
text = wordwrap.String(text, maxlen[0])
}
lines := strings.Split(text, "\n")
for _, l := range lines {
msg := &irc.Message{
Expand All @@ -461,12 +465,20 @@ func (ch *channel) Spoof(from string, text string, cmd string) {
}
}

func (ch *channel) SpoofMessage(from string, text string) {
ch.Spoof(from, text, irc.PRIVMSG)
func (ch *channel) SpoofMessage(from string, text string, maxlen ...int) {
if len(maxlen) == 0 {
ch.Spoof(from, text, irc.PRIVMSG, 440)
} else {
ch.Spoof(from, text, irc.PRIVMSG, maxlen[0])
}
}

func (ch *channel) SpoofNotice(from string, text string) {
ch.Spoof(from, text, irc.NOTICE)
func (ch *channel) SpoofNotice(from string, text string, maxlen ...int) {
if len(maxlen) == 0 {
ch.Spoof(from, text, irc.NOTICE, 440)
} else {
ch.Spoof(from, text, irc.NOTICE, maxlen[0])
}
}

func (ch *channel) IsPrivate() bool {
Expand Down
22 changes: 2 additions & 20 deletions mm-go-irckit/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ func scrollback(u *User, toUser *User, args []string, service string) {
}

var channelID string
var spoof func(string, string)
var spoof func(string, string, ...int)
scrollbackUser, exists := u.Srv.HasUser(args[0])

switch {
Expand Down Expand Up @@ -383,16 +383,7 @@ func scrollback(u *User, toUser *User, args []string, service string) {
nick = "system"
}

codeBlock := false
for _, post := range strings.Split(p.Message, "\n") {
if post == "```" {
codeBlock = !codeBlock
}
// skip empty lines for anything not part of a code block.
if !codeBlock && post == "" {
continue
}

switch { // nolint:dupl
case (u.v.GetString(u.br.Protocol()+".threadcontext") == "mattermost" || u.v.GetString(u.br.Protocol()+".threadcontext") == "mattermost+post") && strings.HasPrefix(args[0], "#") && nick != "system":
threadMsgID := u.prefixContext("", p.Id, p.ParentId, "")
Expand Down Expand Up @@ -458,7 +449,7 @@ func scrollback6(u *User, toUser *User, args []string, service string) {
}

var channelID string
var spoof func(string, string)
var spoof func(string, string, ...int)
scrollbackUser, exists := u.Srv.HasUser(args[0])

switch {
Expand Down Expand Up @@ -503,16 +494,7 @@ func scrollback6(u *User, toUser *User, args []string, service string) {
nick = "system"
}

codeBlock := false
for _, post := range strings.Split(p.Message, "\n") {
if post == "```" {
codeBlock = !codeBlock
}
// skip empty lines for anything not part of a code block.
if !codeBlock && post == "" {
continue
}

switch { // nolint:dupl
case (u.v.GetString(u.br.Protocol()+".threadcontext") == "mattermost" || u.v.GetString(u.br.Protocol()+".threadcontext") == "mattermost+post") && strings.HasPrefix(args[0], "#") && nick != "system":
threadMsgID := u.prefixContext("", p.Id, p.RootId, "")
Expand Down
162 changes: 101 additions & 61 deletions mm-go-irckit/userbridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,35 +139,39 @@ func (u *User) handleDirectMessageEvent(event *bridge.DirectMessageEvent) {
}
}

if u.v.GetBool(u.br.Protocol()+".prefixcontext") || u.v.GetBool(u.br.Protocol()+".suffixcontext") {
prefixUser := event.Sender.User
prefixUser := event.Sender.User
if event.Sender.Me {
prefixUser = event.Receiver.User
}
text, prefix, suffix, showContext, maxlen := u.handleMessageThreadContext(prefixUser, event.MessageID, event.ParentID, event.Event, event.Text)

if event.Sender.Me {
prefixUser = event.Receiver.User
codeBlock := false
text = wordwrap.String(text, maxlen)
lines := strings.Split(text, "\n")
for _, text := range lines {
if text == "```" {
codeBlock = !codeBlock
}
// skip empty lines for anything not part of a code block.
if !codeBlock && text == "" {
continue
} else if text == "" {
text = " "
}

prefix := u.prefixContext(prefixUser, event.MessageID, event.ParentID, event.Event)

switch {
case u.v.GetBool(u.br.Protocol()+".prefixcontext") && strings.HasPrefix(event.Text, "\x01"):
event.Text = strings.Replace(event.Text, "\x01ACTION ", "\x01ACTION "+prefix+" ", 1)
case u.v.GetBool(u.br.Protocol() + ".prefixcontext"):
event.Text = prefix + " " + event.Text
case u.v.GetBool(u.br.Protocol()+".suffixcontext") && strings.HasSuffix(event.Text, "\x01"):
event.Text = strings.Replace(event.Text, " \x01", " "+prefix+" \x01", 1)
case u.v.GetBool(u.br.Protocol() + ".suffixcontext"):
event.Text = event.Text + " " + prefix
if showContext {
text = prefix + text + suffix
}
}

if event.Sender.Me {
if event.Receiver.Me {
u.MsgSpoofUser(u, u.Nick, event.Text)
if event.Sender.Me {
if event.Receiver.Me {
u.MsgSpoofUser(u, u.Nick, text, len(text))
} else {
u.MsgSpoofUser(u, event.Receiver.Nick, text, len(text))
}
} else {
u.MsgSpoofUser(u, event.Receiver.Nick, event.Text)
u.MsgSpoofUser(u.createUserFromInfo(event.Sender), u.Nick, text, len(text))
}
} else {
u.MsgSpoofUser(u.createUserFromInfo(event.Sender), u.Nick, event.Text)
}

if !u.v.GetBool(u.br.Protocol() + ".disableautoview") {
Expand Down Expand Up @@ -276,25 +280,39 @@ func (u *User) handleChannelMessageEvent(event *bridge.ChannelMessageEvent) {
}
}

if (u.v.GetBool(u.br.Protocol()+".prefixcontext") || u.v.GetBool(u.br.Protocol()+".suffixcontext")) && u.Nick != systemUser {
prefix := u.prefixContext(event.ChannelID, event.MessageID, event.ParentID, event.Event)
switch {
case u.v.GetBool(u.br.Protocol()+".prefixcontext") && strings.HasPrefix(event.Text, "\x01"):
event.Text = strings.Replace(event.Text, "\x01ACTION ", "\x01ACTION "+prefix+" ", 1)
case u.v.GetBool(u.br.Protocol() + ".prefixcontext"):
event.Text = prefix + " " + event.Text
case u.v.GetBool(u.br.Protocol()+".suffixcontext") && strings.HasSuffix(event.Text, "\x01"):
event.Text = strings.Replace(event.Text, " \x01", " "+prefix+" \x01", 1)
case u.v.GetBool(u.br.Protocol() + ".suffixcontext"):
event.Text = event.Text + " " + prefix
}
text := event.Text
prefix := ""
suffix := ""
showContext := false
maxlen := 440
if u.Nick != systemUser {
text, prefix, suffix, showContext, maxlen = u.handleMessageThreadContext(event.ChannelID, event.MessageID, event.ParentID, event.Event, event.Text)
}

switch event.MessageType {
case "notice":
ch.SpoofNotice(nick, event.Text)
default:
ch.SpoofMessage(nick, event.Text)
codeBlock := false
text = wordwrap.String(text, maxlen)
lines := strings.Split(text, "\n")
for _, text := range lines {
if text == "```" {
codeBlock = !codeBlock
}
// skip empty lines for anything not part of a code block.
if !codeBlock && text == "" {
continue
} else if text == "" {
text = " "
}

if showContext {
text = prefix + text + suffix
}

switch event.MessageType {
case "notice":
ch.SpoofNotice(nick, text, len(text))
default:
ch.SpoofMessage(nick, text, len(text))
}
}

if !u.v.GetBool(u.br.Protocol() + ".disableautoview") {
Expand Down Expand Up @@ -564,9 +582,9 @@ func (u *User) addUsersToChannels() {
go u.handleEventChan()
}

func (u *User) createSpoof(mmchannel *bridge.ChannelInfo) func(string, string) {
func (u *User) createSpoof(mmchannel *bridge.ChannelInfo) func(string, string, ...int) {
if strings.Contains(mmchannel.Name, "__") {
return func(nick string, msg string) {
return func(nick string, msg string, maxlen ...int) {
if usr, ok := u.Srv.HasUser(nick); ok {
u.MsgSpoofUser(usr, u.Nick, msg)
} else {
Expand Down Expand Up @@ -688,16 +706,7 @@ func (u *User) addUserToChannelWorker(channels <-chan *bridge.ChannelInfo, throt
nick = systemUser
}

codeBlock := false
for _, post := range strings.Split(p.Message, "\n") {
if post == "```" {
codeBlock = !codeBlock
}
// skip empty lines for anything not part of a code block.
if !codeBlock && post == "" {
continue
}

if showReplayHdr {
date := ts.Format("2006-01-02 15:04:05")
if brchannel.DM {
Expand Down Expand Up @@ -813,16 +822,7 @@ func (u *User) addUserToChannelWorker6(channels <-chan *bridge.ChannelInfo, thro
nick = systemUser
}

codeBlock := false
for _, post := range strings.Split(p.Message, "\n") {
if post == "```" {
codeBlock = !codeBlock
}
// skip empty lines for anything not part of a code block.
if !codeBlock && post == "" {
continue
}

if showReplayHdr {
date := ts.Format("2006-01-02 15:04:05")
channame := brchannel.Name
Expand Down Expand Up @@ -876,8 +876,12 @@ func (u *User) MsgUser(toUser *User, msg string) {
})
}

func (u *User) MsgSpoofUser(sender *User, rcvuser string, msg string) {
msg = wordwrap.String(msg, 440)
func (u *User) MsgSpoofUser(sender *User, rcvuser string, msg string, maxlen ...int) {
if len(maxlen) == 0 {
msg = wordwrap.String(msg, 440)
} else {
msg = wordwrap.String(msg, maxlen[0])
}
lines := strings.Split(msg, "\n")
for _, l := range lines {
u.Encode(&irc.Message{
Expand Down Expand Up @@ -1246,3 +1250,39 @@ func (u *User) getMattermostVersion() string {

return resp.Header.Get("X-Version-Id")
}

func (u *User) handleMessageThreadContext(channelID, messageID, parentID, event, text string) (string, string, string, bool, int) {
newText := text
prefix := ""
suffix := ""
maxlen := 440
showContext := false

switch {
case u.v.GetBool(u.br.Protocol()+".prefixcontext") && strings.HasPrefix(text, "\x01"):
prefix = u.prefixContext(channelID, messageID, parentID, event) + " "
newText = strings.Replace(text, "\x01ACTION ", "\x01ACTION "+prefix, 1)
maxlen = len(text)
case u.v.GetBool(u.br.Protocol()+".prefixcontext") && u.v.GetBool(u.br.Protocol()+".showcontextmulti"):
prefix = u.prefixContext(channelID, messageID, parentID, event) + " "
newText = text
showContext = true
maxlen -= len(prefix)
case u.v.GetBool(u.br.Protocol() + ".prefixcontext"):
prefix = u.prefixContext(channelID, messageID, parentID, event) + " "
newText = prefix + text
case u.v.GetBool(u.br.Protocol()+".suffixcontext") && strings.HasSuffix(text, "\x01"):
suffix = " " + u.prefixContext(channelID, messageID, parentID, event)
newText = strings.Replace(text, " \x01", suffix+" \x01", 1)
case u.v.GetBool(u.br.Protocol()+".suffixcontext") && u.v.GetBool(u.br.Protocol()+".showcontextmulti"):
suffix = " " + u.prefixContext(channelID, messageID, parentID, event)
newText = text
showContext = true
maxlen -= len(suffix)
case u.v.GetBool(u.br.Protocol() + ".suffixcontext"):
suffix = " " + u.prefixContext(channelID, messageID, parentID, event)
newText = strings.TrimRight(text, "\n") + suffix
}

return newText, prefix, suffix, showContext, maxlen
}

0 comments on commit db8eb23

Please sign in to comment.