From 7e21d59dcadd1eeb8fdee4521c77121c8ec2c699 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 20 Apr 2017 00:19:23 +0100 Subject: [PATCH 1/3] Handle leave events --- responses.go | 10 ++++++++++ sync.go | 8 ++++++++ 2 files changed, 18 insertions(+) diff --git a/responses.go b/responses.go index de7a8ae..1ae27e3 100644 --- a/responses.go +++ b/responses.go @@ -125,6 +125,16 @@ type RespSync struct { Events []Event `json:"events"` } `json:"presence"` Rooms struct { + Leave map[string]struct { + State struct { + Events []Event `json:"events"` + } `json:"state"` + Timeline struct { + Events []Event `json:"events"` + Limited bool `json:"limited"` + PrevBatch string `json:"prev_batch"` + } `json:"timeline"` + } `json:"leave"` Join map[string]struct { State struct { Events []Event `json:"events"` diff --git a/sync.go b/sync.go index 347e5dc..f0b07e2 100644 --- a/sync.go +++ b/sync.go @@ -73,6 +73,14 @@ func (s *DefaultSyncer) ProcessResponse(res *RespSync, since string) (err error) s.notifyListeners(&event) } } + for roomID, roomData := range res.Rooms.Leave { + room := s.getOrCreateRoom(roomID) + for _, event := range roomData.Timeline.Events { + event.RoomID = roomID + room.UpdateState(&event) + s.notifyListeners(&event) + } + } return } From 06ec893403dc1dff821b72b11315712b04012bf9 Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 20 Apr 2017 14:41:29 +0100 Subject: [PATCH 2/3] Check that event is a state event. --- events.go | 14 +++++++------- room.go | 2 +- sync.go | 10 ++++++---- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/events.go b/events.go index 6ea259e..6355444 100644 --- a/events.go +++ b/events.go @@ -7,13 +7,13 @@ import ( // Event represents a single Matrix event. type Event struct { - StateKey string `json:"state_key"` // The state key for the event. Only present on State Events. - Sender string `json:"sender"` // The user ID of the sender of the event - Type string `json:"type"` // The event type - Timestamp int `json:"origin_server_ts"` // The unix timestamp when this message was sent by the origin server - ID string `json:"event_id"` // The unique ID of this event - RoomID string `json:"room_id"` // The room the event was sent to. May be nil (e.g. for presence) - Content map[string]interface{} `json:"content"` // The JSON content of the event. + StateKey *string `json:"state_key,omitempty"` // The state key for the event. Only present on State Events. + Sender string `json:"sender"` // The user ID of the sender of the event + Type string `json:"type"` // The event type + Timestamp int `json:"origin_server_ts"` // The unix timestamp when this message was sent by the origin server + ID string `json:"event_id"` // The unique ID of this event + RoomID string `json:"room_id"` // The room the event was sent to. May be nil (e.g. for presence) + Content map[string]interface{} `json:"content"` // The JSON content of the event. } // Body returns the value of the "body" key in the event content if it is diff --git a/room.go b/room.go index 0533b3e..c9b2351 100644 --- a/room.go +++ b/room.go @@ -13,7 +13,7 @@ func (room Room) UpdateState(event *Event) { if !exists { room.State[event.Type] = make(map[string]*Event) } - room.State[event.Type][event.StateKey] = event + room.State[event.Type][*event.StateKey] = event } // GetStateEvent returns the state event for the given type/state_key combo, or nil. diff --git a/sync.go b/sync.go index f0b07e2..356d430 100644 --- a/sync.go +++ b/sync.go @@ -76,9 +76,11 @@ func (s *DefaultSyncer) ProcessResponse(res *RespSync, since string) (err error) for roomID, roomData := range res.Rooms.Leave { room := s.getOrCreateRoom(roomID) for _, event := range roomData.Timeline.Events { - event.RoomID = roomID - room.UpdateState(&event) - s.notifyListeners(&event) + if event.StateKey != nil { + event.RoomID = roomID + room.UpdateState(&event) + s.notifyListeners(&event) + } } } return @@ -110,7 +112,7 @@ func (s *DefaultSyncer) shouldProcessResponse(resp *RespSync, since string) bool for roomID, roomData := range resp.Rooms.Join { for i := len(roomData.Timeline.Events) - 1; i >= 0; i-- { e := roomData.Timeline.Events[i] - if e.Type == "m.room.member" && e.StateKey == s.UserID { + if e.Type == "m.room.member" && *e.StateKey == s.UserID { m := e.Content["membership"] mship, ok := m.(string) if !ok { From c7bec461cded824c8ff93d4efbc4b9af2e681fbb Mon Sep 17 00:00:00 2001 From: Richard Lewis Date: Thu, 20 Apr 2017 21:29:44 +0100 Subject: [PATCH 3/3] Check that StateKey is not nil / null --- sync.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sync.go b/sync.go index 356d430..c4bea48 100644 --- a/sync.go +++ b/sync.go @@ -112,7 +112,7 @@ func (s *DefaultSyncer) shouldProcessResponse(resp *RespSync, since string) bool for roomID, roomData := range resp.Rooms.Join { for i := len(roomData.Timeline.Events) - 1; i >= 0; i-- { e := roomData.Timeline.Events[i] - if e.Type == "m.room.member" && *e.StateKey == s.UserID { + if e.Type == "m.room.member" && e.StateKey != nil && *e.StateKey == s.UserID { m := e.Content["membership"] mship, ok := m.(string) if !ok {