diff --git a/app/css/app.css b/app/css/app.css index 48d16be0..9bbdac5c 100644 --- a/app/css/app.css +++ b/app/css/app.css @@ -1529,13 +1529,46 @@ img.img_fullsize { .chat_modal_wrap .modal-body { padding: 23px 25px 15px; } -.chat_modal_image_wrap { +.chat_modal_photo_wrap { width: 120px; margin-right: 22px; } -.chat_modal_image { +.chat_modal_photo { + position: relative; + overflow: hidden; +} +.chat_modal_photo_change_wrap { + background: rgba(0,0,0,0.6); + padding: 2px 5px; + position: absolute; + opacity: 0; + bottom: -30px; + + -webkit-transition: all ease-in-out 0.2s; + transition: all ease-in-out 0.2s; width: 120px; - height: 120px; +} +.chat_modal_photo:hover .chat_modal_photo_change_wrap { + bottom: 0; + opacity: 1; +} + +.chat_modal_photo_update_link, +.chat_modal_photo_delete_link, +.chat_modal_photo_loading { + display: block; + color: rgba(255,255,255,0.8); + text-align: center; + padding: 2px 0; +} +.chat_modal_photo_update_link:hover, +.chat_modal_photo_delete_link:hover { + color: #FFF; + text-decoration: none; +} +.chat_modal_photo_update_link { + position: relative; + overflow: hidden; } .chat_modal_header { margin: 0 0 5px; diff --git a/app/js/controllers.js b/app/js/controllers.js index 0545bbd0..0943a1bf 100644 --- a/app/js/controllers.js +++ b/app/js/controllers.js @@ -795,7 +795,7 @@ angular.module('myApp.controllers', []) }; }) - .controller('ChatModalController', function ($scope, $timeout, $rootScope, AppUsersManager, AppChatsManager, MtpApiManager, NotificationsManager, AppMessagesManager, AppPeersManager, ApiUpdatesManager, ContactsSelectService) { + .controller('ChatModalController', function ($scope, $timeout, $rootScope, $modal, AppUsersManager, AppChatsManager, MtpApiManager, MtpApiFileManager, NotificationsManager, AppMessagesManager, AppPeersManager, ApiUpdatesManager, ContactsSelectService) { $scope.chatFull = AppChatsManager.wrapForFull($scope.chatID, {}); @@ -828,39 +828,34 @@ angular.module('myApp.controllers', []) }); }); + function onStatedMessage (statedMessage) { + AppUsersManager.saveApiUsers(statedMessage.users); + AppChatsManager.saveApiChats(statedMessage.chats); + + if (ApiUpdatesManager.saveSeq(statedMessage.seq)) { + ApiUpdatesManager.saveUpdate({ + _: 'updateNewMessage', + message: statedMessage.message, + pts: statedMessage.pts + }); + } + + $rootScope.$broadcast('history_focus', {peerString: $scope.chatFull.peerString}); + } + $scope.leaveGroup = function () { MtpApiManager.invokeApi('messages.deleteChatUser', { chat_id: $scope.chatID, user_id: {_: 'inputUserSelf'} - }).then(function (result) { - if (ApiUpdatesManager.saveSeq(result.seq)) { - ApiUpdatesManager.saveUpdate({ - _: 'updateNewMessage', - message: result.message, - pts: result.pts - }); - } - - $rootScope.$broadcast('history_focus', {peerString: $scope.chatFull.peerString}); - }); + }).then(onStatedMessage); }; $scope.returnToGroup = function () { MtpApiManager.invokeApi('messages.addChatUser', { chat_id: $scope.chatID, user_id: {_: 'inputUserSelf'} - }).then(function (result) { - if (ApiUpdatesManager.saveSeq(result.seq)) { - ApiUpdatesManager.saveUpdate({ - _: 'updateNewMessage', - message: result.message, - pts: result.pts - }); - } - - $rootScope.$broadcast('history_focus', {peerString: $scope.chatFull.peerString}); - }); + }).then(onStatedMessage); }; @@ -892,21 +887,6 @@ angular.module('myApp.controllers', []) $rootScope.$broadcast('history_focus', {peerString: $scope.chatFull.peerString}); }); - - MtpApiManager.invokeApi('messages.addChatUser', { - chat_id: $scope.chatID, - user_id: {_: 'inputUserSelf'} - }).then(function (result) { - if (ApiUpdatesManager.saveSeq(result.seq)) { - ApiUpdatesManager.saveUpdate({ - _: 'updateNewMessage', - message: result.message, - pts: result.pts - }); - } - - $rootScope.$broadcast('history_focus', {peerString: $scope.chatFull.peerString}); - }); }; $scope.kickFromGroup = function (userID) { @@ -917,17 +897,7 @@ angular.module('myApp.controllers', []) MtpApiManager.invokeApi('messages.deleteChatUser', { chat_id: $scope.chatID, user_id: {_: 'inputUserForeign', user_id: userID, access_hash: user.access_hash || '0'} - }).then(function (result) { - if (ApiUpdatesManager.saveSeq(result.seq)) { - ApiUpdatesManager.saveUpdate({ - _: 'updateNewMessage', - message: result.message, - pts: result.pts - }); - } - - $rootScope.$broadcast('history_focus', {peerString: $scope.chatFull.peerString}); - }); + }).then(onStatedMessage); }; @@ -942,6 +912,54 @@ angular.module('myApp.controllers', []) }; + + $scope.photo = {}; + + $scope.$watch('photo.file', onPhotoSelected); + + function onPhotoSelected (photo) { + if (!photo || !photo.hasOwnProperty('name')) { + return; + } + $scope.photo.updating = true; + MtpApiFileManager.uploadFile(photo).then(function (inputFile) { + MtpApiManager.invokeApi('messages.editChatPhoto', { + chat_id: $scope.chatID, + photo: { + _: 'inputChatUploadedPhoto', + file: inputFile, + crop: {_: 'inputPhotoCropAuto'} + } + }).then(function (updateResult) { + onStatedMessage(updateResult); + $scope.photo.updating = false; + }); + }); + }; + + $scope.deletePhoto = function () { + $scope.photo.updating = true; + MtpApiManager.invokeApi('messages.editChatPhoto', { + chat_id: $scope.chatID, + photo: {_: 'inputChatPhotoEmpty'} + }).then(function (updateResult) { + onStatedMessage(updateResult); + $scope.photo.updating = false; + }); + }; + + $scope.editTitle = function () { + var scope = $rootScope.$new(); + scope.chatID = $scope.chatID; + + $modal.open({ + templateUrl: 'partials/chat_edit_modal.html?3', + controller: 'ChatEditModalController', + scope: scope, + windowClass: 'contacts_modal_window' + }); + } + }) .controller('SettingsModalController', function ($rootScope, $scope, $timeout, AppUsersManager, AppChatsManager, MtpApiManager, AppConfigManager, NotificationsManager, MtpApiFileManager, ApiUpdatesManager) { @@ -1199,3 +1217,37 @@ angular.module('myApp.controllers', []) }; }) + + .controller('ChatEditModalController', function ($scope, $modalInstance, $rootScope, MtpApiManager, AppUsersManager, AppChatsManager, ApiUpdatesManager) { + + var chat = AppChatsManager.getChat($scope.chatID); + $scope.group = {name: chat.title}; + + $scope.updateGroup = function () { + if (!$scope.group.name) { + return; + } + if ($scope.group.name == chat.title) { + return $modalInstance.close(); + } + + return MtpApiManager.invokeApi('messages.editChatTitle', { + chat_id: $scope.chatID, + title: $scope.group.name + }).then(function (editResult) { + AppUsersManager.saveApiUsers(editResult.users); + AppChatsManager.saveApiChats(editResult.chats); + + if (ApiUpdatesManager.saveSeq(editResult.seq)) { + ApiUpdatesManager.saveUpdate({ + _: 'updateNewMessage', + message: editResult.message, + pts: editResult.pts + }); + } + + var peerString = AppChatsManager.getChatString($scope.chatID); + $rootScope.$broadcast('history_focus', {peerString: peerString}); + }); + }; + }) diff --git a/app/js/directives.js b/app/js/directives.js index 3a1e8a4b..2d963cdd 100644 --- a/app/js/directives.js +++ b/app/js/directives.js @@ -502,14 +502,19 @@ angular.module('myApp.directives', ['myApp.filters']) function link (scope, element, attrs) { var counter = 0; - var cachedSrc = MtpApiFileManager.getCachedFile(scope.thumb && scope.thumb.location); + var cachedSrc = MtpApiFileManager.getCachedFile( + scope.thumb && + scope.thumb.location && + !scope.thumb.location.empty + ); + if (cachedSrc) { element.attr('src', cachedSrc); } - scope.$watch('thumb.location', function (newLocation) { + scope.$watchCollection('thumb.location', function (newLocation) { var counterSaved = ++counter; - if (!newLocation) { + if (!newLocation || newLocation.empty) { element.attr('src', scope.thumb && scope.thumb.placeholder || 'img/blank.gif'); return; } diff --git a/app/js/lib/mtproto.js b/app/js/lib/mtproto.js index a4618cbc..e7829b95 100644 --- a/app/js/lib/mtproto.js +++ b/app/js/lib/mtproto.js @@ -1797,7 +1797,7 @@ factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpMessageIdGenerato }; MtpNetworker.prototype.toggleOffline = function(enabled) { - console.log('toggle ', enabled, this.dcID, this.iii); + // console.log('toggle ', enabled, this.dcID, this.iii); if (this.offline !== undefined && this.offline == enabled) { return false; } diff --git a/app/js/services.js b/app/js/services.js index 27ca4cd2..20d14af0 100644 --- a/app/js/services.js +++ b/app/js/services.js @@ -120,6 +120,7 @@ angular.module('myApp.services', []) .service('AppUsersManager', function ($rootScope, $modal, $modalStack, $filter, MtpApiFileManager, MtpApiManager, RichTextProcessor, SearchIndexManager) { var users = {}, + cachedPhotoLocations = {}, contactsFillPromise, contactsIndex = SearchIndexManager.createIndex(); @@ -198,7 +199,11 @@ angular.module('myApp.services', []) if (users[apiUser.id] === undefined) { users[apiUser.id] = apiUser; } else { - angular.extend(users[apiUser.id], apiUser); + safeReplaceObject(users[apiUser.id], apiUser); + } + + if (cachedPhotoLocations[apiUser.id] !== undefined) { + safeReplaceObject(cachedPhotoLocations[apiUser.id], apiUser && apiUser.photo && apiUser.photo.photo_small || {empty: true}); } }; @@ -222,9 +227,13 @@ angular.module('myApp.services', []) } }; + if (cachedPhotoLocations[id] === undefined) { + cachedPhotoLocations[id] = user && user.photo && user.photo.photo_small || {empty: true}; + } + return { placeholder: 'img/placeholders/' + placeholder + 'Avatar'+((Math.abs(id) % 8) + 1)+'@2x.png', - location: user && user.photo && user.photo.photo_small + location: cachedPhotoLocations[id] }; } @@ -298,7 +307,12 @@ angular.module('myApp.services', []) case 'updateUserPhoto': var userID = update.user_id; if (users[userID]) { - users[userID].photo = update.photo; + safeReplaceObject(users[userID].photo, update.photo); + + if (cachedPhotoLocations[userID] !== undefined) { + safeReplaceObject(cachedPhotoLocations[userID], update.photo && update.photo.photo_small || {empty: true}); + } + $rootScope.$broadcast('user_update', userID); } break; @@ -321,7 +335,8 @@ angular.module('myApp.services', []) }) .service('AppChatsManager', function ($rootScope, $modal, MtpApiFileManager, MtpApiManager, AppUsersManager, RichTextProcessor) { - var chats = {}; + var chats = {}, + cachedPhotoLocations = {}; function saveApiChats (apiChats) { angular.forEach(apiChats, saveApiChat); @@ -335,7 +350,11 @@ angular.module('myApp.services', []) if (chats[apiChat.id] === undefined) { chats[apiChat.id] = apiChat; } else { - angular.extend(chats[apiChat.id], apiChat); + safeReplaceObject(chats[apiChat.id], apiChat); + } + + if (cachedPhotoLocations[apiChat.id] !== undefined) { + safeReplaceObject(cachedPhotoLocations[apiChat.id], apiChat && apiChat.photo && apiChat.photo.photo_small || {empty: true}); } }; @@ -350,9 +369,13 @@ angular.module('myApp.services', []) function getChatPhoto(id, placeholder) { var chat = getChat(id); + if (cachedPhotoLocations[id] === undefined) { + cachedPhotoLocations[id] = chat && chat.photo && chat.photo.photo_small || {empty: true}; + } + return { placeholder: 'img/placeholders/' + placeholder + 'Avatar'+((Math.abs(id) % 4) + 1)+'@2x.png', - location: chat && chat.photo && chat.photo.photo_small + location: cachedPhotoLocations[id] }; } diff --git a/app/partials/chat_create_modal.html b/app/partials/chat_create_modal.html index b1bc3dbf..4dca976b 100644 --- a/app/partials/chat_create_modal.html +++ b/app/partials/chat_create_modal.html @@ -2,7 +2,7 @@