mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-02-20 23:27:23 +00:00
moved context bots to emojipan, fixed webpage thumb image size
This commit is contained in:
parent
38ea16fea4
commit
96a698a4dc
@ -2254,7 +2254,9 @@ EmojiPan::EmojiPan(QWidget *parent) : TWidget(parent)
|
||||
, s_scroll(this, st::emojiScroll)
|
||||
, s_inner()
|
||||
, s_switch(&s_scroll, false)
|
||||
, _removingSetId(0) {
|
||||
, _removingSetId(0)
|
||||
, _contextBot(0)
|
||||
, _contextRequestId(0) {
|
||||
setFocusPolicy(Qt::NoFocus);
|
||||
e_scroll.setFocusPolicy(Qt::NoFocus);
|
||||
e_scroll.viewport()->setFocusPolicy(Qt::NoFocus);
|
||||
@ -2319,6 +2321,10 @@ 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()));
|
||||
|
||||
if (cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
|
||||
connect(App::wnd()->windowHandle(), SIGNAL(activeChanged()), this, SLOT(onWndActiveChanged()));
|
||||
}
|
||||
@ -3159,12 +3165,134 @@ void EmojiPan::onDelayedHide() {
|
||||
_removingSetId = 0;
|
||||
}
|
||||
|
||||
MentionsInner::MentionsInner(MentionsDropdown *parent, MentionRows *mrows, HashtagRows *hrows, BotCommandRows *brows, ContextRows *crows)
|
||||
void EmojiPan::clearContextResults() {
|
||||
if (_contextRequestId) MTP::cancel(_contextRequestId);
|
||||
_contextRequestId = 0;
|
||||
_contextQuery = _contextNextQuery = _contextNextOffset = QString();
|
||||
_contextBot = 0;
|
||||
_contextCache.clear();
|
||||
}
|
||||
|
||||
void EmojiPan::contextResultsDone(const MTPmessages_BotResults &result) {
|
||||
_contextRequestId = 0;
|
||||
|
||||
ContextCache::iterator it = _contextCache.find(_contextQuery);
|
||||
|
||||
bool adding = (it != _contextCache.cend());
|
||||
if (result.type() == mtpc_messages_botResults) {
|
||||
const MTPDmessages_botResults &d(result.c_messages_botResults());
|
||||
const QVector<MTPBotContextResult> &v(d.vresults.c_vector().v);
|
||||
uint64 queryId(d.vquery_id.v);
|
||||
|
||||
if (!adding) {
|
||||
it = _contextCache.insert(_contextQuery, ContextCacheEntry());
|
||||
}
|
||||
it->nextOffset = v.isEmpty() ? QString() : qs(d.vnext_offset);
|
||||
|
||||
int32 count = v.size();
|
||||
if (count) {
|
||||
it->results.reserve(it->results.size() + count);
|
||||
}
|
||||
for (int32 i = 0; i < count; ++i) {
|
||||
ContextResult result(queryId);
|
||||
const MTPBotContextMessage *message = 0;
|
||||
switch (v.at(i).type()) {
|
||||
case mtpc_botContextMediaResultPhoto: {
|
||||
const MTPDbotContextMediaResultPhoto &r(v.at(i).c_botContextMediaResultPhoto());
|
||||
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());
|
||||
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());
|
||||
result.id = qs(r.vid);
|
||||
result.type = qs(r.vtype);
|
||||
result.title = qs(r.vtitle);
|
||||
result.description = qs(r.vdescription);
|
||||
result.url = qs(r.vurl);
|
||||
result.thumb_url = qs(r.vthumb_url);
|
||||
result.content_type = qs(r.vcontent_type);
|
||||
result.content_url = qs(r.vcontent_url);
|
||||
message = &r.vsend_message;
|
||||
} break;
|
||||
}
|
||||
bool badAttachment = (!result.photo || result.photo->access) && (!result.doc || result.doc->access);
|
||||
bool canSend = (result.photo || result.doc || !result.message.isEmpty());
|
||||
if (!result.type.isEmpty() && !badAttachment && !canSend) {
|
||||
it->results.push_back(result);
|
||||
}
|
||||
}
|
||||
} else if (adding) {
|
||||
it->results.clear();
|
||||
it->nextOffset = QString();
|
||||
}
|
||||
refreshContextRows(!adding);
|
||||
}
|
||||
|
||||
bool EmojiPan::contextResultsFail(const RPCError &error) {
|
||||
if (mtpIsFlood(error)) return false;
|
||||
_contextRequestId = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void EmojiPan::showContextResults(UserData *bot, QString query) {
|
||||
bool force = false;
|
||||
if (bot != _contextBot) {
|
||||
if (!isHidden()) hideStart();
|
||||
|
||||
clearContextResults();
|
||||
_contextBot = bot;
|
||||
force = true;
|
||||
}
|
||||
if (_contextRequestId) {
|
||||
MTP::cancel(_contextRequestId);
|
||||
_contextRequestId = 0;
|
||||
}
|
||||
if (_contextQuery != query || force) {
|
||||
if (_contextCache.contains(_contextQuery)) {
|
||||
refreshContextRows(true);
|
||||
} else {
|
||||
_contextNextQuery = _contextQuery;
|
||||
_contextRequestTimer.start(ContextBotRequestDelay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EmojiPan::onContextRequest() {
|
||||
if (_contextRequestId) return;
|
||||
_contextQuery = _contextNextQuery;
|
||||
|
||||
QString nextOffset;
|
||||
ContextCache::const_iterator i = _contextCache.constFind(_contextQuery);
|
||||
if (i != _contextCache.cend()) {
|
||||
nextOffset = i->nextOffset;
|
||||
if (nextOffset.isEmpty()) return;
|
||||
}
|
||||
_contextRequestId = MTP::send(MTPmessages_GetContextBotResults(_contextBot->inputUser, MTP_string(_contextQuery), MTP_string(nextOffset)), rpcDone(&EmojiPan::contextResultsDone), rpcFail(&EmojiPan::contextResultsFail));
|
||||
}
|
||||
|
||||
void EmojiPan::refreshContextRows(bool toDown) {
|
||||
bool clear = true;
|
||||
ContextCache::const_iterator i = _contextCache.constFind(_contextQuery);
|
||||
if (i == _contextCache.cend()) {
|
||||
clear = !i->results.isEmpty();
|
||||
_contextNextOffset = i->nextOffset;
|
||||
}
|
||||
}
|
||||
|
||||
MentionsInner::MentionsInner(MentionsDropdown *parent, MentionRows *mrows, HashtagRows *hrows, BotCommandRows *brows)
|
||||
: _parent(parent)
|
||||
, _mrows(mrows)
|
||||
, _hrows(hrows)
|
||||
, _brows(brows)
|
||||
, _crows(crows)
|
||||
, _sel(-1)
|
||||
, _mouseSel(false)
|
||||
, _overDelete(false) {
|
||||
@ -3422,9 +3550,7 @@ void MentionsInner::onParentGeometryChanged() {
|
||||
|
||||
MentionsDropdown::MentionsDropdown(QWidget *parent) : TWidget(parent)
|
||||
, _scroll(this, st::mentionScroll)
|
||||
, _inner(this, &_mrows, &_hrows, &_brows, &_crows)
|
||||
, _contextBot(0)
|
||||
, _contextRequestId(0)
|
||||
, _inner(this, &_mrows, &_hrows, &_brows)
|
||||
, _chat(0)
|
||||
, _user(0)
|
||||
, _channel(0)
|
||||
@ -3437,9 +3563,6 @@ MentionsDropdown::MentionsDropdown(QWidget *parent) : TWidget(parent)
|
||||
connect(&_inner, SIGNAL(chosen(QString)), this, SIGNAL(chosen(QString)));
|
||||
connect(&_inner, SIGNAL(mustScrollTo(int,int)), &_scroll, SLOT(scrollToY(int,int)));
|
||||
|
||||
_contextRequestTimer.setSingleShot(true);
|
||||
connect(&_contextRequestTimer, SIGNAL(timeout()), this, SLOT(onContextRequest()));
|
||||
|
||||
connect(App::wnd(), SIGNAL(imageLoaded()), &_inner, SLOT(update()));
|
||||
|
||||
setFocusPolicy(Qt::NoFocus);
|
||||
@ -3470,137 +3593,7 @@ void MentionsDropdown::paintEvent(QPaintEvent *e) {
|
||||
|
||||
}
|
||||
|
||||
void MentionsDropdown::clearContextResults() {
|
||||
if (_contextRequestId) MTP::cancel(_contextRequestId);
|
||||
_contextRequestId = 0;
|
||||
_contextQuery = _contextNextQuery = _contextNextOffset = QString();
|
||||
_contextBot = 0;
|
||||
_contextCache.clear();
|
||||
|
||||
_crows.clear();
|
||||
}
|
||||
|
||||
void MentionsDropdown::contextResultsDone(const MTPmessages_BotResults &result) {
|
||||
_contextRequestId = 0;
|
||||
|
||||
ContextCache::iterator it = _contextCache.find(_contextQuery);
|
||||
|
||||
bool adding = (it != _contextCache.cend());
|
||||
if (result.type() == mtpc_messages_botResults) {
|
||||
const MTPDmessages_botResults &d(result.c_messages_botResults());
|
||||
const QVector<MTPBotContextResult> &v(d.vresults.c_vector().v);
|
||||
uint64 queryId(d.vquery_id.v);
|
||||
|
||||
if (!adding) {
|
||||
it = _contextCache.insert(_contextQuery, ContextCacheEntry());
|
||||
}
|
||||
it->nextOffset = v.isEmpty() ? QString() : qs(d.vnext_offset);
|
||||
|
||||
int32 count = v.size();
|
||||
if (count) {
|
||||
it->results.reserve(it->results.size() + count);
|
||||
}
|
||||
for (int32 i = 0; i < count; ++i) {
|
||||
ContextResult result(queryId);
|
||||
const MTPBotContextMessage *message = 0;
|
||||
switch (v.at(i).type()) {
|
||||
case mtpc_botContextMediaResultPhoto: {
|
||||
const MTPDbotContextMediaResultPhoto &r(v.at(i).c_botContextMediaResultPhoto());
|
||||
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());
|
||||
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());
|
||||
result.id = qs(r.vid);
|
||||
result.type = qs(r.vtype);
|
||||
result.title = qs(r.vtitle);
|
||||
result.description = qs(r.vdescription);
|
||||
result.url = qs(r.vurl);
|
||||
result.thumb_url = qs(r.vthumb_url);
|
||||
result.content_type = qs(r.vcontent_type);
|
||||
result.content_url = qs(r.vcontent_url);
|
||||
message = &r.vsend_message;
|
||||
} break;
|
||||
}
|
||||
bool badAttachment = (!result.photo || result.photo->access) && (!result.doc || result.doc->access);
|
||||
bool canSend = (result.photo || result.doc || !result.message.isEmpty());
|
||||
if (!result.type.isEmpty() && !badAttachment && !canSend) {
|
||||
it->results.push_back(result);
|
||||
}
|
||||
}
|
||||
} else if (adding) {
|
||||
it->results.clear();
|
||||
it->nextOffset = QString();
|
||||
}
|
||||
refreshContextRows(!adding);
|
||||
}
|
||||
|
||||
bool MentionsDropdown::contextResultsFail(const RPCError &error) {
|
||||
if (mtpIsFlood(error)) return false;
|
||||
_contextRequestId = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void MentionsDropdown::showContextResults(UserData *bot, QString query) {
|
||||
bool force = false;
|
||||
if (bot != _contextBot) {
|
||||
if (!isHidden()) hideStart();
|
||||
|
||||
clearContextResults();
|
||||
_contextBot = bot;
|
||||
force = true;
|
||||
}
|
||||
if (_contextRequestId) {
|
||||
MTP::cancel(_contextRequestId);
|
||||
_contextRequestId = 0;
|
||||
}
|
||||
if (_contextQuery != query || force) {
|
||||
if (_contextCache.contains(_contextQuery)) {
|
||||
refreshContextRows(true);
|
||||
} else {
|
||||
_contextNextQuery = _contextQuery;
|
||||
_contextRequestTimer.start(ContextBotRequestDelay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MentionsDropdown::onContextRequest() {
|
||||
if (_contextRequestId) return;
|
||||
_contextQuery = _contextNextQuery;
|
||||
|
||||
QString nextOffset;
|
||||
ContextCache::const_iterator i = _contextCache.constFind(_contextQuery);
|
||||
if (i != _contextCache.cend()) {
|
||||
nextOffset = i->nextOffset;
|
||||
if (nextOffset.isEmpty()) return;
|
||||
}
|
||||
_contextRequestId = MTP::send(MTPmessages_GetContextBotResults(_contextBot->inputUser, MTP_string(_contextQuery), MTP_string(nextOffset)), rpcDone(&MentionsDropdown::contextResultsDone), rpcFail(&MentionsDropdown::contextResultsFail));
|
||||
}
|
||||
|
||||
void MentionsDropdown::refreshContextRows(bool toDown) {
|
||||
bool clear = true;
|
||||
ContextCache::const_iterator i = _contextCache.constFind(_contextQuery);
|
||||
if (i == _contextCache.cend()) {
|
||||
clear = !i->results.isEmpty();
|
||||
_contextNextOffset = i->nextOffset;
|
||||
}
|
||||
rowsUpdated(MentionRows(), HashtagRows(), BotCommandRows(), clear ? ContextRows() : _crows, toDown);
|
||||
}
|
||||
|
||||
void MentionsDropdown::showFiltered(PeerData *peer, QString start) {
|
||||
if (_contextBot) {
|
||||
clearContextResults();
|
||||
}
|
||||
|
||||
_chat = peer->asChat();
|
||||
_user = peer->asUser();
|
||||
_channel = peer->asChannel();
|
||||
@ -3620,8 +3613,6 @@ bool MentionsDropdown::clearFilteredBotCommands() {
|
||||
}
|
||||
|
||||
void MentionsDropdown::updateFiltered(bool toDown) {
|
||||
clearContextResults();
|
||||
|
||||
int32 now = unixtime();
|
||||
MentionRows rows;
|
||||
HashtagRows hrows;
|
||||
@ -3743,23 +3734,21 @@ void MentionsDropdown::updateFiltered(bool toDown) {
|
||||
}
|
||||
}
|
||||
}
|
||||
rowsUpdated(rows, hrows, brows, ContextRows(), toDown);
|
||||
rowsUpdated(rows, hrows, brows, toDown);
|
||||
}
|
||||
|
||||
void MentionsDropdown::rowsUpdated(const MentionRows &mrows, const HashtagRows &hrows, const BotCommandRows &brows, const ContextRows &crows, bool toDown) {
|
||||
if (mrows.isEmpty() && hrows.isEmpty() && brows.isEmpty() && crows.isEmpty()) {
|
||||
void MentionsDropdown::rowsUpdated(const MentionRows &mrows, const HashtagRows &hrows, const BotCommandRows &brows, bool toDown) {
|
||||
if (mrows.isEmpty() && hrows.isEmpty() && brows.isEmpty()) {
|
||||
if (!isHidden()) {
|
||||
hideStart();
|
||||
}
|
||||
_mrows.clear();
|
||||
_hrows.clear();
|
||||
_brows.clear();
|
||||
_crows.clear();
|
||||
} else {
|
||||
_mrows = mrows;
|
||||
_hrows = hrows;
|
||||
_brows = brows;
|
||||
_crows = crows;
|
||||
bool hidden = _hiding || isHidden();
|
||||
if (hidden) {
|
||||
show();
|
||||
@ -3911,16 +3900,5 @@ bool MentionsDropdown::eventFilter(QObject *obj, QEvent *e) {
|
||||
return QWidget::eventFilter(obj, e);
|
||||
}
|
||||
|
||||
void MentionsDropdown::ui_repaintSavedGif(const LayoutSavedGif *layout) {
|
||||
}
|
||||
|
||||
bool MentionsDropdown::ui_isSavedGifVisible(const LayoutSavedGif *layout) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MentionsDropdown::ui_isGifBeingChosen() {
|
||||
return false;
|
||||
}
|
||||
|
||||
MentionsDropdown::~MentionsDropdown() {
|
||||
}
|
||||
|
@ -491,7 +491,7 @@ protected:
|
||||
|
||||
};
|
||||
|
||||
class EmojiPan : public TWidget {
|
||||
class EmojiPan : public TWidget, public RPCSender {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
@ -524,6 +524,9 @@ public:
|
||||
bool eventFilter(QObject *obj, QEvent *e);
|
||||
void stickersInstalled(uint64 setId);
|
||||
|
||||
void showContextResults(UserData *bot, QString query);
|
||||
void clearContextResults();
|
||||
|
||||
bool overlaps(const QRect &globalRect) {
|
||||
if (isHidden() || !_cache.isNull()) return false;
|
||||
|
||||
@ -563,6 +566,8 @@ public slots:
|
||||
void onSaveConfig();
|
||||
void onSaveConfigDelayed(int32 delay);
|
||||
|
||||
void onContextRequest();
|
||||
|
||||
signals:
|
||||
|
||||
void emojiSelected(EmojiPtr emoji);
|
||||
@ -633,12 +638,50 @@ private:
|
||||
|
||||
QTimer _saveConfigTimer;
|
||||
|
||||
// context bots
|
||||
struct ContextResult {
|
||||
ContextResult(uint64 queryId)
|
||||
: queryId(queryId)
|
||||
, doc(0)
|
||||
, photo(0)
|
||||
, width(0)
|
||||
, height(0)
|
||||
, duration(0)
|
||||
, noWebPage(false) {
|
||||
}
|
||||
uint64 queryId;
|
||||
QString id, type;
|
||||
DocumentData *doc;
|
||||
PhotoData *photo;
|
||||
QString title, description, url, thumb_url;
|
||||
QString content_type, content_url;
|
||||
int32 width, height, duration;
|
||||
|
||||
QString message; // botContextMessageText
|
||||
bool noWebPage;
|
||||
EntitiesInText entities;
|
||||
QString caption; // if message.isEmpty() use botContextMessageMediaAuto
|
||||
};
|
||||
struct ContextCacheEntry {
|
||||
QString nextOffset;
|
||||
QList<ContextResult> results;
|
||||
};
|
||||
typedef QMap<QString, ContextCacheEntry> ContextCache;
|
||||
ContextCache _contextCache;
|
||||
QTimer _contextRequestTimer;
|
||||
|
||||
void refreshContextRows(bool toDown);
|
||||
UserData *_contextBot;
|
||||
QString _contextQuery, _contextNextQuery, _contextNextOffset;
|
||||
mtpRequestId _contextRequestId;
|
||||
void contextResultsDone(const MTPmessages_BotResults &result);
|
||||
bool contextResultsFail(const RPCError &error);
|
||||
|
||||
};
|
||||
|
||||
typedef QList<UserData*> MentionRows;
|
||||
typedef QList<QString> HashtagRows;
|
||||
typedef QList<QPair<UserData*, const BotCommand*> > BotCommandRows;
|
||||
typedef QList<QString> ContextRows;
|
||||
|
||||
class MentionsDropdown;
|
||||
class MentionsInner : public TWidget {
|
||||
@ -646,7 +689,7 @@ class MentionsInner : public TWidget {
|
||||
|
||||
public:
|
||||
|
||||
MentionsInner(MentionsDropdown *parent, MentionRows *mrows, HashtagRows *hrows, BotCommandRows *brows, ContextRows *crows);
|
||||
MentionsInner(MentionsDropdown *parent, MentionRows *mrows, HashtagRows *hrows, BotCommandRows *brows);
|
||||
|
||||
void paintEvent(QPaintEvent *e);
|
||||
|
||||
@ -680,7 +723,6 @@ private:
|
||||
MentionRows *_mrows;
|
||||
HashtagRows *_hrows;
|
||||
BotCommandRows *_brows;
|
||||
ContextRows *_crows;
|
||||
int32 _sel;
|
||||
bool _mouseSel;
|
||||
QPoint _mousePos;
|
||||
@ -688,7 +730,7 @@ private:
|
||||
bool _overDelete;
|
||||
};
|
||||
|
||||
class MentionsDropdown : public TWidget, public RPCSender {
|
||||
class MentionsDropdown : public TWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
@ -700,7 +742,6 @@ public:
|
||||
void fastHide();
|
||||
|
||||
bool clearFilteredBotCommands();
|
||||
void showContextResults(UserData *bot, QString query);
|
||||
void showFiltered(PeerData *peer, QString start);
|
||||
void updateFiltered(bool toDown = false);
|
||||
void setBoundings(QRect boundings);
|
||||
@ -723,11 +764,6 @@ public:
|
||||
|
||||
return rect().contains(QRect(mapFromGlobal(globalRect.topLeft()), globalRect.size()));
|
||||
}
|
||||
void clearContextResults();
|
||||
|
||||
void ui_repaintSavedGif(const LayoutSavedGif *layout);
|
||||
bool ui_isSavedGifVisible(const LayoutSavedGif *layout);
|
||||
bool ui_isGifBeingChosen();
|
||||
|
||||
~MentionsDropdown();
|
||||
|
||||
@ -741,7 +777,6 @@ public slots:
|
||||
void hideFinish();
|
||||
|
||||
void showStart();
|
||||
void onContextRequest();
|
||||
|
||||
private:
|
||||
|
||||
@ -751,51 +786,12 @@ private:
|
||||
MentionRows _mrows;
|
||||
HashtagRows _hrows;
|
||||
BotCommandRows _brows;
|
||||
ContextRows _crows;
|
||||
|
||||
struct ContextResult {
|
||||
ContextResult(uint64 queryId)
|
||||
: queryId(queryId)
|
||||
, doc(0)
|
||||
, photo(0)
|
||||
, width(0)
|
||||
, height(0)
|
||||
, duration(0)
|
||||
, noWebPage(false) {
|
||||
}
|
||||
uint64 queryId;
|
||||
QString id, type;
|
||||
DocumentData *doc;
|
||||
PhotoData *photo;
|
||||
QString title, description, url, thumb_url;
|
||||
QString content_type, content_url;
|
||||
int32 width, height, duration;
|
||||
|
||||
QString message; // botContextMessageText
|
||||
bool noWebPage;
|
||||
EntitiesInText entities;
|
||||
QString caption; // if message.isEmpty() use botContextMessageMediaAuto
|
||||
};
|
||||
struct ContextCacheEntry {
|
||||
QString nextOffset;
|
||||
QList<ContextResult> results;
|
||||
};
|
||||
typedef QMap<QString, ContextCacheEntry> ContextCache;
|
||||
ContextCache _contextCache;
|
||||
QTimer _contextRequestTimer;
|
||||
|
||||
void refreshContextRows(bool toDown);
|
||||
void rowsUpdated(const MentionRows &rows, const HashtagRows &hrows, const BotCommandRows &brows, const ContextRows &crows, bool toDown);
|
||||
void rowsUpdated(const MentionRows &rows, const HashtagRows &hrows, const BotCommandRows &brows, bool toDown);
|
||||
|
||||
ScrollArea _scroll;
|
||||
MentionsInner _inner;
|
||||
|
||||
UserData *_contextBot;
|
||||
QString _contextQuery, _contextNextQuery, _contextNextOffset;
|
||||
mtpRequestId _contextRequestId;
|
||||
void contextResultsDone(const MTPmessages_BotResults &result);
|
||||
bool contextResultsFail(const RPCError &error);
|
||||
|
||||
ChatData *_chat;
|
||||
UserData *_user;
|
||||
ChannelData *_channel;
|
||||
|
@ -258,21 +258,21 @@ void FlatTextarea::getMentionHashtagBotCommandStart(QString &start, UserData *&c
|
||||
|
||||
// check context bot query
|
||||
const QString &text(getLastText());
|
||||
int32 size = text.size();
|
||||
int32 contextUsernameStart = 1, contextUsernameLength = 0, size = text.size();
|
||||
if (size > 2 && text.at(0) == '@' && text.at(1).isLetter()) {
|
||||
int32 usernameStart = 1, usernameLength = 1;
|
||||
for (int32 i = usernameStart + 1, l = text.size(); i < l; ++i) {
|
||||
contextUsernameLength = 1;
|
||||
for (int32 i = contextUsernameStart + 1, l = text.size(); i < l; ++i) {
|
||||
if (text.at(i).isLetterOrNumber() || text.at(i).unicode() == '_') {
|
||||
++usernameLength;
|
||||
++contextUsernameLength;
|
||||
continue;
|
||||
}
|
||||
if (!text.at(i).isSpace()) {
|
||||
usernameLength = 0;
|
||||
contextUsernameLength = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (usernameLength && usernameStart + usernameLength < text.size() && text.at(usernameStart + usernameLength).isSpace()) {
|
||||
QStringRef username = text.midRef(usernameStart, usernameLength);
|
||||
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);
|
||||
@ -291,14 +291,15 @@ void FlatTextarea::getMentionHashtagBotCommandStart(QString &start, UserData *&c
|
||||
if (contextBot && (!contextBot->botInfo || contextBot->botInfo->contextPlaceholder.isEmpty())) {
|
||||
contextBot = 0;
|
||||
} else {
|
||||
start = text.mid(usernameStart + usernameLength + 1);
|
||||
start = text.mid(contextUsernameStart + contextUsernameLength + 1);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
contextBot = 0;
|
||||
contextBotUsername = QString();
|
||||
}
|
||||
}
|
||||
if (!contextUsernameLength) {
|
||||
contextBot = 0;
|
||||
contextBotUsername = QString();
|
||||
}
|
||||
|
||||
// check mention / hashtag / bot command
|
||||
QTextDocument *doc(document());
|
||||
|
@ -5386,11 +5386,18 @@ void HistoryWebPage::draw(Painter &p, const HistoryItem *parent, const QRect &r,
|
||||
_data->photo->medium->load(false, false);
|
||||
bool full = _data->photo->medium->loaded();
|
||||
QPixmap pix;
|
||||
int32 pw = qMax(_pixw, int16(_lineHeight));
|
||||
int32 pw = qMax(_pixw, int16(_lineHeight)), ph = _pixh;
|
||||
int32 pixw = _pixw, pixh = articleThumbHeight(_data->photo, _pixw);
|
||||
int32 maxw = convertScale(_data->photo->medium->width()), maxh = convertScale(_data->photo->medium->height());
|
||||
if (pixw * ph != pixh * pw) {
|
||||
float64 coef = (pixw * ph > pixh * pw) ? qMin(ph / float64(pixh), maxh / float64(pixh)) : qMin(pw / float64(pixw), maxw / float64(pixw));
|
||||
pixh = qRound(pixh * coef);
|
||||
pixw = qRound(pixw * coef);
|
||||
}
|
||||
if (full) {
|
||||
pix = _data->photo->medium->pixSingle(_pixw, articleThumbHeight(_data->photo, _pixw), pw, _pixh);
|
||||
pix = _data->photo->medium->pixSingle(pixw, pixh, pw, ph);
|
||||
} else {
|
||||
pix = _data->photo->thumb->pixBlurredSingle(_pixw, articleThumbHeight(_data->photo, _pixw), pw, _pixh);
|
||||
pix = _data->photo->thumb->pixBlurredSingle(pixw, pixh, pw, ph);
|
||||
}
|
||||
p.drawPixmapLeft(lshift + width - pw, 0, _width, pix);
|
||||
if (selected) {
|
||||
|
@ -5327,17 +5327,22 @@ void HistoryWidget::onCheckMentionDropdown() {
|
||||
}
|
||||
|
||||
if (_contextBot) {
|
||||
_attachMention.showContextResults(_contextBot, start);
|
||||
} else if (!start.isEmpty()) {
|
||||
if (start.at(0) == '#' && cRecentWriteHashtags().isEmpty() && cRecentSearchHashtags().isEmpty()) Local::readRecentHashtags();
|
||||
if (start.at(0) == '@' && _peer->isUser()) return;
|
||||
if (start.at(0) == '/' && _peer->isUser() && !_peer->asUser()->botInfo) return;
|
||||
_attachMention.showFiltered(_peer, start);
|
||||
} else {
|
||||
_emojiPan.showContextResults(_contextBot, start);
|
||||
if (!_attachMention.isHidden()) {
|
||||
_attachMention.hideStart();
|
||||
}
|
||||
_attachMention.clearContextResults();
|
||||
} else {
|
||||
_emojiPan.clearContextResults();
|
||||
if (!start.isEmpty()) {
|
||||
if (start.at(0) == '#' && cRecentWriteHashtags().isEmpty() && cRecentSearchHashtags().isEmpty()) Local::readRecentHashtags();
|
||||
if (start.at(0) == '@' && _peer->isUser()) return;
|
||||
if (start.at(0) == '/' && _peer->isUser() && !_peer->asUser()->botInfo) return;
|
||||
_attachMention.showFiltered(_peer, start);
|
||||
} else {
|
||||
if (!_attachMention.isHidden()) {
|
||||
_attachMention.hideStart();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5770,11 +5775,11 @@ void HistoryWidget::ui_repaintSavedGif(const LayoutSavedGif *layout) {
|
||||
}
|
||||
|
||||
bool HistoryWidget::ui_isSavedGifVisible(const LayoutSavedGif *layout) {
|
||||
return _emojiPan.ui_isSavedGifVisible(layout) || _attachMention.ui_isSavedGifVisible(layout);
|
||||
return _emojiPan.ui_isSavedGifVisible(layout);
|
||||
}
|
||||
|
||||
bool HistoryWidget::ui_isGifBeingChosen() {
|
||||
return _emojiPan.ui_isGifBeingChosen() || _attachMention.ui_isGifBeingChosen();
|
||||
return _emojiPan.ui_isGifBeingChosen();
|
||||
}
|
||||
|
||||
void HistoryWidget::notify_historyItemLayoutChanged(const HistoryItem *item) {
|
||||
|
Loading…
Reference in New Issue
Block a user