diff --git a/app/css/app.css b/app/css/app.css index 62a39e8d..0a6e6224 100644 --- a/app/css/app.css +++ b/app/css/app.css @@ -2,6 +2,8 @@ html { background: #dee4e9 url(../img/bg_tile.png?1) 0 0 repeat; + background-size: 300px 468px; + /*background: #dee4e9 url(../img/bg_full.png) 0 0 no-repeat;*/ /*background-size: cover;*/ /*background-size: contain;*/ @@ -166,11 +168,13 @@ fieldset[disabled] .btn-tg.active { border-radius: 2px; overflow: hidden; } - +.modal { + overflow-y: auto; +} .modal-content { border-radius: 4px; - -webkit-box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3); - box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3); + -webkit-box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); } .modal_close_wrap { cursor: pointer; @@ -287,12 +291,28 @@ fieldset[disabled] .btn-tg.active { -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.1); -moz-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.1); box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.1); - margin-bottom: 40px; + /*margin-bottom: 40px;*/ border-radius: 0 0 3px 3px; overflow: hidden; } +.im_page_footer { + font-size: 11px; + text-align: center; + color: #9cacb9; + line-height: 40px; +} +.im_page_footer_brand { + color: #9cacb9; + font-weight: bold; +} +.im_page_footer_brand:hover, +.im_page_footer_brand:active { + color: #8499aa; + text-decoration: none; +} + .im_dialogs_col_wrap { float: left; width: 310px; @@ -511,6 +531,7 @@ a.im_dialog:hover .im_dialog_message_text { } .im_history_panel_wrap { + cursor: pointer; position: relative; -webkit-box-shadow: 0px 2px 0px rgba(0, 0, 0, 0.12); -moz-box-shadow: 0px 2px 0px rgba(0, 0, 0, 0.12); @@ -573,6 +594,7 @@ a.im_dialog:hover .im_dialog_message_text { width: 100%; margin-bottom: 13px; overflow: hidden; + -webkit-user-select: none; } .im_history_typing { font-size: 11px; @@ -714,66 +736,53 @@ div.im_message_video_thumb { margin-top: 3px; border-radius: 3px; display: inline-block; - line-height: 0; + /*line-height: 0;*/ - width: 300px; + width: 340px; } .icon-document { - display: inline-block; + display: block; + float: left; width: 38px; height: 38px; vertical-align: text-top; background: #F2F2F2 url(../img/icons/DocGrey_2x.png) 8px 10px no-repeat; background-size: 20px 20px; border-radius: 3px; - margin-right: 0; -} -.im_message_document .icon-group { - background-image: url(../img/icons/DialogListGroupChatIcon_Highlighted@2x.png); + margin-right: 10px; } -.im_message_document_size { - color: #999; - float: right; +.im_message_document_info { + float: left; +} - vertical-align: text-top; - display: inline-block; - line-height: 20px; - padding: 9px 3px 9px 0; +.im_message_document_name_wrap { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; -} -.im_message_document:hover .im_message_document_size { - color: #698192; + width: 290px; + padding: 0 0 1px; } .im_message_document_name { color: #000; - font-weight: bold; - vertical-align: text-top; display: inline-block; - line-height: 20px; - padding: 9px 5px 9px 0; + font-weight: bold; max-width: 200px; overflow: hidden; + vertical-align: text-top; white-space: nowrap; text-overflow: ellipsis; } -.im_message_document:hover, -.im_message_document:hover .icon-document { - background: #EBF0F5; - text-decoration: none; -} -.im_message_document:hover .icon-document { - background: #EBF0F5 url(../img/icons/DocBlue_2x.png) 8px 10px no-repeat; - background-size: 20px 20px; +.im_message_document_size { + color: #999; + padding-left: 2px; } .im_message_upload_progress_wrap, .im_message_download_progress_wrap { margin-top: 5px; - width: 300px; + width: 290px; } .tg_up_progress, @@ -781,10 +790,9 @@ div.im_message_video_thumb { height: 5px; margin: 0; padding: 0; - /*background: rgba(0,0,0, 0.1);*/ - background: #E9EBED; + background: #F2F2F2; border: 0; - border-radius: 4px; + border-radius: 0; -webkit-box-shadow: none; box-shadow: none; } @@ -792,19 +800,12 @@ div.im_message_video_thumb { .tg_down_progress .progress-bar { height: 5px; line-height: 5px; - /*background: #43A4DB;*/ - background: #B3BFC7; - border-radius: 3px; + background: #6B9ABD; + border-radius: 0; overflow: hidden; -webkit-box-shadow: none; box-shadow: none; } -.tg_down_progress .progress-bar { - background: #A1D2ED; - /*background: #6DBF69;*/ -} -/*.tg_up_progress .progress-bar { -}*/ @@ -839,7 +840,7 @@ div.im_message_video_thumb { display: block; width: 11px; height: 11px; - border-radius: 5px; + border-radius: 7px; overflow: hidden; position: absolute; margin-left: -27px; @@ -886,6 +887,10 @@ div.im_message_body { overflow: hidden; } +div.im_message_fwd_header { + font-weight: bold; +} + .im_message_text { word-wrap: break-word; } @@ -1028,12 +1033,24 @@ div.im_panel_own_photo { display: block; width: 11px; height: 11px; - border-radius: 5px; + border-radius: 6px; overflow: hidden; position: absolute; margin-top: -7px; margin-left: 43px; } +.modal_participant_online { + background: #6DBF69; + border: 1px solid #FFF; + display: block; + width: 11px; + height: 11px; + border-radius: 6px; + overflow: hidden; + position: absolute; + margin-top: -7px; + margin-left: 33px; +} .media_modal_wrap .modal-body { @@ -1111,24 +1128,25 @@ img.img_fullsize { } .chat_modal_members_header { - margin-top: 15px; + margin: 20px 0 6px; } .chat_modal_participant_wrap { padding: 8px 7px; - border-top: 1px solid #E0E0E0; + border-top: 1px solid #F0F0F0; } .chat_modal_participant_name { + display: block; color: #3C6E97; font-weight: bold; - margin: 4px 0 5px; + margin: 1px 0 2px; } .chat_modal_participant_status { color: #999; } .chat_modal_participant_photo { - width: 50px; - height: 50px; + width: 40px; + height: 40px; margin-right: 10px; overflow: hidden; } diff --git a/app/img/blank.gif b/app/img/blank.gif new file mode 100644 index 00000000..75b945d2 Binary files /dev/null and b/app/img/blank.gif differ diff --git a/app/img/sound_a.wav b/app/img/sound_a.wav new file mode 100644 index 00000000..c6b95a1e Binary files /dev/null and b/app/img/sound_a.wav differ diff --git a/app/index.html b/app/index.html index f9794ca3..557a9cff 100644 --- a/app/index.html +++ b/app/index.html @@ -1,5 +1,5 @@ - +
diff --git a/app/js/controllers.js b/app/js/controllers.js index acd0fc38..ea368bf9 100644 --- a/app/js/controllers.js +++ b/app/js/controllers.js @@ -14,9 +14,9 @@ angular.module('myApp.controllers', []) .controller('AppWelcomeController', function($scope, $location, MtpApiManager) { MtpApiManager.getUserID().then(function (id) { if (id) { - $location.path('/im'); + $location.url('/im'); } else { - $location.path('/login'); + $location.url('/login'); } }); }) @@ -33,7 +33,7 @@ angular.module('myApp.controllers', []) id: result.user.id }); - $location.path('/im'); + $location.url('/im'); }; $scope.sendCode = function () { @@ -116,10 +116,15 @@ angular.module('myApp.controllers', []) $scope.isLoggedIn = true; $scope.logOut = function () { MtpApiManager.logOut().then(function () { - $location.path('/login'); + location.href = 'login'; }); } + // $scope.userID = 0; + // MtpApiManager.getUserID().then(function (userID) { + // $scope.userID = userID; + // }); + updateCurDialog(); @@ -190,7 +195,7 @@ angular.module('myApp.controllers', []) $scope.$broadcast('ui_dialogs_change'); }, function (error) { if (error.code == 401) { - $location.path('/login'); + $location.url('/login'); } }); } @@ -245,7 +250,7 @@ angular.module('myApp.controllers', []) function updateHistoryPeer(preload) { var peerData = AppPeersManager.getPeer(peerID); - dLog('update', preload, peerData); + // dLog('update', preload, peerData); if (!peerData || peerData.deleted) { return false; } @@ -274,7 +279,7 @@ angular.module('myApp.controllers', []) return; } - console.trace('load history'); + // console.trace('load history'); AppMessagesManager.getHistory($scope.curDialog.inputPeer, maxID, limit).then(function (historyResult) { offset += limit; hasMore = offset < historyResult.count; diff --git a/app/js/directives.js b/app/js/directives.js index 0845ce9d..ac25c641 100644 --- a/app/js/directives.js +++ b/app/js/directives.js @@ -105,33 +105,52 @@ angular.module('myApp.directives', ['myApp.filters']) moreNotified = false; onContentLoaded(function () { - $(historyWrap).nanoScroller({preventPageScrolling: true, scroll: 'bottom', tabIndex: -1}); + scrollableWrap.scrollTop = scrollableWrap.scrollHeight; + $(historyWrap).nanoScroller({preventPageScrolling: true, tabIndex: -1}); }); var updateScroller = function (delay) { $timeout(function () { - $(historyWrap).nanoScroller(); + if (!$(scrollableWrap).hasClass('im_history_to_bottom')) { + $(historyWrap).nanoScroller(); + } }, delay || 0); } + var animated = true, + curAnimation = false; scope.$on('ui_history_append', function () { - // var st = scrollableWrap.scrollTop; - $(scrollableWrap).addClass('im_history_to_bottom'); - $(scrollable).css({bottom: 0}); + if (!atBottom) { + return; + } + if (animated) { + $(scrollableWrap).stop(); + } else { + $(scrollable).css({bottom: 0}); + $(scrollableWrap).addClass('im_history_to_bottom'); + } - if (atBottom) { - onContentLoaded(function () { + onContentLoaded(function () { + if (animated) { + curAnimation = true; + $(scrollableWrap).stop().animate({ + scrollTop: scrollableWrap.scrollHeight - scrollableWrap.clientHeight + }, { + duration: 200, + always: function () { + curAnimation = false; + updateScroller(); + } + }); + updateScroller(); + } else { $(scrollableWrap).removeClass('im_history_to_bottom'); $(scrollable).css({bottom: ''}); - // updateSizes(true); - $(historyWrap).nanoScroller({scrollBottom: 0}); - // scrollableWrap.scrollTop = st; - // $(scrollableWrap).animate({ - // scrollTop: scrollableWrap.scrollHeight - scrollableWrap.clientHeight - // }, 200); - updateScroller(); - }); - } + scrollableWrap.scrollTop = scrollableWrap.scrollHeight; + $(historyWrap).nanoScroller(); + } + + }); }); scope.$on('ui_history_change', function () { @@ -141,9 +160,8 @@ angular.module('myApp.directives', ['myApp.filters']) $(scrollableWrap).removeClass('im_history_to_bottom'); $(scrollable).css({bottom: ''}); updateSizes(); - $(historyWrap).nanoScroller(); - $(historyWrap).nanoScroller({scrollBottom: 0}); - updateScroller(100); + scrollableWrap.scrollTop = scrollableWrap.scrollHeight; + updateScroller(); moreNotified = false; }); }); @@ -160,17 +178,21 @@ angular.module('myApp.directives', ['myApp.filters']) onContentLoaded(function () { $(scrollableWrap).removeClass('im_history_to_bottom'); $(scrollable).css({bottom: ''}); - $(historyWrap).nanoScroller(); - $(historyWrap).nanoScroller({scrollTop: st + scrollableWrap.scrollHeight - sh}); + scrollableWrap.scrollTop = st + scrollableWrap.scrollHeight - sh; - // updateScroller(); - updateScroller(50); + updateScroller(); moreNotified = false; }); }); var atBottom = true; $(scrollableWrap).on('scroll', function (e) { + if ($(scrollableWrap).hasClass('im_history_to_bottom')) { + return cancelEvent(e); + } + if (curAnimation) { + return; + } atBottom = scrollableWrap.scrollTop >= scrollableWrap.scrollHeight - scrollableWrap.clientHeight; if (!moreNotified && scrollableWrap.scrollTop <= 300) { @@ -190,7 +212,9 @@ angular.module('myApp.directives', ['myApp.filters']) if (heightOnly) return; if (atBottom) { onContentLoaded(function () { - $(historyWrap).nanoScroller({scroll: 'bottom'}); + scrollableWrap.scrollTop = scrollableWrap.scrollHeight; + updateScroller(); + // $(historyWrap).nanoScroller({scroll: 'bottom'}); }); } updateScroller(100); @@ -252,7 +276,6 @@ angular.module('myApp.directives', ['myApp.filters']) if (submit) { $(element).trigger('submit'); - // dLog('after submit'); return cancelEvent(e); } }); @@ -270,7 +293,10 @@ angular.module('myApp.directives', ['myApp.filters']) $('body').on('dragenter dragleave dragover drop', onDragDropEvent); - scope.$on('ui_peer_change ui_history_change ui_message_send', focusField); + scope.$on('ui_peer_change', focusField); + scope.$on('ui_history_change', focusField); + scope.$on('ui_message_send', focusField); + scope.$on('$destroy', function cleanup() { $('body').off('dragenter dragleave dragover drop', onDragDropEvent); }); @@ -333,6 +359,7 @@ angular.module('myApp.directives', ['myApp.filters']) }; function link (scope, element, attrs) { + element.src = 'img/blank.gif'; scope.$watch('thumb.location', function (newVal) { if (!scope.thumb || !scope.thumb.location) { element.attr('src', scope.thumb && scope.thumb.placeholder || ''); diff --git a/app/js/filters.js b/app/js/filters.js index a2914d42..af444a35 100644 --- a/app/js/filters.js +++ b/app/js/filters.js @@ -82,7 +82,8 @@ angular.module('myApp.filters', []) .filter('phoneNumber', [function() { return function (phoneRaw) { - if (phoneRaw.charAt(0) == '7') { + phoneRaw = (phoneRaw || '').replace(/\D/g, ''); + if (phoneRaw.charAt(0) == '7' && phoneRaw.length == 11) { return '+' + phoneRaw.charAt(0) + ' (' + phoneRaw.substr(1, 3) + ') ' + phoneRaw.substr(4, 3) + '-' + phoneRaw.substr(7, 2) + '-' + phoneRaw.substr(9, 2); } return '+' + phoneRaw; @@ -91,7 +92,31 @@ angular.module('myApp.filters', []) .filter('formatSize', [function () { return function (size) { - return Math.round(size / 1024) + 'Kb'; + if (!size) { + return '0'; + } + else if (size < 1024) { + return size + ' b'; + } + else if (size < 1048576) { + return (Math.round(size / 1024 * 10) / 10) + ' Kb'; + } + + return (Math.round(size / 1048576 * 100) / 100) + ' Mb'; + } + }]) + + .filter('formatSizeProgress', ['$filter', function ($filter) { + return function (progress) { + var done = $filter('formatSize')(progress.done), + doneParts = done.split(' '), + total = $filter('formatSize')(progress.total), + totalParts = total.split(' '); + + if (totalParts[1] === doneParts[1]) { + return doneParts[0] + ' of ' + totalParts[0] + ' ' + (doneParts[1] || ''); + } + return done + ' of ' + total; } }]) diff --git a/app/js/services.js b/app/js/services.js index 8fbf48eb..24c006b5 100644 --- a/app/js/services.js +++ b/app/js/services.js @@ -710,7 +710,7 @@ angular.module('myApp.services', []) type: isPhoto ? 'photo' : 'doc', file_name: file.name, size: file.size, - progress: {percent: 1} + progress: {percent: 1, total: file.size} }; var message = { @@ -764,8 +764,10 @@ angular.module('myApp.services', []) var historyMessage = messagesForHistory[messageID], percent = Math.max(1, Math.floor(100 * progress.done / progress.total)); + media.progress.done = progress.done; media.progress.percent = percent; if (historyMessage) { + historyMessage.media.progress.done = progress.done; historyMessage.media.progress.percent = percent; $rootScope.$broadcast('history_update', {peerID: peerID}); } @@ -879,6 +881,10 @@ angular.module('myApp.services', []) message.fromUser = AppUsersManager.getUser(message.from_id); message.fromPhoto = AppUsersManager.getUserPhoto(message.from_id, 'User'); + if (message._ == 'messageForwarded') { + message.fwdUser = AppUsersManager.getUser(message.fwd_from_id); + } + if (message.media) { switch (message.media._) { case 'messageMediaPhoto': @@ -1383,10 +1389,11 @@ angular.module('myApp.services', []) access_hash: accessHash || doc.access_hash }; - historyDoc.progress = {enabled: true, percent: 1}; + historyDoc.progress = {enabled: true, percent: 1, total: doc.size}; function updateDownloadProgress (progress) { dLog('dl progress', progress); + historyDoc.progress.done = progress.done; historyDoc.progress.percent = Math.max(1, Math.floor(100 * progress.done / progress.total)); $rootScope.$broadcast('history_update'); } @@ -1927,11 +1934,14 @@ angular.module('myApp.services', []) function notificationsClear() { angular.forEach(notificationsShown, function (notification) { - notification.close(); + try { + if (notification.close) { + notification.close() + } else if (notification.cancel) { + notification.cancel(); + } + } catch (e) {} }); notificationsShown = []; } }) - - - diff --git a/app/partials/chat_modal.html b/app/partials/chat_modal.html index 60855a4d..c78ea381 100644 --- a/app/partials/chat_modal.html +++ b/app/partials/chat_modal.html @@ -19,7 +19,7 @@ - +