Browse Source

Contacts import, vertical box align

master
Igor Zhukov 10 years ago
parent
commit
cc98aca8ba
  1. 45
      app/css/app.css
  2. 102
      app/js/controllers.js
  3. 229
      app/js/directives.js
  4. 165
      app/js/services.js
  5. 2
      app/partials/chat_create_modal.html
  6. 2
      app/partials/chat_edit_modal.html
  7. 2
      app/partials/chat_modal.html
  8. 3
      app/partials/contacts_modal.html
  9. 40
      app/partials/edit_contact_modal.html
  10. 2
      app/partials/error_modal.html
  11. 38
      app/partials/import_contact_modal.html
  12. 8
      app/partials/peer_select.html
  13. 2
      app/partials/photo_modal.html
  14. 2
      app/partials/settings_modal.html
  15. 31
      app/partials/user_modal.html
  16. 2
      app/partials/video_modal.html
  17. 2
      webogram.sublime-project

45
app/css/app.css

@ -283,6 +283,12 @@ input[type="number"]::-webkit-inner-spin-button { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 @@ -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;
}

102
app/js/controllers.js

@ -579,8 +579,8 @@ angular.module('myApp.controllers', []) @@ -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', []) @@ -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', []) @@ -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', []) @@ -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', []) @@ -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', []) @@ -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', []) @@ -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', []) @@ -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', []) @@ -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', []) @@ -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;
});
}
};
})

229
app/js/directives.js

@ -36,7 +36,7 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -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']) @@ -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']) @@ -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']) @@ -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']) @@ -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']) @@ -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']) @@ -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']) @@ -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']) @@ -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']) @@ -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']) @@ -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']) @@ -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']) @@ -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']) @@ -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']) @@ -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']) @@ -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']) @@ -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']) @@ -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']) @@ -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 = $('<div>').text(scope.draftMessage.text || '').html();
var html = $('<div>').text($scope.draftMessage.text || '').html();
html = html.replace(/\n/g, '<br/>');
$(richTextarea).html(html);
updateHeight();
@ -478,7 +478,7 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -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']) @@ -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']) @@ -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']) @@ -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']) @@ -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']) @@ -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']) @@ -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']) @@ -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 <a href="https://developer.mozilla.org/en-US/docs/Web/API/LocalFileSystem" target="_blank">LocalFileSystem</a> feature which is needed to display this image.<br/>Please, install <a href="http://google.com/chrome" target="_blank">Google Chrome</a> or use <a href="https://telegram.org/" target="_blank">mobile app</a> instead.'};
$scope.error = {html: 'Your browser doesn\'t support <a href="https://developer.mozilla.org/en-US/docs/Web/API/LocalFileSystem" target="_blank">LocalFileSystem</a> feature which is needed to display this image.<br/>Please, install <a href="http://google.com/chrome" target="_blank">Google Chrome</a> or use <a href="https://telegram.org/" target="_blank">mobile app</a> 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']) @@ -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']) @@ -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 <a href="https://developer.mozilla.org/en-US/docs/Web/API/LocalFileSystem" target="_blank">LocalFileSystem</a> feature which is needed to play this video.<br/>Please, install <a href="http://google.com/chrome" target="_blank">Google Chrome</a> or use <a href="https://telegram.org/" target="_blank">mobile app</a> instead.'};
$scope.error = {html: 'Your browser doesn\'t support <a href="https://developer.mozilla.org/en-US/docs/Web/API/LocalFileSystem" target="_blank">LocalFileSystem</a> feature which is needed to play this video.<br/>Please, install <a href="http://google.com/chrome" target="_blank">Google Chrome</a> or use <a href="https://telegram.org/" target="_blank">mobile app</a> 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']) @@ -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&center=' + 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&center=' + $scope.point['lat'] + ',' + $scope.point['long'] + '&zoom=13&size=200x100&scale=2&key=' + apiKey;
ExternalResourcesManager.downloadImage(src).then(function (url) {
element.append('<img src="' + url + '" width="200" height="100"/>');
});
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']) @@ -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']) @@ -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']) @@ -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']) @@ -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']) @@ -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']) @@ -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);
});
};
});

165
app/js/services.js

@ -295,9 +295,61 @@ angular.module('myApp.services', []) @@ -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', []) @@ -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', []) @@ -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', []) @@ -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', []) @@ -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', []) @@ -1688,6 +1814,7 @@ angular.module('myApp.services', [])
saveMessages: saveMessages,
sendText: sendText,
sendFile: sendFile,
sendOther: sendOther,
forwardMessages: forwardMessages,
getMessagePeer: getMessagePeer,
wrapForDialog: wrapForDialog,

2
app/partials/chat_create_modal.html

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
<div class="contacts_modal_wrap">
<div class="contacts_modal_wrap" my-modal-position>
<div class="modal-header">
<a class="modal-close-link" ng-click="$close()">Close</a>

2
app/partials/chat_edit_modal.html

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
<div class="contacts_modal_wrap">
<div class="contacts_modal_wrap" my-modal-position>
<div class="modal-header">
<a class="modal-close-link" ng-click="$close()">Close</a>

2
app/partials/chat_modal.html

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
<div class="chat_modal_wrap">
<div class="chat_modal_wrap" my-modal-position>
<div class="modal-header">
<a class="modal-close-link" ng-click="$close()">Close</a>

3
app/partials/contacts_modal.html

@ -1,7 +1,8 @@ @@ -1,7 +1,8 @@
<div class="contacts_modal_wrap">
<div class="contacts_modal_wrap" my-modal-position>
<div class="modal-header">
<a class="modal-close-link" ng-click="$dismiss()">Close</a>
<a ng-if="!multiSelect" class="pull-right modal-head-link" ng-click="importContact()">Add new contact</a>
<h4 class="modal-title">Contacts</h4>
</div>

40
app/partials/edit_contact_modal.html

@ -0,0 +1,40 @@ @@ -0,0 +1,40 @@
<div class="import_modal_wrap" my-modal-position>
<div class="modal-header">
<a class="modal-close-link" ng-click="$close()">Close</a>
<h4 class="modal-title">Edit contact</h4>
</div>
<div class="modal-body">
<form ng-submit="doImport()">
<div class="form-group import_modal_field_wrap">
<span class="form-control uneditable-input disabled" disabled>{{importContact.phone | phoneNumber}}</span>
</div>
<div class="form-group import_modal_field_wrap">
<input class="form-control" type="text" my-focused placeholder="First name" ng-model="importContact.first_name"/>
</div>
<div class="form-group import_modal_field_wrap">
<input class="form-control" type="text" placeholder="Last name" ng-model="importContact.last_name"/>
</div>
<div class="import_modal_panel clearfix">
<div class="import_modal_actions pull-right">
<a class="btn btn-default" ng-click="$dismiss()"> Cancel </a>
<button class="btn btn-success" type="submit" ng-class="{disabled: progress.enabled}" ng-disabled="progress.enabled">
{{progress.enabled ? 'Saving...' : 'Save'}}
</button>
</div>
</div>
</form>
</div>
</div>

2
app/partials/error_modal.html

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
<div class="error_modal_wrap">
<div class="error_modal_wrap" my-modal-position>
<div class="modal-header">
<a class="modal-close-link" ng-click="$close()">Close</a>

38
app/partials/import_contact_modal.html

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
<div class="import_modal_wrap" my-modal-position>
<div class="modal-header">
<a class="modal-close-link" ng-click="$close()">Close</a>
<h4 class="modal-title">Add new contact</h4>
</div>
<div class="modal-body">
<form ng-submit="doImport()">
<div class="form-group import_modal_field_wrap">
<input class="form-control" my-focused type="text" placeholder="Phone number" ng-model="importContact.phone"/>
</div>
<div class="form-group import_modal_field_wrap">
<input class="form-control" type="text" placeholder="First name" ng-model="importContact.first_name"/>
</div>
<div class="form-group import_modal_field_wrap">
<input class="form-control" type="text" placeholder="Last name" ng-model="importContact.last_name"/>
</div>
<div class="import_modal_panel clearfix">
<div class="import_modal_actions pull-right">
<a class="btn btn-default" ng-click="$dismiss()"> Cancel </a>
<button class="btn btn-success" type="submit" ng-class="{disabled: progress.enabled}" ng-disabled="progress.enabled">
{{progress.enabled ? 'Importing...' : 'Save'}}
</button>
</div>
</div>
</form>
</div>
</div>

8
app/partials/peer_select.html

@ -8,9 +8,11 @@ @@ -8,9 +8,11 @@
<div class="modal-body">
<div class="im_dialogs_modal_col_wrap" ng-controller="AppImDialogsController">
<div class="im_dialogs_search">
<input class="form-control im_dialogs_search_field" type="search" placeholder="Search" ng-model="search.query"/>
<a class="im_dialogs_search_clear" ng-click="search.query = ''" ng-show="search.query.length"></a>
<div class="im_dialogs_panel">
<div class="im_dialogs_search">
<input class="form-control im_dialogs_search_field" type="search" placeholder="Search" ng-model="search.query"/>
<a class="im_dialogs_search_clear" ng-click="search.query = ''" ng-show="search.query.length"></a>
</div>
</div>
<div my-dialogs-list modal="true" class="im_dialogs_modal_col">
<div class="im_dialogs_wrap nano">

2
app/partials/photo_modal.html

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
<div my-modal-width="{{photo.full.width}}" class="media_modal_wrap photo_modal_wrap">
<div my-modal-width="{{photo.full.width}}" class="media_modal_wrap photo_modal_wrap" my-modal-position>
<div class="modal-body">

2
app/partials/settings_modal.html

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
<div class="settings_modal_wrap">
<div class="settings_modal_wrap" my-modal-position>
<div class="modal-header">
<a class="modal-close-link" ng-click="$close()">Close</a>

31
app/partials/user_modal.html

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
<div class="user_modal_wrap">
<div class="user_modal_wrap" my-modal-position>
<div class="modal-header">
<a class="modal-close-link" ng-click="$close()">Close</a>
@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
<img
class="user_modal_image"
my-load-thumb
thumb="user.thumb"
thumb="userPhoto"
/>
</div>
@ -21,7 +21,32 @@ @@ -21,7 +21,32 @@
<p class="user_modal_status" ng-if="user.status">{{user | userStatus}}</p>
<p class="user_modal_phone" ng-if="user.phone">{{user.phone | phoneNumber}}</p>
<button class="btn btn-primary user_modal_send_btn" ng-click="goToHistory()">Send message</button>
<div class="user_modal_actions_wrap clearfix">
<button class="btn btn-primary user_modal_send_btn" ng-click="goToHistory()">Send message</button>
<div class="dropdown user_modal_other_btn">
<button class="btn btn-link dropdown-toggle">More<i class="icon icon-caret"></i></button>
<ul class="dropdown-menu">
<li ng-if="user._ == 'userContact'">
<a ng-click="importContact(true)">Edit</a>
</li>
<li ng-if="user._ == 'userContact'">
<a ng-click="deleteContact()">Delete Contact</a>
</li>
<li ng-if="user.phone.length > 0 &amp;&amp; user._ != 'userContact'">
<a ng-click="importContact()">Add to contacts</a>
</li>
<li ng-if="user.phone.length > 0">
<a ng-click="shareContact()">Share contact</a>
</li>
<li>
<a ng-click="flushHistory()">Delete chat</a>
</li>
</ul>
</div>
</div>
</div>
<div class="user_modal_settings_wrap">

2
app/partials/video_modal.html

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
<div class="media_modal_wrap video_modal_wrap">
<div class="media_modal_wrap video_modal_wrap" my-modal-position>
<div class="modal-body">

2
webogram.sublime-project vendored

@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
{
"follow_symlinks": true,
"path": ".",
"folder_exclude_patterns": ["*dist"],
"folder_exclude_patterns": ["*dist", "node_modules"],
"file_exclude_patterns": ["*.zip"]
}
]

Loading…
Cancel
Save