Enable lazy loading of members
This commit is contained in:
parent
032a83d70b
commit
442fdac4d5
4
go.mod
4
go.mod
@ -19,7 +19,7 @@ require (
|
|||||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2
|
golang.org/x/net v0.0.0-20200202094626-16171245cfb2
|
||||||
gopkg.in/toast.v1 v1.0.0-20180812000517-0a84660828b2
|
gopkg.in/toast.v1 v1.0.0-20180812000517-0a84660828b2
|
||||||
gopkg.in/yaml.v2 v2.2.8
|
gopkg.in/yaml.v2 v2.2.8
|
||||||
maunium.net/go/mautrix v0.1.0-alpha.3.0.20200220001222-8dc3dd5d538d
|
maunium.net/go/mautrix v0.1.0-alpha.3.0.20200221220303-b441ba9359cf
|
||||||
maunium.net/go/mauview v0.0.0-20200220201003-92b19f8819b4
|
maunium.net/go/mauview v0.0.0-20200220222850-39f1414676d9
|
||||||
maunium.net/go/tcell v1.1.2-0.20200218183045-87c4a25c5b09
|
maunium.net/go/tcell v1.1.2-0.20200218183045-87c4a25c5b09
|
||||||
)
|
)
|
||||||
|
4
go.sum
4
go.sum
@ -82,6 +82,8 @@ maunium.net/go/mautrix v0.1.0-alpha.3.0.20200219230859-de66c34ea5bc h1:1iMzqdMF4
|
|||||||
maunium.net/go/mautrix v0.1.0-alpha.3.0.20200219230859-de66c34ea5bc/go.mod h1:g10T1fh2Q2HkJWycVs93eBXdWpqD67f1YVQhNxdIDr4=
|
maunium.net/go/mautrix v0.1.0-alpha.3.0.20200219230859-de66c34ea5bc/go.mod h1:g10T1fh2Q2HkJWycVs93eBXdWpqD67f1YVQhNxdIDr4=
|
||||||
maunium.net/go/mautrix v0.1.0-alpha.3.0.20200220001222-8dc3dd5d538d h1:doAHXnYCIgNy4qAgReZRRb3EaWR4D0w+Zs2y959Z8Uk=
|
maunium.net/go/mautrix v0.1.0-alpha.3.0.20200220001222-8dc3dd5d538d h1:doAHXnYCIgNy4qAgReZRRb3EaWR4D0w+Zs2y959Z8Uk=
|
||||||
maunium.net/go/mautrix v0.1.0-alpha.3.0.20200220001222-8dc3dd5d538d/go.mod h1:g10T1fh2Q2HkJWycVs93eBXdWpqD67f1YVQhNxdIDr4=
|
maunium.net/go/mautrix v0.1.0-alpha.3.0.20200220001222-8dc3dd5d538d/go.mod h1:g10T1fh2Q2HkJWycVs93eBXdWpqD67f1YVQhNxdIDr4=
|
||||||
|
maunium.net/go/mautrix v0.1.0-alpha.3.0.20200221220303-b441ba9359cf h1:ojEsISqRLmM9PRIJiVDTRHNmj5IZoXn3E64S+2uTJNw=
|
||||||
|
maunium.net/go/mautrix v0.1.0-alpha.3.0.20200221220303-b441ba9359cf/go.mod h1:g10T1fh2Q2HkJWycVs93eBXdWpqD67f1YVQhNxdIDr4=
|
||||||
maunium.net/go/mauview v0.0.0-20200218183549-88ecb1321176 h1:KoTm7ASEzFIZ1SvPWuWYzpkeA+wiR1fuUu4l7TCHcE0=
|
maunium.net/go/mauview v0.0.0-20200218183549-88ecb1321176 h1:KoTm7ASEzFIZ1SvPWuWYzpkeA+wiR1fuUu4l7TCHcE0=
|
||||||
maunium.net/go/mauview v0.0.0-20200218183549-88ecb1321176/go.mod h1:jwg3Ow7akzsCX3q38pZAfmEC5gGN8gXwMyyjy/yZVMg=
|
maunium.net/go/mauview v0.0.0-20200218183549-88ecb1321176/go.mod h1:jwg3Ow7akzsCX3q38pZAfmEC5gGN8gXwMyyjy/yZVMg=
|
||||||
maunium.net/go/mauview v0.0.0-20200218231215-04d01c601d5b h1:Bfov5IkJQpkqDexiFioHIZpx4XL7AILDA1GwLVdqtBw=
|
maunium.net/go/mauview v0.0.0-20200218231215-04d01c601d5b h1:Bfov5IkJQpkqDexiFioHIZpx4XL7AILDA1GwLVdqtBw=
|
||||||
@ -92,5 +94,7 @@ maunium.net/go/mauview v0.0.0-20200219222453-b984e20438e6 h1:yYs5rsnDQrZie4eeWlc
|
|||||||
maunium.net/go/mauview v0.0.0-20200219222453-b984e20438e6/go.mod h1:jwg3Ow7akzsCX3q38pZAfmEC5gGN8gXwMyyjy/yZVMg=
|
maunium.net/go/mauview v0.0.0-20200219222453-b984e20438e6/go.mod h1:jwg3Ow7akzsCX3q38pZAfmEC5gGN8gXwMyyjy/yZVMg=
|
||||||
maunium.net/go/mauview v0.0.0-20200220201003-92b19f8819b4 h1:60G4iPYhO5Z4qkcniM+xPBeXNmuyD1tqXzj8ryeEdWY=
|
maunium.net/go/mauview v0.0.0-20200220201003-92b19f8819b4 h1:60G4iPYhO5Z4qkcniM+xPBeXNmuyD1tqXzj8ryeEdWY=
|
||||||
maunium.net/go/mauview v0.0.0-20200220201003-92b19f8819b4/go.mod h1:jwg3Ow7akzsCX3q38pZAfmEC5gGN8gXwMyyjy/yZVMg=
|
maunium.net/go/mauview v0.0.0-20200220201003-92b19f8819b4/go.mod h1:jwg3Ow7akzsCX3q38pZAfmEC5gGN8gXwMyyjy/yZVMg=
|
||||||
|
maunium.net/go/mauview v0.0.0-20200220222850-39f1414676d9 h1:xwuAYvp2fdCNJHe4bj04BjKFRAX390gZUK21x6NoePM=
|
||||||
|
maunium.net/go/mauview v0.0.0-20200220222850-39f1414676d9/go.mod h1:jwg3Ow7akzsCX3q38pZAfmEC5gGN8gXwMyyjy/yZVMg=
|
||||||
maunium.net/go/tcell v1.1.2-0.20200218183045-87c4a25c5b09 h1:hu+R+0nodoZPS19WGyYiw/d63+/NQS/R3Duw3d9HqAU=
|
maunium.net/go/tcell v1.1.2-0.20200218183045-87c4a25c5b09 h1:hu+R+0nodoZPS19WGyYiw/d63+/NQS/R3Duw3d9HqAU=
|
||||||
maunium.net/go/tcell v1.1.2-0.20200218183045-87c4a25c5b09/go.mod h1:Ru7KmI5AU7xHUx6hGltgJvknrS+8jlGGMKK15pZuc9k=
|
maunium.net/go/tcell v1.1.2-0.20200218183045-87c4a25c5b09/go.mod h1:Ru7KmI5AU7xHUx6hGltgJvknrS+8jlGGMKK15pZuc9k=
|
||||||
|
@ -43,6 +43,7 @@ type MatrixContainer interface {
|
|||||||
LeaveRoom(roomID string) error
|
LeaveRoom(roomID string) error
|
||||||
CreateRoom(req *mautrix.ReqCreateRoom) (*rooms.Room, error)
|
CreateRoom(req *mautrix.ReqCreateRoom) (*rooms.Room, error)
|
||||||
|
|
||||||
|
FetchMembers(room *rooms.Room) error
|
||||||
GetHistory(room *rooms.Room, limit int) ([]*event.Event, error)
|
GetHistory(room *rooms.Room, limit int) ([]*event.Event, error)
|
||||||
GetEvent(room *rooms.Room, eventID string) (*event.Event, error)
|
GetEvent(room *rooms.Room, eventID string) (*event.Event, error)
|
||||||
GetRoom(roomID string) *rooms.Room
|
GetRoom(roomID string) *rooms.Room
|
||||||
|
@ -834,6 +834,18 @@ func (c *Container) LeaveRoom(roomID string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Container) FetchMembers(room *rooms.Room) error {
|
||||||
|
members, err := c.client.Members(room.ID, mautrix.ReqMembers{At: room.LastPrevBatch})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, evt := range members.Chunk {
|
||||||
|
room.UpdateState(evt)
|
||||||
|
}
|
||||||
|
room.MembersFetched = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetHistory fetches room history.
|
// GetHistory fetches room history.
|
||||||
func (c *Container) GetHistory(room *rooms.Room, limit int) ([]*event.Event, error) {
|
func (c *Container) GetHistory(room *rooms.Room, limit int) ([]*event.Event, error) {
|
||||||
events, err := c.history.Load(room, limit)
|
events, err := c.history.Load(room, limit)
|
||||||
@ -849,6 +861,9 @@ func (c *Container) GetHistory(room *rooms.Room, limit int) ([]*event.Event, err
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
debug.Printf("Loaded %d events for %s from server from %s to %s", len(resp.Chunk), room.ID, resp.Start, resp.End)
|
debug.Printf("Loaded %d events for %s from server from %s to %s", len(resp.Chunk), room.ID, resp.Start, resp.End)
|
||||||
|
for _, evt := range resp.State {
|
||||||
|
room.UpdateState(evt)
|
||||||
|
}
|
||||||
room.PrevBatch = resp.End
|
room.PrevBatch = resp.End
|
||||||
c.config.Rooms.Put(room)
|
c.config.Rooms.Put(room)
|
||||||
if len(resp.Chunk) == 0 {
|
if len(resp.Chunk) == 0 {
|
||||||
|
@ -21,7 +21,6 @@ import (
|
|||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
sync "github.com/sasha-s/go-deadlock"
|
sync "github.com/sasha-s/go-deadlock"
|
||||||
@ -41,7 +40,6 @@ type RoomNameSource int
|
|||||||
const (
|
const (
|
||||||
UnknownRoomName RoomNameSource = iota
|
UnknownRoomName RoomNameSource = iota
|
||||||
MemberRoomName
|
MemberRoomName
|
||||||
AliasRoomName
|
|
||||||
CanonicalAliasRoomName
|
CanonicalAliasRoomName
|
||||||
ExplicitRoomName
|
ExplicitRoomName
|
||||||
)
|
)
|
||||||
@ -71,6 +69,8 @@ type Room struct {
|
|||||||
// The first batch of events that has been fetched for this room.
|
// The first batch of events that has been fetched for this room.
|
||||||
// Used for fetching additional history.
|
// Used for fetching additional history.
|
||||||
PrevBatch string
|
PrevBatch string
|
||||||
|
// The last_batch field from the most recent sync. Used for fetching member lists.
|
||||||
|
LastPrevBatch string
|
||||||
// The MXID of the user whose session this room was created for.
|
// The MXID of the user whose session this room was created for.
|
||||||
SessionUserID string
|
SessionUserID string
|
||||||
SessionMember *mautrix.Member
|
SessionMember *mautrix.Member
|
||||||
@ -88,6 +88,10 @@ type Room struct {
|
|||||||
// Timestamp of previously received actual message.
|
// Timestamp of previously received actual message.
|
||||||
LastReceivedMessage time.Time
|
LastReceivedMessage time.Time
|
||||||
|
|
||||||
|
// The lazy loading summary for this room.
|
||||||
|
Summary mautrix.LazyLoadSummary
|
||||||
|
// Whether or not the members for this room have been fetched from the server.
|
||||||
|
MembersFetched bool
|
||||||
// Room state cache.
|
// Room state cache.
|
||||||
state map[mautrix.EventType]map[string]*mautrix.Event
|
state map[mautrix.EventType]map[string]*mautrix.Event
|
||||||
// MXID -> Member cache calculated from membership events.
|
// MXID -> Member cache calculated from membership events.
|
||||||
@ -106,8 +110,6 @@ type Room struct {
|
|||||||
topicCache string
|
topicCache string
|
||||||
// The canonical alias of the room. Directly fetched from the m.room.canonical_alias state event.
|
// The canonical alias of the room. Directly fetched from the m.room.canonical_alias state event.
|
||||||
CanonicalAliasCache string
|
CanonicalAliasCache string
|
||||||
// The list of aliases. Directly fetched from the m.room.aliases state event.
|
|
||||||
aliasesCache []string
|
|
||||||
// Whether or not the room has been tombstoned.
|
// Whether or not the room has been tombstoned.
|
||||||
replacedCache bool
|
replacedCache bool
|
||||||
// The room ID that replaced this room.
|
// The room ID that replaced this room.
|
||||||
@ -199,13 +201,13 @@ func (room *Room) Unload() bool {
|
|||||||
debug.Print("Unloading", room.ID)
|
debug.Print("Unloading", room.ID)
|
||||||
room.Save()
|
room.Save()
|
||||||
room.state = nil
|
room.state = nil
|
||||||
room.aliasesCache = nil
|
|
||||||
room.topicCache = ""
|
room.topicCache = ""
|
||||||
room.CanonicalAliasCache = ""
|
room.CanonicalAliasCache = ""
|
||||||
room.firstMemberCache = nil
|
room.firstMemberCache = nil
|
||||||
room.secondMemberCache = nil
|
room.secondMemberCache = nil
|
||||||
room.memberCache = nil
|
room.memberCache = nil
|
||||||
room.exMemberCache = nil
|
room.exMemberCache = nil
|
||||||
|
room.replacedByCache = nil
|
||||||
if room.postUnload != nil {
|
if room.postUnload != nil {
|
||||||
room.postUnload()
|
room.postUnload()
|
||||||
}
|
}
|
||||||
@ -343,6 +345,21 @@ func (room *Room) Tags() []RoomTag {
|
|||||||
return room.RawTags
|
return room.RawTags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (room *Room) UpdateSummary(summary mautrix.LazyLoadSummary) {
|
||||||
|
if summary.JoinedMemberCount != nil {
|
||||||
|
room.Summary.JoinedMemberCount = summary.JoinedMemberCount
|
||||||
|
}
|
||||||
|
if summary.InvitedMemberCount != nil {
|
||||||
|
room.Summary.InvitedMemberCount = summary.InvitedMemberCount
|
||||||
|
}
|
||||||
|
if summary.Heroes != nil {
|
||||||
|
room.Summary.Heroes = summary.Heroes
|
||||||
|
}
|
||||||
|
if room.nameCacheSource <= MemberRoomName {
|
||||||
|
room.NameCache = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateState updates the room's current state with the given Event. This will clobber events based
|
// UpdateState updates the room's current state with the given Event. This will clobber events based
|
||||||
// on the type/state_key combination.
|
// on the type/state_key combination.
|
||||||
func (room *Room) UpdateState(event *mautrix.Event) {
|
func (room *Room) UpdateState(event *mautrix.Event) {
|
||||||
@ -367,11 +384,6 @@ func (room *Room) UpdateState(event *mautrix.Event) {
|
|||||||
room.nameCacheSource = CanonicalAliasRoomName
|
room.nameCacheSource = CanonicalAliasRoomName
|
||||||
}
|
}
|
||||||
room.CanonicalAliasCache = event.Content.Alias
|
room.CanonicalAliasCache = event.Content.Alias
|
||||||
case mautrix.StateAliases:
|
|
||||||
if room.nameCacheSource <= AliasRoomName {
|
|
||||||
room.NameCache = ""
|
|
||||||
}
|
|
||||||
room.aliasesCache = nil
|
|
||||||
case mautrix.StateMember:
|
case mautrix.StateMember:
|
||||||
if room.nameCacheSource <= MemberRoomName {
|
if room.nameCacheSource <= MemberRoomName {
|
||||||
room.NameCache = ""
|
room.NameCache = ""
|
||||||
@ -395,7 +407,7 @@ func (room *Room) updateMemberState(event *mautrix.Event) {
|
|||||||
}
|
}
|
||||||
if room.memberCache != nil {
|
if room.memberCache != nil {
|
||||||
member := room.eventToMember(userID, &event.Content)
|
member := room.eventToMember(userID, &event.Content)
|
||||||
if event.Content.Membership.IsInviteOrJoin() {
|
if member.Membership.IsInviteOrJoin() {
|
||||||
existingMember, ok := room.memberCache[userID]
|
existingMember, ok := room.memberCache[userID]
|
||||||
if ok {
|
if ok {
|
||||||
*existingMember = *member
|
*existingMember = *member
|
||||||
@ -458,20 +470,6 @@ func (room *Room) GetCanonicalAlias() string {
|
|||||||
return room.CanonicalAliasCache
|
return room.CanonicalAliasCache
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAliases returns the list of aliases that point to this room.
|
|
||||||
func (room *Room) GetAliases() []string {
|
|
||||||
if room.aliasesCache == nil {
|
|
||||||
room.lock.RLock()
|
|
||||||
aliasEvents := room.getStateEvents(mautrix.StateAliases)
|
|
||||||
room.aliasesCache = []string{}
|
|
||||||
for _, event := range aliasEvents {
|
|
||||||
room.aliasesCache = append(room.aliasesCache, event.Content.Aliases...)
|
|
||||||
}
|
|
||||||
room.lock.RUnlock()
|
|
||||||
}
|
|
||||||
return room.aliasesCache
|
|
||||||
}
|
|
||||||
|
|
||||||
// updateNameFromNameEvent updates the room display name to be the name set in the name event.
|
// updateNameFromNameEvent updates the room display name to be the name set in the name event.
|
||||||
func (room *Room) updateNameFromNameEvent() {
|
func (room *Room) updateNameFromNameEvent() {
|
||||||
nameEvt := room.GetStateEvent(mautrix.StateRoomName, "")
|
nameEvt := room.GetStateEvent(mautrix.StateRoomName, "")
|
||||||
@ -480,19 +478,6 @@ func (room *Room) updateNameFromNameEvent() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateNameFromAliases updates the room display name to be the first room alias it finds.
|
|
||||||
//
|
|
||||||
// Deprecated: the Client-Server API recommends against using non-canonical aliases as display name.
|
|
||||||
func (room *Room) updateNameFromAliases() {
|
|
||||||
// TODO the spec says clients should not use m.room.aliases for room names.
|
|
||||||
// However, Riot also uses m.room.aliases, so this is here now.
|
|
||||||
aliases := room.GetAliases()
|
|
||||||
if len(aliases) > 0 {
|
|
||||||
sort.Sort(sort.StringSlice(aliases))
|
|
||||||
room.NameCache = aliases[0]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// updateNameFromMembers updates the room display name based on the members in this room.
|
// updateNameFromMembers updates the room display name based on the members in this room.
|
||||||
//
|
//
|
||||||
// The room name depends on the number of users:
|
// The room name depends on the number of users:
|
||||||
@ -533,10 +518,6 @@ func (room *Room) updateNameCache() {
|
|||||||
room.NameCache = room.GetCanonicalAlias()
|
room.NameCache = room.GetCanonicalAlias()
|
||||||
room.nameCacheSource = CanonicalAliasRoomName
|
room.nameCacheSource = CanonicalAliasRoomName
|
||||||
}
|
}
|
||||||
if len(room.NameCache) == 0 {
|
|
||||||
room.updateNameFromAliases()
|
|
||||||
room.nameCacheSource = AliasRoomName
|
|
||||||
}
|
|
||||||
if len(room.NameCache) == 0 {
|
if len(room.NameCache) == 0 {
|
||||||
room.updateNameFromMembers()
|
room.updateNameFromMembers()
|
||||||
room.nameCacheSource = MemberRoomName
|
room.nameCacheSource = MemberRoomName
|
||||||
@ -616,10 +597,16 @@ func (room *Room) createMemberCache() map[string]*mautrix.Member {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if len(room.Summary.Heroes) > 1 {
|
||||||
|
room.firstMemberCache, _ = cache[room.Summary.Heroes[0]]
|
||||||
|
}
|
||||||
|
if len(room.Summary.Heroes) > 2 {
|
||||||
|
room.secondMemberCache, _ = cache[room.Summary.Heroes[1]]
|
||||||
|
}
|
||||||
room.lock.RUnlock()
|
room.lock.RUnlock()
|
||||||
room.lock.Lock()
|
room.lock.Lock()
|
||||||
room.memberCache = cache
|
room.memberCache = cache
|
||||||
room.exMemberCache = cache
|
room.exMemberCache = exCache
|
||||||
room.lock.Unlock()
|
room.lock.Unlock()
|
||||||
return cache
|
return cache
|
||||||
}
|
}
|
||||||
|
@ -112,6 +112,7 @@ func (s *GomuksSyncer) ProcessResponse(res *mautrix.RespSync, since string) (err
|
|||||||
|
|
||||||
for roomID, roomData := range res.Rooms.Join {
|
for roomID, roomData := range res.Rooms.Join {
|
||||||
room := s.Session.GetRoom(roomID)
|
room := s.Session.GetRoom(roomID)
|
||||||
|
room.UpdateSummary(roomData.Summary)
|
||||||
s.processSyncEvents(room, roomData.State.Events, EventSourceJoin|EventSourceState)
|
s.processSyncEvents(room, roomData.State.Events, EventSourceJoin|EventSourceState)
|
||||||
s.processSyncEvents(room, roomData.Timeline.Events, EventSourceJoin|EventSourceTimeline)
|
s.processSyncEvents(room, roomData.Timeline.Events, EventSourceJoin|EventSourceTimeline)
|
||||||
s.processSyncEvents(room, roomData.Ephemeral.Events, EventSourceJoin|EventSourceEphemeral)
|
s.processSyncEvents(room, roomData.Ephemeral.Events, EventSourceJoin|EventSourceEphemeral)
|
||||||
@ -120,22 +121,26 @@ func (s *GomuksSyncer) ProcessResponse(res *mautrix.RespSync, since string) (err
|
|||||||
if len(room.PrevBatch) == 0 {
|
if len(room.PrevBatch) == 0 {
|
||||||
room.PrevBatch = roomData.Timeline.PrevBatch
|
room.PrevBatch = roomData.Timeline.PrevBatch
|
||||||
}
|
}
|
||||||
|
room.LastPrevBatch = roomData.Timeline.PrevBatch
|
||||||
}
|
}
|
||||||
|
|
||||||
for roomID, roomData := range res.Rooms.Invite {
|
for roomID, roomData := range res.Rooms.Invite {
|
||||||
room := s.Session.GetRoom(roomID)
|
room := s.Session.GetRoom(roomID)
|
||||||
|
room.UpdateSummary(roomData.Summary)
|
||||||
s.processSyncEvents(room, roomData.State.Events, EventSourceInvite|EventSourceState)
|
s.processSyncEvents(room, roomData.State.Events, EventSourceInvite|EventSourceState)
|
||||||
}
|
}
|
||||||
|
|
||||||
for roomID, roomData := range res.Rooms.Leave {
|
for roomID, roomData := range res.Rooms.Leave {
|
||||||
room := s.Session.GetRoom(roomID)
|
room := s.Session.GetRoom(roomID)
|
||||||
room.HasLeft = true
|
room.HasLeft = true
|
||||||
|
room.UpdateSummary(roomData.Summary)
|
||||||
s.processSyncEvents(room, roomData.State.Events, EventSourceLeave|EventSourceState)
|
s.processSyncEvents(room, roomData.State.Events, EventSourceLeave|EventSourceState)
|
||||||
s.processSyncEvents(room, roomData.Timeline.Events, EventSourceLeave|EventSourceTimeline)
|
s.processSyncEvents(room, roomData.Timeline.Events, EventSourceLeave|EventSourceTimeline)
|
||||||
|
|
||||||
if len(room.PrevBatch) == 0 {
|
if len(room.PrevBatch) == 0 {
|
||||||
room.PrevBatch = roomData.Timeline.PrevBatch
|
room.PrevBatch = roomData.Timeline.PrevBatch
|
||||||
}
|
}
|
||||||
|
room.LastPrevBatch = roomData.Timeline.PrevBatch
|
||||||
}
|
}
|
||||||
|
|
||||||
if since == "" && s.InitDoneCallback != nil {
|
if since == "" && s.InitDoneCallback != nil {
|
||||||
@ -207,6 +212,7 @@ func (s *GomuksSyncer) GetFilterJSON(userID string) json.RawMessage {
|
|||||||
Room: mautrix.RoomFilter{
|
Room: mautrix.RoomFilter{
|
||||||
IncludeLeave: false,
|
IncludeLeave: false,
|
||||||
State: mautrix.FilterPart{
|
State: mautrix.FilterPart{
|
||||||
|
LazyLoadMembers: true,
|
||||||
Types: []string{
|
Types: []string{
|
||||||
"m.room.member",
|
"m.room.member",
|
||||||
"m.room.name",
|
"m.room.name",
|
||||||
@ -218,6 +224,7 @@ func (s *GomuksSyncer) GetFilterJSON(userID string) json.RawMessage {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Timeline: mautrix.FilterPart{
|
Timeline: mautrix.FilterPart{
|
||||||
|
LazyLoadMembers: true,
|
||||||
Types: []string{
|
Types: []string{
|
||||||
"m.room.message",
|
"m.room.message",
|
||||||
"m.room.redaction",
|
"m.room.redaction",
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package ui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -40,6 +41,7 @@ func NewMemberList() *MemberList {
|
|||||||
type memberListItem struct {
|
type memberListItem struct {
|
||||||
mautrix.Member
|
mautrix.Member
|
||||||
PowerLevel int
|
PowerLevel int
|
||||||
|
Sigil rune
|
||||||
UserID string
|
UserID string
|
||||||
Color tcell.Color
|
Color tcell.Color
|
||||||
}
|
}
|
||||||
@ -64,11 +66,35 @@ func (rml roomMemberList) Swap(i, j int) {
|
|||||||
func (ml *MemberList) Update(data map[string]*mautrix.Member, levels *mautrix.PowerLevels) *MemberList {
|
func (ml *MemberList) Update(data map[string]*mautrix.Member, levels *mautrix.PowerLevels) *MemberList {
|
||||||
ml.list = make(roomMemberList, len(data))
|
ml.list = make(roomMemberList, len(data))
|
||||||
i := 0
|
i := 0
|
||||||
|
highestLevel := math.MinInt32
|
||||||
|
count := 0
|
||||||
|
for _, level := range levels.Users {
|
||||||
|
if level > highestLevel {
|
||||||
|
highestLevel = level
|
||||||
|
count = 1
|
||||||
|
} else if level == highestLevel {
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
}
|
||||||
for userID, member := range data {
|
for userID, member := range data {
|
||||||
|
level := levels.GetUserLevel(userID)
|
||||||
|
sigil := ' '
|
||||||
|
if level == highestLevel && count == 1 {
|
||||||
|
sigil = '~'
|
||||||
|
} else if level > levels.StateDefault() {
|
||||||
|
sigil = '&'
|
||||||
|
} else if level >= levels.Ban() {
|
||||||
|
sigil = '@'
|
||||||
|
} else if level >= levels.Kick() || level >= levels.Redact() {
|
||||||
|
sigil = '%'
|
||||||
|
} else if level > levels.UsersDefault {
|
||||||
|
sigil = '+'
|
||||||
|
}
|
||||||
ml.list[i] = &memberListItem{
|
ml.list[i] = &memberListItem{
|
||||||
Member: *member,
|
Member: *member,
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
PowerLevel: levels.GetUserLevel(userID),
|
PowerLevel: level,
|
||||||
|
Sigil: sigil,
|
||||||
Color: widget.GetHashColor(userID),
|
Color: widget.GetHashColor(userID),
|
||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
@ -79,17 +105,21 @@ func (ml *MemberList) Update(data map[string]*mautrix.Member, levels *mautrix.Po
|
|||||||
|
|
||||||
func (ml *MemberList) Draw(screen mauview.Screen) {
|
func (ml *MemberList) Draw(screen mauview.Screen) {
|
||||||
width, _ := screen.Size()
|
width, _ := screen.Size()
|
||||||
|
sigilStyle := tcell.StyleDefault.Background(tcell.ColorGreen).Foreground(tcell.ColorWhite)
|
||||||
for y, member := range ml.list {
|
for y, member := range ml.list {
|
||||||
|
if member.Sigil != ' ' {
|
||||||
|
screen.SetCell(0, y, sigilStyle, member.Sigil)
|
||||||
|
}
|
||||||
if member.Membership == "invite" {
|
if member.Membership == "invite" {
|
||||||
widget.WriteLineSimpleColor(screen, member.Displayname, 1, y, member.Color)
|
screen.SetCell(1, y, tcell.StyleDefault, '(')
|
||||||
screen.SetCell(0, y, tcell.StyleDefault, '(')
|
|
||||||
if sw := runewidth.StringWidth(member.Displayname); sw < width-1 {
|
if sw := runewidth.StringWidth(member.Displayname); sw < width-1 {
|
||||||
screen.SetCell(sw+1, y, tcell.StyleDefault, ')')
|
screen.SetCell(sw+1, y, tcell.StyleDefault, ')')
|
||||||
} else {
|
} else {
|
||||||
screen.SetCell(width-1, y, tcell.StyleDefault, ')')
|
screen.SetCell(width-1, y, tcell.StyleDefault, ')')
|
||||||
}
|
}
|
||||||
|
widget.WriteLineSimpleColor(screen, member.Displayname, 2, y, member.Color)
|
||||||
} else {
|
} else {
|
||||||
widget.WriteLineSimpleColor(screen, member.Displayname, 0, y, member.Color)
|
widget.WriteLineSimpleColor(screen, member.Displayname, 1, y, member.Color)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -276,6 +276,17 @@ func (view *MainView) switchRoom(tag string, room *rooms.Room, lock bool) {
|
|||||||
msgView.initialHistoryLoaded = true
|
msgView.initialHistoryLoaded = true
|
||||||
go view.LoadHistory(room.ID)
|
go view.LoadHistory(room.ID)
|
||||||
}
|
}
|
||||||
|
if !room.MembersFetched {
|
||||||
|
go func() {
|
||||||
|
err := view.matrix.FetchMembers(room)
|
||||||
|
if err != nil {
|
||||||
|
debug.Print("Error fetching members:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
roomView.UpdateUserList()
|
||||||
|
view.parent.Render()
|
||||||
|
}()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (view *MainView) addRoomPage(room *rooms.Room) *RoomView {
|
func (view *MainView) addRoomPage(room *rooms.Room) *RoomView {
|
||||||
|
Loading…
Reference in New Issue
Block a user