Improved bots support

This commit is contained in:
Igor Zhukov 2015-07-08 20:15:11 +03:00
parent 0cd91d1674
commit a5b3dd8e07
20 changed files with 342 additions and 233 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -995,8 +995,6 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.selectedFlush = selectedFlush;
$scope.botStart = botStart;
$scope.replyKeyboardToggle = replyKeyboardToggle;
$scope.toggleEdit = toggleEdit;
$scope.toggleMedia = toggleMedia;
$scope.returnToRecent = returnToRecent;
@ -1371,7 +1369,6 @@ angular.module('myApp.controllers', ['myApp.i18n'])
AppMessagesManager.readHistory($scope.curDialog.inputPeer);
updateStartBot();
updateReplyKeyboard();
}, function () {
safeReplaceObject($scope.state, {error: true});
@ -1388,28 +1385,6 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.$broadcast('ui_history_change');
}
function updateReplyKeyboard () {
var replyKeyboard = AppMessagesManager.getReplyKeyboard(peerID);
if (replyKeyboard) {
replyKeyboard = AppMessagesManager.wrapReplyMarkup(replyKeyboard);
}
console.log('update reply markup', peerID, replyKeyboard);
$scope.historyState.replyKeyboard = replyKeyboard;
$scope.$broadcast('ui_keyboard_update');
}
function replyKeyboardToggle ($event) {
var replyKeyboard = $scope.historyState.replyKeyboard;
if (!replyKeyboard) {
return;
}
replyKeyboard.pFlags.hidden = !replyKeyboard.pFlags.hidden;
console.log('toggle reply markup', peerID, replyKeyboard);
$scope.$broadcast('ui_keyboard_update');
return cancelEvent($event);
}
function botStart () {
AppMessagesManager.startBot(peerID, 0, $scope.curDialog.startParam);
$scope.curDialog.startParam = false;
@ -1615,7 +1590,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
return;
}
AppMessagesManager.sendText(peerID, button.text, {
replyToMsgID: replyKeyboard.id
replyToMsgID: peerID < 0 && replyKeyboard.id
});
});
@ -1678,6 +1653,8 @@ angular.module('myApp.controllers', ['myApp.i18n'])
AppMessagesManager.readHistory($scope.curDialog.inputPeer);
});
}
updateStartBot();
}
});
@ -1817,12 +1794,6 @@ angular.module('myApp.controllers', ['myApp.i18n'])
}
});
$scope.$on('history_reply_markup', function (e, peerData) {
if (peerData.peerID == $scope.curDialog.peerID) {
updateReplyKeyboard();
}
});
$scope.$on('history_focus', function (e, peerData) {
if ($scope.historyFilter.mediaType) {
toggleMedia();
@ -1882,7 +1853,11 @@ angular.module('myApp.controllers', ['myApp.i18n'])
});
$scope.$on('ui_typing', onTyping);
$scope.draftMessage = {text: '', send: sendMessage, replyClear: replyClear};
$scope.draftMessage = {
text: '',
send: sendMessage,
replyClear: replyClear
};
$scope.mentions = {};
$scope.commands = {};
$scope.$watch('draftMessage.text', onMessageChange);
@ -1890,7 +1865,16 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.$watch('draftMessage.sticker', onStickerSelected);
$scope.$watch('draftMessage.command', onCommandSelected);
$scope.enterSlash = enterSlash;
$scope.$on('history_reply_markup', function (e, peerData) {
if (peerData.peerID == $scope.curDialog.peerID) {
updateReplyKeyboard();
}
});
$scope.replyKeyboardToggle = replyKeyboardToggle;
$scope.toggleSlash = toggleSlash;
var replyToMarkup = false;
function sendMessage (e) {
$scope.$broadcast('ui_message_before_send');
@ -2008,6 +1992,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
updateMentions();
updateCommands();
replyClear();
updateReplyKeyboard();
if (newPeer) {
Storage.get('draft' + $scope.curDialog.peerID).then(function (draftText) {
@ -2026,19 +2011,67 @@ angular.module('myApp.controllers', ['myApp.i18n'])
function replySelect(messageID) {
$scope.draftMessage.replyToMessage = AppMessagesManager.wrapForDialog(messageID);
$scope.$broadcast('ui_peer_reply');
replyToMarkup = false;
}
function replyClear() {
var message = $scope.draftMessage.replyToMessage;
if (message &&
$scope.historyState.replyKeyboard &&
$scope.historyState.replyKeyboard.id == message.id &&
!$scope.historyState.replyKeyboard.pFlags.hidden) {
$scope.historyState.replyKeyboard.pFlags.hidden = true;
$scope.$broadcast('ui_keyboard_update');
}
delete $scope.draftMessage.replyToMessage;
$scope.$broadcast('ui_peer_reply');
}
function enterSlash ($event) {
$scope.draftMessage.text = '/';
function toggleSlash ($event) {
if ($scope.draftMessage.text &&
$scope.draftMessage.text.charAt(0) == '/') {
$scope.draftMessage.text = '';
} else {
$scope.draftMessage.text = '/';
}
$scope.$broadcast('ui_peer_draft');
return cancelEvent($event);
}
function updateReplyKeyboard () {
var peerID = $scope.curDialog.peerID;
var replyKeyboard = AppMessagesManager.getReplyKeyboard(peerID);
if (replyKeyboard) {
replyKeyboard = AppMessagesManager.wrapReplyMarkup(replyKeyboard);
}
// console.log('update reply markup', peerID, replyKeyboard);
$scope.historyState.replyKeyboard = replyKeyboard;
var addReplyMessage =
replyKeyboard &&
!replyKeyboard.hidden &&
(replyKeyboard._ == 'replyKeyboardForceReply' ||
(replyKeyboard._ == 'replyKeyboardMarkup' && peerID < 0));
if (addReplyMessage) {
replySelect(replyKeyboard.id);
replyToMarkup = true;
}
else if (replyToMarkup) {
replyClear();
}
$scope.$broadcast('ui_keyboard_update');
}
function replyKeyboardToggle ($event) {
var replyKeyboard = $scope.historyState.replyKeyboard;
if (replyKeyboard) {
replyKeyboard.pFlags.hidden = !replyKeyboard.pFlags.hidden;
updateReplyKeyboard();
}
return cancelEvent($event);
}
function onMessageChange(newVal) {
// console.log('ctrl text changed', newVal);
// console.trace('ctrl text changed', newVal);
@ -2356,8 +2389,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.nav = {};
$scope.canForward = true;
var inputUser = AppUsersManager.getUserInput($scope.userID),
list = [$scope.photoID],
var list = [$scope.photoID],
maxID = $scope.photoID,
preloaded = {},
myID = 0,
@ -2365,7 +2397,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
updatePrevNext();
AppPhotosManager.getUserPhotos(inputUser, 0, 1000).then(function (userpicCachedResult) {
AppPhotosManager.getUserPhotos($scope.userID, 0, 1000).then(function (userpicCachedResult) {
if (userpicCachedResult.photos.indexOf($scope.photoID) >= 0) {
list = userpicCachedResult.photos;
maxID = list[list.length - 1];
@ -2434,7 +2466,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
function loadMore () {
if (loadingPromise) return loadingPromise;
return loadingPromise = AppPhotosManager.getUserPhotos(inputUser, maxID).then(function (userpicResult) {
return loadingPromise = AppPhotosManager.getUserPhotos($scope.userID, maxID).then(function (userpicResult) {
if (userpicResult.photos.length) {
maxID = userpicResult.photos[userpicResult.photos.length - 1];
list = list.concat(userpicResult.photos);
@ -2984,7 +3016,9 @@ angular.module('myApp.controllers', ['myApp.i18n'])
id: {_: 'inputUserSelf'}
}).then(function (userFullResult) {
AppUsersManager.saveApiUser(userFullResult.user);
AppPhotosManager.savePhoto(userFullResult.profile_photo);
AppPhotosManager.savePhoto(userFullResult.profile_photo, {
user_id: userFullResult.user.id
});
});
$scope.notify = {volume: 0.5};
@ -3055,8 +3089,10 @@ angular.module('myApp.controllers', ['myApp.i18n'])
crop: {_: 'inputPhotoCropAuto'}
}).then(function (updateResult) {
AppUsersManager.saveApiUsers(updateResult.users);
AppPhotosManager.savePhoto(updateResult.photo);
MtpApiManager.getUserID().then(function (id) {
AppPhotosManager.savePhoto(updateResult.photo, {
user_id: id
});
ApiUpdatesManager.processUpdateMessage({
_: 'updateShort',
update: {

View File

@ -339,6 +339,16 @@ angular.module('myApp.directives', ['myApp.filters'])
};
function link ($scope, element, attrs) {
if (attrs.watch) {
$scope.$watch('replyMessage', function () {
checkMessage($scope, element);
});
} else {
checkMessage($scope, element);
}
}
function checkMessage ($scope, element) {
var message = $scope.replyMessage;
if (!message.loading) {
updateMessage($scope, element);

View File

@ -82,7 +82,9 @@ angular.module('myApp.filters', ['myApp.i18n'])
var dateFilter = $filter('date');
return function (timestamp, extended) {
if (!timestamp) {
return '';
}
var ticks = timestamp * 1000,
diff = Math.abs(tsNow() - ticks),
format = 'shortTime';

File diff suppressed because one or more lines are too long

View File

@ -110,14 +110,14 @@ messageActionChatDeleteUser#b2ae9b0c user_id:int = MessageAction;
dialog#c1dd804a peer:Peer top_message:int read_inbox_max_id:int unread_count:int notify_settings:PeerNotifySettings = Dialog;
photoEmpty#2331b22d id:long = Photo;
photo#690cc3a6 id:long access_hash:long sizes:Vector<PhotoSize> = Photo;
photo#cded42fe id:long access_hash:long date:int sizes:Vector<PhotoSize> = Photo;
photoSizeEmpty#e17e23c type:string = PhotoSize;
photoSize#77bfb61b type:string location:FileLocation w:int h:int size:int = PhotoSize;
photoCachedSize#e9a734fa type:string location:FileLocation w:int h:int bytes:bytes = PhotoSize;
videoEmpty#c10658a8 id:long = Video;
video#954cc1cc id:long access_hash:long duration:int mime_type:string size:int thumb:PhotoSize dc_id:int w:int h:int = Video;
video#f72887d3 id:long access_hash:long date:int duration:int mime_type:string size:int thumb:PhotoSize dc_id:int w:int h:int = Video;
geoPointEmpty#1117dd5f = GeoPoint;
geoPoint#2049d70c long:double lat:double = GeoPoint;
@ -327,10 +327,10 @@ inputAudioFileLocation#74dc404d id:long access_hash:long = InputFileLocation;
inputDocumentFileLocation#4e45abe9 id:long access_hash:long = InputFileLocation;
audioEmpty#586988d8 id:long = Audio;
audio#a5e11d9c id:long access_hash:long duration:int mime_type:string size:int dc_id:int = Audio;
audio#f9e35055 id:long access_hash:long date:int duration:int mime_type:string size:int dc_id:int = Audio;
documentEmpty#36f8c871 id:long = Document;
document#902db111 id:long access_hash:long mime_type:string size:int thumb:PhotoSize dc_id:int attributes:Vector<DocumentAttribute> = Document;
document#f9a39f4f id:long access_hash:long date:int mime_type:string size:int thumb:PhotoSize dc_id:int attributes:Vector<DocumentAttribute> = Document;
help.support#17c6b5f6 phone_number:string user:User = help.Support;
@ -484,6 +484,9 @@ inputPeerUser#7b8e7de6 user_id:int access_hash:long = InputPeer;
inputUser#d8292816 user_id:int access_hash:long = InputUser;
help.appChangelogEmpty#af7e0394 = help.AppChangelog;
help.appChangelog#4668e6bd text:string = help.AppChangelog;
---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
@ -646,4 +649,6 @@ messages.importChatInvite#6c50051c hash:string = Updates;
messages.getStickerSet#2619a90e stickerset:InputStickerSet = messages.StickerSet;
messages.installStickerSet#7b30c3a6 stickerset:InputStickerSet disabled:Bool = Bool;
messages.uninstallStickerSet#f96e55de stickerset:InputStickerSet = Bool;
messages.startBot#1b3e0ffc bot:InputUser chat_id:int random_id:long start_param:string = Updates;
messages.startBot#1b3e0ffc bot:InputUser chat_id:int random_id:long start_param:string = Updates;
help.getAppChangelog#5bab7fb2 device_model:string system_version:string app_version:string lang_code:string = help.AppChangelog;

View File

@ -49,6 +49,21 @@ function cancelEvent (event) {
return false;
}
function getScrollWidth() {
var outer = $('<div>').css({
position: 'absolute',
width: 100,
height: 100,
overflow: 'scroll',
top: -9999
}).appendTo($(document.body));
var scrollbarWidth = outer[0].offsetWidth - outer[0].clientWidth;
outer.remove();
return scrollbarWidth;
};
function onCtrlEnter (textarea, cb) {
$(textarea).on('keydown', function (e) {
if (e.keyCode == 13 && (e.ctrlKey || e.metaKey)) {

View File

@ -498,13 +498,20 @@ function MessageComposer (textarea, options) {
this.onCommandSend = options.onCommandSend;
}
MessageComposer.autoCompleteRegEx = /(\s|^)(:|@|\/)([A-Za-z0-9\-\+\*@_]*)$/;
MessageComposer.prototype.setUpInput = function () {
if ('contentEditable' in document.body) {
this.setUpRich();
} else {
this.setUpPlaintext();
}
this.autoCompleteRegEx = /(\s|^)(:|@|\/)([A-Za-z0-9\-\+\*@_]*)$/;
var sbWidth = getScrollWidth();
if (sbWidth) {
(this.richTextareaEl || this.textareaEl).css({marginRight: -sbWidth});
}
}
MessageComposer.prototype.setUpRich = function () {
@ -696,7 +703,7 @@ MessageComposer.prototype.checkAutocomplete = function (forceFull) {
value = value.substr(0, pos);
}
var matches = value.match(this.autoCompleteRegEx);
var matches = value.match(MessageComposer.autoCompleteRegEx);
if (matches) {
if (this.previousQuery == matches[0]) {
return;
@ -1172,6 +1179,7 @@ function Scroller(content, options) {
this.useNano = options.nano !== undefined ? options.nano : !Config.Mobile;
this.maxHeight = options.maxHeight;
this.minHeight = options.minHeight;
if (this.useNano) {
this.scrollable.addClass('nano-content');
@ -1181,6 +1189,9 @@ function Scroller(content, options) {
if (this.maxHeight) {
this.wrap.css({maxHeight: this.maxHeight});
}
if (this.minHeight) {
this.wrap.css({minHeight: this.minHeight});
}
}
this.updateHeight();
}
@ -1202,9 +1213,14 @@ Scroller.prototype.reinit = function () {
Scroller.prototype.updateHeight = function () {
var height;
if (this.maxHeight) {
var contentHeight = this.content[0].offsetHeight;
height = Math.min(this.maxHeight, contentHeight);
if (this.maxHeight || this.minHeight) {
height = this.content[0].offsetHeight;
if (this.maxHeight && height > this.maxHeight) {
height = this.maxHeight;
}
if (this.minHeight && height < this.minHeight) {
height = this.minHeight;
}
this.wrap.css({height: height});
} else {
height = this.scroller[0].offsetHeight;

View File

@ -875,7 +875,9 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
AppUsersManager.saveApiUser(userFull.user, true);
}
AppPhotosManager.savePhoto(userFull.profile_photo);
AppPhotosManager.savePhoto(userFull.profile_photo, {
user_id: id
});
NotificationsManager.savePeerSettings(id, userFull.notify_settings);
@ -1300,13 +1302,10 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
}
function mergeReplyKeyboard (historyStorage, message) {
console.log('merge', message.id, message.reply_markup, historyStorage.reply_markup);
// console.log('merge', message.id, message.reply_markup, historyStorage.reply_markup);
if (!message.reply_markup &&
!(
historyStorage.reply_markup !== undefined &&
(message.out || message.action)
)
) {
!message.out &&
!message.action) {
return false;
}
var messageReplyMarkup = message.reply_markup;
@ -1319,6 +1318,11 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
!(message.flags & 16)) {
return false;
}
if (historyStorage.maxOutID &&
message.id < historyStorage.maxOutID &&
messageReplyMarkup.pFlags.one_time) {
messageReplyMarkup.pFlags.hidden = true;
}
messageReplyMarkup = angular.extend({
id: message.id
}, messageReplyMarkup);
@ -1326,31 +1330,40 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
messageReplyMarkup.fromID = message.from_id;
}
historyStorage.reply_markup = messageReplyMarkup;
console.log('set', historyStorage.reply_markup);
// console.log('set', historyStorage.reply_markup);
return true;
}
if (lastReplyMarkup &&
lastReplyMarkup.pFlags.one_time &&
!lastReplyMarkup.pFlags.hidden &&
message.out &&
(message.id > lastReplyMarkup.id || message.id < 0) &&
message.message) {
lastReplyMarkup.pFlags.hidden = true;
console.log('set', historyStorage.reply_markup);
return true;
if (message.out) {
if (lastReplyMarkup) {
if (lastReplyMarkup.pFlags.one_time &&
!lastReplyMarkup.pFlags.hidden &&
(message.id > lastReplyMarkup.id || message.id < 0) &&
message.message) {
lastReplyMarkup.pFlags.hidden = true;
// console.log('set', historyStorage.reply_markup);
return true;
}
} else if (!historyStorage.maxOutID ||
message.id > historyStorage.maxOutID) {
historyStorage.maxOutID = message.id;
}
}
if (lastReplyMarkup &&
message.action &&
if (message.action &&
message.action._ == 'messageActionChatDeleteUser' &&
message.action.user_id == lastReplyMarkup.fromID) {
(lastReplyMarkup
? message.action.user_id == lastReplyMarkup.fromID
: AppUsersManager.isBot(message.action.user_id)
)
) {
historyStorage.reply_markup = {
_: 'replyKeyboardHide',
id: message.id,
flags: 0
flags: 0,
pFlags: {}
};
console.log('set', historyStorage.reply_markup);
// console.log('set', historyStorage.reply_markup);
return true;
}
@ -1633,30 +1646,35 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
apiMessage.date -= serverTimeOffset;
var mediaContext = {
user_id: apiMessage.from_id,
date: apiMessage.date
};
if (apiMessage.media) {
switch (apiMessage.media._) {
case 'messageMediaEmpty':
delete apiMessage.media;
break;
case 'messageMediaPhoto':
AppPhotosManager.savePhoto(apiMessage.media.photo);
AppPhotosManager.savePhoto(apiMessage.media.photo, mediaContext);
break;
case 'messageMediaVideo':
AppVideoManager.saveVideo(apiMessage.media.video);
AppVideoManager.saveVideo(apiMessage.media.video, mediaContext);
break;
case 'messageMediaDocument':
AppDocsManager.saveDoc(apiMessage.media.document);
AppDocsManager.saveDoc(apiMessage.media.document, mediaContext);
break;
case 'messageMediaAudio':
AppAudioManager.saveAudio(apiMessage.media.audio);
break;
case 'messageMediaWebPage':
AppWebPagesManager.saveWebPage(apiMessage.media.webpage, apiMessage.id);
AppWebPagesManager.saveWebPage(apiMessage.media.webpage, apiMessage.id, mediaContext);
break;
}
}
if (apiMessage.action && apiMessage.action._ == 'messageActionChatEditPhoto') {
AppPhotosManager.savePhoto(apiMessage.action.photo);
AppPhotosManager.savePhoto(apiMessage.action.photo, mediaContext);
}
if (apiMessage.reply_markup) {
apiMessage.reply_markup.pFlags = {
@ -3067,8 +3085,12 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
windowW = $(window).width(),
windowH = $(window).height();
function savePhoto (apiPhoto) {
function savePhoto (apiPhoto, context) {
if (context) {
angular.extend(apiPhoto, context);
}
photos[apiPhoto.id] = apiPhoto;
angular.forEach(apiPhoto.sizes, function (photoSize) {
if (photoSize._ == 'photoCachedSize') {
MtpApiFileManager.saveSmallFile(photoSize.location, photoSize.bytes);
@ -3102,7 +3124,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
return bestPhotoSize;
}
function getUserPhotos (inputUser, maxID, limit) {
function getUserPhotos (userID, maxID, limit) {
var inputUser = AppUsersManager.getUserInput(userID);
return MtpApiManager.invokeApi('photos.getUserPhotos', {
user_id: inputUser,
offset: 0,
@ -3111,8 +3134,9 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
}).then(function (photosResult) {
AppUsersManager.saveApiUsers(photosResult.users);
var photoIDs = [];
var context = {user_id: userID};
for (var i = 0; i < photosResult.photos.length; i++) {
savePhoto(photosResult.photos[i]);
savePhoto(photosResult.photos[i], context);
photoIDs.push(photosResult.photos[i].id)
}
@ -3312,9 +3336,9 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
var webpages = {};
var pendingWebPages = {};
function saveWebPage (apiWebPage, messageID) {
function saveWebPage (apiWebPage, messageID, mediaContext) {
if (apiWebPage.photo && apiWebPage.photo._ === 'photo') {
AppPhotosManager.savePhoto(apiWebPage.photo);
AppPhotosManager.savePhoto(apiWebPage.photo, mediaContext);
} else {
delete apiWebPage.photo;
}
@ -3453,7 +3477,10 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
windowW = $(window).width(),
windowH = $(window).height();
function saveVideo (apiVideo) {
function saveVideo (apiVideo, context) {
if (context) {
angular.extend(apiVideo, context);
}
videos[apiVideo.id] = apiVideo;
if (apiVideo.thumb && apiVideo.thumb._ == 'photoCachedSize') {
@ -3646,9 +3673,12 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
windowW = $(window).width(),
windowH = $(window).height();
function saveDoc (apiDoc) {
function saveDoc (apiDoc, context) {
docs[apiDoc.id] = apiDoc;
if (context) {
angular.extend(apiDoc, context);
}
if (apiDoc.thumb && apiDoc.thumb._ == 'photoCachedSize') {
MtpApiFileManager.saveSmallFile(apiDoc.thumb.location, apiDoc.thumb.bytes);

View File

@ -858,7 +858,7 @@ a.tg_radio_on:hover i.icon-radio {
vertical-align: top;
margin-right: 18px;
.image-2x('../img/icons/General.png', 40px, 798px);
.image-2x('../img/icons/General.png', 40px, 848px);
background-position: -5px -10px;
}
.icon-tg-title {
@ -899,7 +899,7 @@ a.tg_radio_on:hover i.icon-radio {
margin-left: 12px;
margin-top: -1px;
.image-2x('../img/icons/General.png', 40px, 798px);
.image-2x('../img/icons/General.png', 40px, 848px);
background-position: -18px -50px;
}
@ -1617,7 +1617,7 @@ div.im_message_video_thumb {
height: 18px;
margin: 12px 15px;
.image-2x('../img/icons/General.png', 40px, 798px);
.image-2x('../img/icons/General.png', 40px, 848px);
background-position: -14px -509px;
.im_message_file_button_dl_doc & {
@ -1638,7 +1638,7 @@ div.im_message_video_thumb {
height: 16px;
margin: 13px 16px;
.image-2x('../img/icons/General.png', 40px, 798px);
.image-2x('../img/icons/General.png', 40px, 848px);
background-position: -13px -611px;
}
@ -2281,7 +2281,7 @@ img.img_fullsize {
vertical-align: top;
opacity: 0.8;
.image-2x('../img/icons/General.png', 40px, 798px);
.image-2x('../img/icons/General.png', 40px, 848px);
background-position: -9px -335px;
}
@ -2682,24 +2682,31 @@ a.composer_command_option.composer_autocomplete_option_active .composer_command_
.composer_command_btn {
display: block;
position: absolute;
right: 23px;
top: 2px;
right: 37px;
top: 4px;
cursor: pointer;
padding: 0;
width: 22px;
height: 22px;
margin-top: 1px;
width: 20px;
height: 20px;
}
.icon-slash {
display: inline-block;
width: 22px;
height: 22px;
width: 20px;
height: 20px;
vertical-align: top;
opacity: 0.8;
.image-2x('../img/icons/General.png', 40px, 798px);
background-position: -9px -335px;
.image-2x('../img/icons/General.png', 40px, 848px);
background-position: -10px -790px;
.composer_command_btn.active & {
background-position: -10px -820px;
}
.composer_command_btn:hover & {
opacity: 1.0;
}
}
.composer_keyboard_btn {
@ -2720,7 +2727,7 @@ a.composer_command_option.composer_autocomplete_option_active .composer_command_
vertical-align: top;
opacity: 0.8;
.image-2x('../img/icons/General.png', 40px, 798px);
.image-2x('../img/icons/General.png', 40px, 848px);
background-position: -10px -730px;
.composer_keyboard_btn.active & {

View File

@ -205,7 +205,7 @@
display: inline-block;
vertical-align: top;
margin-top: 3px;
.image-2x('../img/icons/General.png', 40px, 798px);
.image-2x('../img/icons/General.png', 40px, 848px);
background-position: -10px -111px;
}
@ -217,7 +217,7 @@
margin-top: 2px;
display: inline-block;
vertical-align: top;
.image-2x('../img/icons/General.png', 40px, 798px);
.image-2x('../img/icons/General.png', 40px, 848px);
background-position: -11px -135px;
}
@ -228,7 +228,7 @@
margin-top: 1px;
display: inline-block;
vertical-align: top;
.image-2x('../img/icons/General.png', 40px, 798px);
.image-2x('../img/icons/General.png', 40px, 848px);
background-position: -10px -163px;
}
@ -239,7 +239,7 @@
margin-top: 1px;
display: inline-block;
vertical-align: top;
.image-2x('../img/icons/General.png', 40px, 798px);
.image-2x('../img/icons/General.png', 40px, 848px);
background-position: -10px -637px;
}
@ -250,7 +250,7 @@
display: inline-block;
vertical-align: top;
.image-2x('../img/icons/General.png', 40px, 798px);
.image-2x('../img/icons/General.png', 40px, 848px);
background-position: -10px -193px;
}
}
@ -378,7 +378,7 @@
margin-right: 12px;
vertical-align: top;
.image-2x('../img/icons/General.png', 40px, 798px);
.image-2x('../img/icons/General.png', 40px, 848px);
background-position: 0 0;
}
@ -798,44 +798,6 @@ a.footer_link.active:active {
opacity: 1;
}
.icon-message-status {
pointer-events: none;
background: #4eabf1;
border: 0;
display: block;
width: 10px;
height: 10px;
border-radius: 7px;
position: absolute;
margin-left: -26px;
margin-top: 16px;
opacity: 0;
.im_message_unread & {
opacity: 1.0;
}
.im_message_pending & {
opacity: 0.5;
}
}
.im_message_error_btn {
display: none;
.im_message_error & {
display: inline;
}
.icon-message-status {
background: #da564d;
opacity: 0.85;
&:hover {
opacity: 1;
}
}
}
/* Messages edit panel */
.im {
@ -937,47 +899,106 @@ a.footer_link.active:active {
color: #899daf;
}
.im_content_message_select_area {
display: none;
cursor: pointer;
position: absolute;
width: 99px;
height: 58px;
margin: -8px 0 0 -99px;
.user-select(none);
}
.icon-select-tick {
display: none;
width: 26px;
height: 26px;
margin: 16px 0 0 40px;
.image-2x('../img/icons/IconsetW.png', 42px, 1171px);
background-position: -9px -516px;
}
@media (min-width: 1024px) {
.im_content_message_select_area {
display: block;
}
.im_message_wrap {
position: relative;
}
.icon-select-tick {
.im_message_selected &,
.im_history_selectable .im_message_outer_wrap:hover & {
position: absolute;
width: 26px;
height: 26px;
margin: 9px 0 0 -59px;
display: inline-block;
.image-2x('../img/icons/IconsetW.png', 42px, 1171px);
background-position: -9px -481px;
opacity: 0.5;
}
.im_message_selected & {
opacity: 1 !important;
}
.im_grouped_short &,
.im_grouped_short .im_message_outer_wrap:hover & {
margin-top: -2px;
}
.im_message_fwd &,
.im_message_outer_wrap:hover .im_message_fwd & {
margin-top: 10px;
}
.im_grouped_fwd &,
.im_grouped_fwd .im_message_outer_wrap:hover & {
margin-top: 7px;
}
.im_grouped &,
.im_grouped .im_message_outer_wrap:hover & {
margin-top: 7px;
}
.im_grouped_fwd_short &,
.im_grouped_fwd_short .im_message_outer_wrap:hover & {
margin-top: -5px;
}
}
}
.icon-select-tick {
.im_message_selected &,
.im_history_selectable .im_message_outer_wrap:hover &,
.im_content_message_select_area:hover & {
display: inline-block;
background-position: -9px -481px;
.icon-message-status {
pointer-events: none;
background: #4eabf1;
border: 0;
display: block;
width: 10px;
height: 10px;
border-radius: 7px;
position: absolute;
margin-left: -26px;
margin-top: 16px;
opacity: 0;
.im_message_unread & {
opacity: 1.0;
}
.im_message_pending & {
opacity: 0.5;
}
.im_message_selected & {
opacity: 1 !important;
.im_grouped_short & {
margin-top: 5px;
}
.im_message_fwd & {
margin-top: 16px;
}
.im_grouped_fwd & {
margin-top: 13px;
}
.im_grouped & {
margin-top: 13px;
}
.im_grouped_fwd_short & {
margin-top: 2px;
}
}
.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;
}
}
}
@ -1158,11 +1179,15 @@ a.im_panel_peer_photo .peer_initials {
}
.im_send_field_wrap {
margin-bottom: 15px;
margin-bottom: 13px;
position: relative;
padding-bottom: 2px;
overflow-x: hidden;
}
.composer_rich_textarea,
.composer_textarea {
overflow: none;
overflow-y: scroll;
border-radius: 0;
border: 0;
box-shadow: none;
@ -1180,6 +1205,10 @@ a.im_panel_peer_photo .peer_initials {
outline: none;
box-shadow: 0 2px 0 0 #77b7e4;
}
.im_send_field_wrap_2ndbtn & {
padding-right: 65px;
}
}
.icon-paperclip {
@ -1190,7 +1219,7 @@ a.im_panel_peer_photo .peer_initials {
opacity: 0.8;
margin: 0;
.image-2x('../img/icons/General.png', 40px, 798px);
.image-2x('../img/icons/General.png', 40px, 848px);
background-position: -11px -455px;
}
@ -1239,7 +1268,7 @@ a.im_panel_peer_photo .peer_initials {
vertical-align: top;
opacity: 0.8;
.image-2x('../img/icons/General.png', 40px, 798px);
.image-2x('../img/icons/General.png', 40px, 848px);
background-position: -10px -399px;
}
@ -1841,42 +1870,8 @@ a.im_panel_peer_photo .peer_initials {
}
}
.im_content_message_select_area {
.im_grouped_short &,
.im_grouped & {
height: 50px;
}
.im_message_fwd & {
margin-top: -4px;
}
.im_grouped_fwd .im_message_fwd &,
.im_grouped_fwd_short .im_message_fwd & {
margin-top: -8px;
}
.im_history_appending & {
height: 52px;
}
}
.icon-select-tick {
.im_message_fwd & {
margin-top: 12px;
}
.im_grouped_short & {
margin-top: 4px;
}
.im_grouped_fwd_short & {
margin-top: 2px;
}
}
.im_grouped_short .icon-message-status,
.im_grouped_fwd_short .icon-message-status {
margin-top: 5px;
}
.im_grouped_fwd .im_message_fwd_from,
.im_grouped_fwd_short .im_message_fwd_from {
display: none;
@ -1891,12 +1886,6 @@ a.im_panel_peer_photo .peer_initials {
display: none;
}
}
.im_grouped_fwd &,
.im_grouped_fwd_short & {
margin-top: 8px;
}
.im_grouped_fwd &,
.im_grouped_fwd_short & {
margin-top: 8px;
}

View File

@ -16,12 +16,12 @@
</a>
</div>
<div class="media_modal_info_wrap pull-left" ng-switch="messageID > 0">
<div class="media_modal_info_wrap pull-left" ng-if="document.user_id > 0" ng-switch="messageID > 0">
<a class="media_modal_author_photo pull-left" my-peer-photolink="document.user_id" img-class="media_modal_author_photo" watch="true"></a>
<div class="media_modal_author_name">
<a class="media_modal_author" my-user-link="document.user_id" user-watch="true"></a>
</div>
<div class="media_modal_date">
<div class="media_modal_date" ng-if="document.date > 0">
<a ng-switch-when="true" class="media_modal_date" ng-click="goToMessage()" ng-bind="document.date | dateOrTime :true"></a>
<span ng-switch-default ng-bind="document.date | dateOrTime :true"></span>
</div>

View File

@ -158,7 +158,7 @@
<div class="im_send_form_wrap1">
<div class="im_send_form_wrap clearfix" ng-controller="AppImSendController" ng-class="{im_send_reply_form_wrap: draftMessage.replyToMessage != null, im_send_field_wkeyboard: false && historyState.replyKeyboard._ == 'replyKeyboardMarkup' && !historyState.replyKeyboard.pFlags.hidden}">
<div class="im_send_form_wrap clearfix" ng-controller="AppImSendController" ng-class="{im_send_reply_form_wrap: draftMessage.replyToMessage != null}">
<a class="pull-right im_panel_peer_photo" my-peer-photolink="historyPeer.id" img-class="im_panel_peer_photo" watch="true">
<i class="icon im_panel_peer_online" ng-show="historyPeer.id > 0 &amp;&amp; historyPeer.data.status._ == 'userStatusOnline'"></i>
@ -169,12 +169,12 @@
<div class="im_send_reply_wrap" ng-if="draftMessage.replyToMessage != null">
<a class="im_send_reply_cancel" ng-click="draftMessage.replyClear()"><i class="icon icon-reply-bar"></i><i class="icon icon-reply-bar"></i></a>
<div my-reply-message="draftMessage.replyToMessage"></div>
<a class="im_message_reply_wrap" my-reply-message="draftMessage.replyToMessage" watch="true"></a>
</div>
<div class="im_send_field_wrap">
<div class="im_send_field_wrap" ng-class="historyState.replyKeyboard._ == 'replyKeyboardMarkup' ? 'im_send_field_wrap_2ndbtn' : ''">
<a class="composer_emoji_insert_btn"><i class="icon icon-emoji"></i></a>
<a class="composer_command_btn" ng-show="!historyState.replyKeyboard && commands.list.length > 0 && !draftMessage.text.length" ng-mousedown="enterSlash($event)"><i class="icon icon-slash"></i></a>
<a class="composer_command_btn" ng-show="!historyState.replyKeyboard && commands.list.length > 0 && !draftMessage.text.length || draftMessage.text[0] == '/'" ng-mousedown="toggleSlash($event)" ng-class="draftMessage.text[0] == '/' ? 'active' : ''"><i class="icon icon-slash"></i></a>
<a class="composer_keyboard_btn" ng-show="historyState.replyKeyboard._ == 'replyKeyboardMarkup'" ng-mousedown="replyKeyboardToggle($event)" ng-class="!historyState.replyKeyboard.pFlags.hidden ? 'active' : ''"><i class="icon icon-keyboard"></i></a>
<div class="im_send_dropbox_wrap" my-i18n="im_photos_drop_text"></div>

View File

@ -24,9 +24,7 @@
</div>
<div ng-switch-default class="im_content_message_wrap" ng-class="::[historyMessage.out ? 'im_message_out' : 'im_message_in', historyMessage.fwd_from_id > 0 ? 'im_message_fwd' : '']">
<div class="im_content_message_select_area">
<i class="icon icon-select-tick"></i>
</div>
<i class="icon icon-select-tick"></i>
<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>

View File

@ -22,12 +22,12 @@
</a>
</div>
<div class="media_modal_info_wrap pull-left" ng-if="!webpageID">
<div class="media_modal_info_wrap pull-left" ng-if="!webpageID && photo.user_id">
<a class="media_modal_author_photo pull-left" my-peer-photolink="photo.user_id" img-class="media_modal_author_photo" watch="true"></a>
<div class="media_modal_author_name">
<a class="media_modal_author" my-user-link="photo.user_id" user-watch="true"></a>
</div>
<div class="media_modal_date" ng-switch="messageID > 0">
<div class="media_modal_date" ng-if="photo.date > 0" ng-switch="messageID > 0">
<a ng-switch-when="true" class="media_modal_date" ng-click="goToMessage()" ng-bind="photo.date | dateOrTime :true"></a>
<span ng-switch-default ng-bind="photo.date | dateOrTime :true"></span>
</div>

View File

@ -8,6 +8,7 @@
class="im_message_reply_thumb"
my-load-thumb
thumb="thumb"
watch="true"
/>
</div>
<div class="im_message_reply_author" ng-switch-default>

View File

@ -16,12 +16,12 @@
</a>
</div>
<div class="media_modal_info_wrap pull-left" ng-switch="messageID > 0">
<div class="media_modal_info_wrap pull-left" ng-if="video.user_id > 0" ng-switch="messageID > 0">
<a class="media_modal_author_photo pull-left" my-peer-photolink="video.user_id" img-class="media_modal_author_photo" watch="true"></a>
<div class="media_modal_author_name">
<a class="media_modal_author" my-user-link="video.user_id" user-watch="true"></a>
</div>
<div class="media_modal_date">
<div class="media_modal_date" ng-if="video.date > 0">
<a ng-switch-when="true" class="media_modal_date" ng-click="goToMessage()" ng-bind="video.date | dateOrTime :true"></a>
<span ng-switch-default ng-bind="video.date | dateOrTime :true"></span>
</div>

View File

@ -12,7 +12,7 @@
</a>
</div>
<div class="media_modal_info_wrap">
<div class="media_modal_info_wrap" ng-if="photo.user_id > 0">
<a class="media_modal_author" my-user-link="photo.user_id" user-watch="true"></a>
<br/>
<span class="media_modal_date" ng-bind="photo.date | dateOrTime :true"></span>

View File

@ -12,7 +12,7 @@
</a>
</div>
<div class="media_modal_info_wrap">
<div class="media_modal_info_wrap" ng-if="video.user_id > 0">
<a class="media_modal_author" my-user-link="video.user_id" user-watch="true"></a>
<br/>
<span class="media_modal_date" ng-bind="video.date | dateOrTime :true"></span>