summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/channel.go16
-rw-r--r--api/channel_test.go2
-rw-r--r--api/post.go11
-rw-r--r--api/status.go64
-rw-r--r--api/status_test.go36
-rw-r--r--model/client.go24
-rw-r--r--model/status.go10
-rw-r--r--model/status_test.go2
-rw-r--r--model/user.go18
-rw-r--r--store/sql_status_store.go1
-rw-r--r--store/sql_status_store_test.go8
-rw-r--r--store/sql_upgrade.go2
-rw-r--r--webapp/actions/post_actions.jsx2
-rw-r--r--webapp/actions/websocket_actions.jsx2
-rw-r--r--webapp/client/client.jsx13
-rw-r--r--webapp/components/needs_team.jsx1
-rw-r--r--webapp/components/post_view/post_view_cache.jsx2
-rw-r--r--webapp/tests/client_channel.test.jsx1
-rw-r--r--webapp/tests/client_user.test.jsx17
-rw-r--r--webapp/utils/async_client.jsx28
20 files changed, 213 insertions, 47 deletions
diff --git a/api/channel.go b/api/channel.go
index e2c67f18b..c477a5ee4 100644
--- a/api/channel.go
+++ b/api/channel.go
@@ -846,8 +846,16 @@ func updateLastViewedAt(c *Context, w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
id := params["channel_id"]
+ data := model.StringInterfaceFromJson(r.Body)
+
+ var active bool
+ var ok bool
+ if active, ok = data["active"].(bool); !ok {
+ active = true
+ }
+
doClearPush := false
- if *utils.Cfg.EmailSettings.SendPushNotifications && !c.Session.IsMobileApp() {
+ if *utils.Cfg.EmailSettings.SendPushNotifications && !c.Session.IsMobileApp() && active {
if result := <-Srv.Store.User().GetUnreadCountForChannel(c.Session.UserId, id); result.Err != nil {
l4g.Error(utils.T("api.channel.update_last_viewed_at.get_unread_count_for_channel.error"), c.Session.UserId, id, result.Err.Error())
} else {
@@ -857,6 +865,12 @@ func updateLastViewedAt(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
+ go func() {
+ if err := SetActiveChannel(c.Session.UserId, id); err != nil {
+ l4g.Error(err.Error())
+ }
+ }()
+
Srv.Store.Channel().UpdateLastViewedAt(id, c.Session.UserId)
// Must be after update so that unread count is correct
diff --git a/api/channel_test.go b/api/channel_test.go
index 450aac877..7046a9868 100644
--- a/api/channel_test.go
+++ b/api/channel_test.go
@@ -647,7 +647,7 @@ func TestGetChannel(t *testing.T) {
t.Fatal("cache should be empty")
}
- if _, err := Client.UpdateLastViewedAt(channel2.Id); err != nil {
+ if _, err := Client.UpdateLastViewedAt(channel2.Id, true); err != nil {
t.Fatal(err)
}
diff --git a/api/post.go b/api/post.go
index 55e63cd23..d62b85059 100644
--- a/api/post.go
+++ b/api/post.go
@@ -682,7 +682,7 @@ func sendNotifications(c *Context, post *model.Post, team *model.Team, channel *
var status *model.Status
var err *model.AppError
if status, err = GetStatus(id); err != nil {
- status = &model.Status{id, model.STATUS_OFFLINE, false, 0}
+ status = &model.Status{id, model.STATUS_OFFLINE, false, 0, ""}
}
if userAllowsEmails && status.Status != model.STATUS_ONLINE {
@@ -739,10 +739,10 @@ func sendNotifications(c *Context, post *model.Post, team *model.Team, channel *
var status *model.Status
var err *model.AppError
if status, err = GetStatus(id); err != nil {
- status = &model.Status{id, model.STATUS_OFFLINE, false, 0}
+ status = &model.Status{id, model.STATUS_OFFLINE, false, 0, ""}
}
- if profileMap[id].StatusAllowsPushNotification(status) {
+ if DoesStatusAllowPushNotification(profileMap[id], status, post.ChannelId) {
sendPushNotification(post, profileMap[id], channel, senderName, true)
}
}
@@ -752,10 +752,10 @@ func sendNotifications(c *Context, post *model.Post, team *model.Team, channel *
var status *model.Status
var err *model.AppError
if status, err = GetStatus(id); err != nil {
- status = &model.Status{id, model.STATUS_OFFLINE, false, 0}
+ status = &model.Status{id, model.STATUS_OFFLINE, false, 0, ""}
}
- if profileMap[id].StatusAllowsPushNotification(status) {
+ if DoesStatusAllowPushNotification(profileMap[id], status, post.ChannelId) {
sendPushNotification(post, profileMap[id], channel, senderName, false)
}
}
@@ -945,7 +945,6 @@ func sendPushNotification(post *model.Post, user *model.User, channel *model.Cha
func clearPushNotification(userId string, channelId string) {
session := getMobileAppSession(userId)
-
if session == nil {
return
}
diff --git a/api/status.go b/api/status.go
index d83eac033..e8e324778 100644
--- a/api/status.go
+++ b/api/status.go
@@ -28,6 +28,7 @@ func InitStatus() {
l4g.Debug(utils.T("api.status.init.debug"))
BaseRoutes.Users.Handle("/status", ApiUserRequiredActivity(getStatusesHttp, false)).Methods("GET")
+ BaseRoutes.Users.Handle("/status/set_active_channel", ApiUserRequiredActivity(setActiveChannel, false)).Methods("POST")
BaseRoutes.WebSocket.Handle("get_statuses", ApiWebSocketHandler(getStatusesWebSocket))
}
@@ -66,13 +67,12 @@ func GetAllStatuses() (map[string]interface{}, *model.AppError) {
}
func SetStatusOnline(userId string, sessionId string, manual bool) {
- l4g.Debug(userId, "online")
broadcast := false
var status *model.Status
var err *model.AppError
if status, err = GetStatus(userId); err != nil {
- status = &model.Status{userId, model.STATUS_ONLINE, false, model.GetMillis()}
+ status = &model.Status{userId, model.STATUS_ONLINE, false, model.GetMillis(), ""}
broadcast = true
} else {
if status.Manual && !manual {
@@ -113,13 +113,12 @@ func SetStatusOnline(userId string, sessionId string, manual bool) {
}
func SetStatusOffline(userId string, manual bool) {
- l4g.Debug(userId, "offline")
status, err := GetStatus(userId)
if err == nil && status.Manual && !manual {
return // manually set status always overrides non-manual one
}
- status = &model.Status{userId, model.STATUS_OFFLINE, manual, model.GetMillis()}
+ status = &model.Status{userId, model.STATUS_OFFLINE, manual, model.GetMillis(), ""}
AddStatusCache(status)
@@ -133,11 +132,10 @@ func SetStatusOffline(userId string, manual bool) {
}
func SetStatusAwayIfNeeded(userId string, manual bool) {
- l4g.Debug(userId, "away")
status, err := GetStatus(userId)
if err != nil {
- status = &model.Status{userId, model.STATUS_OFFLINE, manual, 0}
+ status = &model.Status{userId, model.STATUS_OFFLINE, manual, 0, ""}
}
if !manual && status.Manual {
@@ -156,6 +154,7 @@ func SetStatusAwayIfNeeded(userId string, manual bool) {
status.Status = model.STATUS_AWAY
status.Manual = manual
+ status.ActiveChannel = ""
AddStatusCache(status)
@@ -183,3 +182,56 @@ func GetStatus(userId string) (*model.Status, *model.AppError) {
func IsUserAway(lastActivityAt int64) bool {
return model.GetMillis()-lastActivityAt >= *utils.Cfg.TeamSettings.UserStatusAwayTimeout*1000
}
+
+func DoesStatusAllowPushNotification(user *model.User, status *model.Status, channelId string) bool {
+ props := user.NotifyProps
+
+ if props["push"] == "none" {
+ return false
+ }
+
+ if pushStatus, ok := props["push_status"]; (pushStatus == model.STATUS_ONLINE || !ok) && (status.ActiveChannel != channelId || model.GetMillis()-status.LastActivityAt > model.STATUS_CHANNEL_TIMEOUT) {
+ return true
+ } else if pushStatus == model.STATUS_AWAY && (status.Status == model.STATUS_AWAY || status.Status == model.STATUS_OFFLINE) {
+ return true
+ } else if pushStatus == model.STATUS_OFFLINE && status.Status == model.STATUS_OFFLINE {
+ return true
+ }
+
+ return false
+}
+
+func setActiveChannel(c *Context, w http.ResponseWriter, r *http.Request) {
+ data := model.MapFromJson(r.Body)
+
+ var channelId string
+ var ok bool
+ if channelId, ok = data["channel_id"]; !ok || len(channelId) > 26 {
+ c.SetInvalidParam("setActiveChannel", "channel_id")
+ return
+ }
+
+ if err := SetActiveChannel(c.Session.UserId, channelId); err != nil {
+ c.Err = err
+ return
+ }
+
+ ReturnStatusOK(w)
+}
+
+func SetActiveChannel(userId string, channelId string) *model.AppError {
+ status, err := GetStatus(userId)
+ if err != nil {
+ status = &model.Status{userId, model.STATUS_ONLINE, false, model.GetMillis(), channelId}
+ } else {
+ status.ActiveChannel = channelId
+ }
+
+ AddStatusCache(status)
+
+ if result := <-Srv.Store.Status().SaveOrUpdate(status); result.Err != nil {
+ return result.Err
+ }
+
+ return nil
+}
diff --git a/api/status_test.go b/api/status_test.go
index 451f39e14..a8292d323 100644
--- a/api/status_test.go
+++ b/api/status_test.go
@@ -151,3 +151,39 @@ func TestStatuses(t *testing.T) {
t.Fatal("didn't get offline event")
}
}
+
+func TestSetActiveChannel(t *testing.T) {
+ th := Setup().InitBasic()
+ Client := th.BasicClient
+
+ if _, err := Client.SetActiveChannel(th.BasicChannel.Id); err != nil {
+ t.Fatal(err)
+ }
+
+ status, _ := GetStatus(th.BasicUser.Id)
+ if status.ActiveChannel != th.BasicChannel.Id {
+ t.Fatal("active channel should be set")
+ }
+
+ if _, err := Client.SetActiveChannel(""); err != nil {
+ t.Fatal(err)
+ }
+
+ status, _ = GetStatus(th.BasicUser.Id)
+ if status.ActiveChannel != "" {
+ t.Fatal("active channel should be blank")
+ }
+
+ if _, err := Client.SetActiveChannel("123456789012345678901234567890"); err == nil {
+ t.Fatal("should have failed, id too long")
+ }
+
+ if _, err := Client.UpdateLastViewedAt(th.BasicChannel.Id, true); err != nil {
+ t.Fatal(err)
+ }
+
+ status, _ = GetStatus(th.BasicUser.Id)
+ if status.ActiveChannel != th.BasicChannel.Id {
+ t.Fatal("active channel should be set")
+ }
+}
diff --git a/model/client.go b/model/client.go
index f43e5ad79..2c3fb5aca 100644
--- a/model/client.go
+++ b/model/client.go
@@ -1140,8 +1140,13 @@ func (c *Client) RemoveChannelMember(id, user_id string) (*Result, *AppError) {
}
}
-func (c *Client) UpdateLastViewedAt(channelId string) (*Result, *AppError) {
- if r, err := c.DoApiPost(c.GetChannelRoute(channelId)+"/update_last_viewed_at", ""); err != nil {
+// UpdateLastViewedAt will mark a channel as read.
+// The channelId indicates the channel to mark as read. If active is true, push notifications
+// will be cleared if there are unread messages. The default for active is true.
+func (c *Client) UpdateLastViewedAt(channelId string, active bool) (*Result, *AppError) {
+ data := make(map[string]interface{})
+ data["active"] = active
+ if r, err := c.DoApiPost(c.GetChannelRoute(channelId)+"/update_last_viewed_at", StringInterfaceToJson(data)); err != nil {
return nil, err
} else {
defer closeBody(r)
@@ -1463,6 +1468,21 @@ func (c *Client) GetStatuses() (*Result, *AppError) {
}
}
+// SetActiveChannel sets the the channel id the user is currently viewing.
+// The channelId key is required but the value can be blank. Returns standard
+// response.
+func (c *Client) SetActiveChannel(channelId string) (*Result, *AppError) {
+ data := map[string]string{}
+ data["channel_id"] = channelId
+ if r, err := c.DoApiPost("/users/status/set_active_channel", MapToJson(data)); err != nil {
+ return nil, err
+ } else {
+ defer closeBody(r)
+ return &Result{r.Header.Get(HEADER_REQUEST_ID),
+ r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil
+ }
+}
+
func (c *Client) GetMyTeam(etag string) (*Result, *AppError) {
if r, err := c.DoApiGet(c.GetTeamRoute()+"/me", "", etag); err != nil {
return nil, err
diff --git a/model/status.go b/model/status.go
index 477b750d5..f4ad8e775 100644
--- a/model/status.go
+++ b/model/status.go
@@ -9,10 +9,11 @@ import (
)
const (
- STATUS_OFFLINE = "offline"
- STATUS_AWAY = "away"
- STATUS_ONLINE = "online"
- STATUS_CACHE_SIZE = 10000
+ STATUS_OFFLINE = "offline"
+ STATUS_AWAY = "away"
+ STATUS_ONLINE = "online"
+ STATUS_CACHE_SIZE = 10000
+ STATUS_CHANNEL_TIMEOUT = 20000 // 20 seconds
)
type Status struct {
@@ -20,6 +21,7 @@ type Status struct {
Status string `json:"status"`
Manual bool `json:"manual"`
LastActivityAt int64 `json:"last_activity_at"`
+ ActiveChannel string `json:"active_channel"`
}
func (o *Status) ToJson() string {
diff --git a/model/status_test.go b/model/status_test.go
index b5e876bc5..0b4a33d5d 100644
--- a/model/status_test.go
+++ b/model/status_test.go
@@ -9,7 +9,7 @@ import (
)
func TestStatus(t *testing.T) {
- status := Status{NewId(), STATUS_ONLINE, true, 0}
+ status := Status{NewId(), STATUS_ONLINE, true, 0, ""}
json := status.ToJson()
status2 := StatusFromJson(strings.NewReader(json))
diff --git a/model/user.go b/model/user.go
index 8917658df..434ce2732 100644
--- a/model/user.go
+++ b/model/user.go
@@ -378,24 +378,6 @@ func (u *User) IsLDAPUser() bool {
return false
}
-func (u *User) StatusAllowsPushNotification(status *Status) bool {
- props := u.NotifyProps
-
- if props["push"] == "none" {
- return false
- }
-
- if pushStatus, ok := props["push_status"]; pushStatus == STATUS_ONLINE || !ok {
- return true
- } else if pushStatus == STATUS_AWAY && (status.Status == STATUS_AWAY || status.Status == STATUS_OFFLINE) {
- return true
- } else if pushStatus == STATUS_OFFLINE && status.Status == STATUS_OFFLINE {
- return true
- }
-
- return false
-}
-
// UserFromJson will decode the input and return a User
func UserFromJson(data io.Reader) *User {
decoder := json.NewDecoder(data)
diff --git a/store/sql_status_store.go b/store/sql_status_store.go
index 9b82484f4..9f7441796 100644
--- a/store/sql_status_store.go
+++ b/store/sql_status_store.go
@@ -24,6 +24,7 @@ func NewSqlStatusStore(sqlStore *SqlStore) StatusStore {
table := db.AddTableWithName(model.Status{}, "Status").SetKeys(false, "UserId")
table.ColMap("UserId").SetMaxSize(26)
table.ColMap("Status").SetMaxSize(32)
+ table.ColMap("ActiveChannel").SetMaxSize(26)
}
return s
diff --git a/store/sql_status_store_test.go b/store/sql_status_store_test.go
index 52759a4b1..dff4db55e 100644
--- a/store/sql_status_store_test.go
+++ b/store/sql_status_store_test.go
@@ -12,7 +12,7 @@ import (
func TestSqlStatusStore(t *testing.T) {
Setup()
- status := &model.Status{model.NewId(), model.STATUS_ONLINE, false, 0}
+ status := &model.Status{model.NewId(), model.STATUS_ONLINE, false, 0, ""}
if err := (<-store.Status().SaveOrUpdate(status)).Err; err != nil {
t.Fatal(err)
@@ -28,12 +28,12 @@ func TestSqlStatusStore(t *testing.T) {
t.Fatal(err)
}
- status2 := &model.Status{model.NewId(), model.STATUS_AWAY, false, 0}
+ status2 := &model.Status{model.NewId(), model.STATUS_AWAY, false, 0, ""}
if err := (<-store.Status().SaveOrUpdate(status2)).Err; err != nil {
t.Fatal(err)
}
- status3 := &model.Status{model.NewId(), model.STATUS_OFFLINE, false, 0}
+ status3 := &model.Status{model.NewId(), model.STATUS_OFFLINE, false, 0, ""}
if err := (<-store.Status().SaveOrUpdate(status3)).Err; err != nil {
t.Fatal(err)
}
@@ -81,7 +81,7 @@ func TestSqlStatusStore(t *testing.T) {
func TestActiveUserCount(t *testing.T) {
Setup()
- status := &model.Status{model.NewId(), model.STATUS_ONLINE, false, model.GetMillis()}
+ status := &model.Status{model.NewId(), model.STATUS_ONLINE, false, model.GetMillis(), ""}
Must(store.Status().SaveOrUpdate(status))
if result := <-store.Status().GetTotalActiveUsersCount(); result.Err != nil {
diff --git a/store/sql_upgrade.go b/store/sql_upgrade.go
index 954139128..302d7fc12 100644
--- a/store/sql_upgrade.go
+++ b/store/sql_upgrade.go
@@ -180,7 +180,9 @@ func UpgradeDatabaseToVersion33(sqlStore *SqlStore) {
func UpgradeDatabaseToVersion34(sqlStore *SqlStore) {
if shouldPerformUpgrade(sqlStore, VERSION_3_3_0, VERSION_3_4_0) {
+
sqlStore.CreateColumnIfNotExists("Status", "Manual", "BOOLEAN", "BOOLEAN", "0")
+ sqlStore.CreateColumnIfNotExists("Status", "ActiveChannel", "varchar(26)", "varchar(26)", "")
// TODO XXX FIXME should be removed before release
//saveSchemaVersion(sqlStore, VERSION_3_4_0)
diff --git a/webapp/actions/post_actions.jsx b/webapp/actions/post_actions.jsx
index 9e0f90377..896a9030d 100644
--- a/webapp/actions/post_actions.jsx
+++ b/webapp/actions/post_actions.jsx
@@ -19,7 +19,7 @@ const Preferences = Constants.Preferences;
export function handleNewPost(post, msg) {
if (ChannelStore.getCurrentId() === post.channel_id) {
if (window.isActive) {
- AsyncClient.updateLastViewedAt();
+ AsyncClient.updateLastViewedAt(null, false);
} else {
AsyncClient.getChannel(post.channel_id);
}
diff --git a/webapp/actions/websocket_actions.jsx b/webapp/actions/websocket_actions.jsx
index 1c4ef9c16..28faf4733 100644
--- a/webapp/actions/websocket_actions.jsx
+++ b/webapp/actions/websocket_actions.jsx
@@ -174,7 +174,7 @@ function handlePostEditEvent(msg) {
// Update channel state
if (ChannelStore.getCurrentId() === msg.channel_id) {
if (window.isActive) {
- AsyncClient.updateLastViewedAt();
+ AsyncClient.updateLastViewedAt(null, false);
}
}
}
diff --git a/webapp/client/client.jsx b/webapp/client/client.jsx
index a059bb38a..80e2cfe3e 100644
--- a/webapp/client/client.jsx
+++ b/webapp/client/client.jsx
@@ -1003,6 +1003,16 @@ export default class Client {
end(this.handleResponse.bind(this, 'getStatuses', success, error));
}
+ setActiveChannel(id, success, error) {
+ request.
+ post(`${this.getUsersRoute()}/status/set_active_channel`).
+ set(this.defaultHeaders).
+ type('application/json').
+ accept('application/json').
+ send({channel_id: id}).
+ end(this.handleResponse.bind(this, 'setActiveChannel', success, error));
+ }
+
verifyEmail(uid, hid, success, error) {
request.
post(`${this.getUsersRoute()}/verify_email`).
@@ -1172,12 +1182,13 @@ export default class Client {
this.track('api', 'api_channels_delete');
}
- updateLastViewedAt(channelId, success, error) {
+ updateLastViewedAt(channelId, active, success, error) {
request.
post(`${this.getChannelNeededRoute(channelId)}/update_last_viewed_at`).
set(this.defaultHeaders).
type('application/json').
accept('application/json').
+ send({active}).
end(this.handleResponse.bind(this, 'updateLastViewedAt', success, error));
}
diff --git a/webapp/components/needs_team.jsx b/webapp/components/needs_team.jsx
index 6c023d497..cd80f0fc7 100644
--- a/webapp/components/needs_team.jsx
+++ b/webapp/components/needs_team.jsx
@@ -94,6 +94,7 @@ export default class NeedsTeam extends React.Component {
$(window).on('blur', () => {
window.isActive = false;
+ AsyncClient.setActiveChannel('');
});
Utils.applyTheme(this.state.theme);
diff --git a/webapp/components/post_view/post_view_cache.jsx b/webapp/components/post_view/post_view_cache.jsx
index 8876ae461..13ce79d7f 100644
--- a/webapp/components/post_view/post_view_cache.jsx
+++ b/webapp/components/post_view/post_view_cache.jsx
@@ -4,6 +4,7 @@
import PostViewController from './post_view_controller.jsx';
import ChannelStore from 'stores/channel_store.jsx';
+import * as AsyncClient from 'utils/async_client.jsx';
import React from 'react';
@@ -28,6 +29,7 @@ export default class PostViewCache extends React.Component {
}
componentWillUnmount() {
+ AsyncClient.setActiveChannel('');
ChannelStore.removeChangeListener(this.onChannelChange);
}
diff --git a/webapp/tests/client_channel.test.jsx b/webapp/tests/client_channel.test.jsx
index 72ba91f9d..ccfcb32a4 100644
--- a/webapp/tests/client_channel.test.jsx
+++ b/webapp/tests/client_channel.test.jsx
@@ -216,6 +216,7 @@ describe('Client.Channels', function() {
var channel = TestHelper.basicChannel();
TestHelper.basicClient().updateLastViewedAt(
channel.id,
+ true,
function(data) {
assert.equal(data.id, channel.id);
done();
diff --git a/webapp/tests/client_user.test.jsx b/webapp/tests/client_user.test.jsx
index a0bddd08b..116eee4ae 100644
--- a/webapp/tests/client_user.test.jsx
+++ b/webapp/tests/client_user.test.jsx
@@ -509,6 +509,23 @@ describe('Client.User', function() {
});
*/
+ it('setActiveChannel', function(done) {
+ TestHelper.initBasic(() => {
+ var ids = [];
+ ids.push(TestHelper.basicUser().id);
+
+ TestHelper.basicClient().setActiveChannel(
+ TestHelper.basicChannel().id,
+ function() {
+ done();
+ },
+ function(err) {
+ done(new Error(err.message));
+ }
+ );
+ });
+ });
+
it('verifyEmail', function(done) {
TestHelper.initBasic(() => {
TestHelper.basicClient().enableLogErrorsToConsole(false); // Disabling since this unit test causes an error
diff --git a/webapp/utils/async_client.jsx b/webapp/utils/async_client.jsx
index 729160fe4..585e4b1c0 100644
--- a/webapp/utils/async_client.jsx
+++ b/webapp/utils/async_client.jsx
@@ -113,7 +113,7 @@ export function getChannel(id) {
);
}
-export function updateLastViewedAt(id) {
+export function updateLastViewedAt(id, active) {
let channelId;
if (id) {
channelId = id;
@@ -129,9 +129,17 @@ export function updateLastViewedAt(id) {
return;
}
+ let isActive;
+ if (active == null) {
+ isActive = true;
+ } else {
+ isActive = active;
+ }
+
callTracker[`updateLastViewed${channelId}`] = utils.getTimestamp();
Client.updateLastViewedAt(
channelId,
+ isActive,
() => {
callTracker[`updateLastViewed${channelId}`] = 0;
ErrorStore.clearLastError();
@@ -753,6 +761,24 @@ export function getStatuses() {
);
}
+export function setActiveChannel(channelId) {
+ if (isCallInProgress(`setActiveChannel${channelId}`)) {
+ return;
+ }
+
+ callTracker[`setActiveChannel${channelId}`] = utils.getTimestamp();
+ Client.setActiveChannel(
+ channelId,
+ () => {
+ callTracker[`setActiveChannel${channelId}`] = 0;
+ },
+ (err) => {
+ callTracker[`setActiveChannel${channelId}`] = 0;
+ dispatchError(err, 'setActiveChannel');
+ }
+ );
+}
+
export function getMyTeam() {
if (isCallInProgress('getMyTeam')) {
return null;