Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions channels.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,32 @@ func (m *Client) GetChannelTeamID(id string) string {
m.RLock()
defer m.RUnlock()

for _, t := range append(m.OtherTeams, m.Team) {
for _, channel := range append(t.Channels, t.MoreChannels...) {
if m.Team != nil {
for _, channel := range m.Team.Channels {
if channel.Id == id {
return channel.TeamId
}
}

for _, channel := range m.Team.MoreChannels {
if channel.Id == id {
return channel.TeamId
}
}
}

for _, t := range m.OtherTeams {
if m.Team != nil && t.ID == m.Team.ID {
continue
}

for _, channel := range t.Channels {
if channel.Id == id {
return channel.TeamId
}
}

for _, channel := range t.MoreChannels {
if channel.Id == id {
return channel.TeamId
}
Expand Down Expand Up @@ -207,6 +231,7 @@ func (m *Client) JoinChannel(channelID string) error {
}

func (m *Client) UpdateChannelsTeam(teamID string) error {

var (
mmchannels []*model.Channel
resp *model.Response
Expand Down
83 changes: 73 additions & 10 deletions matterclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type Team struct {
Channels []*model.Channel
MoreChannels []*model.Channel
Users map[string]*model.User
LastUserSync time.Time
}

type Message struct {
Expand All @@ -58,7 +59,7 @@ type Client struct {
*Credentials

Team *Team
OtherTeams []*Team
OtherTeams map[string]*Team
Client *model.Client4
User *model.User
Users map[string]*model.User
Expand Down Expand Up @@ -146,8 +147,8 @@ func (m *Client) Login() error {

if m.Team == nil {
validTeamNames := make([]string, len(m.OtherTeams))
for i, t := range m.OtherTeams {
validTeamNames[i] = t.Team.Name
for _, t := range m.OtherTeams {
validTeamNames = append(validTeamNames, t.Team.Name)
}

return fmt.Errorf("Team '%s' not found in %v", m.Credentials.Team, validTeamNames)
Expand Down Expand Up @@ -305,6 +306,12 @@ func (m *Client) serverAlive(b *backoff.Backoff) error {
func (m *Client) initUser() error {
ctx := context.TODO()

m.Lock()
if m.OtherTeams == nil {
m.OtherTeams = make(map[string]*Team)
}
m.Unlock()

m.Lock()
defer m.Unlock()
// we only load all team data on initial login.
Expand All @@ -315,6 +322,22 @@ func (m *Client) initUser() error {
}

for _, team := range teams {
m.Lock()
existingTeam, exists := m.OtherTeams[team.Id]
m.Unlock()

if exists && time.Since(existingTeam.LastUserSync) < 15*time.Minute {
m.logger.Debugf("skipping user fetch for team %s: cache is only %v old", team.Name, time.Since(existingTeam.LastUserSync).Round(time.Second))
m.Lock()
if team.Name == m.Credentials.Team {
m.Team = existingTeam
}
m.Unlock()
continue
}

m.logger.Debugf("fetching users for team %s (cache expired or missing)", team.Name)

idx := 0
max := 200
usermap := make(map[string]*model.User)
Expand All @@ -339,18 +362,20 @@ func (m *Client) initUser() error {
time.Sleep(time.Millisecond * 200)
}
m.logger.Debugf("found %d users in team %s", len(usermap), team.Name)

t := &Team{
Team: team,
Users: usermap,
ID: team.Id,
LastUserSync: time.Now(),
}

// add all users
for k, v := range usermap {
m.Users[k] = v
}

t := &Team{
Team: team,
Users: usermap,
ID: team.Id,
}

m.OtherTeams = append(m.OtherTeams, t)
m.OtherTeams[team.Id] = t

if team.Name == m.Credentials.Team {
m.Team = t
Expand Down Expand Up @@ -622,6 +647,11 @@ func (m *Client) WsReceiver(ctx context.Context) {

m.logger.Debugf("WsReceiver event: %#v", event)

eventType := event.EventType()
if eventType == model.WebsocketEventNewUser || eventType == model.WebsocketEventUserUpdated {
go m.syncSingleUser(ctx, event)
}

msg := &Message{
Raw: event,
Team: m.Credentials.Team,
Expand Down Expand Up @@ -761,3 +791,36 @@ func (m *Client) antiIdle(ctx context.Context, channelID string, interval int) {
}
}
}

func (m *Client) syncSingleUser(ctx context.Context, event *model.WebSocketEvent) {
userID, ok := event.GetData()["user_id"].(string)
if !ok {
return
}

user, _, err := m.Client.GetUser(ctx, userID, "")
if err != nil {
m.logger.Errorf("syncSingleUser failed to get user %s: %v", userID, err)
return
}

m.logger.Debugf("dynamically caching updated/new user: %s", user.Username)

m.Lock()
defer m.Unlock()

if m.Users == nil {
m.Users = make(map[string]*model.User)
}
m.Users[user.Id] = user

if teamID, hasTeam := event.GetData()["team_id"].(string); hasTeam {
if team, exists := m.OtherTeams[teamID]; exists {
if team.Users == nil {
team.Users = make(map[string]*model.User)
}
team.Users[user.Id] = user
m.logger.Debugf("added/updated user %s in map for team %s", user.Username, team.Team.Name)
}
}
}