+
+
+
Select participants:
diff --git a/samples/chat/js/QBconfig.js b/samples/chat/js/QBconfig.js
index dc8c92940..efbe3473e 100644
--- a/samples/chat/js/QBconfig.js
+++ b/samples/chat/js/QBconfig.js
@@ -1,8 +1,8 @@
var QBconfig = {
credentials: {
- appId: 72448,
- authKey: 'f4HYBYdeqTZ7KNb',
- authSecret: 'ZC7dK39bOjVc-Z8'
+ appId: '',
+ authKey: '',
+ authSecret: ''
},
appConfig: {
chatProtocol: {
@@ -39,6 +39,7 @@ var CONSTANTS = {
},
NOTIFICATION_TYPES: {
NEW_DIALOG: '1',
- UPDATE_DIALOG: '2'
+ UPDATE_DIALOG: '2',
+ LEAVE_DIALOG: '3'
}
};
diff --git a/samples/chat/js/app.js b/samples/chat/js/app.js
index add1d8f9b..6c0be5b55 100644
--- a/samples/chat/js/app.js
+++ b/samples/chat/js/app.js
@@ -57,22 +57,17 @@ App.prototype.renderDashboard = function (activeTabName) {
listeners.setListeners();
logoutBtn.addEventListener('click', function () {
- QB.users.delete(app.user.id, function(err, user){
- if (err) {
- console.error('Can\'t delete user by id: '+app.user.id+' ', err);
- }
- loginModule.isLogin = false;
- app.isDashboardLoaded = false;
+ loginModule.isLogin = false;
+ app.isDashboardLoaded = false;
- localStorage.removeItem('user');
- helpers.clearCache();
+ localStorage.removeItem('user');
+ helpers.clearCache();
- QB.chat.disconnect();
- QB.destroySession();
-
- router.navigate('#!/login');
- });
+ QB.chat.disconnect();
+ QB.destroySession(() => null);
+
+ router.navigate('#!/login');
});
this.tabSelectInit();
@@ -90,7 +85,7 @@ App.prototype.loadWelcomeTpl = function () {
App.prototype.tabSelectInit = function () {
var self = this,
tabs = document.querySelectorAll('.j-sidebar__tab_link');
-
+
_.each(tabs, function (item) {
item.addEventListener('click', function (e) {
e.preventDefault();
@@ -99,7 +94,16 @@ App.prototype.tabSelectInit = function () {
}
var tab = e.currentTarget;
- self.loadChatList(tab);
+ self.loadChatList(tab).then(function(){
+ var activeTab = document.querySelector('.j-sidebar__tab_link.active'),
+ tabType = activeTab.dataset.type,
+ dialogType = dialogModule._cache[dialogModule.dialogId].type === 1 ? 'public' : 'chat',
+ isActiveTab = tabType === dialogType;
+
+ if(isActiveTab && dialogModule._cache[dialogModule.dialogId].type === CONSTANTS.DIALOG_TYPES.CHAT ) {
+ dialogModule.renderMessages(dialogModule.dialogId);
+ }
+ });
});
});
};
@@ -153,17 +157,10 @@ App.prototype.buildCreateDialogTpl = function () {
if (document.forms.create_dialog.create_dialog_submit.disabled) return false;
document.forms.create_dialog.create_dialog_submit.disabled = true;
-
- var users = self.userListConteiner.querySelectorAll('.selected'),
- type = users.length > 2 ? 2 : 3,
- name = document.forms.create_dialog.dialog_name.value,
- occupants_ids = [];
-
- _.each(users, function (user) {
- if (+user.id !== self.user.id) {
- occupants_ids.push(user.id);
- }
- });
+
+ var occupants_ids = userModule.selectedUserIds,
+ type = occupants_ids.length > 1 ? 2 : 3,
+ name = document.forms.create_dialog.dialog_name.value;
if (!name && type === 2) {
var userNames = [];
@@ -197,6 +194,7 @@ App.prototype.buildCreateDialogTpl = function () {
document.forms.create_dialog.dialog_name.value = titleText.slice(0, 40);
}
});
+
userModule.initGettingUsers();
};
diff --git a/samples/chat/js/dialog.js b/samples/chat/js/dialog.js
index cce3a9c7e..2d784a851 100644
--- a/samples/chat/js/dialog.js
+++ b/samples/chat/js/dialog.js
@@ -69,10 +69,7 @@ Dialog.prototype.loadDialogs = function (type) {
var dialogs = resDialogs.items;
_.each(dialogs, function (dialog) {
- if (!self._cache[dialog._id]) {
- self._cache[dialog._id] = helpers.compileDialogParams(dialog);
- }
-
+ self._cache[dialog._id] = helpers.compileDialogParams(dialog);
self.renderDialog(self._cache[dialog._id]);
});
@@ -188,7 +185,7 @@ Dialog.prototype.replaceDialogLink = function (elem) {
Dialog.prototype.joinToDialog = function (id) {
var self = this,
- jidOrUserId = self._cache[id].jidOrUserId;
+ jidOrUserId = ((typeof self._cache[id].jidOrUserId == "number")?String(self._cache[id].jidOrUserId):self._cache[id].jidOrUserId);
return new Promise(function (resolve, reject){
QB.chat.muc.join(jidOrUserId, function (resultStanza) {
@@ -210,7 +207,7 @@ Dialog.prototype.joinToDialog = function (id) {
Dialog.prototype.renderMessages = function (dialogId) {
var self = this,
dialog = self._cache[dialogId];
-
+ dialog.tplDateMessage = {};
document.querySelector('.j-sidebar__create_dialog').classList.remove('active');
if (!document.forms.send_message) {
@@ -297,8 +294,8 @@ Dialog.prototype.changeLastMessagePreview = function (dialogId, msg) {
var self = this,
dialog = document.getElementById(dialogId),
message = msg.message;
-
- if (message.indexOf('\n') !== -1) {
+
+ if (message && message.indexOf('\n') !== -1) {
message = message.slice(0, message.indexOf('\n'));
}
@@ -317,6 +314,7 @@ Dialog.prototype.changeLastMessagePreview = function (dialogId, msg) {
}
dialog.querySelector('.j-dialog__last_message_date').innerText = msg.date_sent;
+ dialogModule.sortedByLastMessage(dialogId);
}
};
@@ -324,9 +322,7 @@ Dialog.prototype.createDialog = function (params) {
if (!app.checkInternetConnection()) {
return false;
}
-
var self = this;
-
QB.chat.dialog.create(params, function (err, createdDialog) {
if (err) {
console.error(err);
@@ -358,7 +354,7 @@ Dialog.prototype.createDialog = function (params) {
save_to_history: 1,
dialog_id: createdDialog._id,
notification_type: 1,
- occupants_ids: occupants.toString()
+ date_sent: Date.now()
}
};
@@ -366,36 +362,37 @@ Dialog.prototype.createDialog = function (params) {
return item != app.user.id
});
- for (var i = 0; i < newOccupantsIds.length; i++) {
- QB.chat.sendSystemMessage(newOccupantsIds[i], systemMessage);
- }
-
/* Check dialog in cache */
if (!self._cache[id]) {
self._cache[id] = helpers.compileDialogParams(createdDialog);
}
- self.joinToDialog(id).then(function(){
- if(createdDialog.type === CONSTANTS.DIALOG_TYPES.GROUPCHAT){
- messageModule.sendMessage(id, notificationMessage);
+ (new Promise(function (resolve){
+ self.joinToDialog(id).then(function(){
+ if(createdDialog.type === CONSTANTS.DIALOG_TYPES.GROUPCHAT){
+ messageModule.sendMessage(id, notificationMessage);
+ }
+ resolve();
+ });
+ })).then(function(){
+ for (var i = 0; i < newOccupantsIds.length; i++) {
+ QB.chat.sendSystemMessage(newOccupantsIds[i], systemMessage);
}
- });
-
- /* Check active tab [chat / public] */
- var type = params.type === CONSTANTS.DIALOG_TYPES.PUBLICCHAT ? 'public' : 'chat',
- activeTab = document.querySelector('.j-sidebar__tab_link.active');
-
- if (activeTab && type !== activeTab.dataset.type) {
- var tab = document.querySelector('.j-sidebar__tab_link[data-type="chat"]');
- app.loadChatList(tab).then(function () {
+ /* Check active tab [chat / public] */
+ var type = params.type === CONSTANTS.DIALOG_TYPES.PUBLICCHAT ? 'public' : 'chat',
+ activeTab = document.querySelector('.j-sidebar__tab_link.active');
+ if (activeTab && type !== activeTab.dataset.type) {
+ var tab = document.querySelector('.j-sidebar__tab_link[data-type="chat"]');
+ app.loadChatList(tab).then(function () {
+ self.renderDialog(self._cache[id], true);
+ }).catch(function(error){
+ console.error(error);
+ });
+ } else {
self.renderDialog(self._cache[id], true);
- }).catch(function(error){
- console.error(error);
- });
- } else {
- self.renderDialog(self._cache[id], true);
- router.navigate('/dialog/' + id);
- }
+ router.navigate('/dialog/' + id);
+ }
+ });
}
});
};
@@ -459,7 +456,8 @@ Dialog.prototype.updateDialog = function (updates) {
dialog_id: dialog._id,
notification_type: 2,
dialog_updated_at: Date.now() / 1000
- }
+ },
+ markable: 1
};
if(dialog.type !== CONSTANTS.DIALOG_TYPES.GROUPCHAT) return false;
@@ -487,7 +485,7 @@ Dialog.prototype.updateDialog = function (updates) {
self._cache[dialogId].users = self._cache[dialogId].users.concat(newUsers);
updatedMsg.body = app.user.name + ' adds ' + usernames.join(', ') + ' to the conversation.';
- updatedMsg.extension.occupants_ids_added = newUsers.join(',');
+ updatedMsg.extension.new_occupants_ids = newUsers.join(',');
} else {
router.navigate('/dialog/' + dialogId);
return false;
@@ -499,6 +497,19 @@ Dialog.prototype.updateDialog = function (updates) {
_notifyNewUsers(newUsers);
}
+ var msg = {
+ extension: {
+ notification_type: 2,
+ dialog_id: dialog._id,
+ new_occupants_ids: newUsers.toString()
+ }
+ };
+
+ _.each(dialog.occupants_ids, function(user){
+ QB.chat.sendSystemMessage(+user, msg);
+ });
+
+
messageModule.sendMessage(dialogId, updatedMsg);
if(updates.title){
@@ -532,7 +543,8 @@ Dialog.prototype.updateDialog = function (updates) {
var msg = {
extension: {
notification_type: 2,
- dialog_id: dialog._id
+ dialog_id: dialog._id,
+ new_occupants_ids: users.toString()
}
};
@@ -564,24 +576,29 @@ Dialog.prototype.quitFromTheDialog = function(dialogId){
alert('you can\'t remove this dialog');
break;
case CONSTANTS.DIALOG_TYPES.CHAT:
- QB.chat.dialog.delete([dialogId], function(err) {
- if (err) {
- console.error(err);
- } else {
- _removedilogFromCacheAndUi();
- router.navigate('/dashboard');
- }
- });
- break;
case CONSTANTS.DIALOG_TYPES.GROUPCHAT:
- // remove user from current group dialog;
- _notuyfyUsers();
- QB.chat.dialog.update(dialogId, {
- pull_all: {
- occupants_ids: [app.user.id]
+ if(CONSTANTS.DIALOG_TYPES.GROUPCHAT===dialog.type){
+ // remove user from current group dialog;
+ _notuyfyUsers();
+
+ var systemMessage = {
+ extension: {
+ notification_type: 3,
+ dialog_id: dialog._id
+ }
+ };
+
+ for (var i = 0; i < dialog.users.length; i++) {
+ if (dialog.users[i] === app.user.id) {
+ continue;
+ }
+ QB.chat.sendSystemMessage(dialog.users[i], systemMessage);
}
- }, function(err, res) {
+
+ }
+
+ QB.chat.dialog.delete([dialogId], function(err) {
if (err) {
console.error(err);
} else {
@@ -606,10 +623,10 @@ Dialog.prototype.quitFromTheDialog = function(dialogId){
extension: {
save_to_history: 1,
dialog_id: dialog._id,
- notification_type: 2,
- dialog_updated_at: Date.now() / 1000,
- occupants_ids_removed: app.user.id
- }
+ notification_type: 3,
+ dialog_updated_at: Date.now() / 1000
+ },
+ markable: 1
};
messageModule.sendMessage(dialogId, msg);
@@ -617,4 +634,13 @@ Dialog.prototype.quitFromTheDialog = function(dialogId){
};
+Dialog.prototype.sortedByLastMessage = function(dialogId){
+ var self = this,
+ elem = document.getElementById(dialogId);
+ if(elem) {
+ self.dialogsListContainer.insertBefore(elem, self.dialogsListContainer.firstElementChild);
+ }
+};
+
+
var dialogModule = new Dialog();
diff --git a/samples/chat/js/helpers.js b/samples/chat/js/helpers.js
index c31913f44..87b420921 100644
--- a/samples/chat/js/helpers.js
+++ b/samples/chat/js/helpers.js
@@ -156,8 +156,8 @@ Helpers.prototype.getMessageStatus = function(message){
var self = this,
deleveredToOcuupants = self.checkIsMessageDeliveredToOccupants(message),
readedByOcuupants = self.checkIsMessageReadedByOccupants(message),
- status = !deleveredToOcuupants ? 'not delivered yet' :
- readedByOcuupants ? 'seen' : 'delivered';
+ status = !deleveredToOcuupants ? 'sent' :
+ readedByOcuupants ? 'read' : 'delivered';
return status;
@@ -224,8 +224,8 @@ Helpers.prototype.fillNewMessageParams = function (userId, msg) {
message.notification_type = msg.extension.notification_type;
}
- if(msg.extension.occupants_ids_added){
- message.occupants_ids_added = msg.extension.occupants_ids_added;
+ if(msg.extension.new_occupants_ids){
+ message.new_occupants_ids = msg.extension.new_occupants_ids;
}
message.status = (userId !== app.user.id) ? self.getMessageStatus(message) : undefined;
diff --git a/samples/chat/js/listeners.js b/samples/chat/js/listeners.js
index 52bd531f6..cfdf5d28f 100644
--- a/samples/chat/js/listeners.js
+++ b/samples/chat/js/listeners.js
@@ -21,12 +21,19 @@
function Listeners() {};
Listeners.prototype.onMessageListener = function (userId, message) {
- if(userId === app.user.id) return false;
var self = this,
msg = helpers.fillNewMessageParams(userId, message),
dialog = dialogModule._cache[message.dialog_id];
+ if (dialog) {
+ dialogModule.sortedByLastMessage(message.dialog_id);
+ }
+
+ if(userId === app.user.id){
+ return false;
+ }
+
if(message.markable){
messageModule.sendDeliveredStatus(msg._id, userId, msg.chat_dialog_id);
}
@@ -41,11 +48,14 @@ Listeners.prototype.onMessageListener = function (userId, message) {
var activeTab = document.querySelector('.j-sidebar__tab_link.active'),
tabType = activeTab.dataset.type,
- dialogType = dialog.type === 1 ? 'public' : 'chat';
+ dialogType = dialog.type === 1 ? 'public' : 'chat',
+ isActiveTab = tabType === dialogType;
- if(tabType === dialogType){
+ if(isActiveTab) {
dialogModule.renderDialog(dialog, true);
+ }
+ if(isActiveTab || message.dialog_id === dialogModule.dialogId ){
if (dialogModule.dialogId === msg.chat_dialog_id) {
messageModule.renderMessage(msg, true);
} else {
@@ -79,14 +89,14 @@ Listeners.prototype.onNotificationMessage = function(userId, message){
dialog = dialogModule._cache[message.dialog_id],
extension = message.extension,
dialogId = message.dialog_id,
- occupantsIdsAdded = extension.occupants_ids_added && extension.occupants_ids_added.split(',');
+ occupantsIdsAdded = extension.new_occupants_ids && extension.new_occupants_ids.split(',');
- if(extension.notification_type === CONSTANTS.NOTIFICATION_TYPES.UPDATE_DIALOG){
- if (extension.occupants_ids_removed) {
+ if(message.extension && ['2','3'].indexOf(message.extension.notification_type) !== -1){
+ if (message.extension.notification_type === '3') {
dialogModule._cache[dialogId].users = dialogModule._cache[dialogId].users.filter(function(user){
return user !== userId;
});
- } else if(extension.occupants_ids_added) {
+ } else if(extension.new_occupants_ids) {
_.each(occupantsIdsAdded, function(userId) {
if (dialog.users.indexOf(+userId) === -1) {
dialog.users.push(+userId);
@@ -133,7 +143,6 @@ Listeners.prototype.onMessageTypingListener = function (isTyping, userId, dialog
Listeners.prototype.onSystemMessageListener = function (message) {
var dialog = dialogModule._cache[message.dialog_id || message.extension.dialog_id];
-
if (message.extension && message.extension.notification_type === CONSTANTS.NOTIFICATION_TYPES.NEW_DIALOG) {
if (message.extension.dialog_id) {
dialogModule.getDialogById(message.extension.dialog_id).then(function (dialog) {
@@ -149,13 +158,12 @@ Listeners.prototype.onSystemMessageListener = function (message) {
});
}
return false;
- } else if(message.extension && message.extension.notification_type === CONSTANTS.NOTIFICATION_TYPES.UPDATE_DIALOG) {
+ } else if(message.extension && ['2','3'].indexOf(message.extension.notification_type) !== -1 ) {
if(!dialog){
dialogModule.getDialogById(message.extension.dialog_id).then(function (dialog) {
dialogModule._cache[dialog._id] = helpers.compileDialogParams(dialog);
var type = dialog.type === 1 ? 'public' : 'chat',
activeTab = document.querySelector('.j-sidebar__tab_link.active');
-
if (activeTab && type === activeTab.dataset.type) {
dialogModule.renderDialog(dialogModule._cache[dialog._id], true);
}
@@ -182,15 +190,13 @@ Listeners.prototype.onSentMessageCallback = function (messageLost, messageSent)
var message = messageSent || messageLost,
data = {
_id: message.id,
- dialogId: message.extension.dialog_id
+ dialogId: message.extension.dialog_id,
+ status: 'sent'
};
if (messageLost) {
// message was not sent to the chat.
- data.status = 'not sent';
- } else {
- // message was sent to the chat but not delivered to che opponent.
- data.status = 'not delivered yet';
+ data.status = 'not ' + data.status;
}
messageModule.setMessageStatus(data);
@@ -202,7 +208,7 @@ Listeners.prototype.onReadStatusListener = function (messageId, dialogId, userId
_id: messageId,
dialogId: dialogId,
userId: userId,
- status: 'seen'
+ status: 'read'
};
messageModule.setMessageStatus(data);
diff --git a/samples/chat/js/login.js b/samples/chat/js/login.js
index d8f8c20c5..e6ea92da2 100644
--- a/samples/chat/js/login.js
+++ b/samples/chat/js/login.js
@@ -97,7 +97,10 @@ Login.prototype.login = function (user) {
function loginError(error){
self.renderLoginPage();
console.error(error);
- alert(error + "\n" + error.detail);
+ var message = Object.keys(error.detail).map(function (key) {
+ return key + ' ' + error.detail[key].join('')
+ })
+ alert(message);
reject(error);
}
});
@@ -122,26 +125,25 @@ Login.prototype.renderLoadingPage = function(){
Login.prototype.setListeners = function(){
var self = this,
loginForm = document.forms.loginForm,
- formInputs = [loginForm.userName, loginForm.userGroup],
+ formInputs = [loginForm.userName, loginForm.userLogin],
loginBtn = loginForm.login_submit;
loginForm.addEventListener('submit', function(e){
e.preventDefault();
- if(loginForm.hasAttribute('disabled')){
+ if(loginForm.hasAttribute('disabled') || !loginForm.userName.isValid || !loginForm.userLogin.isValid){
return false;
} else {
loginForm.setAttribute('disabled', true);
}
var userName = loginForm.userName.value.trim(),
- userGroup = loginForm.userGroup.value.trim();
+ userLogin = loginForm.userLogin.value.trim();
var user = {
- login: helpers.getUui(),
+ login: userLogin,
password: 'webAppPass',
- full_name: userName,
- tag_list: userGroup
+ full_name: userName
};
localStorage.setItem('user', JSON.stringify(user));
@@ -176,14 +178,24 @@ Login.prototype.setListeners = function(){
}
});
- i.addEventListener('input', function(){
+ i.addEventListener('input', function(e){
var userName = loginForm.userName.value.trim(),
- userGroup = loginForm.userGroup.value.trim();
- if(userName.length >=3 && userGroup.length >= 3){
- loginBtn.removeAttribute('disabled');
- } else {
- loginBtn.setAttribute('disabled', true);
- }
+ userLogin = loginForm.userLogin.value.trim();
+
+ loginForm.userName.isValid = 15 >= userName.length && userName.length >=3;
+ loginForm.userLogin.isValid = 15 >= userLogin.length && userLogin.length >= 3 && (userLogin.match(/^[a-zA-Z]{1}[a-zA-Z0-9]+$/)!=null);
+
+ formInputs.forEach(function(e) {
+ var container = e.parentElement;
+ if(e.isValid){
+ container.classList.remove('error');
+ }else{
+ container.classList.add('error');
+ }
+ });
+
+ loginBtn.removeAttribute('disabled');
+
})
});
};
diff --git a/samples/chat/js/message.js b/samples/chat/js/message.js
index 1095c9ea9..d07bff349 100644
--- a/samples/chat/js/message.js
+++ b/samples/chat/js/message.js
@@ -196,6 +196,7 @@ Message.prototype.getMessages = function (dialogId) {
if (dialogModule._cache[dialogId].type === 1) {
self.checkUsersInPublicDialogMessages(messages.items, params.skip);
} else {
+
for (var i = 0; i < messages.items.length; i++) {
var message = helpers.fillMessagePrams(messages.items[i]);
@@ -260,7 +261,10 @@ Message.prototype.sendReadStatus = function(messageId, userId, dialogId){
dialogId: dialogId
};
- QB.chat.sendReadStatus(params);
+ if (document.visibilityState === 'visible') {
+ QB.chat.sendReadStatus(params);
+ }
+
};
Message.prototype.renderMessage = function (message, setAsFirst) {
@@ -281,7 +285,8 @@ Message.prototype.renderMessage = function (message, setAsFirst) {
messagesHtml = helpers.fillTemplate('tpl_notificationMessage', {
id: message._id,
- text: messageText
+ text: messageText,
+ date_sent: message.date_sent
});
} else {
messageText = message.message ? helpers.fillMessageBody(message.message || '') : helpers.fillMessageBody(message.body || '');
@@ -364,6 +369,27 @@ Message.prototype.renderMessage = function (message, setAsFirst) {
self.container.scrollTop += containerHeightAfterAppend - containerHeightBeforeAppend;
}
}
+
+ var currentDialog = dialogModule._cache[dialogId],
+ date = new Date(message.created_at),
+ month = date.toLocaleString('en-us', { month: 'long' }),
+ template = helpers.fillTemplate('tpl_date_message', {'month':month, 'date':date}),
+ elemDate = helpers.toHtml(template)[0],
+ tmpElem = document.querySelector('#'+month+'-'+date.getDate());
+
+ currentDialog.tplDateMessage = currentDialog.tplDateMessage?currentDialog.tplDateMessage:{};
+
+ if(!currentDialog.tplDateMessage[month+'/'+ date.getDate()] ||
+ parseInt(currentDialog.tplDateMessage[month+'/'+ date.getDate()].replace(/:/, '')) >
+ parseInt(message.date_sent.replace(/:/, ''))
+ ){
+ if(tmpElem){
+ tmpElem.remove();
+ }
+ currentDialog.tplDateMessage[month+'/'+ date.getDate()] = message.date_sent;
+ self.container.insertBefore(elemDate,elem);
+ }
+
};
Message.prototype.prepareToUpload = function (e) {
diff --git a/samples/chat/js/route.js b/samples/chat/js/route.js
index e78cafed6..cb932f56d 100644
--- a/samples/chat/js/route.js
+++ b/samples/chat/js/route.js
@@ -46,33 +46,40 @@ router.on({
dialogModule.loadDialogs('chat');
}
},
- '/dialog/create': function(){
- if (!loginModule.isLogin){
- loginModule.init().then(function(isLogedIn){
- if(!isLogedIn){
+ '/dialog/create': {
+ uses: function() {
+ if (!loginModule.isLogin){
+ loginModule.init().then(function(isLogedIn){
+ if(!isLogedIn){
+ router.navigate('/login');
+ return;
+ }
+ if(!app.isDashboardLoaded) {
+ app.renderDashboard('chat');
+ dialogModule.loadDialogs('chat');
+ }
+ _renderNewDialogTmp();
+ }).catch(function(error){
+ console.error(error);
router.navigate('/login');
- return;
- }
- if(!app.isDashboardLoaded) {
- app.renderDashboard('chat');
- dialogModule.loadDialogs('chat');
- }
+ });
+ } else {
_renderNewDialogTmp();
- }).catch(function(error){
- console.error(error);
- router.navigate('/login');
- });
- } else {
- _renderNewDialogTmp();
- }
+ }
- function _renderNewDialogTmp(){
- var createDialogTab = document.querySelector('.j-sidebar__create_dialog');
+ function _renderNewDialogTmp(){
+ var createDialogTab = document.querySelector('.j-sidebar__create_dialog');
- createDialogTab.classList.add('active');
- app.sidebar.classList.remove('active');
+ createDialogTab.classList.add('active');
+ app.sidebar.classList.remove('active');
- app.buildCreateDialogTpl();
+ app.buildCreateDialogTpl();
+ }
+ },
+ hooks: {
+ leave: function () {
+ userModule.reset()
+ }
}
},
'/dialog/:dialogId': function(params){
@@ -101,196 +108,195 @@ router.on({
function _renderSelectedDialog(){
var currentDialog = dialogModule._cache[dialogId];
- if(!currentDialog){
- dialogModule.getDialogById(dialogId).then(function(dialog){
- var tabDataType = dialog.type === CONSTANTS.DIALOG_TYPES.PUBLICCHAT ? 'public' : 'chat',
- tab = document.querySelector('.j-sidebar__tab_link[data-type="' + tabDataType + '"]');
-
- app.loadChatList(tab).then(function(){
+ if(currentDialog) {
+ dialogModule.selectCurrentDialog(dialogId);
+ }
+ dialogModule.getDialogById(dialogId).then(function(dialog){
+ var tabDataType = dialog.type === CONSTANTS.DIALOG_TYPES.PUBLICCHAT ? 'public' : 'chat',
+ tab = document.querySelector('.j-sidebar__tab_link[data-type="' + tabDataType + '"]');
+ if(!currentDialog) {
+ app.loadChatList(tab).then(function () {
dialogModule.renderMessages(dialogId);
app.sidebar.classList.remove('active');
- }).catch(function(error){
+ }).catch(function (error) {
console.error(error);
});
-
- }).catch(function(error){
- console.error(error);
- var tab = document.querySelector('.j-sidebar__tab_link[data-type="chat"]');
- app.loadChatList(tab)
- router.navigate('/dashboard');
- });
- } else {
- dialogModule.renderMessages(dialogId);
- dialogModule.selectCurrentDialog(dialogId);
- }
- }
- },
- '/dialog/:dialogId/edit': function(params){
- var dialogId = params.dialogId;
- var currentDialog = null;
-
- if (!loginModule.isLogin){
- loginModule.init().then(function(isLogedIn){
- if(!isLogedIn){
- router.navigate('/login');
- return;
+ }else if(tabDataType === 'chat') {
+ userModule.getUsersByIds(currentDialog.users).then(function () {
+ document.getElementById(dialogId).querySelector('.dialog__name').innerHTML = dialog.name;
+ dialogModule.renderMessages(dialogId);
+ }).catch(function (error) {
+ console.error(error);
+ });
+ }else{
+ dialogModule.renderMessages(dialogId);
}
- _renderEditDialogPage();
}).catch(function(error){
console.error(error);
- router.navigate('/login');
+ var tab = document.querySelector('.j-sidebar__tab_link[data-type="chat"]');
+ app.loadChatList(tab);
+ router.navigate('/dashboard');
});
- } else {
- _renderEditDialogPage();
- }
- function _renderEditDialogPage(){
- if(!app.isDashboardLoaded) {
- app.renderDashboard();
- }
- currentDialog = dialogModule._cache[dialogId];
-
- if(!currentDialog){
- dialogModule.dialogId = dialogId;
- dialogModule.getDialogById(dialogId).then(function(dialog){
- var tabDataType = dialog.type === CONSTANTS.DIALOG_TYPES.PUBLICCHAT ? 'public' : 'chat',
- tab = document.querySelector('.j-sidebar__tab_link[data-type="' + tabDataType + '"]');
- // add to dialog template
- app.content.innerHTML = helpers.fillTemplate('tpl_UpdateDialogContainer', {title: dialog.name, _id: dialog._id});
- _setEditDiaogListeners();
- _renderUsers(dialog.occupants_ids);
- app.loadChatList(tab).then(function(){})
- .catch(function(error){
- console.error(error);
- });
- }).catch(function(error){
- router.navigate('#!/dashboard');
- });
- } else {
- app.content.innerHTML = helpers.fillTemplate('tpl_UpdateDialogContainer', {title: currentDialog.name, _id: currentDialog._id});
- _setEditDiaogListeners();
- _renderUsers(currentDialog.users);
- }
}
- function _renderUsers(dialogOccupants){
- var userList = document.querySelector('.j-update_chat__user_list'),
- counterElem = document.querySelector('.j-update__chat_counter'),
- addUsersBtn = document.querySelector('.j-update_dialog_btn'),
+ document.addEventListener('visibilitychange', function() {
+ var currentDialog = dialogModule._cache[dialogId],
+ dialogType = currentDialog.type === 1 ? 'public' : 'chat';
- newUsersCount = +counterElem.innerText.trim();
+ if (document.visibilityState !== 'visible') {
+ dialogType = currentDialog.type === 1 ? 'chat' : 'public';
+ }
- userModule.getUsers().then(function(usersArray){
- var users = usersArray.map(function(user){
- var userItem = JSON.parse(JSON.stringify(user));
+ var tab = document.querySelector('.j-sidebar__tab_link[data-type="'+dialogType+'"]');
+ app.loadChatList(tab).then(function () {
+ if (document.visibilityState === 'visible'
+ && window.location.href.match(/\/dialog\/[a-zA-Z0-9]+$/)
+ && !window.location.href.match(/\/dialog\/create$/)) {
+ dialogModule.renderMessages(dialogModule.dialogId);
+ }
+ });
+ });
- userItem.selected = dialogOccupants.indexOf(userItem.id) !== -1;
-
- return userItem;
+ },
+ '/dialog/:dialogId/edit': {
+ uses: function(params) {
+ var dialogId = params.dialogId;
+ var currentDialog = null;
+
+ if (!loginModule.isLogin){
+ loginModule.init().then(function(isLogedIn){
+ if(!isLogedIn){
+ router.navigate('/login');
+ return;
+ }
+ _renderEditDialogPage();
+ }).catch(function(error){
+ console.error(error);
+ router.navigate('/login');
});
+ } else {
+ _renderEditDialogPage();
+ }
- _.each(users, function(user){
- var userTpl = helpers.fillTemplate('tpl_editChatUser', user),
- userElem = helpers.toHtml(userTpl)[0];
-
- userElem.addEventListener('click', function(e){
- var elem = e.currentTarget;
- if(elem.classList.contains('disabled')) return;
- if(elem.classList.contains('selected')){
- elem.classList.remove('selected');
- newUsersCount--;
- } else {
- elem.classList.add('selected');
- newUsersCount++;
- }
-
- counterElem.innerText = newUsersCount;
-
- addUsersBtn.disabled = !newUsersCount;
+ function _renderEditDialogPage(){
+ if(!app.isDashboardLoaded) {
+ app.renderDashboard();
+ }
+ currentDialog = dialogModule._cache[dialogId];
+
+ if(!currentDialog) {
+ dialogModule.dialogId = dialogId;
+ dialogModule.getDialogById(dialogId).then(function(dialog) {
+ var tabDataType = dialog.type === CONSTANTS.DIALOG_TYPES.PUBLICCHAT ? 'public' : 'chat',
+ tab = document.querySelector('.j-sidebar__tab_link[data-type="' + tabDataType + '"]');
+ // add to dialog template
+ app.content.innerHTML = helpers.fillTemplate('tpl_UpdateDialogContainer', {title: dialog.name, _id: dialog._id});
+ _renderUsers(dialog.occupants_ids).then(_setEditDialogListeners);
+ app.loadChatList(tab).then(function(){})
+ .catch(function(error){
+ console.error(error);
+ });
+ }).catch(function(error){
+ router.navigate('#!/dashboard');
});
-
- userList.appendChild(userElem);
- });
-
- }).catch(function(error){
- console.error(error);
- });
- }
-
- function _setEditDiaogListeners(){
- var editTitleBtn = document.querySelector('.j-update_chat__title_button'),
- editTitleForm = document.forms.update_chat_name,
- editTitleInput = editTitleForm.update_chat__title,
- editUsersCountForm = document.forms.update_dialog,
- canselBtn = editUsersCountForm.update_dialog_cancel;
-
- // change Title listener
- editTitleBtn.addEventListener('click', function(e){
- e.preventDefault();
- e.stopPropagation();
-
-
- editTitleForm.classList.toggle('active');
-
- if(editTitleForm.classList.contains('active')){
- editTitleInput.removeAttribute('disabled');
- editTitleInput.focus();
} else {
- editTitleInput.setAttribute('disabled', true);
- _updateDialogTitleRequest();
+ app.content.innerHTML = helpers.fillTemplate('tpl_UpdateDialogContainer', {title: currentDialog.name, _id: currentDialog._id});
+ _renderUsers(currentDialog.users).then(_setEditDialogListeners);
}
- });
+ }
- editTitleInput.addEventListener('input', function(e){
- var titleText = editTitleInput.value,
- sylmbolsCount = titleText.length;
- if(sylmbolsCount > 40) {
- editTitleInput.value = titleText.slice(0, 40);
- }
- });
+ function _renderUsers(dialogOccupants){
+ userModule.selectedUserIds = dialogOccupants.slice();
+ userModule.disabledUserIds = dialogOccupants.slice();
+ return userModule.initGettingUsers('.j-update_chat__user_list');
+ }
- editTitleForm.addEventListener('submit', function (e) {
- e.preventDefault();
+ function _setEditDialogListeners(){
+ var editTitleBtn = document.querySelector('.j-update_chat__title_button'),
+ editTitleForm = document.forms.update_chat_name,
+ addUsersBtn = document.querySelector('.j-update_dialog_btn'),
+ counterElem = document.querySelector('.j-update__chat_counter'),
+ editTitleInput = editTitleForm.update_chat__title,
+ userList = document.querySelector('.j-update_chat__user_list'),
+ editUsersCountForm = document.forms.update_dialog,
+ canselBtn = editUsersCountForm.update_dialog_cancel;
+
+ // change Title listener
+ editTitleBtn.addEventListener('click', function(e){
+ e.preventDefault();
+ e.stopPropagation();
+
+
+ editTitleForm.classList.toggle('active');
+
+ if(editTitleForm.classList.contains('active')){
+ editTitleInput.removeAttribute('disabled');
+ editTitleInput.focus();
+ } else {
+ editTitleInput.setAttribute('disabled', true);
+ _updateDialogTitleRequest();
+ }
+ });
- _updateDialogTitleRequest();
- });
+ editTitleInput.addEventListener('input', function(e){
+ var titleText = editTitleInput.value,
+ sylmbolsCount = titleText.length;
+ if(sylmbolsCount > 40) {
+ editTitleInput.value = titleText.slice(0, 40);
+ }
+ });
- editUsersCountForm.addEventListener('submit', function(e){
- e.preventDefault();
+ userList.addEventListener('click', function (e) {
+ if (e.target.classList.contains('disabled')) return;
+ var addUsersCount = userModule.selectedUserIds.filter(function (userId) {
+ return userModule.disabledUserIds.indexOf(userId) === -1;
+ }).length;
+ counterElem.innerText = addUsersCount;
+ addUsersBtn.disabled = addUsersCount === 0;
+ });
- var userItemsList = document.querySelectorAll('.user__item.selected:not(.disabled)'),
- userList = [];
+ editTitleForm.addEventListener('submit', function (e) {
+ e.preventDefault();
- _.each(userItemsList, function(userItem){
- userList.push(+userItem.id);
+ _updateDialogTitleRequest();
});
- var params = {
- id: dialogId,
- userList: userList
- };
+ editUsersCountForm.addEventListener('submit', function(e){
+ e.preventDefault();
- dialogModule.updateDialog(params);
- });
+ var params = {
+ id: dialogId,
+ userList: userModule.selectedUserIds
+ };
- canselBtn.addEventListener('click', function(e){
- e.preventDefault();
- e.stopPropagation();
- router.navigate('/dialog/' + dialogId);
- });
+ dialogModule.updateDialog(params);
+ });
- function _updateDialogTitleRequest(){
- var params = {
- id: dialogId,
- title: editTitleInput.value.trim()
- };
+ canselBtn.addEventListener('click', function(e){
+ e.preventDefault();
+ e.stopPropagation();
+ router.navigate('/dialog/' + dialogId);
+ });
- if(dialogModule._cache[dialogId].name !== params.title) {
- dialogModule.updateDialog(params);
- editTitleForm.classList.remove('active');
- editTitleInput.setAttribute('disabled', true);
+ function _updateDialogTitleRequest(){
+ var params = {
+ id: dialogId,
+ title: editTitleInput.value.trim()
+ };
+
+ if(dialogModule._cache[dialogId].name !== params.title) {
+ dialogModule.updateDialog(params);
+ editTitleForm.classList.remove('active');
+ editTitleInput.setAttribute('disabled', true);
+ }
}
}
+ },
+ hooks: {
+ leave: function () {
+ userModule.reset()
+ }
}
}
}).resolve();
diff --git a/samples/chat/js/user.js b/samples/chat/js/user.js
index 0156e6b57..0959444fa 100644
--- a/samples/chat/js/user.js
+++ b/samples/chat/js/user.js
@@ -2,26 +2,176 @@
function User() {
this._cache = {};
+ this.selectedUserIds = [];
this.userListConteiner = null;
this.content = null;
-}
+ this.userListFilter = null;
+ this.disabledUserIds = [];
+ this._isFetching = false;
-User.prototype.initGettingUsers = function () {
var self = this;
- self.content = document.querySelector('.j-content');
- self.userListConteiner = document.querySelector('.j-group_chat__user_list');
+ var fullName = '';
+ var currentPage = 1;
+ var totalPages = 1;
+ var timeout;
- self.userListConteiner.classList.add('loading');
+ function getUsersFilteredByName () {
+ helpers.clearView(self.userListConteiner);
+ self.getUsers({ page: 1 });
+ };
- self.getUsers().then(function(userList){
- _.each(userList, function(user){
- self.buildUserItem(self._cache[user.id]);
+ /**
+ * @typedef GetUsersParam
+ * @type {object}
+ * @property {string} full_name name of user to search by
+ * @property {string} order see [API docs]{@link https://quickblox.com/developers/Users#Sort} for more info on order format
+ * @property {number} page number of page to show
+ * @property {number} per_page limit of items to show per page
+ */
+ /**
+ * Gets users from API
+ * @param {GetUsersParam} args
+ * @returns {Promise} promise resolved with list of users or rejected with error
+ */
+ var _getUsers = function (args) {
+ if (typeof args !== 'object') {
+ args = {}
+ }
+ var params = {
+ filter: {
+ field: 'full_name',
+ param: 'in',
+ value: [args.full_name || fullName]
+ },
+ order: args.order || {
+ field: 'updated_at',
+ sort: 'desc'
+ },
+ page: args.page || currentPage,
+ per_page: args.per_page || 100
+ };
+
+ return new Promise(function (resolve, reject) {
+ self._isFetching = true;
+ QB.users.listUsers(params, function (err, responce) {
+ if (err) {
+ self._isFetching = false;
+ return reject(err);
+ }
+ currentPage = responce.current_page;
+ totalPages = Math.ceil(responce.total_entries / responce.per_page);
+ var userList = responce.items.map(function(data){
+ return self.addToCache(data.user);
+ });
+
+ self._isFetching = false;
+ resolve(userList);
+ });
});
- self.userListConteiner.classList.remove('loading');
- }).catch(function(error){
- self.userListConteiner.classList.remove('loading');
- });
+ };
+
+ /**
+ * Toggles loading state for users list element, load users and append results to the list of users
+ * @param {GetUsersParam} args search / filter criteria
+ * @param {boolean} [renderUsers=true] wheter to render fetched users (`true` by default)
+ */
+ this.getUsers = function (args, renderUsers) {
+ var usersListEl = self.userListConteiner;
+ usersListEl && usersListEl.classList.add('loading');
+ return new Promise(function (resolve, reject) {
+ _getUsers.call(self, args)
+ .then(function (users) {
+ if (renderUsers !== false) {
+ users.forEach(function (user) {
+ self.buildUserItem(self._cache[user.id]);
+ });
+ }
+ usersListEl && usersListEl.classList.remove('loading');
+ resolve(users);
+ })
+ .catch(function (err) {
+ usersListEl && usersListEl.classList.remove('loading');
+ reject(err);
+ });
+ })
+ };
+
+ this.filter = function eventHandler (e) {
+ fullName = e.target.value;
+ if (timeout) {
+ clearTimeout(timeout);
+ timeout = undefined;
+ }
+ timeout = setTimeout(getUsersFilteredByName, 600);
+ };
+
+ this.scrollHandler = function (e) {
+ var item = e.target.children.length
+ ? e.target.children[0]
+ : undefined;
+ var itemHeight = item ? item.getBoundingClientRect().height : 0;
+ var isFetching = self._isFetching;
+ var scrolledToEnd = (
+ e.target.clientHeight + e.target.scrollTop >= e.target.scrollHeight - itemHeight
+ );
+ var shouldLoadNextPage = scrolledToEnd && !isFetching;
+ var notLastPage = currentPage < totalPages;
+ if (shouldLoadNextPage && notLastPage) {
+ self.getUsers({ page: currentPage + 1 });
+ }
+ };
+
+ this.reset = function () {
+ currentPage = 1;
+ fullName = '';
+ self.selectedUserIds = [];
+ self.disabledUserIds = [];
+ self._isFetching = false;
+ self.userListContainer = null;
+ self.userListFilter = null;
+ }
+}
+
+/**
+ * @param {string | HTMLElement} userListContainer HTMLElement or selector string (optional)
+ * @param {string | HTMLElement} userListFilter HTMLElement or selector string (optional)
+ */
+User.prototype.initGettingUsers = function (userListContainer, userListFilter) {
+ var userListSelector = '.j-group_chat__user_list';
+ var userListFilterSelector = '.group_chat__filter > input';
+ if (userListContainer) {
+ if (userListContainer instanceof HTMLElement) {
+ this.userListConteiner = userListContainer;
+ } else {
+ if (typeof userListContainer === 'string') {
+ userListSelector = userListContainer;
+ }
+ this.userListConteiner = document.querySelector(userListSelector);
+ }
+ } else {
+ this.userListConteiner = document.querySelector(userListSelector);
+ }
+ if (userListFilter) {
+ if (userListFilter instanceof HTMLElement) {
+ this.userListFilter = userListFilter;
+ } else {
+ if (typeof userListFilter === 'string') {
+ userListFilterSelector = userListFilter;
+ }
+ this.userListFilter = document.querySelector(userListFilterSelector)
+ }
+ } else {
+ this.userListFilter = document.querySelector(userListFilterSelector);
+ }
+
+ this.userListConteiner &&
+ this.userListConteiner.addEventListener('scroll', this.scrollHandler);
+
+ this.userListFilter &&
+ this.userListFilter.addEventListener('input', this.filter);
+
+ return this.getUsers();
};
User.prototype.addToCache = function(user) {
@@ -34,10 +184,11 @@ User.prototype.addToCache = function(user) {
color: _.random(1, 10),
last_request_at: user.last_request_at
};
- } else {
- self._cache[id].last_request_at = user.last_request_at;
+ }else if(self._cache[id].name !== user.full_name ){
+ self._cache[id].name = user.full_name;
}
+ self._cache[id].last_request_at = user.last_request_at;
return self._cache[id];
};
@@ -53,8 +204,10 @@ User.prototype.getUsersByIds = function (userList) {
};
return new Promise(function(resolve, reject) {
+ self._isFetching = true;
QB.users.listUsers(params, function (err, responce) {
if (err) {
+ self._isFetching = false;
reject(err);
} else {
var users = responce.items;
@@ -68,60 +221,55 @@ User.prototype.getUsersByIds = function (userList) {
self.addToCache(user.user);
}
});
+ self._isFetching = false;
resolve();
}
});
});
};
-User.prototype.getUsers = function () {
- var self = this,
- params = {
- tags: app.user.user_tags,
- per_page: 100
- };
-
- return new Promise(function(resolve, reject){
- QB.users.get(params, function (err, responce) {
- if (err) {
- reject(err);
- }
-
- var userList = responce.items.map(function(data){
- return self.addToCache(data.user);
- });
-
- resolve(userList);
- });
- });
-};
-
User.prototype.buildUserItem = function (user) {
var self = this,
userItem = JSON.parse(JSON.stringify(user));
- if(userItem.id === app.user.id){
+ if (userItem.id === app.user.id) {
+ userItem.selected = true;
+ }
+
+ if (this.disabledUserIds.indexOf(userItem.id) > -1) {
userItem.selected = true;
}
var userTpl = helpers.fillTemplate('tpl_newGroupChatUser', {user: userItem}),
elem = helpers.toHtml(userTpl)[0];
+
+ if (this.selectedUserIds.indexOf(userItem.id) > -1) {
+ elem.classList.add('selected');
+ }
elem.addEventListener('click', function () {
if (elem.classList.contains('disabled')) return;
-
+ var userId = +elem.getAttribute('id');
+ var index = self.selectedUserIds.indexOf(userId);
elem.classList.toggle('selected');
-
- if (self.userListConteiner.querySelectorAll('.selected').length > 1) {
- document.forms.create_dialog.create_dialog_submit.disabled = false;
+ if (index > -1) {
+ self.selectedUserIds.splice(index, 1);
} else {
- document.forms.create_dialog.create_dialog_submit.disabled = true;
+ self.selectedUserIds.push(userId);
}
+
+ if (document.forms.create_dialog) {
+ if (self.selectedUserIds.length) {
+ document.forms.create_dialog.create_dialog_submit.disabled = false;
+ } else {
+ document.forms.create_dialog.create_dialog_submit.disabled = true;
+ }
- if (self.userListConteiner.querySelectorAll('.selected').length >= 3) {
- document.forms.create_dialog.dialog_name.disabled = false;
- } else {
- document.forms.create_dialog.dialog_name.disabled = true;
+ if (self.selectedUserIds.length >= 2) {
+ document.forms.create_dialog.dialog_name.disabled = false;
+ } else {
+ document.forms.create_dialog.dialog_name.disabled = true;
+ }
}
});