From 5e1b8212b2769a776bbe9065cf445fbaea685eb7 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 20 Nov 2018 17:34:07 +0400 Subject: [PATCH] Show tsfname in occupied chats. --- .../SourceFiles/dialogs/dialogs_layout.cpp | 6 +- .../view/history_view_top_bar_widget.cpp | 17 +--- .../SourceFiles/support/support_helper.cpp | 97 +++++++++++++++---- Telegram/SourceFiles/support/support_helper.h | 14 ++- 4 files changed, 97 insertions(+), 37 deletions(-) diff --git a/Telegram/SourceFiles/dialogs/dialogs_layout.cpp b/Telegram/SourceFiles/dialogs/dialogs_layout.cpp index 0d9a07fd0..c1ac9b489 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_layout.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_layout.cpp @@ -256,7 +256,9 @@ void paintRow( auto texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip; - if (draft || (supportMode && Support::IsOccupiedBySomeone(history))) { + if (draft + || (supportMode + && Auth().supportHelper().isOccupiedBySomeone(history))) { if (!promoted) { paintRowDate(p, date, rectForName, active, selected); } @@ -274,7 +276,7 @@ void paintRow( if (history->cloudDraftTextCache.isEmpty()) { auto draftWrapped = textcmdLink(1, lng_dialogs_text_from_wrapped(lt_from, lang(lng_from_draft))); auto draftText = supportMode - ? textcmdLink(1, Support::ChatOccupiedString()) + ? textcmdLink(1, Support::ChatOccupiedString(history)) : lng_dialogs_text_with_from(lt_from_part, draftWrapped, lt_message, TextUtilities::Clean(draft->textWithTags.text)); history->cloudDraftTextCache.setText(st::dialogsTextStyle, draftText, Ui::DialogTextOptions()); } diff --git a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp index 0aeb8d402..372664422 100644 --- a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp @@ -106,8 +106,7 @@ TopBarWidget::TopBarWidget( using UpdateFlag = Notify::PeerUpdate::Flag; auto flags = UpdateFlag::UserHasCalls | UpdateFlag::UserOnlineChanged - | UpdateFlag::MembersChanged - | UpdateFlag::OccupiedChanged; + | UpdateFlag::MembersChanged; subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(flags, [this](const Notify::PeerUpdate &update) { if (update.flags & UpdateFlag::UserHasCalls) { if (update.peer->isUser()) { @@ -334,8 +333,7 @@ void TopBarWidget::paintTopBar(Painter &p, TimeMs ms) { p.setFont(st::dialogsTextFont); if (paintConnectingState(p, nameleft, statustop, width(), ms)) { return; - } else if (!Support::IsOccupiedBySomeone(history) - && history->paintSendAction( + } else if (history->paintSendAction( p, nameleft, statustop, @@ -383,11 +381,7 @@ void TopBarWidget::paintStatus( int top, int availableWidth, int outerWidth) { - const auto occupied = Auth().supportMode() - && Support::IsOccupiedBySomeone(_activeChat.history()); - p.setPen(occupied - ? st::dialogsTextPaletteDraft.linkFg - : _titlePeerTextOnline + p.setPen(_titlePeerTextOnline ? st::historyStatusFgActive : st::historyStatusFg); _titlePeerText.drawLeftElided(p, left, top, availableWidth, outerWidth); @@ -744,10 +738,7 @@ void TopBarWidget::updateOnlineDisplay() { QString text; const auto now = unixtime(); bool titlePeerTextOnline = false; - if (Auth().supportMode() - && Support::IsOccupiedBySomeone(_activeChat.history())) { - text = Support::ChatOccupiedString(); - } else if (const auto user = _activeChat.peer()->asUser()) { + if (const auto user = _activeChat.peer()->asUser()) { text = Data::OnlineText(user, now); titlePeerTextOnline = Data::OnlineTextActive(user, now); } else if (const auto chat = _activeChat.peer()->asChat()) { diff --git a/Telegram/SourceFiles/support/support_helper.cpp b/Telegram/SourceFiles/support/support_helper.cpp index bca761df4..dca95c4aa 100644 --- a/Telegram/SourceFiles/support/support_helper.cpp +++ b/Telegram/SourceFiles/support/support_helper.cpp @@ -25,13 +25,19 @@ uint32 OccupationTag() { return uint32(Sandbox::UserTag() & 0xFFFFFFFFU); } -Data::Draft OccupiedDraft() { +QString NormalizeName(QString name) { + return name.replace(':', '_').replace(';', '_'); +} + +Data::Draft OccupiedDraft(const QString &normalizedName) { const auto now = unixtime(), till = now + kOccupyFor; return { TextWithTags{ "t:" + QString::number(till) + ";u:" - + QString::number(OccupationTag()) }, + + QString::number(OccupationTag()) + + ";n:" + + normalizedName }, MsgId(0), MessageCursor(), false @@ -68,6 +74,36 @@ uint32 ParseOccupationTag(History *history) { return valid ? result : 0; } +QString ParseOccupationName(History *history) { + if (!history) { + return QString(); + } + const auto draft = history->cloudDraft(); + if (!draft) { + return QString(); + } + const auto &text = draft->textWithTags.text; +#ifndef OS_MAC_OLD + const auto parts = text.splitRef(';'); +#else // OS_MAC_OLD + const auto parts = text.split(';'); +#endif // OS_MAC_OLD + auto valid = false; + auto result = QString(); + for (const auto &part : parts) { + if (part.startsWith(qstr("t:"))) { + if (part.mid(2).toInt() >= unixtime()) { + valid = true; + } else { + return 0; + } + } else if (part.startsWith(qstr("n:"))) { + result = part.mid(2).toString(); + } + } + return valid ? result : QString(); +} + TimeId OccupiedBySomeoneTill(History *history) { if (!history) { return 0; @@ -109,6 +145,15 @@ Helper::Helper(not_null session) , _templates(_session) , _reoccupyTimer([=] { reoccupy(); }) , _checkOccupiedTimer([=] { checkOccupiedChats(); }) { + request(MTPhelp_GetSupportName( + )).done([=](const MTPhelp_SupportName &result) { + result.match([&](const MTPDhelp_supportName &data) { + setSupportName(qs(data.vname)); + }); + }).fail([=](const RPCError &error) { + setSupportName( + qsl("[rand^") + QString::number(Sandbox::UserTag()) + ']'); + }).send(); } void Helper::registerWindow(not_null controller) { @@ -126,9 +171,7 @@ void Helper::cloudDraftChanged(not_null history) { if (history != _occupiedHistory) { return; } - if (!IsOccupiedByMe(_occupiedHistory)) { - occupyInDraft(); - } + occupyIfNotYet(); } void Helper::chatOccupiedUpdated(not_null history) { @@ -170,7 +213,7 @@ void Helper::checkOccupiedChats() { void Helper::updateOccupiedHistory( not_null controller, History *history) { - if (IsOccupiedByMe(_occupiedHistory)) { + if (isOccupiedByMe(_occupiedHistory)) { _occupiedHistory->clearCloudDraft(); _session->api().saveDraftToCloudDelayed(_occupiedHistory); } @@ -178,9 +221,23 @@ void Helper::updateOccupiedHistory( occupyInDraft(); } +void Helper::setSupportName(const QString &name) { + _supportName = name; + _supportNameNormalized = NormalizeName(name); + occupyIfNotYet(); +} + +void Helper::occupyIfNotYet() { + if (!isOccupiedByMe(_occupiedHistory)) { + occupyInDraft(); + } +} + void Helper::occupyInDraft() { - if (_occupiedHistory && !IsOccupiedBySomeone(_occupiedHistory)) { - const auto draft = OccupiedDraft(); + if (_occupiedHistory + && !isOccupiedBySomeone(_occupiedHistory) + && !_supportName.isEmpty()) { + const auto draft = OccupiedDraft(_supportNameNormalized); _occupiedHistory->createCloudDraft(&draft); _session->api().saveDraftToCloudDelayed(_occupiedHistory); _reoccupyTimer.callEach(kReoccupyEach); @@ -188,33 +245,37 @@ void Helper::occupyInDraft() { } void Helper::reoccupy() { - if (IsOccupiedByMe(_occupiedHistory)) { - const auto draft = OccupiedDraft(); + if (isOccupiedByMe(_occupiedHistory)) { + const auto draft = OccupiedDraft(_supportNameNormalized); _occupiedHistory->createCloudDraft(&draft); _session->api().saveDraftToCloudDelayed(_occupiedHistory); } } -Templates &Helper::templates() { - return _templates; -} - -bool IsOccupiedByMe(History *history) { +bool Helper::isOccupiedByMe(History *history) const { if (const auto tag = ParseOccupationTag(history)) { return (tag == OccupationTag()); } return false; } -bool IsOccupiedBySomeone(History *history) { +bool Helper::isOccupiedBySomeone(History *history) const { if (const auto tag = ParseOccupationTag(history)) { return (tag != OccupationTag()); } return false; } -QString ChatOccupiedString() { - return QString::fromUtf8("\xe2\x9c\x8b\xef\xb8\x8f chat taken"); +Templates &Helper::templates() { + return _templates; +} + +QString ChatOccupiedString(not_null history) { + const auto hand = QString::fromUtf8("\xe2\x9c\x8b\xef\xb8\x8f"); + const auto name = ParseOccupationName(history); + return (name.isEmpty() || name.startsWith(qstr("[rand^"))) + ? hand + " chat taken" + : hand + ' ' + name + " is here"; } } // namespace Support diff --git a/Telegram/SourceFiles/support/support_helper.h b/Telegram/SourceFiles/support/support_helper.h index 89f29b4db..5f09c6e85 100644 --- a/Telegram/SourceFiles/support/support_helper.h +++ b/Telegram/SourceFiles/support/support_helper.h @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/timer.h" #include "support/support_templates.h" +#include "mtproto/sender.h" class AuthSession; @@ -18,7 +19,7 @@ class Controller; namespace Support { -class Helper { +class Helper : private MTP::Sender { public: explicit Helper(not_null session); @@ -27,6 +28,9 @@ public: void chatOccupiedUpdated(not_null history); + bool isOccupiedByMe(History *history) const; + bool isOccupiedBySomeone(History *history) const; + Templates &templates(); private: @@ -34,11 +38,15 @@ private: void updateOccupiedHistory( not_null controller, History *history); + void setSupportName(const QString &name); + void occupyIfNotYet(); void occupyInDraft(); void reoccupy(); not_null _session; Templates _templates; + QString _supportName; + QString _supportNameNormalized; History *_occupiedHistory = nullptr; base::Timer _reoccupyTimer; @@ -49,8 +57,6 @@ private: }; -bool IsOccupiedByMe(History *history); -bool IsOccupiedBySomeone(History *history); -QString ChatOccupiedString(); +QString ChatOccupiedString(not_null history); } // namespace Support