aboutsummaryrefslogtreecommitdiff
path: root/matrix/matrix.go
diff options
context:
space:
mode:
Diffstat (limited to 'matrix/matrix.go')
-rw-r--r--matrix/matrix.go121
1 files changed, 93 insertions, 28 deletions
diff --git a/matrix/matrix.go b/matrix/matrix.go
index ef272b0..cfd5614 100644
--- a/matrix/matrix.go
+++ b/matrix/matrix.go
@@ -29,7 +29,9 @@ import (
"path"
"path/filepath"
"regexp"
+ "runtime"
"time"
+ dbg "runtime/debug"
"maunium.net/go/mautrix"
"maunium.net/go/mautrix/format"
@@ -204,6 +206,9 @@ func (c *Container) OnLogin() {
debug.Print("Initializing syncer")
c.syncer = NewGomuksSyncer(c.config)
c.syncer.OnEventType(mautrix.EventMessage, c.HandleMessage)
+ // Just pass encrypted events as messages, they'll show up with an encryption unsupported message.
+ c.syncer.OnEventType(mautrix.EventEncrypted, c.HandleMessage)
+ c.syncer.OnEventType(mautrix.EventSticker, c.HandleMessage)
c.syncer.OnEventType(mautrix.StateAliases, c.HandleMessage)
c.syncer.OnEventType(mautrix.StateCanonicalAlias, c.HandleMessage)
c.syncer.OnEventType(mautrix.StateTopic, c.HandleMessage)
@@ -218,9 +223,22 @@ func (c *Container) OnLogin() {
c.syncer.InitDoneCallback = func() {
debug.Print("Initial sync done")
c.config.AuthCache.InitialSyncDone = true
- c.config.SaveAuthCache()
- c.ui.MainView().InitialSyncDone()
+ debug.Print("Updating title caches")
+ for _, room := range c.config.Rooms.Map {
+ room.GetTitle()
+ }
+ debug.Print("Cleaning cached rooms from memory")
+ c.config.Rooms.ForceClean()
+ debug.Print("Saving all data")
+ c.config.SaveAll()
+ debug.Print("Adding rooms to UI")
+ c.ui.MainView().SetRooms(c.config.Rooms)
c.ui.Render()
+ // The initial sync can be a bit heavy, so we force run the GC here
+ // after cleaning up rooms from memory above.
+ debug.Print("Running GC")
+ runtime.GC()
+ dbg.FreeOSMemory()
}
c.client.Syncer = c.syncer
@@ -274,7 +292,9 @@ func (c *Container) HandlePreferences(source EventSource, evt *mautrix.Event) {
return
}
debug.Print("Updated preferences:", orig, "->", c.config.Preferences)
- c.ui.HandleNewPreferences()
+ if c.config.AuthCache.InitialSyncDone {
+ c.ui.HandleNewPreferences()
+ }
}
func (c *Container) SendPreferencesToMatrix() {
@@ -289,9 +309,24 @@ func (c *Container) SendPreferencesToMatrix() {
// HandleMessage is the event handler for the m.room.message timeline event.
func (c *Container) HandleMessage(source EventSource, evt *mautrix.Event) {
- if source&EventSourceLeave != 0 || source&EventSourceState != 0 {
+ room := c.GetOrCreateRoom(evt.RoomID)
+ if source&EventSourceLeave != 0 {
+ room.HasLeft = true
+ return
+ } else if source&EventSourceState != 0 {
+ return
+ }
+
+ err := c.history.Append(room, []*mautrix.Event{evt})
+ if err != nil {
+ debug.Printf("Failed to add event %s to history: %v", evt.ID, err)
+ }
+
+ if !c.config.AuthCache.InitialSyncDone {
+ room.LastReceivedMessage = time.Unix(evt.Timestamp/1000, evt.Timestamp%1000*1000)
return
}
+
mainView := c.ui.MainView()
roomView := mainView.GetRoom(evt.RoomID)
@@ -300,23 +335,29 @@ func (c *Container) HandleMessage(source EventSource, evt *mautrix.Event) {
return
}
- err := c.history.Append(roomView.MxRoom(), []*mautrix.Event{evt})
- if err != nil {
- debug.Printf("Failed to add event %s to history: %v", evt.ID, err)
+ if !room.Loaded() {
+ pushRules := c.PushRules().GetActions(room, evt).Should()
+ shouldNotify := pushRules.Notify || !pushRules.NotifySpecified
+ if !shouldNotify {
+ room.LastReceivedMessage = time.Unix(evt.Timestamp/1000, evt.Timestamp%1000*1000)
+ room.AddUnread(evt.ID, shouldNotify, pushRules.Highlight)
+ mainView.Bump(room)
+ return
+ }
}
// TODO switch to roomView.AddEvent
message := roomView.ParseEvent(evt)
if message != nil {
roomView.AddMessage(message)
- roomView.MxRoom().LastReceivedMessage = message.Timestamp()
+ roomView.MxRoom().LastReceivedMessage = message.Time()
if c.syncer.FirstSyncDone {
pushRules := c.PushRules().GetActions(roomView.MxRoom(), evt).Should()
mainView.NotifyMessage(roomView.MxRoom(), message, pushRules)
c.ui.Render()
}
} else {
- debug.Printf("Parsing event %s type %s %v from %s in %s failed (ParseEvent() returned nil).", evt.ID, evt.Type, evt.Content.Raw, evt.Sender, evt.RoomID)
+ debug.Printf("Parsing event %s type %s %v from %s in %s failed (ParseEvent() returned nil).", evt.ID, evt.Type.String(), evt.Content.Raw, evt.Sender, evt.RoomID)
}
}
@@ -324,6 +365,9 @@ func (c *Container) HandleMessage(source EventSource, evt *mautrix.Event) {
func (c *Container) HandleMembership(source EventSource, evt *mautrix.Event) {
isLeave := source&EventSourceLeave != 0
isTimeline := source&EventSourceTimeline != 0
+ if isLeave {
+ c.GetOrCreateRoom(evt.RoomID).HasLeft = true
+ }
isNonTimelineLeave := isLeave && !isTimeline
if !c.config.AuthCache.InitialSyncDone && isNonTimelineLeave {
return
@@ -350,11 +394,16 @@ func (c *Container) processOwnMembershipChange(evt *mautrix.Event) {
room := c.GetRoom(evt.RoomID)
switch membership {
case "join":
- c.ui.MainView().AddRoom(room)
+ if c.config.AuthCache.InitialSyncDone {
+ c.ui.MainView().AddRoom(room)
+ }
room.HasLeft = false
case "leave":
- c.ui.MainView().RemoveRoom(room)
+ if c.config.AuthCache.InitialSyncDone {
+ c.ui.MainView().RemoveRoom(room)
+ }
room.HasLeft = true
+ room.Unload()
case "invite":
// TODO handle
debug.Printf("%s invited the user to %s", evt.Sender, evt.RoomID)
@@ -399,8 +448,12 @@ func (c *Container) HandleReadReceipt(source EventSource, evt *mautrix.Event) {
}
room := c.GetRoom(evt.RoomID)
- room.MarkRead(lastReadEvent)
- c.ui.Render()
+ if room != nil {
+ room.MarkRead(lastReadEvent)
+ if c.config.AuthCache.InitialSyncDone {
+ c.ui.Render()
+ }
+ }
}
func (c *Container) parseDirectChatInfo(evt *mautrix.Event) map[*rooms.Room]bool {
@@ -417,7 +470,7 @@ func (c *Container) parseDirectChatInfo(evt *mautrix.Event) map[*rooms.Room]bool
continue
}
- room := c.GetRoom(roomID)
+ room := c.GetOrCreateRoom(roomID)
if room != nil && !room.HasLeft {
directChats[room] = true
}
@@ -428,11 +481,13 @@ func (c *Container) parseDirectChatInfo(evt *mautrix.Event) map[*rooms.Room]bool
func (c *Container) HandleDirectChatInfo(source EventSource, evt *mautrix.Event) {
directChats := c.parseDirectChatInfo(evt)
- for _, room := range c.config.Rooms {
+ for _, room := range c.config.Rooms.Map {
shouldBeDirect := directChats[room]
if shouldBeDirect != room.IsDirect {
room.IsDirect = shouldBeDirect
- c.ui.MainView().UpdateTags(room)
+ if c.config.AuthCache.InitialSyncDone {
+ c.ui.MainView().UpdateTags(room)
+ }
}
}
}
@@ -451,7 +506,7 @@ func (c *Container) HandlePushRules(source EventSource, evt *mautrix.Event) {
// HandleTag is the event handler for the m.tag account data event.
func (c *Container) HandleTag(source EventSource, evt *mautrix.Event) {
- room := c.config.GetRoom(evt.RoomID)
+ room := c.GetOrCreateRoom(evt.RoomID)
newTags := make([]rooms.RoomTag, len(evt.Content.RoomTags))
index := 0
@@ -466,14 +521,19 @@ func (c *Container) HandleTag(source EventSource, evt *mautrix.Event) {
}
index++
}
-
- mainView := c.ui.MainView()
room.RawTags = newTags
- mainView.UpdateTags(room)
+
+ if c.config.AuthCache.InitialSyncDone {
+ mainView := c.ui.MainView()
+ mainView.UpdateTags(room)
+ }
}
// HandleTyping is the event handler for the m.typing event.
func (c *Container) HandleTyping(source EventSource, evt *mautrix.Event) {
+ if !c.config.AuthCache.InitialSyncDone {
+ return
+ }
c.ui.MainView().SetTyping(evt.RoomID, evt.Content.TypingUserIDs)
}
@@ -544,7 +604,7 @@ func (c *Container) CreateRoom(req *mautrix.ReqCreateRoom) (*rooms.Room, error)
if err != nil {
return nil, err
}
- room := c.GetRoom(resp.RoomID)
+ room := c.GetOrCreateRoom(resp.RoomID)
return room, nil
}
@@ -557,7 +617,6 @@ func (c *Container) JoinRoom(roomID, server string) (*rooms.Room, error) {
room := c.GetRoom(resp.RoomID)
room.HasLeft = false
-
return room, nil
}
@@ -568,8 +627,9 @@ func (c *Container) LeaveRoom(roomID string) error {
return err
}
- room := c.GetRoom(roomID)
- room.HasLeft = true
+ node := c.GetOrCreateRoom(roomID)
+ node.HasLeft = true
+ node.Unload()
return nil
}
@@ -593,9 +653,9 @@ func (c *Container) GetHistory(room *rooms.Room, limit int) ([]*mautrix.Event, e
return nil, err
}
}
- room.PrevBatch = resp.End
- c.config.PutRoom(room)
debug.Printf("Loaded %d events for %s from server from %s to %s", len(resp.Chunk), room.ID, resp.Start, resp.End)
+ room.PrevBatch = resp.End
+ c.config.Rooms.Put(room)
return resp.Chunk, nil
}
@@ -613,9 +673,14 @@ func (c *Container) GetEvent(room *rooms.Room, eventID string) (*mautrix.Event,
return event, nil
}
+// GetOrCreateRoom gets the room instance stored in the session.
+func (c *Container) GetOrCreateRoom(roomID string) *rooms.Room {
+ return c.config.Rooms.GetOrCreate(roomID)
+}
+
// GetRoom gets the room instance stored in the session.
func (c *Container) GetRoom(roomID string) *rooms.Room {
- return c.config.GetRoom(roomID)
+ return c.config.Rooms.Get(roomID)
}
var mxcRegex = regexp.MustCompile("mxc://(.+)/(.+)")
@@ -642,7 +707,7 @@ func (c *Container) Download(mxcURL string) (data []byte, hs, id string, err err
}
}
- data, err = c.download(hs, id, cacheFile)
+ //FIXME data, err = c.download(hs, id, cacheFile)
return
}