Refactor PushRuleset#GetActions() and ViewMain event processing

This commit is contained in:
Tulir Asokan 2018-03-23 01:00:13 +02:00
parent a5e7800ab6
commit 16635dcde7
5 changed files with 98 additions and 87 deletions

View File

@ -49,8 +49,8 @@ type MainView interface {
SetTyping(roomID string, users []string)
AddServiceMessage(roomID *widget.RoomView, message string)
ProcessMessageEvent(evt *gomatrix.Event) (*widget.RoomView, *types.Message)
ProcessMembershipEvent(evt *gomatrix.Event, new bool) (*widget.RoomView, *types.Message)
ProcessMessageEvent(roomView *widget.RoomView, evt *gomatrix.Event) *types.Message
ProcessMembershipEvent(roomView *widget.RoomView, evt *gomatrix.Event) *types.Message
}
type LoginView interface {

View File

@ -222,11 +222,16 @@ func (c *Container) NotifyMessage(room *rooms.Room, sender, text string, critica
// HandleMessage is the event handler for the m.room.message timeline event.
func (c *Container) HandleMessage(evt *gomatrix.Event) {
room, message := c.ui.MainView().ProcessMessageEvent(evt)
if room != nil {
pushRules := c.PushRules().GetActions(room.Room, evt).Should()
roomView := c.ui.MainView().GetRoom(evt.RoomID)
if roomView == nil {
return
}
message := c.ui.MainView().ProcessMessageEvent(roomView, evt)
if message != nil {
pushRules := c.PushRules().GetActions(roomView.Room, evt).Should()
if (pushRules.Notify || !pushRules.NotifySpecified) && evt.Sender != c.config.Session.UserID {
c.NotifyMessage(room.Room, message.Sender, message.Text, pushRules.Highlight)
c.NotifyMessage(roomView.Room, message.Sender, message.Text, pushRules.Highlight)
}
if pushRules.Highlight {
message.TextColor = tcell.ColorYellow
@ -234,7 +239,7 @@ func (c *Container) HandleMessage(evt *gomatrix.Event) {
if pushRules.PlaySound {
// TODO play sound
}
room.AddMessage(message, widget.AppendMessage)
roomView.AddMessage(message, widget.AppendMessage)
c.ui.Render()
}
}
@ -249,6 +254,22 @@ func (c *Container) HandlePushRules(evt *gomatrix.Event) {
}
}
func (c *Container) processOwnMembershipChange(evt *gomatrix.Event) {
membership, _ := evt.Content["membership"].(string)
prevMembership := "leave"
if evt.Unsigned.PrevContent != nil {
prevMembership, _ = evt.Unsigned.PrevContent["membership"].(string)
}
if membership == prevMembership {
return
}
if membership == "join" {
c.ui.MainView().AddRoom(evt.RoomID)
} else if membership == "leave" {
c.ui.MainView().RemoveRoom(evt.RoomID)
}
}
// HandleMembership is the event handler for the m.room.membership state event.
func (c *Container) HandleMembership(evt *gomatrix.Event) {
const Hour = 1 * 60 * 60 * 1000
@ -256,14 +277,23 @@ func (c *Container) HandleMembership(evt *gomatrix.Event) {
return
}
room, message := c.ui.MainView().ProcessMembershipEvent(evt, true)
if room != nil {
// TODO this shouldn't be necessary
room.Room.UpdateState(evt)
// TODO This should probably also be in a different place
room.UpdateUserList()
if evt.StateKey != nil && *evt.StateKey == c.config.Session.UserID {
c.processOwnMembershipChange(evt)
}
room.AddMessage(message, widget.AppendMessage)
roomView := c.ui.MainView().GetRoom(evt.RoomID)
if roomView == nil {
return
}
message := c.ui.MainView().ProcessMembershipEvent(roomView, evt)
if message != nil {
// TODO this shouldn't be necessary
roomView.Room.UpdateState(evt)
// TODO This should probably also be in a different place
roomView.UpdateUserList()
roomView.AddMessage(message, widget.AppendMessage)
c.ui.Render()
}
}

View File

@ -22,6 +22,10 @@ import (
"maunium.net/go/gomuks/matrix/rooms"
)
type PushRuleCollection interface {
GetActions(room *rooms.Room, event *gomatrix.Event) PushActionArray
}
type PushRuleArray []*PushRule
func (rules PushRuleArray) setType(typ PushRuleType) PushRuleArray {

View File

@ -65,23 +65,23 @@ func (rs *PushRuleset) MarshalJSON() ([]byte, error) {
return json.Marshal(&data)
}
// DefaultPushActions is the value returned if none of the rule
// collections in a Ruleset match the event given to GetActions()
var DefaultPushActions = make(PushActionArray, 0)
// GetActions matches the given event against all of the push rule
// collections in this push ruleset in the order of priority as
// specified in spec section 11.12.1.4.
func (rs *PushRuleset) GetActions(room *rooms.Room, event *gomatrix.Event) (match PushActionArray) {
if match = rs.Override.GetActions(room, event); match != nil {
return
}
if match = rs.Content.GetActions(room, event); match != nil {
return
}
if match = rs.Room.GetActions(room, event); match != nil {
return
}
if match = rs.Sender.GetActions(room, event); match != nil {
return
}
if match = rs.Underride.GetActions(room, event); match != nil {
return
// Add push rule collections to array in priority order
arrays := []PushRuleCollection{rs.Override, rs.Content, rs.Room, rs.Sender, rs.Underride}
// Loop until one of the push rule collections matches the room/event combo.
for _, pra := range arrays {
if match = pra.GetActions(room, event); match != nil {
// Match found, return it.
return
}
}
// No match found, return default actions.
return DefaultPushActions
}

View File

@ -374,15 +374,14 @@ func (view *MainView) LoadHistory(room string, initial bool) {
}
roomView.Room.PrevBatch = prevBatch
for _, evt := range history {
var room *widget.RoomView
var message *types.Message
if evt.Type == "m.room.message" {
room, message = view.ProcessMessageEvent(&evt)
message = view.ProcessMessageEvent(roomView, &evt)
} else if evt.Type == "m.room.member" {
room, message = view.ProcessMembershipEvent(&evt, false)
message = view.ProcessMembershipEvent(roomView, &evt)
}
if room != nil && message != nil {
room.AddMessage(message, widget.PrependMessage)
if message != nil {
roomView.AddMessage(message, widget.PrependMessage)
}
}
err = roomView.SaveHistory(view.config.HistoryDir)
@ -393,66 +392,44 @@ func (view *MainView) LoadHistory(room string, initial bool) {
view.parent.Render()
}
func (view *MainView) ProcessMessageEvent(evt *gomatrix.Event) (room *widget.RoomView, message *types.Message) {
room = view.GetRoom(evt.RoomID)
if room != nil {
text, _ := evt.Content["body"].(string)
msgtype, _ := evt.Content["msgtype"].(string)
message = room.NewMessage(evt.ID, evt.Sender, msgtype, text, unixToTime(evt.Timestamp))
func (view *MainView) ProcessMessageEvent(room *widget.RoomView, evt *gomatrix.Event) (message *types.Message) {
text, _ := evt.Content["body"].(string)
msgtype, _ := evt.Content["msgtype"].(string)
return room.NewMessage(evt.ID, evt.Sender, msgtype, text, unixToTime(evt.Timestamp))
}
func (view *MainView) getMembershipEventContent(evt *gomatrix.Event) (sender, text string) {
membership, _ := evt.Content["membership"].(string)
displayname, _ := evt.Content["displayname"].(string)
if len(displayname) == 0 {
displayname = *evt.StateKey
}
if membership == "invite" {
sender = "---"
text = fmt.Sprintf("%s invited %s.", evt.Sender, displayname)
} else if membership == "join" {
sender = "-->"
text = fmt.Sprintf("%s joined the room.", displayname)
} else if membership == "leave" {
sender = "<--"
if evt.Sender != *evt.StateKey {
reason, _ := evt.Content["reason"].(string)
text = fmt.Sprintf("%s kicked %s: %s", evt.Sender, displayname, reason)
} else {
text = fmt.Sprintf("%s left the room.", displayname)
}
}
return
}
func (view *MainView) processOwnMembershipChange(evt *gomatrix.Event) {
membership, _ := evt.Content["membership"].(string)
prevMembership := "leave"
if evt.Unsigned.PrevContent != nil {
prevMembership, _ = evt.Unsigned.PrevContent["membership"].(string)
}
if membership == prevMembership {
func (view *MainView) ProcessMembershipEvent(room *widget.RoomView, evt *gomatrix.Event) (message *types.Message) {
sender, text := view.getMembershipEventContent(evt)
if len(text) == 0 {
return
}
if membership == "join" {
view.AddRoom(evt.RoomID)
} else if membership == "leave" {
view.RemoveRoom(evt.RoomID)
}
}
func (view *MainView) ProcessMembershipEvent(evt *gomatrix.Event, new bool) (room *widget.RoomView, message *types.Message) {
if new && evt.StateKey != nil && *evt.StateKey == view.config.Session.UserID {
view.processOwnMembershipChange(evt)
}
room = view.GetRoom(evt.RoomID)
if room != nil {
membership, _ := evt.Content["membership"].(string)
displayname, _ := evt.Content["displayname"].(string)
if len(displayname) == 0 {
displayname = *evt.StateKey
}
var sender, text string
if membership == "invite" {
sender = "---"
text = fmt.Sprintf("%s invited %s.", evt.Sender, displayname)
} else if membership == "join" {
sender = "-->"
text = fmt.Sprintf("%s joined the room.", displayname)
} else if membership == "leave" {
sender = "<--"
if evt.Sender != *evt.StateKey {
reason, _ := evt.Content["reason"].(string)
text = fmt.Sprintf("%s kicked %s: %s", evt.Sender, displayname, reason)
} else {
text = fmt.Sprintf("%s left the room.", displayname)
}
} else {
room = nil
return
}
message = room.NewMessage(evt.ID, sender, "m.room.member", text, unixToTime(evt.Timestamp))
message.TextColor = tcell.ColorGreen
}
message = room.NewMessage(evt.ID, sender, "m.room.member", text, unixToTime(evt.Timestamp))
message.TextColor = tcell.ColorGreen
return
}