Supported message views

This commit is contained in:
Igor Zhukov 2015-10-22 23:02:12 +02:00
parent 89151b50ac
commit d0b3f8be81
17 changed files with 281 additions and 53 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 535 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 469 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 713 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 16 KiB

BIN
app/img/icons/Major.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
app/img/icons/Major_2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

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

View File

@ -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, '<br/>');

View File

@ -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;
}
});

View File

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

View File

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

View File

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

View File

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

View File

@ -34,6 +34,11 @@
<a class="im_message_from_photo pull-left" my-peer-photolink="::historyMessage.fromID" img-class="im_message_from_photo"></a>
<div class="im_message_meta pull-right text-right">
<div class="im_message_views_wrap" ng-if="::!historyMessage.fwdFromID && historyMessage.views > 0">
<div class="im_message_views">
<i class="icon-message-views"></i><span class="im_message_views_cnt" my-message-views="historyMessage.mid"></span>
</div>
</div>
<span class="im_message_date" ng-bind="::historyMessage.date | time"></span>
</div>
@ -47,6 +52,9 @@
<a class="im_message_fwd_photo pull-left" my-peer-photolink="::historyMessage.fwdFromID" img-class="im_message_fwd_photo"></a>
<div class="im_message_fwd_author_wrap">
<a class="im_message_fwd_author" my-peer-link="historyMessage.fwdFromID"></a><span class="im_message_fwd_date" ng-bind="::historyMessage.fwd_date | dateOrTime"></span>
<span class="im_message_views_inline" ng-if="::historyMessage.views > 0">
<i class="icon-message-views"></i><span class="im_message_views_cnt" my-message-views="historyMessage.mid"></span>
</span>
</div>
</div>

View File

@ -28,6 +28,11 @@
<a class="im_message_from_photo pull-left" my-peer-photolink="::historyMessage.fromID" img-class="im_message_from_photo"></a>
<div class="im_message_meta">
<div class="im_message_views_wrap" ng-if="::historyMessage.views > 0">
<div class="im_message_views">
<i class="icon-message-views"></i><span class="im_message_views_cnt" my-message-views="historyMessage.mid"></span>
</div>
</div>
<a class="im_message_error_btn" ng-if="::historyMessage.pending || historyMessage.error || false" ng-click="historyMessage.send()">
<i class="icon-message-status" tooltip="Try again"></i>
</a>