webogram-i2p/app/js/messages_manager.js
2015-10-06 13:55:23 +03:00

2602 lines
83 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*!
* Webogram v0.4.8 - messaging web application for MTProto
* https://github.com/zhukov/webogram
* Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com>
* https://github.com/zhukov/webogram/blob/master/LICENSE
*/
'use strict';
angular.module('myApp.services')
.service('AppMessagesManager', function ($q, $rootScope, $location, $filter, $timeout, $sce, ApiUpdatesManager, AppUsersManager, AppChatsManager, AppPeersManager, AppPhotosManager, AppVideoManager, AppDocsManager, AppAudioManager, AppWebPagesManager, MtpApiManager, MtpApiFileManager, RichTextProcessor, NotificationsManager, PeersSelectService, Storage, AppProfileManager, FileManager, TelegramMeWebService, ErrorService, StatusManager, _) {
var messagesStorage = {};
var messagesForHistory = {};
var messagesForDialogs = {};
var historiesStorage = {};
var dialogsStorage = {count: null, dialogs: []};
var pendingByRandomID = {};
var pendingByMessageID = {};
var pendingAfterMsgs = {};
var sendFilePromise = $q.when();
var tempID = -1;
var dialogsIndex = SearchIndexManager.createIndex(),
cachedResults = {query: false};
var lastSearchFilter = {},
lastSearchResults = [];
var needSingleMessages = [],
fetchSingleMessagesTimeout = false;
var serverTimeOffset = 0,
timestampNow = tsNow(true),
midnightNoOffset = timestampNow - (timestampNow % 86400),
midnightOffseted = new Date(),
midnightOffset;
Storage.get('server_time_offset').then(function (to) {
if (to) {
serverTimeOffset = to;
}
});
var maxSeenID = false;
if (Config.Modes.packed) {
Storage.get('max_seen_msg').then(function (maxID) {
maxSeenID = maxID || 0;
});
}
var dateOrTimeFilter = $filter('dateOrTime');
var fwdMessagesPluralize = _.pluralize('conversation_forwarded_X_messages');
midnightOffseted.setHours(0);
midnightOffseted.setMinutes(0);
midnightOffseted.setSeconds(0);
midnightOffset = midnightNoOffset - (Math.floor(+midnightOffseted / 1000));
NotificationsManager.start();
var allChannelsLoaded = false;
var channelsLoadPromise = false;
var allDialogsLoaded = false
var loadedDialogsCount = 0;
var dialogsNum = 0;
var minDialogsIndex = Math.pow(2, 50);
function getConversations (query, offsetIndex, limit) {
var curDialogStorage = dialogsStorage;
var isSearch = angular.isString(query) && query.length;
if (isSearch) {
if (!limit || cachedResults.query !== query) {
cachedResults.query = query;
var results = SearchIndexManager.search(query, dialogsIndex);
cachedResults.dialogs = [];
angular.forEach(dialogsStorage.dialogs, function (dialog) {
if (results[dialog.peerID]) {
cachedResults.dialogs.push(dialog);
}
});
cachedResults.count = cachedResults.dialogs.length;
}
curDialogStorage = cachedResults;
} else {
cachedResults.query = false;
}
var offset = 0;
if (offsetIndex > 0) {
for (offset = 0; offset < curDialogStorage.dialogs.length; offset++) {
if (offsetIndex > curDialogStorage.dialogs[offset].index) {
break;
}
}
}
limit = limit || 20;
if (
isSearch ||
(allChannelsLoaded && allDialogsLoaded) ||
(
curDialogStorage.dialogs.length >= offset + limit &&
curDialogStorage.dialogs[offset + limit - 1].index >= minDialogsIndex
)
) {
return $q.when({
dialogs: curDialogStorage.dialogs.slice(offset, offset + limit)
});
}
return $q.all([getAllChannels(), getTopMessages(loadedDialogsCount, limit)]).then(function () {
offset = 0;
if (offsetIndex > 0) {
for (offset = 0; offset < curDialogStorage.dialogs.length; offset++) {
if (offsetIndex > curDialogStorage.dialogs[offset].index) {
break;
}
}
}
return {
dialogs: curDialogStorage.dialogs.slice(offset, offset + limit)
}
});
}
function getDialogByPeerID (peerID) {
for (var i = 0; i < dialogsStorage.dialogs.length; i++) {
if (dialogsStorage.dialogs[i].peerID == peerID) {
return [dialogsStorage.dialogs[i], i];
}
}
return [];
}
function saveChannelDialog (channelID, dialog) {
var peerID = -channelID;
var peerText = AppPeersManager.getPeerSearchText(peerID);
SearchIndexManager.indexObject(peerID, peerText, dialogsIndex);
var mid = getFullMessageID(dialog.top_important_message, channelID);
dialog.top_message = mid;
dialog.unread_count = dialog.unread_important_count;
dialog.read_inbox_max_id = getFullMessageID(dialog.read_inbox_max_id, channelID);
var message = getMessage(dialog.top_message);
var topDate = message.date;
var channel = AppChatsManager.getChat(channelID);
if (!topDate || channel.date && channel.date > topDate) {
topDate = channel.date;
}
dialog.index = generateDialogIndex(topDate);
dialog.peerID = peerID;
pushDialogToStorage(dialog);
// Because we saved message without dialog present
if (message.mid && message.mid > dialog.read_inbox_max_id) {
message.unread = true;
}
if (historiesStorage[peerID] === undefined) {
var historyStorage = {count: null, history: [mid], pending: []};
historiesStorage[peerID] = historyStorage;
}
NotificationsManager.savePeerSettings(peerID, dialog.notify_settings);
ApiUpdatesManager.addChannelState(channelID, dialog.pts);
}
function getAllChannels () {
if (channelsLoadPromise) {
return channelsLoadPromise;
}
return channelsLoadPromise = MtpApiManager.invokeApi('channels.getDialogs', {
offset: 0,
limit: 100
}).then(function (dialogsResult) {
AppUsersManager.saveApiUsers(dialogsResult.users);
AppChatsManager.saveApiChats(dialogsResult.chats);
saveMessages(dialogsResult.messages);
angular.forEach(dialogsResult.dialogs, function (dialog) {
var peerID = AppPeersManager.getPeerID(dialog.peer);
var channelID = -peerID;
saveChannelDialog(channelID, dialog);
NotificationsManager.savePeerSettings(peerID, dialog.notify_settings);
ApiUpdatesManager.addChannelState(channelID, dialog.pts);
});
allChannelsLoaded = true;
});
}
function getTopMessages (offset, limit) {
return MtpApiManager.invokeApi('messages.getDialogs', {
offset: offset,
limit: limit
}).then(function (dialogsResult) {
if (!offset) {
TelegramMeWebService.setAuthorized(true);
}
// Server-side bug
if (dialogsResult.count && offset >= dialogsResult.count) {
dialogsResult.dialogs = [];
}
AppUsersManager.saveApiUsers(dialogsResult.users);
AppChatsManager.saveApiChats(dialogsResult.chats);
saveMessages(dialogsResult.messages);
if (!dialogsResult.dialogs.length) {
allDialogsLoaded = true;
}
else if (!offset) {
incrementMaxSeenID(dialogsResult.dialogs[0].top_message);
}
angular.forEach(dialogsResult.dialogs, function (dialog) {
var peerID = AppPeersManager.getPeerID(dialog.peer);
var peerText = AppPeersManager.getPeerSearchText(peerID);
SearchIndexManager.indexObject(peerID, peerText, dialogsIndex);
var message = getMessage(dialog.top_message);
dialog.index = generateDialogIndex(message.date);
dialog.peerID = peerID;
pushDialogToStorage(dialog);
if (historiesStorage[peerID] === undefined) {
var historyStorage = {count: null, history: [dialog.top_message], pending: []};
historiesStorage[peerID] = historyStorage;
if (mergeReplyKeyboard(historyStorage, message)) {
$rootScope.$broadcast('history_reply_markup', {peerID: peerID});
}
}
NotificationsManager.savePeerSettings(peerID, dialog.notify_settings);
if (
dialog.unread_count > 0 &&
maxSeenID &&
dialog.top_message > maxSeenID
) {
var notifyPeer = message.flags & 16 ? message.from_id : peerID;
if (message.unread && !message.out) {
NotificationsManager.getPeerMuted(notifyPeer).then(function (muted) {
if (!muted) {
notifyAboutMessage(message);
}
});
}
}
});
});
}
function generateDialogIndex (date) {
if (date === undefined) {
date = tsNow(true) + serverTimeOffset;
}
return (date * 0x10000) + ((++dialogsNum) & 0xFFFF);
}
function pushDialogToStorage (dialog) {
var dialogs = dialogsStorage.dialogs;
var pos = getDialogByPeerID(dialog.peerID)[1];
var index = dialog.index;
var isDialog = dialog._ == 'dialog';
if (pos !== undefined) {
dialogs.splice(pos, 1);
}
else if (isDialog) {
loadedDialogsCount++;
if (index < minDialogsIndex) {
minDialogsIndex = index;
}
}
var i, len = dialogs.length;
if (!len || index < dialogs[len - 1].index) {
dialogs.push(dialog);
}
else if (index >= dialogs[0].index) {
dialogs.unshift(dialog);
}
else {
for (i = 0; i < len; i++) {
if (index > dialogs[i].index) {
dialogs.splice(i, 0, dialog);
break;
}
}
}
}
function requestHistory (inputPeer, maxID, limit, offset) {
var peerID = AppPeersManager.getPeerID(inputPeer);
var isChannel = AppPeersManager.isChannel(peerID);
var promise;
if (isChannel) {
promise = MtpApiManager.invokeApi('channels.getImportantHistory', {
channel: AppChatsManager.getChannelInput(-peerID),
offset_id: maxID ? getMessageLocalID(maxID) : 0,
add_offset: offset || 0,
limit: limit || 0
});
} else {
promise = MtpApiManager.invokeApi('messages.getHistory', {
peer: inputPeer,
offset_id: maxID ? getMessageLocalID(maxID) : 0,
add_offset: offset || 0,
limit: limit || 0
}, {noErrorBox: true});
}
return promise.then(function (historyResult) {
AppUsersManager.saveApiUsers(historyResult.users);
AppChatsManager.saveApiChats(historyResult.chats);
saveMessages(historyResult.messages);
if (isChannel) {
ApiUpdatesManager.addChannelState(-peerID, historyResult.pts);
}
if (
peerID < 0 ||
!AppUsersManager.isBot(peerID) ||
(historyResult.messages.length == limit && limit < historyResult.count)
) {
return historyResult;
}
return AppProfileManager.getProfile(peerID).then(function (userFull) {
var description = userFull.bot_info && userFull.bot_info.description;
if (description) {
var messageID = tempID--;
var message = {
_: 'messageService',
id: messageID,
from_id: peerID,
to_id: AppPeersManager.getOutputPeer(peerID),
flags: 0,
date: tsNow(true) + serverTimeOffset,
action: {
_: 'messageActionBotIntro',
description: description
}
};
saveMessages([message]);
historyResult.messages.push(message);
if (historyResult.count) {
historyResult.count++;
}
}
return historyResult;
});
}, function (error) {
switch (error.type) {
case 'CHANNEL_PRIVATE':
var channel = AppChatsManager.getChat(-peerID);
channel = {_: 'channelForbidden', access_hash: channel.access_hash, title: channel.title};
ApiUpdatesManager.processUpdateMessage({
_: 'updates',
updates: [{
_: 'updateChannel',
channel_id: -peerID
}],
chats: [channel],
users: []
});
break;
}
return $q.reject(error);
});
}
var channelLocals = {};
var channelsByLocals = {};
var channelCurLocal = 0;
var fullMsgIDModulus = 4294967296;
function getFullMessageID (msgID, channelID) {
if (!channelID || msgID < 0) {
return msgID;
}
msgID = getMessageLocalID(msgID);
var localStart = channelLocals[channelID];
if (!localStart) {
localStart = (++channelCurLocal) * fullMsgIDModulus;
channelsByLocals[localStart] = channelID;
channelLocals[channelID] = localStart;
}
return localStart + msgID;
}
function getMessageIDInfo (fullMsgID) {
if (fullMsgID < fullMsgIDModulus) {
return [fullMsgID, 0];
}
var msgID = fullMsgID % fullMsgIDModulus;
var channelID = channelsByLocals[fullMsgID - msgID];
return [msgID, channelID];
}
function getMessageLocalID (fullMsgID) {
return fullMsgID % fullMsgIDModulus;
}
function fillHistoryStorage (inputPeer, maxID, fullLimit, historyStorage) {
// console.log('fill history storage', inputPeer, maxID, fullLimit, angular.copy(historyStorage));
return requestHistory (inputPeer, maxID, fullLimit).then(function (historyResult) {
historyStorage.count = historyResult.count || historyResult.messages.length;
var offset = 0;
if (!maxID && historyResult.messages.length) {
maxID = historyResult.messages[0].mid + 1;
}
if (maxID > 0) {
for (offset = 0; offset < historyStorage.history.length; offset++) {
if (maxID > historyStorage.history[offset]) {
break;
}
}
}
historyStorage.history.splice(offset, historyStorage.history.length - offset);
angular.forEach(historyResult.messages, function (message) {
if (mergeReplyKeyboard(historyStorage, message)) {
$rootScope.$broadcast('history_reply_markup', {peerID: AppPeersManager.getPeerID(inputPeer)});
}
historyStorage.history.push(message.mid);
});
fullLimit -= historyResult.messages.length;
if (fullLimit > 0 && historyStorage.history.length < historyStorage.count) {
maxID = historyStorage.history[historyStorage.history.length - 1];
return fillHistoryStorage(inputPeer, maxID, fullLimit, historyStorage);
}
return true;
});
};
function wrapHistoryResult (peerID, result) {
var unreadOffset = result.unreadOffset;
if (unreadOffset) {
var i, message;
for (i = result.history.length - 1; i >= 0; i--) {
message = messagesStorage[result.history[i]];
if (message && !message.out && message.unread) {
result.unreadOffset = i + 1;
break;
}
}
}
return $q.when(result);
}
function getHistory (inputPeer, maxID, limit, backLimit, prerendered) {
var peerID = AppPeersManager.getPeerID(inputPeer),
historyStorage = historiesStorage[peerID],
offset = 0,
offsetNotFound = false,
unreadOffset = false,
unreadSkip = false;
prerendered = prerendered ? Math.min(50, prerendered) : 0;
if (historyStorage === undefined) {
historyStorage = historiesStorage[peerID] = {count: null, history: [], pending: []};
}
if (!limit && !maxID) {
var foundDialog = getDialogByPeerID(peerID)[0];
if (foundDialog && foundDialog.unread_count > 1) {
var unreadCount = foundDialog.unread_count;
if (unreadSkip = (unreadCount > 50)) {
if (foundDialog.read_inbox_max_id) {
maxID = foundDialog.read_inbox_max_id;
backLimit = 16;
unreadOffset = 16;
limit = 4;
} else {
limit = 20;
unreadOffset = 16;
offset = unreadCount - unreadOffset;
}
} else {
limit = Math.max(10, prerendered, unreadCount + 2);
unreadOffset = unreadCount;
}
}
else if (Config.Mobile) {
limit = 20;
}
}
if (maxID > 0) {
offsetNotFound = true;
for (offset = 0; offset < historyStorage.history.length; offset++) {
if (maxID > historyStorage.history[offset]) {
offsetNotFound = false;
break;
}
}
}
if (!offsetNotFound && (
historyStorage.count !== null && historyStorage.history.length == historyStorage.count ||
historyStorage.history.length >= offset + (limit || 1)
)) {
if (backLimit) {
backLimit = Math.min(offset, backLimit);
offset = Math.max(0, offset - backLimit);
limit += backLimit;
} else {
limit = limit || (offset ? 20 : (prerendered || 5));
}
var history = historyStorage.history.slice(offset, offset + limit);
if (!maxID && historyStorage.pending.length) {
history = historyStorage.pending.slice().concat(history);
}
return wrapHistoryResult(peerID, {
count: historyStorage.count,
history: history,
unreadOffset: unreadOffset,
unreadSkip: unreadSkip
});
}
if (!backLimit && !limit) {
limit = prerendered || 20;
}
if (offsetNotFound) {
offset = 0;
}
if (backLimit || unreadSkip || maxID && historyStorage.history.indexOf(maxID) == -1) {
if (backLimit) {
offset = -backLimit;
limit += backLimit;
}
return requestHistory(inputPeer, maxID, limit, offset).then(function (historyResult) {
historyStorage.count = historyResult.count || historyResult.messages.length;
var history = [];
angular.forEach(historyResult.messages, function (message) {
history.push(message.mid);
});
if (!maxID && historyStorage.pending.length) {
history = historyStorage.pending.slice().concat(history);
}
return wrapHistoryResult(peerID, {
count: historyStorage.count,
history: history,
unreadOffset: unreadOffset,
unreadSkip: unreadSkip
});
})
}
return fillHistoryStorage(inputPeer, maxID, limit, historyStorage).then(function () {
offset = 0;
if (maxID > 0) {
for (offset = 0; offset < historyStorage.history.length; offset++) {
if (maxID > historyStorage.history[offset]) {
break;
}
}
}
var history = historyStorage.history.slice(offset, offset + limit);
if (!maxID && historyStorage.pending.length) {
history = historyStorage.pending.slice().concat(history);
}
return wrapHistoryResult(peerID, {
count: historyStorage.count,
history: history,
unreadOffset: unreadOffset,
unreadSkip: unreadSkip
});
});
}
function getReplyKeyboard (peerID) {
return (historiesStorage[peerID] || {}).reply_markup || false;
}
function mergeReplyKeyboard (historyStorage, message) {
// console.log('merge', message.mid, message.reply_markup, historyStorage.reply_markup);
if (!message.reply_markup &&
!message.out &&
!message.action) {
return false;
}
var messageReplyMarkup = message.reply_markup;
var lastReplyMarkup = historyStorage.reply_markup;
if (messageReplyMarkup) {
if (lastReplyMarkup && lastReplyMarkup.mid >= message.mid) {
return false;
}
if (messageReplyMarkup.pFlags.selective &&
!(message.flags & 16)) {
return false;
}
if (historyStorage.maxOutID &&
message.mid < historyStorage.maxOutID &&
messageReplyMarkup.pFlags.one_time) {
messageReplyMarkup.pFlags.hidden = true;
}
messageReplyMarkup = angular.extend({
id: message.mid
}, messageReplyMarkup);
if (messageReplyMarkup._ != 'replyKeyboardHide') {
messageReplyMarkup.fromID = message.from_id;
}
historyStorage.reply_markup = messageReplyMarkup;
// console.log('set', historyStorage.reply_markup);
return true;
}
if (message.out) {
if (lastReplyMarkup) {
if (lastReplyMarkup.pFlags.one_time &&
!lastReplyMarkup.pFlags.hidden &&
(message.mid > lastReplyMarkup.mid || message.mid < 0) &&
message.message) {
lastReplyMarkup.pFlags.hidden = true;
// console.log('set', historyStorage.reply_markup);
return true;
}
} else if (!historyStorage.maxOutID ||
message.mid > historyStorage.maxOutID) {
historyStorage.maxOutID = message.mid;
}
}
if (message.action &&
message.action._ == 'messageActionChatDeleteUser' &&
(lastReplyMarkup
? message.action.user_id == lastReplyMarkup.fromID
: AppUsersManager.isBot(message.action.user_id)
)
) {
historyStorage.reply_markup = {
_: 'replyKeyboardHide',
mid: message.mid,
flags: 0,
pFlags: {}
};
// console.log('set', historyStorage.reply_markup);
return true;
}
return false;
}
function getSearch (inputPeer, query, inputFilter, maxID, limit) {
var foundMsgs = [],
useSearchCache = !query,
peerID = AppPeersManager.getPeerID(inputPeer),
newSearchFilter = {peer: peerID, filter: inputFilter},
sameSearchCache = useSearchCache && angular.equals(lastSearchFilter, newSearchFilter);
if (useSearchCache && !sameSearchCache) {
lastSearchFilter = newSearchFilter;
lastSearchResults = [];
}
if (!maxID && !query) {
var historyStorage = historiesStorage[peerID];
if (historyStorage !== undefined && historyStorage.history.length) {
var neededContents = {},
neededLimit = limit || 20,
i, message;
switch (inputFilter._) {
case 'inputMessagesFilterPhotos':
neededContents['messageMediaPhoto'] = true;
break;
case 'inputMessagesFilterVideo':
neededContents['messageMediaVideo'] = true;
break;
case 'inputMessagesFilterPhotoVideo':
neededContents['messageMediaPhoto'] = true;
neededContents['messageMediaVideo'] = true;
break;
case 'inputMessagesFilterDocument':
neededContents['messageMediaDocument'] = true;
break;
case 'inputMessagesFilterAudio':
neededContents['messageMediaAudio'] = true;
break;
}
for (i = 0; i < historyStorage.history.length; i++) {
message = messagesStorage[historyStorage.history[i]];
if (message.media && neededContents[message.media._]) {
foundMsgs.push(message.mid);
if (foundMsgs.length >= neededLimit) {
break;
}
}
}
}
// console.log(dT(), sameSearchCache, foundMsgs, lastSearchResults);
if (foundMsgs.length < neededLimit && lastSearchResults.length && sameSearchCache) {
var minID = foundMsgs.length ? foundMsgs[foundMsgs.length - 1] : 0xFFFFFFFF;
for (var i = 0; i < lastSearchResults.length; i++) {
if (lastSearchResults[i] < minID) {
foundMsgs.push(lastSearchResults[i]);
if (foundMsgs.length >= neededLimit) {
break;
}
}
}
}
// console.log(dT(), foundMsgs);
}
if (foundMsgs.length || limit == 1000) {
if (useSearchCache) {
lastSearchResults = listMergeSorted(lastSearchResults, foundMsgs);
}
return $q.when({
count: null,
history: foundMsgs
});
}
return MtpApiManager.invokeApi('messages.search', {
flags: 0,
peer: inputPeer,
q: query || '',
filter: inputFilter || {_: 'inputMessagesFilterEmpty'},
min_date: 0,
max_date: 0,
limit: limit || 20,
max_id: maxID || 0
}).then(function (searchResult) {
AppUsersManager.saveApiUsers(searchResult.users);
AppChatsManager.saveApiChats(searchResult.chats);
saveMessages(searchResult.messages);
var foundCount = searchResult.count || searchResult.messages.length;
foundMsgs = [];
angular.forEach(searchResult.messages, function (message) {
foundMsgs.push(message.mid);
});
if (useSearchCache) {
lastSearchResults = listMergeSorted(lastSearchResults, foundMsgs);
}
return {
count: foundCount,
history: foundMsgs
};
}, function (error) {
if (error.code == 400) {
error.handled = true;
}
return $q.reject(error);
});
}
function getMessage (messageID) {
return messagesStorage[messageID] || {deleted: true};
}
function deleteMessages (messageIDs) {
return MtpApiManager.invokeApi('messages.deleteMessages', {
id: messageIDs
}).then(function (affectedMessages) {
ApiUpdatesManager.processUpdateMessage({
_: 'updateShort',
update: {
_: 'updateDeleteMessages',
messages: messageIDs,
pts: affectedMessages.pts,
pts_count: affectedMessages.pts_count
}
});
return messageIDs;
});
}
function processAffectedHistory (inputPeer, affectedHistory, method) {
ApiUpdatesManager.processUpdateMessage({
_: 'updateShort',
update: {
_: 'updatePts',
pts: affectedHistory.pts,
pts_count: affectedHistory.pts_count
}
});
if (!affectedHistory.offset) {
return $q.when();
}
return MtpApiManager.invokeApi(method, {
peer: inputPeer,
offset: affectedHistory.offset,
max_id: 0
}).then(function (affectedHistory) {
return processAffectedHistory(inputPeer, affectedHistory, method);
});
}
function readHistory (inputPeer) {
// console.trace('start read');
var peerID = AppPeersManager.getPeerID(inputPeer),
isChannel = AppPeersManager.isChannel(peerID),
historyStorage = historiesStorage[peerID],
foundDialog = getDialogByPeerID(peerID)[0];
if (!foundDialog || !foundDialog.unread_count) {
if (!historyStorage || !historyStorage.history.length) {
return false;
}
var messageID,
message,
foundUnread = false;
for (i = historyStorage.history.length; i >= 0; i--) {
messageID = historyStorage.history[i];
message = messagesStorage[messageID];
if (message && !message.out && message.unread) {
foundUnread = true;
break;
}
}
if (!foundUnread) {
return false;
}
}
if (historyStorage.readPromise) {
return historyStorage.readPromise;
}
var apiPromise;
if (isChannel) {
apiPromise = MtpApiManager.invokeApi('channels.readHistory', {
channel: AppChatsManager.getChannelInput(-peerID),
max_id: 0
});
} else {
apiPromise = MtpApiManager.invokeApi('messages.readHistory', {
peer: inputPeer,
offset: 0,
max_id: 0
}).then(function (affectedHistory) {
return processAffectedHistory(inputPeer, affectedHistory, 'messages.readHistory');
});
}
historyStorage.readPromise = apiPromise.then(function () {
if (foundDialog) {
// console.log('done read history', peerID);
foundDialog.unread_count = 0;
$rootScope.$broadcast('dialog_unread', {peerID: peerID, count: 0});
$rootScope.$broadcast('messages_read');
if (historyStorage && historyStorage.history.length) {
foundDialog.read_inbox_max_id = historyStorage.history[0];
}
}
})['finally'](function () {
delete historyStorage.readPromise;
});
if (historyStorage && historyStorage.history.length) {
var messageID, message, i, peerID, foundDialog, dialog;
for (i = 0; i < historyStorage.history.length; i++) {
messageID = historyStorage.history[i];
message = messagesStorage[messageID];
if (message && !message.out) {
message.unread = false;
if (messagesForHistory[messageID]) {
messagesForHistory[messageID].unread = false;
}
if (messagesForDialogs[messageID]) {
messagesForDialogs[messageID].unread = false;
}
NotificationsManager.cancel('msg' + messageID);
}
}
}
NotificationsManager.soundReset(AppPeersManager.getPeerString(peerID))
return historyStorage.readPromise;
}
function readMessages (messageIDs) {
MtpApiManager.invokeApi('messages.readMessageContents', {
id: messageIDs
}).then(function (affectedMessages) {
ApiUpdatesManager.processUpdateMessage({
_: 'updateShort',
update: {
_: 'updateReadMessagesContents',
messages: messageIDs,
pts: affectedMessages.pts,
pts_count: affectedMessages.pts_count
}
});
});
}
function flushHistory (inputPeer) {
// console.log('start flush');
var peerID = AppPeersManager.getPeerID(inputPeer),
historyStorage = historiesStorage[peerID];
return MtpApiManager.invokeApi('messages.deleteHistory', {
peer: inputPeer,
offset: 0
}).then(function (affectedHistory) {
return processAffectedHistory(inputPeer, affectedHistory, 'messages.deleteHistory');
}).then(function () {
var foundDialog = getDialogByPeerID(peerID);
if (foundDialog[0]) {
dialogsStorage.dialogs.splice(foundDialog[1], 1);
}
delete historiesStorage[peerID];
$rootScope.$broadcast('dialog_flush', {peerID: peerID});
});
}
function saveMessages (apiMessages) {
angular.forEach(apiMessages, function (apiMessage) {
if (apiMessage._ == 'messageEmpty') {
return;
}
apiMessage.out = apiMessage.flags & 2 ? true : false;
apiMessage.media_unread = apiMessage.flags & 32 ? true : false;
var toPeerID = AppPeersManager.getPeerID(apiMessage.to_id);
var isChannel = apiMessage.to_id._ == 'peerChannel';
var channelID = isChannel ? -toPeerID : 0;
var mid = getFullMessageID(apiMessage.id, channelID);
apiMessage.mid = mid;
messagesStorage[mid] = apiMessage;
if (channelID && !apiMessage.out) {
var dialog = getDialogByPeerID(toPeerID)[0];
apiMessage.unread = dialog ? mid > dialog.read_inbox_max_id : true;
} else {
apiMessage.unread = apiMessage.flags & 1 ? true : false;
}
if (apiMessage.reply_to_msg_id) {
apiMessage.reply_to_mid = getFullMessageID(apiMessage.reply_to_msg_id, channelID);
}
apiMessage.date -= serverTimeOffset;
apiMessage.toID = toPeerID;
apiMessage.fromID = apiMessage.from_id || toPeerID;
if (apiMessage.fwd_from_id) {
apiMessage.fwdFromID = AppPeersManager.getPeerID(apiMessage.fwd_from_id);
}
var mediaContext = {
user_id: apiMessage.fromID,
date: apiMessage.date
};
if (apiMessage.media) {
switch (apiMessage.media._) {
case 'messageMediaEmpty':
delete apiMessage.media;
break;
case 'messageMediaPhoto':
AppPhotosManager.savePhoto(apiMessage.media.photo, mediaContext);
break;
case 'messageMediaVideo':
AppVideoManager.saveVideo(apiMessage.media.video, mediaContext);
break;
case 'messageMediaDocument':
AppDocsManager.saveDoc(apiMessage.media.document, mediaContext);
break;
case 'messageMediaAudio':
AppAudioManager.saveAudio(apiMessage.media.audio);
break;
case 'messageMediaWebPage':
AppWebPagesManager.saveWebPage(apiMessage.media.webpage, apiMessage.mid, mediaContext);
break;
}
}
if (apiMessage.action) {
if (apiMessage.action._ == 'messageActionChatEditPhoto') {
AppPhotosManager.savePhoto(apiMessage.action.photo, mediaContext);
if (isChannel) {
apiMessage.action._ = 'messageActionChannelEditPhoto';
}
}
else if (isChannel) {
if (apiMessage.action._ == 'messageActionChatEditTitle') {
apiMessage.action._ = 'messageActionChannelEditTitle';
}
if (apiMessage.action._ == 'messageActionChatDeletePhoto') {
apiMessage.action._ = 'messageActionChannelDeletePhoto';
}
}
}
if (apiMessage.reply_markup) {
apiMessage.reply_markup.pFlags = {
resize: (apiMessage.reply_markup.flags & 1) > 0,
one_time: (apiMessage.reply_markup.flags & 2) > 0,
selective: (apiMessage.reply_markup.flags & 4) > 0
};
}
if (apiMessage.message && apiMessage.message.length) {
var myEntities = RichTextProcessor.parseEntities(apiMessage.message);
var apiEntities = apiMessage.entities || [];
apiMessage.totalEntities = RichTextProcessor.mergeEntities(myEntities, apiEntities, !apiMessage.pending);
}
});
}
function sendText(peerID, text, options) {
if (!angular.isString(text) || !text.length) {
return;
}
options = options || {};
var messageID = tempID--,
randomID = [nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)],
randomIDS = bigint(randomID[0]).shiftLeft(32).add(bigint(randomID[1])).toString(),
historyStorage = historiesStorage[peerID],
inputPeer = AppPeersManager.getInputPeerByID(peerID),
flags = 0,
replyToMsgID = options.replyToMsgID,
isChannel = AppPeersManager.isChannel(peerID),
asChannel = isChannel ? true : false,
entities = [],
message;
text = RichTextProcessor.parseMarkdown(text, entities);
if (historyStorage === undefined) {
historyStorage = historiesStorage[peerID] = {count: null, history: [], pending: []};
}
MtpApiManager.getUserID().then(function (fromID) {
if (peerID != fromID) {
flags |= 2;
if (!isChannel && !AppUsersManager.isBot(peerID)) {
flags |= 1;
}
}
if (replyToMsgID) {
flags |= 8;
}
if (asChannel) {
fromID = 0;
} else {
flags |= 256;
}
message = {
_: 'message',
id: messageID,
from_id: fromID,
to_id: AppPeersManager.getOutputPeer(peerID),
flags: flags,
date: tsNow(true) + serverTimeOffset,
message: text,
random_id: randomIDS,
reply_to_msg_id: replyToMsgID,
entities: entities,
pending: true
};
var toggleError = function (on) {
var historyMessage = messagesForHistory[messageID];
if (on) {
message.error = true;
if (historyMessage) {
historyMessage.error = true;
}
} else {
delete message.error;
if (historyMessage) {
delete historyMessage.error;
}
}
$rootScope.$broadcast('messages_pending');
}
message.send = function () {
toggleError(false);
var sentRequestOptions = {};
if (pendingAfterMsgs[peerID]) {
sentRequestOptions.afterMessageID = pendingAfterMsgs[peerID].messageID;
}
var flags = 0;
if (replyToMsgID) {
flags |= 1;
}
if (entities.length) {
flags |= 8;
}
if (asChannel) {
flags |= 16;
}
// console.log(flags, entities);
MtpApiManager.invokeApi('messages.sendMessage', {
flags: flags,
peer: inputPeer,
message: text,
random_id: randomID,
reply_to_msg_id: getMessageLocalID(replyToMsgID),
entities: entities
}, sentRequestOptions).then(function (updates) {
if (updates._ == 'updateShortSentMessage') {
message.flags = updates.flags;
message.date = updates.date;
message.id = updates.id;
message.media = updates.media;
message.entities = updates.entities;
updates = {
_: 'updates',
users: [],
chats: [],
seq: 0,
updates: [{
_: 'updateMessageID',
random_id: randomIDS,
id: updates.id
}, {
_: isChannel ? 'updateNewChannelMessage' : 'updateNewMessage',
message: message,
pts: updates.pts,
pts_count: updates.pts_count
}]
};
}
ApiUpdatesManager.processUpdateMessage(updates);
}, function (error) {
toggleError(true);
})['finally'](function () {
if (pendingAfterMsgs[peerID] === sentRequestOptions) {
delete pendingAfterMsgs[peerID];
}
});
pendingAfterMsgs[peerID] = sentRequestOptions;
};
saveMessages([message]);
historyStorage.pending.unshift(messageID);
$rootScope.$broadcast('history_append', {peerID: peerID, messageID: messageID, my: true});
// setTimeout(function () {
message.send();
// }, 5000);
});
pendingByRandomID[randomIDS] = [peerID, messageID];
};
function sendFile(peerID, file, options) {
options = options || {};
var messageID = tempID--,
randomID = [nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)],
randomIDS = bigint(randomID[0]).shiftLeft(32).add(bigint(randomID[1])).toString(),
historyStorage = historiesStorage[peerID],
inputPeer = AppPeersManager.getInputPeerByID(peerID),
flags = 0,
replyToMsgID = options.replyToMsgID,
isChannel = AppPeersManager.isChannel(peerID),
asChannel = isChannel ? true : false,
attachType, apiFileName, realFileName;
if (!options.isMedia) {
attachType = 'document';
apiFileName = 'document.' + file.type.split('/')[1];
} else if (['image/jpeg', 'image/png', 'image/bmp'].indexOf(file.type) >= 0) {
attachType = 'photo';
apiFileName = 'photo.' + file.type.split('/')[1];
} else if (file.type.substr(0, 6) == 'audio/' || ['video/ogg'].indexOf(file.type) >= 0) {
attachType = 'audio';
apiFileName = 'audio.' + (file.type.split('/')[1] == 'ogg' ? 'ogg' : 'mp3');
} else if (file.type.substr(0, 6) == 'video/') {
attachType = 'video';
apiFileName = 'video.mp4';
} else {
attachType = 'document';
apiFileName = 'document.' + file.type.split('/')[1];
}
if (historyStorage === undefined) {
historyStorage = historiesStorage[peerID] = {count: null, history: [], pending: []};
}
MtpApiManager.getUserID().then(function (fromID) {
if (peerID != fromID) {
flags |= 2;
if (!isChannel && !AppUsersManager.isBot(peerID)) {
flags |= 1;
}
}
if (replyToMsgID) {
flags |= 8;
}
if (asChannel) {
fromID = 0;
} else {
flags |= 256;
}
var media = {
_: 'messageMediaPending',
type: attachType,
file_name: file.name || apiFileName,
size: file.size,
progress: {percent: 1, total: file.size}
};
var message = {
_: 'message',
id: messageID,
from_id: fromID,
to_id: AppPeersManager.getOutputPeer(peerID),
flags: flags,
date: tsNow(true) + serverTimeOffset,
message: '',
media: media,
random_id: randomIDS,
reply_to_msg_id: replyToMsgID,
pending: true
};
var toggleError = function (on) {
var historyMessage = messagesForHistory[messageID];
if (on) {
message.error = true;
if (historyMessage) {
historyMessage.error = true;
}
} else {
delete message.error;
if (historyMessage) {
delete historyMessage.error;
}
}
$rootScope.$broadcast('messages_pending');
}
var uploaded = false,
uploadPromise;
message.send = function () {
var sendFileDeferred = $q.defer();
sendFilePromise.then(function () {
if (!uploaded || message.error) {
uploaded = false;
uploadPromise = MtpApiFileManager.uploadFile(file);
}
uploadPromise.then(function (inputFile) {
inputFile.name = apiFileName;
uploaded = true;
var inputMedia;
switch (attachType) {
case 'photo':
inputMedia = {_: 'inputMediaUploadedPhoto', file: inputFile};
break;
case 'video':
inputMedia = {_: 'inputMediaUploadedVideo', file: inputFile, duration: 0, w: 0, h: 0, mime_type: file.type};
break;
case 'audio':
inputMedia = {_: 'inputMediaUploadedAudio', file: inputFile, duration: 0, mime_type: file.type};
break;
case 'document':
default:
inputMedia = {_: 'inputMediaUploadedDocument', file: inputFile, mime_type: file.type, attributes: [
{_: 'documentAttributeFilename', file_name: file.name}
]};
}
var flags = 0;
if (replyToMsgID) {
flags |= 1;
}
if (asChannel) {
flags |= 16;
}
MtpApiManager.invokeApi('messages.sendMedia', {
flags: flags,
peer: inputPeer,
media: inputMedia,
random_id: randomID,
reply_to_msg_id: getMessageLocalID(replyToMsgID)
}).then(function (updates) {
ApiUpdatesManager.processUpdateMessage(updates);
}, function (error) {
if (attachType == 'photo' &&
error.code == 400 &&
error.type == 'PHOTO_INVALID_DIMENSIONS') {
error.handled = true;
attachType = 'document';
message.send();
return;
}
toggleError(true);
});
}, function (error) {
toggleError(true);
}, function (progress) {
// console.log('upload progress', progress);
media.progress.done = progress.done;
media.progress.percent = Math.max(1, Math.floor(100 * progress.done / progress.total));
$rootScope.$broadcast('history_update', {peerID: peerID});
});
media.progress.cancel = function () {
if (!uploaded) {
sendFileDeferred.resolve();
uploadPromise.cancel();
cancelPendingMessage(randomIDS);
}
}
uploadPromise['finally'](function () {
sendFileDeferred.resolve();
});
});
sendFilePromise = sendFileDeferred.promise;
};
saveMessages([message]);
historyStorage.pending.unshift(messageID);
$rootScope.$broadcast('history_append', {peerID: peerID, messageID: messageID, my: true});
message.send();
});
pendingByRandomID[randomIDS] = [peerID, messageID];
}
function sendOther(peerID, inputMedia, options) {
options = options || {};
var messageID = tempID--,
randomID = [nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)],
randomIDS = bigint(randomID[0]).shiftLeft(32).add(bigint(randomID[1])).toString(),
historyStorage = historiesStorage[peerID],
inputPeer = AppPeersManager.getInputPeerByID(peerID),
replyToMsgID = options.replyToMsgID,
isChannel = AppPeersManager.isChannel(peerID),
asChannel = isChannel ? true : false;
if (historyStorage === undefined) {
historyStorage = historiesStorage[peerID] = {count: null, history: [], pending: []};
}
MtpApiManager.getUserID().then(function (fromID) {
var media;
switch (inputMedia._) {
case 'inputMediaContact':
media = angular.extend({}, inputMedia, {_: 'messageMediaContact'});
break;
case 'inputMediaPhoto':
media = {
_: 'messageMediaPhoto',
photo: AppPhotosManager.getPhoto(inputMedia.id.id)
};
break;
case 'inputMediaDocument':
media = {
_: 'messageMediaDocument',
'document': AppDocsManager.getDoc(inputMedia.id.id)
};
break;
}
var flags = 0;
if (peerID != fromID) {
flags |= 2;
if (!AppUsersManager.isBot(peerID)) {
flags |= 1;
}
}
if (replyToMsgID) {
flags |= 8;
}
if (asChannel) {
fromID = 0;
} else {
flags |= 256;
}
var message = {
_: 'message',
id: messageID,
from_id: fromID,
to_id: AppPeersManager.getOutputPeer(peerID),
flags: flags,
date: tsNow(true) + serverTimeOffset,
message: '',
media: media,
random_id: randomIDS,
reply_to_msg_id: replyToMsgID,
pending: true
};
var toggleError = function (on) {
var historyMessage = messagesForHistory[messageID];
if (on) {
message.error = true;
if (historyMessage) {
historyMessage.error = true;
}
} else {
delete message.error;
if (historyMessage) {
delete historyMessage.error;
}
}
$rootScope.$broadcast('messages_pending');
}
message.send = function () {
var flags = 0;
if (replyToMsgID) {
flags |= 1;
}
if (asChannel) {
flags |= 16;
}
MtpApiManager.invokeApi('messages.sendMedia', {
flags: flags,
peer: inputPeer,
media: inputMedia,
random_id: randomID,
reply_to_msg_id: getMessageLocalID(replyToMsgID)
}).then(function (updates) {
ApiUpdatesManager.processUpdateMessage(updates);
}, function (error) {
toggleError(true);
});
};
saveMessages([message]);
historyStorage.pending.unshift(messageID);
$rootScope.$broadcast('history_append', {peerID: peerID, messageID: messageID, my: true});
message.send();
});
pendingByRandomID[randomIDS] = [peerID, messageID];
}
function forwardMessages (peerID, mids) {
mids = mids.sort();
var flags = 0;
var msgIDs = [];
var randomIDs = [];
var len = mids.length;
var i, mid, msgID;
var fromChannel = getMessageIDInfo(mids[0])[1];
for (i = 0; i < len; i++) {
msgIDs.push(getMessageLocalID(mids[i]));
randomIDs.push([nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)]);
}
var sentRequestOptions = {};
if (pendingAfterMsgs[peerID]) {
sentRequestOptions.afterMessageID = pendingAfterMsgs[peerID].messageID;
}
return MtpApiManager.invokeApi('messages.forwardMessages', {
flags: flags,
from_peer: AppPeersManager.getInputPeerByID(-fromChannel),
id: msgIDs,
random_id: randomIDs,
to_peer: AppPeersManager.getInputPeerByID(peerID),
}, sentRequestOptions).then(function (updates) {
ApiUpdatesManager.processUpdateMessage(updates);
});
};
function startBot (botID, chatID, startParam) {
if (startParam) {
var randomID = bigint(nextRandomInt(0xFFFFFFFF)).shiftLeft(32).add(bigint(nextRandomInt(0xFFFFFFFF))).toString();
return MtpApiManager.invokeApi('messages.startBot', {
bot: AppUsersManager.getUserInput(botID),
chat_id: AppChatsManager.getChatInput(chatID),
random_id: randomID,
start_param: startParam
});
}
var peerID = chatID ? -chatID : botID;
var inputPeer = AppPeersManager.getInputPeerByID(peerID);
if (chatID) {
return MtpApiManager.invokeApi('messages.addChatUser', {
chat_id: AppChatsManager.getChatInput(chatID),
user_id: AppUsersManager.getUserInput(botID)
}).then(function (updates) {
ApiUpdatesManager.processUpdateMessage(updates);
}, function (error) {
if (error && error.type == 'USER_ALREADY_PARTICIPANT') {
var bot = AppUsersManager.getUser(botID);
sendText(-chatID, '/start@' + bot.username);
error.handled = true;
}
});
}
return sendText(botID, '/start');
}
function cancelPendingMessage (randomID) {
var pendingData = pendingByRandomID[randomID];
console.log('pending', randomID, pendingData);
if (pendingData) {
var peerID = pendingData[0],
tempID = pendingData[1],
historyStorage = historiesStorage[peerID],
pos = historyStorage.pending.indexOf(tempID);
ApiUpdatesManager.processUpdateMessage({
_: 'updateShort',
update: {
_: 'updateDeleteMessages',
messages: [tempID]
}
});
if (pos != -1) {
historyStorage.pending.splice(pos, 1);
}
delete messagesForHistory[tempID];
delete messagesStorage[tempID];
return true;
}
return false;
}
function finalizePendingMessage(randomID, finalMessage) {
var pendingData = pendingByRandomID[randomID];
// console.log('pdata', randomID, pendingData);
if (pendingData) {
var peerID = pendingData[0],
tempID = pendingData[1],
historyStorage = historiesStorage[peerID],
message,
historyMessage;
// console.log('pending', randomID, historyStorage.pending);
var pos = historyStorage.pending.indexOf(tempID);
if (pos != -1) {
historyStorage.pending.splice(pos, 1);
}
if (message = messagesStorage[tempID]) {
delete message.pending;
delete message.error;
delete message.random_id;
delete message.send;
}
if (historyMessage = messagesForHistory[tempID]) {
messagesForHistory[finalMessage.mid] = angular.extend(historyMessage, wrapForHistory(finalMessage.mid));
delete historyMessage.pending;
delete historyMessage.error;
delete historyMessage.random_id;
delete historyMessage.send;
$rootScope.$broadcast('messages_pending');
}
delete messagesForHistory[tempID];
delete messagesStorage[tempID];
return message;
}
return false;
}
function openChatInviteLink (hash) {
return MtpApiManager.invokeApi('messages.checkChatInvite', {
hash: hash
}).then(function (chatInvite) {
var chatTitle;
if (chatInvite._ == 'chatInviteAlready') {
AppChatsManager.saveApiChat(chatInvite.chat);
if (!chatInvite.chat.pFlags.left) {
return $rootScope.$broadcast('history_focus', {
peerString: AppChatsManager.getChatString(chatInvite.chat.id)
});
}
chatTitle = chatInvite.chat.title;
} else {
chatTitle = chatInvite.title;
}
ErrorService.confirm({
type: chatInvite.flags & 1 ? 'JOIN_CHANNEL_BY_LINK' : 'JOIN_GROUP_BY_LINK',
title: chatTitle
}).then(function () {
return MtpApiManager.invokeApi('messages.importChatInvite', {
hash: hash
}).then(function (updates) {
ApiUpdatesManager.processUpdateMessage(updates);
if (updates.chats && updates.chats.length == 1) {
$rootScope.$broadcast('history_focus', {peerString: AppChatsManager.getChatString(updates.chats[0].id)
});
}
else if (updates.updates && updates.updates.length) {
for (var i = 0, len = updates.updates.length, update; i < len; i++) {
update = updates.updates[i];
if (update._ == 'updateNewMessage') {
$rootScope.$broadcast('history_focus', {peerString: AppChatsManager.getChatString(update.message.to_id.chat_id)
});
break;
}
}
}
});
});
});
}
function getMessagePeer (message) {
var toID = message.to_id && AppPeersManager.getPeerID(message.to_id) || 0;
if (toID < 0) {
return toID;
} else if (message.out || message.flags & 2) {
return toID;
}
return message.from_id;
}
function wrapForDialog (msgID, unreadCount) {
var useCache = unreadCount != -1;
if (useCache && messagesForDialogs[msgID] !== undefined) {
return messagesForDialogs[msgID];
}
var message = angular.copy(messagesStorage[msgID]);
if (!message || !message.to_id) {
return message;
}
message.peerID = getMessagePeer(message);
message.peerData = AppPeersManager.getPeer(message.peerID);
message.peerString = AppPeersManager.getPeerString(message.peerID);
message.unreadCount = unreadCount;
if (message._ == 'messageService' && message.action.user_id) {
message.action.user = AppUsersManager.getUser(message.action.user_id);
}
if (message.message && message.message.length) {
message.richMessage = RichTextProcessor.wrapRichText(message.message.substr(0, 64), {noLinks: true, noLinebreaks: true});
}
message.dateText = dateOrTimeFilter(message.date);
if (useCache) {
messagesForDialogs[msgID] = message;
}
return message;
}
function wrapForHistory (msgID) {
if (messagesForHistory[msgID] !== undefined) {
return messagesForHistory[msgID];
}
var message = angular.copy(messagesStorage[msgID]) || {id: msgID};
if (message.media && message.media.progress !== undefined) {
message.media.progress = messagesStorage[msgID].media.progress;
}
var fromUser = message.from_id && AppUsersManager.getUser(message.from_id);
var fromBot = fromUser && fromUser.pFlags.bot && fromUser.username || false;
var withBot = (fromBot ||
message.to_id && (
message.to_id.chat_id ||
message.to_id.user_id && AppUsersManager.isBot(message.to_id.user_id)
)
);
if (message.media) {
if (message.media.caption &&
message.media.caption.length) {
message.media.rCaption = RichTextProcessor.wrapRichText(message.media.caption, {
noCommands: !withBot,
fromBot: fromBot
});
}
switch (message.media._) {
case 'messageMediaPhoto':
message.media.photo = AppPhotosManager.wrapForHistory(message.media.photo.id);
break;
case 'messageMediaVideo':
message.media.video = AppVideoManager.wrapForHistory(message.media.video.id);
break;
case 'messageMediaDocument':
message.media.document = AppDocsManager.wrapForHistory(message.media.document.id);
break;
case 'messageMediaAudio':
message.media.audio = AppAudioManager.wrapForHistory(message.media.audio.id);
break;
case 'messageMediaGeo':
var mapUrl = 'https://maps.google.com/?q=' + message.media.geo['lat'] + ',' + message.media.geo['long'];
message.media.mapUrl = $sce.trustAsResourceUrl(mapUrl);
break;
case 'messageMediaVenue':
var mapUrl;
if (message.media.provider == 'foursquare' &&
message.media.venue_id) {
mapUrl = 'https://foursquare.com/v/' + encodeURIComponent(message.media.venue_id);
} else {
mapUrl = 'https://maps.google.com/?q=' + message.media.geo['lat'] + ',' + message.media.geo['long'];
}
message.media.mapUrl = $sce.trustAsResourceUrl(mapUrl);
break;
case 'messageMediaContact':
message.media.rFullName = RichTextProcessor.wrapRichText(
message.media.first_name + ' ' + (message.media.last_name || ''),
{noLinks: true, noLinebreaks: true}
);
break;
case 'messageMediaWebPage':
if (!message.media.webpage ||
message.media.webpage._ == 'webPageEmpty' ||
Config.Mobile) {
delete message.media;
break;
}
message.media.webpage = AppWebPagesManager.wrapForHistory(message.media.webpage.id);
break;
}
}
else if (message.action) {
switch (message.action._) {
case 'messageActionChatEditPhoto':
case 'messageActionChannelEditPhoto':
message.action.photo = AppPhotosManager.wrapForHistory(message.action.photo.id);
break;
case 'messageActionChatCreate':
case 'messageActionChatEditTitle':
case 'messageActionChannelCreate':
case 'messageActionChannelEditTitle':
message.action.rTitle = RichTextProcessor.wrapRichText(message.action.title, {noLinks: true, noLinebreaks: true}) || _('chat_title_deleted');
break;
case 'messageActionBotIntro':
message.action.rDescription = RichTextProcessor.wrapRichText(message.action.description, {
noCommands: !withBot,
fromBot: fromBot
});
break;
}
}
var replyToMsgID = message.reply_to_mid;
if (replyToMsgID) {
if (messagesStorage[replyToMsgID]) {
message.reply_to_msg = wrapForDialog(replyToMsgID);
} else {
message.reply_to_msg = {mid: replyToMsgID, loading: true};
if (needSingleMessages.indexOf(replyToMsgID) == -1) {
needSingleMessages.push(replyToMsgID);
if (fetchSingleMessagesTimeout === false) {
fetchSingleMessagesTimeout = setTimeout(fetchSingleMessages, 100);
}
}
}
}
return messagesForHistory[msgID] = message;
}
function wrapReplyMarkup (replyMarkup) {
if (!replyMarkup ||
replyMarkup._ == 'replyKeyboardHide') {
return false;
}
if (replyMarkup.wrapped) {
return replyMarkup;
}
var count = replyMarkup.rows && replyMarkup.rows.length || 0;
if (count > 0 && count <= 4 && !replyMarkup.pFlags.resize) {
replyMarkup.splitCount = count;
}
replyMarkup.wrapped = true;
angular.forEach(replyMarkup.rows, function (markupRow) {
angular.forEach(markupRow.buttons, function (markupButton) {
markupButton.rText = RichTextProcessor.wrapRichText(markupButton.text, {noLinks: true, noLinebreaks: true});
})
})
if (nextRandomInt(1)) {
replyMarkup.rows = replyMarkup.rows.slice(0, 2);
}
return replyMarkup;
}
function fetchSingleMessages () {
if (fetchSingleMessagesTimeout !== false) {
clearTimeout(fetchSingleMessagesTimeout);
fetchSingleMessagesTimeout = false;
}
if (!needSingleMessages.length) {
return;
}
var mids = needSingleMessages.slice();
needSingleMessages = [];
var msgIDsByChannels = {};
var midsByChannels = {};
var i, mid, msgChannel, channelID;
for (i = 0; i < mids.length; i++) {
mid = mids[i];
msgChannel = getMessageIDInfo(mid);
channelID = msgChannel[1];
if (msgIDsByChannels[channelID] === undefined) {
msgIDsByChannels[channelID] = [];
midsByChannels[channelID] = [];
}
msgIDsByChannels[channelID].push(msgChannel[0]);
midsByChannels[channelID].push(mid);
}
angular.forEach(msgIDsByChannels, function (msgIDs, channelID) {
var promise;
if (channelID > 0) {
promise = MtpApiManager.invokeApi('channels.getMessages', {
channel: AppChatsManager.getChannelInput(channelID),
id: msgIDs
});
} else {
promise = MtpApiManager.invokeApi('messages.getMessages', {
id: msgIDs
});
}
promise.then(function (getMessagesResult) {
AppUsersManager.saveApiUsers(getMessagesResult.users);
AppChatsManager.saveApiChats(getMessagesResult.chats);
saveMessages(getMessagesResult.messages);
$rootScope.$broadcast('messages_downloaded', midsByChannels[channelID]);
})
})
}
function regroupWrappedHistory (history, limit) {
if (!history || !history.length) {
return false;
}
var start = 0,
len = history.length,
end = len,
i, curDay, prevDay, curMessage, prevMessage, curGrouped, prevGrouped,
wasUpdated = false,
groupFwd = !Config.Mobile;
if (limit > 0) {
end = Math.min(limit, len);
} else if (limit < 0) {
start = Math.max(0, end + limit);
}
for (i = start; i < end; i++) {
curMessage = history[i];
curDay = Math.floor((curMessage.date + midnightOffset) / 86400);
prevGrouped = prevMessage && prevMessage.grouped;
curGrouped = curMessage.grouped;
if (curDay === prevDay) {
if (curMessage.needDate) {
delete curMessage.needDate;
wasUpdated = true;
}
} else if (!i || prevMessage) {
if (!curMessage.needDate) {
curMessage.needDate = true;
wasUpdated = true;
}
}
if (curMessage.fwdFromID &&
curMessage.media &&
curMessage.media.document &&
(curMessage.media.document.sticker || curMessage.media.document.audioTitle) &&
(curMessage.fromID != (prevMessage || {}).fromID || !(prevMessage || {}).fwdFromID)) {
delete curMessage.fwdFromID;
curMessage._ = 'message';
}
if (prevMessage &&
curMessage.fromID == prevMessage.fromID &&
!prevMessage.fwdFromID == !curMessage.fwdFromID &&
!prevMessage.action &&
!curMessage.action &&
curMessage.date < prevMessage.date + 900) {
var singleLine = curMessage.message && curMessage.message.length < 70 && curMessage.message.indexOf("\n") == -1 && !curMessage.reply_to_mid;
if (groupFwd && curMessage.fwdFromID && curMessage.fwdFromID == prevMessage.fwdFromID) {
curMessage.grouped = singleLine ? 'im_grouped_fwd_short' : 'im_grouped_fwd';
} else {
curMessage.grouped = !curMessage.fwdFromID && singleLine ? 'im_grouped_short' : 'im_grouped';
}
if (groupFwd && curMessage.fwdFromID) {
if (!prevMessage.grouped) {
prevMessage.grouped = 'im_grouped_fwd_start';
}
if (curMessage.grouped && i == len - 1) {
curMessage.grouped += ' im_grouped_fwd_end';
}
}
} else if (prevMessage || !i) {
delete curMessage.grouped;
if (groupFwd && prevMessage && prevMessage.grouped && prevMessage.fwdFromID) {
prevMessage.grouped += ' im_grouped_fwd_end';
}
}
if (!wasUpdated && prevGrouped != (prevMessage && prevMessage.grouped)) {
wasUpdated = true;
}
prevMessage = curMessage;
prevDay = curDay;
}
if (!wasUpdated && curGrouped != (prevMessage && prevMessage.grouped)) {
wasUpdated = true;
}
return wasUpdated;
}
function incrementMaxSeenID (maxID) {
if (maxSeenID !== false && maxID && maxID > maxSeenID) {
Storage.set({
max_seen_msg: maxID
});
}
}
function notifyAboutMessage (message, options) {
options = options || {};
var peerID = getMessagePeer(message);
var peerString;
var notification = {},
notificationMessage = false,
notificationPhoto;
var notifySettings = NotificationsManager.getNotifySettings();
if (message.fwdFromID && options.fwd_count) {
notificationMessage = fwdMessagesPluralize(options.fwd_count);
} else if (message.message) {
if (notifySettings.nopreview) {
notificationMessage = _('conversation_message_sent');
} else {
notificationMessage = RichTextProcessor.wrapPlainText(message.message);
}
} else if (message.media) {
switch (message.media._) {
case 'messageMediaPhoto': notificationMessage = _('conversation_media_photo_raw'); break;
case 'messageMediaVideo': notificationMessage = _('conversation_media_video_raw'); break;
case 'messageMediaDocument':
if (message.media.document.sticker) {
notificationMessage = _('conversation_media_sticker');
var stickerEmoji = message.media.document.stickerEmojiRaw;
if (stickerEmoji !== undefined) {
notificationMessage = RichTextProcessor.wrapPlainText(stickerEmoji) + ' (' + notificationMessage + ')';
}
} else {
notificationMessage = message.media.document.file_name || _('conversation_media_document_raw');
}
break;
case 'messageMediaAudio': notificationMessage = _('conversation_media_audio_raw'); break;
case 'messageMediaGeo':
case 'messageMediaVenue': notificationMessage = _('conversation_media_location_raw'); break;
case 'messageMediaContact': notificationMessage = _('conversation_media_contact_raw'); break;
default: notificationMessage = _('conversation_media_attachment_raw'); break;
}
} else if (message._ == 'messageService') {
switch (message.action._) {
case 'messageActionChatCreate':
notificationMessage = _('conversation_group_created_raw');
break;
case 'messageActionChatEditTitle': notificationMessage = _('conversation_group_renamed_raw');
break;
case 'messageActionChatEditPhoto': notificationMessage = _('conversation_group_photo_updated_raw');
break;
case 'messageActionChatDeletePhoto': notificationMessage = _('conversation_group_photo_removed_raw');
break;
case 'messageActionChatAddUser':
notificationMessage = message.action.user_id == message.from_id ? _('conversation_returned_to_group') : _('conversation_invited_user_message_raw');
break;
case 'messageActionChatDeleteUser':
notificationMessage = message.action.user_id == message.from_id ? _('conversation_left_group') : _('conversation_kicked_user_message_raw');
break;
case 'messageActionChatJoinedByLink':
notificationMessage = _('conversation_joined_by_link');
break;
case 'messageActionChannelCreate':
notificationMessage = _('conversation_created_channel');
break;
case 'messageActionChannelEditTitle':
notificationMessage = _('conversation_changed_channel_name');
break;
case 'messageActionChannelEditPhoto':
notificationMessage = _('conversation_changed_channel_photo');
break;
case 'messageActionChannelDeletePhoto':
notificationMessage = _('conversation_removed_channel_photo');
break;
}
}
if (peerID > 0) {
var fromUser = AppUsersManager.getUser(message.from_id);
var fromPhoto = AppUsersManager.getUserPhoto(message.from_id);
notification.title = (fromUser.first_name || '') +
(fromUser.first_name && fromUser.last_name ? ' ' : '') +
(fromUser.last_name || '');
if (!notification.title) {
notification.title = fromUser.phone || _('conversation_unknown_user_raw');
}
notificationPhoto = fromPhoto;
peerString = AppUsersManager.getUserString(peerID);
} else {
notification.title = AppChatsManager.getChat(-peerID).title || _('conversation_unknown_chat_raw');
if (message.from_id > 0) {
var fromUser = AppUsersManager.getUser(message.from_id);
notification.title = (fromUser.first_name || fromUser.last_name || _('conversation_unknown_user_raw')) +
' @ ' +
notification.title;
}
notificationPhoto = AppChatsManager.getChatPhoto(-peerID);
peerString = AppChatsManager.getChatString(-peerID);
}
notification.title = RichTextProcessor.wrapPlainText(notification.title);
notification.onclick = function () {
$rootScope.$broadcast('history_focus', {
peerString: peerString,
messageID: message.flags & 16 ? message.mid : 0,
});
};
notification.message = notificationMessage;
notification.image = notificationPhoto.placeholder;
notification.key = 'msg' + message.mid;
notification.tag = peerString;
if (notificationPhoto.location && !notificationPhoto.location.empty) {
MtpApiFileManager.downloadSmallFile(notificationPhoto.location, notificationPhoto.size).then(function (blob) {
notification.image = FileManager.getUrl(blob, 'image/jpeg');
if (message.unread) {
NotificationsManager.notify(notification);
}
});
} else {
NotificationsManager.notify(notification);
}
}
if (window.navigator.mozSetMessageHandler) {
window.navigator.mozSetMessageHandler('activity', function(activityRequest) {
var source = activityRequest.source;
console.log(dT(), 'Received activity', source.name, source.data);
if (source.name === 'share' && source.data.blobs.length > 0) {
PeersSelectService.selectPeers({confirm_type: 'EXT_SHARE_PEER'}).then(function (peerStrings) {
angular.forEach(peerStrings, function (peerString) {
var peerID = AppPeersManager.getPeerID(peerString);
angular.forEach(source.data.blobs, function (blob) {
sendFile(peerID, blob, {isMedia: true});
});
})
if (peerStrings.length == 1) {
$rootScope.$broadcast('history_focus', {peerString: peerStrings[0]});
}
});
}
});
}
var newMessagesHandlePromise = false;
var newMessagesToHandle = {};
var newDialogsHandlePromise = false;
var newDialogsToHandle = {};
var notificationsHandlePromise = false;
var notificationsToHandle = {};
function handleNewMessages () {
$timeout.cancel(newMessagesHandlePromise);
newMessagesHandlePromise = false;
$rootScope.$broadcast('history_multiappend', newMessagesToHandle);
newMessagesToHandle = {};
}
function handleNewDialogs () {
$timeout.cancel(newDialogsHandlePromise);
newDialogsHandlePromise = false;
angular.forEach(newDialogsToHandle, function (dialog) {
pushDialogToStorage(dialog);
});
$rootScope.$broadcast('dialogs_multiupdate', newDialogsToHandle);
newDialogsToHandle = {};
}
function handleNotifications () {
$timeout.cancel(notificationsHandlePromise);
notificationsHandlePromise = false;
var timeout = $rootScope.idle.isIDLE && StatusManager.isOtherDeviceActive() ? 30000 : 1000;
angular.forEach(notificationsToHandle, function (notifyPeerToHandle) {
notifyPeerToHandle.isMutedPromise.then(function (muted) {
var topMessage = notifyPeerToHandle.top_message;
if (muted ||
!topMessage.unread) {
return;
}
setTimeout(function () {
if (topMessage.unread) {
notifyAboutMessage(topMessage, {
fwd_count: notifyPeerToHandle.fwd_count
});
}
}, timeout);
});
});
notificationsToHandle = {};
}
$rootScope.$on('apiUpdate', function (e, update) {
// if (update._ != 'updateUserStatus') {
// console.log('on apiUpdate', update);
// }
switch (update._) {
case 'updateMessageID':
var randomID = update.random_id;
var pendingData = pendingByRandomID[randomID];
if (pendingData) {
var peerID = pendingData[0];
var channelID = AppPeersManager.isChannel(peerID) ? -peerID : 0;
pendingByMessageID[getFullMessageID(update.id, channelID)] = randomID;
}
break;
case 'updateNewMessage':
case 'updateNewChannelMessage':
var message = update.message,
peerID = getMessagePeer(message),
historyStorage = historiesStorage[peerID];
if (update._ == 'updateNewChannelMessage' &&
!(message.flags & 16 || message.flags & 2 || (message.flags & 256) == 0)) {
// we don't support not important messages yet
break;
}
saveMessages([message]);
if (historyStorage !== undefined) {
var history = historyStorage.history;
if (history.indexOf(message.mid) != -1) {
return false;
}
var topMsgID = history[0];
history.unshift(message.mid);
if (message.mid > 0 && message.mid < topMsgID) {
history.sort(function (a, b) {
return b - a;
});
}
if (historyStorage.count !== null) {
historyStorage.count++;
}
} else {
historyStorage = historiesStorage[peerID] = {
count: null,
history: [message.mid],
pending: []
};
}
if (mergeReplyKeyboard(historyStorage, message)) {
$rootScope.$broadcast('history_reply_markup', {peerID: peerID})
}
if (!message.out && message.from_id) {
AppUsersManager.forceUserOnline(message.from_id);
}
var randomID = pendingByMessageID[message.mid],
pendingMessage;
if (randomID) {
if (pendingMessage = finalizePendingMessage(randomID, message)) {
$rootScope.$broadcast('history_update', {peerID: peerID});
}
delete pendingByMessageID[message.mid];
}
if (!pendingMessage) {
if (newMessagesToHandle[peerID] === undefined) {
newMessagesToHandle[peerID] = [];
}
newMessagesToHandle[peerID].push(message.mid);
if (!newMessagesHandlePromise) {
newMessagesHandlePromise = $timeout(handleNewMessages, 0);
}
}
var foundDialog = getDialogByPeerID(peerID);
var dialog;
var inboxUnread = !message.out && message.unread;
if (foundDialog.length) {
dialog = foundDialog[0];
dialog.top_message = message.mid;
if (inboxUnread) {
dialog.unread_count++;
}
} else {
SearchIndexManager.indexObject(peerID, AppPeersManager.getPeerSearchText(peerID), dialogsIndex);
dialog = {
peerID: peerID,
unread_count: inboxUnread ? 1 : 0,
top_message: message.mid
};
}
dialog.index = generateDialogIndex(message.date);
newDialogsToHandle[peerID] = dialog;
if (!newDialogsHandlePromise) {
newDialogsHandlePromise = $timeout(handleNewDialogs, 0);
}
if (inboxUnread && ($rootScope.selectedPeerID != peerID || $rootScope.idle.isIDLE)) {
var notifyPeer = message.flags & 16 ? message.from_id : peerID;
var notifyPeerToHandle = notificationsToHandle[notifyPeer];
if (notifyPeerToHandle === undefined) {
notifyPeerToHandle = notificationsToHandle[notifyPeer] = {
isMutedPromise: NotificationsManager.getPeerMuted(notifyPeer),
fwd_count: 0,
from_id: 0
};
}
if (notifyPeerToHandle.from_id != message.from_id) {
notifyPeerToHandle.from_id = message.from_id;
notifyPeerToHandle.fwd_count = 0;
}
if (message.fwdFromID) {
notifyPeerToHandle.fwd_count++;
}
notifyPeerToHandle.top_message = message;
if (!notificationsHandlePromise) {
notificationsHandlePromise = $timeout(handleNotifications, 1000);
}
}
incrementMaxSeenID(message.id);
break;
case 'updateReadHistoryInbox':
case 'updateReadHistoryOutbox':
case 'updateReadChannelInbox':
var isOut = update._ == 'updateReadHistoryOutbox';
var channelID = update.channel_id;
var maxID = getFullMessageID(update.max_id, channelID);
var peerID = channelID ? -channelID : AppPeersManager.getPeerID(update.peer);
var foundDialog = getDialogByPeerID(peerID);
var history = (historiesStorage[peerID] || {}).history || [];
var newUnreadCount = false;
var length = history.length;
var foundAffected = false;
var messageID, message, i;
if (peerID > 0 && isOut) {
AppUsersManager.forceUserOnline(peerID);
}
for (i = 0; i < length; i++) {
messageID = history[i];
if (messageID > maxID) {
continue;
}
message = messagesStorage[messageID];
if (message.out != isOut) {
continue;
}
if (!message.unread) {
break;
}
// console.log('read', messageID, message.unread, message);
if (message && message.unread) {
message.unread = false;
if (messagesForHistory[messageID]) {
messagesForHistory[messageID].unread = false;
if (!foundAffected) {
foundAffected = true;
}
}
if (messagesForDialogs[messageID]) {
messagesForDialogs[messageID].unread = false;
}
if (!message.out) {
if (foundDialog) {
newUnreadCount = --foundDialog[0].unread_count;
}
NotificationsManager.cancel('msg' + messageID);
}
}
}
if (newUnreadCount !== false) {
$rootScope.$broadcast('dialog_unread', {peerID: peerID, count: newUnreadCount});
}
if (foundAffected) {
$rootScope.$broadcast('messages_read');
}
break;
case 'updateReadMessagesContents':
var messages = update.messages;
var len = messages.length;
var i, messageID, message, historyMessage;
for (i = 0; i < len; i++) {
messageID = messages[i];
if (message = messagesStorage[messageID]) {
delete message.media_unread;
}
if (historyMessage = messagesForHistory[messageID]) {
delete historyMessage.media_unread;
}
}
break;
case 'updateDeleteMessages':
case 'updateDeleteChannelMessages':
var dialogsUpdated = {};
var historiesUpdated = {};
var channelID = update.channel_id;
var messageID, message, i, peerID, foundDialog, history;
for (i = 0; i < update.messages.length; i++) {
messageID = getFullMessageID(update.messages[i], channelID);
message = messagesStorage[messageID];
if (message) {
peerID = getMessagePeer(message);
history = historiesUpdated[peerID] || (historiesUpdated[peerID] = {count: 0, unread: 0, msgs: {}});
if (!message.out && message.unread) {
history.unread++;
NotificationsManager.cancel('msg' + messageID);
}
history.count++;
history.msgs[messageID] = true;
if (messagesForHistory[messageID]) {
messagesForHistory[messageID].deleted = true;
delete messagesForHistory[messageID];
}
if (messagesForDialogs[messageID]) {
messagesForDialogs[messageID].deleted = true;
delete messagesForDialogs[messageID];
}
message.deleted = true;
messagesStorage[messageID] = {
deleted: true,
id: messageID,
from_id: message.from_id,
to_id: message.to_id,
flags: message.flags,
out: message.out,
unread: message.unread,
date: message.date
};
}
}
angular.forEach(historiesUpdated, function (updatedData, peerID) {
var foundDialog = getDialogByPeerID(peerID);
if (foundDialog) {
if (updatedData.unread) {
foundDialog[0].unread_count -= updatedData.unread;
$rootScope.$broadcast('dialog_unread', {peerID: peerID, count: foundDialog[0].unread_count});
}
}
var historyStorage = historiesStorage[peerID];
if (historyStorage !== undefined) {
var newHistory = [],
newPending = [];
for (var i = 0; i < historyStorage.history.length; i++) {
if (!updatedData.msgs[historyStorage.history[i]]) {
newHistory.push(historyStorage.history[i]);
}
}
historyStorage.history = newHistory;
if (updatedData.count &&
historyStorage.count !== null &&
historyStorage.count > 0) {
historyStorage.count -= updatedData.count;
if (historyStorage.count < 0) {
historyStorage.count = 0;
}
}
for (var i = 0; i < historyStorage.pending.length; i++) {
if (!updatedData.msgs[historyStorage.pending[i]]) {
newPending.push(historyStorage.pending[i]);
}
}
historyStorage.pending = newPending;
$rootScope.$broadcast('history_delete', {peerID: peerID, msgs: updatedData.msgs});
}
});
break;
case 'updateChannel':
var channelID = update.channel_id;
var peerID = -channelID;
var channel = AppChatsManager.getChat(channelID);
var needDialog = channel._ == 'channel' && (!channel.pFlags.left && !channel.pFlags.kicked);
var foundDialog = getDialogByPeerID(peerID);
var hasDialog = foundDialog.length > 0;
var canViewHistory = channel._ == 'channel' && (channel.username || !channel.pFlags.left && !channel.pFlags.kicked) && true || false;
var hasHistory = historiesStorage[peerID] !== undefined;
if (canViewHistory != hasHistory) {
delete historiesStorage[peerID];
$rootScope.$broadcast('history_forbidden', peerID);
}
if (hasDialog != needDialog) {
if (needDialog) {
reloadChannelDialog(channelID);
} else {
if (foundDialog[0]) {
dialogsStorage.dialogs.splice(foundDialog[1], 1);
$rootScope.$broadcast('dialog_drop', {peerID: peerID});
}
}
}
break;
case 'updateChannelReload':
var channelID = update.channel_id;
var peerID = -channelID;
var foundDialog = getDialogByPeerID(peerID);
if (foundDialog[0]) {
dialogsStorage.dialogs.splice(foundDialog[1], 1);
}
delete historiesStorage[peerID];
reloadChannelDialog(channelID).then(function () {
$rootScope.$broadcast('history_reload', peerID);
});
break;
}
});
function reloadChannelDialog (channelID) {
var peerID = -channelID;
var inputPeer = AppPeersManager.getInputPeerByID(peerID);
return $q.all([
AppProfileManager.getChannelFull(channelID, true),
getHistory(inputPeer, 0)
]).then(function (results) {
var channelResult = results[0];
var historyResult = results[1];
var topMsgID = historyResult.history[0];
var dialog = {
_: 'dialogChannel',
peer: AppPeersManager.getOutputPeer(peerID),
top_message: topMsgID,
top_important_message: topMsgID,
read_inbox_max_id: channelResult.read_inbox_max_id,
unread_count: channelResult.unread_count,
unread_important_count: channelResult.unread_important_count,
notify_settings: channelResult.notify_settings
};
saveChannelDialog(channelID, dialog);
var updatedDialogs = {};
updatedDialogs[peerID] = dialog;
$rootScope.$broadcast('dialogs_multiupdate', updatedDialogs);
});
}
$rootScope.$on('webpage_updated', function (e, eventData) {
angular.forEach(eventData.msgs, function (msgID) {
var historyMessage = messagesForHistory[msgID];
if (historyMessage) {
historyMessage.media = {
_: 'messageMediaWebPage',
webpage: AppWebPagesManager.wrapForHistory(eventData.id)
};
}
})
})
return {
getConversations: getConversations,
getHistory: getHistory,
getSearch: getSearch,
getMessage: getMessage,
getReplyKeyboard: getReplyKeyboard,
readHistory: readHistory,
readMessages: readMessages,
flushHistory: flushHistory,
deleteMessages: deleteMessages,
saveMessages: saveMessages,
sendText: sendText,
sendFile: sendFile,
sendOther: sendOther,
forwardMessages: forwardMessages,
startBot: startBot,
openChatInviteLink: openChatInviteLink,
getMessagePeer: getMessagePeer,
wrapForDialog: wrapForDialog,
wrapForHistory: wrapForHistory,
wrapReplyMarkup: wrapReplyMarkup,
regroupWrappedHistory: regroupWrappedHistory
}
});