From 16635dcde7b3402e7eff44864b4dba5a2ddd8a37 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 23 Mar 2018 01:00:13 +0200 Subject: [PATCH] Refactor PushRuleset#GetActions() and ViewMain event processing --- interface/ui.go | 4 +- matrix/matrix.go | 54 ++++++++++++++++----- matrix/pushrules/rule.go | 4 ++ matrix/pushrules/ruleset.go | 28 +++++------ ui/view-main.go | 95 ++++++++++++++----------------------- 5 files changed, 98 insertions(+), 87 deletions(-) diff --git a/interface/ui.go b/interface/ui.go index ada1cc0..f08c9f3 100644 --- a/interface/ui.go +++ b/interface/ui.go @@ -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 { diff --git a/matrix/matrix.go b/matrix/matrix.go index 9423f63..b062057 100644 --- a/matrix/matrix.go +++ b/matrix/matrix.go @@ -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() } } diff --git a/matrix/pushrules/rule.go b/matrix/pushrules/rule.go index 933d493..dd8a4d3 100644 --- a/matrix/pushrules/rule.go +++ b/matrix/pushrules/rule.go @@ -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 { diff --git a/matrix/pushrules/ruleset.go b/matrix/pushrules/ruleset.go index a8d212d..b533f94 100644 --- a/matrix/pushrules/ruleset.go +++ b/matrix/pushrules/ruleset.go @@ -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 } diff --git a/ui/view-main.go b/ui/view-main.go index 83da396..9c0550c 100644 --- a/ui/view-main.go +++ b/ui/view-main.go @@ -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 }