scheme updated, contextbot -> inlinebot renamed, web file loader done like mtp file loader

This commit is contained in:
John Preston 2015-12-31 03:09:20 +08:00
parent e58c8a6fcb
commit 14839e7afe
27 changed files with 2103 additions and 1352 deletions

View File

@ -424,7 +424,7 @@ namespace App {
data->setBotInfoVersion(d.vbot_info_version.v);
data->botInfo->readsAllHistory = d.is_bot_chat_history();
data->botInfo->cantJoinGroups = d.is_bot_nochats();
data->botInfo->contextPlaceholder = d.has_bot_context_placeholder() ? qs(d.vbot_context_placeholder) : QString();
data->botInfo->inlinePlaceholder = d.has_bot_inline_placeholder() ? '_' + qs(d.vbot_inline_placeholder) : QString();
} else {
data->setBotInfoVersion(-1);
}
@ -2610,12 +2610,15 @@ namespace App {
}
void setProxySettings(QNetworkAccessManager &manager) {
manager.setProxy(getHttpProxySettings());
}
QNetworkProxy getHttpProxySettings() {
if (cConnectionType() == dbictHttpProxy) {
const ConnectionProxy &p(cConnectionProxy());
manager.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, p.host, p.port, p.user, p.password));
} else {
manager.setProxy(QNetworkProxy(QNetworkProxy::DefaultProxy));
return QNetworkProxy(QNetworkProxy::HttpProxy, p.host, p.port, p.user, p.password);
}
return QNetworkProxy(QNetworkProxy::DefaultProxy);
}
void setProxySettings(QTcpSocket &socket) {

View File

@ -251,6 +251,7 @@ namespace App {
const ReplyMarkup &replyMarkup(ChannelId channelId, MsgId msgId);
void setProxySettings(QNetworkAccessManager &manager);
QNetworkProxy getHttpProxySettings();
void setProxySettings(QTcpSocket &socket);
QImage **cornersMask();

View File

@ -885,6 +885,7 @@ Application::~Application() {
socket.close();
closeApplication();
stopWebLoadManager();
App::deinitMedia();
deinitImageLinkManager();

View File

@ -215,6 +215,7 @@ void ConnectionBox::onSave() {
Local::writeSettings();
MTP::restart();
reinitImageLinkManager();
reinitWebLoadManager();
emit closed();
}
}

View File

@ -86,7 +86,7 @@ enum {
ClipThreadsCount = 8,
AverageGifSize = 320 * 240,
WaitBeforeGifPause = 200, // wait 200ms for gif draw before pausing it
ContextBotRequestDelay = 400, // wait 400ms before context bot realtime request
InlineBotRequestDelay = 400, // wait 400ms before context bot realtime request
AVBlockSize = 4096, // 4Kb for ffmpeg blocksize
@ -344,6 +344,7 @@ enum {
MaxUploadDocumentSize = 1500 * 1024 * 1024, // 1500mb documents max
UseBigFilesFrom = 10 * 1024 * 1024, // mtp big files methods used for files greater than 10mb
MaxFileQueries = 16, // max 16 file parts downloaded at the same time
MaxWebFileQueries = 8, // max 8 http[s] files downloaded at the same time
UploadPartSize = 32 * 1024, // 32kb for photo
DocumentMaxPartsCount = 3000, // no more than 3000 parts

View File

@ -1214,7 +1214,7 @@ StickerPanInner::StickerPanInner() : TWidget()
, _a_selected(animation(this, &StickerPanInner::step_selected))
, _top(0)
, _showingSavedGifs(cShowingSavedGifs())
, _showingContextItems(_showingSavedGifs)
, _showingInlineItems(_showingSavedGifs)
, _lastScrolled(0)
, _selected(-1)
, _pressedSel(-1)
@ -1232,8 +1232,8 @@ StickerPanInner::StickerPanInner() : TWidget()
_previewTimer.setSingleShot(true);
connect(&_previewTimer, SIGNAL(timeout()), this, SLOT(onPreview()));
_updateContextItems.setSingleShot(true);
connect(&_updateContextItems, SIGNAL(timeout()), this, SLOT(onUpdateContextItems()));
_updateInlineItems.setSingleShot(true);
connect(&_updateInlineItems, SIGNAL(timeout()), this, SLOT(onUpdateInlineItems()));
}
void StickerPanInner::setMaxHeight(int32 h) {
@ -1252,10 +1252,10 @@ void StickerPanInner::setScrollTop(int top) {
int StickerPanInner::countHeight() {
int result = 0, minLastH = _maxHeight - st::rbEmoji.height - st::stickerPanPadding;
if (_showingContextItems) {
if (_showingInlineItems) {
result = st::emojiPanHeader;
for (int i = 0, l = _contextRows.count(); i < l; ++i) {
result += _contextRows.at(i).height;
for (int i = 0, l = _inlineRows.count(); i < l; ++i) {
result += _inlineRows.at(i).height;
}
} else {
for (int i = 0; i < _sets.size(); ++i) {
@ -1293,36 +1293,36 @@ void StickerPanInner::paintEvent(QPaintEvent *e) {
}
p.fillRect(r, st::white);
if (_showingContextItems) {
paintContextItems(p, r);
if (_showingInlineItems) {
paintInlineItems(p, r);
} else {
paintStickers(p, r);
}
}
void StickerPanInner::paintContextItems(Painter &p, const QRect &r) {
ContextPaintContext context(getms(), false, _previewShown);
void StickerPanInner::paintInlineItems(Painter &p, const QRect &r) {
InlinePaintContext context(getms(), false, _previewShown);
int32 top = st::emojiPanHeader;
int32 fromx = rtl() ? (width() - r.x() - r.width()) : r.x(), tox = rtl() ? (width() - r.x()) : (r.x() + r.width());
for (int32 row = 0, rows = _contextRows.size(); row < rows; ++row) {
const ContextRow &contextRow(_contextRows.at(row));
for (int32 row = 0, rows = _inlineRows.size(); row < rows; ++row) {
const InlineRow &inlineRow(_inlineRows.at(row));
if (top >= r.top() + r.height()) break;
if (top + contextRow.height > r.top()) {
if (top + inlineRow.height > r.top()) {
int32 left = st::inlineResultsLeft;
for (int32 col = 0, cols = contextRow.items.size(); col < cols; ++col) {
for (int32 col = 0, cols = inlineRow.items.size(); col < cols; ++col) {
if (left >= tox) break;
int32 w = contextRow.items.at(col)->width();
int32 w = inlineRow.items.at(col)->width();
if (left + w > fromx) {
p.translate(left, top);
contextRow.items.at(col)->paint(p, r.translated(-left, -top), 0, &context);
inlineRow.items.at(col)->paint(p, r.translated(-left, -top), 0, &context);
p.translate(-left, -top);
}
left += w + st::inlineResultsSkip;
}
}
top += contextRow.height;
top += inlineRow.height;
}
}
@ -1427,12 +1427,12 @@ void StickerPanInner::mouseReleaseEvent(QMouseEvent *e) {
}
if (_selected < 0 || _selected != pressed || _linkOver != down) return;
if (_showingContextItems) {
if (_showingInlineItems) {
int32 row = _selected / MatrixRowShift, col = _selected % MatrixRowShift;
if (row < _contextRows.size() && col < _contextRows.at(row).items.size()) {
if (row < _inlineRows.size() && col < _inlineRows.at(row).items.size()) {
if (down) {
if (down->type() == qstr("SendContextItemLink") && e->button() == Qt::LeftButton) {
DocumentData *doc = _contextRows.at(row).items.at(col)->document();
if (down->type() == qstr("SendInlineItemLink") && e->button() == Qt::LeftButton) {
DocumentData *doc = _inlineRows.at(row).items.at(col)->document();
if (!doc) return;
if (doc->loaded()) {
@ -1515,12 +1515,12 @@ void StickerPanInner::enterFromChildEvent(QEvent *e) {
void StickerPanInner::clearSelection(bool fast) {
_lastMousePos = mapToGlobal(QPoint(-10, -10));
if (fast) {
if (_showingContextItems) {
if (_showingInlineItems) {
if (_selected >= 0) {
int32 srow = _selected / MatrixRowShift, scol = _selected % MatrixRowShift;
t_assert(srow >= 0 && srow < _contextRows.size() && scol >= 0 && scol < _contextRows.at(srow).items.size());
t_assert(srow >= 0 && srow < _inlineRows.size() && scol >= 0 && scol < _inlineRows.at(srow).items.size());
if (_linkOver) {
_contextRows.at(srow).items.at(scol)->linkOut(_linkOver);
_inlineRows.at(srow).items.at(scol)->linkOut(_linkOver);
_linkOver = TextLinkPtr();
textlnkOver(_linkOver);
}
@ -1558,11 +1558,11 @@ void StickerPanInner::clearSelection(bool fast) {
}
void StickerPanInner::hideFinish() {
clearContextRows();
clearInlineRows();
for (GifLayouts::const_iterator i = _gifLayouts.cbegin(), e = _gifLayouts.cend(); i != e; ++i) {
i.value()->document()->forget();
}
for (ContextLayouts::const_iterator i = _contextLayouts.cbegin(), e = _contextLayouts.cend(); i != e; ++i) {
for (InlineLayouts::const_iterator i = _inlineLayouts.cbegin(), e = _inlineLayouts.cend(); i != e; ++i) {
if (i.value()->result()->doc) {
i.value()->result()->doc->forget();
}
@ -1583,7 +1583,7 @@ void StickerPanInner::refreshStickers() {
appendSet(*i);
}
if (_showingContextItems) {
if (_showingInlineItems) {
_settings.hide();
} else {
int32 h = countHeight();
@ -1598,28 +1598,28 @@ void StickerPanInner::refreshStickers() {
updateSelected();
}
void StickerPanInner::contextRowsAddItem(DocumentData *savedGif, ContextResult *result, ContextRow &row, int32 &sumWidth) {
LayoutContextItem *layout = 0;
void StickerPanInner::inlineRowsAddItem(DocumentData *savedGif, InlineResult *result, InlineRow &row, int32 &sumWidth) {
LayoutInlineItem *layout = 0;
if (savedGif) {
layout = layoutPrepareSavedGif(savedGif, (_contextRows.size() * MatrixRowShift) + row.items.size());
layout = layoutPrepareSavedGif(savedGif, (_inlineRows.size() * MatrixRowShift) + row.items.size());
} else if (result) {
layout = layoutPrepareContextResult(result, (_contextRows.size() * MatrixRowShift) + row.items.size());
layout = layoutPrepareInlineResult(result, (_inlineRows.size() * MatrixRowShift) + row.items.size());
}
if (!layout) return;
contextRowFinalize(row, sumWidth, layout->fullLine());
inlineRowFinalize(row, sumWidth, layout->fullLine());
row.items.push_back(layout);
sumWidth += layout->maxWidth();
}
void StickerPanInner::contextRowFinalize(ContextRow &row, int32 &sumWidth, bool force) {
void StickerPanInner::inlineRowFinalize(InlineRow &row, int32 &sumWidth, bool force) {
if (row.items.isEmpty()) return;
bool full = (row.items.size() >= SavedGifsMaxPerRow);
bool big = (sumWidth >= st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - (row.items.size() - 1) * st::inlineResultsSkip);
if (full || big || force) {
_contextRows.push_back(layoutContextRow(row, (full || big) ? sumWidth : 0));
row = ContextRow();
_inlineRows.push_back(layoutInlineRow(row, (full || big) ? sumWidth : 0));
row = InlineRow();
row.items.reserve(SavedGifsMaxPerRow);
sumWidth = 0;
}
@ -1627,21 +1627,21 @@ void StickerPanInner::contextRowFinalize(ContextRow &row, int32 &sumWidth, bool
void StickerPanInner::refreshSavedGifs() {
if (_showingSavedGifs) {
clearContextRows();
if (_showingContextItems) {
clearInlineRows();
if (_showingInlineItems) {
const SavedGifs &saved(cSavedGifs());
if (saved.isEmpty()) {
showStickerSet(RecentStickerSetId);
return;
} else {
_contextRows.reserve(saved.size());
ContextRow row;
_inlineRows.reserve(saved.size());
InlineRow row;
row.items.reserve(SavedGifsMaxPerRow);
int32 sumWidth = 0;
for (SavedGifs::const_iterator i = saved.cbegin(), e = saved.cend(); i != e; ++i) {
contextRowsAddItem(*i, 0, row, sumWidth);
inlineRowsAddItem(*i, 0, row, sumWidth);
}
contextRowFinalize(row, sumWidth, true);
inlineRowFinalize(row, sumWidth, true);
}
deleteUnusedGifLayouts();
@ -1656,25 +1656,25 @@ void StickerPanInner::refreshSavedGifs() {
updateSelected();
}
void StickerPanInner::contextBotChanged() {
refreshContextRows(0, ContextResults());
deleteUnusedContextLayouts();
void StickerPanInner::inlineBotChanged() {
refreshInlineRows(0, InlineResults());
deleteUnusedInlineLayouts();
}
void StickerPanInner::clearContextRows() {
void StickerPanInner::clearInlineRows() {
clearSelection(true);
for (ContextRows::const_iterator i = _contextRows.cbegin(), e = _contextRows.cend(); i != e; ++i) {
for (ContextItems::const_iterator j = i->items.cbegin(), end = i->items.cend(); j != end; ++j) {
for (InlineRows::const_iterator i = _inlineRows.cbegin(), e = _inlineRows.cend(); i != e; ++i) {
for (InlineItems::const_iterator j = i->items.cbegin(), end = i->items.cend(); j != end; ++j) {
(*j)->setPosition(-1);
}
}
_contextRows.clear();
_inlineRows.clear();
}
LayoutContextGif *StickerPanInner::layoutPrepareSavedGif(DocumentData *doc, int32 position) {
LayoutInlineGif *StickerPanInner::layoutPrepareSavedGif(DocumentData *doc, int32 position) {
GifLayouts::const_iterator i = _gifLayouts.constFind(doc);
if (i == _gifLayouts.cend()) {
i = _gifLayouts.insert(doc, new LayoutContextGif(0, doc, true));
i = _gifLayouts.insert(doc, new LayoutInlineGif(0, doc, true));
i.value()->initDimensions();
}
if (!i.value()->maxWidth()) return 0;
@ -1683,12 +1683,12 @@ LayoutContextGif *StickerPanInner::layoutPrepareSavedGif(DocumentData *doc, int3
return i.value();
}
LayoutContextItem *StickerPanInner::layoutPrepareContextResult(ContextResult *result, int32 position) {
ContextLayouts::const_iterator i = _contextLayouts.constFind(result);
if (i == _contextLayouts.cend()) {
LayoutContextItem *layout = 0;
LayoutInlineItem *StickerPanInner::layoutPrepareInlineResult(InlineResult *result, int32 position) {
InlineLayouts::const_iterator i = _inlineLayouts.constFind(result);
if (i == _inlineLayouts.cend()) {
LayoutInlineItem *layout = 0;
if (result->type == qstr("gif")) {
layout = new LayoutContextGif(result, 0, false);
layout = new LayoutInlineGif(result, 0, false);
} else if (result->type == qstr("photo")) {
} else if (result->type == qstr("web_player_video")) {
} else if (result->type == qstr("article")) {
@ -1696,7 +1696,7 @@ LayoutContextItem *StickerPanInner::layoutPrepareContextResult(ContextResult *re
}
if (!layout) return 0;
i = _contextLayouts.insert(result, layout);
i = _inlineLayouts.insert(result, layout);
layout->initDimensions();
}
if (!i.value()->maxWidth()) return 0;
@ -1706,7 +1706,7 @@ LayoutContextItem *StickerPanInner::layoutPrepareContextResult(ContextResult *re
}
void StickerPanInner::deleteUnusedGifLayouts() {
if (_contextRows.isEmpty()) { // delete all
if (_inlineRows.isEmpty()) { // delete all
for (GifLayouts::const_iterator i = _gifLayouts.cbegin(), e = _gifLayouts.cend(); i != e; ++i) {
delete i.value();
}
@ -1723,17 +1723,17 @@ void StickerPanInner::deleteUnusedGifLayouts() {
}
}
void StickerPanInner::deleteUnusedContextLayouts() {
if (_contextRows.isEmpty()) { // delete all
for (ContextLayouts::const_iterator i = _contextLayouts.cbegin(), e = _contextLayouts.cend(); i != e; ++i) {
void StickerPanInner::deleteUnusedInlineLayouts() {
if (_inlineRows.isEmpty()) { // delete all
for (InlineLayouts::const_iterator i = _inlineLayouts.cbegin(), e = _inlineLayouts.cend(); i != e; ++i) {
delete i.value();
}
_contextLayouts.clear();
_inlineLayouts.clear();
} else {
for (ContextLayouts::iterator i = _contextLayouts.begin(); i != _contextLayouts.cend();) {
for (InlineLayouts::iterator i = _inlineLayouts.begin(); i != _inlineLayouts.cend();) {
if (i.value()->position() < 0) {
delete i.value();
i = _contextLayouts.erase(i);
i = _inlineLayouts.erase(i);
} else {
++i;
}
@ -1741,7 +1741,7 @@ void StickerPanInner::deleteUnusedContextLayouts() {
}
}
StickerPanInner::ContextRow &StickerPanInner::layoutContextRow(ContextRow &row, int32 sumWidth) {
StickerPanInner::InlineRow &StickerPanInner::layoutInlineRow(InlineRow &row, int32 sumWidth) {
int32 count = row.items.size();
t_assert(count <= SavedGifsMaxPerRow);
@ -1760,10 +1760,10 @@ StickerPanInner::ContextRow &StickerPanInner::layoutContextRow(ContextRow &row,
}
void StickerPanInner::preloadImages() {
if (_showingContextItems) {
for (int32 row = 0, rows = _contextRows.size(); row < rows; ++row) {
for (int32 col = 0, cols = _contextRows.at(row).items.size(); col < cols; ++col) {
_contextRows.at(row).items.at(col)->preload();
if (_showingInlineItems) {
for (int32 row = 0, rows = _inlineRows.size(); row < rows; ++row) {
for (int32 col = 0, cols = _inlineRows.at(row).items.size(); col < cols; ++col) {
_inlineRows.at(row).items.at(col)->preload();
}
}
return;
@ -1788,7 +1788,7 @@ void StickerPanInner::preloadImages() {
}
uint64 StickerPanInner::currentSet(int yOffset) const {
if (_showingContextItems) return NoneStickerSetId;
if (_showingInlineItems) return NoneStickerSetId;
int y, ytill = 0;
for (int i = 0, l = _sets.size(); i < l; ++i) {
@ -1802,12 +1802,12 @@ uint64 StickerPanInner::currentSet(int yOffset) const {
return _sets.isEmpty() ? RecentStickerSetId : _sets.back().id;
}
void StickerPanInner::refreshContextRows(UserData *bot, const ContextResults &results) {
void StickerPanInner::refreshInlineRows(UserData *bot, const InlineResults &results) {
int32 count = results.size(), until = 0, untilrow = 0, untilcol = 0;
if (!count) {
_contextRows.clear();
_inlineRows.clear();
_showingSavedGifs = true;
if (_showingContextItems) {
if (_showingInlineItems) {
refreshSavedGifs();
emit scrollToY(0);
emit scrollUpdated();
@ -1818,62 +1818,62 @@ void StickerPanInner::refreshContextRows(UserData *bot, const ContextResults &re
t_assert(bot != 0);
_inlineBotTitle = lng_inline_bot_results(lt_inline_bot, bot->username.isEmpty() ? bot->name : ('@' + bot->username));
_showingContextItems = true;
_showingInlineItems = true;
_showingSavedGifs = false;
for (; until < count;) {
if (untilrow >= _contextRows.size() || _contextRows.at(untilrow).items.at(untilcol)->result() != results.at(until)) {
if (untilrow >= _inlineRows.size() || _inlineRows.at(untilrow).items.at(untilcol)->result() != results.at(until)) {
break;
}
++until;
if (++untilcol == _contextRows.at(untilrow).items.size()) {
if (++untilcol == _inlineRows.at(untilrow).items.size()) {
++untilrow;
untilcol = 0;
}
}
if (until == count) { // all items are layed out
if (untilrow == _contextRows.size()) { // nothing changed
if (untilrow == _inlineRows.size()) { // nothing changed
return;
}
for (int32 i = untilrow, l = _contextRows.size(), skip = untilcol; i < l; ++i) {
for (int32 j = 0, s = _contextRows.at(i).items.size(); j < s; ++j) {
for (int32 i = untilrow, l = _inlineRows.size(), skip = untilcol; i < l; ++i) {
for (int32 j = 0, s = _inlineRows.at(i).items.size(); j < s; ++j) {
if (skip) {
--skip;
} else {
_contextRows.at(i).items.at(j)->setPosition(-1);
_inlineRows.at(i).items.at(j)->setPosition(-1);
}
}
}
if (!untilcol) { // all good rows are filled
_contextRows.resize(untilrow);
_inlineRows.resize(untilrow);
return;
}
_contextRows.resize(untilrow + 1);
_contextRows[untilrow].items.resize(untilcol);
_contextRows[untilrow] = layoutContextRow(_contextRows[untilrow]);
_inlineRows.resize(untilrow + 1);
_inlineRows[untilrow].items.resize(untilcol);
_inlineRows[untilrow] = layoutInlineRow(_inlineRows[untilrow]);
return;
}
if (untilrow && !untilcol) { // remove last row, maybe it is not full
--untilrow;
untilcol = _contextRows.at(untilrow).items.size();
untilcol = _inlineRows.at(untilrow).items.size();
}
until -= untilcol;
for (int32 i = untilrow, l = _contextRows.size(); i < l; ++i) {
for (int32 j = 0, s = _contextRows.at(i).items.size(); j < s; ++j) {
_contextRows.at(i).items.at(j)->setPosition(-1);
for (int32 i = untilrow, l = _inlineRows.size(); i < l; ++i) {
for (int32 j = 0, s = _inlineRows.at(i).items.size(); j < s; ++j) {
_inlineRows.at(i).items.at(j)->setPosition(-1);
}
}
_contextRows.resize(untilrow);
_inlineRows.resize(untilrow);
_contextRows.reserve(count);
ContextRow row;
_inlineRows.reserve(count);
InlineRow row;
row.items.reserve(SavedGifsMaxPerRow);
int32 sumWidth = 0;
for (int32 i = until; i < count; ++i) {
contextRowsAddItem(0, results.at(i), row, sumWidth);
inlineRowsAddItem(0, results.at(i), row, sumWidth);
}
contextRowFinalize(row, sumWidth, true);
inlineRowFinalize(row, sumWidth, true);
int32 h = countHeight();
if (h != height()) resize(width(), h);
@ -1883,33 +1883,33 @@ void StickerPanInner::refreshContextRows(UserData *bot, const ContextResults &re
updateSelected();
}
void StickerPanInner::ui_repaintContextItem(const LayoutContextItem *layout) {
void StickerPanInner::ui_repaintInlineItem(const LayoutInlineItem *layout) {
uint64 ms = getms();
if (_lastScrolled + 100 <= ms) {
update();
} else {
_updateContextItems.start(_lastScrolled + 100 - ms);
_updateInlineItems.start(_lastScrolled + 100 - ms);
}
}
bool StickerPanInner::ui_isContextItemVisible(const LayoutContextItem *layout) {
bool StickerPanInner::ui_isInlineItemVisible(const LayoutInlineItem *layout) {
int32 position = layout->position();
if (!_showingContextItems || position < 0) return false;
if (!_showingInlineItems || position < 0) return false;
int32 row = position / MatrixRowShift, col = position % MatrixRowShift;
t_assert((row < _contextRows.size()) && (col < _contextRows.at(row).items.size()));
t_assert((row < _inlineRows.size()) && (col < _inlineRows.at(row).items.size()));
const ContextItems &contextItems(_contextRows.at(row).items);
const InlineItems &inlineItems(_inlineRows.at(row).items);
int32 top = st::emojiPanHeader;
for (int32 i = 0; i < row; ++i) {
top += _contextRows.at(i).height;
top += _inlineRows.at(i).height;
}
return (top < _top + _maxHeight) && (top + _contextRows.at(row).items.at(col)->height() > _top);
return (top < _top + _maxHeight) && (top + _inlineRows.at(row).items.at(col)->height() > _top);
}
bool StickerPanInner::ui_isContextItemBeingChosen() {
return _showingContextItems;
bool StickerPanInner::ui_isInlineItemBeingChosen() {
return _showingInlineItems;
}
void StickerPanInner::appendSet(uint64 setId) {
@ -1926,7 +1926,7 @@ void StickerPanInner::appendSet(uint64 setId) {
}
void StickerPanInner::refreshRecent() {
if (_showingContextItems) {
if (_showingInlineItems) {
if (_showingSavedGifs) {
refreshSavedGifs();
}
@ -1972,7 +1972,7 @@ void StickerPanInner::refreshRecentStickers(bool performResize) {
}
}
if (performResize && !_showingContextItems) {
if (performResize && !_showingInlineItems) {
int32 h = countHeight();
if (h != height()) {
resize(width(), h);
@ -2016,7 +2016,7 @@ void StickerPanInner::fillPanels(QVector<EmojiPanel*> &panels) {
}
panels.clear();
if (_showingContextItems) {
if (_showingInlineItems) {
panels.push_back(new EmojiPanel(parentWidget(), _showingSavedGifs ? lang(lng_saved_gifs) : _inlineBotTitle, NoneStickerSetId, true, 0));
panels.back()->show();
return;
@ -2038,7 +2038,7 @@ void StickerPanInner::fillPanels(QVector<EmojiPanel*> &panels) {
}
void StickerPanInner::refreshPanels(QVector<EmojiPanel*> &panels) {
if (_showingContextItems) return;
if (_showingInlineItems) return;
if (panels.size() != _sets.size()) return fillPanels(panels);
@ -2057,33 +2057,33 @@ void StickerPanInner::updateSelected() {
int32 selIndex = -1;
QPoint p(mapFromGlobal(_lastMousePos));
if (_showingContextItems) {
if (_showingInlineItems) {
int sx = (rtl() ? width() - p.x() : p.x()) - st::inlineResultsLeft, sy = p.y() - st::emojiPanHeader;
int32 row = -1, col = -1, sel = -1;
TextLinkPtr lnk;
HistoryCursorState cursor = HistoryDefaultCursorState;
if (sy >= 0) {
row = 0;
for (int32 rows = _contextRows.size(); row < rows; ++row) {
if (sy < _contextRows.at(row).height) {
for (int32 rows = _inlineRows.size(); row < rows; ++row) {
if (sy < _inlineRows.at(row).height) {
break;
}
sy -= _contextRows.at(row).height;
sy -= _inlineRows.at(row).height;
}
}
if (sx >= 0 && row >= 0 && row < _contextRows.size()) {
const ContextItems &contextItems(_contextRows.at(row).items);
if (sx >= 0 && row >= 0 && row < _inlineRows.size()) {
const InlineItems &inlineItems(_inlineRows.at(row).items);
col = 0;
for (int32 cols = contextItems.size(); col < cols; ++col) {
int32 width = contextItems.at(col)->width();
for (int32 cols = inlineItems.size(); col < cols; ++col) {
int32 width = inlineItems.at(col)->width();
if (sx < width) {
break;
}
sx -= width + st::inlineResultsSkip;
}
if (col < contextItems.size()) {
if (col < inlineItems.size()) {
sel = row * MatrixRowShift + col;
contextItems.at(col)->getState(lnk, cursor, sx, sy);
inlineItems.at(col)->getState(lnk, cursor, sx, sy);
} else {
row = col = -1;
}
@ -2094,26 +2094,26 @@ void StickerPanInner::updateSelected() {
int32 scol = (_selected >= 0) ? (_selected % MatrixRowShift) : -1;
if (_selected != sel) {
if (srow >= 0 && scol >= 0) {
t_assert(srow >= 0 && srow < _contextRows.size() && scol >= 0 && scol < _contextRows.at(srow).items.size());
Ui::repaintContextItem(_contextRows.at(srow).items.at(scol));
t_assert(srow >= 0 && srow < _inlineRows.size() && scol >= 0 && scol < _inlineRows.at(srow).items.size());
Ui::repaintInlineItem(_inlineRows.at(srow).items.at(scol));
}
_selected = sel;
if (row >= 0 && col >= 0) {
t_assert(row >= 0 && row < _contextRows.size() && col >= 0 && col < _contextRows.at(row).items.size());
Ui::repaintContextItem(_contextRows.at(row).items.at(col));
t_assert(row >= 0 && row < _inlineRows.size() && col >= 0 && col < _inlineRows.at(row).items.size());
Ui::repaintInlineItem(_inlineRows.at(row).items.at(col));
}
if (_pressedSel >= 0 && _selected >= 0 && _pressedSel != _selected) {
_pressedSel = _selected;
if (row >= 0 && col >= 0 && _contextRows.at(row).items.at(col)->document()) {
Ui::showStickerPreview(_contextRows.at(row).items.at(col)->document());
if (row >= 0 && col >= 0 && _inlineRows.at(row).items.at(col)->document()) {
Ui::showStickerPreview(_inlineRows.at(row).items.at(col)->document());
}
}
}
if (_linkOver != lnk) {
if (_linkOver && srow >= 0 && scol >= 0) {
t_assert(srow >= 0 && srow < _contextRows.size() && scol >= 0 && scol < _contextRows.at(srow).items.size());
_contextRows.at(srow).items.at(scol)->linkOut(_linkOver);
Ui::repaintContextItem(_contextRows.at(srow).items.at(scol));
t_assert(srow >= 0 && srow < _inlineRows.size() && scol >= 0 && scol < _inlineRows.at(srow).items.size());
_inlineRows.at(srow).items.at(scol)->linkOut(_linkOver);
Ui::repaintInlineItem(_inlineRows.at(srow).items.at(scol));
}
if ((_linkOver && !lnk) || (!_linkOver && lnk)) {
setCursor(lnk ? style::cur_pointer : style::cur_default);
@ -2121,9 +2121,9 @@ void StickerPanInner::updateSelected() {
_linkOver = lnk;
textlnkOver(lnk);
if (_linkOver && row >= 0 && col >= 0) {
t_assert(row >= 0 && row < _contextRows.size() && col >= 0 && col < _contextRows.at(row).items.size());
_contextRows.at(row).items.at(col)->linkOver(_linkOver);
Ui::repaintContextItem(_contextRows.at(row).items.at(col));
t_assert(row >= 0 && row < _inlineRows.size() && col >= 0 && col < _inlineRows.at(row).items.size());
_inlineRows.at(row).items.at(col)->linkOver(_linkOver);
Ui::repaintInlineItem(_inlineRows.at(row).items.at(col));
}
}
@ -2217,10 +2217,10 @@ void StickerPanInner::onSettings() {
void StickerPanInner::onPreview() {
if (_pressedSel < 0) return;
if (_showingContextItems) {
if (_showingInlineItems) {
int32 row = _pressedSel / MatrixRowShift, col = _pressedSel % MatrixRowShift;
if (row < _contextRows.size() && col < _contextRows.at(row).items.size() && _contextRows.at(row).items.at(col)->document() && _contextRows.at(row).items.at(col)->document()->loaded()) {
Ui::showStickerPreview(_contextRows.at(row).items.at(col)->document());
if (row < _inlineRows.size() && col < _inlineRows.at(row).items.size() && _inlineRows.at(row).items.at(col)->document() && _inlineRows.at(row).items.at(col)->document()->loaded()) {
Ui::showStickerPreview(_inlineRows.at(row).items.at(col)->document());
_previewShown = true;
}
} else if (_pressedSel < MatrixRowShift * _sets.size()) {
@ -2232,14 +2232,14 @@ void StickerPanInner::onPreview() {
}
}
void StickerPanInner::onUpdateContextItems() {
if (!_showingContextItems) return;
void StickerPanInner::onUpdateInlineItems() {
if (!_showingInlineItems) return;
uint64 ms = getms();
if (_lastScrolled + 100 <= ms) {
update();
} else {
_updateContextItems.start(_lastScrolled + 100 - ms);
_updateInlineItems.start(_lastScrolled + 100 - ms);
}
}
@ -2265,9 +2265,9 @@ void StickerPanInner::showStickerSet(uint64 setId) {
clearSelection(true);
if (setId == NoneStickerSetId) {
bool wasNotShowingGifs = !_showingContextItems;
bool wasNotShowingGifs = !_showingInlineItems;
if (wasNotShowingGifs) {
_showingContextItems = true;
_showingInlineItems = true;
cSetShowingSavedGifs(true);
emit saveConfigDelayed(SaveRecentEmojisTimeout);
}
@ -2277,8 +2277,8 @@ void StickerPanInner::showStickerSet(uint64 setId) {
return;
}
if (_showingContextItems) {
_showingContextItems = false;
if (_showingInlineItems) {
_showingInlineItems = false;
cSetShowingSavedGifs(false);
emit saveConfigDelayed(SaveRecentEmojisTimeout);
@ -2433,8 +2433,8 @@ EmojiPan::EmojiPan(QWidget *parent) : TWidget(parent)
, s_inner()
, s_switch(&s_scroll, false)
, _removingSetId(0)
, _contextBot(0)
, _contextRequestId(0) {
, _inlineBot(0)
, _inlineRequestId(0) {
setFocusPolicy(Qt::NoFocus);
e_scroll.setFocusPolicy(Qt::NoFocus);
e_scroll.viewport()->setFocusPolicy(Qt::NoFocus);
@ -2499,9 +2499,9 @@ EmojiPan::EmojiPan(QWidget *parent) : TWidget(parent)
connect(&e_inner, SIGNAL(saveConfigDelayed(int32)), this, SLOT(onSaveConfigDelayed(int32)));
connect(&s_inner, SIGNAL(saveConfigDelayed(int32)), this, SLOT(onSaveConfigDelayed(int32)));
// context bots
_contextRequestTimer.setSingleShot(true);
connect(&_contextRequestTimer, SIGNAL(timeout()), this, SLOT(onContextRequest()));
// inline bots
_inlineRequestTimer.setSingleShot(true);
connect(&_inlineRequestTimer, SIGNAL(timeout()), this, SLOT(onInlineRequest()));
if (cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
connect(App::wnd()->windowHandle(), SIGNAL(activeChanged()), this, SLOT(onWndActiveChanged()));
@ -2679,7 +2679,7 @@ void EmojiPan::enterEvent(QEvent *e) {
}
void EmojiPan::leaveEvent(QEvent *e) {
if (_removingSetId || s_inner.contextResultsShown()) return;
if (_removingSetId || s_inner.inlineResultsShown()) return;
if (_a_appearance.animating()) {
hideStart();
} else {
@ -2693,7 +2693,7 @@ void EmojiPan::otherEnter() {
}
void EmojiPan::otherLeave() {
if (_removingSetId || s_inner.contextResultsShown()) return;
if (_removingSetId || s_inner.inlineResultsShown()) return;
if (_a_appearance.animating()) {
hideStart();
} else {
@ -3007,7 +3007,7 @@ void EmojiPan::step_appearance(float64 ms, bool timer) {
}
void EmojiPan::hideStart() {
if (_removingSetId || s_inner.contextResultsShown()) return;
if (_removingSetId || s_inner.inlineResultsShown()) return;
if (_cache.isNull()) {
QPixmap from = _fromCache, to = _toCache;
@ -3112,22 +3112,22 @@ void EmojiPan::stickersInstalled(uint64 setId) {
showStart();
}
void EmojiPan::ui_repaintContextItem(const LayoutContextItem *layout) {
void EmojiPan::ui_repaintInlineItem(const LayoutInlineItem *layout) {
if (_stickersShown && !isHidden()) {
s_inner.ui_repaintContextItem(layout);
s_inner.ui_repaintInlineItem(layout);
}
}
bool EmojiPan::ui_isContextItemVisible(const LayoutContextItem *layout) {
bool EmojiPan::ui_isInlineItemVisible(const LayoutInlineItem *layout) {
if (_stickersShown && !isHidden()) {
return s_inner.ui_isContextItemVisible(layout);
return s_inner.ui_isInlineItemVisible(layout);
}
return false;
}
bool EmojiPan::ui_isContextItemBeingChosen() {
bool EmojiPan::ui_isInlineItemBeingChosen() {
if (_stickersShown && !isHidden()) {
return s_inner.ui_isContextItemBeingChosen();
return s_inner.ui_isInlineItemBeingChosen();
}
return false;
}
@ -3346,35 +3346,35 @@ void EmojiPan::onDelayedHide() {
_removingSetId = 0;
}
void EmojiPan::contextBotChanged() {
if (!_contextBot) return;
void EmojiPan::inlineBotChanged() {
if (!_inlineBot) return;
if (!isHidden()) hideStart();
if (_contextRequestId) MTP::cancel(_contextRequestId);
_contextRequestId = 0;
_contextQuery = _contextNextQuery = _contextNextOffset = QString();
_contextBot = 0;
for (ContextCache::const_iterator i = _contextCache.cbegin(), e = _contextCache.cend(); i != e; ++i) {
if (_inlineRequestId) MTP::cancel(_inlineRequestId);
_inlineRequestId = 0;
_inlineQuery = _inlineNextQuery = _inlineNextOffset = QString();
_inlineBot = 0;
for (InlineCache::const_iterator i = _inlineCache.cbegin(), e = _inlineCache.cend(); i != e; ++i) {
delete i.value();
}
_contextCache.clear();
s_inner.contextBotChanged();
_inlineCache.clear();
s_inner.inlineBotChanged();
}
void EmojiPan::contextResultsDone(const MTPmessages_BotResults &result) {
_contextRequestId = 0;
void EmojiPan::inlineResultsDone(const MTPmessages_BotResults &result) {
_inlineRequestId = 0;
ContextCache::iterator it = _contextCache.find(_contextQuery);
InlineCache::iterator it = _inlineCache.find(_inlineQuery);
bool adding = (it != _contextCache.cend());
bool adding = (it != _inlineCache.cend());
if (result.type() == mtpc_messages_botResults) {
const MTPDmessages_botResults &d(result.c_messages_botResults());
const QVector<MTPBotContextResult> &v(d.vresults.c_vector().v);
const QVector<MTPBotInlineResult> &v(d.vresults.c_vector().v);
uint64 queryId(d.vquery_id.v);
if (!adding) {
it = _contextCache.insert(_contextQuery, new ContextCacheEntry());
it = _inlineCache.insert(_inlineQuery, new InlineCacheEntry());
}
it.value()->nextOffset = v.isEmpty() ? QString() : qs(d.vnext_offset);
@ -3383,25 +3383,25 @@ void EmojiPan::contextResultsDone(const MTPmessages_BotResults &result) {
it.value()->results.reserve(it.value()->results.size() + count);
}
for (int32 i = 0; i < count; ++i) {
ContextResult *result = new ContextResult(queryId);
const MTPBotContextMessage *message = 0;
InlineResult *result = new InlineResult(queryId);
const MTPBotInlineMessage *message = 0;
switch (v.at(i).type()) {
case mtpc_botContextMediaResultPhoto: {
const MTPDbotContextMediaResultPhoto &r(v.at(i).c_botContextMediaResultPhoto());
case mtpc_botInlineMediaResultPhoto: {
const MTPDbotInlineMediaResultPhoto &r(v.at(i).c_botInlineMediaResultPhoto());
result->id = qs(r.vid);
result->type = qs(r.vtype);
result->photo = App::feedPhoto(r.vphoto);
message = &r.vsend_message;
} break;
case mtpc_botContextMediaResultDocument: {
const MTPDbotContextMediaResultDocument &r(v.at(i).c_botContextMediaResultDocument());
case mtpc_botInlineMediaResultDocument: {
const MTPDbotInlineMediaResultDocument &r(v.at(i).c_botInlineMediaResultDocument());
result->id = qs(r.vid);
result->type = qs(r.vtype);
result->doc = App::feedDocument(r.vdocument);
message = &r.vsend_message;
} break;
case mtpc_botContextResult: {
const MTPDbotContextResult &r(v.at(i).c_botContextResult());
case mtpc_botInlineResult: {
const MTPDbotInlineResult &r(v.at(i).c_botInlineResult());
result->id = qs(r.vid);
result->type = qs(r.vtype);
result->title = qs(r.vtitle);
@ -3420,13 +3420,13 @@ void EmojiPan::contextResultsDone(const MTPmessages_BotResults &result) {
continue;
}
switch (message->type()) {
case mtpc_botContextMessageMediaAuto: {
const MTPDbotContextMessageMediaAuto &r(message->c_botContextMessageMediaAuto());
case mtpc_botInlineMessageMediaAuto: {
const MTPDbotInlineMessageMediaAuto &r(message->c_botInlineMessageMediaAuto());
result->caption = qs(r.vcaption);
} break;
case mtpc_botContextMessageText: {
const MTPDbotContextMessageText &r(message->c_botContextMessageText());
case mtpc_botInlineMessageText: {
const MTPDbotInlineMessageText &r(message->c_botInlineMessageText());
result->message = qs(r.vmessage);
if (r.has_entities()) result->entities = entitiesFromMTP(r.ventities.c_vector().v);
result->noWebPage = r.is_no_webpage();
@ -3448,61 +3448,66 @@ void EmojiPan::contextResultsDone(const MTPmessages_BotResults &result) {
it.value()->clearResults();
it.value()->nextOffset = QString();
}
showContextRows(!adding);
showInlineRows(!adding);
}
bool EmojiPan::contextResultsFail(const RPCError &error) {
bool EmojiPan::inlineResultsFail(const RPCError &error) {
if (mtpIsFlood(error)) return false;
_contextRequestId = 0;
_inlineRequestId = 0;
return true;
}
void EmojiPan::queryContextBot(UserData *bot, QString query) {
void EmojiPan::queryInlineBot(UserData *bot, QString query) {
bool force = false;
if (bot != _contextBot) {
contextBotChanged();
_contextBot = bot;
if (bot != _inlineBot) {
LOG(("Inline bot changed! to @%1").arg(bot->username));
inlineBotChanged();
_inlineBot = bot;
force = true;
}
if (_contextRequestId) {
MTP::cancel(_contextRequestId);
_contextRequestId = 0;
if (_inlineRequestId) {
MTP::cancel(_inlineRequestId);
_inlineRequestId = 0;
}
if (_contextQuery != query || force) {
if (_contextCache.contains(query)) {
_contextQuery = query;
showContextRows(true);
if (_inlineQuery != query || force) {
if (_inlineCache.contains(query)) {
LOG(("Query %1 found in cache!").arg(query));
_inlineQuery = query;
showInlineRows(true);
} else {
_contextNextQuery = query;
_contextRequestTimer.start(ContextBotRequestDelay);
LOG(("Scheduling request for %1!").arg(query));
_inlineNextQuery = query;
_inlineRequestTimer.start(InlineBotRequestDelay);
}
}
}
void EmojiPan::onContextRequest() {
if (_contextRequestId) return;
_contextQuery = _contextNextQuery;
void EmojiPan::onInlineRequest() {
if (_inlineRequestId) return;
_inlineQuery = _inlineNextQuery;
QString nextOffset;
ContextCache::const_iterator i = _contextCache.constFind(_contextQuery);
if (i != _contextCache.cend()) {
InlineCache::const_iterator i = _inlineCache.constFind(_inlineQuery);
if (i != _inlineCache.cend()) {
nextOffset = i.value()->nextOffset;
if (nextOffset.isEmpty()) return;
}
_contextRequestId = MTP::send(MTPmessages_GetContextBotResults(_contextBot->inputUser, MTP_string(_contextQuery), MTP_string(nextOffset)), rpcDone(&EmojiPan::contextResultsDone), rpcFail(&EmojiPan::contextResultsFail));
LOG(("Requesting %1 with offset \"%2\"!").arg(_inlineQuery).arg(nextOffset));
_inlineRequestId = MTP::send(MTPmessages_GetInlineBotResults(_inlineBot->inputUser, MTP_string(_inlineQuery), MTP_string(nextOffset)), rpcDone(&EmojiPan::inlineResultsDone), rpcFail(&EmojiPan::inlineResultsFail));
}
void EmojiPan::showContextRows(bool newResults) {
void EmojiPan::showInlineRows(bool newResults) {
bool clear = true;
ContextCache::const_iterator i = _contextCache.constFind(_contextQuery);
if (i != _contextCache.cend()) {
InlineCache::const_iterator i = _inlineCache.constFind(_inlineQuery);
if (i != _inlineCache.cend()) {
clear = i.value()->results.isEmpty();
_contextNextOffset = i.value()->nextOffset;
_inlineNextOffset = i.value()->nextOffset;
}
s_inner.refreshContextRows(_contextBot, clear ? ContextResults() : i.value()->results);
if (clear) LOG(("Clearing results!")); else LOG(("Showing results: %1").arg(i.value()->results.size()));
s_inner.refreshInlineRows(_inlineBot, clear ? InlineResults() : i.value()->results);
if (newResults) s_scroll.scrollToY(0);
if (clear && !isHidden() && _stickersShown && s_inner.contextResultsShown()) {
if (clear && !isHidden() && _stickersShown && s_inner.inlineResultsShown()) {
hideStart();
} else if (!clear) {
_hideTimer.stop();

View File

@ -341,9 +341,9 @@ public:
void refreshStickers();
void refreshRecentStickers(bool resize = true);
void refreshSavedGifs();
void refreshContextRows(UserData *bot, const ContextResults &results);
void refreshInlineRows(UserData *bot, const InlineResults &results);
void refreshRecent();
void contextBotChanged();
void inlineBotChanged();
void fillIcons(QList<StickerIcon> &icons);
void fillPanels(QVector<EmojiPanel*> &panels);
@ -354,18 +354,18 @@ public:
uint64 currentSet(int yOffset) const;
void ui_repaintContextItem(const LayoutContextItem *layout);
bool ui_isContextItemVisible(const LayoutContextItem *layout);
bool ui_isContextItemBeingChosen();
void ui_repaintInlineItem(const LayoutInlineItem *layout);
bool ui_isInlineItemVisible(const LayoutInlineItem *layout);
bool ui_isInlineItemBeingChosen();
bool contextResultsShown() const {
return _showingContextItems && !_showingSavedGifs;
bool inlineResultsShown() const {
return _showingInlineItems && !_showingSavedGifs;
}
~StickerPanInner() {
clearContextRows();
clearInlineRows();
deleteUnusedGifLayouts();
deleteUnusedContextLayouts();
deleteUnusedInlineLayouts();
}
public slots:
@ -373,7 +373,7 @@ public slots:
void updateSelected();
void onSettings();
void onPreview();
void onUpdateContextItems();
void onUpdateInlineItems();
signals:
@ -393,7 +393,7 @@ signals:
private:
void paintContextItems(Painter &p, const QRect &r);
void paintInlineItems(Painter &p, const QRect &r);
void paintStickers(Painter &p, const QRect &r);
int32 _maxHeight;
@ -422,37 +422,37 @@ private:
QList<DisplayedSet> _sets;
QList<bool> _custom;
bool _showingSavedGifs, _showingContextItems;
bool _showingSavedGifs, _showingInlineItems;
QString _inlineBotTitle;
uint64 _lastScrolled;
QTimer _updateContextItems;
QTimer _updateInlineItems;
typedef QVector<LayoutContextItem*> ContextItems;
struct ContextRow {
ContextRow() : height(0) {
typedef QVector<LayoutInlineItem*> InlineItems;
struct InlineRow {
InlineRow() : height(0) {
}
int32 height;
ContextItems items;
InlineItems items;
};
typedef QVector<ContextRow> ContextRows;
ContextRows _contextRows;
void clearContextRows();
typedef QVector<InlineRow> InlineRows;
InlineRows _inlineRows;
void clearInlineRows();
typedef QMap<DocumentData*, LayoutContextGif*> GifLayouts;
typedef QMap<DocumentData*, LayoutInlineGif*> GifLayouts;
GifLayouts _gifLayouts;
LayoutContextGif *layoutPrepareSavedGif(DocumentData *doc, int32 position);
LayoutInlineGif *layoutPrepareSavedGif(DocumentData *doc, int32 position);
typedef QMap<ContextResult*, LayoutContextItem*> ContextLayouts;
ContextLayouts _contextLayouts;
LayoutContextItem *layoutPrepareContextResult(ContextResult *result, int32 position);
typedef QMap<InlineResult*, LayoutInlineItem*> InlineLayouts;
InlineLayouts _inlineLayouts;
LayoutInlineItem *layoutPrepareInlineResult(InlineResult *result, int32 position);
void contextRowsAddItem(DocumentData *savedGif, ContextResult *result, ContextRow &row, int32 &sumWidth);
void contextRowFinalize(ContextRow &row, int32 &sumWidth, bool force = false);
void inlineRowsAddItem(DocumentData *savedGif, InlineResult *result, InlineRow &row, int32 &sumWidth);
void inlineRowFinalize(InlineRow &row, int32 &sumWidth, bool force = false);
ContextRow &layoutContextRow(ContextRow &row, int32 sumWidth = 0);
InlineRow &layoutInlineRow(InlineRow &row, int32 sumWidth = 0);
void deleteUnusedGifLayouts();
void deleteUnusedContextLayouts();
void deleteUnusedInlineLayouts();
int32 _selected, _pressedSel;
QPoint _lastMousePos;
@ -552,8 +552,8 @@ public:
bool eventFilter(QObject *obj, QEvent *e);
void stickersInstalled(uint64 setId);
void queryContextBot(UserData *bot, QString query);
void contextBotChanged();
void queryInlineBot(UserData *bot, QString query);
void inlineBotChanged();
bool overlaps(const QRect &globalRect) {
if (isHidden() || !_cache.isNull()) return false;
@ -565,9 +565,9 @@ public:
).contains(QRect(mapFromGlobal(globalRect.topLeft()), globalRect.size()));
}
void ui_repaintContextItem(const LayoutContextItem *layout);
bool ui_isContextItemVisible(const LayoutContextItem *layout);
bool ui_isContextItemBeingChosen();
void ui_repaintInlineItem(const LayoutInlineItem *layout);
bool ui_isInlineItemVisible(const LayoutInlineItem *layout);
bool ui_isInlineItemBeingChosen();
public slots:
@ -594,7 +594,7 @@ public slots:
void onSaveConfig();
void onSaveConfigDelayed(int32 delay);
void onContextRequest();
void onInlineRequest();
signals:
@ -666,13 +666,13 @@ private:
QTimer _saveConfigTimer;
// context bots
struct ContextCacheEntry {
~ContextCacheEntry() {
// inline bots
struct InlineCacheEntry {
~InlineCacheEntry() {
clearResults();
}
QString nextOffset;
ContextResults results;
InlineResults results;
void clearResults() {
for (int32 i = 0, l = results.size(); i < l; ++i) {
delete results.at(i);
@ -680,16 +680,16 @@ private:
results.clear();
}
};
typedef QMap<QString, ContextCacheEntry*> ContextCache;
ContextCache _contextCache;
QTimer _contextRequestTimer;
typedef QMap<QString, InlineCacheEntry*> InlineCache;
InlineCache _inlineCache;
QTimer _inlineRequestTimer;
void showContextRows(bool newResults);
UserData *_contextBot;
QString _contextQuery, _contextNextQuery, _contextNextOffset;
mtpRequestId _contextRequestId;
void contextResultsDone(const MTPmessages_BotResults &result);
bool contextResultsFail(const RPCError &error);
void showInlineRows(bool newResults);
UserData *_inlineBot;
QString _inlineQuery, _inlineNextQuery, _inlineNextOffset;
mtpRequestId _inlineRequestId;
void inlineResultsDone(const MTPmessages_BotResults &result);
bool inlineResultsFail(const RPCError &error);
};

View File

@ -102,8 +102,8 @@ namespace Ui {
return false;
}
bool isContextItemBeingChosen() {
if (MainWidget *m = App::main()) return m->ui_isContextItemBeingChosen();
bool isInlineItemBeingChosen() {
if (MainWidget *m = App::main()) return m->ui_isInlineItemBeingChosen();
return false;
}
@ -112,13 +112,13 @@ namespace Ui {
if (MainWidget *m = App::main()) m->ui_repaintHistoryItem(item);
}
void repaintContextItem(const LayoutContextItem *layout) {
void repaintInlineItem(const LayoutInlineItem *layout) {
if (!layout) return;
if (MainWidget *m = App::main()) m->ui_repaintContextItem(layout);
if (MainWidget *m = App::main()) m->ui_repaintInlineItem(layout);
}
bool isContextItemVisible(const LayoutContextItem *layout) {
if (MainWidget *m = App::main()) return m->ui_isContextItemVisible(layout);
bool isInlineItemVisible(const LayoutInlineItem *layout) {
if (MainWidget *m = App::main()) return m->ui_isInlineItemVisible(layout);
return false;
}

View File

@ -46,11 +46,11 @@ namespace Ui { // openssl doesn't allow me to use UI :(
void hideLayer(bool fast = false);
bool isLayerShown();
bool isMediaViewShown();
bool isContextItemBeingChosen();
bool isInlineItemBeingChosen();
void repaintHistoryItem(const HistoryItem *item);
void repaintContextItem(const LayoutContextItem *layout);
bool isContextItemVisible(const LayoutContextItem *reader);
void repaintInlineItem(const LayoutInlineItem *layout);
bool isInlineItemVisible(const LayoutInlineItem *reader);
void showPeerHistory(const PeerId &peer, MsgId msgId, bool back = false);
inline void showPeerHistory(const PeerData *peer, MsgId msgId, bool back = false) {

View File

@ -95,6 +95,7 @@ namespace anim {
_clipThreads.at(i)->quit();
_clipThreads.at(i)->wait();
delete _clipManagers.at(i);
delete _clipThreads.at(i);
}
_clipThreads.clear();
_clipManagers.clear();

View File

@ -252,53 +252,53 @@ EmojiPtr FlatTextarea::getSingleEmoji() const {
return 0;
}
void FlatTextarea::getMentionHashtagBotCommandStart(QString &start, UserData *&contextBot, QString &contextBotUsername) const {
void FlatTextarea::getMentionHashtagBotCommandStart(QString &start, UserData *&inlineBot, QString &inlineBotUsername) const {
int32 pos = textCursor().position();
if (textCursor().anchor() != pos) return;
// check context bot query
// check inline bot query
const QString &text(getLastText());
int32 contextUsernameStart = 1, contextUsernameLength = 0, size = text.size();
int32 inlineUsernameStart = 1, inlineUsernameLength = 0, size = text.size();
if (size > 2 && text.at(0) == '@' && text.at(1).isLetter()) {
contextUsernameLength = 1;
for (int32 i = contextUsernameStart + 1, l = text.size(); i < l; ++i) {
inlineUsernameLength = 1;
for (int32 i = inlineUsernameStart + 1, l = text.size(); i < l; ++i) {
if (text.at(i).isLetterOrNumber() || text.at(i).unicode() == '_') {
++contextUsernameLength;
++inlineUsernameLength;
continue;
}
if (!text.at(i).isSpace()) {
contextUsernameLength = 0;
inlineUsernameLength = 0;
}
break;
}
if (contextUsernameLength && contextUsernameStart + contextUsernameLength < text.size() && text.at(contextUsernameStart + contextUsernameLength).isSpace()) {
QStringRef username = text.midRef(contextUsernameStart, contextUsernameLength);
if (username != contextBotUsername) {
contextBotUsername = username.toString();
PeerData *peer = App::peerByName(contextBotUsername);
if (inlineUsernameLength && inlineUsernameStart + inlineUsernameLength < text.size() && text.at(inlineUsernameStart + inlineUsernameLength).isSpace()) {
QStringRef username = text.midRef(inlineUsernameStart, inlineUsernameLength);
if (username != inlineBotUsername) {
inlineBotUsername = username.toString();
PeerData *peer = App::peerByName(inlineBotUsername);
if (peer) {
if (peer->isUser()) {
contextBot = peer->asUser();
inlineBot = peer->asUser();
} else {
contextBot = 0;
inlineBot = 0;
}
} else {
contextBot = ContextBotLookingUpData;
inlineBot = InlineBotLookingUpData;
}
}
if (contextBot == ContextBotLookingUpData) return;
if (inlineBot == InlineBotLookingUpData) return;
if (contextBot && (!contextBot->botInfo || contextBot->botInfo->contextPlaceholder.isEmpty())) {
contextBot = 0;
if (inlineBot && (!inlineBot->botInfo || inlineBot->botInfo->inlinePlaceholder.isEmpty())) {
inlineBot = 0;
} else {
start = text.mid(contextUsernameStart + contextUsernameLength + 1);
start = text.mid(inlineUsernameStart + inlineUsernameLength + 1);
return;
}
}
}
if (!contextUsernameLength) {
contextBot = 0;
contextBotUsername = QString();
if (!inlineUsernameLength) {
inlineBot = 0;
inlineBotUsername = QString();
}
// check mention / hashtag / bot command

View File

@ -30,6 +30,9 @@ namespace {
typedef QMap<QString, Image*> LocalImages;
LocalImages localImages;
typedef QMap<QString, Image*> WebImages;
WebImages webImages;
Image *blank() {
static Image *img = getImage(qsl(":/gui/art/blank.gif"), "GIF");
return img;
@ -558,13 +561,22 @@ Image::~Image() {
}
Image *getImage(const QString &file, QByteArray format) {
QFileInfo f(file);
QString key = qsl("//:%1//:%2//:").arg(f.size()).arg(f.lastModified().toTime_t()) + file;
LocalImages::const_iterator i = localImages.constFind(key);
if (i == localImages.cend()) {
i = localImages.insert(key, new Image(file, format));
if (file.startsWith(qstr("http://"), Qt::CaseInsensitive) || file.startsWith(qstr("https://"), Qt::CaseInsensitive)) {
QString key = file;
WebImages::const_iterator i = webImages.constFind(key);
if (i == webImages.cend()) {
i = webImages.insert(key, new WebImage(file));
}
return i.value();
} else {
QFileInfo f(file);
QString key = qsl("//:%1//:%2//:").arg(f.size()).arg(f.lastModified().toTime_t()) + file;
LocalImages::const_iterator i = localImages.constFind(key);
if (i == localImages.cend()) {
i = localImages.insert(key, new Image(file, format));
}
return i.value();
}
return i.value();
}
Image *getImage(const QByteArray &filecontent, QByteArray format) {
@ -584,6 +596,10 @@ void clearStorageImages() {
delete i.value();
}
storageImages.clear();
for (WebImages::const_iterator i = webImages.cbegin(), e = webImages.cend(); i != e; ++i) {
delete i.value();
}
webImages.clear();
}
void clearAllImages() {
@ -598,10 +614,149 @@ int64 imageCacheSize() {
return globalAcquiredSize;
}
StorageImage::StorageImage(const StorageImageLocation &location, int32 size) : _location(location), _size(size), _loader(0) {
void RemoteImage::doCheckload() const {
if (!amLoading() || !_loader->done()) return;
QPixmap data = _loader->imagePixmap();
if (data.isNull()) {
_loader->deleteLater();
_loader->stop();
_loader = CancelledFileLoader;
return;
}
if (!_data.isNull()) {
globalAcquiredSize -= int64(_data.width()) * _data.height() * 4;
}
_format = _loader->imageFormat();
_data = data;
_saved = _loader->bytes();
const_cast<RemoteImage*>(this)->setInformation(_saved.size(), _data.width(), _data.height());
globalAcquiredSize += int64(_data.width()) * _data.height() * 4;
invalidateSizeCache();
_loader->deleteLater();
_loader->stop();
_loader = 0;
_forgot = false;
}
StorageImage::StorageImage(const StorageImageLocation &location, QByteArray &bytes) : _location(location), _size(bytes.size()), _loader(0) {
void RemoteImage::setData(QByteArray &bytes, const QByteArray &bytesFormat) {
QBuffer buffer(&bytes);
if (!_data.isNull()) {
globalAcquiredSize -= int64(_data.width()) * _data.height() * 4;
}
QByteArray fmt(bytesFormat);
_data = QPixmap::fromImage(App::readImage(bytes, &fmt, false), Qt::ColorOnly);
if (!_data.isNull()) {
globalAcquiredSize += int64(_data.width()) * _data.height() * 4;
setInformation(bytes.size(), _data.width(), _data.height());
}
invalidateSizeCache();
if (amLoading()) {
_loader->deleteLater();
_loader->stop();
_loader = 0;
}
_saved = bytes;
_format = fmt;
_forgot = false;
}
void RemoteImage::automaticLoad(const HistoryItem *item) {
if (loaded()) return;
if (_loader != CancelledFileLoader && item) {
bool loadFromCloud = false;
if (item->history()->peer->isUser()) {
loadFromCloud = !(cAutoDownloadPhoto() & dbiadNoPrivate);
} else {
loadFromCloud = !(cAutoDownloadPhoto() & dbiadNoGroups);
}
if (_loader) {
if (loadFromCloud) _loader->permitLoadFromCloud();
} else {
_loader = createLoader(loadFromCloud ? LoadFromCloudOrLocal : LoadFromLocalOnly, true);
if (_loader) _loader->start();
}
}
}
void RemoteImage::automaticLoadSettingsChanged() {
if (loaded() || _loader != CancelledFileLoader) return;
_loader = 0;
}
void RemoteImage::load(bool loadFirst, bool prior) {
if (loaded()) return;
if (!_loader) {
_loader = createLoader(LoadFromCloudOrLocal, false);
}
if (amLoading()) {
_loader->start(loadFirst, prior);
}
}
void RemoteImage::loadEvenCancelled(bool loadFirst, bool prior) {
if (_loader == CancelledFileLoader) _loader = 0;
return load(loadFirst, prior);
}
RemoteImage::~RemoteImage() {
if (!_data.isNull()) {
globalAcquiredSize -= int64(_data.width()) * _data.height() * 4;
}
if (amLoading()) {
_loader->deleteLater();
_loader->stop();
_loader = 0;
}
}
bool RemoteImage::loaded() const {
doCheckload();
return (!_data.isNull() || !_saved.isNull());
}
bool RemoteImage::displayLoading() const {
return amLoading() && (!_loader->loadingLocal() || !_loader->autoLoading());
}
void RemoteImage::cancel() {
if (!amLoading()) return;
FileLoader *l = _loader;
_loader = CancelledFileLoader;
if (l) {
l->cancel();
l->deleteLater();
l->stop();
}
}
float64 RemoteImage::progress() const {
return amLoading() ? _loader->currentProgress() : (loaded() ? 1 : 0);
}
int32 RemoteImage::loadOffset() const {
return amLoading() ? _loader->currentOffset() : 0;
}
StorageImage::StorageImage(const StorageImageLocation &location, int32 size)
: _location(location)
, _size(size) {
}
StorageImage::StorageImage(const StorageImageLocation &location, QByteArray &bytes)
: _location(location)
, _size(bytes.size()) {
setData(bytes);
if (!_location.isNull()) {
Local::writeImage(storageKey(_location), StorageImageSaved(mtpToStorageType(mtpc_storage_filePartial), bytes));
@ -616,140 +771,14 @@ int32 StorageImage::height() const {
return _location.height();
}
void StorageImage::doCheckload() const {
if (!amLoading() || !_loader->done()) return;
QPixmap data = _loader->imagePixmap();
if (data.isNull()) {
_loader->deleteLater();
_loader->rpcInvalidate();
_loader = CancelledFileLoader;
return;
}
if (!_data.isNull()) {
globalAcquiredSize -= int64(_data.width()) * _data.height() * 4;
}
_format = _loader->imageFormat();
_data = data;
_saved = _loader->bytes();
const_cast<StorageImage*>(this)->_size = _saved.size();
const_cast<StorageImage*>(this)->_location.setSize(_data.width(), _data.height());
globalAcquiredSize += int64(_data.width()) * _data.height() * 4;
invalidateSizeCache();
_loader->deleteLater();
_loader->rpcInvalidate();
_loader = 0;
_forgot = false;
void StorageImage::setInformation(int32 size, int32 width, int32 height) {
_size = size;
_location.setSize(width, height);
}
void StorageImage::setData(QByteArray &bytes, const QByteArray &bytesFormat) {
QBuffer buffer(&bytes);
if (!_data.isNull()) {
globalAcquiredSize -= int64(_data.width()) * _data.height() * 4;
}
QByteArray fmt(bytesFormat);
_data = QPixmap::fromImage(App::readImage(bytes, &fmt, false), Qt::ColorOnly);
if (!_data.isNull()) {
globalAcquiredSize += int64(_data.width()) * _data.height() * 4;
_location.setSize(_data.width(), _data.height());
}
invalidateSizeCache();
if (amLoading()) {
_loader->deleteLater();
_loader->rpcInvalidate();
_loader = 0;
}
_saved = bytes;
_format = fmt;
_forgot = false;
}
void StorageImage::automaticLoad(const HistoryItem *item) {
if (loaded()) return;
if (_loader != CancelledFileLoader && item) {
bool loadFromCloud = false;
if (item->history()->peer->isUser()) {
loadFromCloud = !(cAutoDownloadPhoto() & dbiadNoPrivate);
} else {
loadFromCloud = !(cAutoDownloadPhoto() & dbiadNoGroups);
}
if (_loader) {
if (loadFromCloud) _loader->permitLoadFromCloud();
} else if (!_location.isNull()) {
_loader = new mtpFileLoader(&_location, _size, loadFromCloud ? LoadFromCloudOrLocal : LoadFromLocalOnly, true);
_loader->start();
}
}
}
void StorageImage::automaticLoadSettingsChanged() {
if (loaded() || _loader != CancelledFileLoader) return;
_loader = 0;
}
void StorageImage::load(bool loadFirst, bool prior) {
if (loaded()) return;
if (!_loader && !_location.isNull()) {
_loader = new mtpFileLoader(&_location, _size, LoadFromCloudOrLocal, false);
}
if (amLoading()) {
_loader->start(loadFirst, prior);
}
}
void StorageImage::loadEvenCancelled(bool loadFirst, bool prior) {
if (_loader == CancelledFileLoader) _loader = 0;
return load(loadFirst, prior);
}
StorageImage::~StorageImage() {
if (!_data.isNull()) {
globalAcquiredSize -= int64(_data.width()) * _data.height() * 4;
}
if (amLoading()) {
_loader->deleteLater();
_loader->rpcInvalidate();
_loader = 0;
}
}
bool StorageImage::loaded() const {
doCheckload();
return (!_data.isNull() || !_saved.isNull());
}
bool StorageImage::displayLoading() const {
return amLoading() && (!_loader->loadingLocal() || !_loader->autoLoading());
}
void StorageImage::cancel() {
if (!amLoading()) return;
mtpFileLoader *l = _loader;
_loader = CancelledFileLoader;
if (l) {
l->cancel();
l->deleteLater();
l->rpcInvalidate();
}
}
float64 StorageImage::progress() const {
return amLoading() ? _loader->currentProgress() : (loaded() ? 1 : 0);
}
int32 StorageImage::loadOffset() const {
return amLoading() ? _loader->currentOffset() : 0;
FileLoader *StorageImage::createLoader(LoadFromCloudSetting fromCloud, bool autoLoading) {
if (_location.isNull()) return 0;
return new mtpFileLoader(&_location, _size, fromCloud, autoLoading);
}
StorageImage *getImage(const StorageImageLocation &location, int32 size) {
@ -777,6 +806,28 @@ StorageImage *getImage(const StorageImageLocation &location, const QByteArray &b
return i.value();
}
WebImage::WebImage(const QString &url) : _url(url), _width(0), _height(0), _size(0) {
}
int32 WebImage::width() const {
return _width;
}
int32 WebImage::height() const {
return _height;
}
void WebImage::setInformation(int32 size, int32 width, int32 height) {
_size = size;
_width = width;
_height = height;
}
FileLoader *WebImage::createLoader(LoadFromCloudSetting fromCloud, bool autoLoading) {
return new webFileLoader(_url, QString(), fromCloud, autoLoading);
}
ReadAccessEnabler::ReadAccessEnabler(const PsFileBookmark *bookmark) : _bookmark(bookmark), _failed(_bookmark ? !_bookmark->enable() : false) {
}

View File

@ -224,14 +224,11 @@ inline StorageKey storageKey(const StorageImageLocation &location) {
return storageKey(location.dc(), location.volume(), location.local());
}
class StorageImage : public Image {
class RemoteImage : public Image {
public:
StorageImage(const StorageImageLocation &location, int32 size = 0);
StorageImage(const StorageImageLocation &location, QByteArray &bytes);
int32 width() const;
int32 height() const;
RemoteImage() : _loader(0) {
}
void automaticLoad(const HistoryItem *item); // auto load photo
void automaticLoadSettingsChanged();
@ -250,11 +247,10 @@ public:
void load(bool loadFirst = false, bool prior = true);
void loadEvenCancelled(bool loadFirst = false, bool prior = true);
virtual const StorageImageLocation &location() const {
return _location;
}
virtual void setInformation(int32 size, int32 width, int32 height) = 0;
virtual FileLoader *createLoader(LoadFromCloudSetting fromCloud, bool autoLoading) = 0;
~StorageImage();
~RemoteImage();
protected:
void checkload() const {
@ -262,10 +258,7 @@ protected:
}
private:
StorageImageLocation _location;
int32 _size;
mutable mtpFileLoader *_loader;
mutable FileLoader *_loader;
bool amLoading() const {
return _loader && _loader != CancelledFileLoader;
}
@ -273,10 +266,51 @@ private:
};
class StorageImage : public RemoteImage {
public:
StorageImage(const StorageImageLocation &location, int32 size = 0);
StorageImage(const StorageImageLocation &location, QByteArray &bytes);
int32 width() const;
int32 height() const;
virtual void setInformation(int32 size, int32 width, int32 height);
virtual FileLoader *createLoader(LoadFromCloudSetting fromCloud, bool autoLoading);
virtual const StorageImageLocation &location() const {
return _location;
}
private:
StorageImageLocation _location;
int32 _size;
};
StorageImage *getImage(const StorageImageLocation &location, int32 size = 0);
StorageImage *getImage(const StorageImageLocation &location, const QByteArray &bytes);
Image *getImage(int32 width, int32 height, const MTPFileLocation &location);
class WebImage : public RemoteImage {
public:
WebImage(const QString &url);
int32 width() const;
int32 height() const;
virtual void setInformation(int32 size, int32 width, int32 height);
virtual FileLoader *createLoader(LoadFromCloudSetting fromCloud, bool autoLoading);
private:
QString _url;
int32 _size, _width, _height;
};
WebImage *getImage(const QUrl &url);
class ImagePtr : public ManagedPtr<Image> {
public:
ImagePtr();

View File

@ -4583,7 +4583,7 @@ void HistoryGif::draw(Painter &p, const HistoryItem *parent, const QRect &r, boo
QRect rthumb(rtlrect(skipx, skipy, width, height, _width));
if (animating) {
p.drawPixmap(rthumb.topLeft(), _gif->current(_thumbw, _thumbh, width, height, (Ui::isLayerShown() || Ui::isMediaViewShown() || Ui::isContextItemBeingChosen()) ? 0 : ms));
p.drawPixmap(rthumb.topLeft(), _gif->current(_thumbw, _thumbh, width, height, (Ui::isLayerShown() || Ui::isMediaViewShown() || Ui::isInlineItemBeingChosen()) ? 0 : ms));
} else {
p.drawPixmap(rthumb.topLeft(), _data->thumb->pixBlurredSingle(_thumbw, _thumbh, width, height));
}

View File

@ -2630,8 +2630,8 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
, _toHistoryEnd(this, st::historyToEnd)
, _collapseComments(this)
, _attachMention(this)
, _contextBot(0)
, _contextBotResolveRequestId(0)
, _inlineBot(0)
, _inlineBotResolveRequestId(0)
, _reportSpamPanel(this)
, _send(this, lang(lng_send_button), st::btnSend)
, _unblock(this, lang(lng_unblock_button), st::btnUnblock)
@ -4949,23 +4949,23 @@ bool HistoryWidget::hasBroadcastToggle() const {
return _peer && _peer->isChannel() && !_peer->isMegagroup() && _peer->asChannel()->canPublish() && !_peer->asChannel()->isBroadcast();
}
void HistoryWidget::contextBotResolveDone(const MTPcontacts_ResolvedPeer &result) {
_contextBot = 0;
void HistoryWidget::inlineBotResolveDone(const MTPcontacts_ResolvedPeer &result) {
_inlineBot = 0;
if (result.type() == mtpc_contacts_resolvedPeer) {
const MTPDcontacts_resolvedPeer &d(result.c_contacts_resolvedPeer());
App::feedUsers(d.vusers);
App::feedChats(d.vchats);
PeerId peerId = peerFromMTP(d.vpeer);
if (peerId && peerIsUser(peerId)) {
_contextBot = App::user(peerId);
_inlineBot = App::user(peerId);
}
}
onCheckMentionDropdown();
}
bool HistoryWidget::contextBotResolveFail(const RPCError &error) {
bool HistoryWidget::inlineBotResolveFail(const RPCError &error) {
if (mtpIsFlood(error)) return false;
_contextBot = 0;
_inlineBot = 0;
onCheckMentionDropdown();
return true;
}
@ -5311,28 +5311,29 @@ void HistoryWidget::onFieldFocused() {
void HistoryWidget::onCheckMentionDropdown() {
if (!_history || _a_show.animating()) return;
QString start, contextBotUsername(_contextBotUsername);
_field.getMentionHashtagBotCommandStart(start, _contextBot, _contextBotUsername);
if (contextBotUsername != _contextBotUsername) {
if (_contextBotResolveRequestId) {
MTP::cancel(_contextBotResolveRequestId);
_contextBotResolveRequestId = 0;
QString start, inlineBotUsername(_inlineBotUsername);
_field.getMentionHashtagBotCommandStart(start, _inlineBot, _inlineBotUsername);
if (inlineBotUsername != _inlineBotUsername) {
if (_inlineBotResolveRequestId) {
MTP::cancel(_inlineBotResolveRequestId);
_inlineBotResolveRequestId = 0;
}
if (_contextBot == ContextBotLookingUpData) {
_contextBotResolveRequestId = MTP::send(MTPcontacts_ResolveUsername(MTP_string(_contextBotUsername)), rpcDone(&HistoryWidget::contextBotResolveDone), rpcFail(&HistoryWidget::contextBotResolveFail));
if (_inlineBot == InlineBotLookingUpData) {
LOG(("Inline bot unknown! resolving @%1").arg(_inlineBotUsername));
_inlineBotResolveRequestId = MTP::send(MTPcontacts_ResolveUsername(MTP_string(_inlineBotUsername)), rpcDone(&HistoryWidget::inlineBotResolveDone), rpcFail(&HistoryWidget::inlineBotResolveFail));
return;
}
} else if (_contextBot == ContextBotLookingUpData) {
} else if (_inlineBot == InlineBotLookingUpData) {
return;
}
if (_contextBot) {
_emojiPan.queryContextBot(_contextBot, start);
if (_inlineBot) {
_emojiPan.queryInlineBot(_inlineBot, start);
if (!_attachMention.isHidden()) {
_attachMention.hideStart();
}
} else {
_emojiPan.contextBotChanged();
_emojiPan.inlineBotChanged();
if (!start.isEmpty()) {
if (start.at(0) == '#' && cRecentWriteHashtags().isEmpty() && cRecentSearchHashtags().isEmpty()) Local::readRecentHashtags();
if (start.at(0) == '@' && _peer->isUser()) return;
@ -5770,16 +5771,16 @@ void HistoryWidget::ui_repaintHistoryItem(const HistoryItem *item) {
}
}
void HistoryWidget::ui_repaintContextItem(const LayoutContextItem *layout) {
_emojiPan.ui_repaintContextItem(layout);
void HistoryWidget::ui_repaintInlineItem(const LayoutInlineItem *layout) {
_emojiPan.ui_repaintInlineItem(layout);
}
bool HistoryWidget::ui_isContextItemVisible(const LayoutContextItem *layout) {
return _emojiPan.ui_isContextItemVisible(layout);
bool HistoryWidget::ui_isInlineItemVisible(const LayoutInlineItem *layout) {
return _emojiPan.ui_isInlineItemVisible(layout);
}
bool HistoryWidget::ui_isContextItemBeingChosen() {
return _emojiPan.ui_isContextItemBeingChosen();
bool HistoryWidget::ui_isInlineItemBeingChosen() {
return _emojiPan.ui_isInlineItemBeingChosen();
}
void HistoryWidget::notify_historyItemLayoutChanged(const HistoryItem *item) {

View File

@ -559,9 +559,9 @@ public:
bool isItemVisible(HistoryItem *item);
void ui_repaintHistoryItem(const HistoryItem *item);
void ui_repaintContextItem(const LayoutContextItem *gif);
bool ui_isContextItemVisible(const LayoutContextItem *layout);
bool ui_isContextItemBeingChosen();
void ui_repaintInlineItem(const LayoutInlineItem *gif);
bool ui_isInlineItemVisible(const LayoutInlineItem *layout);
bool ui_isInlineItemBeingChosen();
void notify_historyItemLayoutChanged(const HistoryItem *item);
void notify_botCommandsChanged(UserData *user);
@ -760,11 +760,11 @@ private:
CollapseButton _collapseComments;
MentionsDropdown _attachMention;
UserData *_contextBot;
QString _contextBotUsername;
mtpRequestId _contextBotResolveRequestId;
void contextBotResolveDone(const MTPcontacts_ResolvedPeer &result);
bool contextBotResolveFail(const RPCError &error);
UserData *_inlineBot;
QString _inlineBotUsername;
mtpRequestId _inlineBotResolveRequestId;
void inlineBotResolveDone(const MTPcontacts_ResolvedPeer &result);
bool inlineBotResolveFail(const RPCError &error);
bool isBotStart() const;
bool isBlocked() const;

View File

@ -1281,34 +1281,34 @@ LayoutOverviewLink::Link::Link(const QString &url, const QString &text)
, lnk(linkFromUrl(url)) {
}
LayoutContextItem::LayoutContextItem(ContextResult *result, DocumentData *doc, PhotoData *photo)
LayoutInlineItem::LayoutInlineItem(InlineResult *result, DocumentData *doc, PhotoData *photo)
: _result(result)
, _doc(doc)
, _photo(photo)
, _position(0) {
}
void LayoutContextItem::setPosition(int32 position) {
void LayoutInlineItem::setPosition(int32 position) {
_position = position;
}
int32 LayoutContextItem::position() const {
int32 LayoutInlineItem::position() const {
return _position;
}
ContextResult *LayoutContextItem::result() const {
InlineResult *LayoutInlineItem::result() const {
return _result;
}
DocumentData *LayoutContextItem::document() const {
DocumentData *LayoutInlineItem::document() const {
return _doc;
}
PhotoData *LayoutContextItem::photo() const {
PhotoData *LayoutInlineItem::photo() const {
return _photo;
}
void LayoutContextItem::preload() {
void LayoutInlineItem::preload() {
if (_result) {
if (_result->photo) {
_result->photo->thumb->load();
@ -1324,15 +1324,15 @@ void LayoutContextItem::preload() {
}
}
LayoutContextGif::LayoutContextGif(ContextResult *result, DocumentData *doc, bool saved) : LayoutContextItem(result, doc, 0)
LayoutInlineGif::LayoutInlineGif(InlineResult *result, DocumentData *doc, bool saved) : LayoutInlineItem(result, doc, 0)
, _state(0)
, _gif(0)
, _send(new SendContextItemLink())
, _send(new SendInlineItemLink())
, _delete((doc && saved) ? new DeleteSavedGifLink(doc) : 0)
, _animation(0) {
}
void LayoutContextGif::initDimensions() {
void LayoutInlineGif::initDimensions() {
int32 w = content_width(), h = content_height();
if (w <= 0 || h <= 0) {
_maxw = 0;
@ -1343,8 +1343,8 @@ void LayoutContextGif::initDimensions() {
_minh = st::inlineMediaHeight + st::inlineResultsSkip;
}
void LayoutContextGif::setPosition(int32 position) {
LayoutContextItem::setPosition(position);
void LayoutInlineGif::setPosition(int32 position) {
LayoutInlineItem::setPosition(position);
if (_position < 0) {
if (gif()) delete _gif;
_gif = 0;
@ -1364,13 +1364,13 @@ void DeleteSavedGifLink::onClick(Qt::MouseButton button) const {
if (App::main()) emit App::main()->savedGifsUpdated();
}
void LayoutContextGif::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const {
void LayoutInlineGif::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const {
content_automaticLoad();
bool loaded = content_loaded(), loading = content_loading(), displayLoading = content_displayLoading();
if (loaded && !gif() && _gif != BadClipReader) {
LayoutContextGif *that = const_cast<LayoutContextGif*>(this);
that->_gif = new ClipReader(content_location(), content_data(), func(that, &LayoutContextGif::clipCallback));
LayoutInlineGif *that = const_cast<LayoutInlineGif*>(this);
that->_gif = new ClipReader(content_location(), content_data(), func(that, &LayoutInlineGif::clipCallback));
if (gif()) _gif->setAutoplay();
}
@ -1388,8 +1388,8 @@ void LayoutContextGif::paint(Painter &p, const QRect &clip, uint32 selection, co
QRect r(0, 0, _width, height);
if (animating) {
if (!_thumb.isNull()) const_cast<LayoutContextGif*>(this)->_thumb = QPixmap();
const ContextPaintContext *ctx = context->toContextPaintContext();
if (!_thumb.isNull()) const_cast<LayoutInlineGif*>(this)->_thumb = QPixmap();
const InlinePaintContext *ctx = context->toInlinePaintContext();
t_assert(ctx);
p.drawPixmap(r.topLeft(), _gif->current(frame.width(), frame.height(), _width, height, ctx->paused ? 0 : context->ms));
} else {
@ -1426,7 +1426,7 @@ void LayoutContextGif::paint(Painter &p, const QRect &clip, uint32 selection, co
}
}
if (_state & StateOver) {
if (_delete && (_state & StateOver)) {
float64 deleteOver = _a_deleteOver.current(context->ms, (_state & StateDeleteOver) ? 1 : 0);
QPoint deletePos = QPoint(_width - st::stickerPanDelete.pxWidth(), 0);
p.setOpacity(deleteOver + (1 - deleteOver) * st::stickerPanDeleteOpacity);
@ -1435,7 +1435,7 @@ void LayoutContextGif::paint(Painter &p, const QRect &clip, uint32 selection, co
}
}
void LayoutContextGif::getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const {
void LayoutInlineGif::getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const {
if (x >= 0 && x < _width && y >= 0 && y < st::inlineMediaHeight) {
if (_delete && (rtl() ? _width - x : x) >= _width - st::stickerPanDelete.pxWidth() && y < st::stickerPanDelete.pxHeight()) {
link = _delete;
@ -1445,10 +1445,10 @@ void LayoutContextGif::getState(TextLinkPtr &link, HistoryCursorState &cursor, i
}
}
void LayoutContextGif::linkOver(const TextLinkPtr &link) {
void LayoutInlineGif::linkOver(const TextLinkPtr &link) {
if (_delete && link == _delete) {
if (!(_state & StateDeleteOver)) {
EnsureAnimation(_a_deleteOver, 0, func(this, &LayoutContextGif::update));
EnsureAnimation(_a_deleteOver, 0, func(this, &LayoutInlineGif::update));
_state |= StateDeleteOver;
_a_deleteOver.start(1, st::stickersRowDuration);
}
@ -1457,7 +1457,7 @@ void LayoutContextGif::linkOver(const TextLinkPtr &link) {
if (!content_loaded()) {
ensureAnimation();
if (!(_state & StateOver)) {
EnsureAnimation(_animation->_a_over, 0, func(this, &LayoutContextGif::update));
EnsureAnimation(_animation->_a_over, 0, func(this, &LayoutInlineGif::update));
_animation->_a_over.start(1, st::stickersRowDuration);
}
}
@ -1465,10 +1465,10 @@ void LayoutContextGif::linkOver(const TextLinkPtr &link) {
}
}
void LayoutContextGif::linkOut(const TextLinkPtr &link) {
void LayoutInlineGif::linkOut(const TextLinkPtr &link) {
if (_delete && link == _delete) {
if (_state & StateDeleteOver) {
EnsureAnimation(_a_deleteOver, 1, func(this, &LayoutContextGif::update));
EnsureAnimation(_a_deleteOver, 1, func(this, &LayoutInlineGif::update));
_state &= ~StateDeleteOver;
_a_deleteOver.start(0, st::stickersRowDuration);
}
@ -1477,7 +1477,7 @@ void LayoutContextGif::linkOut(const TextLinkPtr &link) {
if (!content_loaded()) {
ensureAnimation();
if (_state & StateOver) {
EnsureAnimation(_animation->_a_over, 1, func(this, &LayoutContextGif::update));
EnsureAnimation(_animation->_a_over, 1, func(this, &LayoutInlineGif::update));
_animation->_a_over.start(0, st::stickersRowDuration);
}
}
@ -1485,7 +1485,7 @@ void LayoutContextGif::linkOut(const TextLinkPtr &link) {
}
}
QSize LayoutContextGif::countFrameSize() const {
QSize LayoutInlineGif::countFrameSize() const {
bool animating = (gif() && _gif->ready());
int32 framew = animating ? _gif->width() : content_width(), frameh = animating ? _gif->height() : content_height(), height = st::inlineMediaHeight;
if (framew * height > frameh * _width) {
@ -1512,15 +1512,15 @@ QSize LayoutContextGif::countFrameSize() const {
return QSize(framew, frameh);
}
LayoutContextGif::~LayoutContextGif() {
LayoutInlineGif::~LayoutInlineGif() {
deleteAndMark(_animation);
}
void LayoutContextGif::prepareThumb(int32 width, int32 height, const QSize &frame) const {
void LayoutInlineGif::prepareThumb(int32 width, int32 height, const QSize &frame) const {
if (_doc && !_doc->thumb->isNull()) {
if (_doc->thumb->loaded()) {
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
const_cast<LayoutContextGif*>(this)->_thumb = _doc->thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), true, false, false, width, height);
const_cast<LayoutInlineGif*>(this)->_thumb = _doc->thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), true, false, false, width, height);
}
} else {
_doc->thumb->load();
@ -1528,7 +1528,7 @@ void LayoutContextGif::prepareThumb(int32 width, int32 height, const QSize &fram
} else if (_result && !_result->thumb_url.isEmpty()) {
if (_result->thumb->loaded()) {
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
const_cast<LayoutContextGif*>(this)->_thumb = _result->thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), true, false, false, width, height);
const_cast<LayoutInlineGif*>(this)->_thumb = _result->thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), true, false, false, width, height);
}
} else {
_result->thumb->load();
@ -1536,20 +1536,20 @@ void LayoutContextGif::prepareThumb(int32 width, int32 height, const QSize &fram
}
}
void LayoutContextGif::ensureAnimation() const {
void LayoutInlineGif::ensureAnimation() const {
if (!_animation) {
_animation = new AnimationData(animation(const_cast<LayoutContextGif*>(this), &LayoutContextGif::step_radial));
_animation = new AnimationData(animation(const_cast<LayoutInlineGif*>(this), &LayoutInlineGif::step_radial));
}
}
bool LayoutContextGif::isRadialAnimation(uint64 ms) const {
bool LayoutInlineGif::isRadialAnimation(uint64 ms) const {
if (!_animation || !_animation->radial.animating()) return false;
_animation->radial.step(ms);
return _animation && _animation->radial.animating();
}
void LayoutContextGif::step_radial(uint64 ms, bool timer) {
void LayoutInlineGif::step_radial(uint64 ms, bool timer) {
if (timer) {
update();
} else {
@ -1561,7 +1561,7 @@ void LayoutContextGif::step_radial(uint64 ms, bool timer) {
}
}
void LayoutContextGif::clipCallback(ClipReaderNotification notification) {
void LayoutInlineGif::clipCallback(ClipReaderNotification notification) {
switch (notification) {
case ClipReaderReinit: {
if (gif()) {
@ -1573,7 +1573,7 @@ void LayoutContextGif::clipCallback(ClipReaderNotification notification) {
int32 height = st::inlineMediaHeight;
QSize frame = countFrameSize();
_gif->start(frame.width(), frame.height(), _width, height, false);
} else if (_gif->paused() && !Ui::isContextItemVisible(this)) {
} else if (_gif->paused() && !Ui::isInlineItemVisible(this)) {
delete _gif;
_gif = 0;
content_forget();
@ -1591,19 +1591,20 @@ void LayoutContextGif::clipCallback(ClipReaderNotification notification) {
}
}
void LayoutContextGif::update() {
void LayoutInlineGif::update() {
if (_position >= 0) {
Ui::repaintContextItem(this);
Ui::repaintInlineItem(this);
}
}
int32 LayoutContextGif::content_width() const {
if (_doc) {
if (_doc->dimensions.width() > 0) {
return _doc->dimensions.width();
int32 LayoutInlineGif::content_width() const {
DocumentData *doc = _doc ? _doc : (_result ? _result->doc : 0);
if (doc) {
if (doc->dimensions.width() > 0) {
return doc->dimensions.width();
}
if (!_doc->thumb->isNull()) {
return _doc->thumb->width();
if (!doc->thumb->isNull()) {
return doc->thumb->width();
}
} else if (_result) {
return _result->width;
@ -1611,13 +1612,14 @@ int32 LayoutContextGif::content_width() const {
return 0;
}
int32 LayoutContextGif::content_height() const {
if (_doc) {
if (_doc->dimensions.height() > 0) {
return _doc->dimensions.height();
int32 LayoutInlineGif::content_height() const {
DocumentData *doc = _doc ? _doc : (_result ? _result->doc : 0);
if (doc) {
if (doc->dimensions.height() > 0) {
return doc->dimensions.height();
}
if (!_doc->thumb->isNull()) {
return _doc->thumb->height();
if (!doc->thumb->isNull()) {
return doc->thumb->height();
}
} else if (_result) {
return _result->height;
@ -1625,42 +1627,50 @@ int32 LayoutContextGif::content_height() const {
return 0;
}
bool LayoutContextGif::content_loading() const {
return _doc ? _doc->loading() : _result->loading();
bool LayoutInlineGif::content_loading() const {
DocumentData *doc = _doc ? _doc : (_result ? _result->doc : 0);
return doc ? doc->loading() : _result->loading();
}
bool LayoutContextGif::content_displayLoading() const {
return _doc ? _doc->displayLoading() : _result->displayLoading();
bool LayoutInlineGif::content_displayLoading() const {
DocumentData *doc = _doc ? _doc : (_result ? _result->doc : 0);
return doc ? doc->displayLoading() : _result->displayLoading();
}
bool LayoutContextGif::content_loaded() const {
return _doc ? _doc->loaded() : _result->loaded();
bool LayoutInlineGif::content_loaded() const {
DocumentData *doc = _doc ? _doc : (_result ? _result->doc : 0);
return doc ? doc->loaded() : _result->loaded();
}
float64 LayoutContextGif::content_progress() const {
return _doc ? _doc->progress() : _result->progress();
float64 LayoutInlineGif::content_progress() const {
DocumentData *doc = _doc ? _doc : (_result ? _result->doc : 0);
return doc ? doc->progress() : _result->progress();
}
void LayoutContextGif::content_automaticLoad() const {
if (_doc) {
_doc->automaticLoad(0);
void LayoutInlineGif::content_automaticLoad() const {
DocumentData *doc = _doc ? _doc : (_result ? _result->doc : 0);
if (doc) {
doc->automaticLoad(0);
} else {
_result->automaticLoadGif();
}
}
void LayoutContextGif::content_forget() {
if (_doc) {
_doc->forget();
void LayoutInlineGif::content_forget() {
DocumentData *doc = _doc ? _doc : (_result ? _result->doc : 0);
if (doc) {
doc->forget();
} else {
_result->forget();
}
}
FileLocation LayoutContextGif::content_location() const {
return _doc ? _doc->location() : FileLocation();
FileLocation LayoutInlineGif::content_location() const {
DocumentData *doc = _doc ? _doc : (_result ? _result->doc : 0);
return doc ? doc->location() : FileLocation();
}
QByteArray LayoutContextGif::content_data() const {
return _doc ? _doc->data() : _result->data();
QByteArray LayoutInlineGif::content_data() const {
DocumentData *doc = _doc ? _doc : (_result ? _result->doc : 0);
return doc ? doc->data() : _result->data();
}

View File

@ -78,7 +78,7 @@ style::color documentColor(int32 colorIndex);
style::sprite documentCorner(int32 colorIndex);
RoundCorners documentCorners(int32 colorIndex);
class ContextPaintContext;
class InlinePaintContext;
class PaintContext {
public:
@ -86,7 +86,7 @@ public:
}
uint64 ms;
bool selecting;
virtual const ContextPaintContext *toContextPaintContext() const {
virtual const InlinePaintContext *toInlinePaintContext() const {
return 0;
}
@ -475,22 +475,20 @@ private:
};
class ContextPaintContext : public PaintContext {
class InlinePaintContext : public PaintContext {
public:
ContextPaintContext(uint64 ms, bool selecting, bool paused) : PaintContext(ms, selecting), paused(paused) {
InlinePaintContext(uint64 ms, bool selecting, bool paused) : PaintContext(ms, selecting), paused(paused) {
}
virtual const ContextPaintContext *toContextPaintContext() const {
virtual const InlinePaintContext *toInlinePaintContext() const {
return this;
}
bool paused;
};
struct ContextResult;
class LayoutContextItem : public LayoutItem {
class LayoutInlineItem : public LayoutItem {
public:
LayoutContextItem(ContextResult *result, DocumentData *doc, PhotoData *photo);
LayoutInlineItem(InlineResult *result, DocumentData *doc, PhotoData *photo);
virtual void setPosition(int32 position);
int32 position() const;
@ -499,13 +497,13 @@ public:
return true;
}
ContextResult *result() const;
InlineResult *result() const;
DocumentData *document() const;
PhotoData *photo() const;
void preload();
protected:
ContextResult *_result;
InlineResult *_result;
DocumentData *_doc;
PhotoData *_photo;
@ -513,8 +511,8 @@ protected:
};
class SendContextItemLink : public ITextLink {
TEXT_LINK_CLASS(SendContextItemLink)
class SendInlineItemLink : public ITextLink {
TEXT_LINK_CLASS(SendInlineItemLink)
public:
virtual void onClick(Qt::MouseButton) const {
@ -535,9 +533,9 @@ private:
};
class LayoutContextGif : public LayoutContextItem {
class LayoutInlineGif : public LayoutInlineItem {
public:
LayoutContextGif(ContextResult *result, DocumentData *doc, bool saved);
LayoutInlineGif(InlineResult *result, DocumentData *doc, bool saved);
virtual void setPosition(int32 position);
virtual void initDimensions();
@ -551,7 +549,7 @@ public:
virtual void linkOver(const TextLinkPtr &lnk);
virtual void linkOut(const TextLinkPtr &lnk);
~LayoutContextGif();
~LayoutInlineGif();
private:
QSize countFrameSize() const;

View File

@ -798,16 +798,16 @@ void MainWidget::ui_repaintHistoryItem(const HistoryItem *item) {
if (overview) overview->ui_repaintHistoryItem(item);
}
void MainWidget::ui_repaintContextItem(const LayoutContextItem *layout) {
history.ui_repaintContextItem(layout);
void MainWidget::ui_repaintInlineItem(const LayoutInlineItem *layout) {
history.ui_repaintInlineItem(layout);
}
bool MainWidget::ui_isContextItemVisible(const LayoutContextItem *layout) {
return history.ui_isContextItemVisible(layout);
bool MainWidget::ui_isInlineItemVisible(const LayoutInlineItem *layout) {
return history.ui_isInlineItemVisible(layout);
}
bool MainWidget::ui_isContextItemBeingChosen() {
return history.ui_isContextItemBeingChosen();
bool MainWidget::ui_isInlineItemBeingChosen() {
return history.ui_isInlineItemBeingChosen();
}
void MainWidget::notify_historyItemLayoutChanged(const HistoryItem *item) {
@ -1638,8 +1638,11 @@ void MainWidget::messagesAffected(PeerData *peer, const MTPmessages_AffectedMess
}
}
void MainWidget::videoLoadProgress(mtpFileLoader *loader) {
VideoData *video = App::video(loader->objId());
void MainWidget::videoLoadProgress(FileLoader *loader) {
mtpFileLoader *l = loader ? loader->mtpLoader() : 0;
if (!l) return;
VideoData *video = App::video(l->objId());
if (video->loaded()) {
video->performActionOnLoad();
}
@ -1679,9 +1682,12 @@ void MainWidget::ui_showPeerHistoryAsync(quint64 peerId, qint32 showAtMsgId) {
Ui::showPeerHistory(peerId, showAtMsgId);
}
void MainWidget::videoLoadFailed(mtpFileLoader *loader, bool started) {
loadFailed(loader, started, SLOT(videoLoadRetry()));
VideoData *video = App::video(loader->objId());
void MainWidget::videoLoadFailed(FileLoader *loader, bool started) {
mtpFileLoader *l = loader ? loader->mtpLoader() : 0;
if (!l) return;
loadFailed(l, started, SLOT(videoLoadRetry()));
VideoData *video = App::video(l->objId());
if (video) {
if (video->loading()) video->cancel();
video->status = FileDownloadFailed;
@ -1694,8 +1700,11 @@ void MainWidget::videoLoadRetry() {
if (video) video->save(failedFileName);
}
void MainWidget::audioLoadProgress(mtpFileLoader *loader) {
AudioData *audio = App::audio(loader->objId());
void MainWidget::audioLoadProgress(FileLoader *loader) {
mtpFileLoader *l = loader ? loader->mtpLoader() : 0;
if (!l) return;
AudioData *audio = App::audio(l->objId());
if (audio->loaded()) {
audio->performActionOnLoad();
}
@ -1813,9 +1822,12 @@ void MainWidget::hidePlayer() {
}
}
void MainWidget::audioLoadFailed(mtpFileLoader *loader, bool started) {
loadFailed(loader, started, SLOT(audioLoadRetry()));
AudioData *audio = App::audio(loader->objId());
void MainWidget::audioLoadFailed(FileLoader *loader, bool started) {
mtpFileLoader *l = loader ? loader->mtpLoader() : 0;
if (!l) return;
loadFailed(l, started, SLOT(audioLoadRetry()));
AudioData *audio = App::audio(l->objId());
if (audio) {
if (audio->loading()) audio->cancel();
audio->status = FileDownloadFailed;
@ -1828,8 +1840,11 @@ void MainWidget::audioLoadRetry() {
if (audio) audio->save(failedFileName);
}
void MainWidget::documentLoadProgress(mtpFileLoader *loader) {
DocumentData *document = App::document(loader->objId());
void MainWidget::documentLoadProgress(FileLoader *loader) {
mtpFileLoader *l = loader ? loader->mtpLoader() : 0;
if (!l) return;
DocumentData *document = App::document(l->objId());
if (document->loaded()) {
document->performActionOnLoad();
}
@ -1855,9 +1870,12 @@ void MainWidget::documentLoadProgress(mtpFileLoader *loader) {
}
}
void MainWidget::documentLoadFailed(mtpFileLoader *loader, bool started) {
loadFailed(loader, started, SLOT(documentLoadRetry()));
DocumentData *document = App::document(loader->objId());
void MainWidget::documentLoadFailed(FileLoader *loader, bool started) {
mtpFileLoader *l = loader ? loader->mtpLoader() : 0;
if (!l) return;
loadFailed(l, started, SLOT(documentLoadRetry()));
DocumentData *document = App::document(l->objId());
if (document) {
if (document->loading()) document->cancel();
document->status = FileDownloadFailed;

View File

@ -410,9 +410,9 @@ public:
void ui_showStickerPreview(DocumentData *sticker);
void ui_hideStickerPreview();
void ui_repaintHistoryItem(const HistoryItem *item);
void ui_repaintContextItem(const LayoutContextItem *layout);
bool ui_isContextItemVisible(const LayoutContextItem *layout);
bool ui_isContextItemBeingChosen();
void ui_repaintInlineItem(const LayoutInlineItem *layout);
bool ui_isInlineItemVisible(const LayoutInlineItem *layout);
bool ui_isInlineItemBeingChosen();
void ui_showPeerHistory(quint64 peer, qint32 msgId, bool back);
void notify_botCommandsChanged(UserData *bot);
@ -439,15 +439,15 @@ public slots:
void webPagesUpdate();
void videoLoadProgress(mtpFileLoader *loader);
void videoLoadFailed(mtpFileLoader *loader, bool started);
void videoLoadProgress(FileLoader *loader);
void videoLoadFailed(FileLoader *loader, bool started);
void videoLoadRetry();
void audioLoadProgress(mtpFileLoader *loader);
void audioLoadFailed(mtpFileLoader *loader, bool started);
void audioLoadProgress(FileLoader *loader);
void audioLoadFailed(FileLoader *loader, bool started);
void audioLoadRetry();
void audioPlayProgress(const AudioMsgId &audioId);
void documentLoadProgress(mtpFileLoader *loader);
void documentLoadFailed(mtpFileLoader *loader, bool started);
void documentLoadProgress(FileLoader *loader);
void documentLoadFailed(FileLoader *loader, bool started);
void documentLoadRetry();
void documentPlayProgress(const SongMsgId &songId);
void hidePlayer();

File diff suppressed because it is too large Load Diff

View File

@ -117,15 +117,16 @@ enum LoadToCacheSetting {
LoadToCacheAsWell,
};
struct mtpFileLoaderQueue;
class StorageImageLocation;
class mtpFileLoader : public QObject, public RPCSender {
class mtpFileLoader;
class webFileLoader;
struct FileLoaderQueue;
class FileLoader : public QObject {
Q_OBJECT
public:
mtpFileLoader(const StorageImageLocation *location, int32 size, LoadFromCloudSetting fromCloud, bool autoLoading);
mtpFileLoader(int32 dc, const uint64 &id, const uint64 &access, LocationType type, const QString &toFile, int32 size, LoadToCacheSetting toCache, LoadFromCloudSetting fromCloud, bool autoLoading);
FileLoader(const QString &toFile, int32 size, LocationType locationType, LoadFromCloudSetting fromCloud, bool autoLoading);
bool done() const {
return _complete;
}
@ -141,7 +142,7 @@ public:
return _fname;
}
float64 currentProgress() const;
int32 currentOffset(bool includeSkipped = false) const;
virtual int32 currentOffset(bool includeSkipped = false) const = 0;
int32 fullSize() const;
bool setFileName(const QString &filename); // set filename for loaders to cache
@ -167,50 +168,48 @@ public:
return _autoLoading;
}
uint64 objId() const;
~mtpFileLoader();
virtual mtpFileLoader *mtpLoader() {
return 0;
}
virtual const mtpFileLoader *mtpLoader() const {
return 0;
}
virtual webFileLoader *webLoader() {
return 0;
}
virtual const webFileLoader *webLoader() const {
return 0;
}
virtual void stop() {
}
virtual ~FileLoader();
void localLoaded(const StorageImageSaved &result, const QByteArray &imageFormat = QByteArray(), const QPixmap &imagePixmap = QPixmap());
mtpFileLoader *prev, *next;
int32 priority;
signals:
void progress(mtpFileLoader *loader);
void failed(mtpFileLoader *loader, bool started);
void progress(FileLoader *loader);
void failed(FileLoader *loader, bool started);
private:
protected:
FileLoader *_prev, *_next;
int32 _priority;
FileLoaderQueue *_queue;
mtpFileLoaderQueue *queue;
bool _paused, _autoLoading, _inQueue, _complete;
mutable LocalLoadStatus _localStatus;
bool tryLoadLocal();
void cancelRequests();
typedef QMap<mtpRequestId, int32> Requests;
Requests _requests;
int32 _skippedBytes;
int32 _nextRequestOffset;
bool _lastComplete;
virtual bool tryLoadLocal() = 0;
virtual void cancelRequests() = 0;
void startLoading(bool loadFirst, bool prior);
void removeFromQueue();
void cancel(bool failed);
void loadNext();
void cancel(bool failed);
bool loadPart();
void partLoaded(int32 offset, const MTPupload_File &result, mtpRequestId req);
bool partFailed(const RPCError &error);
virtual bool loadPart() = 0;
int32 _dc;
LocationType _locationType;
const StorageImageLocation *_location;
uint64 _id; // for other locations
uint64 _access;
QFile _file;
QString _fname;
bool _fileIsOpen;
@ -222,6 +221,7 @@ private:
int32 _size;
mtpTypeId _type;
LocationType _locationType;
TaskId _localTaskId;
mutable QByteArray _imageFormat;
@ -230,4 +230,176 @@ private:
};
static mtpFileLoader * const CancelledFileLoader = SharedMemoryLocation<mtpFileLoader, 0>();
class StorageImageLocation;
class mtpFileLoader : public FileLoader, public RPCSender {
Q_OBJECT
public:
mtpFileLoader(const StorageImageLocation *location, int32 size, LoadFromCloudSetting fromCloud, bool autoLoading);
mtpFileLoader(int32 dc, const uint64 &id, const uint64 &access, LocationType type, const QString &toFile, int32 size, LoadToCacheSetting toCache, LoadFromCloudSetting fromCloud, bool autoLoading);
virtual int32 currentOffset(bool includeSkipped = false) const;
uint64 objId() const {
return _id;
}
virtual mtpFileLoader *mtpLoader() {
return this;
}
virtual const mtpFileLoader *mtpLoader() const {
return this;
}
virtual void stop() {
rpcInvalidate();
}
~mtpFileLoader();
protected:
virtual bool tryLoadLocal();
virtual void cancelRequests();
typedef QMap<mtpRequestId, int32> Requests;
Requests _requests;
virtual bool loadPart();
void partLoaded(int32 offset, const MTPupload_File &result, mtpRequestId req);
bool partFailed(const RPCError &error);
bool _lastComplete;
int32 _skippedBytes;
int32 _nextRequestOffset;
int32 _dc;
const StorageImageLocation *_location;
uint64 _id; // for other locations
uint64 _access;
};
class webFileLoaderPrivate;
class webFileLoader : public FileLoader {
Q_OBJECT
public:
webFileLoader(const QString &url, const QString &to, LoadFromCloudSetting fromCloud, bool autoLoading);
virtual int32 currentOffset(bool includeSkipped = false) const;
virtual webFileLoader *webLoader() {
return this;
}
virtual const webFileLoader *webLoader() const {
return this;
}
void onProgress(qint64 already, qint64 size);
void onFinished(const QByteArray &data);
void onError();
virtual void stop() {
cancelRequests();
}
~webFileLoader();
protected:
virtual void cancelRequests();
virtual bool tryLoadLocal();
virtual bool loadPart();
QString _url;
bool _requestSent;
int32 _already;
friend class WebLoadManager;
webFileLoaderPrivate *_private;
};
enum WebReplyProcessResult {
WebReplyProcessError,
WebReplyProcessProgress,
WebReplyProcessFinished,
};
class WebLoadManager : public QObject {
Q_OBJECT
public:
WebLoadManager(QThread *thread);
void setProxySettings(const QNetworkProxy &proxy);
void append(webFileLoader *loader, const QString &url);
void stop(webFileLoader *reader);
bool carries(webFileLoader *reader) const;
~WebLoadManager();
signals:
void processDelayed();
void proxyApplyDelayed();
void progress(webFileLoader *loader, qint64 already, qint64 size);
void finished(webFileLoader *loader, QByteArray data);
void error(webFileLoader *loader);
public slots:
void onFailed(QNetworkReply *reply);
void onFailed(QNetworkReply::NetworkError error);
void onProgress(qint64 already, qint64 size);
void onMeta();
void process();
void proxyApply();
void finish();
private:
void clear();
void sendRequest(webFileLoaderPrivate *loader, const QString &redirect = QString());
bool handleReplyResult(webFileLoaderPrivate *loader, WebReplyProcessResult result);
QNetworkProxy _proxySettings;
QNetworkAccessManager _manager;
typedef QMap<webFileLoader*, webFileLoaderPrivate*> LoaderPointers;
LoaderPointers _loaderPointers;
mutable QMutex _loaderPointersMutex;
typedef OrderedSet<webFileLoaderPrivate*> Loaders;
Loaders _loaders;
typedef QMap<QNetworkReply*, webFileLoaderPrivate*> Replies;
Replies _replies;
};
class WebLoadMainManager : public QObject {
Q_OBJECT
public:
public slots:
void progress(webFileLoader *loader, qint64 already, qint64 size);
void finished(webFileLoader *loader, QByteArray data);
void error(webFileLoader *loader);
};
static FileLoader * const CancelledFileLoader = SharedMemoryLocation<FileLoader, 0>();
static mtpFileLoader * const CancelledMtpFileLoader = static_cast<mtpFileLoader*>(CancelledFileLoader);
static webFileLoader * const CancelledWebFileLoader = static_cast<webFileLoader*>(CancelledFileLoader);
static WebLoadManager * const FinishedWebLoadManager = SharedMemoryLocation<WebLoadManager, 0>();
void reinitWebLoadManager();
void stopWebLoadManager();

View File

@ -1144,7 +1144,7 @@ void _serialize_user(MTPStringLogger &to, int32 stage, int32 lev, Types &types,
case 17: to.add(" status: "); ++stages.back(); if (flag & MTPDuser::flag_status) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
case 18: to.add(" bot_info_version: "); ++stages.back(); if (flag & MTPDuser::flag_bot_info_version) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 14 IN FIELD flags ]"); } break;
case 19: to.add(" restriction_reason: "); ++stages.back(); if (flag & MTPDuser::flag_restriction_reason) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 18 IN FIELD flags ]"); } break;
case 20: to.add(" bot_context_placeholder: "); ++stages.back(); if (flag & MTPDuser::flag_bot_context_placeholder) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 19 IN FIELD flags ]"); } break;
case 20: to.add(" bot_inline_placeholder: "); ++stages.back(); if (flag & MTPDuser::flag_bot_inline_placeholder) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 19 IN FIELD flags ]"); } break;
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
}
}
@ -3053,11 +3053,11 @@ void _serialize_updateSavedGifs(MTPStringLogger &to, int32 stage, int32 lev, Typ
to.add("{ updateSavedGifs }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
}
void _serialize_updateBotContextQuery(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
void _serialize_updateBotInlineQuery(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
if (stage) {
to.add(",\n").addSpaces(lev);
} else {
to.add("{ updateBotContextQuery");
to.add("{ updateBotInlineQuery");
to.add("\n").addSpaces(lev);
}
switch (stage) {
@ -5116,7 +5116,8 @@ void _serialize_foundGifCached(MTPStringLogger &to, int32 stage, int32 lev, Type
}
switch (stage) {
case 0: to.add(" url: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 1: to.add(" document: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 1: to.add(" photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 2: to.add(" document: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
}
}
@ -5153,11 +5154,11 @@ void _serialize_messages_savedGifs(MTPStringLogger &to, int32 stage, int32 lev,
}
}
void _serialize_inputBotContextMessageMediaAuto(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
void _serialize_inputBotInlineMessageMediaAuto(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
if (stage) {
to.add(",\n").addSpaces(lev);
} else {
to.add("{ inputBotContextMessageMediaAuto");
to.add("{ inputBotInlineMessageMediaAuto");
to.add("\n").addSpaces(lev);
}
switch (stage) {
@ -5166,52 +5167,52 @@ void _serialize_inputBotContextMessageMediaAuto(MTPStringLogger &to, int32 stage
}
}
void _serialize_inputBotContextMessageText(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
void _serialize_inputBotInlineMessageText(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
if (stage) {
to.add(",\n").addSpaces(lev);
} else {
to.add("{ inputBotContextMessageText");
to.add("{ inputBotInlineMessageText");
to.add("\n").addSpaces(lev);
}
switch (stage) {
case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 1: to.add(" no_webpage: "); ++stages.back(); if (flag & MTPDinputBotContextMessageText::flag_no_webpage) { to.add("YES [ BY BIT 0 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
case 1: to.add(" no_webpage: "); ++stages.back(); if (flag & MTPDinputBotInlineMessageText::flag_no_webpage) { to.add("YES [ BY BIT 0 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
case 2: to.add(" message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 3: to.add(" entities: "); ++stages.back(); if (flag & MTPDinputBotContextMessageText::flag_entities) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
case 3: to.add(" entities: "); ++stages.back(); if (flag & MTPDinputBotInlineMessageText::flag_entities) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
}
}
void _serialize_inputBotContextResult(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
void _serialize_inputBotInlineResult(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
if (stage) {
to.add(",\n").addSpaces(lev);
} else {
to.add("{ inputBotContextResult");
to.add("{ inputBotInlineResult");
to.add("\n").addSpaces(lev);
}
switch (stage) {
case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 1: to.add(" id: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 2: to.add(" type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 3: to.add(" title: "); ++stages.back(); if (flag & MTPDinputBotContextResult::flag_title) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
case 4: to.add(" description: "); ++stages.back(); if (flag & MTPDinputBotContextResult::flag_description) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
case 5: to.add(" url: "); ++stages.back(); if (flag & MTPDinputBotContextResult::flag_url) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break;
case 6: to.add(" thumb_url: "); ++stages.back(); if (flag & MTPDinputBotContextResult::flag_thumb_url) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break;
case 7: to.add(" content_url: "); ++stages.back(); if (flag & MTPDinputBotContextResult::flag_content_url) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
case 8: to.add(" content_type: "); ++stages.back(); if (flag & MTPDinputBotContextResult::flag_content_type) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
case 9: to.add(" w: "); ++stages.back(); if (flag & MTPDinputBotContextResult::flag_w) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
case 10: to.add(" h: "); ++stages.back(); if (flag & MTPDinputBotContextResult::flag_h) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
case 11: to.add(" duration: "); ++stages.back(); if (flag & MTPDinputBotContextResult::flag_duration) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 7 IN FIELD flags ]"); } break;
case 3: to.add(" title: "); ++stages.back(); if (flag & MTPDinputBotInlineResult::flag_title) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
case 4: to.add(" description: "); ++stages.back(); if (flag & MTPDinputBotInlineResult::flag_description) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
case 5: to.add(" url: "); ++stages.back(); if (flag & MTPDinputBotInlineResult::flag_url) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break;
case 6: to.add(" thumb_url: "); ++stages.back(); if (flag & MTPDinputBotInlineResult::flag_thumb_url) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break;
case 7: to.add(" content_url: "); ++stages.back(); if (flag & MTPDinputBotInlineResult::flag_content_url) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
case 8: to.add(" content_type: "); ++stages.back(); if (flag & MTPDinputBotInlineResult::flag_content_type) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
case 9: to.add(" w: "); ++stages.back(); if (flag & MTPDinputBotInlineResult::flag_w) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
case 10: to.add(" h: "); ++stages.back(); if (flag & MTPDinputBotInlineResult::flag_h) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
case 11: to.add(" duration: "); ++stages.back(); if (flag & MTPDinputBotInlineResult::flag_duration) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 7 IN FIELD flags ]"); } break;
case 12: to.add(" send_message: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
}
}
void _serialize_botContextMessageMediaAuto(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
void _serialize_botInlineMessageMediaAuto(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
if (stage) {
to.add(",\n").addSpaces(lev);
} else {
to.add("{ botContextMessageMediaAuto");
to.add("{ botInlineMessageMediaAuto");
to.add("\n").addSpaces(lev);
}
switch (stage) {
@ -5220,27 +5221,27 @@ void _serialize_botContextMessageMediaAuto(MTPStringLogger &to, int32 stage, int
}
}
void _serialize_botContextMessageText(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
void _serialize_botInlineMessageText(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
if (stage) {
to.add(",\n").addSpaces(lev);
} else {
to.add("{ botContextMessageText");
to.add("{ botInlineMessageText");
to.add("\n").addSpaces(lev);
}
switch (stage) {
case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 1: to.add(" no_webpage: "); ++stages.back(); if (flag & MTPDbotContextMessageText::flag_no_webpage) { to.add("YES [ BY BIT 0 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
case 1: to.add(" no_webpage: "); ++stages.back(); if (flag & MTPDbotInlineMessageText::flag_no_webpage) { to.add("YES [ BY BIT 0 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
case 2: to.add(" message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 3: to.add(" entities: "); ++stages.back(); if (flag & MTPDbotContextMessageText::flag_entities) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
case 3: to.add(" entities: "); ++stages.back(); if (flag & MTPDbotInlineMessageText::flag_entities) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
}
}
void _serialize_botContextMediaResultDocument(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
void _serialize_botInlineMediaResultDocument(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
if (stage) {
to.add(",\n").addSpaces(lev);
} else {
to.add("{ botContextMediaResultDocument");
to.add("{ botInlineMediaResultDocument");
to.add("\n").addSpaces(lev);
}
switch (stage) {
@ -5252,11 +5253,11 @@ void _serialize_botContextMediaResultDocument(MTPStringLogger &to, int32 stage,
}
}
void _serialize_botContextMediaResultPhoto(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
void _serialize_botInlineMediaResultPhoto(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
if (stage) {
to.add(",\n").addSpaces(lev);
} else {
to.add("{ botContextMediaResultPhoto");
to.add("{ botInlineMediaResultPhoto");
to.add("\n").addSpaces(lev);
}
switch (stage) {
@ -5268,26 +5269,26 @@ void _serialize_botContextMediaResultPhoto(MTPStringLogger &to, int32 stage, int
}
}
void _serialize_botContextResult(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
void _serialize_botInlineResult(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
if (stage) {
to.add(",\n").addSpaces(lev);
} else {
to.add("{ botContextResult");
to.add("{ botInlineResult");
to.add("\n").addSpaces(lev);
}
switch (stage) {
case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 1: to.add(" id: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 2: to.add(" type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 3: to.add(" title: "); ++stages.back(); if (flag & MTPDbotContextResult::flag_title) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
case 4: to.add(" description: "); ++stages.back(); if (flag & MTPDbotContextResult::flag_description) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
case 5: to.add(" url: "); ++stages.back(); if (flag & MTPDbotContextResult::flag_url) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break;
case 6: to.add(" thumb_url: "); ++stages.back(); if (flag & MTPDbotContextResult::flag_thumb_url) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break;
case 7: to.add(" content_url: "); ++stages.back(); if (flag & MTPDbotContextResult::flag_content_url) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
case 8: to.add(" content_type: "); ++stages.back(); if (flag & MTPDbotContextResult::flag_content_type) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
case 9: to.add(" w: "); ++stages.back(); if (flag & MTPDbotContextResult::flag_w) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
case 10: to.add(" h: "); ++stages.back(); if (flag & MTPDbotContextResult::flag_h) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
case 11: to.add(" duration: "); ++stages.back(); if (flag & MTPDbotContextResult::flag_duration) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 7 IN FIELD flags ]"); } break;
case 3: to.add(" title: "); ++stages.back(); if (flag & MTPDbotInlineResult::flag_title) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
case 4: to.add(" description: "); ++stages.back(); if (flag & MTPDbotInlineResult::flag_description) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
case 5: to.add(" url: "); ++stages.back(); if (flag & MTPDbotInlineResult::flag_url) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break;
case 6: to.add(" thumb_url: "); ++stages.back(); if (flag & MTPDbotInlineResult::flag_thumb_url) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break;
case 7: to.add(" content_url: "); ++stages.back(); if (flag & MTPDbotInlineResult::flag_content_url) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
case 8: to.add(" content_type: "); ++stages.back(); if (flag & MTPDbotInlineResult::flag_content_type) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
case 9: to.add(" w: "); ++stages.back(); if (flag & MTPDbotInlineResult::flag_w) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
case 10: to.add(" h: "); ++stages.back(); if (flag & MTPDbotInlineResult::flag_h) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
case 11: to.add(" duration: "); ++stages.back(); if (flag & MTPDbotInlineResult::flag_duration) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 7 IN FIELD flags ]"); } break;
case 12: to.add(" send_message: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
}
@ -5302,7 +5303,7 @@ void _serialize_messages_botResults(MTPStringLogger &to, int32 stage, int32 lev,
}
switch (stage) {
case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 1: to.add(" media: "); ++stages.back(); if (flag & MTPDmessages_botResults::flag_media) { to.add("YES [ BY BIT 0 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
case 1: to.add(" gallery: "); ++stages.back(); if (flag & MTPDmessages_botResults::flag_gallery) { to.add("YES [ BY BIT 0 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
case 2: to.add(" query_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 3: to.add(" next_offset: "); ++stages.back(); if (flag & MTPDmessages_botResults::flag_next_offset) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
case 4: to.add(" results: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
@ -5838,21 +5839,21 @@ void _serialize_messages_saveGif(MTPStringLogger &to, int32 stage, int32 lev, Ty
}
}
void _serialize_messages_setContextBotResults(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
void _serialize_messages_setInlineBotResults(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
if (stage) {
to.add(",\n").addSpaces(lev);
} else {
to.add("{ messages_setContextBotResults");
to.add("{ messages_setInlineBotResults");
to.add("\n").addSpaces(lev);
}
switch (stage) {
case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 1: to.add(" media: "); ++stages.back(); if (flag & MTPmessages_setContextBotResults::flag_media) { to.add("YES [ BY BIT 0 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
case 2: to.add(" private: "); ++stages.back(); if (flag & MTPmessages_setContextBotResults::flag_private) { to.add("YES [ BY BIT 1 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
case 1: to.add(" gallery: "); ++stages.back(); if (flag & MTPmessages_setInlineBotResults::flag_gallery) { to.add("YES [ BY BIT 0 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
case 2: to.add(" private: "); ++stages.back(); if (flag & MTPmessages_setInlineBotResults::flag_private) { to.add("YES [ BY BIT 1 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
case 3: to.add(" query_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 4: to.add(" results: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 5: to.add(" cache_time: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 6: to.add(" next_offset: "); ++stages.back(); if (flag & MTPmessages_setContextBotResults::flag_next_offset) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
case 6: to.add(" next_offset: "); ++stages.back(); if (flag & MTPmessages_setInlineBotResults::flag_next_offset) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
}
}
@ -6903,18 +6904,18 @@ void _serialize_messages_migrateChat(MTPStringLogger &to, int32 stage, int32 lev
}
}
void _serialize_messages_sendContextBotResult(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
void _serialize_messages_sendInlineBotResult(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
if (stage) {
to.add(",\n").addSpaces(lev);
} else {
to.add("{ messages_sendContextBotResult");
to.add("{ messages_sendInlineBotResult");
to.add("\n").addSpaces(lev);
}
switch (stage) {
case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 1: to.add(" broadcast: "); ++stages.back(); if (flag & MTPmessages_sendContextBotResult::flag_broadcast) { to.add("YES [ BY BIT 4 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break;
case 1: to.add(" broadcast: "); ++stages.back(); if (flag & MTPmessages_sendInlineBotResult::flag_broadcast) { to.add("YES [ BY BIT 4 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break;
case 2: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 3: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPmessages_sendContextBotResult::flag_reply_to_msg_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
case 3: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPmessages_sendInlineBotResult::flag_reply_to_msg_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
case 4: to.add(" random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 5: to.add(" query_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 6: to.add(" id: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
@ -7366,11 +7367,11 @@ void _serialize_messages_getSavedGifs(MTPStringLogger &to, int32 stage, int32 le
}
}
void _serialize_messages_getContextBotResults(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
void _serialize_messages_getInlineBotResults(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
if (stage) {
to.add(",\n").addSpaces(lev);
} else {
to.add("{ messages_getContextBotResults");
to.add("{ messages_getInlineBotResults");
to.add("\n").addSpaces(lev);
}
switch (stage) {
@ -7871,7 +7872,7 @@ namespace {
_serializers.insert(mtpc_updateStickerSetsOrder, _serialize_updateStickerSetsOrder);
_serializers.insert(mtpc_updateStickerSets, _serialize_updateStickerSets);
_serializers.insert(mtpc_updateSavedGifs, _serialize_updateSavedGifs);
_serializers.insert(mtpc_updateBotContextQuery, _serialize_updateBotContextQuery);
_serializers.insert(mtpc_updateBotInlineQuery, _serialize_updateBotInlineQuery);
_serializers.insert(mtpc_updates_state, _serialize_updates_state);
_serializers.insert(mtpc_updates_differenceEmpty, _serialize_updates_differenceEmpty);
_serializers.insert(mtpc_updates_difference, _serialize_updates_difference);
@ -8042,14 +8043,14 @@ namespace {
_serializers.insert(mtpc_messages_foundGifs, _serialize_messages_foundGifs);
_serializers.insert(mtpc_messages_savedGifsNotModified, _serialize_messages_savedGifsNotModified);
_serializers.insert(mtpc_messages_savedGifs, _serialize_messages_savedGifs);
_serializers.insert(mtpc_inputBotContextMessageMediaAuto, _serialize_inputBotContextMessageMediaAuto);
_serializers.insert(mtpc_inputBotContextMessageText, _serialize_inputBotContextMessageText);
_serializers.insert(mtpc_inputBotContextResult, _serialize_inputBotContextResult);
_serializers.insert(mtpc_botContextMessageMediaAuto, _serialize_botContextMessageMediaAuto);
_serializers.insert(mtpc_botContextMessageText, _serialize_botContextMessageText);
_serializers.insert(mtpc_botContextMediaResultDocument, _serialize_botContextMediaResultDocument);
_serializers.insert(mtpc_botContextMediaResultPhoto, _serialize_botContextMediaResultPhoto);
_serializers.insert(mtpc_botContextResult, _serialize_botContextResult);
_serializers.insert(mtpc_inputBotInlineMessageMediaAuto, _serialize_inputBotInlineMessageMediaAuto);
_serializers.insert(mtpc_inputBotInlineMessageText, _serialize_inputBotInlineMessageText);
_serializers.insert(mtpc_inputBotInlineResult, _serialize_inputBotInlineResult);
_serializers.insert(mtpc_botInlineMessageMediaAuto, _serialize_botInlineMessageMediaAuto);
_serializers.insert(mtpc_botInlineMessageText, _serialize_botInlineMessageText);
_serializers.insert(mtpc_botInlineMediaResultDocument, _serialize_botInlineMediaResultDocument);
_serializers.insert(mtpc_botInlineMediaResultPhoto, _serialize_botInlineMediaResultPhoto);
_serializers.insert(mtpc_botInlineResult, _serialize_botInlineResult);
_serializers.insert(mtpc_messages_botResults, _serialize_messages_botResults);
_serializers.insert(mtpc_req_pq, _serialize_req_pq);
@ -8092,7 +8093,7 @@ namespace {
_serializers.insert(mtpc_messages_editChatAdmin, _serialize_messages_editChatAdmin);
_serializers.insert(mtpc_messages_reorderStickerSets, _serialize_messages_reorderStickerSets);
_serializers.insert(mtpc_messages_saveGif, _serialize_messages_saveGif);
_serializers.insert(mtpc_messages_setContextBotResults, _serialize_messages_setContextBotResults);
_serializers.insert(mtpc_messages_setInlineBotResults, _serialize_messages_setInlineBotResults);
_serializers.insert(mtpc_upload_saveFilePart, _serialize_upload_saveFilePart);
_serializers.insert(mtpc_upload_saveBigFilePart, _serialize_upload_saveBigFilePart);
_serializers.insert(mtpc_help_saveAppLog, _serialize_help_saveAppLog);
@ -8170,7 +8171,7 @@ namespace {
_serializers.insert(mtpc_messages_startBot, _serialize_messages_startBot);
_serializers.insert(mtpc_messages_toggleChatAdmins, _serialize_messages_toggleChatAdmins);
_serializers.insert(mtpc_messages_migrateChat, _serialize_messages_migrateChat);
_serializers.insert(mtpc_messages_sendContextBotResult, _serialize_messages_sendContextBotResult);
_serializers.insert(mtpc_messages_sendInlineBotResult, _serialize_messages_sendInlineBotResult);
_serializers.insert(mtpc_channels_createChannel, _serialize_channels_createChannel);
_serializers.insert(mtpc_channels_editAdmin, _serialize_channels_editAdmin);
_serializers.insert(mtpc_channels_editTitle, _serialize_channels_editTitle);
@ -8203,7 +8204,7 @@ namespace {
_serializers.insert(mtpc_messages_getDocumentByHash, _serialize_messages_getDocumentByHash);
_serializers.insert(mtpc_messages_searchGifs, _serialize_messages_searchGifs);
_serializers.insert(mtpc_messages_getSavedGifs, _serialize_messages_getSavedGifs);
_serializers.insert(mtpc_messages_getContextBotResults, _serialize_messages_getContextBotResults);
_serializers.insert(mtpc_messages_getInlineBotResults, _serialize_messages_getInlineBotResults);
_serializers.insert(mtpc_updates_getState, _serialize_updates_getState);
_serializers.insert(mtpc_updates_getDifference, _serialize_updates_getDifference);
_serializers.insert(mtpc_updates_getChannelDifference, _serialize_updates_getChannelDifference);

File diff suppressed because it is too large Load Diff

View File

@ -204,7 +204,7 @@ fileLocationUnavailable#7c596b46 volume_id:long local_id:int secret:long = FileL
fileLocation#53d69076 dc_id:int volume_id:long local_id:int secret:long = FileLocation;
userEmpty#200250ba id:int = User;
user#cb574c74 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true id:int access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?string bot_context_placeholder:flags.19?string = User;
user#d10d979a flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true id:int access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?string bot_inline_placeholder:flags.19?string = User;
userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
userProfilePhoto#d559d8c8 photo_id:long photo_small:FileLocation photo_big:FileLocation = UserProfilePhoto;
@ -400,7 +400,7 @@ updateNewStickerSet#688a30aa stickerset:messages.StickerSet = Update;
updateStickerSetsOrder#f0dfb451 order:Vector<long> = Update;
updateStickerSets#43ae3dec = Update;
updateSavedGifs#9375341e = Update;
updateBotContextQuery#934bca16 query_id:long user_id:int query:string offset:string = Update;
updateBotInlineQuery#c01eea08 query_id:long user_id:int query:string offset:string = Update;
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
@ -640,26 +640,26 @@ channels.channelParticipant#d0d9b163 participant:ChannelParticipant users:Vector
help.termsOfService#f1ee3e90 text:string = help.TermsOfService;
foundGif#162ecc1f url:string thumb_url:string content_url:string content_type:string w:int h:int = FoundGif;
foundGifCached#fdfe5e4d url:string document:Document = FoundGif;
foundGifCached#9c750409 url:string photo:Photo document:Document = FoundGif;
messages.foundGifs#450a1c0a next_offset:int results:Vector<FoundGif> = messages.FoundGifs;
messages.savedGifsNotModified#e8025ca2 = messages.SavedGifs;
messages.savedGifs#2e0709a5 hash:int gifs:Vector<Document> = messages.SavedGifs;
inputBotContextMessageMediaAuto#113c6793 caption:string = InputBotContextMessage;
inputBotContextMessageText#52832c56 flags:# no_webpage:flags.0?true message:string entities:flags.1?Vector<MessageEntity> = InputBotContextMessage;
inputBotInlineMessageMediaAuto#2e43e587 caption:string = InputBotInlineMessage;
inputBotInlineMessageText#adf0df71 flags:# no_webpage:flags.0?true message:string entities:flags.1?Vector<MessageEntity> = InputBotInlineMessage;
inputBotContextResult#72d8b33b flags:# id:string type:string title:flags.1?string description:flags.2?string url:flags.3?string thumb_url:flags.4?string content_url:flags.5?string content_type:flags.5?string w:flags.6?int h:flags.6?int duration:flags.7?int send_message:InputBotContextMessage = InputBotContextResult;
inputBotInlineResult#2cbbe15a flags:# id:string type:string title:flags.1?string description:flags.2?string url:flags.3?string thumb_url:flags.4?string content_url:flags.5?string content_type:flags.5?string w:flags.6?int h:flags.6?int duration:flags.7?int send_message:InputBotInlineMessage = InputBotInlineResult;
botContextMessageMediaAuto#a9ec3903 caption:string = BotContextMessage;
botContextMessageText#2eb67d88 flags:# no_webpage:flags.0?true message:string entities:flags.1?Vector<MessageEntity> = BotContextMessage;
botInlineMessageMediaAuto#fc56e87d caption:string = BotInlineMessage;
botInlineMessageText#a56197a9 flags:# no_webpage:flags.0?true message:string entities:flags.1?Vector<MessageEntity> = BotInlineMessage;
botContextMediaResultDocument#392ebe49 id:string type:string document:Document send_message:BotContextMessage = BotContextResult;
botContextMediaResultPhoto#139ce337 id:string type:string photo:Photo send_message:BotContextMessage = BotContextResult;
botContextResult#50a2cecf flags:# id:string type:string title:flags.1?string description:flags.2?string url:flags.3?string thumb_url:flags.4?string content_url:flags.5?string content_type:flags.5?string w:flags.6?int h:flags.6?int duration:flags.7?int send_message:BotContextMessage = BotContextResult;
botInlineMediaResultDocument#f897d33e id:string type:string document:Document send_message:BotInlineMessage = BotInlineResult;
botInlineMediaResultPhoto#c5528587 id:string type:string photo:Photo send_message:BotInlineMessage = BotInlineResult;
botInlineResult#9bebaeb9 flags:# id:string type:string title:flags.1?string description:flags.2?string url:flags.3?string thumb_url:flags.4?string content_url:flags.5?string content_type:flags.5?string w:flags.6?int h:flags.6?int duration:flags.7?int send_message:BotInlineMessage = BotInlineResult;
messages.botResults#772740b1 flags:# media:flags.0?true query_id:long next_offset:flags.1?string results:Vector<BotContextResult> = messages.BotResults;
messages.botResults#1170b0a3 flags:# gallery:flags.0?true query_id:long next_offset:flags.1?string results:Vector<BotInlineResult> = messages.BotResults;
---functions---
@ -781,9 +781,9 @@ messages.getDocumentByHash#338e2464 sha256:bytes size:int mime_type:string = Doc
messages.searchGifs#bf9a776b q:string offset:int = messages.FoundGifs;
messages.getSavedGifs#83bf3d52 hash:int = messages.SavedGifs;
messages.saveGif#327a30cb id:InputDocument unsave:Bool = Bool;
messages.getContextBotResults#36e7d06c bot:InputUser query:string offset:string = messages.BotResults;
messages.setContextBotResults#d7f2de0f flags:# media:flags.0?true private:flags.1?true query_id:long results:Vector<InputBotContextResult> cache_time:int next_offset:flags.2?string = Bool;
messages.sendContextBotResult#bdb3c4d0 flags:# broadcast:flags.4?true peer:InputPeer reply_to_msg_id:flags.0?int random_id:long query_id:long id:string = Updates;
messages.getInlineBotResults#9324600d bot:InputUser query:string offset:string = messages.BotResults;
messages.setInlineBotResults#3f23ec12 flags:# gallery:flags.0?true private:flags.1?true query_id:long results:Vector<InputBotInlineResult> cache_time:int next_offset:flags.2?string = Bool;
messages.sendInlineBotResult#b16e06fe flags:# broadcast:flags.4?true peer:InputPeer reply_to_msg_id:flags.0?int random_id:long query_id:long id:string = Updates;
updates.getState#edd4882a = updates.State;
updates.getDifference#a041495 pts:int date:int qts:int = updates.Difference;

View File

@ -891,7 +891,7 @@ bool VideoData::loaded(bool check) const {
if (_loader->fileType() == mtpc_storage_fileUnknown) {
_loader->deleteLater();
_loader->rpcInvalidate();
_loader = CancelledFileLoader;
_loader = CancelledMtpFileLoader;
} else {
VideoData *that = const_cast<VideoData*>(this);
that->_location = FileLocation(mtpToStorageType(_loader->fileType()), _loader->fileName());
@ -906,7 +906,7 @@ bool VideoData::loaded(bool check) const {
}
bool VideoData::loading() const {
return _loader && _loader != CancelledFileLoader;
return _loader && _loader != CancelledMtpFileLoader;
}
bool VideoData::displayLoading() const {
@ -943,7 +943,7 @@ void VideoData::save(const QString &toFile, ActionOnLoad action, const FullMsgId
return;
}
if (_loader == CancelledFileLoader) _loader = 0;
if (_loader == CancelledMtpFileLoader) _loader = 0;
if (_loader) {
if (!_loader->setFileName(toFile)) {
cancel();
@ -959,8 +959,8 @@ void VideoData::save(const QString &toFile, ActionOnLoad action, const FullMsgId
} else {
status = FileReady;
_loader = new mtpFileLoader(dc, id, access, VideoFileLocation, toFile, size, (saveToCache() ? LoadToCacheAsWell : LoadToFileOnly), fromCloud, autoLoading);
_loader->connect(_loader, SIGNAL(progress(mtpFileLoader*)), App::main(), SLOT(videoLoadProgress(mtpFileLoader*)));
_loader->connect(_loader, SIGNAL(failed(mtpFileLoader*,bool)), App::main(), SLOT(videoLoadProgress(mtpFileLoader*,bool)));
_loader->connect(_loader, SIGNAL(progress(FileLoader*)), App::main(), SLOT(videoLoadProgress(FileLoader*)));
_loader->connect(_loader, SIGNAL(failed(FileLoader*,bool)), App::main(), SLOT(videoLoadFailed(FileLoader*,bool)));
_loader->start();
}
@ -971,7 +971,7 @@ void VideoData::cancel() {
if (!loading()) return;
mtpFileLoader *l = _loader;
_loader = CancelledFileLoader;
_loader = CancelledMtpFileLoader;
if (l) {
l->cancel();
l->deleteLater();
@ -1148,7 +1148,7 @@ void AudioData::forget() {
void AudioData::automaticLoad(const HistoryItem *item) {
if (loaded() || status != FileReady) return;
if (saveToCache() && _loader != CancelledFileLoader) {
if (saveToCache() && _loader != CancelledMtpFileLoader) {
if (item) {
bool loadFromCloud = false;
if (item->history()->peer->isUser()) {
@ -1162,7 +1162,7 @@ void AudioData::automaticLoad(const HistoryItem *item) {
}
void AudioData::automaticLoadSettingsChanged() {
if (loaded() || status != FileReady || !saveToCache() || _loader != CancelledFileLoader) return;
if (loaded() || status != FileReady || !saveToCache() || _loader != CancelledMtpFileLoader) return;
_loader = 0;
}
@ -1208,7 +1208,7 @@ bool AudioData::loaded(bool check) const {
if (_loader->fileType() == mtpc_storage_fileUnknown) {
_loader->deleteLater();
_loader->rpcInvalidate();
_loader = CancelledFileLoader;
_loader = CancelledMtpFileLoader;
} else {
AudioData *that = const_cast<AudioData*>(this);
that->_location = FileLocation(mtpToStorageType(_loader->fileType()), _loader->fileName());
@ -1224,7 +1224,7 @@ bool AudioData::loaded(bool check) const {
}
bool AudioData::loading() const {
return _loader && _loader != CancelledFileLoader;
return _loader && _loader != CancelledMtpFileLoader;
}
bool AudioData::displayLoading() const {
@ -1265,7 +1265,7 @@ void AudioData::save(const QString &toFile, ActionOnLoad action, const FullMsgId
return;
}
if (_loader == CancelledFileLoader) _loader = 0;
if (_loader == CancelledMtpFileLoader) _loader = 0;
if (_loader) {
if (!_loader->setFileName(toFile)) {
cancel();
@ -1281,8 +1281,8 @@ void AudioData::save(const QString &toFile, ActionOnLoad action, const FullMsgId
} else {
status = FileReady;
_loader = new mtpFileLoader(dc, id, access, AudioFileLocation, toFile, size, (saveToCache() ? LoadToCacheAsWell : LoadToFileOnly), fromCloud, autoLoading);
_loader->connect(_loader, SIGNAL(progress(mtpFileLoader*)), App::main(), SLOT(audioLoadProgress(mtpFileLoader*)));
_loader->connect(_loader, SIGNAL(failed(mtpFileLoader*,bool)), App::main(), SLOT(audioLoadFailed(mtpFileLoader*,bool)));
_loader->connect(_loader, SIGNAL(progress(FileLoader*)), App::main(), SLOT(audioLoadProgress(FileLoader*)));
_loader->connect(_loader, SIGNAL(failed(FileLoader*,bool)), App::main(), SLOT(audioLoadFailed(FileLoader*,bool)));
_loader->start();
}
@ -1293,7 +1293,7 @@ void AudioData::cancel() {
if (!loading()) return;
mtpFileLoader *l = _loader;
_loader = CancelledFileLoader;
_loader = CancelledMtpFileLoader;
if (l) {
l->cancel();
l->deleteLater();
@ -1561,7 +1561,7 @@ void DocumentData::forget() {
void DocumentData::automaticLoad(const HistoryItem *item) {
if (loaded() || status != FileReady) return;
if (saveToCache() && _loader != CancelledFileLoader) {
if (saveToCache() && _loader != CancelledMtpFileLoader) {
if (type == StickerDocument) {
save(QString(), _actionOnLoad, _actionOnLoadMsgId);
} else if (isAnimation()) {
@ -1581,7 +1581,7 @@ void DocumentData::automaticLoad(const HistoryItem *item) {
}
void DocumentData::automaticLoadSettingsChanged() {
if (loaded() || status != FileReady || !isAnimation() || !saveToCache() || _loader != CancelledFileLoader) return;
if (loaded() || status != FileReady || !isAnimation() || !saveToCache() || _loader != CancelledMtpFileLoader) return;
_loader = 0;
}
@ -1646,7 +1646,7 @@ bool DocumentData::loaded(bool check) const {
if (_loader->fileType() == mtpc_storage_fileUnknown) {
_loader->deleteLater();
_loader->rpcInvalidate();
_loader = CancelledFileLoader;
_loader = CancelledMtpFileLoader;
} else {
DocumentData *that = const_cast<DocumentData*>(this);
that->_location = FileLocation(mtpToStorageType(_loader->fileType()), _loader->fileName());
@ -1665,7 +1665,7 @@ bool DocumentData::loaded(bool check) const {
}
bool DocumentData::loading() const {
return _loader && _loader != CancelledFileLoader;
return _loader && _loader != CancelledMtpFileLoader;
}
bool DocumentData::displayLoading() const {
@ -1706,7 +1706,7 @@ void DocumentData::save(const QString &toFile, ActionOnLoad action, const FullMs
return;
}
if (_loader == CancelledFileLoader) _loader = 0;
if (_loader == CancelledMtpFileLoader) _loader = 0;
if (_loader) {
if (!_loader->setFileName(toFile)) {
cancel();
@ -1722,8 +1722,8 @@ void DocumentData::save(const QString &toFile, ActionOnLoad action, const FullMs
} else {
status = FileReady;
_loader = new mtpFileLoader(dc, id, access, DocumentFileLocation, toFile, size, (saveToCache() ? LoadToCacheAsWell : LoadToFileOnly), fromCloud, autoLoading);
_loader->connect(_loader, SIGNAL(progress(mtpFileLoader*)), App::main(), SLOT(documentLoadProgress(mtpFileLoader*)));
_loader->connect(_loader, SIGNAL(failed(mtpFileLoader*,bool)), App::main(), SLOT(documentLoadFailed(mtpFileLoader*,bool)));
_loader->connect(_loader, SIGNAL(progress(FileLoader*)), App::main(), SLOT(documentLoadProgress(FileLoader*)));
_loader->connect(_loader, SIGNAL(failed(FileLoader*,bool)), App::main(), SLOT(documentLoadFailed(FileLoader*,bool)));
_loader->start();
}
@ -1734,7 +1734,7 @@ void DocumentData::cancel() {
if (!loading()) return;
mtpFileLoader *l = _loader;
_loader = CancelledFileLoader;
_loader = CancelledMtpFileLoader;
if (l) {
l->cancel();
l->deleteLater();
@ -2034,30 +2034,30 @@ void ImageLinkData::load() {
manager.getData(this);
}
void ContextResult::automaticLoadGif() const {
void InlineResult::automaticLoadGif() const {
}
QByteArray ContextResult::data() const {
QByteArray InlineResult::data() const {
return _data;
}
bool ContextResult::loading() const {
bool InlineResult::loading() const {
return false;
}
bool ContextResult::loaded() const {
bool InlineResult::loaded() const {
return false;
}
bool ContextResult::displayLoading() const {
bool InlineResult::displayLoading() const {
return false;
}
void ContextResult::forget() {
void InlineResult::forget() {
}
float64 ContextResult::progress() const {
float64 InlineResult::progress() const {
return 0.;
}

View File

@ -327,7 +327,7 @@ struct BotInfo {
bool inited;
bool readsAllHistory, cantJoinGroups;
int32 version;
QString shareText, description, contextPlaceholder;
QString shareText, description, inlinePlaceholder;
QList<BotCommand> commands;
Text text; // description
@ -385,7 +385,7 @@ public:
BotInfo *botInfo;
};
static UserData * const ContextBotLookingUpData = SharedMemoryLocation<UserData, 0>();
static UserData * const InlineBotLookingUpData = SharedMemoryLocation<UserData, 0>();
class ChatData : public PeerData {
public:
@ -1324,7 +1324,7 @@ public:
deinit();
}
public slots:
public slots:
void onFinished(QNetworkReply *reply);
void onFailed(QNetworkReply *reply);
@ -1337,9 +1337,9 @@ private:
ImagePtr *black;
};
class ContextResult {
class InlineResult {
public:
ContextResult(uint64 queryId)
InlineResult(uint64 queryId)
: queryId(queryId)
, doc(0)
, photo(0)
@ -1374,7 +1374,7 @@ private:
QByteArray _data;
};
typedef QList<ContextResult*> ContextResults;
typedef QList<InlineResult*> InlineResults;
QString saveFileName(const QString &title, const QString &filter, const QString &prefix, QString name, bool savingAs, const QDir &dir = QDir());
MsgId clientMsgId();