From 0fc42cbe0debda002b0507824749ae101bbba4ef Mon Sep 17 00:00:00 2001 From: Igor Zhukov Date: Thu, 27 Nov 2014 13:20:09 +0000 Subject: [PATCH] Updated desktop media modals New photo viewer with preloads New video modal New document modal --- app/css/app.css | 75 +------ app/css/desktop.css | 191 +++++++++++++++++- app/img/icons/PhotoControls.png | Bin 2411 -> 0 bytes app/img/icons/PhotoControls_1x.png | Bin 1255 -> 0 bytes app/img/icons/PhotoIcons.png | Bin 0 -> 3785 bytes app/img/icons/PhotoIcons_1x.png | Bin 0 -> 2463 bytes app/js/controllers.js | 68 +++++-- app/js/directives.js | 50 +++-- app/js/filters.js | 9 +- app/js/lib/mtproto.js | 2 +- app/js/lib/utils.js | 5 + app/js/locales/en-us.json | 1 + app/js/services.js | 47 +++-- app/partials/desktop/document_modal.html | 52 +++-- app/partials/desktop/media_modal_layout.html | 1 + app/partials/desktop/photo_modal.html | 61 ++++-- app/partials/desktop/video_modal.html | 53 +++-- .../ui-bootstrap-custom-tpls-0.12.0.js | 11 +- 18 files changed, 450 insertions(+), 176 deletions(-) delete mode 100644 app/img/icons/PhotoControls.png delete mode 100644 app/img/icons/PhotoControls_1x.png create mode 100644 app/img/icons/PhotoIcons.png create mode 100644 app/img/icons/PhotoIcons_1x.png create mode 100644 app/partials/desktop/media_modal_layout.html diff --git a/app/css/app.css b/app/css/app.css index 3311d532..433deb14 100644 --- a/app/css/app.css +++ b/app/css/app.css @@ -290,8 +290,9 @@ input[type="number"] { } .modal-backdrop { - background: #111111; - opacity: 0.25 !important; + background: rgba(26, 26, 26, 0.7); + opacity: 1 !important; + /*opacity: 0.25 !important;*/ } .modal.fade .modal-dialog { @@ -318,69 +319,10 @@ input[type="number"] { } .modal-content { border: 0; - border-radius: 4px; + border-radius: 0; -webkit-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.15); box-shadow: 0 1px 10px rgba(0, 0, 0, 0.15); } -.modal_close_wrap { - cursor: pointer; - position: fixed; - top: 0; - right: 0; - width: 50%; - height: 100%; -} -.modal_close { - background: url(../img/icons/PhotoControls.png) 0 -53px no-repeat; - background-size: 33px 86px; - width: 33px; - height: 33px; - float: right; - margin: 60px 30px 0 0; - opacity: 0.6; - pointer-events: none; - - -webkit-transition : .2s; - -moz-transition : .2s; - -o-transition : .2s; - transition : .2s; -} -.modal_close_wrap:hover .modal_close { - opacity: 0.85; -} - - -.modal_prev_wrap { - cursor: pointer; - position: fixed; - top: 0; - left: 0; - width: 50%; - height: 100%; -} -.modal_prev { - background: url(../img/icons/PhotoControls.png) 0 0 no-repeat; - background-size: 33px 86px; - width: 33px; - height: 33px; - float: left; - margin: 60px 0 0 30px; - opacity: 0.6; - pointer-events: none; - - -webkit-transition : .2s; - -moz-transition : .2s; - -o-transition : .2s; - transition : .2s; -} -.modal_prev_wrap:hover .modal_prev { - opacity: 0.85; -} - -.is_1x .modal_close, -.is_1x .modal_prev { - background-image: url(../img/icons/PhotoControls_1x.png); -} .text-invisible { visibility: hidden; @@ -1894,9 +1836,6 @@ textarea.im_message_field { } -.media_modal_wrap .modal-body { - padding: 19px 18px 17px; -} a.img_fullsize, .img_fullsize_wrap { display: block; @@ -2158,7 +2097,11 @@ img.img_fullsize { } - +.photo_modal_window, +.video_modal_window, +.document_modal_window { + display: block; +} .photo_modal_error { color: #999; position: absolute; diff --git a/app/css/desktop.css b/app/css/desktop.css index 3891c7f3..32db34b1 100644 --- a/app/css/desktop.css +++ b/app/css/desktop.css @@ -976,4 +976,193 @@ div.im_panel_own_photo { .changelog_modal_window .modal-dialog { max-width: 506px; -} \ No newline at end of file +} + + +.modal_close_wrap { + display: none; + cursor: pointer; + position: fixed; + top: 0; + right: 0; + width: 50%; + height: 100%; +} +.modal_close_wrap_wnext { + width: 104px; + height: 150px; +} +.modal_close { + background: url(../img/icons/PhotoIcons.png) -10px -10px no-repeat; + background-size: 40px 200px; + width: 20px; + height: 21px; + float: right; + margin: 43px 40px 0 0; + opacity: 0.5; + pointer-events: none; + + -webkit-transition : .2s; + -moz-transition : .2s; + -o-transition : .2s; + transition : .2s; +} +.modal_close_wrap:hover .modal_close { + opacity: 1; +} + +.modal_prev_wrap, +.modal_next_wrap { + display: none; + cursor: pointer; + position: fixed; + top: 0; + left: 0; + bottom: 64px; + width: 104px; +} +.modal_next_wrap { + left: auto; + right: 0; +} +.modal_prev, +.modal_next { + background: url(../img/icons/PhotoIcons.png) -12px -41px no-repeat; + background-size: 40px 200px; + width: 16px; + height: 24px; + opacity: 0.5; + position: absolute; + top: 50%; + pointer-events: none; + margin: 0 0 0 38px; + + -webkit-transition : .2s; + -moz-transition : .2s; + -o-transition : .2s; + transition : .2s; +} +.modal_next { + margin: 0 0 0 50px; + background-position: -14px -75px; +} +.modal_prev_wrap:hover, +.modal_next_wrap:hover { + background-color: rgba(0,0,0,0.2); +} +.modal_prev_wrap:hover .modal_prev, +.modal_next_wrap:hover .modal_next { + opacity: 1; +} + +.is_1x .modal_close, +.is_1x .modal_prev, +.is_1x .modal_next { + background-image: url(../img/icons/PhotoIcons_1x.png); +} + +@media (min-width: 800px) { + .modal_close_wrap, + .modal_next_wrap, + .modal_prev_wrap { + display: block; + } +} + +.media_modal_bottom_panel_wrap { + position: fixed; + bottom: 0; + left: 0; + right: 0; + height: 64px; + background: #313131; +} +.media_modal_bottom_panel { + max-width: 1000px; + margin: 0 auto; + color: rgba(255, 255, 255, 0.6); +} + +.media_modal_title_wrap { + max-width: 300px; + margin: 0 auto; + text-align: center; + font-size: 14px; + line-height: 16px; + padding: 24px 0; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} +.media_modal_info_wrap { + line-height: 16px; + padding: 24px 20px; +} +.media_modal_author { + font-size: 14px; + margin-right: 4px; +} +.media_modal_date, +a.media_modal_date:hover { + font-size: 12px; + color: rgba(255, 255, 255, 0.4); +} + +.photo_modal_window, +.video_modal_window, +.document_modal_window { + padding: 0; +} +.media_modal_wrap .modal-body { + padding: 16px; +} +.video_modal_window .modal-body { + padding: 0; +} +.media_modal_bottom_actions { + width: 204px; +} +.media_modal_action_btn { + float: left; + display: block; + width: 68px; + height: 64px; +} +.media_modal_action_btn:hover { + background: rgba(0,0,0,0.2); +} + +.media_modal_action_btn i { + background: url(../img/icons/PhotoIcons.png) 0 0 no-repeat; + background-size: 40px 200px; + display: block; + opacity: 0.5; +} +.media_modal_action_btn:hover i { + opacity: 1; +} +.is_1x .media_modal_action_btn i { + background-image: url(../img/icons/PhotoIcons_1x.png); +} + +.media_modal_action_btn i.media_modal_action_btn_download { + background-position: -12px -163px; + width: 16px; + height: 20px; + margin: 22px 26px; +} +.media_modal_action_btn i.media_modal_action_btn_forward { + background-position: -9px -109px; + width: 23px; + height: 15px; + margin: 24px 22px; +} +.media_modal_action_btn i.media_modal_action_btn_delete { + background-position: -13px -135px; + width: 14px; + height: 18px; + margin: 23px 27px; +} + + + diff --git a/app/img/icons/PhotoControls.png b/app/img/icons/PhotoControls.png deleted file mode 100644 index 8abd1c586ce4720bde00270eebb31debeeb22cf5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2411 zcmbW3`9IT-AHZiD=KAz@U&GMc$BLH9u?ZPkg;o@1HszSRF!>mklsiNycjw1dGQQ3^ z!s6p2IX<>e&gpPON*n6)-S=Pkz8;U)>-l(Hzq}rg*X!}ReHMR8Mp8`@1Omz6oE_YS zv={0hFfpMWQ=_Q~0lk7fjRk=khK`Ef`6TpJV;nEWc!USW#QH~3Kv;4(iGsjU{jX5m zDgNa6$YF{#2n73ybHIAW&8|J*obfybAG{K4_`CvPpk$zfFbp+5XC`VC^s1(^zo^8L z`c}`o{IhF-sXs^= zqpn=u88H{|OxoYH-MGGTwEMnAbeAnDt2X&V%43f?F-_1|ZsHZiec8lLjGuY(*!WoM z%q!WEW@4x7`fg^vvID7q^wN#V=TCLVxw{u`+s6%Mf-Tt=g_Yb=W5@-paPX zo#-Lq%Wf(#T-Vyvv?`zTS{qS-fpVowA@h`ZT)*a?)V@;Lbfzf+WDi46!k^Q9PXczm z0#h$=iZ5Swv$H>bN4jIe`P#S?NuMv?EQo%QMUSl;l)Ng9S*9ON>9*(kd(2PM2cqvG zBzxu_3zAEvw{y_+%97lmw#Lgv_Lv044iRwsoJqPHH_ugjC}~JH5CaWzbJp8nk_;4i zPFQ#(cC}*g8OW){7tp@7A`zHBNGp*E0VmrGc;78<$qMW%!MvL(G=|&#eq*e^zyJPO zg97#zO4~s3#3W|zbq`6Iaqr%}mp50{4%CL7Nj@0D&e07&fk;k=fW~8j#ZAp(K**;BGA`VtNML#OVWS z4ju;U{L=^g)q*L5>7;9DrXl|R4che2k}$Ft4|OTRVqAA#;%hF$w87x^8ox&F5}(g6 z8WaduVpr@*;+WvN8;sb}n`2d$( z)J*B|Gw%t`iE9c93W|Fd_&9>yITKX zIN*y}%2tNu%dAUZCPYyYpL@>0z~ONb8V{nZGHYOh=Z4=^qnyijDm-CND3a6EBJrg!%|f?aKa$=Vb4! za@(SRj*gC+Mv&C=M-mbe+KY;c%A=1jyG}n_yJj|f&S)7~{p5*(6v*1d)bwXCjkaqz z_!fms(w(w)E%X1^40m}?c|QcSm1zK8cC|UQDS(QN*D@MaVa;EHY+NkWFAyY-05d5u zNEJrwv_kkpWPQ0B4uH+^Cm^>?i5Wgh!?@RhkrA<~?_^$RSK-aYwE6nkmzxQbeZ6AmTOS@z>VVo>7WH$3I z@8b*Y6C@UbPoHuO#_oN`3226h|+x zG)nz;{cMv4BcOoe?AbV?1Y~=LO{kw7p+|H?l|KATQeZq6W@3;Q(LlXtnC`gf*Aa{Y zplr+>a2@(qGgE&dY$9sIzU?$5o#7s)YqV?sP>4uPw~xnoEu${2XTvfey=Wdf!^A

y*uXt^2CU z&VUXz0abkGnap6ehQ%&da)(X5(BQj%$;T)0#UW>wNE$qa9J|3)4G9Ukglct#yO5uA z(y$f+%SZRK}$b=3+F-*{SD+A|CSz;Plol9u-PZKHsW z>55?cgE+)8Y5vjsM~Z2ufrA-O42j;O=W$pWF><;Vfk2oQ6`?AfK-q*nEc1xgKVSdM3MazFc7;t1o|>EcH$FaIP$k z_KdV{6*q14gN;6>F?hzDa2R>5Z)>lLa1#i_(y#KFd6$yITS0BDN6~ z7;3=8A;IP7{T>`(Vx+qCRw~{vVC3Wb<0nqoEr?*Hq~&A(v&mY_Z^AH!|IHy!QR?dI znDZ$`@z-kuSSlJCozzAAG>|vinjhOTWl%i*Z6lIMoL^X5Te}(%5a4J9*IYjG5Rs#L z^5jX#h?e@~);>qJU#ipRH6UoM|BU_Pbienb{TUFvY(Q01XtW!LH#aMIH#`2W>;61G*m zS{IKC$A)B$l$c#GUeJH|iAM~Xvaf%5zr*b7_ki5+Q^ z6>>s*nbx5nkOx|TrlD^<9s2!#!KU;NDQq^Ih?k>KA(Ws4*af{oU(;F_szLxD7cZxw zM8SA0La)%LTNeak4|EpF70e0xRl@)o;f1h67udX;9g|SMKXATfAY!4576C}{0SqtH zAkLdO1#0mUAn)WL@}LSKJh1~k1PCo@K@7MNON{o|*4B1vbab@AZnuk^P3XF^z&|LC zv7}=NpsA^;p|G&9xV5$QgpQ^eNC5|>=^$N!;*A1`q8QuL)AOjhy85xsE0~ygEs|GdISKZ+hH+=?FsuL03gK%k?fBk07W7}#6=K*!XdI8p&9k{_2&q{ z>-Bn?o16PhOkASK4kMaTTU&e2?RL+_$Hyo2_4QpZDk@4a31W*Nd^}eoBW_eyR^B3z z@l*8cGE$3D4O$H4gz)QW8NQZoLfsGnm3b;Vfn{-?KWLdwQ7S=S-jJ&D zzb-~Fkd%Pu6Hb;!!Zafea_fb##E64Ncp)q|;uw@7L|BYC=!F_Y*o-*nog75ijW}A; z1i@v*RaI4`W@TmB^?Zv)8+}F`b=KY8eRFVdu#p#}uC6XkYLk+ZqU0iEKnEoVnvw#g z4#&pE);u1M8vuDcAOz6W)pf(^bS6$sO-(N^FK?+_ULZlJ8ga9;vzsL)CAa71=00nI z1Of~U3_L3qd`28?V7!S)4n$=G+szSNMjUNmtE;O^ zym=rHL}LT{W5h{^8hX8~l)~xPXzYeY+KdaoO_<0Uadc0}oiW2^#6dG^M}EtVIOx4r z-C?N_$7&DmGSGA*j@75SYf;mTIF^_~dNg3zh=aUlKcC<-;*=_IC5T@F3;;Ny5Zk9+ Rph5ru002ovPDHLkV1j#`CsP0b diff --git a/app/img/icons/PhotoIcons.png b/app/img/icons/PhotoIcons.png new file mode 100644 index 0000000000000000000000000000000000000000..70e31b9797718a3d201fd3ac669672c377c48f1b GIT binary patch literal 3785 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 R^L*_u6NBbMt)@iE{{kv|0YCr% literal 0 HcmV?d00001 diff --git a/app/js/controllers.js b/app/js/controllers.js index 9f1e42b2..70b77cc8 100644 --- a/app/js/controllers.js +++ b/app/js/controllers.js @@ -1510,12 +1510,6 @@ angular.module('myApp.controllers', ['myApp.i18n']) AppPhotosManager.downloadPhoto($scope.photoID); }; - if (!$scope.messageID || Config.Mobile) { - $scope.nav.next = function () { - $modalInstance.close(); - } - } - if (!$scope.messageID) { return; } @@ -1531,6 +1525,14 @@ angular.module('myApp.controllers', ['myApp.i18n']) }); }; + $scope.goToMessage = function () { + var messageID = $scope.messageID; + var peerID = AppMessagesManager.getMessagePeer(AppMessagesManager.getMessage(messageID)); + var peerString = AppPeersManager.getPeerString(peerID); + $modalInstance.dismiss(); + $rootScope.$broadcast('history_focus', {peerString: peerString, messageID: messageID}); + }; + if (Config.Mobile) { $scope.canForward = true; @@ -1550,21 +1552,24 @@ angular.module('myApp.controllers', ['myApp.i18n']) inputQuery = '', inputFilter = {_: 'inputMessagesFilterPhotos'}, list = [$scope.messageID], + preloaded = {}, maxID = $scope.messageID, hasMore = true; + preloaded[$scope.messageID] = true; + updatePrevNext(); AppMessagesManager.getSearch(inputPeer, inputQuery, inputFilter, 0, 1000).then(function (searchCachedResult) { - // console.log(dT(), 'search cache', searchCachedResult); if (searchCachedResult.history.indexOf($scope.messageID) >= 0) { list = searchCachedResult.history; maxID = list[list.length - 1]; updatePrevNext(); + preloadPhotos(+1); } - // console.log(dT(), list, maxID); - }); + loadMore(); + }, loadMore); var jump = 0; @@ -1575,7 +1580,7 @@ angular.module('myApp.controllers', ['myApp.i18n']) var promise = index >= list.length ? loadMore() : $q.when(); promise.then(function () { - if (curJump != jump || !hasMore) { + if (curJump != jump) { return; } @@ -1593,10 +1598,33 @@ angular.module('myApp.controllers', ['myApp.i18n']) $scope.photoID = message.media.photo.id; $scope.photo = AppPhotosManager.wrapForFull($scope.photoID); + preloaded[$scope.messageID] = true; + updatePrevNext(); + + if (sign > 0 && hasMore && list.indexOf(messageID) + 1 >= list.length) { + loadMore(); + } else { + preloadPhotos(sign); + } }); }; + function preloadPhotos (sign) { + // var preloadOffsets = sign < 0 ? [-1,-2,1,-3,2] : [1,2,-1,3,-2]; + var preloadOffsets = sign < 0 ? [-1,-2] : [1,2]; + var index = list.indexOf($scope.messageID); + angular.forEach(preloadOffsets, function (offset) { + var messageID = list[index + offset]; + if (messageID !== undefined && preloaded[messageID] === undefined) { + preloaded[messageID] = true; + var message = AppMessagesManager.getMessage(messageID); + var photoID = message.media.photo.id; + AppPhotosManager.preloadPhoto(photoID); + } + }) + } + var loadingPromise = false; function loadMore () { if (loadingPromise) return loadingPromise; @@ -1610,13 +1638,27 @@ angular.module('myApp.controllers', ['myApp.i18n']) hasMore = false; } - updatePrevNext(); + updatePrevNext(searchResult.count); loadingPromise = false; + + if (searchResult.history.length) { + return $q.reject(); + } + + preloadPhotos(+1); }); }; - function updatePrevNext () { + function updatePrevNext (count) { var index = list.indexOf($scope.messageID); + if (hasMore) { + if (count) { + $scope.count = Math.max(count, list.length); + } + } else { + $scope.count = list.length; + } + $scope.pos = $scope.count - index; $scope.nav.hasNext = index > 0; $scope.nav.hasPrev = hasMore || index < list.length - 1; $scope.canForward = $scope.canDelete = $scope.messageID > 0; @@ -1658,8 +1700,6 @@ angular.module('myApp.controllers', ['myApp.i18n']) } }); - loadMore(); - }) .controller('UserpicModalController', function ($q, $scope, $rootScope, $modalInstance, AppPhotosManager, AppUsersManager, AppPeersManager, AppMessagesManager, PeersSelectService, ErrorService) { diff --git a/app/js/directives.js b/app/js/directives.js index cbc9b10a..1dd42f92 100644 --- a/app/js/directives.js +++ b/app/js/directives.js @@ -1429,7 +1429,7 @@ angular.module('myApp.directives', ['myApp.filters']) .add($(imgElement)), resize = function () { resizeElements.css({width: $scope.fullPhoto.width, height: $scope.fullPhoto.height}); - $scope.$emit('ui_height'); + $scope.$emit('ui_height', true); }; var jump = 0; @@ -1621,7 +1621,7 @@ angular.module('myApp.directives', ['myApp.filters']) element = element.parentNode; } if (element) { - $(element).width(width + (Config.Mobile ? 0 : 36)); + $(element).width(width + (Config.Mobile ? 0 : 32)); } } @@ -1630,8 +1630,11 @@ angular.module('myApp.directives', ['myApp.filters']) var fullSizeWrap = $('.document_fullsize_wrap', element); var fullSizeImage = $('.document_fullsize_img', element); - var fullWidth = $(window).width() - (Config.Mobile ? 20 : 36); + var fullWidth = $(window).width() - (Config.Mobile ? 20 : 32); var fullHeight = $(window).height() - 150; + if (fullWidth > 800) { + fullWidth -= 208; + } $scope.imageWidth = fullWidth; $scope.imageHeight = fullHeight; @@ -1823,7 +1826,7 @@ angular.module('myApp.directives', ['myApp.filters']) function link($scope, element, attrs) { attrs.$observe('myModalWidth', function (newW) { - $(element[0].parentNode.parentNode).css({width: parseInt(newW) + (Config.Mobile ? 0 : 36)}); + $(element[0].parentNode.parentNode).css({width: parseInt(newW) + (Config.Mobile ? 0 : 32)}); }); }; @@ -1931,7 +1934,9 @@ angular.module('myApp.directives', ['myApp.filters']) return; } var height = element[0].parentNode.offsetHeight, - contHeight = element[0].parentNode.parentNode.parentNode.offsetHeight; + modal = element[0].parentNode.parentNode.parentNode, + bottomPanel = $('.media_modal_bottom_panel_wrap', modal)[0], + contHeight = modal.offsetHeight - (bottomPanel && bottomPanel.offsetHeight || 0); if (height < contHeight) { $(element[0].parentNode).css('marginTop', (contHeight - height) / 2); @@ -1950,8 +1955,12 @@ angular.module('myApp.directives', ['myApp.filters']) $($window).on('resize', updateMargin); - $scope.$on('ui_height', function () { - onContentLoaded(updateMargin); + $scope.$on('ui_height', function (e, sync) { + if (sync) { + updateMargin(); + } else { + onContentLoaded(updateMargin); + } }); }; @@ -2013,20 +2022,33 @@ angular.module('myApp.directives', ['myApp.filters']) }; function link($scope, element, attrs) { - var userID = $scope.$eval(attrs.myUserLink), - user = AppUsersManager.getUser(userID); - element.html( - (user[attrs.short && $scope.$eval(attrs.short) ? 'rFirstName' : 'rFullName'] || '').valueOf() - ); + var userID; + var update = function () { + var user = AppUsersManager.getUser(userID); + + element.html( + (user[attrs.short && $scope.$eval(attrs.short) ? 'rFirstName' : 'rFullName'] || '').valueOf() + ); + if (attrs.color && $scope.$eval(attrs.color)) { + element.addClass('user_color_' + user.num); + } + }; if (element[0].tagName == 'A') { element.on('click', function () { AppUsersManager.openUser(userID, attrs.userOverride && $scope.$eval(attrs.userOverride)); }); } - if (attrs.color && $scope.$eval(attrs.color)) { - element.addClass('user_color_' + user.num); + + if (attrs.userWatch) { + $scope.$watch(attrs.myUserLink, function (newUserID) { + userID = newUserID; + update(); + }); + } else { + userID = $scope.$eval(attrs.myUserLink); + update(); } } }) diff --git a/app/js/filters.js b/app/js/filters.js index 0211ca2e..26438a4b 100644 --- a/app/js/filters.js +++ b/app/js/filters.js @@ -66,15 +66,10 @@ angular.module('myApp.filters', ['myApp.i18n']) }) .filter('dateOrTime', function($filter) { - var cachedDates = {}, - dateFilter = $filter('date'); + var dateFilter = $filter('date'); return function (timestamp, extended) { - if (cachedDates[timestamp]) { - return cachedDates[timestamp]; - } - var ticks = timestamp * 1000, diff = Math.abs(tsNow() - ticks), format = 'shortTime'; @@ -86,7 +81,7 @@ angular.module('myApp.filters', ['myApp.i18n']) format = extended ? 'EEEE' : 'EEE'; } - return cachedDates[timestamp] = dateFilter(ticks, format); + return dateFilter(ticks, format); } }) diff --git a/app/js/lib/mtproto.js b/app/js/lib/mtproto.js index 4be592a2..f77f222f 100644 --- a/app/js/lib/mtproto.js +++ b/app/js/lib/mtproto.js @@ -17,7 +17,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) {id: 3, host: '174.140.142.5', port: 80} ] : [ - {id: 1, host: '173.240.5.1', port: 80}, + {id: 1, host: '149.154.175.50', port: 80}, {id: 2, host: '149.154.167.51', port: 80}, {id: 3, host: '174.140.142.6', port: 80}, {id: 4, host: '149.154.167.91', port: 80}, diff --git a/app/js/lib/utils.js b/app/js/lib/utils.js index f1ceb9bd..f95cad93 100644 --- a/app/js/lib/utils.js +++ b/app/js/lib/utils.js @@ -139,6 +139,11 @@ function calcImageInBox(imageW, imageH, boxW, boxH, noZooom) { } } + if (Config.Navigator.retina) { + imageW = Math.floor(imageW / 2); + imageH = Math.floor(imageH / 2); + } + if (noZooom && boxedImageW >= imageW && boxedImageH >= imageH) { boxedImageW = imageW; boxedImageH = imageH; diff --git a/app/js/locales/en-us.json b/app/js/locales/en-us.json index cd0f016f..54b94fbf 100644 --- a/app/js/locales/en-us.json +++ b/app/js/locales/en-us.json @@ -79,6 +79,7 @@ "user_modal_notifications": "Notifications", "user_modal_contact_info": "Contact info", + "media_modal_photo": "Photo {pos} of {count}", "media_modal_forward": "Forward", "media_modal_download": "Download", "media_modal_delete": "Delete", diff --git a/app/js/services.js b/app/js/services.js index 4665b8ba..2285b71a 100644 --- a/app/js/services.js +++ b/app/js/services.js @@ -610,6 +610,12 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) } return text; }, + getPeerString: function (peerID) { + if (peerID > 0) { + return AppUsersManager.getUserString(peerID); + } + return AppChatsManager.getChatString(-peerID); + }, getOutputPeer: function (peerID) { return peerID > 0 ? {_: 'peerUser', user_id: peerID} @@ -1673,13 +1679,11 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) if (message.chatID = message.to_id.chat_id) { message.peerID = -message.chatID; message.peerData = AppChatsManager.getChat(message.chatID); - message.peerString = AppChatsManager.getChatString(message.chatID); } else { message.peerID = message.out ? message.to_id.user_id : message.from_id; message.peerData = AppUsersManager.getUser(message.peerID); - message.peerString = AppUsersManager.getUserString(message.peerID); } - + message.peerString = AppPeersManager.getPeerString(message.peerID); message.peerPhoto = AppPeersManager.getPeerPhoto(message.peerID, 'User', 'Group'); message.unreadCount = unreadCount; @@ -2194,6 +2198,10 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) }; function choosePhotoSize (photo, width, height) { + if (Config.Navigator.retina) { + width *= 2; + height *= 2; + } var bestPhotoSize = {_: 'photoSizeEmpty'}, bestDiff = 0xFFFFFF; @@ -2235,10 +2243,13 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) if (!photos[photoID]) { return; } - var photo = photos[photoID], - fullWidth = $(window).width() - 36, - fullHeight = $($window).height() - 150, - fullPhotoSize = choosePhotoSize(photo, fullWidth, fullHeight); + var photo = photos[photoID]; + var fullWidth = $(window).width() - (Config.Mobile ? 20 : 32); + var fullHeight = $($window).height() - (Config.Mobile ? 150 : 116); + if (fullWidth > 800) { + fullWidth -= 208; + } + var fullPhotoSize = choosePhotoSize(photo, fullWidth, fullHeight); if (fullPhotoSize && !fullPhotoSize.preloaded) { fullPhotoSize.preloaded = true; @@ -2297,23 +2308,22 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) } function wrapForFull (photoID) { - var photo = wrapForHistory(photoID), - fullWidth = $(window).width() - (Config.Mobile ? 20 : 36), - fullHeight = $($window).height() - 150, - fullPhotoSize = choosePhotoSize(photo, fullWidth, fullHeight), - full = { + var photo = wrapForHistory(photoID); + var fullWidth = $(window).width() - (Config.Mobile ? 20 : 32); + var fullHeight = $($window).height() - (Config.Mobile ? 150 : 116); + if (fullWidth > 800) { + fullWidth -= 208; + } + var fullPhotoSize = choosePhotoSize(photo, fullWidth, fullHeight); + var full = { placeholder: 'img/placeholders/PhotoThumbModal.gif' }; - if (fullWidth > 800) { - fullWidth -= 200; - } - full.width = fullWidth; full.height = fullHeight; if (fullPhotoSize && fullPhotoSize._ != 'photoSizeEmpty') { - var wh = calcImageInBox(fullPhotoSize.w, fullPhotoSize.h, fullWidth, fullHeight, Config.Mobile); + var wh = calcImageInBox(fullPhotoSize.w, fullPhotoSize.h, fullWidth, fullHeight, true); full.width = wh.w; full.height = wh.h; @@ -2344,6 +2354,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) var modalInstance = $modal.open({ templateUrl: templateUrl('photo_modal'), + windowTemplateUrl: !Config.Mobile && templateUrl('media_modal_layout') || undefined, controller: scope.userID ? 'UserpicModalController' : 'PhotoModalController', scope: scope, windowClass: 'photo_modal_window' @@ -2492,6 +2503,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) return $modal.open({ templateUrl: templateUrl('video_modal'), + windowTemplateUrl: !Config.Mobile && templateUrl('media_modal_layout') || undefined, controller: 'VideoModalController', scope: scope, windowClass: 'video_modal_window' @@ -2722,6 +2734,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) var modalInstance = $modal.open({ templateUrl: templateUrl('document_modal'), + windowTemplateUrl: !Config.Mobile && templateUrl('media_modal_layout') || undefined, controller: 'DocumentModalController', scope: scope, windowClass: 'document_modal_window' diff --git a/app/partials/desktop/document_modal.html b/app/partials/desktop/document_modal.html index 0a0e494f..86b2ec0d 100644 --- a/app/partials/desktop/document_modal.html +++ b/app/partials/desktop/document_modal.html @@ -1,21 +1,41 @@ -

+ -