From 5880113b70de4e9878898b97515f0c609119cd34 Mon Sep 17 00:00:00 2001 From: Igor Zhukov Date: Mon, 15 Sep 2014 23:24:19 +0400 Subject: [PATCH] Improved mobile scrollers --- app/css/app.css | 74 +------ app/css/desktop.css | 60 +++++- app/css/mobile.css | 81 ++------ app/js/directives_mobile.js | 194 ++++++++++++------ app/partials/desktop/head.html | 104 ---------- app/partials/mobile/contacts_modal.html | 30 +-- app/partials/mobile/country_select_modal.html | 26 +-- app/partials/mobile/edit_contact_modal.html | 2 +- app/partials/mobile/head.html | 7 - app/partials/mobile/im.html | 64 +----- app/partials/mobile/peer_select.html | 60 +++--- app/partials/mobile/phonebook_modal.html | 54 +++-- 12 files changed, 287 insertions(+), 469 deletions(-) diff --git a/app/css/app.css b/app/css/app.css index 11f8fb9e..a9051b24 100644 --- a/app/css/app.css +++ b/app/css/app.css @@ -231,12 +231,6 @@ input[type="number"] { line-height: 20px; } -.navbar-peer-wrap { - display: none; -} -.navbar-toggle-wrap { - display: none; -} .tg_page_head .navbar-menu .navbar-nav.navbar-right { margin-right: 0; } @@ -825,29 +819,7 @@ a.tg_radio_on:hover i.icon-radio { } -.im_dialogs_col .nano > .nano-pane { - background : rgba(0,0,0,0.0); - width : 12px; - right: 0px; - -moz-border-radius : 0; - -webkit-border-radius : 0; - border-radius : 0; - /*-webkit-transition : .2s; - -moz-transition : .2s; - -o-transition : .2s; - transition : .2s;*/ - -webkit-transition : none; - -moz-transition : none; - -o-transition : none; - transition : none; -} -.im_dialogs_col .nano > .nano-pane > .nano-slider { - background: #A5B1B9; - margin: 0 5px; - -moz-border-radius : 0; - -webkit-border-radius : 0; - border-radius : 0; -} + .im_dialogs_panel { padding: 12px 12px 6px; @@ -1190,7 +1162,10 @@ a.im_dialog_selected .im_dialog_date { -webkit-perspective: 1000; -webkit-backface-visibility: hidden; } - +.im_history_to_bottom { + overflow: hidden; + position: relative; +} .im_history_to_bottom .im_history_scrollable { position: absolute; bottom: 0; @@ -1892,10 +1867,6 @@ textarea.im_message_field { background-position: -10px -36px; opacity: 1; } - -.im_head_attach { - display: none; -} .im_attach_input, .im_media_attach_input { cursor: pointer; @@ -2358,16 +2329,6 @@ img.chat_modal_participant_photo { } -.emoji-menu .nano > .nano-pane { - background : rgba(255,255,255,0.0); - right: -2px; -} -.emoji-menu .nano > .nano-pane > .nano-slider { - background: #d1d1d1; - margin: 0 3px 0 4px; -} - - .error_modal_window .modal-dialog { max-width: 350px; } @@ -2727,11 +2688,7 @@ a:hover .icon-twitter { opacity: 1; } -.contacts_modal_col { - margin-right: -17px; -} .contacts_scrollable_wrap { - padding: 0 17px 0 0; outline: none ! important; } .contacts_modal_contacts_empty { @@ -3206,27 +3163,6 @@ ce671b orange padding: 14px 0; } -.countries_modal_col .nano > .nano-pane { - background : rgba(3,36,64,0.08); - width : 3px; - right: 6px; - top: 0; - -webkit-transition : .2s; - -moz-transition : .2s; - -o-transition : .2s; - transition : .2s; - -moz-border-radius : 0; - -webkit-border-radius : 0; - border-radius : 0; -} -.countries_modal_col .nano > .nano-pane > .nano-slider { - background : rgba(3,46,79,0.22); - margin: 0; - -moz-border-radius : 0; - -webkit-border-radius : 0; - border-radius : 0; -} - .countries_scrollable_wrap a.countries_modal_country { clear: both; diff --git a/app/css/desktop.css b/app/css/desktop.css index 0ae380b2..40b06895 100644 --- a/app/css/desktop.css +++ b/app/css/desktop.css @@ -54,6 +54,36 @@ opacity : 0.99; } +.emoji-menu .nano > .nano-pane { + background : rgba(255,255,255,0.0); + right: -2px; +} +.emoji-menu .nano > .nano-pane > .nano-slider { + background: #d1d1d1; + margin: 0 3px 0 4px; +} + +.countries_modal_col .nano > .nano-pane { + background : rgba(3,36,64,0.08); + width : 3px; + right: 6px; + top: 0; + -webkit-transition : .2s; + -moz-transition : .2s; + -o-transition : .2s; + transition : .2s; + -moz-border-radius : 0; + -webkit-border-radius : 0; + border-radius : 0; +} +.countries_modal_col .nano > .nano-pane > .nano-slider { + background : rgba(3,46,79,0.22); + margin: 0; + -moz-border-radius : 0; + -webkit-border-radius : 0; + border-radius : 0; +} + .im_page_wrap { @@ -99,6 +129,29 @@ .im_dialogs_scrollable_wrap { padding: 0 19px 0 12px; } +.im_dialogs_col .nano > .nano-pane { + background : rgba(0,0,0,0.0); + width : 12px; + right: 0px; + -moz-border-radius : 0; + -webkit-border-radius : 0; + border-radius : 0; + /*-webkit-transition : .2s; + -moz-transition : .2s; + -o-transition : .2s; + transition : .2s;*/ + -webkit-transition : none; + -moz-transition : none; + -o-transition : none; + transition : none; +} +.im_dialogs_col .nano > .nano-pane > .nano-slider { + background: #A5B1B9; + margin: 0 5px; + -moz-border-radius : 0; + -webkit-border-radius : 0; + border-radius : 0; +} .im_history_col_wrap { float: left; @@ -124,7 +177,6 @@ -o-transition : none; transition : none; } - .contacts_modal_col .nano > .nano-pane { width: 6px; right: 7px; @@ -137,6 +189,12 @@ .im_dialogs_modal_col .im_dialogs_scrollable_wrap { padding: 0 12px 0 12px; } +.contacts_modal_col { + margin-right: -17px; +} +.contacts_scrollable_wrap { + padding: 0 17px 0 0; +} .im_history_col .nano > .nano-pane { top: 10px; diff --git a/app/css/mobile.css b/app/css/mobile.css index 98107881..f82e4196 100644 --- a/app/css/mobile.css +++ b/app/css/mobile.css @@ -38,7 +38,7 @@ html { } .tg_page_head .navbar-inverse .navbar-toggle:hover, -.tg_page_head .navbar-inverse .navbar-toggle:active, +/*.tg_page_head .navbar-inverse .navbar-toggle:active,*/ .tg_page_head .navbar-inverse .navbar-toggle:focus, .tg_page_head .navbar-inverse .open .navbar-toggle { background-color: rgba(0,0,0,0.1); @@ -158,8 +158,8 @@ html { font-size: 13px; height: 46px; } -.tg_page_head .navbar-inverse .navbar-quick-nav > li > a:hover, -.tg_page_head .navbar-inverse .navbar-quick-nav > li > a:active { +.tg_page_head .navbar-inverse .navbar-quick-nav > li > a:hover/*, +.tg_page_head .navbar-inverse .navbar-quick-nav > li > a:active*/ { background-color: rgba(0,0,0,0.1); } .navbar-quick-nav .icon-back { @@ -281,6 +281,12 @@ html { text-align: center; } +.mobile_scrollable_wrap { + overflow: hidden; + overflow-y: scroll; + -webkit-overflow-scrolling: touch; +} + .login_form_wrap { border-radius: 0; @@ -506,10 +512,10 @@ img.im_message_video_thumb, .im_send_panel_wrap { padding: 10px 0 12px; } -.im_history_scrollable_wrap { + +.im_history_scrollable_wrap.im_history_to_bottom { overflow: hidden; - overflow-y: scroll; - -webkit-overflow-scrolling: touch; + position: relative; } .im_history { position: static; @@ -746,19 +752,6 @@ a.im_message_from_photo { padding: 5px 0; margin: 0; } -.im_history_col .nano > .nano-pane { - top: 3px; - right: 3px; - width: 6px; -} -.im_history_col .nano > .nano-pane > .nano-slider, -.contacts_modal_col .nano > .nano-pane > .nano-slider, -.im_dialogs_modal_col .nano > .nano-pane > .nano-slider { - background : rgba(3,46,79,0.22); - border-radius: 3px; - margin: 0; -} - .im_dialogs_col_wrap { @@ -783,9 +776,6 @@ a.im_message_from_photo { .im_dialogs_col { } .im_dialogs_scrollable_wrap { - overflow: hidden; - overflow-y: scroll; - -webkit-overflow-scrolling: touch; } .im_dialogs_panel { @@ -1196,58 +1186,17 @@ a.mobile_modal_action .tg_checkbox_label { padding: 5px; } -.im_head_attach { - display: block; - float: right; - cursor: pointer; - overflow: hidden; - position: relative; - margin: 5px 0 5px 5px; - height: 34px; - border-radius: 4px; - padding: 3px 7px; - border: 1px solid #497495; -} -.navbar_peer_not_selected .im_head_attach { - display: none; -} -.im_head_attach:active { - background-color: rgba(255,255,255,0.1); -} - -.im_head_attach .icon-paperclip { - display: inline-block; - width: 21px; - height: 22px; - vertical-align: text-top; - opacity: 0.8; - background: url(../img/icons/MobileIcons_2x.png) 0 -30px no-repeat; - background-size: 21px 52px; -} -.is_1x .im_head_attach .icon-paperclip { - background-image: url(../img/icons/MobileIcons_1x.png); -} -.im_head_attach:active .icon-paperclip { - opacity: 1; -} .contacts_modal_search { padding: 3px 0 12px; } .contacts_modal_col { - margin-right: -12px; -} -.contacts_scrollable_wrap { - padding-right: 12px; -} -.contacts_modal_col .nano > .nano-pane { - width: 6px; - right: 5px; + margin: 0 -9px; } .contacts_modal_members_list a.contacts_modal_contact { - padding: 8px 0; + padding: 8px 9px; border-radius: 0; - border-bottom: 1px solid #e0e0e0; + border-bottom: 1px solid #eee; } .contacts_modal_members_list li.contacts_modal_contact_wrap { margin: 0; diff --git a/app/js/directives_mobile.js b/app/js/directives_mobile.js index d20dec94..5e3374a7 100644 --- a/app/js/directives_mobile.js +++ b/app/js/directives_mobile.js @@ -89,7 +89,7 @@ angular.module('myApp.directives') } $(element).css({ height: $($window).height() - - (headWrap ? headWrap.offsetHeight : 44) - + (headWrap ? headWrap.offsetHeight : 46) - (panelWrap ? panelWrap.offsetHeight : 58) - parseInt($(dialogsColWrap).css('paddingBottom') || 0) }); @@ -112,10 +112,8 @@ angular.module('myApp.directives') function link ($scope, element, attrs) { var historyWrap = $('.im_history_wrap', element)[0], historyMessagesEl = $('.im_history_messages', element)[0], - historyEl = $('.im_history', element)[0], scrollableWrap = $('.im_history_scrollable_wrap', element)[0], scrollable = $('.im_history_scrollable', element)[0], - panelWrap = $('.im_history_panel_wrap', element)[0], bottomPanelWrap = $('.im_bottom_panel_wrap', element)[0], sendFormWrap = $('.im_send_form_wrap', element)[0], headWrap = $('.tg_page_head')[0], @@ -127,82 +125,58 @@ angular.module('myApp.directives') scrollableWrap.scrollTop = scrollableWrap.scrollHeight; }); - var transform = false, - trs = ['transform', 'webkitTransform', 'MozTransform', 'msTransform', 'OTransform'], - i; - for (i = 0; i < trs.length; i++) { - if (trs[i] in historyMessagesEl.style) { - transform = trs[i]; - break; - } - } - - var animated = transform ? true : false, - curAnimation = false; - $scope.$on('ui_history_append_new', function (e, options) { if (!atBottom && !options.my) { return; } - var curAnimated = animated && - !$rootScope.idle.isIDLE && - historyMessagesEl.clientHeight > 0, - wasH; - - if (curAnimated) { - wasH = scrollableWrap.scrollHeight; - } else { - $(scrollable).css({bottom: 0}); - $(scrollableWrap).addClass('im_history_to_bottom'); - } + + var pr = parseInt($(scrollableWrap).css('paddingRight')) + $(scrollableWrap).addClass('im_history_to_bottom'); + $(scrollable).css({bottom: 0, marginLeft: -Math.ceil(pr / 2)}); onContentLoaded(function () { - if (curAnimated) { - curAnimation = true; - $(historyMessagesEl).removeClass('im_history_appending'); - scrollableWrap.scrollTop = scrollableWrap.scrollHeight; - $(historyMessagesEl).css(transform, 'translate(0px, ' + (scrollableWrap.scrollHeight - wasH) + 'px)'); - var styles = {}; - styles[transform] = 'translate(0px, 0px)'; - $(historyMessagesEl).addClass('im_history_appending'); - $transition($(historyMessagesEl), styles).then(function () { - curAnimation = false; - $(historyMessagesEl).removeClass('im_history_appending'); - updateBottomizer(); - }); - } else { - $(scrollableWrap).removeClass('im_history_to_bottom'); - $(scrollable).css({bottom: ''}); - scrollableWrap.scrollTop = scrollableWrap.scrollHeight; - updateBottomizer(); - } + $(scrollableWrap).removeClass('im_history_to_bottom'); + $(scrollable).css({bottom: '', marginLeft: ''}); + scrollableWrap.scrollTop = scrollableWrap.scrollHeight; + updateBottomizer(); }); }); function changeScroll () { var unreadSplit, focusMessage; + // console.trace('change scroll'); if (focusMessage = $('.im_message_focus:visible', scrollableWrap)[0]) { - scrollableWrap.scrollTop = Math.max(0, focusMessage.offsetTop - Math.floor(scrollableWrap.clientHeight / 2) + 26); + var ch = scrollableWrap.clientHeight, + st = scrollableWrap.scrollTop, + ot = focusMessage.offsetTop, + h = focusMessage.clientHeight; + if (!st || st + ch < ot || st > ot + h) { + scrollableWrap.scrollTop = Math.max(0, ot - Math.floor(ch / 2) + 26); + } atBottom = false; } else if (unreadSplit = $('.im_message_unread_split:visible', scrollableWrap)[0]) { + // console.log('change scroll unread', unreadSplit.offsetTop); scrollableWrap.scrollTop = Math.max(0, unreadSplit.offsetTop - 52); atBottom = false; } else { + // console.log('change scroll bottom'); scrollableWrap.scrollTop = scrollableWrap.scrollHeight; atBottom = true; } $timeout(function () { $(scrollableWrap).trigger('scroll'); + scrollTopInitial = scrollableWrap.scrollTop; }); }; $scope.$on('ui_history_change', function () { + var pr = parseInt($(scrollableWrap).css('paddingRight')) $(scrollableWrap).addClass('im_history_to_bottom'); - $(scrollable).css({bottom: 0}); + $(scrollable).css({bottom: 0, marginLeft: -Math.ceil(pr / 2)}); onContentLoaded(function () { $(scrollableWrap).removeClass('im_history_to_bottom'); - $(scrollable).css({bottom: ''}); + $(scrollable).css({bottom: '', marginLeft: ''}); updateSizes(true); moreNotified = false; lessNotified = false; @@ -227,14 +201,18 @@ angular.module('myApp.directives') pr = parseInt($(scrollableWrap).css('paddingRight')), ch = scrollableWrap.clientHeight; + $(scrollable).css({marginBottom: -(sh - st - ch - 4), marginLeft: -Math.ceil(pr / 2)}); $(scrollableWrap).addClass('im_history_to_bottom'); - scrollableWrap.scrollHeight; // Some strange Chrome bug workaround - $(scrollable).css({bottom: -(sh - st - ch), marginLeft: -Math.ceil(pr / 2)}); + var upd = function () { $(scrollableWrap).removeClass('im_history_to_bottom'); - $(scrollable).css({bottom: '', marginLeft: ''}); - scrollableWrap.scrollTop = st + scrollableWrap.scrollHeight - sh; + $(scrollable).css({marginBottom: '', marginLeft: ''}); + if (scrollTopInitial >= 0) { + changeScroll(); + } else { + scrollableWrap.scrollTop = st + scrollableWrap.scrollHeight - sh; + } updateBottomizer(); moreNotified = false; @@ -259,6 +237,10 @@ angular.module('myApp.directives') updateBottomizer(); lessNotified = false; + if (scrollTopInitial >= 0) { + changeScroll(); + } + $timeout(function () { if (scrollableWrap.scrollHeight != sh) { $(scrollableWrap).trigger('scroll'); @@ -293,23 +275,26 @@ angular.module('myApp.directives') $scope.$on('ui_editor_resize', updateSizes); $scope.$on('ui_height', function () { onContentLoaded(updateSizes); - // updateSizes(); }); - var atBottom = true; + var atBottom = true, + scrollTopInitial = -1; $(scrollableWrap).on('scroll', function (e) { if (!element.is(':visible') || - $(scrollableWrap).hasClass('im_history_to_bottom') || - curAnimation) { + $(scrollableWrap).hasClass('im_history_to_bottom')) { return; } - atBottom = scrollableWrap.scrollTop >= scrollableWrap.scrollHeight - scrollableWrap.clientHeight; + var st = scrollableWrap.scrollTop; + atBottom = st >= scrollableWrap.scrollHeight - scrollableWrap.clientHeight; + if (scrollTopInitial >= 0 && scrollTopInitial != st) { + scrollTopInitial = -1; + } - if (!moreNotified && scrollableWrap.scrollTop <= 300) { + if (!moreNotified && st <= 300) { moreNotified = true; $scope.$emit('history_need_more'); } - else if (!lessNotified && scrollableWrap.scrollTop >= scrollableWrap.scrollHeight - scrollableWrap.clientHeight - 300) { + else if (!lessNotified && st >= scrollableWrap.scrollHeight - scrollableWrap.clientHeight - 300) { lessNotified = true; $scope.$emit('history_need_less'); } @@ -328,7 +313,7 @@ angular.module('myApp.directives') if (!headWrap || !headWrap.offsetHeight) { headWrap = $('.tg_page_head')[0]; } - var historyH = $($window).height() - panelWrap.offsetHeight - bottomPanelWrap.offsetHeight - (headWrap ? headWrap.offsetHeight : 44); + var historyH = $($window).height() - bottomPanelWrap.offsetHeight - (headWrap ? headWrap.offsetHeight : 46); $(historyWrap).css({ height: historyH }); @@ -345,11 +330,11 @@ angular.module('myApp.directives') } function updateBottomizer () { + return; $(historyMessagesEl).css({marginTop: 0}); var marginTop = scrollableWrap.offsetHeight - historyMessagesEl.offsetHeight - - 20 - - (Config.Mobile ? 0 : 49); + - 20; if (historyMessagesEl.offsetHeight > 0 && marginTop > 0) { $(historyMessagesEl).css({marginTop: marginTop}); @@ -362,4 +347,87 @@ angular.module('myApp.directives') onContentLoaded(updateSizes); } + }) + + .directive('myContactsListMobile', function($window, $timeout) { + + return { + link: link + }; + + function link ($scope, element, attrs) { + var searchWrap = $('.contacts_modal_search')[0], + panelWrap = $('.contacts_modal_panel')[0]; + + function updateSizes () { + $(element).css({ + height: $($window).height() - + (panelWrap && panelWrap.offsetHeight || 0) - + (searchWrap && searchWrap.offsetHeight || 0) - + 64 + }); + } + + $($window).on('resize', updateSizes); + $scope.$on('contacts_change', function () { + onContentLoaded(updateSizes) + }); + onContentLoaded(updateSizes); + }; + + }) + + .directive('myCountriesListMobile', function($window, $timeout) { + + return { + link: link + }; + + function link ($scope, element, attrs) { + var searchWrap = $('.countries_modal_search')[0], + panelWrap = $('.countries_modal_panel')[0]; + + function updateSizes () { + $(element).css({ + height: $($window).height() + - (panelWrap && panelWrap.offsetHeight || 0) + - (searchWrap && searchWrap.offsetHeight || 0) + - (46 + 18) + }); + } + + $($window).on('resize', updateSizes); + onContentLoaded(updateSizes); + }; + + }) + + .directive('myInfiniteScrollerMobile', function () { + + return { + link: link, + scope: true + }; + + function link($scope, element, attrs) { + + var scrollableWrap = element[0], + moreNotified = false; + + $(scrollableWrap).on('scroll', function (e) { + if (!element.is(':visible')) return; + if (!moreNotified && + scrollableWrap.scrollTop >= scrollableWrap.scrollHeight - scrollableWrap.clientHeight - 300) { + moreNotified = true; + $scope.$apply(function () { + $scope.slice.limit += ($scope.slice.limitDelta || 20); + }); + + onContentLoaded(function () { + moreNotified = false; + }); + } + }); + + }; }) \ No newline at end of file diff --git a/app/partials/desktop/head.html b/app/partials/desktop/head.html index 0de2e01f..510ec950 100644 --- a/app/partials/desktop/head.html +++ b/app/partials/desktop/head.html @@ -2,112 +2,8 @@ diff --git a/app/partials/mobile/im.html b/app/partials/mobile/im.html index 54036d94..0b7c25ec 100644 --- a/app/partials/mobile/im.html +++ b/app/partials/mobile/im.html @@ -19,7 +19,7 @@ -
+

No contacts yet

@@ -65,13 +65,6 @@
-
-
-

Get started

-

Welcome to Telegram Web. You can always set your profile photo and change your name in Settings.

- -
-
Loading history
@@ -79,58 +72,7 @@
-
- -
-
- - Info - Edit - - - - Show recent messages - Show all messages - - - -
-

Photos

-

Videos

-

Documents

-

Voice messages

- -

-
- - -
-
- - - - - -
-

-
- -
- -
- -
- -
+
@@ -140,7 +82,7 @@
-
+
diff --git a/app/partials/mobile/peer_select.html b/app/partials/mobile/peer_select.html index c7dbcb61..f36ceaab 100644 --- a/app/partials/mobile/peer_select.html +++ b/app/partials/mobile/peer_select.html @@ -32,41 +32,37 @@
-
-
-
- -
-
Contacts
- -
-
+
+ +
+
Contacts
+
diff --git a/app/partials/mobile/phonebook_modal.html b/app/partials/mobile/phonebook_modal.html index c3dae07f..18ef0623 100644 --- a/app/partials/mobile/phonebook_modal.html +++ b/app/partials/mobile/phonebook_modal.html @@ -37,45 +37,41 @@
-
+
+
-
-
- -
- Your phonebook is empty. -
+
+ Your phonebook is empty. +
- -
-