Browse Source

Improved message date format

Added date splitters when messages were sent on different days
Closes #286
master
Igor Zhukov 11 years ago
parent
commit
8682586ca9
  1. 10
      app/css/app.css
  2. 43
      app/js/controllers.js
  3. 31
      app/js/filters.js
  4. 26
      app/js/lib/mtproto.js
  5. 59
      app/js/services.js
  6. 6
      app/partials/message.html

10
app/css/app.css

@ -1818,6 +1818,16 @@ img.im_message_document_thumb { @@ -1818,6 +1818,16 @@ img.im_message_document_thumb {
padding: 0 0 20px 10px;
}
.im_message_date_seconds {
padding: 0;
margin: 0;
position: absolute;
display: none;
}
.im_message_meta:hover .im_message_date_seconds {
display: inline;
}
@media (max-width: 900px) {
/* Status ticks */

43
app/js/controllers.js

@ -728,39 +728,6 @@ angular.module('myApp.controllers', []) @@ -728,39 +728,6 @@ angular.module('myApp.controllers', [])
}
}
function updateHistoryGroups (limit) {
var start = 0,
end = $scope.history.length,
i, curMessage, prevMessage;
if (limit > 0) {
end = limit;
} else if (limit < 0) {
start = end + limit;
}
for (i = start; i < end; i++) {
curMessage = $scope.history[i];
if (prevMessage &&
curMessage.from_id == prevMessage.from_id &&
!prevMessage.fwd_from_id == !curMessage.fwd_from_id &&
!prevMessage.action &&
!curMessage.action &&
curMessage.date < prevMessage.date + 900) {
var singleLine = curMessage.message && curMessage.message.length < 70 && curMessage.message.indexOf("\n") == -1;
if (curMessage.fwd_from_id && curMessage.fwd_from_id == prevMessage.fwd_from_id) {
curMessage.grouped = singleLine ? 4 : 3;
} else {
curMessage.grouped = !curMessage.fwd_from_id && singleLine ? 1 : 2;
}
} else if (prevMessage || !i) {
delete curMessage.grouped;
}
prevMessage = curMessage;
}
}
function messageFocusHistory () {
var i, found = false;
for (i = 0; i < $scope.history.length; i++) {
@ -803,7 +770,7 @@ angular.module('myApp.controllers', []) @@ -803,7 +770,7 @@ angular.module('myApp.controllers', [])
minID = historyResult.history.length >= backLimit
? historyResult.history[0]
: 0;
updateHistoryGroups(-backLimit);
AppMessagesManager.regroupWrappedHistory($scope.history, -backLimit);
$scope.$broadcast('ui_history_append');
} else {
minID = 0;
@ -837,7 +804,7 @@ angular.module('myApp.controllers', []) @@ -837,7 +804,7 @@ angular.module('myApp.controllers', [])
if (historyResult.history.length) {
maxID = historyResult.history[historyResult.history.length - 1];
updateHistoryGroups(historyResult.history.length + 1);
AppMessagesManager.regroupWrappedHistory($scope.history, historyResult.history.length + 1);
$scope.$broadcast('ui_history_prepend');
}
});
@ -898,7 +865,7 @@ angular.module('myApp.controllers', []) @@ -898,7 +865,7 @@ angular.module('myApp.controllers', [])
});
$scope.history.reverse();
updateHistoryGroups();
AppMessagesManager.regroupWrappedHistory($scope.history);
if (historyResult.unreadOffset) {
$scope.historyUnreadAfter = historyResult.history[historyResult.unreadOffset - 1];
@ -1074,7 +1041,7 @@ angular.module('myApp.controllers', []) @@ -1074,7 +1041,7 @@ angular.module('myApp.controllers', [])
// console.log('append', addedMessage);
// console.trace();
$scope.history.push(AppMessagesManager.wrapForHistory(addedMessage.messageID));
updateHistoryGroups(-3);
AppMessagesManager.regroupWrappedHistory($scope.history, -3);
$scope.typing = {};
$scope.$broadcast('ui_history_append_new', {my: addedMessage.my});
if (addedMessage.my) {
@ -1100,7 +1067,7 @@ angular.module('myApp.controllers', []) @@ -1100,7 +1067,7 @@ angular.module('myApp.controllers', [])
}
};
$scope.history = newHistory;
updateHistoryGroups();
AppMessagesManager.regroupWrappedHistory($scope.history);
}
});

31
app/js/filters.js

@ -74,6 +74,37 @@ angular.module('myApp.filters', []) @@ -74,6 +74,37 @@ angular.module('myApp.filters', [])
}
}])
.filter('time', ['$filter', function($filter) {
var cachedDates = {};
return function (timestamp) {
if (cachedDates[timestamp]) {
return cachedDates[timestamp];
}
return cachedDates[timestamp] = $filter('date')(timestamp * 1000, 'HH:mm');
}
}])
.filter('myDate', ['$filter', function($filter) {
var cachedDates = {};
return function (timestamp) {
if (cachedDates[timestamp]) {
return cachedDates[timestamp];
}
return cachedDates[timestamp] = $filter('date')(timestamp * 1000, 'fullDate');
}
}])
.filter('seconds', function($filter) {
return function (timestamp) {
var sec = timestamp % 60;
return sec < 10 ? '0' + sec : sec;
}
})
.filter('duration', [function() {
return function (duration) {
var secs = duration % 60,

26
app/js/lib/mtproto.js

@ -118,7 +118,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) @@ -118,7 +118,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils'])
return new SecureRandom();
})
.factory('MtpDateManager', function (Storage) {
.factory('MtpTimeManager', function (Storage) {
var lastMessageID = [0, 0],
timeOffset = 0;
@ -171,7 +171,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) @@ -171,7 +171,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils'])
};
})
.factory('MtpAuthorizer', function (MtpDcConfigurator, MtpRsaKeysManager, MtpSecureRandom, MtpDateManager, CryptoWorker, $http, $q, $timeout) {
.factory('MtpAuthorizer', function (MtpDcConfigurator, MtpRsaKeysManager, MtpSecureRandom, MtpTimeManager, CryptoWorker, $http, $q, $timeout) {
function mtpSendPlainRequest (dcID, requestBuffer) {
var requestLength = requestBuffer.byteLength,
@ -179,7 +179,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) @@ -179,7 +179,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils'])
var header = new TLSerialization();
header.storeLongP(0, 0, 'auth_key_id'); // Auth key
header.storeLong(MtpDateManager.generateID(), 'msg_id'); // Msg_id
header.storeLong(MtpTimeManager.generateID(), 'msg_id'); // Msg_id
header.storeInt(requestLength, 'request_length');
var headerBuffer = header.getBuffer(),
@ -391,7 +391,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) @@ -391,7 +391,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils'])
throw new Error('server_DH_inner_data SHA1-hash mismatch');
}
MtpDateManager.applyServerTime(auth.serverTime, auth.localTime);
MtpTimeManager.applyServerTime(auth.serverTime, auth.localTime);
};
function mtpSendSetClientDhParams(auth) {
@ -539,7 +539,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) @@ -539,7 +539,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils'])
})
.factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpDateManager, MtpSecureRandom, Storage, CryptoWorker, $http, $q, $timeout, $interval, $rootScope) {
.factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpTimeManager, MtpSecureRandom, Storage, CryptoWorker, $http, $q, $timeout, $interval, $rootScope) {
var updatesProcessor,
iii = 0,
@ -642,7 +642,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) @@ -642,7 +642,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils'])
sentMessage.inner = newInner;
}
sentMessage.msg_id = MtpDateManager.generateID();
sentMessage.msg_id = MtpTimeManager.generateID();
sentMessage.seq_no = this.generateSeqNo(
sentMessage.notContentRelated ||
sentMessage.container
@ -669,7 +669,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) @@ -669,7 +669,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils'])
serializer.storeMethod(method, params);
var messageID = MtpDateManager.generateID(),
var messageID = MtpTimeManager.generateID(),
seqNo = this.generateSeqNo(),
message = {
msg_id: messageID,
@ -690,7 +690,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) @@ -690,7 +690,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils'])
var serializer = new TLSerialization({mtproto: true});
serializer.storeObject(object, 'Object');
var messageID = MtpDateManager.generateID(),
var messageID = MtpTimeManager.generateID(),
seqNo = this.generateSeqNo(options.notContentRelated),
message = {
msg_id: messageID,
@ -725,7 +725,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) @@ -725,7 +725,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils'])
options.resultType = serializer.storeMethod(method, params);
var messageID = MtpDateManager.generateID(),
var messageID = MtpTimeManager.generateID(),
seqNo = this.generateSeqNo(),
message = {
msg_id: messageID,
@ -849,7 +849,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) @@ -849,7 +849,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils'])
serializer.storeMethod('ping', {ping_id: pingID});
var pingMessage = {
msg_id: MtpDateManager.generateID(),
msg_id: MtpTimeManager.generateID(),
seq_no: this.generateSeqNo(true),
body: serializer.getBytes()
};
@ -964,7 +964,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) @@ -964,7 +964,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils'])
var serializer = new TLSerialization({mtproto: true});
serializer.storeMethod('http_wait', {max_delay: 0, wait_after: 0, max_wait: 1000});
messages.push({
msg_id: MtpDateManager.generateID(),
msg_id: MtpTimeManager.generateID(),
seq_no: this.generateSeqNo(),
body: serializer.getBytes()
});
@ -995,7 +995,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) @@ -995,7 +995,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils'])
}
var containerSentMessage = {
msg_id: MtpDateManager.generateID(),
msg_id: MtpTimeManager.generateID(),
seq_no: this.generateSeqNo(true),
container: true,
inner: innerMessages
@ -1345,7 +1345,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils']) @@ -1345,7 +1345,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils'])
}
if (message.error_code == 16 || message.error_code == 17) {
if (MtpDateManager.applyServerTime(
if (MtpTimeManager.applyServerTime(
bigStringInt(messageID).shiftRight(32).toString(10)
)) {
this.updateSession();

59
app/js/services.js

@ -673,7 +673,7 @@ angular.module('myApp.services', []) @@ -673,7 +673,7 @@ angular.module('myApp.services', [])
}
})
.service('AppMessagesManager', function ($q, $rootScope, $location, $filter, ApiUpdatesManager, AppUsersManager, AppChatsManager, AppPeersManager, AppPhotosManager, AppVideoManager, AppDocsManager, AppAudioManager, MtpApiManager, MtpApiFileManager, RichTextProcessor, NotificationsManager, SearchIndexManager) {
.service('AppMessagesManager', function ($q, $rootScope, $location, $filter, ApiUpdatesManager, AppUsersManager, AppChatsManager, AppPeersManager, AppPhotosManager, AppVideoManager, AppDocsManager, AppAudioManager, MtpApiManager, MtpApiFileManager, MtpTimeManager, RichTextProcessor, NotificationsManager, SearchIndexManager) {
var messagesStorage = {};
var messagesForHistory = {};
@ -692,6 +692,17 @@ angular.module('myApp.services', []) @@ -692,6 +692,17 @@ angular.module('myApp.services', [])
var lastSearchFilter = {},
lastSearchResults = [];
var serverTimeOffset = MtpTimeManager.getTimeOffset(),
timestampNow = tsNow(true),
midnightNoOffset = timestampNow - (timestampNow % 86400),
midnightOffseted = new Date(),
midnightOffset;
midnightOffseted.setHours(0);
midnightOffseted.setMinutes(0);
midnightOffseted.setSeconds(0);
midnightOffset = midnightNoOffset - (Math.floor(+midnightOffseted / 1000));
NotificationsManager.start();
function getDialogs (query, maxID, limit) {
@ -1773,6 +1784,46 @@ angular.module('myApp.services', []) @@ -1773,6 +1784,46 @@ angular.module('myApp.services', [])
return messagesForHistory[msgID] = message;
}
function regroupWrappedHistory (history, limit) {
var start = 0,
end = history.length,
i, curDay, prevDay, curMessage, prevMessage;
if (limit > 0) {
end = limit;
} else if (limit < 0) {
start = end + limit;
}
for (i = start; i < end; i++) {
curMessage = history[i];
curDay = Math.floor((curMessage.date - midnightOffset) / 86400);
if (curDay !== prevDay) {
curMessage.needDate = true;
} else if (prevMessage) {
delete curMessage.needDate;
}
if (prevMessage &&
curMessage.from_id == prevMessage.from_id &&
!prevMessage.fwd_from_id == !curMessage.fwd_from_id &&
!prevMessage.action &&
!curMessage.action &&
curMessage.date < prevMessage.date + 900) {
var singleLine = curMessage.message && curMessage.message.length < 70 && curMessage.message.indexOf("\n") == -1;
if (curMessage.fwd_from_id && curMessage.fwd_from_id == prevMessage.fwd_from_id) {
curMessage.grouped = singleLine ? 4 : 3;
} else {
curMessage.grouped = !curMessage.fwd_from_id && singleLine ? 1 : 2;
}
} else if (prevMessage || !i) {
delete curMessage.grouped;
}
prevMessage = curMessage;
prevDay = curDay;
}
}
function getDialogByPeerID (peerID) {
for (var i = 0; i < dialogsStorage.dialogs.length; i++) {
if (dialogsStorage.dialogs[i].peerID == peerID) {
@ -1886,6 +1937,9 @@ angular.module('myApp.services', []) @@ -1886,6 +1937,9 @@ angular.module('myApp.services', [])
historyStorage = historiesStorage[peerID] = {count: null, history: [message.id], pending: []};
}
// Fix time offset
message.date -= serverTimeOffset;
saveMessages([message]);
if (historyStorage.count !== null) {
@ -2054,7 +2108,8 @@ angular.module('myApp.services', []) @@ -2054,7 +2108,8 @@ angular.module('myApp.services', [])
forwardMessages: forwardMessages,
getMessagePeer: getMessagePeer,
wrapForDialog: wrapForDialog,
wrapForHistory: wrapForHistory
wrapForHistory: wrapForHistory,
regroupWrappedHistory: regroupWrappedHistory
}
})

6
app/partials/message.html

@ -2,6 +2,10 @@ @@ -2,6 +2,10 @@
Unread messages
</div>
<div class="im_message_date_split im_service_message_wrap" bo-if="historyMessage.needDate" ng-show="historyMessage.needDate">
<div class="im_service_message" ng-bind="historyMessage.date | myDate"></div>
</div>
<div class="im_message_outer_wrap" ng-class="[ selectedMsgs[historyMessage.id] &amp;&amp; 'im_message_selected', historyMessage.grouped &amp;&amp; ('im_message_grouped' + historyMessage.grouped) , historyFocus == historyMessage.id &amp;&amp; 'im_message_focus']" ng-click="toggleMessage(historyMessage.id, $event)">
@ -77,7 +81,7 @@ @@ -77,7 +81,7 @@
</a>
<div class="im_message_meta pull-right text-right">
<i class="icon-message-status-tick"></i>
<span class="im_message_date" bo-bind="historyMessage.date | dateOrTime"></span>
<span class="im_message_date" ng-bind="historyMessage.date | time"></span><span class="im_message_date im_message_date_seconds">:<span ng-bind="historyMessage.date | seconds"></span></span>
</div>
<div class="im_message_body">

Loading…
Cancel
Save