diff --git a/app/img/icons/Checks1.png b/app/img/icons/Checks1.png deleted file mode 100755 index 35b72dec..00000000 Binary files a/app/img/icons/Checks1.png and /dev/null differ diff --git a/app/img/icons/Checks1_2x.png b/app/img/icons/Checks1_2x.png deleted file mode 100644 index 86c6f6a8..00000000 Binary files a/app/img/icons/Checks1_2x.png and /dev/null differ diff --git a/app/img/icons/Checks2.png b/app/img/icons/Checks2.png deleted file mode 100755 index 5ee5c1cb..00000000 Binary files a/app/img/icons/Checks2.png and /dev/null differ diff --git a/app/img/icons/Checks2_2x.png b/app/img/icons/Checks2_2x.png deleted file mode 100644 index 233b8282..00000000 Binary files a/app/img/icons/Checks2_2x.png and /dev/null differ diff --git a/app/img/icons/General.png b/app/img/icons/General.png index 16d772ae..44c5d241 100644 Binary files a/app/img/icons/General.png and b/app/img/icons/General.png differ diff --git a/app/img/icons/General_2x.png b/app/img/icons/General_2x.png index 72b8b7a3..494c9575 100644 Binary files a/app/img/icons/General_2x.png and b/app/img/icons/General_2x.png differ diff --git a/app/img/icons/Major.png b/app/img/icons/Major.png new file mode 100644 index 00000000..031b82c1 Binary files /dev/null and b/app/img/icons/Major.png differ diff --git a/app/img/icons/Major_2x.png b/app/img/icons/Major_2x.png new file mode 100644 index 00000000..e47c379c Binary files /dev/null and b/app/img/icons/Major_2x.png differ diff --git a/app/js/directives.js b/app/js/directives.js index 4e019468..19bf9232 100755 --- a/app/js/directives.js +++ b/app/js/directives.js @@ -502,6 +502,33 @@ angular.module('myApp.directives', ['myApp.filters']) } }) + .directive('myMessageViews', function($filter, AppMessagesManager) { + + var formatNumberFilter = $filter('formatShortNumber'); + + return { + link: link + }; + + function updateHtml (views, element) { + element.html(formatNumberFilter(views)); + } + + function link ($scope, element, attrs) { + var mid = $scope.$eval(attrs.myMessageViews); + // console.log(element[0], mid); + var views = AppMessagesManager.getMessage(mid).views || 0; + + updateHtml(views, element); + + $scope.$on('message_views', function (e, viewData) { + if (viewData.mid == mid) { + updateHtml(viewData.views, element); + } + }) + } + }) + .directive('myReplyMarkup', function() { return { diff --git a/app/js/filters.js b/app/js/filters.js index 4ac33311..be7dbbc8 100644 --- a/app/js/filters.js +++ b/app/js/filters.js @@ -199,6 +199,23 @@ angular.module('myApp.filters', ['myApp.i18n']) } }) + .filter('formatShortNumber', [function () { + return function (num) { + if (!num) { + return '0'; + } + else if (num < 1000) { + return num.toString(); + } + else if (num < 900000) { + var mult = num > 10000 ? 1 : 10; + return (Math.round(num / 1000 * mult) / mult) + 'K'; + } + var mult = num > 10000000 ? 1 : 10; + return (Math.round(num / 1000000 * mult) / mult) + 'M'; + } + }]) + .filter('nl2br', [function () { return function (text) { return text.replace(/\n/g, '
'); diff --git a/app/js/messages_manager.js b/app/js/messages_manager.js index 5d1c2954..b7210808 100644 --- a/app/js/messages_manager.js +++ b/app/js/messages_manager.js @@ -31,6 +31,10 @@ angular.module('myApp.services') var needSingleMessages = [], fetchSingleMessagesTimeout = false; + var incrementedMessageViews = {}, + needIncrementMessageViews = [], + incrementMessageViewsTimeout = false; + var serverTimeOffset = 0, timestampNow = tsNow(true), midnightNoOffset = timestampNow - (timestampNow % 86400), @@ -421,6 +425,28 @@ angular.module('myApp.services') return fullMsgID % fullMsgIDModulus; } + function splitMessageIDsByChannels (mids) { + var msgIDsByChannels = {}; + var midsByChannels = {}; + var i, mid, msgChannel, channelID; + for (i = 0; i < mids.length; i++) { + mid = mids[i]; + msgChannel = getMessageIDInfo(mid); + channelID = msgChannel[1]; + if (msgIDsByChannels[channelID] === undefined) { + msgIDsByChannels[channelID] = []; + midsByChannels[channelID] = []; + } + msgIDsByChannels[channelID].push(msgChannel[0]); + midsByChannels[channelID].push(mid); + } + + return { + msgIDs: msgIDsByChannels, + mids: midsByChannels + }; + } + function fillHistoryStorage (inputPeer, maxID, fullLimit, historyStorage) { // console.log('fill history storage', inputPeer, maxID, fullLimit, angular.copy(historyStorage)); return requestHistory (inputPeer, maxID, fullLimit).then(function (historyResult) { @@ -1094,6 +1120,7 @@ angular.module('myApp.services') random_id: randomIDS, reply_to_msg_id: replyToMsgID, entities: entities, + views: asChannel && 1, pending: true }; @@ -1252,6 +1279,7 @@ angular.module('myApp.services') media: media, random_id: randomIDS, reply_to_msg_id: replyToMsgID, + views: asChannel && 1, pending: true }; @@ -1435,6 +1463,7 @@ angular.module('myApp.services') media: media, random_id: randomIDS, reply_to_msg_id: replyToMsgID, + views: asChannel && 1, pending: true }; @@ -1503,6 +1532,13 @@ angular.module('myApp.services') var len = mids.length; var i, mid, msgID; var fromChannel = getMessageIDInfo(mids[0])[1]; + var isChannel = AppPeersManager.isChannel(peerID); + var asChannel = isChannel ? true : false; + + if (asChannel) { + flags |= 16; + } + for (i = 0; i < len; i++) { msgIDs.push(getMessageLocalID(mids[i])); randomIDs.push([nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)]); @@ -1888,21 +1924,8 @@ angular.module('myApp.services') var mids = needSingleMessages.slice(); needSingleMessages = []; - var msgIDsByChannels = {}; - var midsByChannels = {}; - var i, mid, msgChannel, channelID; - for (i = 0; i < mids.length; i++) { - mid = mids[i]; - msgChannel = getMessageIDInfo(mid); - channelID = msgChannel[1]; - if (msgIDsByChannels[channelID] === undefined) { - msgIDsByChannels[channelID] = []; - midsByChannels[channelID] = []; - } - msgIDsByChannels[channelID].push(msgChannel[0]); - midsByChannels[channelID].push(mid); - } - angular.forEach(msgIDsByChannels, function (msgIDs, channelID) { + var splitted = splitMessageIDsByChannels(mids); + angular.forEach(splitted.msgIDs, function (msgIDs, channelID) { var promise; if (channelID > 0) { promise = MtpApiManager.invokeApi('channels.getMessages', { @@ -1920,7 +1943,48 @@ angular.module('myApp.services') AppChatsManager.saveApiChats(getMessagesResult.chats); saveMessages(getMessagesResult.messages); - $rootScope.$broadcast('messages_downloaded', midsByChannels[channelID]); + $rootScope.$broadcast('messages_downloaded', splitted.mids[channelID]); + }) + }) + } + + function incrementMessageViews () { + if (incrementMessageViewsTimeout !== false) { + clearTimeout(incrementMessageViewsTimeout); + incrementMessageViewsTimeout = false; + } + if (!needIncrementMessageViews.length) { + return; + } + var mids = needIncrementMessageViews.slice(); + needIncrementMessageViews = []; + + var splitted = splitMessageIDsByChannels(mids); + angular.forEach(splitted.msgIDs, function (msgIDs, channelID) { + console.log('increment', msgIDs, channelID); + MtpApiManager.invokeApi('messages.getMessagesViews', { + peer: AppPeersManager.getInputPeerByID(-channelID), + id: msgIDs, + increment: true + }).then(function (views) { + if (channelID) { + var mids = splitted.mids[channelID]; + var updates = []; + for (var i = 0; i < mids.length; i++) { + updates.push({ + _: 'updateChannelMessageViews', + channel_id: channelID, + id: mids[i], + views: views[i] + }); + } + ApiUpdatesManager.processUpdateMessage({ + _: 'updates', + updates: updates, + chats: [], + users: [] + }); + } }) }) } @@ -1970,7 +2034,17 @@ angular.module('myApp.services') curMessage._ = 'message'; } + if (curMessage.views && + !incrementedMessageViews[curMessage.mid]) { + incrementedMessageViews[curMessage.mid] = true; + needIncrementMessageViews.push(curMessage.mid); + if (incrementMessageViewsTimeout === false) { + incrementMessageViewsTimeout = setTimeout(incrementMessageViews, 10000); + } + } + if (prevMessage && + // !curMessage.views && curMessage.fromID == prevMessage.fromID && !prevMessage.fwdFromID == !curMessage.fwdFromID && !prevMessage.action && @@ -2597,6 +2671,19 @@ angular.module('myApp.services') $rootScope.$broadcast('history_reload', peerID); }); break; + + case 'updateChannelMessageViews': + var views = update.views; + var mid = getFullMessageID(update.id, update.channel_id); + var message = getMessage(mid); + if (message && message.views && message.views < views) { + message.views = views; + $rootScope.$broadcast('message_views', { + mid: mid, + views: views + }); + } + break; } }); diff --git a/app/js/services.js b/app/js/services.js index 8ce6dde0..0baf8966 100755 --- a/app/js/services.js +++ b/app/js/services.js @@ -786,6 +786,9 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) } function getInputPeerByID (peerID) { + if (!peerID) { + return {_: 'inputPeerEmpty'}; + } if (peerID < 0) { var chatID = -peerID; if (!AppChatsManager.isChannel(chatID)) { diff --git a/app/less/app.less b/app/less/app.less index e523b51c..6d3a1bc1 100644 --- a/app/less/app.less +++ b/app/less/app.less @@ -865,7 +865,7 @@ a.tg_radio_on:hover i.icon-radio { vertical-align: top; margin-right: 18px; - .image-2x('../img/icons/General.png', 40px, 848px); + .image-2x('../img/icons/General.png', 40px, 948px); background-position: -5px -10px; } .icon-tg-title { @@ -906,7 +906,7 @@ a.tg_radio_on:hover i.icon-radio { margin-left: 12px; margin-top: -1px; - .image-2x('../img/icons/General.png', 40px, 848px); + .image-2x('../img/icons/General.png', 40px, 948px); background-position: -18px -50px; } @@ -1599,7 +1599,7 @@ div.im_message_video_thumb { height: 18px; margin: 12px 15px; - .image-2x('../img/icons/General.png', 40px, 848px); + .image-2x('../img/icons/General.png', 40px, 948px); background-position: -14px -509px; .im_message_file_button_dl_doc & { @@ -1620,7 +1620,7 @@ div.im_message_video_thumb { height: 16px; margin: 13px 16px; - .image-2x('../img/icons/General.png', 40px, 848px); + .image-2x('../img/icons/General.png', 40px, 948px); background-position: -13px -611px; } @@ -1636,7 +1636,7 @@ div.im_message_video_thumb { } .im_message_selected .icon-document, -.im_history_selectable .im_message_outer_wrap:hover .icon-document { +.im_history_select_active .im_message_outer_wrap:hover .icon-document { background-color: #dae6f0; background-position: -2px -542px; } @@ -1944,6 +1944,62 @@ div.im_message_body { .user-select(text); } +.im_message_error_btn { + display: none; + + .im_message_error & { + display: inline; + } + + .icon-message-status { + background: #da564d; + opacity: 0.85; + pointer-events: auto; + + &:hover { + opacity: 1; + } + } +} + + +.im_message_views_wrap { + position: relative; +} +.im_message_views { + display: inline-block; + position: absolute; + white-space: nowrap; + line-height: normal; +} +.im_message_views_inline { + display: inline-block; + white-space: nowrap; + // line-height: normal; + font-size: 0.85em; + margin-left: 5px; +} +.icon-message-views { + display: inline-block; + width: 16px; + height: 11px; + .image-2x('../img/icons/General.png', 40px, 948px); + background-position: -12px -850px; + vertical-align: text-bottom; + margin-right: 0.3rem; + + .message_focus &, + .im_message_selected &, + .im_history_select_active .im_message_outer_wrap:hover & { + background-position: -12px -871px; + } +} +.im_message_views_cnt { + color: #adadad; + font-weight: bold; + vertical-align: top; +} + .im_message_reply_wrap { display: block; color: inherit; @@ -2319,7 +2375,7 @@ img.img_fullsize { vertical-align: top; opacity: 0.8; - .image-2x('../img/icons/General.png', 40px, 848px); + .image-2x('../img/icons/General.png', 40px, 948px); background-position: -9px -335px; } @@ -2865,7 +2921,7 @@ _:-ms-lang(x), .composer_rich_textarea:empty:focus:before { vertical-align: top; opacity: 0.8; - .image-2x('../img/icons/General.png', 40px, 848px); + .image-2x('../img/icons/General.png', 40px, 948px); background-position: -10px -790px; .composer_command_btn.active & { @@ -2895,7 +2951,7 @@ _:-ms-lang(x), .composer_rich_textarea:empty:focus:before { vertical-align: top; opacity: 0.8; - .image-2x('../img/icons/General.png', 40px, 848px); + .image-2x('../img/icons/General.png', 40px, 948px); background-position: -10px -730px; .composer_keyboard_btn.active & { @@ -3351,7 +3407,8 @@ a.contacts_modal_contact:hover .md_modal_list_peer_description, .im_message_document_size, .audio_player_duration, .audio_player_size, - .im_message_fwd_date { + .im_message_fwd_date, + .im_message_views_cnt { color: #899daf; } diff --git a/app/less/desktop.less b/app/less/desktop.less index 8e3a39f6..ca014f3f 100644 --- a/app/less/desktop.less +++ b/app/less/desktop.less @@ -205,7 +205,7 @@ display: inline-block; vertical-align: top; margin-top: 3px; - .image-2x('../img/icons/General.png', 40px, 848px); + .image-2x('../img/icons/General.png', 40px, 948px); background-position: -10px -111px; } @@ -217,7 +217,7 @@ margin-top: 2px; display: inline-block; vertical-align: top; - .image-2x('../img/icons/General.png', 40px, 848px); + .image-2x('../img/icons/General.png', 40px, 948px); background-position: -11px -135px; } @@ -228,7 +228,7 @@ margin-top: 1px; display: inline-block; vertical-align: top; - .image-2x('../img/icons/General.png', 40px, 848px); + .image-2x('../img/icons/General.png', 40px, 948px); background-position: -10px -163px; } @@ -239,7 +239,7 @@ margin-top: 1px; display: inline-block; vertical-align: top; - .image-2x('../img/icons/General.png', 40px, 848px); + .image-2x('../img/icons/General.png', 40px, 948px); background-position: -10px -637px; } @@ -250,7 +250,7 @@ display: inline-block; vertical-align: top; - .image-2x('../img/icons/General.png', 40px, 848px); + .image-2x('../img/icons/General.png', 40px, 948px); background-position: -10px -193px; } } @@ -378,7 +378,7 @@ margin-right: 12px; vertical-align: top; - .image-2x('../img/icons/General.png', 40px, 848px); + .image-2x('../img/icons/General.png', 40px, 948px); background-position: 0 0; } @@ -898,11 +898,13 @@ a.footer_link.active:active { .im_message_selected .im_message_audio_duration, .im_message_selected .im_message_audio_size, .im_message_selected .im_message_fwd_date, +.im_message_selected .im_message_views_cnt, .im_history_select_active .im_message_outer_wrap:hover .im_message_date, .im_history_select_active .im_message_outer_wrap:hover .im_message_document_size, .im_history_select_active .im_message_outer_wrap:hover .im_message_audio_duration, .im_history_select_active .im_message_outer_wrap:hover .im_message_audio_size, -.im_history_select_active .im_message_outer_wrap:hover .im_message_fwd_date { +.im_history_select_active .im_message_outer_wrap:hover .im_message_fwd_date, +.im_history_select_active .im_message_outer_wrap:hover .im_message_views_cnt { color: #899daf; } @@ -991,24 +993,6 @@ a.footer_link.active:active { } } -.im_message_error_btn { - display: none; - - .im_message_error & { - display: inline; - } - - .icon-message-status { - background: #da564d; - opacity: 0.85; - pointer-events: auto; - - &:hover { - opacity: 1; - } - } -} - /* Dialogs modal */ .peer_select { &_window { @@ -1179,7 +1163,7 @@ a.im_panel_peer_photo .peer_initials { opacity: 0.8; margin: 0; - .image-2x('../img/icons/General.png', 40px, 848px); + .image-2x('../img/icons/General.png', 40px, 948px); background-position: -11px -455px; } @@ -1228,7 +1212,7 @@ a.im_panel_peer_photo .peer_initials { vertical-align: top; opacity: 0.8; - .image-2x('../img/icons/General.png', 40px, 848px); + .image-2x('../img/icons/General.png', 40px, 948px); background-position: -10px -399px; } @@ -1744,6 +1728,37 @@ a.im_panel_peer_photo .peer_initials { margin: 8px 10px 8px 16px; } +.im_message_views_wrap { + width: 0; + + .im_grouped &, + .im_grouped_short &, + .im_grouped_fwd &, + .im_grouped_fwd_short & { + display: none; + .im_message_selected& { + display: block; + } + } + .im_message_selected.im_grouped &, + .im_message_selected.im_grouped_fwd & { + width: auto; + } +} +.im_message_views { + right: 0; + font-size: 0.85em; + top: 3px; + + .im_grouped &, + .im_grouped_fwd & { + top: 19px; + } + .im_message_fwd & { + top: 3px; + } +} + .im_grouped_short { .im_content_message_wrap { margin: 6px 10px 6px 16px; diff --git a/app/less/mobile.less b/app/less/mobile.less index 0544637f..7dba6982 100644 --- a/app/less/mobile.less +++ b/app/less/mobile.less @@ -795,7 +795,7 @@ img.im_message_video_thumb, margin-left: -60px; width: 60px; padding: 0 0 0 8px; - overflow: hidden; + // overflow: hidden; .im_message_out & { width: 80px; @@ -806,6 +806,15 @@ img.im_message_video_thumb, } } +.im_message_views { + top: -12px; + font-size: 10px; + + .im_message_out & { + right: 0; + } +} + .im_message_date { font-size: 10px; padding: 0; diff --git a/app/partials/desktop/message.html b/app/partials/desktop/message.html index c42e25a1..fac1b5d3 100644 --- a/app/partials/desktop/message.html +++ b/app/partials/desktop/message.html @@ -34,6 +34,11 @@
+
+
+ +
+
@@ -47,6 +52,9 @@
+ + +
diff --git a/app/partials/mobile/message.html b/app/partials/mobile/message.html index 60075397..6343fe4b 100644 --- a/app/partials/mobile/message.html +++ b/app/partials/mobile/message.html @@ -28,6 +28,11 @@
+
+
+ +
+