Browse Source

Merge branch 'master' into message-composer

Conflicts:
	app/js/lib/ng_utils.js
master
Igor Zhukov 10 years ago
parent
commit
450dc2d537
  1. 3
      app/css/app.css
  2. 2
      app/css/desktop.css
  3. 165
      app/js/controllers.js
  4. 5
      app/js/lib/config.js
  5. 8
      app/js/lib/mtproto_wrapper.js
  6. 30
      app/js/lib/utils.js
  7. 8
      app/js/locales/en-us.json
  8. 47
      app/js/services.js
  9. 2
      app/partials/desktop/dialog.html
  10. 2
      app/partials/desktop/head.html
  11. 30
      app/partials/desktop/im.html
  12. 2
      app/partials/mobile/chat_modal.html
  13. 2
      app/partials/mobile/dialog.html
  14. 33
      app/partials/mobile/im.html

3
app/css/app.css

@ -2578,7 +2578,8 @@ a.peer_photo_init:focus {
.im_dialogs_contacts_wrap h5 { .im_dialogs_contacts_wrap h5,
.im_dialogs_messages_wrap h5 {
color: #999; color: #999;
font-size: 13px; font-size: 13px;
margin-left: 20px; margin-left: 20px;

2
app/css/desktop.css

@ -1597,7 +1597,7 @@ div.im_dialog_photo .peer_initials {
background-size: 40px 200px; background-size: 40px 200px;
width: 16px; width: 16px;
height: 24px; height: 24px;
opacity: 0.3; opacity: 0.15;
position: absolute; position: absolute;
top: 50%; top: 50%;
pointer-events: none; pointer-events: none;

165
app/js/controllers.js

@ -273,8 +273,8 @@ angular.module('myApp.controllers', ['myApp.i18n'])
if (forceSignUp) { if (forceSignUp) {
method = 'auth.signUp'; method = 'auth.signUp';
angular.extend(params, { angular.extend(params, {
first_name: $scope.credentials.first_name, first_name: $scope.credentials.first_name || '',
last_name: $scope.credentials.last_name last_name: $scope.credentials.last_name || ''
}); });
} }
@ -359,6 +359,18 @@ angular.module('myApp.controllers', ['myApp.i18n'])
}); });
}; };
$scope.openFaq = function () {
var url = 'https://telegram.org/faq';
switch (Config.I18n.locale) {
case 'es-es': url += '/es'; break;
case 'it-it': url += '/it'; break;
case 'de-de': url += '/de'; break;
case 'ko-ko': url += '/ko'; break;
case 'pt-br': url += '/br'; break;
};
window.open(url, '_blank');
};
$scope.openContacts = function () { $scope.openContacts = function () {
ContactsSelectService.selectContact().then(function (userID) { ContactsSelectService.selectContact().then(function (userID) {
$scope.dialogSelect(AppUsersManager.getUserString(userID)); $scope.dialogSelect(AppUsersManager.getUserString(userID));
@ -397,7 +409,6 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.searchClear = function () { $scope.searchClear = function () {
$scope.search.query = ''; $scope.search.query = '';
$scope.search.messages = false;
$scope.$broadcast('search_clear'); $scope.$broadcast('search_clear');
} }
@ -456,7 +467,6 @@ angular.module('myApp.controllers', ['myApp.i18n'])
if ($routeParams.q) { if ($routeParams.q) {
if ($routeParams.q !== lastSearch) { if ($routeParams.q !== lastSearch) {
$scope.search.query = lastSearch = $routeParams.q; $scope.search.query = lastSearch = $routeParams.q;
$scope.search.messages = true;
if ($scope.curDialog !== undefined) { if ($scope.curDialog !== undefined) {
return false; return false;
} }
@ -494,7 +504,8 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.dialogs = []; $scope.dialogs = [];
$scope.contacts = []; $scope.contacts = [];
$scope.foundUsers = []; $scope.foundUsers = [];
$scope.contactsLoaded = false; $scope.foundMessages = [];
if ($scope.search === undefined) { if ($scope.search === undefined) {
$scope.search = {}; $scope.search = {};
} }
@ -503,12 +514,13 @@ angular.module('myApp.controllers', ['myApp.i18n'])
} }
$scope.phonebookAvailable = PhonebookContactsService.isAvailable(); $scope.phonebookAvailable = PhonebookContactsService.isAvailable();
var offset = 0, var searchMessages = false;
maxID = 0, var maxID = 0;
hasMore = false, var hasMore = false;
jump = 0, var jump = 0;
peersInDialogs = {}, var contactsJump = 0;
contactsShown; var peersInDialogs = {};
var contactsShown;
$scope.$on('dialogs_need_more', function () { $scope.$on('dialogs_need_more', function () {
// console.log('on need more'); // console.log('on need more');
@ -539,7 +551,6 @@ angular.module('myApp.controllers', ['myApp.i18n'])
if (pos !== false) { if (pos !== false) {
var prev = $scope.dialogs.splice(pos, 1); var prev = $scope.dialogs.splice(pos, 1);
safeReplaceObject(prev, wrappedDialog); safeReplaceObject(prev, wrappedDialog);
offset++;
} }
$scope.dialogs.unshift(wrappedDialog); $scope.dialogs.unshift(wrappedDialog);
delete $scope.isEmpty.dialogs; delete $scope.isEmpty.dialogs;
@ -547,7 +558,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
if (!peersInDialogs[dialog.peerID]) { if (!peersInDialogs[dialog.peerID]) {
peersInDialogs[dialog.peerID] = true; peersInDialogs[dialog.peerID] = true;
if (contactsShown) { if (contactsShown) {
showMoreContacts(); showMoreConversations();
} }
} }
@ -573,17 +584,14 @@ angular.module('myApp.controllers', ['myApp.i18n'])
} }
}); });
var prevMessages = false;
$scope.$watchCollection('search', function () { $scope.$watchCollection('search', function () {
if ($scope.search.messages != prevMessages) { $scope.dialogs = [];
prevMessages = $scope.search.messages; $scope.foundMessages = [];
$scope.dialogs = []; searchMessages = false;
loadDialogs(true); contactsJump++;
} else { loadDialogs();
loadDialogs();
}
if ($routeParams.q && (!$scope.search.messages || $scope.search.query != $routeParams.q)) { if ($routeParams.q && $scope.search.query != $routeParams.q) {
$timeout(function () { $timeout(function () {
$location.url( $location.url(
'/im' + '/im' +
@ -609,7 +617,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.$on('contacts_update', function () { $scope.$on('contacts_update', function () {
if (contactsShown) { if (contactsShown) {
showMoreContacts(); showMoreConversations();
} }
}); });
@ -617,13 +625,12 @@ angular.module('myApp.controllers', ['myApp.i18n'])
var searchTimeoutPromise; var searchTimeoutPromise;
function getDialogs(force) { function getDialogs(force) {
var searchMessages = $scope.search.messages && $scope.search.query.length > 0, var curJump = ++jump,
curJump = ++jump,
promise; promise;
$timeout.cancel(searchTimeoutPromise); $timeout.cancel(searchTimeoutPromise);
if (searchMessages) { if (searchMessages) {
searchTimeoutPromise = force ? $q.when() : $timeout(angular.noop, 500); searchTimeoutPromise = (force || maxID) ? $q.when() : $timeout(angular.noop, 500);
promise = searchTimeoutPromise.then(function () { promise = searchTimeoutPromise.then(function () {
return AppMessagesManager.getSearch({_: 'inputPeerEmpty'}, $scope.search.query, {_: 'inputMessagesFilterEmpty'}, maxID); return AppMessagesManager.getSearch({_: 'inputPeerEmpty'}, $scope.search.query, {_: 'inputMessagesFilterEmpty'}, maxID);
}); });
@ -675,29 +682,38 @@ angular.module('myApp.controllers', ['myApp.i18n'])
}; };
function loadDialogs (force) { function loadDialogs (force) {
offset = 0;
maxID = 0; maxID = 0;
hasMore = false; hasMore = false;
peersInDialogs = {}; if (!searchMessages) {
contactsShown = false; peersInDialogs = {};
contactsShown = false;
}
getDialogs(force).then(function (dialogsResult) { getDialogs(force).then(function (dialogsResult) {
$scope.dialogs = []; if (!searchMessages) {
$scope.contacts = []; $scope.dialogs = [];
$scope.foundUsers = []; $scope.contacts = [];
$scope.foundUsers = [];
if (dialogsResult.dialogs.length) { }
offset += dialogsResult.dialogs.length; $scope.foundMessages = [];
maxID = dialogsResult.dialogs[dialogsResult.dialogs.length - 1].top_message; var dialogsList = searchMessages ? $scope.foundMessages : $scope.dialogs;
hasMore = dialogsResult.count === null || offset < dialogsResult.count;
if (dialogsResult.dialogs.length) {
angular.forEach(dialogsResult.dialogs, function (dialog) { angular.forEach(dialogsResult.dialogs, function (dialog) {
peersInDialogs[dialog.peerID] = true;
var wrappedDialog = AppMessagesManager.wrapForDialog(dialog.top_message, dialog.unread_count); var wrappedDialog = AppMessagesManager.wrapForDialog(dialog.top_message, dialog.unread_count);
$scope.dialogs.push(wrappedDialog); if (!searchMessages) {
peersInDialogs[dialog.peerID] = true;
}
dialogsList.push(wrappedDialog);
}); });
delete $scope.isEmpty.dialogs;
maxID = dialogsResult.dialogs[dialogsResult.dialogs.length - 1].top_message;
hasMore = dialogsResult.count === null || dialogsList.length < dialogsResult.count;
if (!searchMessages) {
delete $scope.isEmpty.dialogs;
}
} }
$scope.$broadcast('ui_dialogs_change'); $scope.$broadcast('ui_dialogs_change');
@ -715,12 +731,42 @@ angular.module('myApp.controllers', ['myApp.i18n'])
}); });
} }
function showMoreContacts () { function showMoreDialogs () {
if (contactsShown && (!hasMore || !maxID)) {
return;
}
if (!hasMore && !searchMessages && ($scope.search.query || !$scope.dialogs.length)) {
showMoreConversations();
return;
}
getDialogs().then(function (dialogsResult) {
if (dialogsResult.dialogs.length) {
var dialogsList = searchMessages ? $scope.foundMessages : $scope.dialogs;
angular.forEach(dialogsResult.dialogs, function (dialog) {
var wrappedDialog = AppMessagesManager.wrapForDialog(dialog.top_message, dialog.unread_count);
if (!searchMessages) {
peersInDialogs[dialog.peerID] = true;
}
dialogsList.push(wrappedDialog);
});
maxID = dialogsResult.dialogs[dialogsResult.dialogs.length - 1].top_message;
hasMore = dialogsResult.count === null || dialogsList.length < dialogsResult.count;
$scope.$broadcast('ui_dialogs_append');
}
});
};
function showMoreConversations () {
contactsShown = true; contactsShown = true;
var curJump = ++jump; var curJump = ++contactsJump;
AppUsersManager.getContacts($scope.search.query).then(function (contactsList) { AppUsersManager.getContacts($scope.search.query).then(function (contactsList) {
if (curJump != jump) return; if (curJump != contactsJump) return;
$scope.contacts = []; $scope.contacts = [];
angular.forEach(contactsList, function(userID) { angular.forEach(contactsList, function(userID) {
if (peersInDialogs[userID] === undefined) { if (peersInDialogs[userID] === undefined) {
@ -742,10 +788,10 @@ angular.module('myApp.controllers', ['myApp.i18n'])
if ($scope.search.query && $scope.search.query.length >= 5) { if ($scope.search.query && $scope.search.query.length >= 5) {
$timeout(function() { $timeout(function() {
if (curJump != jump) return; if (curJump != contactsJump) return;
MtpApiManager.invokeApi('contacts.search', {q: $scope.search.query, limit: 10}).then(function (result) { MtpApiManager.invokeApi('contacts.search', {q: $scope.search.query, limit: 10}).then(function (result) {
AppUsersManager.saveApiUsers(result.users); AppUsersManager.saveApiUsers(result.users);
if (curJump != jump) return; if (curJump != contactsJump) return;
$scope.foundUsers = []; $scope.foundUsers = [];
angular.forEach(result.results, function(contactFound) { angular.forEach(result.results, function(contactFound) {
var userID = contactFound.user_id; var userID = contactFound.user_id;
@ -764,33 +810,12 @@ angular.module('myApp.controllers', ['myApp.i18n'])
}); });
}, 500); }, 500);
} }
}
function showMoreDialogs () { if ($scope.search.query) {
if (contactsShown && (!hasMore || !offset)) { searchMessages = true;
return; loadDialogs();
}
if (!hasMore && !$scope.search.messages && ($scope.search.query || !$scope.dialogs.length)) {
showMoreContacts();
return;
} }
}
getDialogs().then(function (dialogsResult) {
if (dialogsResult.dialogs.length) {
offset += dialogsResult.dialogs.length;
maxID = dialogsResult.dialogs[dialogsResult.dialogs.length - 1].top_message;
hasMore = dialogsResult.count === null || offset < dialogsResult.count;
angular.forEach(dialogsResult.dialogs, function (dialog) {
peersInDialogs[dialog.peerID] = true;
$scope.dialogs.push(AppMessagesManager.wrapForDialog(dialog.top_message, dialog.unread_count));
});
$scope.$broadcast('ui_dialogs_append');
}
});
};
}) })

5
app/js/lib/config.js

File diff suppressed because one or more lines are too long

8
app/js/lib/mtproto_wrapper.js

@ -467,6 +467,14 @@ angular.module('izhukov.mtproto.wrapper', ['izhukov.utils', 'izhukov.mtproto'])
writeFileDeferred; writeFileDeferred;
if (fileWriter.length) { if (fileWriter.length) {
startOffset = fileWriter.length; startOffset = fileWriter.length;
if (startOffset >= size) {
if (toFileEntry) {
deferred.resolve(fileWriter.finalize());
} else {
deferred.resolve(cachedDownloads[fileName] = fileWriter.finalize());
}
return;
}
fileWriter.seek(startOffset); fileWriter.seek(startOffset);
deferred.notify({done: startOffset, total: size}); deferred.notify({done: startOffset, total: size});
} }

30
app/js/lib/utils.js

@ -346,16 +346,14 @@ function versionCompare (ver1, ver2) {
(function (global) { (function (global) {
var badCharsRe = /[`~!@#$%^&*()\-_=+\[\]\\|{}'";:\/?.>,<\s]+/g, var badCharsRe = /[`~!@#$%^&*()\-_=+\[\]\\|{}'";:\/?.>,<\s]+/g,
trimRe = /^\s+|\s$/g, trimRe = /^\s+|\s$/g;
accentsReplace = {
a: /[åáâäà]/g, return {
e: /[éêëè]/g, createIndex: createIndex,
i: /[íîïì]/g, indexObject: indexObject,
o: /[óôöò]/g, cleanSearchText: cleanSearchText,
u: /[úûüù]/g, search: search
c: /ç/g, };
ss: /ß/g
};
function createIndex () { function createIndex () {
return { return {
@ -365,13 +363,11 @@ function versionCompare (ver1, ver2) {
} }
function cleanSearchText (text) { function cleanSearchText (text) {
text = text.replace(badCharsRe, ' ').replace(trimRe, '').toLowerCase(); text = text.replace(badCharsRe, ' ').replace(trimRe, '');
text = text.replace(/[^A-Za-z0-9]/g, function (ch) {
for (var key in accentsReplace) { return Config.LatinizeMap[ch] || ch;
if (accentsReplace.hasOwnProperty(key)) { });
text = text.replace(accentsReplace[key], key); text = text.toLowerCase();
}
}
return text; return text;
} }

8
app/js/locales/en-us.json

@ -22,7 +22,7 @@
"group_modal_settings": "Settings", "group_modal_settings": "Settings",
"group_modal_notifications": "Notifications", "group_modal_notifications": "Notifications",
"group_modal_members": "Members", "group_modal_members": "Members",
"group_modal_members_kick": "Kick", "group_modal_members_kick": "Remove",
"country_select_modal_title": "Country", "country_select_modal_title": "Country",
@ -201,9 +201,9 @@
"conversation_returned_to_group": "returned to group", "conversation_returned_to_group": "returned to group",
"conversation_invited_user": "invited {user}", "conversation_invited_user": "invited {user}",
"conversation_left_group": "left group", "conversation_left_group": "left group",
"conversation_kicked_user": "kicked {user}", "conversation_kicked_user": "removed {user}",
"conversation_invited_user_message": "invited user", "conversation_invited_user_message": "invited user",
"conversation_kicked_user_message": "kicked user", "conversation_kicked_user_message": "removed user",
"conversation_unknown_user": "Somebody", "conversation_unknown_user": "Somebody",
"conversation_unknown_chat": "Unknown chat", "conversation_unknown_chat": "Unknown chat",
@ -214,7 +214,7 @@
"message_service_removed_group_photo": "removed group photo", "message_service_removed_group_photo": "removed group photo",
"message_service_invited_user": "invited {user}", "message_service_invited_user": "invited {user}",
"message_service_returned_to_group": "returned to group", "message_service_returned_to_group": "returned to group",
"message_service_kicked_user": "kicked {user}", "message_service_kicked_user": "removed {user}",
"message_service_left_group": "left group", "message_service_left_group": "left group",
"message_service_unsupported_action": "Unsupported action {action}", "message_service_unsupported_action": "Unsupported action {action}",

47
app/js/services.js

@ -713,6 +713,14 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
midnightOffseted = new Date(), midnightOffseted = new Date(),
midnightOffset; midnightOffset;
var maxSeenID = false;
if (Config.Modes.packed) {
Storage.get('max_seen_msg').then(function (maxID) {
maxSeenID = maxID || 0;
});
}
Storage.get('server_time_offset').then(function (to) { Storage.get('server_time_offset').then(function (to) {
if (to) { if (to) {
serverTimeOffset = to; serverTimeOffset = to;
@ -792,6 +800,10 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
curDialogStorage.count = dialogsResult.count || dialogsResult.dialogs.length; curDialogStorage.count = dialogsResult.count || dialogsResult.dialogs.length;
if (!maxID && curDialogStorage.dialogs.length) {
incrementMaxSeenID(curDialogStorage.dialogs[0].top_message);
}
curDialogStorage.dialogs.splice(offset, curDialogStorage.dialogs.length - offset); curDialogStorage.dialogs.splice(offset, curDialogStorage.dialogs.length - offset);
angular.forEach(dialogsResult.dialogs, function (dialog) { angular.forEach(dialogsResult.dialogs, function (dialog) {
var peerID = AppPeersManager.getPeerID(dialog.peer), var peerID = AppPeersManager.getPeerID(dialog.peer),
@ -810,6 +822,21 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
} }
NotificationsManager.savePeerSettings(peerID, dialog.notify_settings); NotificationsManager.savePeerSettings(peerID, dialog.notify_settings);
if (
dialog.unread_count > 0 &&
maxSeenID &&
dialog.top_message > maxSeenID
) {
var message = getMessage(dialog.top_message);
if (message.unread && !message.out) {
NotificationsManager.getPeerMuted(peerID).then(function (muted) {
if (!muted) {
notifyAboutMessage(message);
}
});
}
}
}); });
return { return {
@ -1928,6 +1955,14 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
return []; return [];
} }
function incrementMaxSeenID (maxID) {
if (maxSeenID !== false && maxID && maxID > maxSeenID) {
Storage.set({
max_seen_msg: maxID
});
}
}
function notifyAboutMessage (message) { function notifyAboutMessage (message) {
var peerID = getMessagePeer(message); var peerID = getMessagePeer(message);
var fromUser = AppUsersManager.getUser(message.from_id); var fromUser = AppUsersManager.getUser(message.from_id);
@ -2125,6 +2160,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
}) })
}, timeout); }, timeout);
} }
incrementMaxSeenID(message.id);
break; break;
case 'updateReadMessages': case 'updateReadMessages':
@ -2833,11 +2870,13 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
}); });
downloadPromise.then(function (blob) { downloadPromise.then(function (blob) {
FileManager.getFileCorrectUrl(blob, doc.mime_type).then(function (url) {
historyDoc.url = $sce.trustAsResourceUrl(url);
})
delete historyDoc.progress; delete historyDoc.progress;
historyDoc.downloaded = true; if (blob) {
FileManager.getFileCorrectUrl(blob, doc.mime_type).then(function (url) {
historyDoc.url = $sce.trustAsResourceUrl(url);
})
historyDoc.downloaded = true;
}
console.log('file save done'); console.log('file save done');
}, function (e) { }, function (e) {
console.log('document download failed', e); console.log('document download failed', e);

2
app/partials/desktop/dialog.html

@ -1,4 +1,4 @@
<a class="im_dialog" ng-mousedown="dialogSelect(dialogMessage.peerString, search.messages &amp;&amp; dialogMessage.id)"> <a class="im_dialog" ng-mousedown="dialogSelect(dialogMessage.peerString, dialogMessage.unreadCount == -1 &amp;&amp; dialogMessage.id)">
<div class="im_dialog_meta pull-right text-right"> <div class="im_dialog_meta pull-right text-right">
<div class="im_dialog_date" ng-bind="dialogMessage.dateText"></div> <div class="im_dialog_date" ng-bind="dialogMessage.dateText"></div>

2
app/partials/desktop/head.html

@ -21,7 +21,7 @@
<li><a ng-click="openSettings()"> <li><a ng-click="openSettings()">
<i class="icon icon-settings"></i><span my-i18n="im_settings"></span> <i class="icon icon-settings"></i><span my-i18n="im_settings"></span>
</a></li> </a></li>
<li><a href="https://telegram.org/faq" target="_blank"> <li><a ng-click="openFaq()">
<i class="icon icon-faq"></i><span my-i18n="head_telegram_faq"></span> <i class="icon icon-faq"></i><span my-i18n="head_telegram_faq"></span>
</a></li> </a></li>
<li><a href="" ng-click="openChangelog()"> <li><a href="" ng-click="openChangelog()">

30
app/partials/desktop/im.html

@ -12,13 +12,6 @@
<i class="icon icon-search-clear"></i> <i class="icon icon-search-clear"></i>
</a> </a>
</div> </div>
<div class="im_dialogs_tabs_wrap">
<div class="im_dialogs_tabs clearfix">
<a href="" class="im_dialogs_tab" ng-class="{active: !search.messages}" ng-click="search.messages = false" my-i18n="im_conversations"></a>
<a href="" class="im_dialogs_tab" ng-class="{active: search.messages}" ng-click="search.messages = true" my-i18n="im_messages"></a>
</div>
</div>
</div> </div>
<div my-dialogs-list class="im_dialogs_col"> <div my-dialogs-list class="im_dialogs_col">
@ -32,22 +25,16 @@
<button ng-if="phonebookAvailable" type="button" class="btn btn-primary btn-sm im_dialogs_import_phonebook" ng-click="importPhonebook()" my-i18n="im_import_phonebook"></button> <button ng-if="phonebookAvailable" type="button" class="btn btn-primary btn-sm im_dialogs_import_phonebook" ng-click="importPhonebook()" my-i18n="im_import_phonebook"></button>
</div> </div>
<div ng-switch="search.messages"> <ul class="nav nav-pills nav-stacked">
<ul ng-switch-when="true" class="nav nav-pills nav-stacked"> <li class="im_dialog_wrap" my-dialog dialog-message="dialogMessage" ng-repeat="dialogMessage in dialogs track by dialogMessage.peerID" ng-class="{active: curDialog.peerID == dialogMessage.peerID}"></li>
<li class="im_dialog_wrap" my-dialog dialog-message="dialogMessage" ng-repeat="dialogMessage in dialogs track by dialogMessage.id" ng-class="{active: curDialog.peerID == dialogMessage.peerID &amp;&amp; curDialog.messageID == dialogMessage.id}"></li> </ul>
</ul>
<ul ng-switch-default class="nav nav-pills nav-stacked">
<li class="im_dialog_wrap" my-dialog dialog-message="dialogMessage" ng-repeat="dialogMessage in dialogs track by dialogMessage.peerID" ng-class="{active: curDialog.peerID == dialogMessage.peerID}"></li>
</ul>
</div>
<div class="im_dialogs_contacts_wrap" ng-show="!search.messages &amp;&amp; contacts.length > 0"> <div class="im_dialogs_contacts_wrap" ng-show="contacts.length > 0">
<h5 my-i18n="im_contacts_title"></h5> <h5 my-i18n="im_contacts_title"></h5>
<ul class="nav nav-pills nav-stacked"> <ul class="nav nav-pills nav-stacked">
<li class="im_dialog_wrap" ng-repeat="contact in contacts | orderBy:'user.sortName' track by contact.userID" ng-class="{active: curDialog.peerID == contact.userID}"> <li class="im_dialog_wrap" ng-repeat="contact in contacts | orderBy:'user.sortName' track by contact.userID" ng-class="{active: curDialog.peerID == contact.userID}">
<a class="im_dialog" ng-mousedown="dialogSelect(contact.peerString)"> <a class="im_dialog" ng-mousedown="dialogSelect(contact.peerString)">
<div class="im_dialog_photo pull-left" my-peer-photolink="contact.userID" img-class="im_dialog_photo" watch="true"></div> <div class="im_dialog_photo pull-left" my-peer-photolink="contact.userID" img-class="im_dialog_photo" watch="true"></div>
<div class="im_dialog_message_wrap"> <div class="im_dialog_message_wrap">
<div class="im_dialog_peer"> <div class="im_dialog_peer">
<span class="im_dialog_user" my-user-link="contact.userID"></span> <span class="im_dialog_user" my-user-link="contact.userID"></span>
@ -61,7 +48,7 @@
</ul> </ul>
</div> </div>
<div class="im_dialogs_contacts_wrap" ng-show="!search.messages &amp;&amp; foundUsers.length > 0"> <div class="im_dialogs_contacts_wrap" ng-show="foundUsers.length > 0">
<h5 my-i18n="im_found_title"></h5> <h5 my-i18n="im_found_title"></h5>
<ul class="nav nav-pills nav-stacked"> <ul class="nav nav-pills nav-stacked">
<li class="im_dialog_wrap" ng-repeat="foundUser in foundUsers track by foundUser.userID" ng-class="{active: curDialog.peerID == foundUser.userID}"> <li class="im_dialog_wrap" ng-repeat="foundUser in foundUsers track by foundUser.userID" ng-class="{active: curDialog.peerID == foundUser.userID}">
@ -81,6 +68,13 @@
</ul> </ul>
</div> </div>
<div class="im_dialogs_messages_wrap" ng-show="foundMessages.length > 0">
<h5 my-i18n="im_messages"></h5>
<ul class="nav nav-pills nav-stacked">
<li class="im_dialog_wrap" my-dialog dialog-message="dialogMessage" ng-repeat="dialogMessage in foundMessages track by dialogMessage.id" ng-class="{active: curDialog.peerID == dialogMessage.peerID &amp;&amp; curDialog.messageID == dialogMessage.id}"></li>
</ul>
</div>
</div> </div>
</div> </div>
</div> </div>

2
app/partials/mobile/chat_modal.html

@ -18,7 +18,7 @@
<a ng-click="editTitle()" my-i18n="group_modal_menu_edit_group"></a> <a ng-click="editTitle()" my-i18n="group_modal_menu_edit_group"></a>
</li> </li>
<li ng-if="chatFull.chat._ != 'chatForbidden' &amp;&amp; !chatFull.chat.left"> <li ng-if="chatFull.chat._ != 'chatForbidden' &amp;&amp; !chatFull.chat.left">
<a ng-click="leaveGroup()" my-i18n="group_modal_menu_leave_group"></a> <a ng-click="leaveGroup()" my-i18n="group_modal_menu_leave"></a>
</li> </li>
<li> <li>
<a ng-click="flushHistory()" my-i18n="group_modal_menu_delete_chat"></a> <a ng-click="flushHistory()" my-i18n="group_modal_menu_delete_chat"></a>

2
app/partials/mobile/dialog.html

@ -1,4 +1,4 @@
<a class="im_dialog" ng-mousedown="dialogSelect(dialogMessage.peerString, search.messages &amp;&amp; dialogMessage.id)"> <a class="im_dialog" ng-mousedown="dialogSelect(dialogMessage.peerString, dialogMessage.unreadCount == -1 &amp;&amp; dialogMessage.id)">
<div class="im_dialog_meta pull-right text-right"> <div class="im_dialog_meta pull-right text-right">
<div class="im_dialog_date" ng-bind="dialogMessage.dateText"></div> <div class="im_dialog_date" ng-bind="dialogMessage.dateText"></div>

33
app/partials/mobile/im.html

@ -12,13 +12,6 @@
<i class="icon icon-search-clear"></i> <i class="icon icon-search-clear"></i>
</a> </a>
</div> </div>
<div class="im_dialogs_tabs_wrap">
<div class="im_dialogs_tabs clearfix">
<a href="" class="im_dialogs_tab" ng-class="{active: !search.messages}" ng-click="search.messages = false" my-i18n="im_conversations"></a>
<a href="" class="im_dialogs_tab" ng-class="{active: search.messages}" ng-click="search.messages = true" my-i18n="im_messages"></a>
</div>
</div>
</div> </div>
<div my-dialogs-list-mobile class="im_dialogs_col im_dialogs_scrollable_wrap mobile_scrollable_wrap"> <div my-dialogs-list-mobile class="im_dialogs_col im_dialogs_scrollable_wrap mobile_scrollable_wrap">
@ -30,21 +23,16 @@
<button ng-if="phonebookAvailable" type="button" class="btn btn-primary btn-block im_dialogs_import_phonebook" ng-click="importPhonebook()" my-i18n="im_import_phonebook"></button> <button ng-if="phonebookAvailable" type="button" class="btn btn-primary btn-block im_dialogs_import_phonebook" ng-click="importPhonebook()" my-i18n="im_import_phonebook"></button>
</div> </div>
<div ng-switch="search.messages"> <ul class="nav nav-pills nav-stacked">
<ul ng-switch-when="true" class="nav nav-pills nav-stacked"> <li class="im_dialog_wrap" my-dialog dialog-message="dialogMessage" ng-repeat="dialogMessage in dialogs track by dialogMessage.peerID" ng-class="{active: curDialog.peerID == dialogMessage.peerID}"></li>
<li class="im_dialog_wrap" my-dialog dialog-message="dialogMessage" ng-repeat="dialogMessage in dialogs track by dialogMessage.id" ng-class="{active: curDialog.peerID == dialogMessage.peerID &amp;&amp; curDialog.messageID == dialogMessage.id}"></li> </ul>
</ul>
<ul ng-switch-default class="nav nav-pills nav-stacked">
<li class="im_dialog_wrap" my-dialog dialog-message="dialogMessage" ng-repeat="dialogMessage in dialogs track by dialogMessage.peerID" ng-class="{active: curDialog.peerID == dialogMessage.peerID}"></li>
</ul>
</div>
<div class="im_dialogs_contacts_wrap" ng-show="!search.messages &amp;&amp; contacts.length > 0"> <div class="im_dialogs_contacts_wrap" ng-show="contacts.length > 0">
<h5 my-i18n="im_contacts_title"></h5> <h5 my-i18n="im_contacts_title"></h5>
<ul class="nav nav-pills nav-stacked"> <ul class="nav nav-pills nav-stacked">
<li class="im_dialog_wrap" ng-repeat="contact in contacts | orderBy:'user.sortName' track by contact.userID" ng-class="{active: curDialog.peerID == contact.userID}"> <li class="im_dialog_wrap" ng-repeat="contact in contacts | orderBy:'user.sortName' track by contact.userID" ng-class="{active: curDialog.peerID == contact.userID}">
<a class="im_dialog" ng-mousedown="dialogSelect(contact.peerString)"> <a class="im_dialog" ng-mousedown="dialogSelect(contact.peerString)">
<div class="im_dialog_photo pull-left" my-user-photolink="contact.userID" img-class="im_dialog_photo"></div> <div class="im_dialog_photo pull-left" my-user-photolink="contact.userID" img-class="im_dialog_photo" watch="true"></div>
<div class="im_dialog_message_wrap"> <div class="im_dialog_message_wrap">
<div class="im_dialog_peer"> <div class="im_dialog_peer">
<span class="im_dialog_user" my-user-link="contact.userID"></span> <span class="im_dialog_user" my-user-link="contact.userID"></span>
@ -58,12 +46,12 @@
</ul> </ul>
</div> </div>
<div class="im_dialogs_contacts_wrap" ng-show="!search.messages &amp;&amp; foundUsers.length > 0"> <div class="im_dialogs_contacts_wrap" ng-show="foundUsers.length > 0">
<h5 my-i18n="im_found_title"></h5> <h5 my-i18n="im_found_title"></h5>
<ul class="nav nav-pills nav-stacked"> <ul class="nav nav-pills nav-stacked">
<li class="im_dialog_wrap" ng-repeat="foundUser in foundUsers track by foundUser.userID" ng-class="{active: curDialog.peerID == foundUser.userID}"> <li class="im_dialog_wrap" ng-repeat="foundUser in foundUsers track by foundUser.userID" ng-class="{active: curDialog.peerID == foundUser.userID}">
<a class="im_dialog" ng-mousedown="dialogSelect(foundUser.peerString)"> <a class="im_dialog" ng-mousedown="dialogSelect(foundUser.peerString)">
<div class="im_dialog_photo pull-left" my-user-photolink="foundUser.userID" img-class="im_dialog_photo"></div> <div class="im_dialog_photo pull-left" my-user-photolink="foundUser.userID" img-class="im_dialog_photo" watch="true"></div>
<div class="im_dialog_message_wrap"> <div class="im_dialog_message_wrap">
<div class="im_dialog_peer"> <div class="im_dialog_peer">
<span class="im_dialog_user" my-user-link="foundUser.userID"></span> <span class="im_dialog_user" my-user-link="foundUser.userID"></span>
@ -78,6 +66,13 @@
</ul> </ul>
</div> </div>
<div class="im_dialogs_messages_wrap" ng-show="foundMessages.length > 0">
<h5 my-i18n="im_messages"></h5>
<ul class="nav nav-pills nav-stacked">
<li class="im_dialog_wrap" my-dialog dialog-message="dialogMessage" ng-repeat="dialogMessage in foundMessages track by dialogMessage.id" ng-class="{active: curDialog.peerID == dialogMessage.peerID &amp;&amp; curDialog.messageID == dialogMessage.id}"></li>
</ul>
</div>
</div> </div>
</div> </div>

Loading…
Cancel
Save