summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/channel.go13
-rw-r--r--api/channel_test.go56
-rw-r--r--api/command_join.go2
-rw-r--r--api/command_join_test.go2
-rw-r--r--api/team.go8
-rw-r--r--api/team_test.go4
-rw-r--r--manualtesting/manual_testing.go6
-rw-r--r--model/channel_list.go35
-rw-r--r--model/channel_member.go21
-rw-r--r--model/client.go16
-rw-r--r--store/sql_channel_store.go55
-rw-r--r--store/sql_channel_store_test.go55
-rw-r--r--store/store.go1
-rw-r--r--webapp/actions/global_actions.jsx6
-rw-r--r--webapp/actions/post_actions.jsx2
-rw-r--r--webapp/actions/websocket_actions.jsx1
-rw-r--r--webapp/client/client.jsx9
-rw-r--r--webapp/routes/route_team.jsx5
-rw-r--r--webapp/stores/channel_store.jsx39
-rw-r--r--webapp/tests/client_channel.test.jsx18
-rw-r--r--webapp/utils/async_client.jsx33
-rw-r--r--webapp/utils/constants.jsx1
22 files changed, 271 insertions, 117 deletions
diff --git a/api/channel.go b/api/channel.go
index bae2a5277..2232786fd 100644
--- a/api/channel.go
+++ b/api/channel.go
@@ -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"]
diff --git a/api/channel_test.go b/api/channel_test.go
index 4835ee9b7..83bb732dd 100644
--- a/api/channel_test.go
+++ b/api/channel_test.go
@@ -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")
diff --git a/api/command_join.go b/api/command_join.go
index b8c863425..2aba1bbd5 100644
--- a/api/command_join.go
+++ b/api/command_join.go
@@ -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 {
diff --git a/api/command_join_test.go b/api/command_join_test.go
index 6cf474c6b..a1dbace41 100644
--- a/api/command_join_test.go
+++ b/api/command_join_test.go
@@ -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
}
diff --git a/api/team.go b/api/team.go
index 4d4795ab6..46e822504 100644
--- a/api/team.go
+++ b/api/team.go
@@ -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 {
diff --git a/api/team_test.go b/api/team_test.go
index a58710145..bac0228ad 100644
--- a/api/team_test.go
+++ b/api/team_test.go
@@ -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")
}
diff --git a/manualtesting/manual_testing.go b/manualtesting/manual_testing.go
index 77a5b89c8..9a2d557bc 100644
--- a/manualtesting/manual_testing.go
+++ b/manualtesting/manual_testing.go
@@ -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
}
diff --git a/model/channel_list.go b/model/channel_list.go
index 49ba384a2..7a46de45d 100644
--- a/model/channel_list.go
+++ b/model/channel_list.go
@@ -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 {
diff --git a/model/channel_member.go b/model/channel_member.go
index 705c6bfbd..4180bb8e6 100644
--- a/model/channel_member.go
+++ b/model/channel_member.go
@@ -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 {
diff --git a/model/client.go b/model/client.go
index f5aeea4db..e9d6c512c 100644
--- a/model/client.go
+++ b/model/client.go
@@ -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
diff --git a/store/sql_channel_store.go b/store/sql_channel_store.go
index f863d57fd..f1cf7f849 100644
--- a/store/sql_channel_store.go
+++ b/store/sql_channel_store.go
@@ -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
+}
diff --git a/store/sql_channel_store_test.go b/store/sql_channel_store_test.go
index d80d54d52..8a51d2ae3 100644
--- a/store/sql_channel_store_test.go
+++ b/store/sql_channel_store_test.go
@@ -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()
diff --git a/store/store.go b/store/store.go
index 51aada920..6cf216699 100644
--- a/store/store.go
+++ b/store/store.go
@@ -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 {
diff --git a/webapp/actions/global_actions.jsx b/webapp/actions/global_actions.jsx
index 23ff5a295..123c1c392 100644
--- a/webapp/actions/global_actions.jsx
+++ b/webapp/actions/global_actions.jsx
@@ -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();
}
diff --git a/webapp/actions/post_actions.jsx b/webapp/actions/post_actions.jsx
index 462576021..1a2056a2e 100644
--- a/webapp/actions/post_actions.jsx
+++ b/webapp/actions/post_actions.jsx
@@ -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);
}
diff --git a/webapp/actions/websocket_actions.jsx b/webapp/actions/websocket_actions.jsx
index c3a3010b0..e58bded0d 100644
--- a/webapp/actions/websocket_actions.jsx
+++ b/webapp/actions/websocket_actions.jsx
@@ -76,6 +76,7 @@ function handleFirstConnect() {
function handleReconnect() {
if (Client.teamId) {
AsyncClient.getChannels();
+ AsyncClient.getMyChannelMembers();
loadPosts(ChannelStore.getCurrentId());
}
diff --git a/webapp/client/client.jsx b/webapp/client/client.jsx
index 596242e41..fd091fd69 100644
--- a/webapp/client/client.jsx
+++ b/webapp/client/client.jsx
@@ -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`).
diff --git a/webapp/routes/route_team.jsx b/webapp/routes/route_team.jsx
index e63be5a5e..608052a58 100644
--- a/webapp/routes/route_team.jsx
+++ b/webapp/routes/route_team.jsx
@@ -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) => {
diff --git a/webapp/stores/channel_store.jsx b/webapp/stores/channel_store.jsx
index 20e7c966f..2ca01fc6e 100644
--- a/webapp/stores/channel_store.jsx
+++ b/webapp/stores/channel_store.jsx
@@ -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();
diff --git a/webapp/tests/client_channel.test.jsx b/webapp/tests/client_channel.test.jsx
index 92145f6e1..b7fa57dc8 100644
--- a/webapp/tests/client_channel.test.jsx
+++ b/webapp/tests/client_channel.test.jsx
@@ -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(
diff --git a/webapp/utils/async_client.jsx b/webapp/utils/async_client.jsx
index ee9d1a4f0..67100ea3f 100644
--- a/webapp/utils/async_client.jsx
+++ b/webapp/utils/async_client.jsx
@@ -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) => {
diff --git a/webapp/utils/constants.jsx b/webapp/utils/constants.jsx
index f87b36fc8..6ea8d040e 100644
--- a/webapp/utils/constants.jsx
+++ b/webapp/utils/constants.jsx
@@ -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,