From cc98aca8ba8f13462dc3e6d1f7790cd1dd0a2e99 Mon Sep 17 00:00:00 2001 From: Igor Zhukov Date: Mon, 24 Mar 2014 16:13:34 +0400 Subject: [PATCH] Contacts import, vertical box align --- app/css/app.css | 45 ++++- app/js/controllers.js | 102 ++++++++++- app/js/directives.js | 229 ++++++++++++++----------- app/js/services.js | 165 ++++++++++++++++-- app/partials/chat_create_modal.html | 2 +- app/partials/chat_edit_modal.html | 2 +- app/partials/chat_modal.html | 2 +- app/partials/contacts_modal.html | 3 +- app/partials/edit_contact_modal.html | 40 +++++ app/partials/error_modal.html | 2 +- app/partials/import_contact_modal.html | 38 ++++ app/partials/peer_select.html | 8 +- app/partials/photo_modal.html | 2 +- app/partials/settings_modal.html | 2 +- app/partials/user_modal.html | 31 +++- app/partials/video_modal.html | 2 +- webogram.sublime-project | 2 +- 17 files changed, 528 insertions(+), 149 deletions(-) create mode 100644 app/partials/edit_contact_modal.html create mode 100644 app/partials/import_contact_modal.html diff --git a/app/css/app.css b/app/css/app.css index ef31e543..4eece49b 100644 --- a/app/css/app.css +++ b/app/css/app.css @@ -283,6 +283,12 @@ input[type="number"]::-webkit-inner-spin-button { overflow: hidden; } +.dropdown-menu { + border-radius: 2px; + padding: 0; + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.175); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.175); +} .dropdown-menu > li > a { padding: 5px 14px; font-size: 13px; @@ -347,7 +353,7 @@ input[type="number"]::-webkit-inner-spin-button { } .modal-close-link, -.modal-save-link { +.modal-head-link { font-size: 12px; line-height: 1.4; float: right; @@ -355,10 +361,10 @@ input[type="number"]::-webkit-inner-spin-button { margin: 6px 2px 0 0; } .modal-close-link:hover, -.modal-save-link:hover { +.modal-head-link:hover { text-decoration: none; } -.modal-save-link { +.modal-head-link { margin-right: 15px; } @@ -519,7 +525,7 @@ input[type="number"]::-webkit-inner-spin-button { padding: 14px 12px; position: relative; } -.im_dialogs_search { +.im_page_split .im_dialogs_search { margin-right: 48px; position: relative; } @@ -567,13 +573,9 @@ input[type="number"]::-webkit-inner-spin-button { } .im_dialogs_panel_dropdown .dropdown-menu { - border-radius: 2px; right: auto; left: 0; margin-top: 8px; - padding: 0; - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.175); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.175); } @@ -1687,17 +1689,29 @@ img.img_fullsize { .user_modal_status { color: #999; } + +.user_modal_actions_wrap { + margin-top: 8px; +} .user_modal_send_btn { border: 0; background: #4E9CD8; font-size: 12px; - margin-top: 8px; padding-left: 16px; padding-right: 16px; + float: left; } .user_modal_send_btn:hover { background: #539BD1; } +.user_modal_other_btn { + margin-left: 10px; + float: left; +} +.user_modal_other_btn .dropdown-toggle { + border: 0; + font-size: 12px; +} .user_modal_settings_wrap { margin-top: 25px; @@ -2638,3 +2652,16 @@ ce671b orange .im_dialogs_panel_dropdown.open .dropdown-toggle .icon-bar { background: #fff; } + +/* Import contact modal */ +.import_contact_modal_window .modal-dialog { + max-width: 380px; +} +.import_modal_field_wrap { + margin-bottom: 10px; +} + +.modal-content-animated { + -webkit-transition: margin-top linear 0.2s; + transition: margin-top linear 0.2s; +} \ No newline at end of file diff --git a/app/js/controllers.js b/app/js/controllers.js index a8f27f2d..aaed4663 100644 --- a/app/js/controllers.js +++ b/app/js/controllers.js @@ -579,8 +579,8 @@ angular.module('myApp.controllers', []) }); PeersSelectService.selectPeer().then(function (peerString) { - var inputPeer = AppPeersManager.getInputPeer(peerString); - AppMessagesManager.forwardMessages(selectedMessageIDs, inputPeer).then(function () { + var peerID = AppPeersManager.getPeerID(peerString); + AppMessagesManager.forwardMessages(peerID, selectedMessageIDs).then(function () { selectedCancel(); $rootScope.$broadcast('history_focus', {peerString: peerString}); }); @@ -824,8 +824,12 @@ angular.module('myApp.controllers', []) $scope.video = AppVideoManager.wrapForFull($scope.videoID); }) - .controller('UserModalController', function ($scope, $location, $rootScope, $modalStack, AppUsersManager, NotificationsManager, AppMessagesManager, AppPeersManager) { - $scope.user = AppUsersManager.wrapForFull($scope.userID); + .controller('UserModalController', function ($scope, $location, $rootScope, $modal, AppUsersManager, NotificationsManager, AppMessagesManager, AppPeersManager, PeersSelectService) { + + var peerString = AppUsersManager.getUserString($scope.userID); + + $scope.user = AppUsersManager.getUser($scope.userID); + $scope.userPhoto = AppUsersManager.getUserPhoto($scope.userID, 'User'); $scope.settings = {notifications: true}; @@ -849,7 +853,7 @@ angular.module('myApp.controllers', []) $scope.goToHistory = function () { - $rootScope.$broadcast('history_focus', {peerString: $scope.user.peerString}); + $rootScope.$broadcast('history_focus', {peerString: peerString}); }; $scope.flushHistory = function () { @@ -860,6 +864,49 @@ angular.module('myApp.controllers', []) $scope.goToHistory(); }); }; + + $scope.importContact = function (edit) { + var scope = $rootScope.$new(); + scope.importContact = { + phone: $scope.user.phone, + first_name: $scope.user.first_name, + last_name: $scope.user.last_name, + }; + + $modal.open({ + templateUrl: edit ? 'partials/edit_contact_modal.html' : 'partials/import_contact_modal.html', + controller: 'ImportContactModalController', + windowClass: 'import_contact_modal_window', + scope: scope + }).result.then(function (foundUserID) { + if ($scope.userID == foundUserID) { + $scope.user = AppUsersManager.getUser($scope.userID); + console.log($scope.user); + } + }); + }; + + $scope.deleteContact = function () { + AppUsersManager.deleteContacts([$scope.userID]).then(function () { + $scope.user = AppUsersManager.getUser($scope.userID); + console.log($scope.user); + }); + }; + + $scope.shareContact = function () { + PeersSelectService.selectPeer().then(function (peerString) { + var peerID = AppPeersManager.getPeerID(peerString); + + AppMessagesManager.sendOther(peerID, { + _: 'inputMediaContact', + phone_number: $scope.user.phone, + first_name: $scope.user.first_name, + last_name: $scope.user.last_name + }); + $rootScope.$broadcast('history_focus', {peerString: peerString}); + }) + } + }) .controller('ChatModalController', function ($scope, $timeout, $rootScope, $modal, AppUsersManager, AppChatsManager, MtpApiManager, MtpApiFileManager, NotificationsManager, AppMessagesManager, AppPeersManager, ApiUpdatesManager, ContactsSelectService, ErrorService) { @@ -873,6 +920,7 @@ angular.module('myApp.controllers', []) AppUsersManager.saveApiUsers(result.users); $scope.chatFull = AppChatsManager.wrapForFull($scope.chatID, result.full_chat); + $scope.$broadcast('ui_height'); }); $scope.settings = {notifications: true}; @@ -1190,7 +1238,7 @@ angular.module('myApp.controllers', []) } }) - .controller('ContactsModalController', function ($scope, $modalInstance, AppUsersManager) { + .controller('ContactsModalController', function ($scope, $modal, $modalInstance, AppUsersManager) { $scope.contacts = []; $scope.search = {}; @@ -1213,8 +1261,8 @@ angular.module('myApp.controllers', []) } } - $scope.$watch('search.query', function (newValue) { - AppUsersManager.getContacts(newValue).then(function (contactsList) { + function updateContacts (query) { + AppUsersManager.getContacts(query).then(function (contactsList) { $scope.contacts = []; angular.forEach(contactsList, function(userID) { var contact = { @@ -1226,7 +1274,9 @@ angular.module('myApp.controllers', []) }); $scope.$broadcast('contacts_change'); }); - }); + }; + + $scope.$watch('search.query', updateContacts); $scope.contactSelect = function (userID) { if ($scope.disabledContacts[userID]) { @@ -1254,6 +1304,18 @@ angular.module('myApp.controllers', []) } } + $scope.importContact = function () { + $modal.open({ + templateUrl: 'partials/import_contact_modal.html', + controller: 'ImportContactModalController', + windowClass: 'import_contact_modal_window' + }).result.then(function (foundUserID) { + if (foundUserID) { + updateContacts($scope.search && $scope.search.query || ''); + } + }); + }; + }) .controller('PeerSelectController', function ($scope, $modalInstance) { @@ -1334,3 +1396,25 @@ angular.module('myApp.controllers', []) }); }; }) + + .controller('ImportContactModalController', function ($scope, $modalInstance, $rootScope, AppUsersManager) { + if ($scope.importContact === undefined) { + $scope.importContact = {}; + } + + $scope.doImport = function () { + if ($scope.importContact && $scope.importContact.phone) { + $scope.progress = {enabled: true}; + AppUsersManager.importContact( + $scope.importContact.phone, + $scope.importContact.first_name, + $scope.importContact.last_name + ).then(function (foundUserID) { + $modalInstance.close(foundUserID); + })['finally'](function () { + delete $scope.progress.enabled; + }); + } + }; + + }) diff --git a/app/js/directives.js b/app/js/directives.js index 0a701144..9d9fa903 100644 --- a/app/js/directives.js +++ b/app/js/directives.js @@ -36,7 +36,7 @@ angular.module('myApp.directives', ['myApp.filters']) }; - function link (scope, element, attrs) { + function link ($scope, element, attrs) { var dialogsWrap = $('.im_dialogs_wrap', element)[0], scrollableWrap = $('.im_dialogs_scrollable_wrap', element)[0], headWrap = $('.tg_page_head')[0], @@ -53,10 +53,10 @@ angular.module('myApp.directives', ['myApp.filters']) }); } - scope.$on('ui_dialogs_prepend', updateScroller); + $scope.$on('ui_dialogs_prepend', updateScroller); - scope.$on('ui_dialogs_append', function () { + $scope.$on('ui_dialogs_append', function () { onContentLoaded(function () { updateScroller(); moreNotified = false; @@ -67,7 +67,7 @@ angular.module('myApp.directives', ['myApp.filters']) }); }); - scope.$on('ui_dialogs_change', function () { + $scope.$on('ui_dialogs_change', function () { onContentLoaded(function () { updateScroller(); moreNotified = false; @@ -82,7 +82,7 @@ angular.module('myApp.directives', ['myApp.filters']) // console.log('scroll', moreNotified); if (!moreNotified && scrollableWrap.scrollTop >= scrollableWrap.scrollHeight - scrollableWrap.clientHeight - 300) { // console.log('emit need more'); - scope.$emit('dialogs_need_more'); + $scope.$emit('dialogs_need_more'); moreNotified = true; } }); @@ -124,7 +124,7 @@ angular.module('myApp.directives', ['myApp.filters']) link: link }; - function link (scope, element, attrs) { + function link ($scope, element, attrs) { var searchWrap = $('.contacts_modal_search')[0], panelWrap = $('.contacts_modal_panel')[0], contactsWrap = $('.contacts_wrap', element)[0]; @@ -142,7 +142,7 @@ angular.module('myApp.directives', ['myApp.filters']) } $($window).on('resize', updateSizes); - scope.$on('contacts_change', function () { + $scope.$on('contacts_change', function () { onContentLoaded(updateSizes) }); }; @@ -155,7 +155,7 @@ angular.module('myApp.directives', ['myApp.filters']) link: link }; - function link (scope, element, attrs) { + function link ($scope, element, attrs) { var historyWrap = $('.im_history_wrap', element)[0], historyMessagesEl = $('.im_history_messages', element)[0], historyEl = $('.im_history', element)[0], @@ -195,7 +195,7 @@ angular.module('myApp.directives', ['myApp.filters']) var animated = transform ? true : false, curAnimation = false; - scope.$on('ui_history_append', function (e, options) { + $scope.$on('ui_history_append', function (e, options) { if (!atBottom && !options.my) { return; } @@ -232,7 +232,7 @@ angular.module('myApp.directives', ['myApp.filters']) }); }); - scope.$on('ui_history_change', function () { + $scope.$on('ui_history_change', function () { $(scrollableWrap).addClass('im_history_to_bottom'); $(scrollable).css({bottom: 0}); onContentLoaded(function () { @@ -257,7 +257,7 @@ angular.module('myApp.directives', ['myApp.filters']) }); }); - scope.$on('ui_history_focus', function () { + $scope.$on('ui_history_focus', function () { if (!atBottom) { scrollableWrap.scrollTop = scrollableWrap.scrollHeight; updateScroller(); @@ -265,7 +265,7 @@ angular.module('myApp.directives', ['myApp.filters']) } }); - scope.$on('ui_history_prepend', function () { + $scope.$on('ui_history_prepend', function () { var sh = scrollableWrap.scrollHeight, st = scrollableWrap.scrollTop, ch = scrollableWrap.clientHeight; @@ -287,10 +287,10 @@ angular.module('myApp.directives', ['myApp.filters']) }); }); - scope.$on('ui_panel_update', function () { + $scope.$on('ui_panel_update', function () { onContentLoaded(function () { updateSizes(); - scope.$broadcast('ui_message_send'); + $scope.$broadcast('ui_message_send'); $timeout(function () { $(scrollableWrap).trigger('scroll'); @@ -298,7 +298,7 @@ angular.module('myApp.directives', ['myApp.filters']) }); }); - scope.$on('ui_editor_resize', updateSizes); + $scope.$on('ui_editor_resize', updateSizes); var atBottom = true; $(scrollableWrap).on('scroll', function (e) { @@ -312,7 +312,7 @@ angular.module('myApp.directives', ['myApp.filters']) if (!moreNotified && scrollableWrap.scrollTop <= 300) { moreNotified = true; - scope.$emit('history_need_more'); + $scope.$emit('history_need_more'); } }); @@ -375,7 +375,7 @@ angular.module('myApp.directives', ['myApp.filters']) } }; - function link (scope, element, attrs) { + function link ($scope, element, attrs) { var messageField = $('textarea', element)[0], fileSelects = $('input', element), dropbox = $('.im_send_dropbox_wrap', element)[0], @@ -395,7 +395,7 @@ angular.module('myApp.directives', ['myApp.filters']) $(richTextarea).on('keyup', function (e) { updateHeight(); - scope.draftMessage.text = richTextarea.innerText; + $scope.draftMessage.text = richTextarea.innerText; $timeout.cancel(updatePromise); updatePromise = $timeout(updateValue, 1000); @@ -404,9 +404,9 @@ angular.module('myApp.directives', ['myApp.filters']) fileSelects.on('change', function () { var self = this; - scope.$apply(function () { - scope.draftMessage.files = Array.prototype.slice.call(self.files); - scope.draftMessage.isMedia = $(self).hasClass('im_media_attach_input'); + $scope.$apply(function () { + $scope.draftMessage.files = Array.prototype.slice.call(self.files); + $scope.draftMessage.isMedia = $(self).hasClass('im_media_attach_input'); setTimeout(function () { try { self.value = ''; @@ -422,7 +422,7 @@ angular.module('myApp.directives', ['myApp.filters']) }); }; - scope.$on('settings_changed', updateSendSettings); + $scope.$on('settings_changed', updateSendSettings); updateSendSettings(); $(editorElement).on('keydown', function (e) { @@ -453,13 +453,13 @@ angular.module('myApp.directives', ['myApp.filters']) return; } lastTyping = now; - scope.$emit('ui_typing'); + $scope.$emit('ui_typing'); }); function updateField () { if (richTextarea) { $timeout.cancel(updatePromise); - var html = $('
').text(scope.draftMessage.text || '').html(); + var html = $('
').text($scope.draftMessage.text || '').html(); html = html.replace(/\n/g, '
'); $(richTextarea).html(html); updateHeight(); @@ -478,7 +478,7 @@ angular.module('myApp.directives', ['myApp.filters']) var newHeight = richTextarea.offsetHeight; if (height != newHeight) { height = newHeight; - scope.$emit('ui_editor_resize'); + $scope.$emit('ui_editor_resize'); } }; @@ -488,15 +488,15 @@ angular.module('myApp.directives', ['myApp.filters']) $(richTextarea).on('DOMNodeInserted', onPastedImageEvent); } - scope.$on('ui_peer_change', focusField); - scope.$on('ui_history_focus', focusField); - scope.$on('ui_history_change', focusField); - scope.$on('ui_message_send', focusField); - scope.$on('ui_peer_draft', updateField); - scope.$on('ui_message_before_send', updateValue); + $scope.$on('ui_peer_change', focusField); + $scope.$on('ui_history_focus', focusField); + $scope.$on('ui_history_change', focusField); + $scope.$on('ui_message_send', focusField); + $scope.$on('ui_peer_draft', updateField); + $scope.$on('ui_message_before_send', updateValue); - scope.$on('$destroy', function cleanup() { + $scope.$on('$destroy', function cleanup() { $('body').off('dragenter dragleave dragover drop', onDragDropEvent); $(document).off('paste', onPasteEvent); if (richTextarea) { @@ -529,9 +529,9 @@ angular.module('myApp.directives', ['myApp.filters']) var blob = new Blob([array], {type: contentType}); if (safeConfirm('Are you sure to send file(s) from clipboard?')) { - scope.$apply(function () { - scope.draftMessage.files = [blob]; - scope.draftMessage.isMedia = true; + $scope.$apply(function () { + $scope.draftMessage.files = [blob]; + $scope.draftMessage.isMedia = true; }); } } @@ -550,9 +550,9 @@ angular.module('myApp.directives', ['myApp.filters']) } if (files.length && safeConfirm('Are you sure to send file(s) from clipboard?')) { - scope.$apply(function () { - scope.draftMessage.files = files; - scope.draftMessage.isMedia = true; + $scope.$apply(function () { + $scope.draftMessage.files = files; + $scope.draftMessage.isMedia = true; }); } } @@ -579,9 +579,9 @@ angular.module('myApp.directives', ['myApp.filters']) } } else { if (e.type == 'drop') { - scope.$apply(function () { - scope.draftMessage.files = Array.prototype.slice.call(e.originalEvent.dataTransfer.files); - scope.draftMessage.isMedia = true; + $scope.$apply(function () { + $scope.draftMessage.files = Array.prototype.slice.call(e.originalEvent.dataTransfer.files); + $scope.draftMessage.isMedia = true; }); } dragTimeout = setTimeout(function () { @@ -607,25 +607,25 @@ angular.module('myApp.directives', ['myApp.filters']) } }; - function link (scope, element, attrs) { + function link ($scope, element, attrs) { var counter = 0; var cachedSrc = MtpApiFileManager.getCachedFile( - scope.thumb && - scope.thumb.location && - !scope.thumb.location.empty && - scope.thumb.location + $scope.thumb && + $scope.thumb.location && + !$scope.thumb.location.empty && + $scope.thumb.location ); if (cachedSrc) { element.attr('src', cachedSrc); } - scope.$watchCollection('thumb.location', function (newLocation) { + $scope.$watchCollection('thumb.location', function (newLocation) { // console.log('new loc', newLocation, arguments); var counterSaved = ++counter; if (!newLocation || newLocation.empty) { - element.attr('src', scope.thumb && scope.thumb.placeholder || 'img/blank.gif'); + element.attr('src', $scope.thumb && $scope.thumb.placeholder || 'img/blank.gif'); return; } @@ -636,17 +636,17 @@ angular.module('myApp.directives', ['myApp.filters']) } if (!element.attr('src')) { - element.attr('src', scope.thumb.placeholder || 'img/blank.gif'); + element.attr('src', $scope.thumb.placeholder || 'img/blank.gif'); } - MtpApiFileManager.downloadSmallFile(scope.thumb.location, scope.thumb.size).then(function (url) { + MtpApiFileManager.downloadSmallFile($scope.thumb.location, $scope.thumb.size).then(function (url) { if (counterSaved == counter) { element.attr('src', url); } }, function (e) { - console.log('Download image failed', e, scope.thumb.location); + console.log('Download image failed', e, $scope.thumb.location); if (counterSaved == counter) { - element.attr('src', scope.thumb.placeholder || 'img/blank.gif'); + element.attr('src', $scope.thumb.placeholder || 'img/blank.gif'); } }); }) @@ -687,52 +687,52 @@ angular.module('myApp.directives', ['myApp.filters']) } }; - function link (scope, element, attrs) { + function link ($scope, element, attrs) { var imgElement = $('img', element); imgElement - .attr('src', MtpApiFileManager.getCachedFile(scope.thumbLocation) || 'img/blank.gif') + .attr('src', MtpApiFileManager.getCachedFile($scope.thumbLocation) || 'img/blank.gif') .addClass('thumb_blurred') .addClass('thumb_blur_animation'); - if (!scope.fullPhoto.location) { + if (!$scope.fullPhoto.location) { return; } var apiPromise; - if (scope.fullPhoto.size) { + if ($scope.fullPhoto.size) { var inputLocation = { _: 'inputFileLocation', - volume_id: scope.fullPhoto.location.volume_id, - local_id: scope.fullPhoto.location.local_id, - secret: scope.fullPhoto.location.secret + volume_id: $scope.fullPhoto.location.volume_id, + local_id: $scope.fullPhoto.location.local_id, + secret: $scope.fullPhoto.location.secret }; - apiPromise = MtpApiFileManager.downloadFile(scope.fullPhoto.location.dc_id, inputLocation, scope.fullPhoto.size); + apiPromise = MtpApiFileManager.downloadFile($scope.fullPhoto.location.dc_id, inputLocation, $scope.fullPhoto.size); } else { - apiPromise = MtpApiFileManager.downloadSmallFile(scope.fullPhoto.location); + apiPromise = MtpApiFileManager.downloadSmallFile($scope.fullPhoto.location); } - scope.progress = {enabled: true, percent: 1}; + $scope.progress = {enabled: true, percent: 1}; apiPromise.then(function (url) { - scope.progress.enabled = false; + $scope.progress.enabled = false; imgElement .attr('src', url) .removeClass('thumb_blurred'); }, function (e) { - console.log('Download image failed', e, scope.fullPhoto.location); - scope.progress.enabled = false; + console.log('Download image failed', e, $scope.fullPhoto.location); + $scope.progress.enabled = false; if (e && e.type == 'FS_BROWSER_UNSUPPORTED') { - scope.error = {html: 'Your browser doesn\'t support LocalFileSystem feature which is needed to display this image.
Please, install Google Chrome or use mobile app instead.'}; + $scope.error = {html: 'Your browser doesn\'t support LocalFileSystem feature which is needed to display this image.
Please, install Google Chrome or use mobile app instead.'}; } else { - scope.error = {text: 'Download failed', error: e}; + $scope.error = {text: 'Download failed', error: e}; } }, function (progress) { - scope.progress.percent = Math.max(1, Math.floor(100 * progress.done / progress.total)); + $scope.progress.percent = Math.max(1, Math.floor(100 * progress.done / progress.total)); }); } @@ -780,15 +780,15 @@ angular.module('myApp.directives', ['myApp.filters']) } }; - function link (scope, element, attrs) { + function link ($scope, element, attrs) { - scope.progress = {enabled: true, percent: 1}; - scope.player = {}; + $scope.progress = {enabled: true, percent: 1}; + $scope.player = {}; var inputLocation = { _: 'inputVideoFileLocation', - id: scope.video.id, - access_hash: scope.video.access_hash + id: $scope.video.id, + access_hash: $scope.video.access_hash }; var hasQt = false, i; @@ -800,25 +800,25 @@ angular.module('myApp.directives', ['myApp.filters']) } } - MtpApiFileManager.downloadFile(scope.video.dc_id, inputLocation, scope.video.size, null, {mime: 'video/mp4'}).then(function (url) { - scope.progress.enabled = false; - // scope.progress = {enabled: true, percent: 50}; - scope.player.hasQuicktime = hasQt; - scope.player.quicktime = false; - scope.player.src = $sce.trustAsResourceUrl(url); + MtpApiFileManager.downloadFile($scope.video.dc_id, inputLocation, $scope.video.size, null, {mime: 'video/mp4'}).then(function (url) { + $scope.progress.enabled = false; + // $scope.progress = {enabled: true, percent: 50}; + $scope.player.hasQuicktime = hasQt; + $scope.player.quicktime = false; + $scope.player.src = $sce.trustAsResourceUrl(url); }, function (e) { - console.log('Download video failed', e, scope.video); - scope.progress.enabled = false; - scope.player.src = ''; + console.log('Download video failed', e, $scope.video); + $scope.progress.enabled = false; + $scope.player.src = ''; if (e && e.type == 'FS_BROWSER_UNSUPPORTED') { - scope.error = {html: 'Your browser doesn\'t support LocalFileSystem feature which is needed to play this video.
Please, install Google Chrome or use mobile app instead.'}; + $scope.error = {html: 'Your browser doesn\'t support LocalFileSystem feature which is needed to play this video.
Please, install Google Chrome or use mobile app instead.'}; } else { - scope.error = {text: 'Video download failed', error: e}; + $scope.error = {text: 'Video download failed', error: e}; } }, function (progress) { - scope.progress.percent = Math.max(1, Math.floor(100 * progress.done / progress.total)); + $scope.progress.percent = Math.max(1, Math.floor(100 * progress.done / progress.total)); }); } @@ -833,17 +833,17 @@ angular.module('myApp.directives', ['myApp.filters']) } }; - function link (scope, element, attrs) { + function link ($scope, element, attrs) { var apiKey = 'AIzaSyC32ij28dCa0YzEV_HqbWfIwTZQql-RNS0'; - var src = 'https://maps.googleapis.com/maps/api/staticmap?sensor=false¢er=' + scope.point['lat'] + ',' + scope.point['long'] + '&zoom=13&size=200x100&scale=2&key=' + apiKey; + var src = 'https://maps.googleapis.com/maps/api/staticmap?sensor=false¢er=' + $scope.point['lat'] + ',' + $scope.point['long'] + '&zoom=13&size=200x100&scale=2&key=' + apiKey; ExternalResourcesManager.downloadImage(src).then(function (url) { element.append(''); }); - element.attr('href','https://maps.google.com/?q=' + scope.point['lat'] + ',' + scope.point['long']); + element.attr('href','https://maps.google.com/?q=' + $scope.point['lat'] + ',' + $scope.point['long']); element.attr('target','_blank'); } @@ -858,7 +858,7 @@ angular.module('myApp.directives', ['myApp.filters']) var interval; - function link (scope, element, attrs) { + function link ($scope, element, attrs) { var promise = $interval(function () { var time = tsNow(), cnt = 3; @@ -877,7 +877,7 @@ angular.module('myApp.directives', ['myApp.filters']) element.html(html); }, 200); - scope.$on('$destroy', function cleanup() { + $scope.$on('$destroy', function cleanup() { $interval.cancel(promise); }); } @@ -892,8 +892,8 @@ angular.module('myApp.directives', ['myApp.filters']) } }; - function link (scope, element, attrs) { - scope.$watch('audio.autoplay', function (autoplay) { + function link ($scope, element, attrs) { + $scope.$watch('audio.autoplay', function (autoplay) { if (autoplay) { element.autoplay = true; element[0].play(); @@ -906,7 +906,7 @@ angular.module('myApp.directives', ['myApp.filters']) .directive('myFocused', function(){ return { - link: function(scope, element, attrs) { + link: function($scope, element, attrs) { setTimeout(function () { element[0].focus(); }, 100); @@ -920,11 +920,11 @@ angular.module('myApp.directives', ['myApp.filters']) link: link }; - function link(scope, element, attrs) { + function link($scope, element, attrs) { element.on('change', function () { var self = this; - scope.$apply(function () { - scope.photo.file = self.files[0]; + $scope.$apply(function () { + $scope.photo.file = self.files[0]; setTimeout(function () { try { self.value = ''; @@ -942,10 +942,45 @@ angular.module('myApp.directives', ['myApp.filters']) link: link }; - function link(scope, element, attrs) { + function link($scope, element, attrs) { attrs.$observe('myModalWidth', function (newW) { $(element[0].parentNode.parentNode).css({width: parseInt(newW) + 36}); }); }; + }) + + + .directive('myModalPosition', function ($window, $timeout) { + + return { + link: link + }; + + function link($scope, element, attrs) { + + var updateMargin = function () { + var height = element[0].parentNode.offsetHeight, + contHeight = element[0].parentNode.parentNode.parentNode.offsetHeight; + + if (height < contHeight) { + $(element[0].parentNode).css('marginTop', (contHeight - height) / 2); + } else { + $(element[0].parentNode).css('marginTop', ''); + } + $timeout(function () { + $(element[0].parentNode).addClass('modal-content-animated'); + }, 300); + }; + + onContentLoaded(updateMargin); + + $($window).on('resize', updateMargin); + + $scope.$on('ui_height', function () { + onContentLoaded(updateMargin); + }); + + }; + }); diff --git a/app/js/services.js b/app/js/services.js index 1b3592bc..2813e573 100644 --- a/app/js/services.js +++ b/app/js/services.js @@ -295,9 +295,61 @@ angular.module('myApp.services', []) scope: scope, windowClass: 'user_modal_window' }); + }; + $rootScope.openUser = openUser; + + function importContact (phone, firstName, lastName) { + return MtpApiManager.invokeApi('contacts.importContacts', { + contacts: [{ + _: 'inputPhoneContact', + client_id: '1', + phone: phone, + first_name: firstName, + last_name: lastName + }], + replace: false + }).then(function (importedContactsResult) { + saveApiUsers(importedContactsResult.users); + + var foundUserID = false; + angular.forEach(importedContactsResult.imported, function (importedContact) { + onContactUpdated(foundUserID = importedContact.user_id, true); + }); + + return foundUserID; + }); + }; + + function deleteContacts (userIDs) { + var ids = [] + angular.forEach(userIDs, function (userID) { + ids.push({_: 'inputUserContact', user_id: userID}) + }); + return MtpApiManager.invokeApi('contacts.deleteContacts', { + id: ids + }, function () { + angular.forEach(userIDs, function (userID) { + onContactUpdated(userID, false); + }); + }) + } + + function onContactUpdated (userID, isContact) { + if (angular.isArray(contactsList)) { + var curPos = curIsContact = contactsList.indexOf(userID), + curIsContact = curPos != -1; + + if (isContact != curIsContact) { + if (isContact) { + contactsList.push(userID); + SearchIndexManager.indexObject(userID, getUserSearchText(userID), contactsIndex); + } else { + contactsList.splice(curPos, 1); + } + } + } } - $rootScope.openUser = openUser; $rootScope.$on('apiUpdate', function (e, update) { // console.log('on apiUpdate', update); @@ -326,21 +378,7 @@ angular.module('myApp.services', []) break; case 'updateContactLink': - if (angular.isArray(contactsList)) { - var userID = update.user_id, - curPos = curIsContact = contactsList.indexOf(userID), - curIsContact = curPos != -1, - newIsContact = update.my_link._ == 'contacts.myLinkContact'; - - if (newIsContact != curIsContact) { - if (newIsContact) { - contactsList.push(userID); - SearchIndexManager.indexObject(userID, getUserSearchText(userID), contactsIndex); - } else { - contactsList.splice(curPos, 1); - } - } - } + onContactUpdated(update.user_id, update.my_link._ == 'contacts.myLinkContact'); break; } }); @@ -355,6 +393,8 @@ angular.module('myApp.services', []) getUserString: getUserString, getUserSearchText: getUserSearchText, hasUser: hasUser, + importContact: importContact, + deleteContacts: deleteContacts, wrapForFull: wrapForFull, openUser: openUser } @@ -1118,7 +1158,7 @@ angular.module('myApp.services', []) randomIDS = bigint(randomID[0]).shiftLeft(32).add(bigint(randomID[1])).toString(), historyStorage = historiesStorage[peerID], inputPeer = AppPeersManager.getInputPeerByID(peerID), - attachType, fileName, fileName; + attachType, fileName; if (!options.isMedia) { attachType = 'document'; @@ -1256,9 +1296,95 @@ angular.module('myApp.services', []) pendingByRandomID[randomIDS] = [peerID, messageID]; } - function forwardMessages (msgIDs, inputPeer) { + function sendOther(peerID, inputMedia) { + var messageID = tempID--, + randomID = [nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)], + randomIDS = bigint(randomID[0]).shiftLeft(32).add(bigint(randomID[1])).toString(), + historyStorage = historiesStorage[peerID], + inputPeer = AppPeersManager.getInputPeerByID(peerID); + + if (historyStorage === undefined) { + historyStorage = historiesStorage[peerID] = {count: null, history: [], pending: []}; + } + + MtpApiManager.getUserID().then(function (fromID) { + var media; + switch (inputMedia._) { + case 'inputMediaContact': + media = angular.extend({}, inputMedia, {_: 'messageMediaContact', user_id: 0}); + break; + } + + var message = { + _: 'message', + id: messageID, + from_id: fromID, + to_id: AppPeersManager.getOutputPeer(peerID), + out: true, + unread: true, + date: tsNow() / 1000, + message: '', + media: media, + random_id: randomIDS, + pending: true + }; + + var toggleError = function (on) { + var historyMessage = messagesForHistory[messageID]; + if (on) { + message.error = true; + if (historyMessage) { + historyMessage.error = true; + } + } else { + delete message.error; + if (historyMessage) { + delete historyMessage.error; + } + } + } + + message.send = function () { + MtpApiManager.invokeApi('messages.sendMedia', { + peer: inputPeer, + media: inputMedia, + random_id: randomID + }).then(function (result) { + if (ApiUpdatesManager.saveSeq(result.seq)) { + ApiUpdatesManager.saveUpdate({ + _: 'updateMessageID', + random_id: randomIDS, + id: result.message.id + }); + + message.date = result.message.date; + message.id = result.message.id; + message.media = result.message.media; + + ApiUpdatesManager.saveUpdate({ + _: 'updateNewMessage', + message: message, + pts: result.pts + }); + } + }, function (error) { + toggleError(true); + }); + }; + + saveMessages([message]); + historyStorage.pending.unshift(messageID); + $rootScope.$broadcast('history_append', {peerID: peerID, messageID: messageID, my: true}); + + message.send(); + }); + + pendingByRandomID[randomIDS] = [peerID, messageID]; + } + + function forwardMessages (peerID, msgIDs) { return MtpApiManager.invokeApi('messages.forwardMessages', { - peer: inputPeer, + peer: AppPeersManager.getInputPeerByID(peerID), id: msgIDs }).then(function (forwardResult) { AppUsersManager.saveApiUsers(forwardResult.users); @@ -1688,6 +1814,7 @@ angular.module('myApp.services', []) saveMessages: saveMessages, sendText: sendText, sendFile: sendFile, + sendOther: sendOther, forwardMessages: forwardMessages, getMessagePeer: getMessagePeer, wrapForDialog: wrapForDialog, diff --git a/app/partials/chat_create_modal.html b/app/partials/chat_create_modal.html index ffe1fc3c..f32ddfbb 100644 --- a/app/partials/chat_create_modal.html +++ b/app/partials/chat_create_modal.html @@ -1,4 +1,4 @@ -
+