Merge branch 'master' into voice_recorder
This commit is contained in:
commit
c24bfc640d
1
app/img/Telegram.svg
Normal file
1
app/img/Telegram.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 5.2 KiB |
@ -7,6 +7,12 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
var extraModules = [];
|
||||||
|
if (Config.Modes.animations) {
|
||||||
|
extraModules.push('ngAnimate');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Declare app level module which depends on filters, and services
|
// Declare app level module which depends on filters, and services
|
||||||
angular.module('myApp', [
|
angular.module('myApp', [
|
||||||
'ngRoute',
|
'ngRoute',
|
||||||
@ -24,7 +30,7 @@ angular.module('myApp', [
|
|||||||
PRODUCTION_ONLY_END*/
|
PRODUCTION_ONLY_END*/
|
||||||
'myApp.directives',
|
'myApp.directives',
|
||||||
'myApp.controllers'
|
'myApp.controllers'
|
||||||
]).
|
].concat(extraModules)).
|
||||||
config(['$locationProvider', '$routeProvider', '$compileProvider', 'StorageProvider', function($locationProvider, $routeProvider, $compileProvider, StorageProvider) {
|
config(['$locationProvider', '$routeProvider', '$compileProvider', 'StorageProvider', function($locationProvider, $routeProvider, $compileProvider, StorageProvider) {
|
||||||
|
|
||||||
$compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|file|blob|filesystem|chrome-extension|app):|data:image\//);
|
$compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|file|blob|filesystem|chrome-extension|app):|data:image\//);
|
||||||
|
@ -1058,6 +1058,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
|
|||||||
$scope.selectedReply = selectedReply;
|
$scope.selectedReply = selectedReply;
|
||||||
$scope.selectedCancel = selectedCancel;
|
$scope.selectedCancel = selectedCancel;
|
||||||
$scope.selectedFlush = selectedFlush;
|
$scope.selectedFlush = selectedFlush;
|
||||||
|
$scope.selectInlineBot = selectInlineBot;
|
||||||
|
|
||||||
$scope.startBot = startBot;
|
$scope.startBot = startBot;
|
||||||
$scope.cancelBot = cancelBot;
|
$scope.cancelBot = cancelBot;
|
||||||
@ -1195,7 +1196,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
|
|||||||
$scope.historyState.typing.splice(0, $scope.historyState.typing.length);
|
$scope.historyState.typing.splice(0, $scope.historyState.typing.length);
|
||||||
$scope.$broadcast('ui_peer_change');
|
$scope.$broadcast('ui_peer_change');
|
||||||
$scope.$broadcast('ui_history_change');
|
$scope.$broadcast('ui_history_change');
|
||||||
safeReplaceObject($scope.state, {loaded: true, empty: !peerHistory.messages.length});
|
safeReplaceObject($scope.state, {loaded: true, empty: !peerHistory.messages.length, mayBeHasMore: true});
|
||||||
|
|
||||||
updateBotActions();
|
updateBotActions();
|
||||||
updateChannelActions();
|
updateChannelActions();
|
||||||
@ -1299,14 +1300,14 @@ angular.module('myApp.controllers', ['myApp.i18n'])
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lessPending = false;
|
lessPending = false;
|
||||||
lessActive = true;
|
$scope.state.lessActive = lessActive = true;
|
||||||
|
|
||||||
var curJump = jump,
|
var curJump = jump,
|
||||||
curLessJump = ++lessJump,
|
curLessJump = ++lessJump,
|
||||||
limit = 0,
|
limit = 0,
|
||||||
backLimit = 20;
|
backLimit = 20;
|
||||||
AppMessagesManager.getHistory($scope.curDialog.peerID, minID, limit, backLimit).then(function (historyResult) {
|
AppMessagesManager.getHistory($scope.curDialog.peerID, minID, limit, backLimit).then(function (historyResult) {
|
||||||
lessActive = false;
|
$scope.state.lessActive = lessActive = false;
|
||||||
if (curJump != jump || curLessJump != lessJump) return;
|
if (curJump != jump || curLessJump != lessJump) return;
|
||||||
|
|
||||||
var i, id;
|
var i, id;
|
||||||
@ -1347,7 +1348,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
morePending = false;
|
morePending = false;
|
||||||
moreActive = true;
|
$scope.state.moreActive = moreActive = true;
|
||||||
|
|
||||||
var curJump = jump,
|
var curJump = jump,
|
||||||
curMoreJump = ++moreJump,
|
curMoreJump = ++moreJump,
|
||||||
@ -1358,7 +1359,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
|
|||||||
: AppMessagesManager.getHistory($scope.curDialog.peerID, maxID, limit);
|
: AppMessagesManager.getHistory($scope.curDialog.peerID, maxID, limit);
|
||||||
|
|
||||||
getMessagesPromise.then(function (historyResult) {
|
getMessagesPromise.then(function (historyResult) {
|
||||||
moreActive = false;
|
$scope.state.moreActive = moreActive = false;
|
||||||
if (curJump != jump || curMoreJump != moreJump) return;
|
if (curJump != jump || curMoreJump != moreJump) return;
|
||||||
|
|
||||||
angular.forEach(historyResult.history, function (id) {
|
angular.forEach(historyResult.history, function (id) {
|
||||||
@ -1405,9 +1406,9 @@ angular.module('myApp.controllers', ['myApp.i18n'])
|
|||||||
limit = 10;
|
limit = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
moreActive = false;
|
$scope.state.moreActive = moreActive = false;
|
||||||
morePending = false;
|
morePending = false;
|
||||||
lessActive = false;
|
$scope.state.lessActive = lessActive = false;
|
||||||
lessPending = false;
|
lessPending = false;
|
||||||
|
|
||||||
var prerenderedLen = peerHistory.messages.length;
|
var prerenderedLen = peerHistory.messages.length;
|
||||||
@ -1550,23 +1551,31 @@ angular.module('myApp.controllers', ['myApp.i18n'])
|
|||||||
|
|
||||||
var target = $event.target;
|
var target = $event.target;
|
||||||
while (target) {
|
while (target) {
|
||||||
if (target.className.indexOf('im_message_outer_wrap') != -1) {
|
if (target instanceof SVGElement) {
|
||||||
|
target = target.parentNode;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (target.className && target.className.indexOf('im_message_outer_wrap') != -1) {
|
||||||
if (Config.Mobile) {
|
if (Config.Mobile) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (target.className &&
|
||||||
|
target.className.indexOf('im_message_date') != -1) {
|
||||||
|
if ($scope.historyState.canReply) {
|
||||||
|
selectedReply(messageID);
|
||||||
|
} else {
|
||||||
|
selectedForward(messageID);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (Config.Mobile &&
|
if (Config.Mobile &&
|
||||||
|
target.className &&
|
||||||
target.className.indexOf('im_message_body') != -1) {
|
target.className.indexOf('im_message_body') != -1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (target.tagName == 'A' ||
|
if (target.tagName == 'A' || hasOnlick(target)) {
|
||||||
target.onclick ||
|
|
||||||
target.getAttribute('ng-click')) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
var events = $._data(target, 'events');
|
|
||||||
if (events && (events.click || events.mousedown)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
target = target.parentNode;
|
target = target.parentNode;
|
||||||
@ -1651,6 +1660,11 @@ angular.module('myApp.controllers', ['myApp.i18n'])
|
|||||||
$scope.$broadcast('messages_select');
|
$scope.$broadcast('messages_select');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function selectInlineBot (botID, $event) {
|
||||||
|
$scope.$broadcast('inline_bot_select', botID);
|
||||||
|
return cancelEvent($event);
|
||||||
|
}
|
||||||
|
|
||||||
function selectedCancel (noBroadcast) {
|
function selectedCancel (noBroadcast) {
|
||||||
$scope.selectedMsgs = {};
|
$scope.selectedMsgs = {};
|
||||||
$scope.selectedCount = 0;
|
$scope.selectedCount = 0;
|
||||||
@ -2069,7 +2083,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
|
|||||||
$scope.$on('user_update', angular.noop);
|
$scope.$on('user_update', angular.noop);
|
||||||
})
|
})
|
||||||
|
|
||||||
.controller('AppImSendController', function ($scope, $timeout, MtpApiManager, Storage, AppProfileManager, AppChatsManager, AppUsersManager, AppPeersManager, AppDocsManager, AppMessagesManager, MtpApiFileManager, RichTextProcessor) {
|
.controller('AppImSendController', function ($scope, $timeout, MtpApiManager, Storage, AppProfileManager, AppChatsManager, AppUsersManager, AppPeersManager, AppDocsManager, AppMessagesManager, AppInlineBotsManager, MtpApiFileManager, RichTextProcessor) {
|
||||||
|
|
||||||
$scope.$watch('curDialog.peer', resetDraft);
|
$scope.$watch('curDialog.peer', resetDraft);
|
||||||
$scope.$on('user_update', angular.noop);
|
$scope.$on('user_update', angular.noop);
|
||||||
@ -2091,6 +2105,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
|
|||||||
$scope.$watch('draftMessage.files', onFilesSelected);
|
$scope.$watch('draftMessage.files', onFilesSelected);
|
||||||
$scope.$watch('draftMessage.sticker', onStickerSelected);
|
$scope.$watch('draftMessage.sticker', onStickerSelected);
|
||||||
$scope.$watch('draftMessage.command', onCommandSelected);
|
$scope.$watch('draftMessage.command', onCommandSelected);
|
||||||
|
$scope.$watch('draftMessage.inlineResultID', onInlineResultSelected);
|
||||||
|
|
||||||
$scope.$on('history_reply_markup', function (e, peerData) {
|
$scope.$on('history_reply_markup', function (e, peerData) {
|
||||||
if (peerData.peerID == $scope.curDialog.peerID) {
|
if (peerData.peerID == $scope.curDialog.peerID) {
|
||||||
@ -2098,6 +2113,12 @@ angular.module('myApp.controllers', ['myApp.i18n'])
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$scope.$on('inline_bot_select', function (e, botID) {
|
||||||
|
var bot = AppUsersManager.getUser(botID);
|
||||||
|
$scope.draftMessage.text = '@' + bot.username + ' ';;
|
||||||
|
$scope.$broadcast('ui_peer_draft', {focus: true});
|
||||||
|
});
|
||||||
|
|
||||||
$scope.replyKeyboardToggle = replyKeyboardToggle;
|
$scope.replyKeyboardToggle = replyKeyboardToggle;
|
||||||
$scope.toggleSlash = toggleSlash;
|
$scope.toggleSlash = toggleSlash;
|
||||||
|
|
||||||
@ -2250,6 +2271,9 @@ angular.module('myApp.controllers', ['myApp.i18n'])
|
|||||||
$scope.draftMessage.text = '';
|
$scope.draftMessage.text = '';
|
||||||
$scope.$broadcast('ui_peer_draft');
|
$scope.$broadcast('ui_peer_draft');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete $scope.draftMessage.inlineProgress;
|
||||||
|
$scope.$broadcast('inline_results', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyDraftAttachment (e, attachment) {
|
function applyDraftAttachment (e, attachment) {
|
||||||
@ -2394,6 +2418,60 @@ angular.module('myApp.controllers', ['myApp.i18n'])
|
|||||||
Storage.remove('draft' + $scope.curDialog.peerID);
|
Storage.remove('draft' + $scope.curDialog.peerID);
|
||||||
// console.log(dT(), 'draft delete', 'draft' + $scope.curDialog.peerID);
|
// console.log(dT(), 'draft delete', 'draft' + $scope.curDialog.peerID);
|
||||||
}
|
}
|
||||||
|
checkInlinePattern(newVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
var inlineUsernameRegex = /^@([a-zA-Z\d_]{1,32})( | )([\s\S]*)$/;
|
||||||
|
var getInlineResultsTO = false;
|
||||||
|
var jump = 0;
|
||||||
|
|
||||||
|
function checkInlinePattern (message) {
|
||||||
|
if (getInlineResultsTO) {
|
||||||
|
$timeout.cancel(getInlineResultsTO);
|
||||||
|
}
|
||||||
|
var curJump = ++jump;
|
||||||
|
if (!message || !message.length) {
|
||||||
|
delete $scope.draftMessage.inlineProgress;
|
||||||
|
$scope.$broadcast('inline_results', false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var matches = message.match(inlineUsernameRegex);
|
||||||
|
if (!matches) {
|
||||||
|
delete $scope.draftMessage.inlineProgress;
|
||||||
|
$scope.$broadcast('inline_results', false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var username = matches[1];
|
||||||
|
$scope.draftMessage.inlineProgress = true;
|
||||||
|
AppPeersManager.resolveInlineMention(username).then(function (inlineBot) {
|
||||||
|
if (curJump != jump) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$scope.$broadcast('inline_placeholder', {
|
||||||
|
prefix: '@' + username + matches[2],
|
||||||
|
placeholder: inlineBot.placeholder
|
||||||
|
});
|
||||||
|
if (getInlineResultsTO) {
|
||||||
|
$timeout.cancel(getInlineResultsTO);
|
||||||
|
}
|
||||||
|
getInlineResultsTO = $timeout(function () {
|
||||||
|
AppInlineBotsManager.getInlineResults(inlineBot.id, matches[3], '').then(function (botResults) {
|
||||||
|
getInlineResultsTO = false;
|
||||||
|
if (curJump != jump) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
botResults.text = message;
|
||||||
|
$scope.$broadcast('inline_results', botResults);
|
||||||
|
delete $scope.draftMessage.inlineProgress;
|
||||||
|
}, function () {
|
||||||
|
$scope.$broadcast('inline_results', false);
|
||||||
|
delete $scope.draftMessage.inlineProgress;
|
||||||
|
});
|
||||||
|
}, 500);
|
||||||
|
}, function () {
|
||||||
|
$scope.$broadcast('inline_results', false);
|
||||||
|
delete $scope.draftMessage.inlineProgress;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function onTyping () {
|
function onTyping () {
|
||||||
@ -2455,7 +2533,6 @@ angular.module('myApp.controllers', ['myApp.i18n'])
|
|||||||
fwdsSend();
|
fwdsSend();
|
||||||
}
|
}
|
||||||
delete $scope.draftMessage.sticker;
|
delete $scope.draftMessage.sticker;
|
||||||
resetDraft();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onCommandSelected (command) {
|
function onCommandSelected (command) {
|
||||||
@ -2467,6 +2544,25 @@ angular.module('myApp.controllers', ['myApp.i18n'])
|
|||||||
delete $scope.draftMessage.sticker;
|
delete $scope.draftMessage.sticker;
|
||||||
delete $scope.draftMessage.text;
|
delete $scope.draftMessage.text;
|
||||||
delete $scope.draftMessage.command;
|
delete $scope.draftMessage.command;
|
||||||
|
delete $scope.draftMessage.inlineResultID;
|
||||||
|
$scope.$broadcast('ui_message_send');
|
||||||
|
$scope.$broadcast('ui_peer_draft');
|
||||||
|
}
|
||||||
|
|
||||||
|
function onInlineResultSelected (qID) {
|
||||||
|
if (!qID) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var options = {
|
||||||
|
replyToMsgID: $scope.draftMessage.replyToMessage && $scope.draftMessage.replyToMessage.mid
|
||||||
|
};
|
||||||
|
AppInlineBotsManager.sendInlineResult($scope.curDialog.peerID, qID, options);
|
||||||
|
fwdsSend();
|
||||||
|
resetDraft();
|
||||||
|
delete $scope.draftMessage.sticker;
|
||||||
|
delete $scope.draftMessage.text;
|
||||||
|
delete $scope.draftMessage.command;
|
||||||
|
delete $scope.draftMessage.inlineResultID;
|
||||||
$scope.$broadcast('ui_message_send');
|
$scope.$broadcast('ui_message_send');
|
||||||
$scope.$broadcast('ui_peer_draft');
|
$scope.$broadcast('ui_peer_draft');
|
||||||
}
|
}
|
||||||
@ -4654,11 +4750,14 @@ angular.module('myApp.controllers', ['myApp.i18n'])
|
|||||||
.controller('StickersetModalController', function ($scope, $rootScope, $modalInstance, MtpApiManager, RichTextProcessor, AppStickersManager, AppDocsManager, AppMessagesManager, LocationParamsService) {
|
.controller('StickersetModalController', function ($scope, $rootScope, $modalInstance, MtpApiManager, RichTextProcessor, AppStickersManager, AppDocsManager, AppMessagesManager, LocationParamsService) {
|
||||||
$scope.slice = {limit: 20, limitDelta: 20};
|
$scope.slice = {limit: 20, limitDelta: 20};
|
||||||
|
|
||||||
|
var fullSet;
|
||||||
|
|
||||||
AppStickersManager.getStickerset($scope.inputStickerset).then(function (result) {
|
AppStickersManager.getStickerset($scope.inputStickerset).then(function (result) {
|
||||||
$scope.$broadcast('ui_height');
|
$scope.$broadcast('ui_height');
|
||||||
$scope.stickersetLoaded = true;
|
$scope.stickersetLoaded = true;
|
||||||
|
fullSet = result;
|
||||||
$scope.stickerset = result.set;
|
$scope.stickerset = result.set;
|
||||||
$scope.stickersetInstalled = result.installed;
|
$scope.stickersetInstalled = result.set.pFlags.installed == true;
|
||||||
$scope.documents = result.documents;
|
$scope.documents = result.documents;
|
||||||
|
|
||||||
$scope.stickerEmojis = {};
|
$scope.stickerEmojis = {};
|
||||||
@ -4673,7 +4772,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
|
|||||||
});
|
});
|
||||||
|
|
||||||
$scope.toggleInstalled = function (installed) {
|
$scope.toggleInstalled = function (installed) {
|
||||||
AppStickersManager.installStickerset($scope.stickerset, !installed).then(function () {
|
AppStickersManager.installStickerset(fullSet, !installed).then(function () {
|
||||||
$scope.stickersetInstalled = installed;
|
$scope.stickersetInstalled = installed;
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
@ -1099,6 +1099,7 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
historyEl = $('.im_history', element)[0],
|
historyEl = $('.im_history', element)[0],
|
||||||
scrollableWrap = $('.im_history_scrollable_wrap', element)[0],
|
scrollableWrap = $('.im_history_scrollable_wrap', element)[0],
|
||||||
scrollable = $('.im_history_scrollable', element)[0],
|
scrollable = $('.im_history_scrollable', element)[0],
|
||||||
|
emptyWrapEl = $('.im_history_empty_wrap', element)[0],
|
||||||
bottomPanelWrap = $('.im_bottom_panel_wrap', element)[0],
|
bottomPanelWrap = $('.im_bottom_panel_wrap', element)[0],
|
||||||
sendFormWrap = $('.im_send_form_wrap', element)[0],
|
sendFormWrap = $('.im_send_form_wrap', element)[0],
|
||||||
headWrap = $('.tg_page_head')[0],
|
headWrap = $('.tg_page_head')[0],
|
||||||
@ -1412,7 +1413,7 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
$(historyMessagesEl).css({marginTop: 0});
|
$(historyMessagesEl).css({marginTop: 0});
|
||||||
var marginTop = scrollableWrap.offsetHeight
|
var marginTop = scrollableWrap.offsetHeight
|
||||||
- historyMessagesEl.offsetHeight
|
- historyMessagesEl.offsetHeight
|
||||||
- 20
|
- emptyWrapEl.offsetHeight
|
||||||
- (Config.Mobile ? 0 : 39);
|
- (Config.Mobile ? 0 : 39);
|
||||||
|
|
||||||
if (historyMessagesEl.offsetHeight > 0 && marginTop > 0) {
|
if (historyMessagesEl.offsetHeight > 0 && marginTop > 0) {
|
||||||
@ -1429,8 +1430,7 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
.directive('mySendForm', function (_, $window, $compile, $modalStack, $http, $interpolate, Storage, AppStickersManager, AppDocsManager, ErrorService, shouldFocusOnInteraction) {
|
.directive('mySendForm', function (_, $timeout, $compile, $modalStack, $http, $interpolate, Storage, AppStickersManager, AppDocsManager, ErrorService, AppInlineBotsManager, shouldFocusOnInteraction) {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
link: link,
|
link: link,
|
||||||
scope: {
|
scope: {
|
||||||
@ -1497,6 +1497,11 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$scope.$on('stickers_changed', function () {
|
||||||
|
emojiTooltip.onStickersChanged();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
var composerEmojiPanel;
|
var composerEmojiPanel;
|
||||||
if (emojiPanel) {
|
if (emojiPanel) {
|
||||||
composerEmojiPanel = new EmojiPanel(emojiPanel, {
|
composerEmojiPanel = new EmojiPanel(emojiPanel, {
|
||||||
@ -1506,9 +1511,6 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var peerPhotoCompiled = $compile('<span class="composer_user_photo" my-peer-photolink="peerID" img-class="composer_user_photo"></span>');
|
|
||||||
var cachedPeerPhotos = {};
|
|
||||||
|
|
||||||
var composer = new MessageComposer(messageField, {
|
var composer = new MessageComposer(messageField, {
|
||||||
onTyping: function () {
|
onTyping: function () {
|
||||||
$scope.$emit('ui_typing');
|
$scope.$emit('ui_typing');
|
||||||
@ -1516,21 +1518,17 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
getSendOnEnter: function () {
|
getSendOnEnter: function () {
|
||||||
return sendOnEnter;
|
return sendOnEnter;
|
||||||
},
|
},
|
||||||
getPeerImage: function (element, peerID, noReplace) {
|
dropdownDirective: function (element, callback) {
|
||||||
if (cachedPeerPhotos[peerID] && !noReplace) {
|
|
||||||
element.replaceWith(cachedPeerPhotos[peerID]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var scope = $scope.$new(true);
|
var scope = $scope.$new(true);
|
||||||
scope.peerID = peerID;
|
var clonedElement = $compile('<div><div my-composer-dropdown></div></div>')(scope, function (clonedElement, scope) {
|
||||||
peerPhotoCompiled(scope, function (clonedElement) {
|
|
||||||
cachedPeerPhotos[peerID] = clonedElement;
|
|
||||||
element.replaceWith(clonedElement);
|
element.replaceWith(clonedElement);
|
||||||
|
callback(scope, clonedElement);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
mentions: $scope.mentions,
|
mentions: $scope.mentions,
|
||||||
commands: $scope.commands,
|
commands: $scope.commands,
|
||||||
onMessageSubmit: onMessageSubmit,
|
onMessageSubmit: onMessageSubmit,
|
||||||
|
onInlineResultSend: onInlineResultSend,
|
||||||
onFilePaste: onFilePaste,
|
onFilePaste: onFilePaste,
|
||||||
onCommandSend: function (command) {
|
onCommandSend: function (command) {
|
||||||
$scope.$apply(function () {
|
$scope.$apply(function () {
|
||||||
@ -1544,6 +1542,21 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
$(richTextarea).on('keydown keyup', updateHeight);
|
$(richTextarea).on('keydown keyup', updateHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$scope.$on('inline_results', function (e, inlineResults) {
|
||||||
|
if (inlineResults) {
|
||||||
|
var w = ((richTextarea || messageField).offsetWidth || 382) - 2;
|
||||||
|
var h = 80;
|
||||||
|
AppInlineBotsManager.regroupWrappedResults(inlineResults.results, w, h);
|
||||||
|
setZeroTimeout(function () {
|
||||||
|
composer.setInlineSuggestions(inlineResults);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$scope.$on('inline_placeholder', function(e, data) {
|
||||||
|
composer.setInlinePlaceholder(data.prefix, data.placeholder);
|
||||||
|
});
|
||||||
|
|
||||||
fileSelects.on('change', function () {
|
fileSelects.on('change', function () {
|
||||||
var self = this;
|
var self = this;
|
||||||
$scope.$apply(function () {
|
$scope.$apply(function () {
|
||||||
@ -1659,6 +1672,12 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
return cancelEvent(e);
|
return cancelEvent(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onInlineResultSend (qID) {
|
||||||
|
$scope.$apply(function () {
|
||||||
|
$scope.draftMessage.inlineResultID = qID;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function updateValue () {
|
function updateValue () {
|
||||||
if (richTextarea) {
|
if (richTextarea) {
|
||||||
composer.onChange();
|
composer.onChange();
|
||||||
@ -2063,7 +2082,7 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
.directive('myLoadGif', function(AppDocsManager) {
|
.directive('myLoadGif', function(AppDocsManager, $timeout) {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
link: link,
|
link: link,
|
||||||
@ -2082,6 +2101,15 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
|
|
||||||
$scope.isActive = false;
|
$scope.isActive = false;
|
||||||
|
|
||||||
|
// Demo
|
||||||
|
// $scope.document.progress = {enabled: true, percent: 30};
|
||||||
|
// $timeout(function () {
|
||||||
|
// $scope.document.progress.percent = 60;
|
||||||
|
// }, 3000);
|
||||||
|
// $timeout(function () {
|
||||||
|
// $scope.document.progress.percent = 100;
|
||||||
|
// }, 10000);
|
||||||
|
|
||||||
$scope.toggle = function (e) {
|
$scope.toggle = function (e) {
|
||||||
if (e && checkClick(e, true)) {
|
if (e && checkClick(e, true)) {
|
||||||
AppDocsManager.saveDocFile($scope.document.id);
|
AppDocsManager.saveDocFile($scope.document.id);
|
||||||
@ -2092,6 +2120,16 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
onContentLoaded(function () {
|
onContentLoaded(function () {
|
||||||
$scope.isActive = !$scope.isActive;
|
$scope.isActive = !$scope.isActive;
|
||||||
$scope.$emit('ui_height');
|
$scope.$emit('ui_height');
|
||||||
|
|
||||||
|
var video = $('video', element)[0];
|
||||||
|
if (video) {
|
||||||
|
if (!$scope.isActive) {
|
||||||
|
video.pause();
|
||||||
|
video.currentTime = 0;
|
||||||
|
} else {
|
||||||
|
video.play();
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2105,8 +2143,9 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
downloadPromise = AppDocsManager.downloadDoc($scope.document.id);
|
downloadPromise = AppDocsManager.downloadDoc($scope.document.id);
|
||||||
|
|
||||||
downloadPromise.then(function () {
|
downloadPromise.then(function () {
|
||||||
$scope.isActive = true;
|
$timeout(function () {
|
||||||
$scope.$emit('ui_height');
|
$scope.isActive = true;
|
||||||
|
}, 200);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2330,8 +2369,8 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
|
|
||||||
var src = 'https://maps.googleapis.com/maps/api/staticmap?sensor=false¢er=' + $scope.point['lat'] + ',' + $scope.point['long'] + '&zoom=15&size='+width+'x'+height+'&scale=2&key=' + apiKey;
|
var src = 'https://maps.googleapis.com/maps/api/staticmap?sensor=false¢er=' + $scope.point['lat'] + ',' + $scope.point['long'] + '&zoom=15&size='+width+'x'+height+'&scale=2&key=' + apiKey;
|
||||||
|
|
||||||
ExternalResourcesManager.downloadImage(src).then(function (url) {
|
ExternalResourcesManager.downloadByURL(src).then(function (url) {
|
||||||
element.attr('src', url);
|
element.attr('src', url.valueOf());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2831,7 +2870,7 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (element[0].tagName == 'A') {
|
if (element[0].tagName == 'A' && !hasOnlick(element[0])) {
|
||||||
element.on('click', function () {
|
element.on('click', function () {
|
||||||
if (peerID > 0) {
|
if (peerID > 0) {
|
||||||
AppUsersManager.openUser(peerID, override);
|
AppUsersManager.openUser(peerID, override);
|
||||||
@ -3317,44 +3356,67 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
})
|
})
|
||||||
|
|
||||||
.directive('myArcProgress', function () {
|
.directive('myArcProgress', function () {
|
||||||
var html = '<svg class="progress-arc" viewPort="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg"><circle class="progress-arc-circle" fill="transparent" stroke-dashoffset="0"></circle><circle class="progress-arc-bar" fill="transparent" stroke-dashoffset="0"></circle></svg>';
|
var html =
|
||||||
|
'<svg class="progress-arc" viewPort="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg">\
|
||||||
|
<defs>\
|
||||||
|
<linearGradient id="grad_intermediate%id%" x1="0%" y1="0%" x2="100%" y2="0%">\
|
||||||
|
<stop offset="0%" class="stop0" />\
|
||||||
|
<stop offset="60%" class="stop60" />\
|
||||||
|
<stop offset="100%" class="stop100"/>\
|
||||||
|
</linearGradient>\
|
||||||
|
</defs>\
|
||||||
|
<circle class="progress-arc-bar"></circle>\
|
||||||
|
</svg>';
|
||||||
|
|
||||||
|
function updateProgress (bar, progress, fullLen) {
|
||||||
|
progress = Math.max(0.0, Math.min(progress, 1.0));
|
||||||
|
var minProgress = 0.2;
|
||||||
|
progress = minProgress + (1 - minProgress) * progress;
|
||||||
|
bar.css({strokeDasharray: (progress * fullLen) + ', ' + ((1 - progress) * fullLen)});
|
||||||
|
}
|
||||||
|
|
||||||
|
var num = 0;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
scope: {
|
scope: {
|
||||||
progress: '=myArcProgress'
|
progress: '=myArcProgress'
|
||||||
},
|
},
|
||||||
link: function ($scope, element, attrs) {
|
link: function ($scope, element, attrs) {
|
||||||
element
|
var intermediate = !attrs.myArcProgress;
|
||||||
.html(html)
|
var width = attrs.width || element.width() || 40;
|
||||||
.addClass('progress-arc-wrap');
|
var stroke = attrs.stroke || (width / 2 * 0.14);
|
||||||
|
|
||||||
var svgEl = element[0].firstChild;
|
|
||||||
var circle = $('.progress-arc-circle', element);
|
|
||||||
var bar = $('.progress-arc-bar', element);
|
|
||||||
|
|
||||||
var width = attrs.width || 40;
|
|
||||||
var radius = width * 0.86;
|
|
||||||
var stroke = width * 0.14;
|
|
||||||
var center = width / 2;
|
var center = width / 2;
|
||||||
|
var radius = center - (stroke / 2);
|
||||||
|
|
||||||
$(svgEl).attr('width', width);
|
// Doesn't work without unique id for every gradient
|
||||||
$(svgEl).attr('height', width);
|
var curNum = ++num;
|
||||||
circle.attr('cx', center);
|
|
||||||
circle.attr('cy', center);
|
|
||||||
circle.attr('r', radius);
|
|
||||||
circle.css({strokeWidth: stroke});
|
|
||||||
|
|
||||||
bar.attr('cx', center);
|
element
|
||||||
bar.attr('cy', center);
|
.html(html.replace('%id%', curNum))
|
||||||
bar.attr('r', radius);
|
.addClass('progress-arc-wrap')
|
||||||
bar.css({strokeWidth: stroke});
|
.addClass(intermediate ? 'progress-arc-intermediate' : 'progress-arc-percent')
|
||||||
|
.css({width: width, height: width});
|
||||||
|
|
||||||
|
$(element[0].firstChild)
|
||||||
|
.attr('width', width)
|
||||||
|
.attr('height', width);
|
||||||
|
|
||||||
|
var bar = $('.progress-arc-bar', element);
|
||||||
|
bar
|
||||||
|
.attr('cx', center)
|
||||||
|
.attr('cy', center)
|
||||||
|
.attr('r', radius)
|
||||||
|
.css({strokeWidth: stroke});
|
||||||
|
|
||||||
var fullLen = 2 * Math.PI * radius;
|
var fullLen = 2 * Math.PI * radius;
|
||||||
$scope.$watch('progress', function (newProgress) {
|
if (intermediate) {
|
||||||
var progress = newProgress / 100.0;
|
updateProgress(bar, 0.3, fullLen);
|
||||||
progress = Math.max(0.0, Math.min(progress, 1.0));
|
bar.css({stroke: 'url(#grad_intermediate' + curNum + ')'});
|
||||||
bar.css({strokeDasharray: (progress * fullLen) + ', ' + ((1 - progress) * fullLen)});
|
} else {
|
||||||
});
|
$scope.$watch('progress', function (newProgress) {
|
||||||
|
updateProgress(bar, newProgress / 100.0, fullLen);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -3380,3 +3442,87 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
};
|
};
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
.directive('myComposerDropdown', function () {
|
||||||
|
|
||||||
|
return {
|
||||||
|
templateUrl: templateUrl('composer_dropdown')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
.directive('myEmojiSuggestions', function () {
|
||||||
|
|
||||||
|
return {
|
||||||
|
link: function($scope, element, attrs) {
|
||||||
|
$scope.$watchCollection('emojiCodes', function (codes) {
|
||||||
|
// var codes = $scope.$eval(attrs.myEmojiSuggestions);
|
||||||
|
var html = [];
|
||||||
|
var iconSize = Config.Mobile ? 26 : 20;
|
||||||
|
|
||||||
|
var emoticonCode, emoticonData, spritesheet, pos, categoryIndex;
|
||||||
|
var count = Math.min(5, codes.length);
|
||||||
|
var i, x, y;
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
emoticonCode = codes[i];
|
||||||
|
if (emoticonCode.code) {
|
||||||
|
emoticonCode = emoticonCode.code;
|
||||||
|
}
|
||||||
|
if (emoticonData = Config.Emoji[emoticonCode]) {
|
||||||
|
spritesheet = EmojiHelper.spritesheetPositions[emoticonCode];
|
||||||
|
categoryIndex = spritesheet[0];
|
||||||
|
pos = spritesheet[1];
|
||||||
|
x = iconSize * spritesheet[3];
|
||||||
|
y = iconSize * spritesheet[2];
|
||||||
|
html.push('<li><a class="composer_emoji_option" data-code="' + encodeEntities(emoticonCode) + '"><i class="emoji emoji-w', iconSize, ' emoji-spritesheet-' + categoryIndex + '" style="background-position: -' + x + 'px -' + y + 'px;"></i><span class="composer_emoji_shortcut">:' + encodeEntities(emoticonData[1][0]) + ':</span></a></li>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// onContentLoaded(function () {
|
||||||
|
element.html(html.join(''));
|
||||||
|
console.log(dT(), 'emoji done');
|
||||||
|
// });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
.directive('myInlineResults', function (AppPhotosManager, ExternalResourcesManager, AppDocsManager) {
|
||||||
|
|
||||||
|
return {
|
||||||
|
templateUrl: templateUrl('inline_results'),
|
||||||
|
scope: {
|
||||||
|
botResults: '=myInlineResults'
|
||||||
|
},
|
||||||
|
|
||||||
|
link: function ($scope, element, attrs) {
|
||||||
|
$scope.$watch('botResults.results', function (results) {
|
||||||
|
angular.forEach(results, function (result) {
|
||||||
|
if (result.thumb_url && !result.thumbUrl) {
|
||||||
|
ExternalResourcesManager.downloadByURL(result.thumb_url).then(function (url) {
|
||||||
|
result.thumbUrl = url;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (result.type == 'gif' && result.content_url && !result.contentUrl) {
|
||||||
|
ExternalResourcesManager.downloadByURL(result.content_url).then(function (url) {
|
||||||
|
result.contentUrl = url;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (result.type == 'gif' && result.document) {
|
||||||
|
AppDocsManager.downloadDoc(result.document.id);
|
||||||
|
}
|
||||||
|
if (result.type == 'photo' && result.photo) {
|
||||||
|
var photoSize = AppPhotosManager.choosePhotoSize(result.photo, result.thumbW, result.thumbH),
|
||||||
|
dim = calcImageInBox(photoSize.w, photoSize.h, result.thumbW, result.thumbH);
|
||||||
|
result.thumb = {
|
||||||
|
width: dim.w,
|
||||||
|
height: dim.h,
|
||||||
|
location: photoSize.location,
|
||||||
|
size: photoSize.size
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
@ -187,6 +187,9 @@ angular.module('myApp.filters', ['myApp.i18n'])
|
|||||||
.filter('formatSizeProgress', function ($filter, _) {
|
.filter('formatSizeProgress', function ($filter, _) {
|
||||||
var formatSizeFilter = $filter('formatSize');
|
var formatSizeFilter = $filter('formatSize');
|
||||||
return function (progress) {
|
return function (progress) {
|
||||||
|
if (!progress.total) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
var done = formatSizeFilter(progress.done, true),
|
var done = formatSizeFilter(progress.done, true),
|
||||||
doneParts = done.split(' '),
|
doneParts = done.split(' '),
|
||||||
total = formatSizeFilter(progress.total),
|
total = formatSizeFilter(progress.total),
|
||||||
|
@ -36,7 +36,9 @@ Config.Modes = {
|
|||||||
webcrypto: location.search.indexOf('webcrypto=0')== -1,
|
webcrypto: location.search.indexOf('webcrypto=0')== -1,
|
||||||
packed: location.protocol == 'app:' || location.protocol == 'chrome-extension:',
|
packed: location.protocol == 'app:' || location.protocol == 'chrome-extension:',
|
||||||
ios_standalone: window.navigator.standalone && navigator.userAgent.match(/iOS|iPhone|iPad/),
|
ios_standalone: window.navigator.standalone && navigator.userAgent.match(/iOS|iPhone|iPad/),
|
||||||
chrome_packed: window.chrome && chrome.app && chrome.app.window && true || false
|
chrome_packed: window.chrome && chrome.app && chrome.app.window && true || false,
|
||||||
|
animations: true,
|
||||||
|
memory_only: false
|
||||||
};
|
};
|
||||||
|
|
||||||
Config.Navigator = {
|
Config.Navigator = {
|
||||||
|
@ -384,11 +384,13 @@ angular.module('izhukov.mtproto.wrapper', ['izhukov.utils', 'izhukov.mtproto'])
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getFileStorage () {
|
function getFileStorage () {
|
||||||
if (TmpfsFileStorage.isAvailable()) {
|
if (!Config.Modes.memory_only) {
|
||||||
return TmpfsFileStorage;
|
if (TmpfsFileStorage.isAvailable()) {
|
||||||
}
|
return TmpfsFileStorage;
|
||||||
if (IdbFileStorage.isAvailable()) {
|
}
|
||||||
return IdbFileStorage;
|
if (IdbFileStorage.isAvailable()) {
|
||||||
|
return IdbFileStorage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return MemoryFileStorage;
|
return MemoryFileStorage;
|
||||||
}
|
}
|
||||||
|
@ -963,10 +963,10 @@ angular.module('izhukov.utils', [])
|
|||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
.service('ExternalResourcesManager', function ($q, $http) {
|
.service('ExternalResourcesManager', function ($q, $http, $sce) {
|
||||||
var urlPromises = {};
|
var urlPromises = {};
|
||||||
|
|
||||||
function downloadImage (url) {
|
function downloadByURL (url) {
|
||||||
if (urlPromises[url] !== undefined) {
|
if (urlPromises[url] !== undefined) {
|
||||||
return urlPromises[url];
|
return urlPromises[url];
|
||||||
}
|
}
|
||||||
@ -974,12 +974,18 @@ angular.module('izhukov.utils', [])
|
|||||||
return urlPromises[url] = $http.get(url, {responseType: 'blob', transformRequest: null})
|
return urlPromises[url] = $http.get(url, {responseType: 'blob', transformRequest: null})
|
||||||
.then(function (response) {
|
.then(function (response) {
|
||||||
window.URL = window.URL || window.webkitURL;
|
window.URL = window.URL || window.webkitURL;
|
||||||
return window.URL.createObjectURL(response.data);
|
var url = window.URL.createObjectURL(response.data);
|
||||||
|
return $sce.trustAsResourceUrl(url);
|
||||||
|
}, function (error) {
|
||||||
|
if (!Config.modes.chrome_packed) {
|
||||||
|
return $q.when($sce.trustAsResourceUrl(url));
|
||||||
|
}
|
||||||
|
return $q.reject(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
downloadImage: downloadImage
|
downloadByURL: downloadByURL
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -60,6 +60,18 @@ function cancelEvent (event) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hasOnlick (element) {
|
||||||
|
if (element.onclick ||
|
||||||
|
element.getAttribute('ng-click')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
var events = $._data(element, 'events');
|
||||||
|
if (events && (events.click || events.mousedown)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
function getScrollWidth() {
|
function getScrollWidth() {
|
||||||
var outer = $('<div>').css({
|
var outer = $('<div>').css({
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
@ -289,7 +301,21 @@ function scrollToNode (scrollable, node, scroller) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Config.Modes.animations &&
|
||||||
|
typeof window.requestAnimationFrame == 'function') {
|
||||||
|
window.onAnimationFrameCallback = function (cb) {
|
||||||
|
return (function () {
|
||||||
|
window.requestAnimationFrame(cb);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
window.onAnimationFrameCallback = function (cb) {
|
||||||
|
return cb;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function onContentLoaded (cb) {
|
function onContentLoaded (cb) {
|
||||||
|
cb = onAnimationFrameCallback(cb);
|
||||||
setZeroTimeout(cb);
|
setZeroTimeout(cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,6 +253,7 @@
|
|||||||
"conversation_media_video": "Video",
|
"conversation_media_video": "Video",
|
||||||
"conversation_media_document": "Datei",
|
"conversation_media_document": "Datei",
|
||||||
"conversation_media_sticker": "Sticker",
|
"conversation_media_sticker": "Sticker",
|
||||||
|
"conversation_media_gif": "GIF",
|
||||||
"conversation_media_audio": "Audio",
|
"conversation_media_audio": "Audio",
|
||||||
"conversation_media_location": "Standort",
|
"conversation_media_location": "Standort",
|
||||||
"conversation_media_contact": "Kontakt",
|
"conversation_media_contact": "Kontakt",
|
||||||
@ -472,7 +473,9 @@
|
|||||||
"password_recover_submit": "Absenden",
|
"password_recover_submit": "Absenden",
|
||||||
"login_controller_unknown_country": "Unbekannt",
|
"login_controller_unknown_country": "Unbekannt",
|
||||||
"message_forwarded_message": "Weitergeleitete Nachricht",
|
"message_forwarded_message": "Weitergeleitete Nachricht",
|
||||||
|
"message_via_bot": "via {bot}",
|
||||||
"message_forwarded_message_mobile": "Weitergeleitet von {from}, {date}",
|
"message_forwarded_message_mobile": "Weitergeleitet von {from}, {date}",
|
||||||
|
"message_forwarded_via_message_mobile": "Weitergeleitet von {from} via {bot}, {date}",
|
||||||
"message_attach_audio_message": "Sprachnachricht",
|
"message_attach_audio_message": "Sprachnachricht",
|
||||||
"message_attach_audio_play": "Abspielen",
|
"message_attach_audio_play": "Abspielen",
|
||||||
"message_attach_document_open": "Öffnen",
|
"message_attach_document_open": "Öffnen",
|
||||||
|
@ -253,6 +253,7 @@
|
|||||||
"conversation_media_video": "Video",
|
"conversation_media_video": "Video",
|
||||||
"conversation_media_document": "File",
|
"conversation_media_document": "File",
|
||||||
"conversation_media_sticker": "Sticker",
|
"conversation_media_sticker": "Sticker",
|
||||||
|
"conversation_media_gif": "GIF",
|
||||||
"conversation_media_audio": "Audio",
|
"conversation_media_audio": "Audio",
|
||||||
"conversation_media_location": "Posizione",
|
"conversation_media_location": "Posizione",
|
||||||
"conversation_media_contact": "Contatto",
|
"conversation_media_contact": "Contatto",
|
||||||
@ -472,7 +473,9 @@
|
|||||||
"password_recover_submit": "Invia",
|
"password_recover_submit": "Invia",
|
||||||
"login_controller_unknown_country": "Sconosciuto",
|
"login_controller_unknown_country": "Sconosciuto",
|
||||||
"message_forwarded_message": "Messaggio inoltrato",
|
"message_forwarded_message": "Messaggio inoltrato",
|
||||||
|
"message_via_bot": "via {bot}",
|
||||||
"message_forwarded_message_mobile": "Inoltrato da {from},{date}",
|
"message_forwarded_message_mobile": "Inoltrato da {from},{date}",
|
||||||
|
"message_forwarded_via_message_mobile": "Inoltrato da {from} via {bot}, {date}",
|
||||||
"message_attach_audio_message": "Nota vocale",
|
"message_attach_audio_message": "Nota vocale",
|
||||||
"message_attach_audio_play": "Riproduci",
|
"message_attach_audio_play": "Riproduci",
|
||||||
"message_attach_document_open": "Apri",
|
"message_attach_document_open": "Apri",
|
||||||
|
@ -253,6 +253,7 @@
|
|||||||
"conversation_media_video": "Vídeo",
|
"conversation_media_video": "Vídeo",
|
||||||
"conversation_media_document": "Arquivo",
|
"conversation_media_document": "Arquivo",
|
||||||
"conversation_media_sticker": "Sticker",
|
"conversation_media_sticker": "Sticker",
|
||||||
|
"conversation_media_gif": "GIF",
|
||||||
"conversation_media_audio": "Áudio",
|
"conversation_media_audio": "Áudio",
|
||||||
"conversation_media_location": "Localização",
|
"conversation_media_location": "Localização",
|
||||||
"conversation_media_contact": "Contato",
|
"conversation_media_contact": "Contato",
|
||||||
@ -472,7 +473,9 @@
|
|||||||
"password_recover_submit": "Enviar",
|
"password_recover_submit": "Enviar",
|
||||||
"login_controller_unknown_country": "Desconhecido",
|
"login_controller_unknown_country": "Desconhecido",
|
||||||
"message_forwarded_message": "Encaminhar mensagem",
|
"message_forwarded_message": "Encaminhar mensagem",
|
||||||
|
"message_via_bot": "via {bot}",
|
||||||
"message_forwarded_message_mobile": "Encaminhado de {from}, {date}",
|
"message_forwarded_message_mobile": "Encaminhado de {from}, {date}",
|
||||||
|
"message_forwarded_via_message_mobile": "Encaminhado de {from} via {bot}, {date}",
|
||||||
"message_attach_audio_message": "Mensagem de voz",
|
"message_attach_audio_message": "Mensagem de voz",
|
||||||
"message_attach_audio_play": "Tocar",
|
"message_attach_audio_play": "Tocar",
|
||||||
"message_attach_document_open": "Abrir",
|
"message_attach_document_open": "Abrir",
|
||||||
|
@ -251,8 +251,9 @@
|
|||||||
"conversation_you": "Вы",
|
"conversation_you": "Вы",
|
||||||
"conversation_media_photo": "Фотография",
|
"conversation_media_photo": "Фотография",
|
||||||
"conversation_media_video": "Видео",
|
"conversation_media_video": "Видео",
|
||||||
"conversation_media_document": "File",
|
"conversation_media_document": "Файл",
|
||||||
"conversation_media_sticker": "Стикер",
|
"conversation_media_sticker": "Стикер",
|
||||||
|
"conversation_media_gif": "GIF",
|
||||||
"conversation_media_audio": "Аудио",
|
"conversation_media_audio": "Аудио",
|
||||||
"conversation_media_location": "Местоположение",
|
"conversation_media_location": "Местоположение",
|
||||||
"conversation_media_contact": "Контакт",
|
"conversation_media_contact": "Контакт",
|
||||||
@ -357,7 +358,7 @@
|
|||||||
"head_edit_messages": "Редактировать сообщения",
|
"head_edit_messages": "Редактировать сообщения",
|
||||||
"head_media_photos": "Фотографии",
|
"head_media_photos": "Фотографии",
|
||||||
"head_media_video": "Видео",
|
"head_media_video": "Видео",
|
||||||
"head_media_documents": "Files",
|
"head_media_documents": "Файлы",
|
||||||
"head_media_audio": "Голосовые сообщения",
|
"head_media_audio": "Голосовые сообщения",
|
||||||
"head_about": "О приложении",
|
"head_about": "О приложении",
|
||||||
"head_clear_all": "Очистить всё",
|
"head_clear_all": "Очистить всё",
|
||||||
@ -393,7 +394,7 @@
|
|||||||
"im_media": "Медиа",
|
"im_media": "Медиа",
|
||||||
"im_media_photos": "Фотографии",
|
"im_media_photos": "Фотографии",
|
||||||
"im_media_video": "Видео",
|
"im_media_video": "Видео",
|
||||||
"im_media_documents": "Files",
|
"im_media_documents": "Файлы",
|
||||||
"im_media_audio": "Голосовые сообщения",
|
"im_media_audio": "Голосовые сообщения",
|
||||||
"im_pluralize_participants": "{'one': '{} участник', 'few': '{} участника', 'many': '{} участников', 'other': '{} участников'}",
|
"im_pluralize_participants": "{'one': '{} участник', 'few': '{} участника', 'many': '{} участников', 'other': '{} участников'}",
|
||||||
"im_show_recent_messages": "Показать последние сообщения",
|
"im_show_recent_messages": "Показать последние сообщения",
|
||||||
@ -472,7 +473,9 @@
|
|||||||
"password_recover_submit": "Отправить",
|
"password_recover_submit": "Отправить",
|
||||||
"login_controller_unknown_country": "Неизвестно",
|
"login_controller_unknown_country": "Неизвестно",
|
||||||
"message_forwarded_message": "Пересланное сообщение",
|
"message_forwarded_message": "Пересланное сообщение",
|
||||||
|
"message_via_bot": "via {bot}",
|
||||||
"message_forwarded_message_mobile": "Переслано от {from}, {date}",
|
"message_forwarded_message_mobile": "Переслано от {from}, {date}",
|
||||||
|
"message_forwarded_via_message_mobile": "Forwarded from {from} via {bot}, {date}",
|
||||||
"message_attach_audio_message": "Запись голоса",
|
"message_attach_audio_message": "Запись голоса",
|
||||||
"message_attach_audio_play": "Воспроизвести",
|
"message_attach_audio_play": "Воспроизвести",
|
||||||
"message_attach_document_open": "Открыть",
|
"message_attach_document_open": "Открыть",
|
||||||
|
@ -364,7 +364,7 @@ EmojiTooltip.prototype.createTooltip = function () {
|
|||||||
|
|
||||||
|
|
||||||
EmojiTooltip.prototype.selectCategory = function (cat, force) {
|
EmojiTooltip.prototype.selectCategory = function (cat, force) {
|
||||||
if (this.cat === cat && !force) {
|
if (!this.tab && this.cat === cat && !force) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$('.active', this.categoriesEl).removeClass('active');
|
$('.active', this.categoriesEl).removeClass('active');
|
||||||
@ -566,6 +566,12 @@ EmojiTooltip.prototype.onStickersScroll = function (scrollable, scrollTop) {
|
|||||||
this.activateStickerCategory();
|
this.activateStickerCategory();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
EmojiTooltip.prototype.onStickersChanged = function () {
|
||||||
|
if (this.tab) {
|
||||||
|
this.updateStickersContents(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
EmojiTooltip.prototype.activateStickerCategory = function () {
|
EmojiTooltip.prototype.activateStickerCategory = function () {
|
||||||
var categoriesEl = this.categoriesEl[1];
|
var categoriesEl = this.categoriesEl[1];
|
||||||
var categoryEl = categoriesEl.childNodes[this.cat];
|
var categoryEl = categoriesEl.childNodes[this.cat];
|
||||||
@ -668,19 +674,77 @@ EmojiPanel.prototype.update = function () {
|
|||||||
|
|
||||||
|
|
||||||
function MessageComposer (textarea, options) {
|
function MessageComposer (textarea, options) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
this.textareaEl = $(textarea);
|
this.textareaEl = $(textarea);
|
||||||
|
|
||||||
this.setUpInput();
|
this.setUpInput();
|
||||||
|
|
||||||
this.autoCompleteWrapEl = $('<div class="composer_dropdown_wrap"></div>').appendTo(document.body);
|
this.autoCompleteWrapEl = $('<div class="composer_dropdown_wrap"></div>').appendTo(document.body);
|
||||||
this.autoCompleteEl = $('<ul class="composer_dropdown dropdown-menu"></ul>').appendTo(this.autoCompleteWrapEl);
|
var autoCompleteEl = $('<div></div>').appendTo(this.autoCompleteWrapEl);
|
||||||
|
|
||||||
|
options.dropdownDirective(autoCompleteEl, function (scope, newAutoCompleteEl) {
|
||||||
|
self.autoCompleteEl = newAutoCompleteEl;
|
||||||
|
self.autoCompleteScope = scope;
|
||||||
|
self.setUpAutoComplete();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.isActive = false;
|
||||||
|
|
||||||
|
this.onTyping = options.onTyping;
|
||||||
|
this.onMessageSubmit = options.onMessageSubmit;
|
||||||
|
this.getSendOnEnter = options.getSendOnEnter;
|
||||||
|
this.onFilePaste = options.onFilePaste;
|
||||||
|
this.onCommandSend = options.onCommandSend;
|
||||||
|
this.onInlineResultSend = options.onInlineResultSend;
|
||||||
|
this.mentions = options.mentions;
|
||||||
|
this.commands = options.commands;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageComposer.autoCompleteRegEx = /(\s|^)(:|@|\/)([A-Za-z0-9\-\+\*@_]*)$/;
|
||||||
|
|
||||||
|
|
||||||
|
MessageComposer.prototype.setUpInput = function () {
|
||||||
|
this.inlinePlaceholderWrap = $('<div class="im_inline_placeholder_wrap"></div>').prependTo(this.textareaEl[0].parentNode);
|
||||||
|
this.inlinePlaceholderPrefixEl = $('<span class="im_inline_placeholder_prefix"></span>').appendTo(this.inlinePlaceholderWrap);
|
||||||
|
this.inlinePlaceholderEl = $('<span class="im_inline_placeholder"></span>').appendTo(this.inlinePlaceholderWrap);
|
||||||
|
|
||||||
|
if ('contentEditable' in document.body) {
|
||||||
|
this.setUpRich();
|
||||||
|
} else {
|
||||||
|
this.setUpPlaintext();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Config.Mobile) {
|
||||||
|
var sbWidth = getScrollWidth();
|
||||||
|
if (sbWidth) {
|
||||||
|
(this.richTextareaEl || this.textareaEl).css({marginRight: -sbWidth});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageComposer.prototype.setInlinePlaceholder = function (prefix, placeholder) {
|
||||||
|
this.inlinePlaceholderPrefix = prefix
|
||||||
|
this.inlinePlaceholderPrefixEl.html(encodeEntities(prefix));
|
||||||
|
this.inlinePlaceholderEl.html(encodeEntities(placeholder));
|
||||||
|
this.onChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageComposer.prototype.updateInlinePlaceholder = function () {
|
||||||
|
var prefix = this.inlinePlaceholderPrefix;
|
||||||
|
if (prefix) {
|
||||||
|
var value = this.textareaEl.val();
|
||||||
|
this.inlinePlaceholderWrap.toggleClass('active', value == prefix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageComposer.prototype.setUpAutoComplete = function () {
|
||||||
this.scroller = new Scroller(this.autoCompleteEl, {maxHeight: 180});
|
this.scroller = new Scroller(this.autoCompleteEl, {maxHeight: 180});
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
this.autoCompleteEl.on('mousedown', function (e) {
|
this.autoCompleteEl.on('mousedown', function (e) {
|
||||||
e = e.originalEvent || e;
|
e = e.originalEvent || e;
|
||||||
var target = $(e.target), mention, code, command;
|
var target = $(e.target), mention, code, command, inlineID;
|
||||||
if (target[0].tagName != 'A') {
|
if (target[0].tagName != 'A') {
|
||||||
target = $(target[0].parentNode);
|
target = $(target[0].parentNode);
|
||||||
}
|
}
|
||||||
@ -699,37 +763,14 @@ function MessageComposer (textarea, options) {
|
|||||||
}
|
}
|
||||||
self.hideSuggestions();
|
self.hideSuggestions();
|
||||||
}
|
}
|
||||||
|
if (inlineID = target.attr('data-inlineid')) {
|
||||||
|
if (self.onInlineResultSend) {
|
||||||
|
self.onInlineResultSend(inlineID);
|
||||||
|
}
|
||||||
|
self.hideSuggestions();
|
||||||
|
}
|
||||||
return cancelEvent(e);
|
return cancelEvent(e);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.isActive = false;
|
|
||||||
|
|
||||||
this.onTyping = options.onTyping;
|
|
||||||
this.onMessageSubmit = options.onMessageSubmit;
|
|
||||||
this.getSendOnEnter = options.getSendOnEnter;
|
|
||||||
this.onFilePaste = options.onFilePaste;
|
|
||||||
this.mentions = options.mentions;
|
|
||||||
this.commands = options.commands;
|
|
||||||
this.getPeerImage = options.getPeerImage;
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Config.Mobile) {
|
|
||||||
var sbWidth = getScrollWidth();
|
|
||||||
if (sbWidth) {
|
|
||||||
(this.richTextareaEl || this.textareaEl).css({marginRight: -sbWidth});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageComposer.prototype.setUpRich = function () {
|
MessageComposer.prototype.setUpRich = function () {
|
||||||
@ -763,7 +804,7 @@ MessageComposer.prototype.onKeyEvent = function (e) {
|
|||||||
if (this.keyupStarted === undefined) {
|
if (this.keyupStarted === undefined) {
|
||||||
this.keyupStarted = now;
|
this.keyupStarted = now;
|
||||||
}
|
}
|
||||||
if (now - this.keyupStarted > 10000) {
|
if (now - this.keyupStarted > 3000 || true) {
|
||||||
this.onChange();
|
this.onChange();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -771,6 +812,8 @@ MessageComposer.prototype.onKeyEvent = function (e) {
|
|||||||
if (this.wasEmpty != !length) {
|
if (this.wasEmpty != !length) {
|
||||||
this.wasEmpty = !this.wasEmpty;
|
this.wasEmpty = !this.wasEmpty;
|
||||||
this.onChange();
|
this.onChange();
|
||||||
|
} else if (this.inlinePlaceholderPrefix) {
|
||||||
|
this.onChange();
|
||||||
} else {
|
} else {
|
||||||
this.updateValueTO = setTimeout(this.onChange.bind(this), 1000);
|
this.updateValueTO = setTimeout(this.onChange.bind(this), 1000);
|
||||||
}
|
}
|
||||||
@ -797,48 +840,57 @@ MessageComposer.prototype.onKeyEvent = function (e) {
|
|||||||
if (this.autocompleteShown) {
|
if (this.autocompleteShown) {
|
||||||
if (e.keyCode == 38 || e.keyCode == 40) { // UP / DOWN
|
if (e.keyCode == 38 || e.keyCode == 40) { // UP / DOWN
|
||||||
var next = e.keyCode == 40;
|
var next = e.keyCode == 40;
|
||||||
var currentSelected = $(this.autoCompleteEl).find('.composer_autocomplete_option_active');
|
var currentSel = $(this.autoCompleteEl).find('li.composer_autocomplete_option_active');
|
||||||
|
var allLIs = Array.prototype.slice.call($(this.autoCompleteEl).find('li'));
|
||||||
|
var nextSel;
|
||||||
|
|
||||||
if (currentSelected.length) {
|
if (currentSel.length) {
|
||||||
var currentSelectedWrap = currentSelected[0].parentNode;
|
var pos = allLIs.indexOf(currentSel[0]);
|
||||||
var nextWrap = currentSelectedWrap[next ? 'nextSibling' : 'previousSibling'];
|
var nextPos = pos + (next ? 1 : -1);
|
||||||
currentSelected.removeClass('composer_autocomplete_option_active');
|
nextSel = allLIs[nextPos];
|
||||||
if (nextWrap) {
|
currentSel.removeClass('composer_autocomplete_option_active');
|
||||||
$(nextWrap).find('a').addClass('composer_autocomplete_option_active');
|
if (nextSel) {
|
||||||
this.scroller.scrollToNode(nextWrap);
|
$(nextSel).addClass('composer_autocomplete_option_active');
|
||||||
|
this.scroller.scrollToNode(nextSel);
|
||||||
return cancelEvent(e);
|
return cancelEvent(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var childNodes = this.autoCompleteEl[0].childNodes;
|
nextSel = allLIs[next ? 0 : allLIs.length - 1];
|
||||||
var nextWrap = childNodes[next ? 0 : childNodes.length - 1];
|
this.scroller.scrollToNode(nextSel);
|
||||||
this.scroller.scrollToNode(nextWrap);
|
$(nextSel).addClass('composer_autocomplete_option_active');
|
||||||
$(nextWrap).find('a').addClass('composer_autocomplete_option_active');
|
|
||||||
|
|
||||||
return cancelEvent(e);
|
return cancelEvent(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.keyCode == 13 || e.keyCode == 9) { // Enter or Tab
|
if (e.keyCode == 13 || e.keyCode == 9) { // Enter or Tab
|
||||||
var currentSelected = $(this.autoCompleteEl).find('.composer_autocomplete_option_active');
|
var currentSel = $(this.autoCompleteEl).find('li.composer_autocomplete_option_active');
|
||||||
if (!currentSelected.length && e.keyCode == 9) {
|
if (!currentSel.length && e.keyCode == 9) {
|
||||||
currentSelected = $(this.autoCompleteEl[0].childNodes[0]).find('a');
|
currentSel = $(this.autoCompleteEl).find('li:first');
|
||||||
}
|
}
|
||||||
var code, mention, command;
|
currentSel = currentSel.find('a:first');
|
||||||
if (code = currentSelected.attr('data-code')) {
|
var code, mention, command, inlineID;
|
||||||
|
if (code = currentSel.attr('data-code')) {
|
||||||
this.onEmojiSelected(code, true);
|
this.onEmojiSelected(code, true);
|
||||||
EmojiHelper.pushPopularEmoji(code);
|
EmojiHelper.pushPopularEmoji(code);
|
||||||
return cancelEvent(e);
|
return cancelEvent(e);
|
||||||
}
|
}
|
||||||
if (mention = currentSelected.attr('data-mention')) {
|
if (mention = currentSel.attr('data-mention')) {
|
||||||
this.onMentionSelected(mention);
|
this.onMentionSelected(mention);
|
||||||
return cancelEvent(e);
|
return cancelEvent(e);
|
||||||
}
|
}
|
||||||
if (command = currentSelected.attr('data-command')) {
|
if (command = currentSel.attr('data-command')) {
|
||||||
if (this.onCommandSelected) {
|
if (this.onCommandSelected) {
|
||||||
this.onCommandSelected(command, e.keyCode == 9);
|
this.onCommandSelected(command, e.keyCode == 9);
|
||||||
}
|
}
|
||||||
return cancelEvent(e);
|
return cancelEvent(e);
|
||||||
}
|
}
|
||||||
|
if (inlineID = currentSel.attr('data-inlineid')) {
|
||||||
|
if (self.onInlineResultSend) {
|
||||||
|
self.onInlineResultSend(inlineID);
|
||||||
|
}
|
||||||
|
return cancelEvent(e);
|
||||||
|
}
|
||||||
checkSubmit = true;
|
checkSubmit = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -918,6 +970,13 @@ MessageComposer.prototype.checkAutocomplete = function (forceFull) {
|
|||||||
var value = textarea.value;
|
var value = textarea.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (value &&
|
||||||
|
this.curInlineResults &&
|
||||||
|
this.curInlineResults.text == value) {
|
||||||
|
this.showInlineSuggestions(this.curInlineResults);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
if (!forceFull) {
|
if (!forceFull) {
|
||||||
value = value.substr(0, pos);
|
value = value.substr(0, pos);
|
||||||
}
|
}
|
||||||
@ -1268,6 +1327,7 @@ MessageComposer.prototype.onChange = function (e) {
|
|||||||
delete this.keyupStarted;
|
delete this.keyupStarted;
|
||||||
this.textareaEl.val(getRichValue(this.richTextareaEl[0])).trigger('change');
|
this.textareaEl.val(getRichValue(this.richTextareaEl[0])).trigger('change');
|
||||||
}
|
}
|
||||||
|
this.updateInlinePlaceholder();
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageComposer.prototype.getEmojiHtml = function (code, emoji) {
|
MessageComposer.prototype.getEmojiHtml = function (code, emoji) {
|
||||||
@ -1347,8 +1407,7 @@ MessageComposer.prototype.blur = function () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageComposer.prototype.renderSuggestions = function (html) {
|
MessageComposer.prototype.renderSuggestions = function () {
|
||||||
this.autoCompleteEl.html(html.join(''));
|
|
||||||
this.autoCompleteWrapEl.show();
|
this.autoCompleteWrapEl.show();
|
||||||
this.scroller.reinit();
|
this.scroller.reinit();
|
||||||
this.updatePosition();
|
this.updatePosition();
|
||||||
@ -1356,75 +1415,66 @@ MessageComposer.prototype.renderSuggestions = function (html) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MessageComposer.prototype.showEmojiSuggestions = function (codes) {
|
MessageComposer.prototype.showEmojiSuggestions = function (codes) {
|
||||||
var html = [];
|
var self = this;
|
||||||
var iconSize = Config.Mobile ? 26 : 20;
|
setZeroTimeout(function () {
|
||||||
|
self.autoCompleteScope.$apply(function () {
|
||||||
var emoticonCode, emoticonData, spritesheet, pos, categoryIndex;
|
self.autoCompleteScope.type = 'emoji';
|
||||||
var count = Math.min(5, codes.length);
|
self.autoCompleteScope.emojiCodes = codes;
|
||||||
var i, x, y;
|
});
|
||||||
|
onContentLoaded(function () {
|
||||||
for (i = 0; i < count; i++) {
|
self.renderSuggestions();
|
||||||
emoticonCode = codes[i];
|
});
|
||||||
if (emoticonCode.code) {
|
});
|
||||||
emoticonCode = emoticonCode.code;
|
|
||||||
}
|
|
||||||
if (emoticonData = Config.Emoji[emoticonCode]) {
|
|
||||||
spritesheet = EmojiHelper.spritesheetPositions[emoticonCode];
|
|
||||||
categoryIndex = spritesheet[0];
|
|
||||||
pos = spritesheet[1];
|
|
||||||
x = iconSize * spritesheet[3];
|
|
||||||
y = iconSize * spritesheet[2];
|
|
||||||
html.push('<li><a class="composer_emoji_option" data-code="' + encodeEntities(emoticonCode) + '"><i class="emoji emoji-w', iconSize, ' emoji-spritesheet-' + categoryIndex + '" style="background-position: -' + x + 'px -' + y + 'px;"></i><span class="composer_emoji_shortcut">:' + encodeEntities(emoticonData[1][0]) + ':</span></a></li>');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.renderSuggestions(html);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageComposer.prototype.showMentionSuggestions = function (users) {
|
MessageComposer.prototype.showMentionSuggestions = function (users) {
|
||||||
var html = [];
|
|
||||||
var user;
|
|
||||||
var count = users.length;
|
|
||||||
var i;
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
user = users[i];
|
|
||||||
html.push('<li><a class="composer_mention_option" data-mention="' + user.username + '"><span class="composer_user_photo" data-user-id="' + user.id + '"></span><span class="composer_user_name">' + user.rFullName + '</span><span class="composer_user_mention">@' + user.username + '</span></a></li>');
|
|
||||||
}
|
|
||||||
|
|
||||||
this.renderSuggestions(html);
|
|
||||||
var self = this;
|
var self = this;
|
||||||
this.autoCompleteEl.find('.composer_user_photo').each(function (k, element) {
|
setZeroTimeout(function () {
|
||||||
self.getPeerImage($(element), element.getAttribute('data-user-id'));
|
self.autoCompleteScope.$apply(function () {
|
||||||
|
self.autoCompleteScope.type = 'mentions';
|
||||||
|
self.autoCompleteScope.mentionUsers = users;
|
||||||
|
});
|
||||||
|
onContentLoaded(function () {
|
||||||
|
self.renderSuggestions();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageComposer.prototype.showCommandsSuggestions = function (commands) {
|
MessageComposer.prototype.showCommandsSuggestions = function (commands) {
|
||||||
var html = [];
|
|
||||||
var command;
|
|
||||||
var count = Math.min(200, commands.length);
|
|
||||||
var i;
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
command = commands[i];
|
|
||||||
html.push('<li><a class="composer_command_option" data-command="' + encodeEntities(command.value) + '"><span class="composer_user_photo" data-user-id="' + command.botID + '"></span><span class="composer_command_value">' + encodeEntities(command.value) + '</span><span class="composer_command_desc">' + command.rDescription + '</span></a></li>');
|
|
||||||
}
|
|
||||||
|
|
||||||
this.renderSuggestions(html);
|
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
var usedImages = {};
|
setZeroTimeout(function () {
|
||||||
this.autoCompleteEl.find('.composer_user_photo').each(function (k, element) {
|
self.autoCompleteScope.$apply(function () {
|
||||||
var noReplace = true;
|
self.autoCompleteScope.type = 'commands';
|
||||||
var botID = element.getAttribute('data-user-id');
|
self.autoCompleteScope.commands = commands;
|
||||||
if (!usedImages[botID]) {
|
});
|
||||||
usedImages[botID] = true;
|
onContentLoaded(function () {
|
||||||
noReplace = false;
|
self.renderSuggestions();
|
||||||
}
|
});
|
||||||
self.getPeerImage($(element), botID, noReplace);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MessageComposer.prototype.showInlineSuggestions = function (botResults) {
|
||||||
|
if (!botResults || !botResults.results.length) {
|
||||||
|
this.hideSuggestions();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var self = this;
|
||||||
|
setZeroTimeout(function () {
|
||||||
|
self.autoCompleteScope.$apply(function () {
|
||||||
|
self.autoCompleteScope.type = 'inline';
|
||||||
|
self.autoCompleteScope.botResults = botResults;
|
||||||
|
});
|
||||||
|
onContentLoaded(function () {
|
||||||
|
self.renderSuggestions();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageComposer.prototype.setInlineSuggestions = function (botResults) {
|
||||||
|
this.curInlineResults = botResults;
|
||||||
|
this.checkAutocomplete();
|
||||||
|
}
|
||||||
|
|
||||||
MessageComposer.prototype.updatePosition = function () {
|
MessageComposer.prototype.updatePosition = function () {
|
||||||
var offset = (this.richTextareaEl || this.textareaEl).offset();
|
var offset = (this.richTextareaEl || this.textareaEl).offset();
|
||||||
var height = this.scroller.updateHeight();
|
var height = this.scroller.updateHeight();
|
||||||
@ -1438,6 +1488,8 @@ MessageComposer.prototype.updatePosition = function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MessageComposer.prototype.hideSuggestions = function () {
|
MessageComposer.prototype.hideSuggestions = function () {
|
||||||
|
// console.trace();
|
||||||
|
// return;
|
||||||
this.autoCompleteWrapEl.hide();
|
this.autoCompleteWrapEl.hide();
|
||||||
delete this.autocompleteShown;
|
delete this.autocompleteShown;
|
||||||
}
|
}
|
||||||
|
@ -181,7 +181,10 @@ angular.module('myApp.services')
|
|||||||
}
|
}
|
||||||
|
|
||||||
NotificationsManager.savePeerSettings(peerID, dialog.notify_settings);
|
NotificationsManager.savePeerSettings(peerID, dialog.notify_settings);
|
||||||
ApiUpdatesManager.addChannelState(channelID, dialog.pts);
|
|
||||||
|
if (dialog.pts) {
|
||||||
|
ApiUpdatesManager.addChannelState(channelID, dialog.pts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTopMessages (limit) {
|
function getTopMessages (limit) {
|
||||||
@ -1291,10 +1294,12 @@ angular.module('myApp.services')
|
|||||||
isChannel = AppPeersManager.isChannel(peerID),
|
isChannel = AppPeersManager.isChannel(peerID),
|
||||||
isMegagroup = isChannel && AppPeersManager.isMegagroup(peerID),
|
isMegagroup = isChannel && AppPeersManager.isMegagroup(peerID),
|
||||||
asChannel = isChannel && !isMegagroup ? true : false,
|
asChannel = isChannel && !isMegagroup ? true : false,
|
||||||
entities = [],
|
entities = options.entities || [],
|
||||||
message;
|
message;
|
||||||
|
|
||||||
text = RichTextProcessor.parseMarkdown(text, entities);
|
if (!options.viaBotID) {
|
||||||
|
text = RichTextProcessor.parseMarkdown(text, entities);
|
||||||
|
}
|
||||||
|
|
||||||
if (historyStorage === undefined) {
|
if (historyStorage === undefined) {
|
||||||
historyStorage = historiesStorage[peerID] = {count: null, history: [], pending: []};
|
historyStorage = historiesStorage[peerID] = {count: null, history: [], pending: []};
|
||||||
@ -1328,6 +1333,7 @@ angular.module('myApp.services')
|
|||||||
message: text,
|
message: text,
|
||||||
random_id: randomIDS,
|
random_id: randomIDS,
|
||||||
reply_to_msg_id: replyToMsgID,
|
reply_to_msg_id: replyToMsgID,
|
||||||
|
via_bot_id: options.viaBotID,
|
||||||
entities: entities,
|
entities: entities,
|
||||||
views: asChannel && 1,
|
views: asChannel && 1,
|
||||||
pending: true
|
pending: true
|
||||||
@ -1359,21 +1365,34 @@ angular.module('myApp.services')
|
|||||||
if (replyToMsgID) {
|
if (replyToMsgID) {
|
||||||
flags |= 1;
|
flags |= 1;
|
||||||
}
|
}
|
||||||
if (entities.length) {
|
|
||||||
flags |= 8;
|
|
||||||
}
|
|
||||||
if (asChannel) {
|
if (asChannel) {
|
||||||
flags |= 16;
|
flags |= 16;
|
||||||
}
|
}
|
||||||
|
var apiPromise;
|
||||||
|
if (options.viaBotID) {
|
||||||
|
apiPromise = MtpApiManager.invokeApi('messages.sendInlineBotResult', {
|
||||||
|
flags: flags,
|
||||||
|
peer: AppPeersManager.getInputPeerByID(peerID),
|
||||||
|
random_id: randomID,
|
||||||
|
reply_to_msg_id: getMessageLocalID(replyToMsgID),
|
||||||
|
query_id: options.queryID,
|
||||||
|
id: options.resultID
|
||||||
|
}, sentRequestOptions);
|
||||||
|
} else {
|
||||||
|
if (entities.length) {
|
||||||
|
flags |= 8;
|
||||||
|
}
|
||||||
|
apiPromise = MtpApiManager.invokeApi('messages.sendMessage', {
|
||||||
|
flags: flags,
|
||||||
|
peer: AppPeersManager.getInputPeerByID(peerID),
|
||||||
|
message: text,
|
||||||
|
random_id: randomID,
|
||||||
|
reply_to_msg_id: getMessageLocalID(replyToMsgID),
|
||||||
|
entities: entities
|
||||||
|
}, sentRequestOptions)
|
||||||
|
}
|
||||||
// console.log(flags, entities);
|
// console.log(flags, entities);
|
||||||
MtpApiManager.invokeApi('messages.sendMessage', {
|
apiPromise.then(function (updates) {
|
||||||
flags: flags,
|
|
||||||
peer: AppPeersManager.getInputPeerByID(peerID),
|
|
||||||
message: text,
|
|
||||||
random_id: randomID,
|
|
||||||
reply_to_msg_id: getMessageLocalID(replyToMsgID),
|
|
||||||
entities: entities
|
|
||||||
}, sentRequestOptions).then(function (updates) {
|
|
||||||
if (updates._ == 'updateShortSentMessage') {
|
if (updates._ == 'updateShortSentMessage') {
|
||||||
message.flags = updates.flags;
|
message.flags = updates.flags;
|
||||||
message.date = updates.date;
|
message.date = updates.date;
|
||||||
@ -1637,7 +1656,8 @@ angular.module('myApp.services')
|
|||||||
case 'inputMediaPhoto':
|
case 'inputMediaPhoto':
|
||||||
media = {
|
media = {
|
||||||
_: 'messageMediaPhoto',
|
_: 'messageMediaPhoto',
|
||||||
photo: AppPhotosManager.getPhoto(inputMedia.id.id)
|
photo: AppPhotosManager.getPhoto(inputMedia.id.id),
|
||||||
|
caption: inputMedia.caption || ''
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1648,9 +1668,14 @@ angular.module('myApp.services')
|
|||||||
};
|
};
|
||||||
media = {
|
media = {
|
||||||
_: 'messageMediaDocument',
|
_: 'messageMediaDocument',
|
||||||
'document': doc
|
'document': doc,
|
||||||
|
caption: inputMedia.caption || ''
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'messageMediaPending':
|
||||||
|
media = inputMedia;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var flags = 0;
|
var flags = 0;
|
||||||
@ -1684,6 +1709,7 @@ angular.module('myApp.services')
|
|||||||
media: media,
|
media: media,
|
||||||
random_id: randomIDS,
|
random_id: randomIDS,
|
||||||
reply_to_msg_id: replyToMsgID,
|
reply_to_msg_id: replyToMsgID,
|
||||||
|
via_bot_id: options.viaBotID,
|
||||||
views: asChannel && 1,
|
views: asChannel && 1,
|
||||||
pending: true
|
pending: true
|
||||||
};
|
};
|
||||||
@ -1718,13 +1744,26 @@ angular.module('myApp.services')
|
|||||||
sentRequestOptions.afterMessageID = pendingAfterMsgs[peerID].messageID;
|
sentRequestOptions.afterMessageID = pendingAfterMsgs[peerID].messageID;
|
||||||
}
|
}
|
||||||
|
|
||||||
MtpApiManager.invokeApi('messages.sendMedia', {
|
var apiPromise;
|
||||||
flags: flags,
|
if (options.viaBotID) {
|
||||||
peer: AppPeersManager.getInputPeerByID(peerID),
|
apiPromise = MtpApiManager.invokeApi('messages.sendInlineBotResult', {
|
||||||
media: inputMedia,
|
flags: flags,
|
||||||
random_id: randomID,
|
peer: AppPeersManager.getInputPeerByID(peerID),
|
||||||
reply_to_msg_id: getMessageLocalID(replyToMsgID)
|
random_id: randomID,
|
||||||
}, sentRequestOptions).then(function (updates) {
|
reply_to_msg_id: getMessageLocalID(replyToMsgID),
|
||||||
|
query_id: options.queryID,
|
||||||
|
id: options.resultID
|
||||||
|
}, sentRequestOptions);
|
||||||
|
} else {
|
||||||
|
apiPromise = MtpApiManager.invokeApi('messages.sendMedia', {
|
||||||
|
flags: flags,
|
||||||
|
peer: AppPeersManager.getInputPeerByID(peerID),
|
||||||
|
media: inputMedia,
|
||||||
|
random_id: randomID,
|
||||||
|
reply_to_msg_id: getMessageLocalID(replyToMsgID)
|
||||||
|
}, sentRequestOptions);
|
||||||
|
}
|
||||||
|
apiPromise.then(function (updates) {
|
||||||
ApiUpdatesManager.processUpdateMessage(updates);
|
ApiUpdatesManager.processUpdateMessage(updates);
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
toggleError(true);
|
toggleError(true);
|
||||||
@ -3007,7 +3046,7 @@ angular.module('myApp.services')
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
getConversations: getConversations,
|
getConversations: getConversations,
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
||||||
|
|
||||||
.service('AppUsersManager', function ($rootScope, $modal, $modalStack, $filter, $q, qSync, MtpApiFileManager, MtpApiManager, RichTextProcessor, ErrorService, Storage, _) {
|
.service('AppUsersManager', function ($rootScope, $modal, $modalStack, $filter, $q, qSync, MtpApiManager, RichTextProcessor, ErrorService, Storage, _) {
|
||||||
var users = {},
|
var users = {},
|
||||||
usernames = {},
|
usernames = {},
|
||||||
userAccess = {},
|
userAccess = {},
|
||||||
@ -575,7 +575,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
.service('AppChatsManager', function ($q, $rootScope, $modal, _, MtpApiFileManager, MtpApiManager, AppUsersManager, AppPhotosManager, RichTextProcessor) {
|
.service('AppChatsManager', function ($q, $rootScope, $modal, _, MtpApiManager, AppUsersManager, AppPhotosManager, RichTextProcessor) {
|
||||||
var chats = {},
|
var chats = {},
|
||||||
usernames = {},
|
usernames = {},
|
||||||
channelAccess = {},
|
channelAccess = {},
|
||||||
@ -833,7 +833,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
.service('AppPeersManager', function (qSync, AppUsersManager, AppChatsManager, MtpApiManager) {
|
.service('AppPeersManager', function ($q, qSync, AppUsersManager, AppChatsManager, MtpApiManager) {
|
||||||
|
|
||||||
function getInputPeer (peerString) {
|
function getInputPeer (peerString) {
|
||||||
var firstChar = peerString.charAt(0),
|
var firstChar = peerString.charAt(0),
|
||||||
@ -944,6 +944,24 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resolveInlineMention (username) {
|
||||||
|
return resolveUsername(username).then(function (peerID) {
|
||||||
|
if (peerID > 0) {
|
||||||
|
var bot = AppUsersManager.getUser(peerID);
|
||||||
|
if (bot.pFlags.bot && bot.bot_inline_placeholder !== undefined) {
|
||||||
|
return qSync.when({
|
||||||
|
id: peerID,
|
||||||
|
placeholder: bot.bot_inline_placeholder
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $q.reject();
|
||||||
|
}, function (error) {
|
||||||
|
error.handled = true;
|
||||||
|
return $q.reject(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function getPeerID (peerString) {
|
function getPeerID (peerString) {
|
||||||
if (angular.isObject(peerString)) {
|
if (angular.isObject(peerString)) {
|
||||||
return peerString.user_id
|
return peerString.user_id
|
||||||
@ -990,6 +1008,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
getPeer: getPeer,
|
getPeer: getPeer,
|
||||||
getPeerPhoto: getPeerPhoto,
|
getPeerPhoto: getPeerPhoto,
|
||||||
resolveUsername: resolveUsername,
|
resolveUsername: resolveUsername,
|
||||||
|
resolveInlineMention: resolveInlineMention,
|
||||||
isChannel: isChannel,
|
isChannel: isChannel,
|
||||||
isMegagroup: isMegagroup,
|
isMegagroup: isMegagroup,
|
||||||
isBot: isBot
|
isBot: isBot
|
||||||
@ -1222,6 +1241,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return $q.reject(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1907,7 +1927,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
.service('AppDocsManager', function ($sce, $rootScope, $modal, $window, $q, RichTextProcessor, MtpApiFileManager, FileManager, qSync) {
|
.service('AppDocsManager', function ($sce, $rootScope, $modal, $window, $q, $timeout, RichTextProcessor, MtpApiFileManager, FileManager, qSync) {
|
||||||
var docs = {},
|
var docs = {},
|
||||||
docsForHistory = {},
|
docsForHistory = {},
|
||||||
windowW = $(window).width(),
|
windowW = $(window).width(),
|
||||||
@ -2096,13 +2116,18 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
});
|
});
|
||||||
|
|
||||||
downloadPromise.then(function (blob) {
|
downloadPromise.then(function (blob) {
|
||||||
delete historyDoc.progress;
|
|
||||||
if (blob) {
|
if (blob) {
|
||||||
FileManager.getFileCorrectUrl(blob, doc.mime_type).then(function (url) {
|
FileManager.getFileCorrectUrl(blob, doc.mime_type).then(function (url) {
|
||||||
historyDoc.url = $sce.trustAsResourceUrl(url);
|
var trustedUrl = $sce.trustAsResourceUrl(url);
|
||||||
|
historyDoc.url = trustedUrl;
|
||||||
|
doc.url = trustedUrl;
|
||||||
})
|
})
|
||||||
historyDoc.downloaded = true;
|
historyDoc.downloaded = true;
|
||||||
}
|
}
|
||||||
|
historyDoc.progress.percent = 100;
|
||||||
|
$timeout(function () {
|
||||||
|
delete historyDoc.progress;
|
||||||
|
});
|
||||||
console.log('file save done');
|
console.log('file save done');
|
||||||
}, function (e) {
|
}, function (e) {
|
||||||
console.log('document download failed', e);
|
console.log('document download failed', e);
|
||||||
@ -2274,24 +2299,81 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
.service('AppStickersManager', function ($q, $rootScope, $modal, _, FileManager, MtpApiManager, MtpApiFileManager, AppDocsManager, Storage) {
|
.service('AppStickersManager', function ($q, $rootScope, $modal, _, FileManager, MtpApiManager, AppDocsManager, Storage, ApiUpdatesManager) {
|
||||||
|
|
||||||
var currentStickers = [];
|
|
||||||
var currentStickersets = [];
|
|
||||||
var installedStickersets = {};
|
|
||||||
var stickersetItems = {};
|
|
||||||
var applied = false;
|
|
||||||
var started = false;
|
var started = false;
|
||||||
|
var applied = false;
|
||||||
|
var currentStickerSets = [];
|
||||||
|
|
||||||
|
$rootScope.$on('apiUpdate', function (e, update) {
|
||||||
|
if (update._ != 'updateStickerSets' &&
|
||||||
|
update._ != 'updateNewStickerSet' &&
|
||||||
|
update._ != 'updateDelStickerSet' &&
|
||||||
|
update._ != 'updateStickerSetsOrder') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Storage.get('all_stickers').then(function (stickers) {
|
||||||
|
if (!stickers ||
|
||||||
|
stickers.layer != Config.Schema.API.layer) {
|
||||||
|
$rootScope.$broadcast('stickers_changed');
|
||||||
|
}
|
||||||
|
switch (update._) {
|
||||||
|
case 'updateNewStickerSet':
|
||||||
|
var fullSet = update.stickerset;
|
||||||
|
var set = fullSet.set;
|
||||||
|
var pos = false;
|
||||||
|
for (var i = 0, len = stickers.sets.length; i < len; i++) {
|
||||||
|
if (stickers.sets[i].id == set.id) {
|
||||||
|
pos = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pos !== false) {
|
||||||
|
stickers.sets.splice(pos, 1);
|
||||||
|
}
|
||||||
|
set.pFlags.installed = true;
|
||||||
|
stickers.sets.unshift(set);
|
||||||
|
stickers.fullSets[set.id] = fullSet;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'updateDelStickerSet':
|
||||||
|
var set;
|
||||||
|
for (var i = 0, len = stickers.sets.length; i < len; i++) {
|
||||||
|
set = stickers.sets[i];
|
||||||
|
if (set.id == update.id) {
|
||||||
|
set.pFlags.installed = false;
|
||||||
|
stickers.sets.splice(i, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete stickers.fullSets[update.id];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'updateStickerSetsOrder':
|
||||||
|
var order = update.order;
|
||||||
|
stickers.sets.sort(function (a, b) {
|
||||||
|
return order.indexOf(a.id) - order.indexOf(b.id);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
stickers.hash = getStickerSetsHash(stickers.sets);
|
||||||
|
stickers.date = 0;
|
||||||
|
Storage.set({all_stickers: stickers}).then(function () {
|
||||||
|
$rootScope.$broadcast('stickers_changed');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
start: start,
|
start: start,
|
||||||
|
getStickers: getStickers,
|
||||||
openStickersetLink: openStickersetLink,
|
openStickersetLink: openStickersetLink,
|
||||||
openStickerset: openStickerset,
|
openStickerset: openStickerset,
|
||||||
installStickerset: installStickerset,
|
installStickerset: installStickerset,
|
||||||
pushPopularSticker: pushPopularSticker,
|
pushPopularSticker: pushPopularSticker,
|
||||||
getStickers: getStickers,
|
getStickerset: getStickerset
|
||||||
getStickerset: getStickerset,
|
|
||||||
getStickersImages: getStickersImages
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function start () {
|
function start () {
|
||||||
@ -2301,6 +2383,109 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getStickers (force) {
|
||||||
|
return Storage.get('all_stickers').then(function (stickers) {
|
||||||
|
var layer = Config.Schema.API.layer;
|
||||||
|
if (stickers.layer != layer) {
|
||||||
|
stickers = false;
|
||||||
|
}
|
||||||
|
if (stickers && stickers.date > tsNow(true) && !force) {
|
||||||
|
return processRawStickers(stickers);
|
||||||
|
}
|
||||||
|
return MtpApiManager.invokeApi('messages.getAllStickers', {
|
||||||
|
hash: stickers && stickers.hash || ''
|
||||||
|
}).then(function (newStickers) {
|
||||||
|
var notModified = newStickers._ == 'messages.allStickersNotModified';
|
||||||
|
if (notModified) {
|
||||||
|
newStickers = stickers;
|
||||||
|
}
|
||||||
|
newStickers.date = tsNow(true) + 3600;
|
||||||
|
newStickers.layer = layer;
|
||||||
|
delete newStickers._;
|
||||||
|
|
||||||
|
if (notModified) {
|
||||||
|
Storage.set({all_stickers: newStickers});
|
||||||
|
return processRawStickers(newStickers);
|
||||||
|
}
|
||||||
|
|
||||||
|
return getStickerSets(newStickers, stickers && stickers.fullSets).then(function () {
|
||||||
|
Storage.set({all_stickers: newStickers});
|
||||||
|
return processRawStickers(newStickers);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function processRawStickers(stickers) {
|
||||||
|
if (applied !== stickers.hash) {
|
||||||
|
applied = stickers.hash;
|
||||||
|
var i, j, len1, len2, doc, set, docIDs, documents;
|
||||||
|
|
||||||
|
currentStickerSets = [];
|
||||||
|
len1 = stickers.sets.length;
|
||||||
|
for (i = 0; i < len1; i++) {
|
||||||
|
set = stickers.sets[i];
|
||||||
|
if (set.pFlags.disabled) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
documents = stickers.fullSets[set.id].documents;
|
||||||
|
len2 = documents.length;
|
||||||
|
docIDs = [];
|
||||||
|
for (j = 0; j < len2; j++) {
|
||||||
|
doc = documents[j];
|
||||||
|
AppDocsManager.saveDoc(doc);
|
||||||
|
docIDs.push(doc.id);
|
||||||
|
}
|
||||||
|
set.docIDs = docIDs;
|
||||||
|
currentStickerSets.push(set);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return getPopularStickers().then(function (popularStickers) {
|
||||||
|
var resultStickersets = currentStickerSets;
|
||||||
|
if (popularStickers.length) {
|
||||||
|
resultStickersets = currentStickerSets.slice();
|
||||||
|
var docIDs = [];
|
||||||
|
var i, len;
|
||||||
|
for (i = 0, len = popularStickers.length; i < len; i++) {
|
||||||
|
docIDs.push(popularStickers[i].id);
|
||||||
|
}
|
||||||
|
resultStickersets.unshift({
|
||||||
|
id: 0,
|
||||||
|
title: _('im_stickers_tab_recent_raw'),
|
||||||
|
short_name: '',
|
||||||
|
docIDs: docIDs
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return resultStickersets;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getStickerSets (allStickers, prevCachedSets) {
|
||||||
|
var promises = [];
|
||||||
|
var cachedSets = prevCachedSets || allStickers.fullSets || {};
|
||||||
|
allStickers.fullSets = {};
|
||||||
|
angular.forEach(allStickers.sets, function (shortSet) {
|
||||||
|
var fullSet = cachedSets[shortSet.id];
|
||||||
|
if (fullSet && fullSet.set.hash == shortSet.hash) {
|
||||||
|
allStickers.fullSets[shortSet.id] = fullSet;
|
||||||
|
} else {
|
||||||
|
var promise = MtpApiManager.invokeApi('messages.getStickerSet', {
|
||||||
|
stickerset: {
|
||||||
|
_: 'inputStickerSetID',
|
||||||
|
id: shortSet.id,
|
||||||
|
access_hash: shortSet.access_hash
|
||||||
|
}
|
||||||
|
}).then(function (fullSet) {
|
||||||
|
allStickers.fullSets[shortSet.id] = fullSet;
|
||||||
|
});
|
||||||
|
promises.push(promise);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return $q.all(promises);
|
||||||
|
}
|
||||||
|
|
||||||
function getPopularStickers () {
|
function getPopularStickers () {
|
||||||
return Storage.get('stickers_popular').then(function (popStickers) {
|
return Storage.get('stickers_popular').then(function (popStickers) {
|
||||||
var result = [];
|
var result = [];
|
||||||
@ -2343,140 +2528,6 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function processRawStickers(stickers) {
|
|
||||||
if (applied !== stickers.hash) {
|
|
||||||
applied = stickers.hash;
|
|
||||||
var i, j, len1, len2, doc, set, setItems, fullSet;
|
|
||||||
|
|
||||||
currentStickersets = [];
|
|
||||||
currentStickers = [];
|
|
||||||
len1 = stickers.sets.length;
|
|
||||||
for (i = 0; i < len1; i++) {
|
|
||||||
set = stickers.sets[i];
|
|
||||||
fullSet = stickers.fullSets[set.id];
|
|
||||||
len2 = fullSet.documents.length;
|
|
||||||
setItems = [];
|
|
||||||
for (j = 0; j < len2; j++) {
|
|
||||||
doc = fullSet.documents[j];
|
|
||||||
AppDocsManager.saveDoc(doc);
|
|
||||||
currentStickers.push(doc.id);
|
|
||||||
setItems.push(doc.id);
|
|
||||||
}
|
|
||||||
currentStickersets.push({
|
|
||||||
id: set.id,
|
|
||||||
title: set.title,
|
|
||||||
short_name: set.short_name,
|
|
||||||
installed: (set.flags & (1 << 0)) > 0,
|
|
||||||
disabled: (set.flags & (1 << 1)) > 0,
|
|
||||||
official: (set.flags & (1 << 2)) > 0,
|
|
||||||
docIDs: setItems
|
|
||||||
});
|
|
||||||
installedStickersets[set.id] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return getPopularStickers().then(function (popularStickers) {
|
|
||||||
var resultStickersets = currentStickersets;
|
|
||||||
if (popularStickers.length) {
|
|
||||||
resultStickersets = currentStickersets.slice();
|
|
||||||
var setItems = [];
|
|
||||||
var i, len;
|
|
||||||
for (i = 0, len = popularStickers.length; i < len; i++) {
|
|
||||||
setItems.push(popularStickers[i].id);
|
|
||||||
}
|
|
||||||
resultStickersets.unshift({
|
|
||||||
id: 0,
|
|
||||||
title: _('im_stickers_tab_recent_raw'),
|
|
||||||
short_name: '',
|
|
||||||
installed: true,
|
|
||||||
disabled: false,
|
|
||||||
official: false,
|
|
||||||
docIDs: setItems
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return resultStickersets;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getStickers (force) {
|
|
||||||
return Storage.get('all_stickers').then(function (stickers) {
|
|
||||||
var layer = Config.Schema.API.layer;
|
|
||||||
if (stickers.layer != layer) {
|
|
||||||
stickers = false;
|
|
||||||
}
|
|
||||||
if (stickers && stickers.date > tsNow(true) && !force) {
|
|
||||||
return processRawStickers(stickers);
|
|
||||||
}
|
|
||||||
return MtpApiManager.invokeApi('messages.getAllStickers', {
|
|
||||||
hash: stickers && stickers.hash || ''
|
|
||||||
}).then(function (newStickers) {
|
|
||||||
var notModified = newStickers._ == 'messages.allStickersNotModified';
|
|
||||||
if (notModified) {
|
|
||||||
newStickers = stickers;
|
|
||||||
}
|
|
||||||
newStickers.date = tsNow(true) + 3600;
|
|
||||||
newStickers.layer = layer;
|
|
||||||
delete newStickers._;
|
|
||||||
|
|
||||||
if (notModified) {
|
|
||||||
Storage.set({all_stickers: newStickers});
|
|
||||||
return processRawStickers(newStickers);
|
|
||||||
}
|
|
||||||
|
|
||||||
return getStickerSets(newStickers).then(function () {
|
|
||||||
Storage.set({all_stickers: newStickers});
|
|
||||||
return processRawStickers(newStickers);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function getStickerSets (allStickers) {
|
|
||||||
var promises = [];
|
|
||||||
var cachedSets = allStickers.fullSets || {};
|
|
||||||
allStickers.fullSets = {};
|
|
||||||
angular.forEach(allStickers.sets, function (shortSet) {
|
|
||||||
var fullSet = cachedSets[shortSet.id];
|
|
||||||
if (fullSet && fullSet.set.hash == shortSet.hash) {
|
|
||||||
allStickers.fullSets[shortSet.id] = fullSet;
|
|
||||||
} else {
|
|
||||||
var promise = MtpApiManager.invokeApi('messages.getStickerSet', {
|
|
||||||
stickerset: {
|
|
||||||
_: 'inputStickerSetID',
|
|
||||||
id: shortSet.id,
|
|
||||||
access_hash: shortSet.access_hash
|
|
||||||
}
|
|
||||||
}).then(function (fullSet) {
|
|
||||||
allStickers.fullSets[shortSet.id] = fullSet;
|
|
||||||
});
|
|
||||||
promises.push(promise);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return $q.all(promises);
|
|
||||||
}
|
|
||||||
|
|
||||||
function downloadStickerThumb (docID) {
|
|
||||||
var doc = AppDocsManager.getDoc(docID);
|
|
||||||
var thumbLocation = angular.copy(doc.thumb.location);
|
|
||||||
thumbLocation.sticker = true;
|
|
||||||
return MtpApiFileManager.downloadSmallFile(thumbLocation).then(function (blob) {
|
|
||||||
return {
|
|
||||||
id: doc.id,
|
|
||||||
src: FileManager.getUrl(blob, 'image/webp')
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getStickersImages () {
|
|
||||||
var promises = [];
|
|
||||||
angular.forEach(currentStickers, function (docID) {
|
|
||||||
promises.push(downloadStickerThumb (docID));
|
|
||||||
});
|
|
||||||
return $q.all(promises);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getStickerset (inputStickerset) {
|
function getStickerset (inputStickerset) {
|
||||||
return MtpApiManager.invokeApi('messages.getStickerSet', {
|
return MtpApiManager.invokeApi('messages.getStickerSet', {
|
||||||
stickerset: inputStickerset
|
stickerset: inputStickerset
|
||||||
@ -2484,31 +2535,32 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
for (var i = 0; i < result.documents.length; i++) {
|
for (var i = 0; i < result.documents.length; i++) {
|
||||||
AppDocsManager.saveDoc(result.documents[i]);
|
AppDocsManager.saveDoc(result.documents[i]);
|
||||||
}
|
}
|
||||||
result.installed = installedStickersets[result.set.id] !== undefined;
|
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function installStickerset (set, uninstall) {
|
function installStickerset (fullSet, uninstall) {
|
||||||
var method = uninstall
|
var method = uninstall
|
||||||
? 'messages.uninstallStickerSet'
|
? 'messages.uninstallStickerSet'
|
||||||
: 'messages.installStickerSet';
|
: 'messages.installStickerSet';
|
||||||
var inputStickerset = {
|
var inputStickerset = {
|
||||||
_: 'inputStickerSetID',
|
_: 'inputStickerSetID',
|
||||||
id: set.id,
|
id: fullSet.set.id,
|
||||||
access_hash: set.access_hash
|
access_hash: fullSet.set.access_hash
|
||||||
};
|
};
|
||||||
return MtpApiManager.invokeApi(method, {
|
return MtpApiManager.invokeApi(method, {
|
||||||
stickerset: inputStickerset,
|
stickerset: inputStickerset,
|
||||||
disabled: false
|
disabled: false
|
||||||
}).then(function (result) {
|
}).then(function (result) {
|
||||||
|
var update;
|
||||||
if (uninstall) {
|
if (uninstall) {
|
||||||
delete installedStickersets[set.id];
|
update = {_: 'updateDelStickerSet', id: fullSet.set.id};
|
||||||
} else {
|
} else {
|
||||||
installedStickersets[set.id] = true;
|
update = {_: 'updateNewStickerSet', stickerset: fullSet};
|
||||||
}
|
}
|
||||||
Storage.remove('all_stickers').then(function () {
|
ApiUpdatesManager.processUpdateMessage({
|
||||||
getStickers(true);
|
_: 'updateShort',
|
||||||
|
update: update
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -2530,6 +2582,186 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
windowClass: 'stickerset_modal_window mobile_modal'
|
windowClass: 'stickerset_modal_window mobile_modal'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getStickerSetsHash (stickerSets) {
|
||||||
|
var acc = 0, set;
|
||||||
|
for (var i = 0; i < stickerSets.length; i++) {
|
||||||
|
set = stickerSets[i];
|
||||||
|
if (set.pFlags.disabled || !set.pFlags.installed) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
acc = ((acc * 20261) + 0x80000000 + set.hash) % 0x80000000;
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
.service('AppInlineBotsManager', function (MtpApiManager, AppMessagesManager, AppDocsManager, AppPhotosManager, RichTextProcessor, AppUsersManager) {
|
||||||
|
|
||||||
|
var inlineResults = {};
|
||||||
|
|
||||||
|
return {
|
||||||
|
sendInlineResult: sendInlineResult,
|
||||||
|
regroupWrappedResults: regroupWrappedResults,
|
||||||
|
getInlineResults: getInlineResults
|
||||||
|
};
|
||||||
|
|
||||||
|
function getInlineResults (botID, query, offset) {
|
||||||
|
return MtpApiManager.invokeApi('messages.getInlineBotResults', {
|
||||||
|
bot: AppUsersManager.getUserInput(botID),
|
||||||
|
query: query,
|
||||||
|
offset: offset
|
||||||
|
}, {timeout: 1, stopTime: -1, noErrorBox: true}).then(function(botResults) {
|
||||||
|
var queryID = botResults.query_id;
|
||||||
|
delete botResults._;
|
||||||
|
delete botResults.flags;
|
||||||
|
delete botResults.query_id;
|
||||||
|
|
||||||
|
angular.forEach(botResults.results, function (result) {
|
||||||
|
var qID = queryID + '_' + result.id;
|
||||||
|
result.qID = qID;
|
||||||
|
result.botID = botID;
|
||||||
|
|
||||||
|
result.rTitle = RichTextProcessor.wrapRichText(result.title, {noLinebreaks: true, noLinks: true});
|
||||||
|
result.rDescription = RichTextProcessor.wrapRichText(result.description, {noLinebreaks: true, noLinks: true});
|
||||||
|
result.initials = (result.url || result.title || result.type || '').substr(0, 1)
|
||||||
|
|
||||||
|
if (result.document) {
|
||||||
|
AppDocsManager.saveDoc(result.document);
|
||||||
|
}
|
||||||
|
if (result.photo) {
|
||||||
|
AppPhotosManager.savePhoto(result.photo);
|
||||||
|
}
|
||||||
|
|
||||||
|
inlineResults[qID] = result;
|
||||||
|
});
|
||||||
|
return botResults;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function regroupWrappedResults (results, rowW, rowH) {
|
||||||
|
if (!results ||
|
||||||
|
!results[0] ||
|
||||||
|
results[0].type != 'photo' && results[0].type != 'gif') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var ratios = [];
|
||||||
|
angular.forEach(results, function (result) {
|
||||||
|
var w, h;
|
||||||
|
if (result._ == 'botInlineMediaResultDocument') {
|
||||||
|
w = result.document.w;
|
||||||
|
h = result.document.h;
|
||||||
|
}
|
||||||
|
else if (result._ == 'botInlineMediaResultPhoto') {
|
||||||
|
var photoSize = (result.photo.sizes || [])[0];
|
||||||
|
w = photoSize && photoSize.w;
|
||||||
|
h = photoSize && photoSize.h;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
w = result.w;
|
||||||
|
h = result.h;
|
||||||
|
}
|
||||||
|
if (!w || !h) {
|
||||||
|
w = h = 1;
|
||||||
|
}
|
||||||
|
ratios.push(w / h);
|
||||||
|
});
|
||||||
|
|
||||||
|
var rows = [];
|
||||||
|
var curCnt = 0;
|
||||||
|
var curW = 0;
|
||||||
|
angular.forEach(ratios, function (ratio) {
|
||||||
|
var w = ratio * rowH;
|
||||||
|
curW += w;
|
||||||
|
if (!curCnt || curCnt < 4 && curW < (rowW * 1.1)) {
|
||||||
|
curCnt++;
|
||||||
|
} else {
|
||||||
|
rows.push(curCnt);
|
||||||
|
curCnt = 1;
|
||||||
|
curW = w;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (curCnt) {
|
||||||
|
rows.push(curCnt);
|
||||||
|
}
|
||||||
|
|
||||||
|
var i = 0;
|
||||||
|
var thumbs = [];
|
||||||
|
var lastRowI = rows.length - 1;
|
||||||
|
angular.forEach(rows, function (rowCnt, rowI) {
|
||||||
|
var lastRow = rowI == lastRowI;
|
||||||
|
var curRatios = ratios.slice(i, i + rowCnt);
|
||||||
|
var sumRatios = 0;
|
||||||
|
angular.forEach(curRatios, function (ratio) {
|
||||||
|
sumRatios += ratio;
|
||||||
|
});
|
||||||
|
angular.forEach(curRatios, function (ratio, j) {
|
||||||
|
var thumbH = rowH;
|
||||||
|
var thumbW = rowW * ratio / sumRatios;
|
||||||
|
var realW = thumbH * ratio;
|
||||||
|
if (lastRow && thumbW > realW) {
|
||||||
|
thumbW = realW;
|
||||||
|
}
|
||||||
|
var result = results[i + j];
|
||||||
|
result.thumbW = Math.floor(thumbW);
|
||||||
|
result.thumbH = Math.floor(thumbH);
|
||||||
|
});
|
||||||
|
|
||||||
|
i += rowCnt;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendInlineResult (peerID, qID, options) {
|
||||||
|
var inlineResult = inlineResults[qID];
|
||||||
|
if (inlineResult === undefined) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var splitted = qID.split('_');
|
||||||
|
var queryID = splitted.shift();
|
||||||
|
var resultID = splitted.join('_');
|
||||||
|
options = options || {};
|
||||||
|
options.viaBotID = inlineResult.botID;
|
||||||
|
options.queryID = queryID;
|
||||||
|
options.resultID = resultID;
|
||||||
|
|
||||||
|
if (inlineResult.send_message._ == 'botInlineMessageText') {
|
||||||
|
options.entities = inlineResult.send_message.entities;
|
||||||
|
AppMessagesManager.sendText(peerID, inlineResult.send_message.message, options);
|
||||||
|
} else {
|
||||||
|
var caption = '';
|
||||||
|
if (inlineResult.send_message._ == 'botInlineMessageMediaAuto') {
|
||||||
|
caption = inlineResult.send_message.caption;
|
||||||
|
}
|
||||||
|
var inputMedia = false;
|
||||||
|
if (inlineResult._ == 'botInlineMediaResultDocument') {
|
||||||
|
var doc = inlineResult.document;
|
||||||
|
inputMedia = {
|
||||||
|
_: 'inputMediaDocument',
|
||||||
|
id: {_: 'inputDocument', id: doc.id, access_hash: doc.access_hash},
|
||||||
|
caption: caption
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (inlineResult._ == 'botInlineMediaResultPhoto') {
|
||||||
|
var photo = inlineResult.photo;
|
||||||
|
inputMedia = {
|
||||||
|
_: 'inputMediaPhoto',
|
||||||
|
id: {_: 'inputPhoto', id: photo.id, access_hash: photo.access_hash},
|
||||||
|
caption: caption
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (!inputMedia) {
|
||||||
|
inputMedia = {
|
||||||
|
_: 'messageMediaPending',
|
||||||
|
type: inlineResult.type,
|
||||||
|
file_name: inlineResult.title || inlineResult.content_url || inlineResult.url,
|
||||||
|
size: 0,
|
||||||
|
progress: {percent: 30, total: 0}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
AppMessagesManager.sendOther(peerID, inputMedia, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
.service('ApiUpdatesManager', function ($rootScope, MtpNetworkerFactory, AppUsersManager, AppChatsManager, AppPeersManager, MtpApiManager) {
|
.service('ApiUpdatesManager', function ($rootScope, MtpNetworkerFactory, AppUsersManager, AppChatsManager, AppPeersManager, MtpApiManager) {
|
||||||
@ -2828,6 +3060,9 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
}
|
}
|
||||||
|
|
||||||
function addChannelState (channelID, pts) {
|
function addChannelState (channelID, pts) {
|
||||||
|
if (!pts) {
|
||||||
|
throw new Error('Add channel state without pts ' + channelID);
|
||||||
|
}
|
||||||
if (channelStates[channelID] === undefined) {
|
if (channelStates[channelID] === undefined) {
|
||||||
channelStates[channelID] = {
|
channelStates[channelID] = {
|
||||||
pts: pts,
|
pts: pts,
|
||||||
@ -2842,9 +3077,6 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
|
|
||||||
function getChannelState (channelID, pts) {
|
function getChannelState (channelID, pts) {
|
||||||
if (channelStates[channelID] === undefined) {
|
if (channelStates[channelID] === undefined) {
|
||||||
if (!pts) {
|
|
||||||
throw new Error('Get channel empty state without pts ' + channelID);
|
|
||||||
}
|
|
||||||
addChannelState(channelID, pts);
|
addChannelState(channelID, pts);
|
||||||
}
|
}
|
||||||
return channelStates[channelID];
|
return channelStates[channelID];
|
||||||
@ -3997,7 +4229,11 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
type: 'JUMP_EXT_URL',
|
type: 'JUMP_EXT_URL',
|
||||||
url: url
|
url: url
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
window.open(url, '_blank');
|
var target = '_blank';
|
||||||
|
if (url.search('https://telegram.me/') === 0) {
|
||||||
|
target = '_self';
|
||||||
|
}
|
||||||
|
window.open(url, target);
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -4142,4 +4378,4 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
|||||||
start: start,
|
start: start,
|
||||||
shareUrl: shareUrl
|
shareUrl: shareUrl
|
||||||
};
|
};
|
||||||
})
|
})
|
@ -420,20 +420,56 @@ a {
|
|||||||
display: block;
|
display: block;
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
}
|
}
|
||||||
.progress-arc circle {
|
|
||||||
stroke-dashoffset: 0;
|
|
||||||
stroke: rgba(0,0,0,0.3);
|
|
||||||
stroke-width: 3px;
|
|
||||||
}
|
|
||||||
.progress-arc .progress-arc-bar {
|
.progress-arc .progress-arc-bar {
|
||||||
stroke: #FFF;
|
stroke-dashoffset: 0;
|
||||||
transform-origin: center center;
|
transform-origin: center center;
|
||||||
transition: stroke-dasharray 500ms linear;
|
fill: transparent;
|
||||||
|
|
||||||
-webkit-animation: infinite_rotation 2s linear infinite;
|
.progress-arc-intermediate & {
|
||||||
-moz-animation: infinite_rotation 2s linear infinite;
|
stroke: #68a4d1;
|
||||||
-ms-animation: infinite_rotation 2s linear infinite;
|
|
||||||
animation: infinite_rotation 2s linear infinite;
|
-webkit-animation: infinite_rotation 0.8s linear infinite;
|
||||||
|
-moz-animation: infinite_rotation 0.8s linear infinite;
|
||||||
|
-ms-animation: infinite_rotation 0.8s linear infinite;
|
||||||
|
animation: infinite_rotation 0.8s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.composer_progress_icon & {
|
||||||
|
stroke: rgba(0,0,0,0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-arc-percent & {
|
||||||
|
stroke: #FFF;
|
||||||
|
stroke: rgba(255,255,255,0.95);
|
||||||
|
|
||||||
|
transition: stroke-dasharray 500ms linear;
|
||||||
|
|
||||||
|
-webkit-animation: infinite_rotation 2s linear infinite;
|
||||||
|
-moz-animation: infinite_rotation 2s linear infinite;
|
||||||
|
-ms-animation: infinite_rotation 2s linear infinite;
|
||||||
|
animation: infinite_rotation 2s linear infinite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.stop0 {
|
||||||
|
stop-opacity: 1.0;
|
||||||
|
stop-color: #68a4d1;
|
||||||
|
.composer_progress_icon & {
|
||||||
|
stop-color: rgba(0,0,0,0.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.stop60 {
|
||||||
|
stop-opacity: 1.0;
|
||||||
|
stop-color: #68a4d1;
|
||||||
|
.composer_progress_icon & {
|
||||||
|
stop-color: rgba(0,0,0,0.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.stop100 {
|
||||||
|
stop-opacity: 0.0;
|
||||||
|
stop-color: #68a4d1;
|
||||||
|
.composer_progress_icon & {
|
||||||
|
stop-color: rgba(0,0,0,0.3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Infinite rotation */
|
/* Infinite rotation */
|
||||||
@ -926,13 +962,14 @@ a.tg_radio_on:hover i.icon-radio {
|
|||||||
background-position: -5px -10px;
|
background-position: -5px -10px;
|
||||||
}
|
}
|
||||||
.icon-tg-title {
|
.icon-tg-title {
|
||||||
width: 63px;
|
width: 62px;
|
||||||
height: 16px;
|
height: 14px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
background-image: url('../img/Telegram.svg');
|
||||||
.image-2x('../img/Telegram.png', 63px, 16px);
|
background-repeat: no-repeat;
|
||||||
background-position: 0 0;
|
background-position: 0 0;
|
||||||
|
margin-top: 1px;
|
||||||
}
|
}
|
||||||
.login_head_submit_wrap,
|
.login_head_submit_wrap,
|
||||||
.login_head_submit_progress {
|
.login_head_submit_progress {
|
||||||
@ -1392,7 +1429,8 @@ a.im_dialog_selected {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.im_history {
|
.im_history {
|
||||||
padding: 20px 0 0 0;
|
// padding: 20px 0 0 0;
|
||||||
|
padding: 0;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
.im_message_unread_split {
|
.im_message_unread_split {
|
||||||
@ -1403,12 +1441,14 @@ a.im_dialog_selected {
|
|||||||
margin: 10px 0;
|
margin: 10px 0;
|
||||||
}
|
}
|
||||||
.im_message_author,
|
.im_message_author,
|
||||||
.im_message_fwd_author {
|
.im_message_fwd_author,
|
||||||
|
.im_message_via_author {
|
||||||
color: #3a6d99;
|
color: #3a6d99;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
.non_osx .im_message_author,
|
.non_osx .im_message_author,
|
||||||
.non_osx .im_message_fwd_author {
|
.non_osx .im_message_fwd_author,
|
||||||
|
.non_osx .im_message_via_author {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
.im_message_author_via {
|
.im_message_author_via {
|
||||||
@ -1505,6 +1545,9 @@ div.im_message_video_thumb {
|
|||||||
|
|
||||||
.image-2x('../img/icons/IconsetW.png', 42px, 1171px);
|
.image-2x('../img/icons/IconsetW.png', 42px, 1171px);
|
||||||
background-position: 0 -590px;
|
background-position: 0 -590px;
|
||||||
|
.is_2x & {
|
||||||
|
background-position: 0 -591px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.im_message_geopoint {
|
.im_message_geopoint {
|
||||||
@ -1999,6 +2042,10 @@ img.im_message_document_thumb {
|
|||||||
padding: 0 0 20px 10px;
|
padding: 0 0 20px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.im_message_date {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
div.im_message_author,
|
div.im_message_author,
|
||||||
div.im_message_body {
|
div.im_message_body {
|
||||||
display: block;
|
display: block;
|
||||||
@ -2245,6 +2292,37 @@ a.im_message_fwd_photo {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.im_history_loading {
|
||||||
|
width: 60px;
|
||||||
|
margin: 0 auto;
|
||||||
|
visibility: hidden;
|
||||||
|
|
||||||
|
&.vertical-aligned {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.im_history_loading_more {
|
||||||
|
display: block;
|
||||||
|
width: 26px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px 0 0;
|
||||||
|
visibility: hidden;
|
||||||
|
|
||||||
|
&.im_history_loading_more_active {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.im_history_loading_less {
|
||||||
|
display: block;
|
||||||
|
width: 26px;
|
||||||
|
margin: 0 auto;
|
||||||
|
visibility: hidden;
|
||||||
|
|
||||||
|
&.im_history_loading_less_active {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.im_send_panel_wrap {
|
.im_send_panel_wrap {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
@ -2293,6 +2371,22 @@ textarea.im_message_field {
|
|||||||
height: 50px;
|
height: 50px;
|
||||||
resize: none;
|
resize: none;
|
||||||
}
|
}
|
||||||
|
.im_inline_placeholder_wrap {
|
||||||
|
position: absolute;
|
||||||
|
margin-top: 2px;
|
||||||
|
white-space: nowrap;
|
||||||
|
pointer-events: none;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.im_inline_placeholder_wrap.active {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.im_inline_placeholder_prefix {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
.im_inline_placeholder {
|
||||||
|
color: #9aa2ab;
|
||||||
|
}
|
||||||
|
|
||||||
.icon-online {
|
.icon-online {
|
||||||
background: #6ec26d;
|
background: #6ec26d;
|
||||||
@ -2423,7 +2517,27 @@ img.img_fullsize {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Message composer */
|
/* Message composer */
|
||||||
|
.composer_progress_icon {
|
||||||
|
display: block;
|
||||||
|
opacity: 0;
|
||||||
|
position: absolute;
|
||||||
|
right: 3px;
|
||||||
|
top: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
margin-top: 1px;
|
||||||
|
transition: opacity cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.2s;
|
||||||
|
pointer-events: none;
|
||||||
|
|
||||||
|
.composer_progress_enabled & {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
.composer_emoji_insert_btn {
|
.composer_emoji_insert_btn {
|
||||||
|
opacity: 1;
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 3px;
|
right: 3px;
|
||||||
@ -2434,7 +2548,13 @@ img.img_fullsize {
|
|||||||
width: 22px;
|
width: 22px;
|
||||||
height: 22px;
|
height: 22px;
|
||||||
margin-top: 1px;
|
margin-top: 1px;
|
||||||
|
transition: opacity cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.2s;
|
||||||
|
|
||||||
|
.composer_progress_enabled & {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-emoji {
|
.icon-emoji {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 22px;
|
width: 22px;
|
||||||
@ -2757,6 +2877,7 @@ a.composer_emoji_btn {
|
|||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
margin-top: -5px;
|
margin-top: -5px;
|
||||||
margin-left: -1px;
|
margin-left: -1px;
|
||||||
|
width: 180px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.composer_dropdown {
|
.composer_dropdown {
|
||||||
@ -2780,9 +2901,10 @@ a.composer_emoji_btn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
li a:hover,
|
li a:hover,
|
||||||
li a.composer_autocomplete_option_active {
|
li.composer_autocomplete_option_active a {
|
||||||
color: #52719a;
|
color: #52719a;
|
||||||
background: #f2f6fa;
|
background: #f2f6fa;
|
||||||
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2802,7 +2924,7 @@ a.composer_emoji_btn {
|
|||||||
|
|
||||||
.composer_dropdown {
|
.composer_dropdown {
|
||||||
li a:hover .composer_user_mention,
|
li a:hover .composer_user_mention,
|
||||||
li a.composer_autocomplete_option_active .composer_user_mention {
|
li.composer_autocomplete_option_active a .composer_user_mention {
|
||||||
color: #698192;
|
color: #698192;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2861,7 +2983,7 @@ a.composer_emoji_btn {
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
a.composer_command_option:hover .composer_command_desc,
|
a.composer_command_option:hover .composer_command_desc,
|
||||||
a.composer_command_option.composer_autocomplete_option_active .composer_command_desc {
|
.composer_autocomplete_option_active a.composer_command_option .composer_command_desc {
|
||||||
color: #698192;
|
color: #698192;
|
||||||
}
|
}
|
||||||
.composer_command_desc .emoji {
|
.composer_command_desc .emoji {
|
||||||
@ -3031,6 +3153,64 @@ _:-ms-lang(x), .composer_rich_textarea:empty:focus:before {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.inline_results_wrap {
|
||||||
|
line-height: 0;
|
||||||
|
}
|
||||||
|
.inline_result_wrap {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.inline_result_gif,
|
||||||
|
.inline_result_photo {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.inline_result_article {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.inline_article_thumb_wrap {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
margin-right: 10px;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.inline_article_thumb {
|
||||||
|
max-width: 50px;
|
||||||
|
max-height: 50px;
|
||||||
|
line-height: 0;
|
||||||
|
}
|
||||||
|
.inline_article_thumb_initials {
|
||||||
|
background: rgba(0,0,0, 0.05);
|
||||||
|
line-height: 50px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 25px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
.inline_article_content_wrap {
|
||||||
|
overflow: hidden;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.inline_article_title {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.composer_dropdown > li.inline_result_gif > a,
|
||||||
|
.composer_dropdown > li.inline_result_photo > a {
|
||||||
|
padding: 0;
|
||||||
|
line-height: 0;
|
||||||
|
display: block;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.inline_result_gif .img_gif_video,
|
||||||
|
.inline_result_photo .inline_result_photo_image {
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
.inline_result_gif_mtproto,
|
||||||
|
.inline_result_gif_http,
|
||||||
|
.inline_result_photo_mtproto,
|
||||||
|
.inline_result_photo_http {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.error_modal_window {
|
.error_modal_window {
|
||||||
.modal-dialog {
|
.modal-dialog {
|
||||||
@ -3553,64 +3733,83 @@ h5 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Gif documents */
|
/* Gif documents */
|
||||||
.img_gif_with_progress_wrap {
|
.img_gif_image_wrap {
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
float: left;
|
}
|
||||||
margin-top: 3px;
|
.img_gif_meta {
|
||||||
max-width: 100%;
|
background: rgba(0,0,0,0.3);
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
line-height: 0;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 2;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
margin: 0 auto;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -20px;
|
||||||
|
margin-top: -20px;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.img_gif_label {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #FFF;
|
||||||
|
display: block;
|
||||||
|
line-height: 40px;
|
||||||
|
font-size: 13px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.icon-cancel {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -9px;
|
||||||
|
margin-top: -1px;
|
||||||
|
|
||||||
|
.icon-bar {
|
||||||
|
display: block;
|
||||||
|
width: 18px;
|
||||||
|
height: 2px;
|
||||||
|
background: #FFF;
|
||||||
|
transform-origin: 50% 50%;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
.transform(rotate(-45deg));
|
||||||
|
}
|
||||||
|
&:last-child {
|
||||||
|
.transform(translate3d(0,-2px,0) rotate(45deg));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.img_gif_thumb {
|
.img_gif_thumb {
|
||||||
-webkit-filter: blur(3px);
|
-webkit-filter: blur(2px);
|
||||||
-moz-filter: blur(3px);
|
-moz-filter: blur(2px);
|
||||||
-o-filter: blur(3px);
|
-o-filter: blur(2px);
|
||||||
-ms-filter: blur(3px);
|
-ms-filter: blur(2px);
|
||||||
filter: blur(3px);
|
filter: blur(2px);
|
||||||
filter: progid:DXImageTransform.Microsoft.Blur(PixelRadius='3');
|
filter: progid:DXImageTransform.Microsoft.Blur(PixelRadius='3');
|
||||||
margin: -1px;
|
transform-origin: center center;
|
||||||
padding: 1px;
|
-webkit-transform-origin: center center;
|
||||||
|
-webkit-transform: scale(1.02, 1.02);
|
||||||
|
transform: scale(1.02, 1.02);
|
||||||
|
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
.img_gif_image {
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
.img_gif_info_wrap {
|
|
||||||
color: #fff;
|
|
||||||
font-size: 10px;
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
padding: 4px;
|
|
||||||
}
|
|
||||||
.img_gif_label,
|
|
||||||
.img_gif_size {
|
|
||||||
padding: 1px 8px;
|
|
||||||
background: rgba(0,0,0,0.5);
|
|
||||||
border-radius: 3px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.img_gif_progress_wrap {
|
.img_gif_meta_contents {
|
||||||
position: absolute;
|
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.2s;
|
||||||
bottom: 0;
|
}
|
||||||
left: 0;
|
.img_gif_meta_contents.ng-leave.ng-leave-active,
|
||||||
right: 0;
|
.img_gif_meta_contents.ng-enter {
|
||||||
|
opacity: 0;
|
||||||
.tg_progress {
|
}
|
||||||
background: rgba(0,0,0, 0.6);
|
.img_gif_meta_contents.ng-leave,
|
||||||
border-color: rgba(0,0,0, 0.6);
|
.img_gif_meta_contents.ng-enter.ng-enter-active {
|
||||||
border-width: 8px;
|
opacity: 1;
|
||||||
height: 18px;
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.progress-bar {
|
|
||||||
background: #fff;
|
|
||||||
height: 2px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.countries_modal_window {
|
.countries_modal_window {
|
||||||
|
@ -748,7 +748,6 @@ a.footer_link.active:active {
|
|||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 39px;
|
height: 39px;
|
||||||
padding: 13px 0 8px;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
}
|
}
|
||||||
@ -758,7 +757,7 @@ a.footer_link.active:active {
|
|||||||
color: #999;
|
color: #999;
|
||||||
max-width: 556px;
|
max-width: 556px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 0 81px 0 85px;
|
padding: 13px 81px 8px 85px;
|
||||||
|
|
||||||
a.im_history_typing_author {
|
a.im_history_typing_author {
|
||||||
color: #999;
|
color: #999;
|
||||||
@ -767,6 +766,10 @@ a.footer_link.active:active {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.im_history_loading_less {
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Contacts modal */
|
/* Contacts modal */
|
||||||
.contacts_modal {
|
.contacts_modal {
|
||||||
&_window {
|
&_window {
|
||||||
|
27
app/partials/desktop/composer_dropdown.html
Normal file
27
app/partials/desktop/composer_dropdown.html
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<div ng-switch="type">
|
||||||
|
|
||||||
|
<ul ng-switch-when="mentions" class="composer_dropdown">
|
||||||
|
<li ng-repeat="user in mentionUsers">
|
||||||
|
<a class="composer_mention_option" data-mention="{{user.username}}">
|
||||||
|
<span class="composer_user_photo" my-peer-photolink="user.id" img-class="composer_user_photo"></span>
|
||||||
|
<span class="composer_user_name" ng-bind-html="user.rFullName"></span>
|
||||||
|
<span class="composer_user_mention" ng-bind="'@' + user.username"></span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ul ng-switch-when="commands" class="composer_dropdown">
|
||||||
|
<li ng-repeat="command in commands track by (command.botID + command.value)">
|
||||||
|
<a class="composer_command_option" data-command="{{command.value}}">
|
||||||
|
<span class="composer_user_photo" my-peer-photolink="command.botID" img-class="composer_user_photo"></span>
|
||||||
|
<span class="composer_command_value" ng-bind="command.value"></span>
|
||||||
|
<span class="composer_command_desc" ng-bind-html="command.rDescription"></span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ul ng-switch-when="emoji" my-emoji-suggestions="emojiCodes" class="composer_dropdown"></ul>
|
||||||
|
|
||||||
|
<div ng-switch-when="inline" my-inline-results="botResults"></div>
|
||||||
|
|
||||||
|
</div>
|
@ -3,11 +3,14 @@
|
|||||||
<div class="img_gif_image_wrap">
|
<div class="img_gif_image_wrap">
|
||||||
|
|
||||||
<div class="img_gif_meta" ng-show="!isActive" ng-switch="document.progress.enabled">
|
<div class="img_gif_meta" ng-show="!isActive" ng-switch="document.progress.enabled">
|
||||||
<div ng-switch-when="true" my-arc-progress="document.progress.percent"></div>
|
<div ng-switch-when="true" class="img_gif_meta_contents">
|
||||||
<div ng-switch-default class="img_gif_info_wrap">
|
<i class="icon icon-cancel">
|
||||||
<div class="img_gif_label pull-left">GIF</div>
|
<i class="icon icon-bar"></i>
|
||||||
<div ng-if="!document.downloaded" class="img_gif_size pull-right" ng-bind="::document.size | formatSize"></div>
|
<i class="icon icon-bar"></i>
|
||||||
|
</i>
|
||||||
|
<div my-arc-progress="document.progress.percent"></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div ng-switch-default class="img_gif_label noselect img_gif_meta_contents">GIF</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ng-if="document.url" ng-show="document.downloaded && isActive" ng-switch="document.mime_type == 'video/mp4'">
|
<div ng-if="document.url" ng-show="document.downloaded && isActive" ng-switch="document.mime_type == 'video/mp4'">
|
||||||
|
@ -90,8 +90,8 @@
|
|||||||
<div ng-switch-default class="im_history_not_selected" my-vertical-position="0.35" padding="true" my-i18n="im_select_a_chat"></div>
|
<div ng-switch-default class="im_history_not_selected" my-vertical-position="0.35" padding="true" my-i18n="im_select_a_chat"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ng-show="!state.notSelected && !state.loaded" class="im_history_not_selected" my-vertical-position="0.35" padding="true">
|
<div ng-show="!state.notSelected && !state.loaded" class="im_history_loading" my-vertical-position="0.35" padding="true">
|
||||||
<my-i18n msgid="im_loading_history"></my-i18n><span my-loading-dots></span>
|
<div my-arc-progress stroke="5" width="60"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ng-show="state.loaded">
|
<div ng-show="state.loaded">
|
||||||
@ -103,14 +103,18 @@
|
|||||||
|
|
||||||
<div class="im_history_scrollable">
|
<div class="im_history_scrollable">
|
||||||
<div class="im_history" ng-class="{im_history_selectable: !historyState.botActions, im_history_select_active: historyState.selectActions}">
|
<div class="im_history" ng-class="{im_history_selectable: !historyState.botActions, im_history_select_active: historyState.selectActions}">
|
||||||
<div ng-if="state.empty" class="im_history_empty" ng-switch="state.mayBeHasMore" my-vertical-position="0.25" padding="true">
|
|
||||||
<span ng-switch-when="true">
|
<div class="im_history_empty_wrap" ng-show="state.empty" ng-switch="state.mayBeHasMore">
|
||||||
<my-i18n msgid="im_loading_history"></my-i18n><span my-loading-dots></span>
|
<div ng-switch-when="true" class="im_history_loading" my-vertical-position="0.25" padding="true">
|
||||||
</span>
|
<div my-arc-progress stroke="5" width="60"></div>
|
||||||
<span ng-switch-default my-i18n="im_no_messages"></span>
|
</div>
|
||||||
|
<div ng-switch-default class="im_history_empty" my-vertical-position="0.25" padding="true" my-i18n="im_no_messages"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="im_history_messages" ng-class="{im_history_messages_group: historyPeer.id < 0}">
|
<div class="im_history_messages" ng-class="{im_history_messages_group: historyPeer.id < 0}">
|
||||||
|
<div class="im_history_loading_more" ng-class="{im_history_loading_more_active: state.moreActive}">
|
||||||
|
<div my-arc-progress stroke="3" width="26"></div>
|
||||||
|
</div>
|
||||||
<div class="im_history_messages_peer" ng-show="peerHistory.peerID == historyPeer.id" ng-repeat="peerHistory in peerHistories">
|
<div class="im_history_messages_peer" ng-show="peerHistory.peerID == historyPeer.id" ng-repeat="peerHistory in peerHistories">
|
||||||
<div class="im_history_message_wrap" my-message ng-repeat="historyMessage in peerHistory.messages"></div>
|
<div class="im_history_message_wrap" my-message ng-repeat="historyMessage in peerHistory.messages"></div>
|
||||||
</div>
|
</div>
|
||||||
@ -118,9 +122,12 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="im_history_typing_wrap">
|
<div class="im_history_typing_wrap" ng-switch="historyState.skipped">
|
||||||
|
|
||||||
<div class="im_history_typing" ng-show="historyState.typing.length > 0 && !historyFilter.mediaType && !state.empty" ng-switch="historyState.typing.length" my-i18n>
|
<div ng-switch-when="true" class="im_history_loading_less" ng-class="{im_history_loading_less_active: state.lessActive}">
|
||||||
|
<div my-arc-progress stroke="3" width="26"></div>
|
||||||
|
</div>
|
||||||
|
<div ng-switch-default class="im_history_typing" ng-show="historyState.typing.length > 0 && !historyFilter.mediaType && !state.empty" ng-switch="historyState.typing.length" my-i18n>
|
||||||
<span ng-switch-when="1" my-i18n-format="im_one_typing"></span>
|
<span ng-switch-when="1" my-i18n-format="im_one_typing"></span>
|
||||||
<span ng-switch-when="2" my-i18n-format="im_two_typing"></span>
|
<span ng-switch-when="2" my-i18n-format="im_two_typing"></span>
|
||||||
<span ng-switch-default my-i18n-format="im_many_typing"></span>
|
<span ng-switch-default my-i18n-format="im_many_typing"></span>
|
||||||
@ -175,7 +182,9 @@
|
|||||||
</a>
|
</a>
|
||||||
<a class="pull-left im_panel_own_photo" my-peer-photolink="draftMessage.isBroadcast ? historyPeer.id : ownID" img-class="im_panel_own_photo" watch="true" ng-click="openSettings()" no-open="true"></a>
|
<a class="pull-left im_panel_own_photo" my-peer-photolink="draftMessage.isBroadcast ? historyPeer.id : ownID" img-class="im_panel_own_photo" watch="true" ng-click="openSettings()" no-open="true"></a>
|
||||||
|
|
||||||
<form my-send-form draft-message="draftMessage" mentions="mentions" commands="commands" class="im_send_form" ng-class="{im_send_form_empty: !draftMessage.text.length}">
|
<form my-send-form draft-message="draftMessage" mentions="mentions" commands="commands" class="im_send_form" ng-class="{im_send_form_empty: !draftMessage.text.length, composer_progress_enabled: draftMessage.inlineProgress}">
|
||||||
|
|
||||||
|
<div class="im_send_form_inline_results" my-inline-results="inlineResults"></div>
|
||||||
|
|
||||||
<div class="im_send_reply_wrap" ng-if="draftMessage.replyToMessage != null">
|
<div class="im_send_reply_wrap" ng-if="draftMessage.replyToMessage != null">
|
||||||
<a class="im_send_reply_cancel" ng-mousedown="draftMessage.replyClear()"><i class="icon icon-reply-bar"></i><i class="icon icon-reply-bar"></i></a>
|
<a class="im_send_reply_cancel" ng-mousedown="draftMessage.replyClear()"><i class="icon icon-reply-bar"></i><i class="icon icon-reply-bar"></i></a>
|
||||||
@ -189,23 +198,24 @@
|
|||||||
|
|
||||||
<div class="im_send_field_wrap" ng-class="historyState.replyKeyboard._ == 'replyKeyboardMarkup' ? 'im_send_field_wrap_2ndbtn' : ''">
|
<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_emoji_insert_btn"><i class="icon icon-emoji"></i></a>
|
||||||
|
<div class="composer_progress_icon" my-arc-progress width="22" stroke="2.5"></div>
|
||||||
<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_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>
|
<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>
|
<div class="im_send_dropbox_wrap" my-i18n="im_photos_drop_text"></div>
|
||||||
<textarea ng-model="draftMessage.text" class="form-control im_message_field no_outline" dir="auto"></textarea>
|
<textarea ng-model="draftMessage.text" class="form-control im_message_field no_outline" dir="auto" ng-trim="false"></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="im_send_buttons_wrap clearfix">
|
<div class="im_send_buttons_wrap clearfix">
|
||||||
<button type="submit" class="btn btn-md im_submit" my-i18n="im_submit_message"></button>
|
<button type="submit" class="btn btn-md im_submit" my-i18n="im_submit_message"></button>
|
||||||
|
|
||||||
<div class="im_attach pull-left">
|
<div class="im_attach pull-left">
|
||||||
<input type="file" class="im_attach_input" size="28" multiple="true" title="{{'im_attach_file_title' | i18n}}" />
|
<input type="file" class="im_attach_input" size="28" multiple="multiple" title="{{'im_attach_file_title' | i18n}}" />
|
||||||
<i class="icon icon-paperclip"></i>
|
<i class="icon icon-paperclip"></i>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="im_media_attach pull-left">
|
<div class="im_media_attach pull-left">
|
||||||
<input type="file" class="im_media_attach_input" size="28" multiple="true" accept="image/*, video/*, audio/*" title="{{'im_media_attach_title' | i18n}}"/>
|
<input type="file" class="im_media_attach_input" size="28" multiple="multiple" accept="image/*, video/*, audio/*" title="{{'im_media_attach_title' | i18n}}"/>
|
||||||
<i class="icon icon-camera"></i>
|
<i class="icon icon-camera"></i>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -234,4 +244,4 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="footer_wrap footer_empty"></div>
|
<div class="footer_wrap footer_empty"></div>
|
||||||
|
53
app/partials/desktop/inline_results.html
Normal file
53
app/partials/desktop/inline_results.html
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<ul class="inline_results_wrap composer_dropdown">
|
||||||
|
<li class="inline_result_wrap" ng-class="'inline_result_' + result.type" ng-repeat="result in botResults.results track by result.qID" ng-switch="result.type">
|
||||||
|
|
||||||
|
<a ng-switch-when="gif" class="img_gif_with_progress_wrap" data-inlineid="{{result.qID}}" ng-style="::{width: result.thumbW, height: result.thumbH}" ng-switch="result._">
|
||||||
|
<div ng-switch-when="botInlineMediaResultDocument" ng-switch="result.document.url !== undefined" class="inline_result_gif_mtproto">
|
||||||
|
<div ng-switch-when="true" ng-switch="result.document.mime_type == 'video/mp4'">
|
||||||
|
<video ng-switch-when="true" width="{{result.thumbW}}" height="{{result.thumbH}}" loop autoplay class="img_gif_video">
|
||||||
|
<source ng-src="{{result.document.url}}" type="video/mp4">
|
||||||
|
</video>
|
||||||
|
<img ng-switch-default class="img_gif_image" ng-src="{{result.document.url}}" width="{{result.thumbW}}" height="{{result.thumbH}}" />
|
||||||
|
</div>
|
||||||
|
<div ng-switch-default class="img_gif_image_wrap">
|
||||||
|
<img class="img_gif_thumb" my-load-thumb thumb="result.document.thumb" width="{{result.thumbW}}" height="{{result.thumbH}}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div ng-switch-default ng-switch="result.contentUrl !== undefined" class="inline_result_gif_http">
|
||||||
|
<div ng-switch-when="true" ng-switch="result.content_type == 'video/mp4'">
|
||||||
|
<video ng-switch-when="true" width="{{result.thumbW}}" height="{{result.thumbH}}" loop autoplay class="img_gif_video">
|
||||||
|
<source ng-src="{{result.contentUrl}}" type="video/mp4">
|
||||||
|
</video>
|
||||||
|
<img ng-switch-default class="img_gif_image" ng-src="{{result.contentUrl}}" width="{{result.thumbW}}" height="{{result.thumbH}}" />
|
||||||
|
</div>
|
||||||
|
<img ng-switch-default ng-if="result.thumbUrl !== undefined" class="img_gif_thumb" width="{{result.thumbW}}" height="{{result.thumbH}}" ng-src="{{result.thumbUrl}}" />
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a ng-switch-when="photo" data-inlineid="{{result.qID}}" ng-style="::{width: result.thumbW, height: result.thumbH}" ng-switch="result._">
|
||||||
|
<div ng-switch-when="botInlineMediaResultPhoto" class="inline_result_photo_mtproto">
|
||||||
|
<img
|
||||||
|
class="inline_result_photo_image"
|
||||||
|
my-load-thumb
|
||||||
|
thumb="result.thumb"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div ng-switch-default ng-switch="result.contentUrl !== undefined" class="inline_result_photo_http">
|
||||||
|
<img ng-switch-default ng-if="result.thumbUrl !== undefined" class="inline_result_photo_image" width="{{result.thumbW}}" height="{{result.thumbH}}" ng-src="{{result.thumbUrl}}" />
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a ng-switch-default class="inline_result_article clearfix" data-inlineid="{{result.qID}}">
|
||||||
|
<div class="inline_article_thumb_wrap pull-left" ng-switch="result.thumbUrl !== undefined">
|
||||||
|
<img ng-switch-when="true" class="inline_article_thumb" ng-src="{{result.thumbUrl}}"/>
|
||||||
|
<div ng-switch-default class="inline_article_thumb_initials" ng-bind="result.initials"></div>
|
||||||
|
</div>
|
||||||
|
<div class="inline_article_content_wrap">
|
||||||
|
<div class="inline_article_title" ng-if="::result.title.length > 0" ng-bind-html="::result.rTitle"></div>
|
||||||
|
<div class="inline_article_description" ng-if="::result.description.length > 0" ng-bind-html="::result.rDescription"></div>
|
||||||
|
<div class="inline_article_url" ng-if="::result.url.length > 0" ng-bind="::result.url"></div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
</ul>
|
@ -39,12 +39,12 @@
|
|||||||
<i class="icon-message-views"></i><span class="im_message_views_cnt" my-message-views="historyMessage.mid"></span>
|
<i class="icon-message-views"></i><span class="im_message_views_cnt" my-message-views="historyMessage.mid"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span class="im_message_date" ng-bind="::historyMessage.date | time"></span>
|
<span class="im_message_date clickable" ng-bind="::historyMessage.date | time"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="im_message_body" ng-class="::{im_message_body_media: historyMessage._ == 'message' && historyMessage.media ? true : false}">
|
<div class="im_message_body" ng-class="::{im_message_body_media: historyMessage._ == 'message' && historyMessage.media ? true : false}">
|
||||||
|
|
||||||
<a class="im_message_author" my-peer-link="historyMessage.fromID" short="historyMessage.toID > 0" color="historyMessage.toID < 0" no-watch="true"></a><span ng-if="::historyMessage.viaBotID && !historyMessage.fwdFromID" class="im_message_author_via" my-i18n="message_via_bot"><my-i18n-param name="bot"><a class="im_message_fwd_author" my-peer-link="historyMessage.viaBotID" username="true" no-watch="true"></a></my-i18n-param></span>
|
<a class="im_message_author" my-peer-link="historyMessage.fromID" short="historyMessage.toID > 0" color="historyMessage.toID < 0" no-watch="true"></a><span ng-if="::historyMessage.viaBotID && !historyMessage.fwdFromID" class="im_message_author_via" my-i18n="message_via_bot"><my-i18n-param name="bot"><a class="im_message_fwd_author" my-peer-link="historyMessage.viaBotID" username="true" no-watch="true" ng-click="selectInlineBot(historyMessage.viaBotID, $event)"></a></my-i18n-param></span>
|
||||||
|
|
||||||
<a class="im_message_reply_wrap" my-reply-message="historyMessage.reply_to_msg" ng-if="::historyMessage.reply_to_mid"></a>
|
<a class="im_message_reply_wrap" my-reply-message="historyMessage.reply_to_msg" ng-if="::historyMessage.reply_to_mid"></a>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user