mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
PLT-4430 improve slow channel switching (#4331)
* PLT-4430 improve slow channel switching * Update client side unit tests * Convert getChannelsUnread to getMyChannelMembers and address other feedback * Pull channel members on websocket reconnect
This commit is contained in:
@@ -21,6 +21,7 @@ func InitChannel() {
|
||||
BaseRoutes.Channels.Handle("/", ApiUserRequired(getChannels)).Methods("GET")
|
||||
BaseRoutes.Channels.Handle("/more", ApiUserRequired(getMoreChannels)).Methods("GET")
|
||||
BaseRoutes.Channels.Handle("/counts", ApiUserRequired(getChannelCounts)).Methods("GET")
|
||||
BaseRoutes.Channels.Handle("/members", ApiUserRequired(getMyChannelMembers)).Methods("GET")
|
||||
BaseRoutes.Channels.Handle("/create", ApiUserRequired(createChannel)).Methods("POST")
|
||||
BaseRoutes.Channels.Handle("/create_direct", ApiUserRequired(createDirectChannel)).Methods("POST")
|
||||
BaseRoutes.Channels.Handle("/update", ApiUserRequired(updateChannel)).Methods("POST")
|
||||
@@ -81,7 +82,7 @@ func createChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
} else {
|
||||
data := result.Data.(*model.ChannelList)
|
||||
if int64(len(data.Channels)+1) > *utils.Cfg.TeamSettings.MaxChannelsPerTeam {
|
||||
if int64(len(*data)+1) > *utils.Cfg.TeamSettings.MaxChannelsPerTeam {
|
||||
c.Err = model.NewLocAppError("createChannel", "api.channel.create_channel.max_channel_limit.app_error", map[string]interface{}{"MaxChannelsPerTeam": *utils.Cfg.TeamSettings.MaxChannelsPerTeam}, "")
|
||||
return
|
||||
}
|
||||
@@ -987,6 +988,16 @@ func getChannelMember(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
func getMyChannelMembers(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if result := <-Srv.Store.Channel().GetMembersForUser(c.TeamId, c.Session.UserId); result.Err != nil {
|
||||
c.Err = result.Err
|
||||
return
|
||||
} else {
|
||||
data := result.Data.(*model.ChannelMembers)
|
||||
w.Write([]byte(data.ToJson()))
|
||||
}
|
||||
}
|
||||
|
||||
func addMember(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
params := mux.Vars(r)
|
||||
id := params["channel_id"]
|
||||
|
||||
@@ -35,7 +35,7 @@ func TestCreateChannel(t *testing.T) {
|
||||
|
||||
rget := Client.Must(Client.GetChannels("")).Data.(*model.ChannelList)
|
||||
nameMatch := false
|
||||
for _, c := range rget.Channels {
|
||||
for _, c := range *rget {
|
||||
if c.Name == channel.Name {
|
||||
nameMatch = true
|
||||
}
|
||||
@@ -240,8 +240,8 @@ func TestUpdateChannel(t *testing.T) {
|
||||
}
|
||||
|
||||
rget := Client.Must(Client.GetChannels(""))
|
||||
data := rget.Data.(*model.ChannelList)
|
||||
for _, c := range data.Channels {
|
||||
channels := rget.Data.(*model.ChannelList)
|
||||
for _, c := range *channels {
|
||||
if c.Name == model.DEFAULT_CHANNEL {
|
||||
c.Header = "new header"
|
||||
c.Name = "pseudo-square"
|
||||
@@ -654,13 +654,13 @@ func TestGetChannel(t *testing.T) {
|
||||
channel2 = Client.Must(Client.CreateChannel(channel2)).Data.(*model.Channel)
|
||||
|
||||
rget := Client.Must(Client.GetChannels(""))
|
||||
data := rget.Data.(*model.ChannelList)
|
||||
channels := rget.Data.(*model.ChannelList)
|
||||
|
||||
if data.Channels[0].DisplayName != channel1.DisplayName {
|
||||
if (*channels)[0].DisplayName != channel1.DisplayName {
|
||||
t.Fatal("full name didn't match")
|
||||
}
|
||||
|
||||
if data.Channels[1].DisplayName != channel2.DisplayName {
|
||||
if (*channels)[1].DisplayName != channel2.DisplayName {
|
||||
t.Fatal("full name didn't match")
|
||||
}
|
||||
|
||||
@@ -717,13 +717,13 @@ func TestGetMoreChannel(t *testing.T) {
|
||||
th.LoginBasic2()
|
||||
|
||||
rget := Client.Must(Client.GetMoreChannels(""))
|
||||
data := rget.Data.(*model.ChannelList)
|
||||
channels := rget.Data.(*model.ChannelList)
|
||||
|
||||
if data.Channels[0].DisplayName != channel1.DisplayName {
|
||||
if (*channels)[0].DisplayName != channel1.DisplayName {
|
||||
t.Fatal("full name didn't match")
|
||||
}
|
||||
|
||||
if data.Channels[1].DisplayName != channel2.DisplayName {
|
||||
if (*channels)[1].DisplayName != channel2.DisplayName {
|
||||
t.Fatal("full name didn't match")
|
||||
}
|
||||
|
||||
@@ -770,6 +770,30 @@ func TestGetChannelCounts(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestGetMyChannelMembers(t *testing.T) {
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
team := th.BasicTeam
|
||||
|
||||
channel1 := &model.Channel{DisplayName: "A Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
|
||||
|
||||
channel2 := &model.Channel{DisplayName: "B Test API Name", Name: "a" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
|
||||
channel2 = Client.Must(Client.CreateChannel(channel2)).Data.(*model.Channel)
|
||||
|
||||
if result, err := Client.GetMyChannelMembers(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
members := result.Data.(*model.ChannelMembers)
|
||||
|
||||
// town-square, off-topic, basic test channel, channel1, channel2
|
||||
if len(*members) != 5 {
|
||||
t.Fatal("wrong number of members", len(*members))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestJoinChannelById(t *testing.T) {
|
||||
th := Setup().InitBasic()
|
||||
Client := th.BasicClient
|
||||
@@ -905,7 +929,7 @@ func TestLeaveChannel(t *testing.T) {
|
||||
|
||||
rget := Client.Must(Client.GetChannels(""))
|
||||
cdata := rget.Data.(*model.ChannelList)
|
||||
for _, c := range cdata.Channels {
|
||||
for _, c := range *cdata {
|
||||
if c.Name == model.DEFAULT_CHANNEL {
|
||||
if _, err := Client.LeaveChannel(c.Id); err == nil {
|
||||
t.Fatal("should have errored on leaving default channel")
|
||||
@@ -969,7 +993,7 @@ func TestDeleteChannel(t *testing.T) {
|
||||
|
||||
rget := Client.Must(Client.GetChannels(""))
|
||||
cdata := rget.Data.(*model.ChannelList)
|
||||
for _, c := range cdata.Channels {
|
||||
for _, c := range *cdata {
|
||||
if c.Name == model.DEFAULT_CHANNEL {
|
||||
if _, err := Client.DeleteChannel(c.Id); err == nil {
|
||||
t.Fatal("should have errored on deleting default channel")
|
||||
@@ -1249,7 +1273,7 @@ func TestUpdateNotifyProps(t *testing.T) {
|
||||
data["user_id"] = user.Id
|
||||
data["desktop"] = model.CHANNEL_NOTIFY_MENTION
|
||||
|
||||
timeBeforeUpdate := model.GetMillis()
|
||||
//timeBeforeUpdate := model.GetMillis()
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
// test updating desktop
|
||||
@@ -1261,14 +1285,6 @@ func TestUpdateNotifyProps(t *testing.T) {
|
||||
t.Fatalf("NotifyProps[\"mark_unread\"] changed to %v", notifyProps["mark_unread"])
|
||||
}
|
||||
|
||||
rget := Client.Must(Client.GetChannels(""))
|
||||
rdata := rget.Data.(*model.ChannelList)
|
||||
if len(rdata.Members) == 0 || rdata.Members[channel1.Id].NotifyProps["desktop"] != data["desktop"] {
|
||||
t.Fatal("NotifyProps[\"desktop\"] did not update properly")
|
||||
} else if rdata.Members[channel1.Id].LastUpdateAt <= timeBeforeUpdate {
|
||||
t.Fatal("LastUpdateAt did not update")
|
||||
}
|
||||
|
||||
// test an empty update
|
||||
delete(data, "desktop")
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ func (me *JoinProvider) DoCommand(c *Context, channelId string, message string)
|
||||
} else {
|
||||
channels := result.Data.(*model.ChannelList)
|
||||
|
||||
for _, v := range channels.Channels {
|
||||
for _, v := range *channels {
|
||||
|
||||
if v.Name == message {
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ func TestJoinCommands(t *testing.T) {
|
||||
c1 := Client.Must(Client.GetChannels("")).Data.(*model.ChannelList)
|
||||
|
||||
found := false
|
||||
for _, c := range c1.Channels {
|
||||
for _, c := range *c1 {
|
||||
if c.Id == channel2.Id {
|
||||
found = true
|
||||
}
|
||||
|
||||
@@ -325,20 +325,20 @@ func LeaveTeam(team *model.Team, user *model.User) *model.AppError {
|
||||
teamMember = result.Data.(model.TeamMember)
|
||||
}
|
||||
|
||||
var channelMembers *model.ChannelList
|
||||
var channelList *model.ChannelList
|
||||
|
||||
if result := <-Srv.Store.Channel().GetChannels(team.Id, user.Id); result.Err != nil {
|
||||
if result.Err.Id == "store.sql_channel.get_channels.not_found.app_error" {
|
||||
channelMembers = &model.ChannelList{make([]*model.Channel, 0), make(map[string]*model.ChannelMember)}
|
||||
channelList = &model.ChannelList{}
|
||||
} else {
|
||||
return result.Err
|
||||
}
|
||||
|
||||
} else {
|
||||
channelMembers = result.Data.(*model.ChannelList)
|
||||
channelList = result.Data.(*model.ChannelList)
|
||||
}
|
||||
|
||||
for _, channel := range channelMembers.Channels {
|
||||
for _, channel := range *channelList {
|
||||
if channel.Type != model.CHANNEL_DIRECT {
|
||||
Srv.Store.User().InvalidateProfilesInChannelCache(channel.Id)
|
||||
if result := <-Srv.Store.Channel().RemoveMember(channel.Id, user.Id); result.Err != nil {
|
||||
|
||||
@@ -63,7 +63,7 @@ func TestCreateFromSignupTeam(t *testing.T) {
|
||||
}
|
||||
|
||||
c1 := Client.Must(Client.GetChannels("")).Data.(*model.ChannelList)
|
||||
if len(c1.Channels) != 2 {
|
||||
if len(*c1) != 2 {
|
||||
t.Fatal("default channels not created")
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ func TestCreateTeam(t *testing.T) {
|
||||
Client.SetTeamId(rteam.Data.(*model.Team).Id)
|
||||
|
||||
c1 := Client.Must(Client.GetChannels("")).Data.(*model.ChannelList)
|
||||
if len(c1.Channels) != 2 {
|
||||
if len(*c1) != 2 {
|
||||
t.Fatal("default channels not created")
|
||||
}
|
||||
|
||||
|
||||
@@ -159,13 +159,13 @@ func getChannelID(channelname string, teamid string, userid string) (id string,
|
||||
return "", false
|
||||
}
|
||||
|
||||
data := result.Data.(*model.ChannelList)
|
||||
data := result.Data.(model.ChannelList)
|
||||
|
||||
for _, channel := range data.Channels {
|
||||
for _, channel := range data {
|
||||
if channel.Name == channelname {
|
||||
return channel.Id, true
|
||||
}
|
||||
}
|
||||
l4g.Debug(utils.T("manaultesting.get_channel_id.no_found.debug"), channelname, strconv.Itoa(len(data.Channels)))
|
||||
l4g.Debug(utils.T("manaultesting.get_channel_id.no_found.debug"), channelname, strconv.Itoa(len(data)))
|
||||
return "", false
|
||||
}
|
||||
|
||||
@@ -8,15 +8,11 @@ import (
|
||||
"io"
|
||||
)
|
||||
|
||||
type ChannelList struct {
|
||||
Channels []*Channel `json:"channels"`
|
||||
Members map[string]*ChannelMember `json:"members"`
|
||||
}
|
||||
type ChannelList []*Channel
|
||||
|
||||
func (o *ChannelList) ToJson() string {
|
||||
b, err := json.Marshal(o)
|
||||
if err != nil {
|
||||
return ""
|
||||
if b, err := json.Marshal(o); err != nil {
|
||||
return "[]"
|
||||
} else {
|
||||
return string(b)
|
||||
}
|
||||
@@ -28,7 +24,7 @@ func (o *ChannelList) Etag() string {
|
||||
var t int64 = 0
|
||||
var delta int64 = 0
|
||||
|
||||
for _, v := range o.Channels {
|
||||
for _, v := range *o {
|
||||
if v.LastPostAt > t {
|
||||
t = v.LastPostAt
|
||||
id = v.Id
|
||||
@@ -39,30 +35,9 @@ func (o *ChannelList) Etag() string {
|
||||
id = v.Id
|
||||
}
|
||||
|
||||
member := o.Members[v.Id]
|
||||
|
||||
if member != nil {
|
||||
max := v.LastPostAt
|
||||
if v.UpdateAt > max {
|
||||
max = v.UpdateAt
|
||||
}
|
||||
|
||||
delta += max - member.LastViewedAt
|
||||
|
||||
if member.LastViewedAt > t {
|
||||
t = member.LastViewedAt
|
||||
id = v.Id
|
||||
}
|
||||
|
||||
if member.LastUpdateAt > t {
|
||||
t = member.LastUpdateAt
|
||||
id = v.Id
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return Etag(id, t, delta, len(o.Channels))
|
||||
return Etag(id, t, delta, len(*o))
|
||||
}
|
||||
|
||||
func ChannelListFromJson(data io.Reader) *ChannelList {
|
||||
|
||||
@@ -29,6 +29,27 @@ type ChannelMember struct {
|
||||
LastUpdateAt int64 `json:"last_update_at"`
|
||||
}
|
||||
|
||||
type ChannelMembers []ChannelMember
|
||||
|
||||
func (o *ChannelMembers) ToJson() string {
|
||||
if b, err := json.Marshal(o); err != nil {
|
||||
return "[]"
|
||||
} else {
|
||||
return string(b)
|
||||
}
|
||||
}
|
||||
|
||||
func ChannelMembersFromJson(data io.Reader) *ChannelMembers {
|
||||
decoder := json.NewDecoder(data)
|
||||
var o ChannelMembers
|
||||
err := decoder.Decode(&o)
|
||||
if err == nil {
|
||||
return &o
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (o *ChannelMember) ToJson() string {
|
||||
b, err := json.Marshal(o)
|
||||
if err != nil {
|
||||
|
||||
@@ -1124,13 +1124,13 @@ func (c *Client) UpdateNotifyProps(data map[string]string) (*Result, *AppError)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) GetChannels(etag string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet(c.GetTeamRoute()+"/channels/", "", etag); err != nil {
|
||||
func (c *Client) GetMyChannelMembers() (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet(c.GetTeamRoute()+"/channels/members", "", ""); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
defer closeBody(r)
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
r.Header.Get(HEADER_ETAG_SERVER), ChannelListFromJson(r.Body)}, nil
|
||||
r.Header.Get(HEADER_ETAG_SERVER), ChannelMembersFromJson(r.Body)}, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1164,6 +1164,16 @@ func (c *Client) GetChannelCounts(etag string) (*Result, *AppError) {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) GetChannels(etag string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiGet(c.GetTeamRoute()+"/channels/", "", etag); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
defer closeBody(r)
|
||||
return &Result{r.Header.Get(HEADER_REQUEST_ID),
|
||||
r.Header.Get(HEADER_ETAG_SERVER), ChannelListFromJson(r.Body)}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) JoinChannel(id string) (*Result, *AppError) {
|
||||
if r, err := c.DoApiPost(c.GetChannelRoute(id)+"/join", ""); err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -367,23 +367,16 @@ func (s SqlChannelStore) GetChannels(teamId string, userId string) StoreChannel
|
||||
go func() {
|
||||
result := StoreResult{}
|
||||
|
||||
var data []channelWithMember
|
||||
_, err := s.GetReplica().Select(&data, "SELECT * FROM Channels, ChannelMembers WHERE Id = ChannelId AND UserId = :UserId AND DeleteAt = 0 AND (TeamId = :TeamId OR TeamId = '') ORDER BY DisplayName", map[string]interface{}{"TeamId": teamId, "UserId": userId})
|
||||
data := &model.ChannelList{}
|
||||
_, err := s.GetReplica().Select(data, "SELECT Channels.* FROM Channels, ChannelMembers WHERE Id = ChannelId AND UserId = :UserId AND DeleteAt = 0 AND (TeamId = :TeamId OR TeamId = '') ORDER BY DisplayName", map[string]interface{}{"TeamId": teamId, "UserId": userId})
|
||||
|
||||
if err != nil {
|
||||
result.Err = model.NewLocAppError("SqlChannelStore.GetChannels", "store.sql_channel.get_channels.get.app_error", nil, "teamId="+teamId+", userId="+userId+", err="+err.Error())
|
||||
} else {
|
||||
channels := &model.ChannelList{make([]*model.Channel, len(data)), make(map[string]*model.ChannelMember)}
|
||||
for i := range data {
|
||||
v := data[i]
|
||||
channels.Channels[i] = &v.Channel
|
||||
channels.Members[v.Channel.Id] = &v.ChannelMember
|
||||
}
|
||||
|
||||
if len(channels.Channels) == 0 {
|
||||
if len(*data) == 0 {
|
||||
result.Err = model.NewLocAppError("SqlChannelStore.GetChannels", "store.sql_channel.get_channels.not_found.app_error", nil, "teamId="+teamId+", userId="+userId)
|
||||
} else {
|
||||
result.Data = channels
|
||||
result.Data = data
|
||||
}
|
||||
}
|
||||
|
||||
@@ -400,8 +393,8 @@ func (s SqlChannelStore) GetMoreChannels(teamId string, userId string) StoreChan
|
||||
go func() {
|
||||
result := StoreResult{}
|
||||
|
||||
var data []*model.Channel
|
||||
_, err := s.GetReplica().Select(&data,
|
||||
data := &model.ChannelList{}
|
||||
_, err := s.GetReplica().Select(data,
|
||||
`SELECT
|
||||
*
|
||||
FROM
|
||||
@@ -426,7 +419,7 @@ func (s SqlChannelStore) GetMoreChannels(teamId string, userId string) StoreChan
|
||||
if err != nil {
|
||||
result.Err = model.NewLocAppError("SqlChannelStore.GetMoreChannels", "store.sql_channel.get_more_channels.get.app_error", nil, "teamId="+teamId+", userId="+userId+", err="+err.Error())
|
||||
} else {
|
||||
result.Data = &model.ChannelList{data, make(map[string]*model.ChannelMember)}
|
||||
result.Data = data
|
||||
}
|
||||
|
||||
storeChannel <- result
|
||||
@@ -918,11 +911,12 @@ func (s SqlChannelStore) IncrementMentionCount(channelId string, userId string)
|
||||
`UPDATE
|
||||
ChannelMembers
|
||||
SET
|
||||
MentionCount = MentionCount + 1
|
||||
MentionCount = MentionCount + 1,
|
||||
LastUpdateAt = :LastUpdateAt
|
||||
WHERE
|
||||
UserId = :UserId
|
||||
AND ChannelId = :ChannelId`,
|
||||
map[string]interface{}{"ChannelId": channelId, "UserId": userId})
|
||||
map[string]interface{}{"ChannelId": channelId, "UserId": userId, "LastUpdateAt": model.GetMillis()})
|
||||
if err != nil {
|
||||
result.Err = model.NewLocAppError("SqlChannelStore.IncrementMentionCount", "store.sql_channel.increment_mention_count.app_error", nil, "channel_id="+channelId+", user_id="+userId+", "+err.Error())
|
||||
}
|
||||
@@ -1032,3 +1026,32 @@ func (s SqlChannelStore) ExtraUpdateByUser(userId string, time int64) StoreChann
|
||||
|
||||
return storeChannel
|
||||
}
|
||||
|
||||
func (s SqlChannelStore) GetMembersForUser(teamId string, userId string) StoreChannel {
|
||||
storeChannel := make(StoreChannel, 1)
|
||||
|
||||
go func() {
|
||||
result := StoreResult{}
|
||||
|
||||
members := &model.ChannelMembers{}
|
||||
_, err := s.GetReplica().Select(members, `
|
||||
SELECT cm.*
|
||||
FROM ChannelMembers cm
|
||||
INNER JOIN Channels c
|
||||
ON c.Id = cm.ChannelId
|
||||
AND c.TeamId = :TeamId
|
||||
WHERE cm.UserId = :UserId
|
||||
`, map[string]interface{}{"TeamId": teamId, "UserId": userId})
|
||||
|
||||
if err != nil {
|
||||
result.Err = model.NewLocAppError("SqlChannelStore.GetMembersForUser", "store.sql_channel.get_members.app_error", nil, "teamId="+teamId+", userId="+userId+", err="+err.Error())
|
||||
} else {
|
||||
result.Data = members
|
||||
}
|
||||
|
||||
storeChannel <- result
|
||||
close(storeChannel)
|
||||
}()
|
||||
|
||||
return storeChannel
|
||||
}
|
||||
|
||||
@@ -305,14 +305,14 @@ func TestChannelStoreDelete(t *testing.T) {
|
||||
cresult := <-store.Channel().GetChannels(o1.TeamId, m1.UserId)
|
||||
list := cresult.Data.(*model.ChannelList)
|
||||
|
||||
if len(list.Channels) != 1 {
|
||||
if len(*list) != 1 {
|
||||
t.Fatal("invalid number of channels")
|
||||
}
|
||||
|
||||
cresult = <-store.Channel().GetMoreChannels(o1.TeamId, m1.UserId)
|
||||
list = cresult.Data.(*model.ChannelList)
|
||||
|
||||
if len(list.Channels) != 1 {
|
||||
if len(*list) != 1 {
|
||||
t.Fatal("invalid number of channels")
|
||||
}
|
||||
}
|
||||
@@ -514,7 +514,7 @@ func TestChannelStoreGetChannels(t *testing.T) {
|
||||
cresult := <-store.Channel().GetChannels(o1.TeamId, m1.UserId)
|
||||
list := cresult.Data.(*model.ChannelList)
|
||||
|
||||
if list.Channels[0].Id != o1.Id {
|
||||
if (*list)[0].Id != o1.Id {
|
||||
t.Fatal("missing channel")
|
||||
}
|
||||
|
||||
@@ -614,11 +614,11 @@ func TestChannelStoreGetMoreChannels(t *testing.T) {
|
||||
cresult := <-store.Channel().GetMoreChannels(o1.TeamId, m1.UserId)
|
||||
list := cresult.Data.(*model.ChannelList)
|
||||
|
||||
if len(list.Channels) != 1 {
|
||||
if len(*list) != 1 {
|
||||
t.Fatal("wrong list")
|
||||
}
|
||||
|
||||
if list.Channels[0].Name != o3.Name {
|
||||
if (*list)[0].Name != o3.Name {
|
||||
t.Fatal("missing channel")
|
||||
}
|
||||
|
||||
@@ -688,6 +688,51 @@ func TestChannelStoreGetChannelCounts(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestChannelStoreGetMembersForUser(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
t1 := model.Team{}
|
||||
t1.DisplayName = "Name"
|
||||
t1.Name = model.NewId()
|
||||
t1.Email = model.NewId() + "@nowhere.com"
|
||||
t1.Type = model.TEAM_OPEN
|
||||
Must(store.Team().Save(&t1))
|
||||
|
||||
o1 := model.Channel{}
|
||||
o1.TeamId = t1.Id
|
||||
o1.DisplayName = "Channel1"
|
||||
o1.Name = "a" + model.NewId() + "b"
|
||||
o1.Type = model.CHANNEL_OPEN
|
||||
Must(store.Channel().Save(&o1))
|
||||
|
||||
o2 := model.Channel{}
|
||||
o2.TeamId = o1.TeamId
|
||||
o2.DisplayName = "Channel2"
|
||||
o2.Name = "a" + model.NewId() + "b"
|
||||
o2.Type = model.CHANNEL_OPEN
|
||||
Must(store.Channel().Save(&o2))
|
||||
|
||||
m1 := model.ChannelMember{}
|
||||
m1.ChannelId = o1.Id
|
||||
m1.UserId = model.NewId()
|
||||
m1.NotifyProps = model.GetDefaultChannelNotifyProps()
|
||||
Must(store.Channel().SaveMember(&m1))
|
||||
|
||||
m2 := model.ChannelMember{}
|
||||
m2.ChannelId = o2.Id
|
||||
m2.UserId = m1.UserId
|
||||
m2.NotifyProps = model.GetDefaultChannelNotifyProps()
|
||||
Must(store.Channel().SaveMember(&m2))
|
||||
|
||||
cresult := <-store.Channel().GetMembersForUser(o1.TeamId, m1.UserId)
|
||||
members := cresult.Data.(*model.ChannelMembers)
|
||||
|
||||
// no unread messages
|
||||
if len(*members) != 2 {
|
||||
t.Fatal("wrong number of members")
|
||||
}
|
||||
}
|
||||
|
||||
func TestChannelStoreUpdateLastViewedAt(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
|
||||
@@ -109,6 +109,7 @@ type ChannelStore interface {
|
||||
IncrementMentionCount(channelId string, userId string) StoreChannel
|
||||
AnalyticsTypeCount(teamId string, channelType string) StoreChannel
|
||||
ExtraUpdateByUser(userId string, time int64) StoreChannel
|
||||
GetMembersForUser(teamId string, userId string) StoreChannel
|
||||
}
|
||||
|
||||
type PostStore interface {
|
||||
|
||||
@@ -42,8 +42,6 @@ export function emitChannelClickEvent(channel) {
|
||||
);
|
||||
}
|
||||
function switchToChannel(chan) {
|
||||
AsyncClient.getChannels(true);
|
||||
AsyncClient.getMoreChannels(true);
|
||||
AsyncClient.getChannelStats(chan.id);
|
||||
AsyncClient.updateLastViewedAt(chan.id);
|
||||
loadPosts(chan.id);
|
||||
@@ -436,10 +434,6 @@ export function loadDefaultLocale() {
|
||||
}
|
||||
|
||||
export function viewLoggedIn() {
|
||||
AsyncClient.getChannels();
|
||||
AsyncClient.getMoreChannels();
|
||||
AsyncClient.getChannelStats();
|
||||
|
||||
// Clear pending posts (shouldn't have pending posts if we are loading)
|
||||
PostStore.clearPendingPosts();
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ export function setUnreadPost(channelId, postId) {
|
||||
member.msg_count = channel.total_msg_count - unreadPosts;
|
||||
member.mention_count = 0;
|
||||
ChannelStore.storeMyChannelMember(member);
|
||||
ChannelStore.setUnreadCount(channelId);
|
||||
ChannelStore.setUnreadCountByChannel(channelId);
|
||||
AsyncClient.setLastViewedAt(lastViewed, channelId);
|
||||
}
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ function handleFirstConnect() {
|
||||
function handleReconnect() {
|
||||
if (Client.teamId) {
|
||||
AsyncClient.getChannels();
|
||||
AsyncClient.getMyChannelMembers();
|
||||
loadPosts(ChannelStore.getCurrentId());
|
||||
}
|
||||
|
||||
|
||||
@@ -1357,6 +1357,15 @@ export default class Client {
|
||||
end(this.handleResponse.bind(this, 'getChannelCounts', success, error));
|
||||
}
|
||||
|
||||
getMyChannelMembers(success, error) {
|
||||
request.
|
||||
get(`${this.getChannelsRoute()}/members`).
|
||||
set(this.defaultHeaders).
|
||||
type('application/json').
|
||||
accept('application/json').
|
||||
end(this.handleResponse.bind(this, 'getMyChannelMembers', success, error));
|
||||
}
|
||||
|
||||
getChannelStats(channelId, success, error) {
|
||||
request.
|
||||
get(`${this.getChannelNeededRoute(channelId)}/stats`).
|
||||
|
||||
@@ -75,10 +75,11 @@ function preNeedsTeam(nextState, replace, callback) {
|
||||
(data) => {
|
||||
AppDispatcher.handleServerAction({
|
||||
type: ActionTypes.RECEIVED_CHANNELS,
|
||||
channels: data.channels,
|
||||
members: data.members
|
||||
channels: data
|
||||
});
|
||||
|
||||
AsyncClient.getMyChannelMembers();
|
||||
|
||||
d1.resolve();
|
||||
},
|
||||
(err) => {
|
||||
|
||||
@@ -156,7 +156,7 @@ class ChannelStoreClass extends EventEmitter {
|
||||
if (c) {
|
||||
cm[cmid].msg_count = this.get(id).total_msg_count;
|
||||
cm[cmid].mention_count = 0;
|
||||
this.setUnreadCount(id);
|
||||
this.setUnreadCountByChannel(id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -250,6 +250,12 @@ class ChannelStoreClass extends EventEmitter {
|
||||
this.myChannelMembers = channelMembers;
|
||||
}
|
||||
|
||||
storeMyChannelMembersList(channelMembers) {
|
||||
channelMembers.forEach((m) => {
|
||||
this.myChannelMembers[m.channel_id] = m;
|
||||
});
|
||||
}
|
||||
|
||||
getMyMembers() {
|
||||
return this.myChannelMembers;
|
||||
}
|
||||
@@ -278,7 +284,13 @@ class ChannelStoreClass extends EventEmitter {
|
||||
return this.postMode;
|
||||
}
|
||||
|
||||
setUnreadCount(id) {
|
||||
setUnreadCountsByMembers(members) {
|
||||
members.forEach((m) => {
|
||||
this.setUnreadCountByChannel(m.channel_id);
|
||||
});
|
||||
}
|
||||
|
||||
setUnreadCountByChannel(id) {
|
||||
const ch = this.get(id);
|
||||
const chMember = this.getMyMember(id);
|
||||
|
||||
@@ -292,13 +304,6 @@ class ChannelStoreClass extends EventEmitter {
|
||||
this.unreadCounts[id] = {msgs: chUnreadCount, mentions: chMentionCount};
|
||||
}
|
||||
|
||||
setUnreadCounts() {
|
||||
const channels = this.getAll();
|
||||
channels.forEach((ch) => {
|
||||
this.setUnreadCount(ch.id);
|
||||
});
|
||||
}
|
||||
|
||||
getUnreadCount(id) {
|
||||
return this.unreadCounts[id] || {msgs: 0, mentions: 0};
|
||||
}
|
||||
@@ -362,12 +367,6 @@ ChannelStore.dispatchToken = AppDispatcher.register((payload) => {
|
||||
|
||||
case ActionTypes.RECEIVED_CHANNELS:
|
||||
ChannelStore.storeChannels(action.channels);
|
||||
ChannelStore.storeMyChannelMembers(action.members);
|
||||
currentId = ChannelStore.getCurrentId();
|
||||
if (currentId && window.isActive) {
|
||||
ChannelStore.resetCounts(currentId);
|
||||
}
|
||||
ChannelStore.setUnreadCounts();
|
||||
ChannelStore.emitChange();
|
||||
break;
|
||||
|
||||
@@ -380,10 +379,18 @@ ChannelStore.dispatchToken = AppDispatcher.register((payload) => {
|
||||
if (currentId && window.isActive) {
|
||||
ChannelStore.resetCounts(currentId);
|
||||
}
|
||||
ChannelStore.setUnreadCount(action.channel.id);
|
||||
ChannelStore.setUnreadCountByChannel(action.channel.id);
|
||||
ChannelStore.emitChange();
|
||||
break;
|
||||
|
||||
case ActionTypes.RECEIVED_MY_CHANNEL_MEMBERS:
|
||||
ChannelStore.storeMyChannelMembersList(action.members);
|
||||
currentId = ChannelStore.getCurrentId();
|
||||
if (currentId && window.isActive) {
|
||||
ChannelStore.resetCounts(currentId);
|
||||
}
|
||||
ChannelStore.setUnreadCountsByMembers(action.members);
|
||||
break;
|
||||
case ActionTypes.RECEIVED_MORE_CHANNELS:
|
||||
ChannelStore.storeMoreChannels(action.channels);
|
||||
ChannelStore.emitMoreChange();
|
||||
|
||||
@@ -232,7 +232,7 @@ describe('Client.Channels', function() {
|
||||
TestHelper.initBasic(() => {
|
||||
TestHelper.basicClient().getChannels(
|
||||
function(data) {
|
||||
assert.equal(data.channels.length, 3);
|
||||
assert.equal(data.length, 3);
|
||||
done();
|
||||
},
|
||||
function(err) {
|
||||
@@ -261,7 +261,7 @@ describe('Client.Channels', function() {
|
||||
TestHelper.initBasic(() => {
|
||||
TestHelper.basicClient().getMoreChannels(
|
||||
function(data) {
|
||||
assert.equal(data.channels.length, 0);
|
||||
assert.equal(data.length, 0);
|
||||
done();
|
||||
},
|
||||
function(err) {
|
||||
@@ -285,6 +285,20 @@ describe('Client.Channels', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('getMyChannelMembers', function(done) {
|
||||
TestHelper.initBasic(() => {
|
||||
TestHelper.basicClient().getMyChannelMembers(
|
||||
function(data) {
|
||||
assert.equal(data.length > 0, true);
|
||||
done();
|
||||
},
|
||||
function(err) {
|
||||
done(new Error(err.message));
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('getChannelStats', function(done) {
|
||||
TestHelper.initBasic(() => {
|
||||
TestHelper.basicClient().getChannelStats(
|
||||
|
||||
@@ -80,8 +80,7 @@ export function getChannels(doVersionCheck) {
|
||||
|
||||
AppDispatcher.handleServerAction({
|
||||
type: ActionTypes.RECEIVED_CHANNELS,
|
||||
channels: data.channels,
|
||||
members: data.members
|
||||
channels: data
|
||||
});
|
||||
},
|
||||
(err) => {
|
||||
@@ -115,6 +114,33 @@ export function getChannel(id) {
|
||||
);
|
||||
}
|
||||
|
||||
export function getMyChannelMembers(doVersionCheck) {
|
||||
if (isCallInProgress('getMyChannelMembers')) {
|
||||
return;
|
||||
}
|
||||
|
||||
callTracker.getMyChannelMembers = utils.getTimestamp();
|
||||
|
||||
Client.getMyChannelMembers(
|
||||
(data) => {
|
||||
callTracker.getMyChannelMembers = 0;
|
||||
|
||||
if (doVersionCheck) {
|
||||
checkVersion();
|
||||
}
|
||||
|
||||
AppDispatcher.handleServerAction({
|
||||
type: ActionTypes.RECEIVED_MY_CHANNEL_MEMBERS,
|
||||
members: data
|
||||
});
|
||||
},
|
||||
(err) => {
|
||||
callTracker.getChannelsUnread = 0;
|
||||
dispatchError(err, 'getMyChannelMembers');
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function updateLastViewedAt(id, active) {
|
||||
let channelId;
|
||||
if (id) {
|
||||
@@ -205,8 +231,7 @@ export function getMoreChannels(force) {
|
||||
|
||||
AppDispatcher.handleServerAction({
|
||||
type: ActionTypes.RECEIVED_MORE_CHANNELS,
|
||||
channels: data.channels,
|
||||
members: data.members
|
||||
channels: data
|
||||
});
|
||||
},
|
||||
(err) => {
|
||||
|
||||
@@ -73,6 +73,7 @@ export const ActionTypes = keyMirror({
|
||||
RECEIVED_CHANNEL: null,
|
||||
RECEIVED_MORE_CHANNELS: null,
|
||||
RECEIVED_CHANNEL_STATS: null,
|
||||
RECEIVED_MY_CHANNEL_MEMBERS: null,
|
||||
|
||||
FOCUS_POST: null,
|
||||
RECEIVED_POSTS: null,
|
||||
|
||||
Reference in New Issue
Block a user