diff --git a/packages/rocketchat-livechat/client/methods/changeLivechatStatus.js b/packages/rocketchat-livechat/client/methods/changeLivechatStatus.js
new file mode 100644
index 000000000000..8114134652e0
--- /dev/null
+++ b/packages/rocketchat-livechat/client/methods/changeLivechatStatus.js
@@ -0,0 +1,13 @@
+Meteor.methods({
+ 'livechat:changeLivechatStatus'() {
+ if (!Meteor.userId()) {
+ throw new Meteor.Error('error-not-authorized', 'Not authorized');
+ }
+
+ const user = Meteor.user();
+
+ let newStatus = user.statusLivechat === 'available' ? 'not-available' : 'available';
+
+ Meteor.users.update(user._id, { $set: { statusLivechat: newStatus }});
+ }
+});
diff --git a/packages/rocketchat-livechat/client/stylesheets/livechat.less b/packages/rocketchat-livechat/client/stylesheets/livechat.less
index d31b90df8dab..379a29fa44b8 100644
--- a/packages/rocketchat-livechat/client/stylesheets/livechat.less
+++ b/packages/rocketchat-livechat/client/stylesheets/livechat.less
@@ -1,29 +1,3 @@
-.calc(...) {
- @process: ~`(function(e){function t(t,r){var a=");\n",c=n.split(","),i=c[0]+":"+t+"("+(c[1].trim()||0)+a;"start"==r?e="0;\n"+i:e+=i}e=e||8121991;var r="@{state}",n=e;if(8121991==e)return e;switch(r){case"1":t("-webkit-calc","start"),t("-moz-calc"),t("calc");break;case"2":t("-webkit-calc","start"),t("-moz-calc");break;case"3":t("-webkit-calc","start"),t("calc");break;case"4":t("-webkit-calc","start");break;case"5":t("-moz-calc","start"),t("calc");break;case"6":t("-moz-calc","start");break;case"7":t("calc","start")}return e=e.replace(/;$/g,"")})((function(){var e="@{arguments}";return e=e.replace(/^\[|\]$/g,"")})())`;
- @state: 1; -lh-property: @process;
-
-}
-
-.transition(...) {
- @process_webkit: ~`(function(e){e=e||"all 0 ease 0";var r=["background-size","border-radius","border-bottom-left-radius","border-bottom-right-radius","border-top-left-radius","border-top-right-radius","box-shadow","column","transform","filter"],t="-webkit-",n=/(?:\d)(?:ms|s)/gi,a=/(?:\s|^)(\.?\d+\.?\d*)(?![^(]*\)|\w|%)/gi;return/^[^, ]*,/.test(e)&&(e=e.replace(/(?:,)(?![^(]*\))/g,"")),r.forEach(function(r){-1!==e.indexOf(r)&&(e=e.replace(new RegExp(r,"g"),function(e){return t+e}))}),n.test(e)||"0"===e||(e=e.replace(a,function(e){return e+=parseFloat(e,10)>10?"ms":"s"})),e})((function(){var e="@{arguments}";return e=e.replace(/^\[|\]$/g,"")})())`;
- @process_moz: ~`(function(e){e=e||"all 0 ease 0";var r=["background-size","box-shadow","column","transform","filter"],t="-moz-",n=/(?:\d)(?:ms|s)/gi,a=/(?:\s|^)(\.?\d+\.?\d*)(?![^(]*\)|\w|%)/gi;return/^[^, ]*,/.test(e)&&(e=e.replace(/(?:,)(?![^(]*\))/g,"")),r.forEach(function(r){-1!==e.indexOf(r)&&(e=e.replace(new RegExp(r,"g"),function(e){return t+e}))}),n.test(e)||"0"===e||(e=e.replace(a,function(e){return e+=parseFloat(e,10)>10?"ms":"s"})),e})((function(){var e="@{arguments}";return e=e.replace(/^\[|\]$/g,"")})())`;
- @process_opera: ~`(function(e){e=e||"all 0 ease 0";var r=["transform"],t="-o-",n=/(?:\d)(?:ms|s)/gi,a=/(?:\s|^)(\.?\d+\.?\d*)(?![^(]*\)|\w|%)/gi;return/^[^, ]*,/.test(e)&&(e=e.replace(/(?:,)(?![^(]*\))/g,"")),r.forEach(function(r){-1!==e.indexOf(r)&&(e=e.replace(new RegExp(r,"g"),function(e){return t+e}))}),n.test(e)||"0"===e||(e=e.replace(a,function(e){return e+=parseFloat(e,10)>10?"ms":"s"})),e})((function(){var e="@{arguments}";return e=e.replace(/^\[|\]$/g,"")})())`;
- @process: ~`(function(e){e=e||"all 0 ease 0";var r=["-webkit-","-moz-","-o-",""],t=["column","transform","filter"],n=/(?:\d)(?:ms|s)/gi,a=/(?:\s|^)(\.?\d+\.?\d*)(?![^(]*\)|\w|%)/gi;/^[^, ]*,/.test(e)&&(e=e.replace(/(?:,)(?![^(]*\))/g,""));var c=e.split(/(?:,)(?![^(]*\))/g);return c.forEach(function(e,n){t.forEach(function(t){-1!==e.indexOf(t)&&(c[n]="",r.forEach(function(a,u){c[n]+=e.trim().replace(new RegExp(t,"g"),function(e){return a+e}),u
10?"ms":"s"})),e})((function(){var e="@{arguments}";return e=e.replace(/^\[|\]$/g,"")})())`;
- -webkit-transition: @process_webkit;
- -moz-transition: @process_moz;
- -o-transition: @process_opera;
- transition: @process;
-}
-
-.transform(...) {
- @process: ~`(function(e){e=e||"none";var r={translate:"px",rotate:"deg",rotate3d:"deg",skew:"deg"};/^\w*\(?[a-z0-9.]*\)?/.test(e)&&(e=e.replace(/(?:,)(?![^(]*\))/g,""));for(var t in r)e.indexOf(t)>=0&&(e=e.replace(new RegExp(t+"[\\w]?\\([a-z0-9, %]*\\)"),function(e){var n=/(\d+\.?\d*)(?!\w|%)/g;return"rotate3d"==t&&(n=/,\s*\d+$/),e.replace(n,function(e){return e+r[t]})}));return e})((function(){var e="@{arguments}";return e=e.replace(/^\[|\]$/g,"")})())`;
- -webkit-transform: @process;
- -moz-transform: @process;
- -o-transform: @process;
- -ms-transform: @process;
- transform: @process;
-}
-
.flex-list {
.active {
background-color: rgba(255,255,255,0.075);
@@ -505,3 +479,25 @@
}
}
}
+
+.livechat-section {
+ opacity: 0.5;
+
+ .transition(opacity .4s ease);
+
+ &.available {
+ opacity: 1;
+ }
+}
+
+.livechat-status {
+ float: right;
+ margin-right: 10px;
+ font-size: 20px;
+ &.available {
+ color: @status-online;
+ }
+ &.not-available {
+ color: @status-offline;
+ }
+}
diff --git a/packages/rocketchat-livechat/client/views/sideNav/livechat.html b/packages/rocketchat-livechat/client/views/sideNav/livechat.html
index c6aab41be12e..2ab2e9b3cda7 100644
--- a/packages/rocketchat-livechat/client/views/sideNav/livechat.html
+++ b/packages/rocketchat-livechat/client/views/sideNav/livechat.html
@@ -1,12 +1,18 @@
-
- {{_ "Livechat"}}
-
-
- {{#each rooms}}
- {{> chatRoomItem }}
- {{else}}
- {{_ "No_livechats" }}
- {{/each}}
-
+
+
+ {{_ "Livechat"}}
+
+ {{#with available}}
+
+ {{/with}}
+
+
+ {{#each rooms}}
+ {{> chatRoomItem }}
+ {{else}}
+ {{_ "No_livechats" }}
+ {{/each}}
+
+
diff --git a/packages/rocketchat-livechat/client/views/sideNav/livechat.js b/packages/rocketchat-livechat/client/views/sideNav/livechat.js
index ec42e0b9e651..a2151f2a0592 100644
--- a/packages/rocketchat-livechat/client/views/sideNav/livechat.js
+++ b/packages/rocketchat-livechat/client/views/sideNav/livechat.js
@@ -1,5 +1,5 @@
Template.livechat.helpers({
- isActive: function() {
+ isActive() {
if (ChatSubscription.findOne({
t: 'l',
f: {
@@ -15,7 +15,7 @@ Template.livechat.helpers({
return 'active';
}
},
- rooms: function() {
+ rooms() {
var query = {
t: 'l',
open: true
@@ -35,8 +35,30 @@ Template.livechat.helpers({
'name': 1
}
});
+ },
+ available() {
+ const user = Meteor.user();
+ return {
+ status: user.statusLivechat,
+ icon: user.statusLivechat === 'available' ? 'icon-toggle-on' : 'icon-toggle-off',
+ hint: user.statusLivechat === 'available' ? t('Available') : t('Not_Available')
+ };
+ },
+ livechatAvailable() {
+ const user = Meteor.user();
+
+ if (user) {
+ return user.statusLivechat;
+ }
}
});
Template.livechat.events({
+ 'click .livechat-status'() {
+ Meteor.call('livechat:changeLivechatStatus', (err /*, results*/) => {
+ if (err) {
+ return toastr.error(t(err.reason));
+ }
+ });
+ }
});
diff --git a/packages/rocketchat-livechat/package.js b/packages/rocketchat-livechat/package.js
index 4cf6c3b3d2df..e8887070521c 100644
--- a/packages/rocketchat-livechat/package.js
+++ b/packages/rocketchat-livechat/package.js
@@ -48,6 +48,8 @@ Package.onUse(function(api) {
api.addFiles('client/collections/LivechatPageVisited.js', 'client');
api.addFiles('client/collections/LivechatTrigger.js', 'client');
+ api.addFiles('client/methods/changeLivechatStatus.js', 'client');
+
// client views
api.addFiles('client/views/app/livechatAppearance.html', 'client');
api.addFiles('client/views/app/livechatAppearance.js', 'client');
@@ -79,6 +81,7 @@ Package.onUse(function(api) {
// methods
api.addFiles('server/methods/addAgent.js', 'server');
api.addFiles('server/methods/addManager.js', 'server');
+ api.addFiles('server/methods/changeLivechatStatus.js', 'server');
api.addFiles('server/methods/pageVisited.js', 'server');
api.addFiles('server/methods/registerGuest.js', 'server');
api.addFiles('server/methods/removeAgent.js', 'server');
diff --git a/packages/rocketchat-livechat/server/methods/addAgent.js b/packages/rocketchat-livechat/server/methods/addAgent.js
index d71339acf638..403d1ce56a9f 100644
--- a/packages/rocketchat-livechat/server/methods/addAgent.js
+++ b/packages/rocketchat-livechat/server/methods/addAgent.js
@@ -15,7 +15,9 @@ Meteor.methods({
}
if (RocketChat.authz.addUserRoles(user._id, 'livechat-agent')) {
- return RocketChat.models.Users.setOperator(user._id, true);
+ RocketChat.models.Users.setOperator(user._id, true);
+ RocketChat.models.Users.setLivechatStatus(user._id, 'available');
+ return true;
}
return false;
diff --git a/packages/rocketchat-livechat/server/methods/changeLivechatStatus.js b/packages/rocketchat-livechat/server/methods/changeLivechatStatus.js
new file mode 100644
index 000000000000..6d0f4298aafe
--- /dev/null
+++ b/packages/rocketchat-livechat/server/methods/changeLivechatStatus.js
@@ -0,0 +1,13 @@
+Meteor.methods({
+ 'livechat:changeLivechatStatus'() {
+ if (!Meteor.userId()) {
+ throw new Meteor.Error('error-not-authorized', 'Not authorized');
+ }
+
+ const user = Meteor.user();
+
+ let newStatus = user.statusLivechat === 'available' ? 'not-available' : 'available';
+
+ return RocketChat.models.Users.setLivechatStatus(user._id, newStatus);
+ }
+});
diff --git a/packages/rocketchat-livechat/server/methods/removeAgent.js b/packages/rocketchat-livechat/server/methods/removeAgent.js
index ee77ad4af549..d9284e0f0174 100644
--- a/packages/rocketchat-livechat/server/methods/removeAgent.js
+++ b/packages/rocketchat-livechat/server/methods/removeAgent.js
@@ -15,7 +15,9 @@ Meteor.methods({
}
if (RocketChat.authz.removeUserFromRoles(user._id, 'livechat-agent')) {
- return RocketChat.models.Users.setOperator(user._id, false);
+ RocketChat.models.Users.setOperator(user._id, false);
+ RocketChat.models.Users.setLivechatStatus(user._id, 'not-available');
+ return true;
}
return false;
diff --git a/packages/rocketchat-livechat/server/models/Users.js b/packages/rocketchat-livechat/server/models/Users.js
index c67e78cf5a5e..21332f75b79c 100644
--- a/packages/rocketchat-livechat/server/models/Users.js
+++ b/packages/rocketchat-livechat/server/models/Users.js
@@ -33,7 +33,8 @@ RocketChat.models.Users.findOnlineAgents = function() {
*/
RocketChat.models.Users.findOnlineUserFromList = function(userList) {
var query = {
- status: 'online',
+ statusConnection: { $ne: 'offline' },
+ statusLivechat: 'available',
username: {
$in: [].concat(userList)
}
@@ -48,7 +49,8 @@ RocketChat.models.Users.findOnlineUserFromList = function(userList) {
*/
RocketChat.models.Users.getNextAgent = function() {
var query = {
- status: 'online',
+ statusConnection: { $ne: 'offline' },
+ statusLivechat: 'available',
roles: 'livechat-agent'
};
@@ -102,3 +104,21 @@ RocketChat.models.Users.findVisitorByToken = function(token) {
return this.find(query);
};
+
+/**
+ * Change user's livechat status
+ * @param {string} token - Visitor token
+ */
+RocketChat.models.Users.setLivechatStatus = function(userId, status) {
+ let query = {
+ '_id': userId
+ };
+
+ let update = {
+ $set: {
+ 'statusLivechat': status
+ }
+ };
+
+ return this.update(query, update);
+};
diff --git a/server/publications/userData.coffee b/server/publications/userData.coffee
index af3db514d0fa..3f84dc2b2b84 100644
--- a/server/publications/userData.coffee
+++ b/server/publications/userData.coffee
@@ -19,3 +19,4 @@ Meteor.publish 'userData', ->
requirePasswordChange: 1
requirePasswordChangeReason: 1
'services.password.bcrypt': 1
+ statusLivechat: 1 # @TODO create an API so a package could add fields here