Show tsfname in occupied chats.

This commit is contained in:
John Preston 2018-11-20 17:34:07 +04:00
parent 7ca821f38c
commit 5e1b8212b2
4 changed files with 97 additions and 37 deletions

View File

@ -256,7 +256,9 @@ void paintRow(
auto texttop = st::dialogsPadding.y() auto texttop = st::dialogsPadding.y()
+ st::msgNameFont->height + st::msgNameFont->height
+ st::dialogsSkip; + st::dialogsSkip;
if (draft || (supportMode && Support::IsOccupiedBySomeone(history))) { if (draft
|| (supportMode
&& Auth().supportHelper().isOccupiedBySomeone(history))) {
if (!promoted) { if (!promoted) {
paintRowDate(p, date, rectForName, active, selected); paintRowDate(p, date, rectForName, active, selected);
} }
@ -274,7 +276,7 @@ void paintRow(
if (history->cloudDraftTextCache.isEmpty()) { if (history->cloudDraftTextCache.isEmpty()) {
auto draftWrapped = textcmdLink(1, lng_dialogs_text_from_wrapped(lt_from, lang(lng_from_draft))); auto draftWrapped = textcmdLink(1, lng_dialogs_text_from_wrapped(lt_from, lang(lng_from_draft)));
auto draftText = supportMode 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)); : lng_dialogs_text_with_from(lt_from_part, draftWrapped, lt_message, TextUtilities::Clean(draft->textWithTags.text));
history->cloudDraftTextCache.setText(st::dialogsTextStyle, draftText, Ui::DialogTextOptions()); history->cloudDraftTextCache.setText(st::dialogsTextStyle, draftText, Ui::DialogTextOptions());
} }

View File

@ -106,8 +106,7 @@ TopBarWidget::TopBarWidget(
using UpdateFlag = Notify::PeerUpdate::Flag; using UpdateFlag = Notify::PeerUpdate::Flag;
auto flags = UpdateFlag::UserHasCalls auto flags = UpdateFlag::UserHasCalls
| UpdateFlag::UserOnlineChanged | UpdateFlag::UserOnlineChanged
| UpdateFlag::MembersChanged | UpdateFlag::MembersChanged;
| UpdateFlag::OccupiedChanged;
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(flags, [this](const Notify::PeerUpdate &update) { subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(flags, [this](const Notify::PeerUpdate &update) {
if (update.flags & UpdateFlag::UserHasCalls) { if (update.flags & UpdateFlag::UserHasCalls) {
if (update.peer->isUser()) { if (update.peer->isUser()) {
@ -334,8 +333,7 @@ void TopBarWidget::paintTopBar(Painter &p, TimeMs ms) {
p.setFont(st::dialogsTextFont); p.setFont(st::dialogsTextFont);
if (paintConnectingState(p, nameleft, statustop, width(), ms)) { if (paintConnectingState(p, nameleft, statustop, width(), ms)) {
return; return;
} else if (!Support::IsOccupiedBySomeone(history) } else if (history->paintSendAction(
&& history->paintSendAction(
p, p,
nameleft, nameleft,
statustop, statustop,
@ -383,11 +381,7 @@ void TopBarWidget::paintStatus(
int top, int top,
int availableWidth, int availableWidth,
int outerWidth) { int outerWidth) {
const auto occupied = Auth().supportMode() p.setPen(_titlePeerTextOnline
&& Support::IsOccupiedBySomeone(_activeChat.history());
p.setPen(occupied
? st::dialogsTextPaletteDraft.linkFg
: _titlePeerTextOnline
? st::historyStatusFgActive ? st::historyStatusFgActive
: st::historyStatusFg); : st::historyStatusFg);
_titlePeerText.drawLeftElided(p, left, top, availableWidth, outerWidth); _titlePeerText.drawLeftElided(p, left, top, availableWidth, outerWidth);
@ -744,10 +738,7 @@ void TopBarWidget::updateOnlineDisplay() {
QString text; QString text;
const auto now = unixtime(); const auto now = unixtime();
bool titlePeerTextOnline = false; bool titlePeerTextOnline = false;
if (Auth().supportMode() if (const auto user = _activeChat.peer()->asUser()) {
&& Support::IsOccupiedBySomeone(_activeChat.history())) {
text = Support::ChatOccupiedString();
} else if (const auto user = _activeChat.peer()->asUser()) {
text = Data::OnlineText(user, now); text = Data::OnlineText(user, now);
titlePeerTextOnline = Data::OnlineTextActive(user, now); titlePeerTextOnline = Data::OnlineTextActive(user, now);
} else if (const auto chat = _activeChat.peer()->asChat()) { } else if (const auto chat = _activeChat.peer()->asChat()) {

View File

@ -25,13 +25,19 @@ uint32 OccupationTag() {
return uint32(Sandbox::UserTag() & 0xFFFFFFFFU); 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; const auto now = unixtime(), till = now + kOccupyFor;
return { return {
TextWithTags{ "t:" TextWithTags{ "t:"
+ QString::number(till) + QString::number(till)
+ ";u:" + ";u:"
+ QString::number(OccupationTag()) }, + QString::number(OccupationTag())
+ ";n:"
+ normalizedName },
MsgId(0), MsgId(0),
MessageCursor(), MessageCursor(),
false false
@ -68,6 +74,36 @@ uint32 ParseOccupationTag(History *history) {
return valid ? result : 0; 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) { TimeId OccupiedBySomeoneTill(History *history) {
if (!history) { if (!history) {
return 0; return 0;
@ -109,6 +145,15 @@ Helper::Helper(not_null<AuthSession*> session)
, _templates(_session) , _templates(_session)
, _reoccupyTimer([=] { reoccupy(); }) , _reoccupyTimer([=] { reoccupy(); })
, _checkOccupiedTimer([=] { checkOccupiedChats(); }) { , _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<Window::Controller*> controller) { void Helper::registerWindow(not_null<Window::Controller*> controller) {
@ -126,9 +171,7 @@ void Helper::cloudDraftChanged(not_null<History*> history) {
if (history != _occupiedHistory) { if (history != _occupiedHistory) {
return; return;
} }
if (!IsOccupiedByMe(_occupiedHistory)) { occupyIfNotYet();
occupyInDraft();
}
} }
void Helper::chatOccupiedUpdated(not_null<History*> history) { void Helper::chatOccupiedUpdated(not_null<History*> history) {
@ -170,7 +213,7 @@ void Helper::checkOccupiedChats() {
void Helper::updateOccupiedHistory( void Helper::updateOccupiedHistory(
not_null<Window::Controller*> controller, not_null<Window::Controller*> controller,
History *history) { History *history) {
if (IsOccupiedByMe(_occupiedHistory)) { if (isOccupiedByMe(_occupiedHistory)) {
_occupiedHistory->clearCloudDraft(); _occupiedHistory->clearCloudDraft();
_session->api().saveDraftToCloudDelayed(_occupiedHistory); _session->api().saveDraftToCloudDelayed(_occupiedHistory);
} }
@ -178,9 +221,23 @@ void Helper::updateOccupiedHistory(
occupyInDraft(); occupyInDraft();
} }
void Helper::setSupportName(const QString &name) {
_supportName = name;
_supportNameNormalized = NormalizeName(name);
occupyIfNotYet();
}
void Helper::occupyIfNotYet() {
if (!isOccupiedByMe(_occupiedHistory)) {
occupyInDraft();
}
}
void Helper::occupyInDraft() { void Helper::occupyInDraft() {
if (_occupiedHistory && !IsOccupiedBySomeone(_occupiedHistory)) { if (_occupiedHistory
const auto draft = OccupiedDraft(); && !isOccupiedBySomeone(_occupiedHistory)
&& !_supportName.isEmpty()) {
const auto draft = OccupiedDraft(_supportNameNormalized);
_occupiedHistory->createCloudDraft(&draft); _occupiedHistory->createCloudDraft(&draft);
_session->api().saveDraftToCloudDelayed(_occupiedHistory); _session->api().saveDraftToCloudDelayed(_occupiedHistory);
_reoccupyTimer.callEach(kReoccupyEach); _reoccupyTimer.callEach(kReoccupyEach);
@ -188,33 +245,37 @@ void Helper::occupyInDraft() {
} }
void Helper::reoccupy() { void Helper::reoccupy() {
if (IsOccupiedByMe(_occupiedHistory)) { if (isOccupiedByMe(_occupiedHistory)) {
const auto draft = OccupiedDraft(); const auto draft = OccupiedDraft(_supportNameNormalized);
_occupiedHistory->createCloudDraft(&draft); _occupiedHistory->createCloudDraft(&draft);
_session->api().saveDraftToCloudDelayed(_occupiedHistory); _session->api().saveDraftToCloudDelayed(_occupiedHistory);
} }
} }
Templates &Helper::templates() { bool Helper::isOccupiedByMe(History *history) const {
return _templates;
}
bool IsOccupiedByMe(History *history) {
if (const auto tag = ParseOccupationTag(history)) { if (const auto tag = ParseOccupationTag(history)) {
return (tag == OccupationTag()); return (tag == OccupationTag());
} }
return false; return false;
} }
bool IsOccupiedBySomeone(History *history) { bool Helper::isOccupiedBySomeone(History *history) const {
if (const auto tag = ParseOccupationTag(history)) { if (const auto tag = ParseOccupationTag(history)) {
return (tag != OccupationTag()); return (tag != OccupationTag());
} }
return false; return false;
} }
QString ChatOccupiedString() { Templates &Helper::templates() {
return QString::fromUtf8("\xe2\x9c\x8b\xef\xb8\x8f chat taken"); return _templates;
}
QString ChatOccupiedString(not_null<History*> 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 } // namespace Support

View File

@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/timer.h" #include "base/timer.h"
#include "support/support_templates.h" #include "support/support_templates.h"
#include "mtproto/sender.h"
class AuthSession; class AuthSession;
@ -18,7 +19,7 @@ class Controller;
namespace Support { namespace Support {
class Helper { class Helper : private MTP::Sender {
public: public:
explicit Helper(not_null<AuthSession*> session); explicit Helper(not_null<AuthSession*> session);
@ -27,6 +28,9 @@ public:
void chatOccupiedUpdated(not_null<History*> history); void chatOccupiedUpdated(not_null<History*> history);
bool isOccupiedByMe(History *history) const;
bool isOccupiedBySomeone(History *history) const;
Templates &templates(); Templates &templates();
private: private:
@ -34,11 +38,15 @@ private:
void updateOccupiedHistory( void updateOccupiedHistory(
not_null<Window::Controller*> controller, not_null<Window::Controller*> controller,
History *history); History *history);
void setSupportName(const QString &name);
void occupyIfNotYet();
void occupyInDraft(); void occupyInDraft();
void reoccupy(); void reoccupy();
not_null<AuthSession*> _session; not_null<AuthSession*> _session;
Templates _templates; Templates _templates;
QString _supportName;
QString _supportNameNormalized;
History *_occupiedHistory = nullptr; History *_occupiedHistory = nullptr;
base::Timer _reoccupyTimer; base::Timer _reoccupyTimer;
@ -49,8 +57,6 @@ private:
}; };
bool IsOccupiedByMe(History *history); QString ChatOccupiedString(not_null<History*> history);
bool IsOccupiedBySomeone(History *history);
QString ChatOccupiedString();
} // namespace Support } // namespace Support