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 @@