From 820339d390338762dcdc21969c1f350dadf4ae6c Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 29 Dec 2015 01:06:27 +0300 Subject: [PATCH] context bot resolve done --- Telegram/SourceFiles/app.cpp | 5 +-- Telegram/SourceFiles/app.h | 5 +-- Telegram/SourceFiles/dropdown.cpp | 4 +++ Telegram/SourceFiles/dropdown.h | 1 + Telegram/SourceFiles/gui/flattextarea.cpp | 27 ++++++++++----- Telegram/SourceFiles/gui/flattextarea.h | 2 +- Telegram/SourceFiles/historywidget.cpp | 42 +++++++++++++++++++++-- Telegram/SourceFiles/historywidget.h | 3 ++ Telegram/SourceFiles/structs.h | 3 +- 9 files changed, 74 insertions(+), 18 deletions(-) diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index 2957fe5ad..9f58b9cb3 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -424,6 +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(); } else { data->setBotInfoVersion(-1); } @@ -1430,8 +1431,8 @@ namespace App { return ::self; } - PeerData *peerByName(const QStringRef &username) { - QStringRef uname(username.trimmed()); + PeerData *peerByName(const QString &username) { + QString uname(username.trimmed()); for (PeersData::const_iterator i = peersData.cbegin(), e = peersData.cend(); i != e; ++i) { if (!i.value()->userName().compare(uname, Qt::CaseInsensitive)) { return i.value()->asUser(); diff --git a/Telegram/SourceFiles/app.h b/Telegram/SourceFiles/app.h index 3c6cab29e..628858734 100644 --- a/Telegram/SourceFiles/app.h +++ b/Telegram/SourceFiles/app.h @@ -132,10 +132,7 @@ namespace App { ChatData *chat(int32 chat_id); ChannelData *channel(int32 channel_id); UserData *self(); - PeerData *peerByName(const QStringRef &username); - inline PeerData *peerByName(const QString &username) { - return peerByName(username.midRef(0)); - } + PeerData *peerByName(const QString &username); QString peerName(const PeerData *peer, bool forDialogs = false); PhotoData *photo(const PhotoId &photo); PhotoData *photoSet(const PhotoId &photo, PhotoData *convert, const uint64 &access, int32 date, const ImagePtr &thumb, const ImagePtr &medium, const ImagePtr &full); diff --git a/Telegram/SourceFiles/dropdown.cpp b/Telegram/SourceFiles/dropdown.cpp index 50f6efafd..2d0cae199 100644 --- a/Telegram/SourceFiles/dropdown.cpp +++ b/Telegram/SourceFiles/dropdown.cpp @@ -3457,6 +3457,10 @@ void MentionsDropdown::paintEvent(QPaintEvent *e) { } +void MentionsDropdown::showContextResults(UserData *bot, QString query) { + +} + void MentionsDropdown::showFiltered(PeerData *peer, QString start) { _chat = peer->asChat(); _user = peer->asUser(); diff --git a/Telegram/SourceFiles/dropdown.h b/Telegram/SourceFiles/dropdown.h index fc69d249d..d6baf235d 100644 --- a/Telegram/SourceFiles/dropdown.h +++ b/Telegram/SourceFiles/dropdown.h @@ -698,6 +698,7 @@ public: void fastHide(); bool clearFilteredCommands(); + void showContextResults(UserData *bot, QString query); void showFiltered(PeerData *peer, QString start); void updateFiltered(bool toDown = false); void setBoundings(QRect boundings); diff --git a/Telegram/SourceFiles/gui/flattextarea.cpp b/Telegram/SourceFiles/gui/flattextarea.cpp index 04af02cb2..f1719ad63 100644 --- a/Telegram/SourceFiles/gui/flattextarea.cpp +++ b/Telegram/SourceFiles/gui/flattextarea.cpp @@ -252,7 +252,7 @@ EmojiPtr FlatTextarea::getSingleEmoji() const { return 0; } -void FlatTextarea::getMentionHashtagBotCommandStart(QString &start, UserData *&contextBot, QString &lookedUpUsername) const { +void FlatTextarea::getMentionHashtagBotCommandStart(QString &start, UserData *&contextBot, QString &contextBotUsername) const { int32 pos = textCursor().position(); if (textCursor().anchor() != pos) return; @@ -272,19 +272,30 @@ void FlatTextarea::getMentionHashtagBotCommandStart(QString &start, UserData *&c break; } if (usernameLength) { - UserData *bot = 0; - if (contextBot && !contextBot->username.compare(text.midRef(1, usernameLength))) { - bot = contextBot; - } else { - PeerData *peer = App::peerByName(text.midRef(1, usernameLength)); + QStringRef username = text.midRef(1, usernameLength); + if (username != contextBotUsername) { + contextBotUsername = username.toString(); + PeerData *peer = App::peerByName(contextBotUsername); if (peer) { if (peer->isUser()) { - bot = peer->asUser(); + contextBot = peer->asUser(); } else { - + contextBot = 0; } + } else { + contextBot = ContextBotLookingUpData; } } + if (contextBot == ContextBotLookingUpData) return; + + if (contextBot && (!contextBot->botInfo || contextBot->botInfo->contextPlaceholder.isEmpty())) { + contextBot = 0; + } else { + start = text.mid(usernameStart + usernameLength + 1); + } + } else { + contextBot = 0; + contextBotUsername = QString(); } } diff --git a/Telegram/SourceFiles/gui/flattextarea.h b/Telegram/SourceFiles/gui/flattextarea.h index 9cdf10201..f24bba43b 100644 --- a/Telegram/SourceFiles/gui/flattextarea.h +++ b/Telegram/SourceFiles/gui/flattextarea.h @@ -63,7 +63,7 @@ public: QSize minimumSizeHint() const; EmojiPtr getSingleEmoji() const; - void getMentionHashtagBotCommandStart(QString &start, UserData *&contextBot, QString &lookedUpUsername) const; + void getMentionHashtagBotCommandStart(QString &start, UserData *&contextBot, QString &contextBotUsername) const; void removeSingleEmoji(); bool hasText() const; diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 08d9a4a08..5bd79eb91 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -2630,6 +2630,8 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent) , _toHistoryEnd(this, st::historyToEnd) , _collapseComments(this) , _attachMention(this) +, _contextBot(0) +, _contextBotResolveRequestId(0) , _reportSpamPanel(this) , _send(this, lang(lng_send_button), st::btnSend) , _unblock(this, lang(lng_unblock_button), st::btnUnblock) @@ -4946,6 +4948,27 @@ 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; + 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); + } + } + checkMentionDropdown(); +} + +bool HistoryWidget::contextBotResolveFail(const RPCError &error) { + if (mtpIsFlood(error)) return false; + _contextBot = 0; + checkMentionDropdown(); + return true; +} + bool HistoryWidget::isBotStart() const { if (!_peer || !_peer->isUser() || !_peer->asUser()->botInfo || !_canSendMessages) return false; return !_peer->asUser()->botInfo->startToken.isEmpty() || (_history->isEmpty() && !_history->lastMsg); @@ -5287,9 +5310,24 @@ void HistoryWidget::onFieldFocused() { void HistoryWidget::checkMentionDropdown() { if (!_history || _a_show.animating()) return; - QString start; + QString start, contextBotUsername(_contextBotUsername); _field.getMentionHashtagBotCommandStart(start, _contextBot, _contextBotUsername); - if (!start.isEmpty()) { + if (contextBotUsername != _contextBotUsername) { + if (_contextBotResolveRequestId) { + MTP::cancel(_contextBotResolveRequestId); + _contextBotResolveRequestId = 0; + } + if (_contextBot == ContextBotLookingUpData) { + _contextBotResolveRequestId = MTP::send(MTPcontacts_ResolveUsername(MTP_string(_contextBotUsername)), rpcDone(&HistoryWidget::contextBotResolveDone), rpcFail(&HistoryWidget::contextBotResolveFail)); + return; + } + } else if (_contextBot == ContextBotLookingUpData) { + return; + } + + 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; diff --git a/Telegram/SourceFiles/historywidget.h b/Telegram/SourceFiles/historywidget.h index 6a4b4a332..9f3afe30c 100644 --- a/Telegram/SourceFiles/historywidget.h +++ b/Telegram/SourceFiles/historywidget.h @@ -763,6 +763,9 @@ private: MentionsDropdown _attachMention; UserData *_contextBot; QString _contextBotUsername; + mtpRequestId _contextBotResolveRequestId; + void contextBotResolveDone(const MTPcontacts_ResolvedPeer &result); + bool contextBotResolveFail(const RPCError &error); bool isBotStart() const; bool isBlocked() const; diff --git a/Telegram/SourceFiles/structs.h b/Telegram/SourceFiles/structs.h index fa9d14905..5902cfcda 100644 --- a/Telegram/SourceFiles/structs.h +++ b/Telegram/SourceFiles/structs.h @@ -327,7 +327,7 @@ struct BotInfo { bool inited; bool readsAllHistory, cantJoinGroups; int32 version; - QString shareText, description; + QString shareText, description, contextPlaceholder; QList commands; Text text; // description @@ -385,6 +385,7 @@ public: BotInfo *botInfo; }; +static UserData * const ContextBotLookingUpData = reinterpret_cast(&SharedMemoryLocation0); class ChatData : public PeerData { public: