Browse Source

merged with master

gh-pages
Igor Zhukov 11 years ago
parent
commit
bf89d90416
  1. 40
      css/app.css
  2. BIN
      img/icons/IconsetW.png
  3. BIN
      img/icons/IconsetW_1x.png
  4. 17
      js/controllers.js
  5. 37
      js/directives.js
  6. 140
      js/services.js
  7. 6
      partials/message.html
  8. 10
      vendor/jquery.emojiarea/jquery.emojiarea.js

40
css/app.css

@ -256,7 +256,7 @@ input[type="number"]::-webkit-inner-spin-button {
vertical-align: text-top;
background: url(../img/icons/IconsetW.png?1) -15px -419px no-repeat;
background-size: 42px 560px;
background-size: 42px 620px;
opacity: 0.6;
}
.is_1x .icon-back {
@ -511,7 +511,7 @@ input[type="number"]::-webkit-inner-spin-button {
font-size: 12px;
line-height: normal;
background: #F2F2F2 url(../img/icons/IconsetW.png?1) -6px -205px no-repeat;
background-size: 42px 560px;
background-size: 42px 620px;
border: 1px solid #F2F2F2;
border-radius: 3px;
padding: 6px 20px 6px 30px;
@ -535,7 +535,7 @@ input[type="number"]::-webkit-inner-spin-button {
height: 13px;
vertical-align: text-top;
background: url(../img/icons/IconsetW.png?1) -15px -192px no-repeat;
background-size: 42px 560px;
background-size: 42px 620px;
opacity: 0.6;
}
.is_1x .im_dialogs_search_clear {
@ -788,7 +788,7 @@ a.im_dialog:hover .im_dialog_date {
margin-left: 6px;
background: url(../img/icons/IconsetW.png?1) -17px -444px no-repeat;
background-size: 42px 560px;
background-size: 42px 620px;
}
.is_1x .icon-caret {
background-image: url(../img/icons/IconsetW_1x.png?2);
@ -896,6 +896,13 @@ a.im_dialog:hover .im_dialog_date {
opacity: 0;
}*/
.im_message_unread_split {
background: #E9EBED;
text-align: center;
padding: 4px 10px;
margin: 10px 0;
}
.im_message_author {
@ -987,7 +994,7 @@ div.im_message_video_thumb {
height: 19px;
background: url(../img/icons/IconsetW.png?1) -14px -389px no-repeat;
background-size: 42px 560px;
background-size: 42px 620px;
}
.is_1x .icon-geo-point {
background-image: url(../img/icons/IconsetW_1x.png?2);
@ -1015,7 +1022,7 @@ div.im_message_video_thumb {
vertical-align: text-top;
background: #F2F2F2 url(../img/icons/IconsetW.png?1) -2px -229px no-repeat;
background-size: 42px 560px;
background-size: 42px 620px;
border-radius: 3px;
margin-right: 10px;
}
@ -1032,6 +1039,7 @@ div.im_message_video_thumb {
.im_history_selectable .im_message_outer_wrap:hover .icon-photo,
.im_history_selectable .im_message_outer_wrap:hover .icon-video {
background-color: #dae6f0;
background-position: -2px -542px;
}
.im_message_document_info {
@ -1076,7 +1084,7 @@ div.im_message_video_thumb {
vertical-align: text-top;
background: #F2F2F2 url(../img/icons/IconsetW.png?1) -2px -277px no-repeat;
background-size: 42px 560px;
background-size: 42px 620px;
border-radius: 3px;
margin-right: 10px;
}
@ -1335,7 +1343,7 @@ textarea.im_message_field {
height: 23px;
vertical-align: text-top;
background: url(../img/icons/IconsetW.png?1) -12px -68px no-repeat;
background-size: 42px 560px;
background-size: 42px 620px;
opacity: 0.8;
}
.is_1x .icon-paperclip {
@ -1363,7 +1371,7 @@ textarea.im_message_field {
height: 23px;
vertical-align: text-top;
background: url(../img/icons/IconsetW.png?1) -10px -4px no-repeat;
background-size: 42px 560px;
background-size: 42px 620px;
opacity: 0.8;
}
.is_1x .icon-emoji {
@ -1413,7 +1421,7 @@ textarea.im_message_field {
height: 21px;
vertical-align: text-top;
background: url(../img/icons/IconsetW.png?1) -9px -132px no-repeat;
background-size: 42px 560px;
background-size: 42px 620px;
opacity: 0.8;
}
.is_1x .icon-camera {
@ -1833,7 +1841,7 @@ img.img_fullsize {
.emoji-menu-tail {
display: none;
background: url(../img/icons/IconsetW.png?1) -14px -268px no-repeat;
background-size: 42px 560px;
background-size: 42px 620px;
width: 14px;
height: 7px;
margin: 0 83px;
@ -1984,7 +1992,7 @@ img.img_fullsize {
font-size: 12px;
line-height: normal;
background: #F2F2F2 url(../img/icons/IconsetW.png?1) -6px -205px no-repeat;
background-size: 42px 560px;
background-size: 42px 620px;
border: 1px solid #F2F2F2;
border-radius: 3px;
padding: 6px 20px 6px 30px;
@ -2008,7 +2016,7 @@ img.img_fullsize {
height: 13px;
vertical-align: text-top;
background: url(../img/icons/IconsetW.png?1) -15px -192px no-repeat;
background-size: 42px 560px;
background-size: 42px 620px;
opacity: 0.6;
}
.is_1x .contacts_modal_search_clear {
@ -2085,7 +2093,7 @@ a.contacts_modal_contact:hover .contacts_modal_contact_status {
width: 17px;
height: 15px;
background: url(../img/icons/IconsetW.png?1) -13px -366px no-repeat;
background-size: 42px 560px;
background-size: 42px 620px;
opacity: 0.5;
}
.is_1x .icon-contact-tick {
@ -2183,7 +2191,7 @@ a.contacts_modal_contact:hover .contacts_modal_contact_status {
height: 15px;
background: url(../img/icons/IconsetW.png?1) -15px -319px no-repeat;
background-size: 42px 560px;
background-size: 42px 620px;
}
.is_1x .icon-delete {
background-image: url(../img/icons/IconsetW_1x.png?2);
@ -2230,7 +2238,7 @@ a.contacts_modal_contact:hover .contacts_modal_contact_status {
height: 26px;
margin: 13px 0 0 40px;
background: url(../img/icons/IconsetW.png?1) -9px -516px no-repeat;
background-size: 42px 560px;
background-size: 42px 620px;
}
.is_1x .icon-select-tick {
background-image: url(../img/icons/IconsetW_1x.png?2);

BIN
img/icons/IconsetW.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

BIN
img/icons/IconsetW_1x.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

17
js/controllers.js

@ -447,12 +447,12 @@ angular.module('myApp.controllers', [])
inputMediaFilter = $scope.mediaType && {_: inputMediaFilters[$scope.mediaType]},
getMessagesPromise = inputMediaFilter
? AppMessagesManager.getSearch($scope.curDialog.inputPeer, '', inputMediaFilter, maxID, startLimit)
: AppMessagesManager.getHistory($scope.curDialog.inputPeer, maxID, startLimit);
: AppMessagesManager.getHistory($scope.curDialog.inputPeer, maxID);
getMessagesPromise.then(function (historyResult) {
if (curJump != jump) return;
offset += startLimit;
offset += historyResult.history.length;
hasMore = offset < historyResult.count;
maxID = historyResult.history[historyResult.history.length - 1];
@ -462,6 +462,15 @@ angular.module('myApp.controllers', [])
});
$scope.history.reverse();
if (historyResult.unreadLimit) {
$scope.historyUnread = {
beforeID: historyResult.history[historyResult.unreadLimit - 1],
count: historyResult.unreadLimit
};
} else {
$scope.historyUnread = {};
}
safeReplaceObject($scope.state, {loaded: true});
$scope.$broadcast('ui_history_change');
@ -589,6 +598,8 @@ angular.module('myApp.controllers', [])
$scope.history.push(AppMessagesManager.wrapForHistory(addedMessage.messageID));
$scope.typing = {};
$scope.$broadcast('ui_history_append', {my: addedMessage.my});
$scope.historyUnread = {};
offset++;
// console.log('append check', $rootScope.idle.isIDLE, addedMessage.peerID, $scope.curDialog.peerID);
@ -728,7 +739,7 @@ angular.module('myApp.controllers', [])
// console.trace('ctrl text changed', newVal);
AppMessagesManager.readHistory($scope.curDialog.inputPeer);
if (newVal.length) {
if (newVal && newVal.length) {
var backupDraftObj = {};
backupDraftObj['draft' + $scope.curDialog.peerID] = newVal;
AppConfigManager.set(backupDraftObj);

37
js/directives.js

@ -215,8 +215,16 @@ angular.module('myApp.directives', ['myApp.filters'])
onContentLoaded(function () {
$(scrollableWrap).removeClass('im_history_to_bottom');
$(scrollable).css({bottom: ''});
updateSizes();
scrollableWrap.scrollTop = scrollableWrap.scrollHeight;
updateSizes(true);
var unreadSplit = $('.im_message_unread_split', scrollableWrap);
if (unreadSplit[0]) {
scrollableWrap.scrollTop = unreadSplit[0].offsetTop;
atBottom = false;
} else {
scrollableWrap.scrollTop = scrollableWrap.scrollHeight;
}
updateScroller();
moreNotified = false;
});
@ -429,6 +437,7 @@ angular.module('myApp.directives', ['myApp.filters'])
};
$('body').on('dragenter dragleave dragover drop', onDragDropEvent);
$(document).on('paste', onPasteEvent);
scope.$on('ui_peer_change', focusField);
scope.$on('ui_history_focus', focusField);
@ -440,6 +449,7 @@ angular.module('myApp.directives', ['myApp.filters'])
scope.$on('$destroy', function cleanup() {
$('body').off('dragenter dragleave dragover drop', onDragDropEvent);
$(document).off('paste', onPasteEvent);
});
focusField();
@ -450,6 +460,26 @@ angular.module('myApp.directives', ['myApp.filters'])
});
}
function onPasteEvent (e) {
var cData = (e.originalEvent || e).clipboardData,
items = cData && cData.items || [],
files = [],
i;
for (i = 0; i < items.length; i++) {
if (items[i].kind == 'file') {
files.push(items[i].getAsFile());
}
}
if (files.length && safeConfirm('Are you sure to send file(s) from clipboard?')) {
scope.$apply(function () {
scope.draftMessage.files = files;
scope.draftMessage.isMedia = true;
});
}
}
function onDragDropEvent(e) {
var dragStateChanged = false;
if (!dragStarted || dragStarted == 1) {
@ -696,7 +726,8 @@ angular.module('myApp.directives', ['myApp.filters'])
MtpApiFileManager.downloadFile(scope.video.dc_id, inputLocation, scope.video.size, null, {mime: 'video/mp4'}).then(function (url) {
scope.progress.enabled = false;
// scope.progress = {enabled: true, percent: 50};
scope.player.quicktime = hasQt;
scope.player.hasQuicktime = hasQt;
scope.player.quicktime = false;
scope.player.src = $sce.trustAsResourceUrl(url);
}, function (e) {
console.log('Download video failed', e, scope.video);

140
js/services.js

@ -134,6 +134,7 @@ angular.module('myApp.services', [])
var users = {},
cachedPhotoLocations = {},
contactsFillPromise,
contactsList,
contactsIndex = SearchIndexManager.createIndex();
function fillContacts () {
@ -143,8 +144,8 @@ angular.module('myApp.services', [])
return contactsFillPromise = MtpApiManager.invokeApi('contacts.getContacts', {
hash: ''
}).then(function (result) {
var contactsList = [],
userID, searchText, i;
var userID, searchText, i;
contactsList = [];
saveApiUsers(result.users);
for (var i = 0; i < result.contacts.length; i++) {
@ -323,6 +324,24 @@ angular.module('myApp.services', [])
$rootScope.$broadcast('user_update', userID);
}
break;
case 'updateContactLink':
if (angular.isArray(contactsList)) {
var userID = update.user_id,
curPos = curIsContact = contactsList.indexOf(userID),
curIsContact = curPos != -1,
newIsContact = update.my_link._ == 'contacts.myLinkContact';
if (newIsContact != curIsContact) {
if (newIsContact) {
contactsList.push(userID);
SearchIndexManager.indexObject(userID, getUserSearchText(userID), contactsIndex);
} else {
contactsList.splice(curPos, 1);
}
}
}
break;
}
});
@ -729,6 +748,46 @@ angular.module('myApp.services', [])
return deferred.promise;
}
function fillHistoryStorage (inputPeer, maxID, fullLimit, historyStorage) {
return MtpApiManager.invokeApi('messages.getHistory', {
peer: inputPeer,
offset: 0,
limit: fullLimit,
max_id: maxID || 0
}).then(function (historyResult) {
AppUsersManager.saveApiUsers(historyResult.users);
AppChatsManager.saveApiChats(historyResult.chats);
saveMessages(historyResult.messages);
historyStorage.count = historyResult._ == 'messages.messagesSlice'
? historyResult.count
: historyResult.messages.length;
var offset = 0;
if (maxID > 0) {
for (offset = 0; offset < historyStorage.history.length; offset++) {
if (maxID > historyStorage.history[offset]) {
break;
}
}
}
historyStorage.history.splice(offset, historyStorage.history.length - offset);
angular.forEach(historyResult.messages, function (message) {
historyStorage.history.push(message.id);
});
fullLimit -= historyResult.messages.length;
if (fullLimit > 0 && historyStorage.history.length < historyStorage.count) {
maxID = historyStorage.history[historyStorage.history.length - 1];
return fillHistoryStorage(inputPeer, maxID, fullLimit, historyStorage);
}
return true;
});
};
function getHistory (inputPeer, maxID, limit) {
var peerID = AppPeersManager.getPeerID(inputPeer),
@ -743,6 +802,17 @@ angular.module('myApp.services', [])
resultPending = historyStorage.pending.slice();
}
var unreadLimit = false;
if (!limit && !maxID) {
var foundDialog = getDialogByPeerID(peerID);
if (foundDialog && foundDialog[0] && foundDialog[0].unread_count > 0) {
unreadLimit = foundDialog[0].unread_count;
limit = Math.max(20, unreadLimit + 2);
}
}
if (!limit) {
limit = 20;
}
if (maxID > 0) {
for (offset = 0; offset < historyStorage.history.length; offset++) {
@ -751,7 +821,6 @@ angular.module('myApp.services', [])
}
}
}
// console.log('history storage', angular.copy(historyStorage.history), maxID, offset);
if (historyStorage.count !== null && (
historyStorage.history.length >= offset + limit ||
@ -759,26 +828,12 @@ angular.module('myApp.services', [])
)) {
return $q.when({
count: historyStorage.count,
history: resultPending.concat(historyStorage.history.slice(offset, offset + limit))
history: resultPending.concat(historyStorage.history.slice(offset, offset + limit)),
unreadLimit: unreadLimit
});
}
var deferred = $q.defer();
MtpApiManager.invokeApi('messages.getHistory', {
peer: inputPeer,
offset: offset,
limit: limit,
max_id: maxID || 0
}).then(function (historyResult) {
AppUsersManager.saveApiUsers(historyResult.users);
AppChatsManager.saveApiChats(historyResult.chats);
saveMessages(historyResult.messages);
historyStorage.count = historyResult._ == 'messages.messagesSlice'
? historyResult.count
: historyResult.messages.length;
return fillHistoryStorage(inputPeer, maxID, limit, historyStorage).then(function () {
offset = 0;
if (maxID > 0) {
for (offset = 0; offset < historyStorage.history.length; offset++) {
@ -788,23 +843,12 @@ angular.module('myApp.services', [])
}
}
// console.log('history storage after', angular.copy(historyStorage.history), historyResult.messages, maxID, offset);
historyStorage.history.splice(offset, historyStorage.history.length - offset);
angular.forEach(historyResult.messages, function (message) {
historyStorage.history.push(message.id);
});
// console.log('history storage final', angular.copy(historyStorage.history), historyResult.messages, maxID, offset);
deferred.resolve({
return {
count: historyStorage.count,
history: resultPending.concat(historyStorage.history.slice(offset, offset + limit))
});
}, function (error) {
deferred.reject(error);
history: resultPending.concat(historyStorage.history.slice(offset, offset + limit)),
unreadLimit: unreadLimit
};
});
return deferred.promise;
}
function getSearch (inputPeer, query, inputFilter, maxID, limit) {
@ -1072,18 +1116,27 @@ angular.module('myApp.services', [])
randomIDS = bigint(randomID[0]).shiftLeft(32).add(bigint(randomID[1])).toString(),
historyStorage = historiesStorage[peerID],
inputPeer = AppPeersManager.getInputPeerByID(peerID),
attachType;
attachType, fileName, fileName;
if (!options.isMedia) {
attachType = 'doc';
fileName = 'doc.' + file.type.split('/')[1];
} else if (['image/jpeg', 'image/gif', 'image/png', 'image/bmp'].indexOf(file.type) >= 0) {
attachType = 'photo';
fileName = 'photo.' + file.type.split('/')[1];
} else if (file.type.substr(0, 6) == 'video/') {
attachType = 'video';
fileName = 'video.mp4';
} else if (file.type == 'audio/mpeg' || file.type == 'audio/mp3') {
attachType = 'audio';
fileName = 'audio.mp3';
} else {
attachType = 'doc';
fileName = 'doc.' + file.type.split('/')[1];
}
if (!file.name) {
file.name = fileName;
}
if (historyStorage === undefined) {
@ -1113,6 +1166,21 @@ angular.module('myApp.services', [])
pending: true
};
var toggleError = function (on) {
var historyMessage = messagesForHistory[messageID];
if (on) {
message.error = true;
if (historyMessage) {
historyMessage.error = true;
}
} else {
delete message.error;
if (historyMessage) {
delete historyMessage.error;
}
}
}
message.send = function () {
MtpApiFileManager.uploadFile(file).then(function (inputFile) {
var inputMedia;

6
partials/message.html

@ -1,3 +1,9 @@
<div class="im_message_unread_split" ng-if="historyUnread &amp;&amp; historyUnread.beforeID == historyMessage.id">
<ng-pluralize count="historyUnread.count"
when="{'one': '1 unread message', 'other': '{} unread messages'}">
</ng-pluralize>
</div>
<div class="im_message_outer_wrap" ng-class="{im_message_selected: selectedMsgs[historyMessage.id]}" ng-click="toggleMessage(historyMessage.id, $event.target)">

10
vendor/jquery.emojiarea/jquery.emojiarea.js vendored

@ -315,6 +315,16 @@
Following code was modified by Igor Zhukov, in order to improve rich text paste
*/
EmojiArea_WYSIWYG.prototype.onPaste = function(e) {
var cData = (e.originalEvent || e).clipboardData,
items = cData && cData.items || [],
i;
for (i = 0; i < items.length; i++) {
if (items[i].kind == 'file') {
e.preventDefault();
return true;
}
}
var text = (e.originalEvent || e).clipboardData.getData('text/plain'),
self = this;
setTimeout(function () {

Loading…
Cancel
Save