Move online phrase code from app module.

Also fix possible assertion violation in online change timeout.
This commit is contained in:
John Preston 2017-12-17 12:13:26 +04:00
parent b3a723c871
commit 712b3f481c
14 changed files with 265 additions and 186 deletions

View File

@ -128,7 +128,8 @@ namespace {
LastPhotosList lastPhotos; LastPhotosList lastPhotos;
using LastPhotosMap = QHash<PhotoData*, LastPhotosList::iterator>; using LastPhotosMap = QHash<PhotoData*, LastPhotosList::iterator>;
LastPhotosMap lastPhotosMap; LastPhotosMap lastPhotosMap;
}
} // namespace
namespace App { namespace App {
@ -219,117 +220,6 @@ namespace {
} }
} }
TimeId onlineForSort(UserData *user, TimeId now) {
if (isServiceUser(user->id) || user->botInfo) {
return -1;
}
TimeId online = user->onlineTill;
if (online <= 0) {
switch (online) {
case 0:
case -1: return online;
case -2: {
QDate yesterday(date(now).date());
return int32(QDateTime(yesterday.addDays(-3)).toTime_t()) + (unixtime() - myunixtime());
} break;
case -3: {
QDate weekago(date(now).date());
return int32(QDateTime(weekago.addDays(-7)).toTime_t()) + (unixtime() - myunixtime());
} break;
case -4: {
QDate monthago(date(now).date());
return int32(QDateTime(monthago.addDays(-30)).toTime_t()) + (unixtime() - myunixtime());
} break;
}
return -online;
}
return online;
}
int32 onlineWillChangeIn(UserData *user, TimeId now) {
if (isServiceUser(user->id) || user->botInfo) {
return 86400;
}
return onlineWillChangeIn(user->onlineTill, now);
}
int32 onlineWillChangeIn(TimeId online, TimeId now) {
if (online <= 0) {
if (-online > now) return std::max(-online - now, 86400);
return 86400;
}
if (online > now) {
return std::max(online - now, 86400);
}
int32 minutes = (now - online) / 60;
if (minutes < 60) {
return (minutes + 1) * 60 - (now - online);
}
int32 hours = (now - online) / 3600;
if (hours < 12) {
return (hours + 1) * 3600 - (now - online);
}
QDateTime dNow(date(now)), dTomorrow(dNow.date().addDays(1));
return std::max(dNow.secsTo(dTomorrow), 86400LL);
}
QString onlineText(UserData *user, TimeId now, bool precise) {
if (isNotificationsUser(user->id)) {
return lang(lng_status_service_notifications);
} else if (user->botInfo) {
return lang(lng_status_bot);
} else if (isServiceUser(user->id)) {
return lang(lng_status_support);
}
return onlineText(user->onlineTill, now, precise);
}
QString onlineText(TimeId online, TimeId now, bool precise) {
if (online <= 0) {
switch (online) {
case 0:
case -1: return lang(lng_status_offline);
case -2: return lang(lng_status_recently);
case -3: return lang(lng_status_last_week);
case -4: return lang(lng_status_last_month);
}
return (-online > now) ? lang(lng_status_online) : lang(lng_status_recently);
}
if (online > now) {
return lang(lng_status_online);
}
QString when;
if (precise) {
QDateTime dOnline(date(online)), dNow(date(now));
if (dOnline.date() == dNow.date()) {
return lng_status_lastseen_today(lt_time, dOnline.time().toString(cTimeFormat()));
} else if (dOnline.date().addDays(1) == dNow.date()) {
return lng_status_lastseen_yesterday(lt_time, dOnline.time().toString(cTimeFormat()));
}
return lng_status_lastseen_date_time(lt_date, dOnline.date().toString(qsl("dd.MM.yy")), lt_time, dOnline.time().toString(cTimeFormat()));
}
int32 minutes = (now - online) / 60;
if (!minutes) {
return lang(lng_status_lastseen_now);
} else if (minutes < 60) {
return lng_status_lastseen_minutes(lt_count, minutes);
}
int32 hours = (now - online) / 3600;
if (hours < 12) {
return lng_status_lastseen_hours(lt_count, hours);
}
QDateTime dOnline(date(online)), dNow(date(now));
if (dOnline.date() == dNow.date()) {
return lng_status_lastseen_today(lt_time, dOnline.time().toString(cTimeFormat()));
} else if (dOnline.date().addDays(1) == dNow.date()) {
return lng_status_lastseen_yesterday(lt_time, dOnline.time().toString(cTimeFormat()));
}
return lng_status_lastseen_date(lt_date, dOnline.date().toString(qsl("dd.MM.yy")));
}
namespace { namespace {
// we should get a full restriction in "{fulltype}: {reason}" format and we // we should get a full restriction in "{fulltype}: {reason}" format and we
// need to find a "-all" tag in {fulltype}, otherwise ignore this restriction // need to find a "-all" tag in {fulltype}, otherwise ignore this restriction
@ -354,27 +244,6 @@ namespace {
} }
} }
bool onlineColorUse(UserData *user, TimeId now) {
if (isServiceUser(user->id) || user->botInfo) {
return false;
}
return onlineColorUse(user->onlineTill, now);
}
bool onlineColorUse(TimeId online, TimeId now) {
if (online <= 0) {
switch (online) {
case 0:
case -1:
case -2:
case -3:
case -4: return false;
}
return (-online > now);
}
return (online > now);
}
UserData *feedUser(const MTPUser &user) { UserData *feedUser(const MTPUser &user) {
UserData *data = nullptr; UserData *data = nullptr;
bool wasContact = false, minimal = false; bool wasContact = false, minimal = false;

View File

@ -52,14 +52,6 @@ namespace App {
QString formatPhone(QString phone); QString formatPhone(QString phone);
TimeId onlineForSort(UserData *user, TimeId now);
int32 onlineWillChangeIn(UserData *user, TimeId now);
int32 onlineWillChangeIn(TimeId online, TimeId now);
QString onlineText(UserData *user, TimeId now, bool precise = false);
QString onlineText(TimeId online, TimeId now, bool precise = false);
bool onlineColorUse(UserData *user, TimeId now);
bool onlineColorUse(TimeId online, TimeId now);
UserData *feedUser(const MTPUser &user); UserData *feedUser(const MTPUser &user);
UserData *feedUsers(const MTPVector<MTPUser> &users); // returns last user UserData *feedUsers(const MTPVector<MTPUser> &users); // returns last user
PeerData *feedChat(const MTPChat &chat); PeerData *feedChat(const MTPChat &chat);

View File

@ -27,6 +27,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "styles/style_boxes.h" #include "styles/style_boxes.h"
#include "ui/special_buttons.h" #include "ui/special_buttons.h"
#include "boxes/calendar_box.h" #include "boxes/calendar_box.h"
#include "data/data_peer_values.h"
namespace { namespace {
@ -176,7 +177,7 @@ void EditParticipantBox::Inner::paintEvent(QPaintEvent *e) {
auto seesAllMessages = (_user->botInfo->readsAllHistory || _hasAdminRights); auto seesAllMessages = (_user->botInfo->readsAllHistory || _hasAdminRights);
return lang(seesAllMessages ? lng_status_bot_reads_all : lng_status_bot_not_reads_all); return lang(seesAllMessages ? lng_status_bot_reads_all : lng_status_bot_not_reads_all);
} }
return App::onlineText(_user->onlineTill, unixtime()); return Data::OnlineText(_user->onlineTill, unixtime());
}; };
p.setFont(st::contactsStatusFont); p.setFont(st::contactsStatusFont);
p.setPen(st::contactsStatusFg); p.setPen(st::contactsStatusFg);

View File

@ -37,6 +37,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "observer_peer.h" #include "observer_peer.h"
#include "storage/file_download.h" #include "storage/file_download.h"
#include "data/data_peer_values.h"
#include "window/themes/window_theme.h" #include "window/themes/window_theme.h"
PeerListBox::PeerListBox( PeerListBox::PeerListBox(
@ -357,12 +358,12 @@ void PeerListRow::refreshStatus() {
setStatusText(lang(lng_saved_forward_here)); setStatusText(lang(lng_saved_forward_here));
} else { } else {
auto time = unixtime(); auto time = unixtime();
setStatusText(App::onlineText(user, time)); setStatusText(Data::OnlineText(user, time));
if (App::onlineColorUse(user, time)) { if (Data::OnlineTextActive(user, time)) {
_statusType = StatusType::Online; _statusType = StatusType::Online;
} }
_statusValidTill = getms() _statusValidTill = getms()
+ App::onlineWillChangeIn(user, time) * 1000LL; + Data::OnlineChangeTimeout(user, time);
} }
} else if (auto chat = peer()->asChat()) { } else if (auto chat = peer()->asChat()) {
if (!chat->amIn()) { if (!chat->amIn()) {

View File

@ -21,6 +21,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "chat_helpers/field_autocomplete.h" #include "chat_helpers/field_autocomplete.h"
#include "data/data_document.h" #include "data/data_document.h"
#include "data/data_peer_values.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "apiwrap.h" #include "apiwrap.h"
#include "storage/localstorage.h" #include "storage/localstorage.h"
@ -191,7 +192,10 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) {
} }
} }
if (_chat) { if (_chat) {
QMultiMap<int32, UserData*> ordered; auto ordered = QMultiMap<TimeId, not_null<UserData*>>();
const auto byOnline = [&](not_null<UserData*> user) {
return Data::SortByOnlineValue(user, now);
};
mrows.reserve(mrows.size() + (_chat->participants.empty() ? _chat->lastAuthors.size() : _chat->participants.size())); mrows.reserve(mrows.size() + (_chat->participants.empty() ? _chat->lastAuthors.size() : _chat->participants.size()));
if (_chat->noParticipantInfo()) { if (_chat->noParticipantInfo()) {
Auth().api().requestFullPeer(_chat); Auth().api().requestFullPeer(_chat);
@ -200,7 +204,7 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) {
if (user->isInaccessible()) continue; if (user->isInaccessible()) continue;
if (!listAllSuggestions && filterNotPassedByName(user)) continue; if (!listAllSuggestions && filterNotPassedByName(user)) continue;
if (indexOfInFirstN(mrows, user, recentInlineBots) >= 0) continue; if (indexOfInFirstN(mrows, user, recentInlineBots) >= 0) continue;
ordered.insertMulti(App::onlineForSort(user, now), user); ordered.insertMulti(byOnline(user), user);
} }
} }
for (const auto user : _chat->lastAuthors) { for (const auto user : _chat->lastAuthors) {
@ -209,7 +213,7 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) {
if (indexOfInFirstN(mrows, user, recentInlineBots) >= 0) continue; if (indexOfInFirstN(mrows, user, recentInlineBots) >= 0) continue;
mrows.push_back(user); mrows.push_back(user);
if (!ordered.isEmpty()) { if (!ordered.isEmpty()) {
ordered.remove(App::onlineForSort(user, now), user); ordered.remove(byOnline(user), user);
} }
} }
if (!ordered.isEmpty()) { if (!ordered.isEmpty()) {

View File

@ -20,7 +20,67 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/ */
#include "data/data_peer_values.h" #include "data/data_peer_values.h"
#include "lang/lang_keys.h"
namespace Data { namespace Data {
namespace {
constexpr auto kMinOnlineChangeTimeout = TimeMs(1000);
constexpr auto kMaxOnlineChangeTimeout = 86400 * TimeMs(1000);
int OnlinePhraseChangeInSeconds(TimeId online, TimeId now) {
if (online <= 0) {
if (-online > now) {
return (-online - now);
}
return std::numeric_limits<int32>::max();
}
if (online > now) {
return online - now;
}
const auto minutes = (now - online) / 60;
if (minutes < 60) {
return (minutes + 1) * 60 - (now - online);
}
const auto hours = (now - online) / 3600;
if (hours < 12) {
return (hours + 1) * 3600 - (now - online);
}
const auto nowFull = ::date(now);
const auto tomorrow = QDateTime(nowFull.date().addDays(1));
return static_cast<int32>(nowFull.secsTo(tomorrow));
}
base::optional<QString> OnlineTextSpecial(not_null<UserData*> user) {
if (isNotificationsUser(user->id)) {
return lang(lng_status_service_notifications);
} else if (user->botInfo) {
return lang(lng_status_bot);
} else if (isServiceUser(user->id)) {
return lang(lng_status_support);
}
return base::none;
}
base::optional<QString> OnlineTextCommon(TimeId online, TimeId now) {
if (online <= 0) {
switch (online) {
case 0:
case -1: return lang(lng_status_offline);
case -2: return lang(lng_status_recently);
case -3: return lang(lng_status_last_week);
case -4: return lang(lng_status_last_month);
}
return (-online > now)
? lang(lng_status_online)
: lang(lng_status_recently);
} else if (online > now) {
return lang(lng_status_online);
}
return base::none;
}
} // namespace
inline auto AdminRightsValue(not_null<ChannelData*> channel) { inline auto AdminRightsValue(not_null<ChannelData*> channel) {
return channel->adminRightsValue(); return channel->adminRightsValue();
@ -123,4 +183,129 @@ rpl::producer<bool> CanWriteValue(not_null<PeerData*> peer) {
Unexpected("Bad peer value in CanWriteValue()"); Unexpected("Bad peer value in CanWriteValue()");
} }
TimeId SortByOnlineValue(not_null<UserData*> user, TimeId now) {
if (isServiceUser(user->id) || user->botInfo) {
return -1;
}
const auto online = user->onlineTill;
const auto fromDate = [](const QDate &date) {
const auto shift = (unixtime() - myunixtime());
return static_cast<TimeId>(QDateTime(date).toTime_t()) + shift;
};
if (online <= 0) {
switch (online) {
case 0:
case -1: return online;
case -2: {
const auto recently = date(now).date().addDays(-3);
return fromDate(recently);
} break;
case -3: {
const auto weekago = date(now).date().addDays(-7);
return fromDate(weekago);
} break;
case -4: {
const auto monthago = date(now).date().addDays(-30);
return fromDate(monthago);
} break;
}
return -online;
}
return online;
}
TimeMs OnlineChangeTimeout(TimeId online, TimeId now) {
const auto result = OnlinePhraseChangeInSeconds(online, now);
Assert(result >= 0);
return snap(
result * TimeMs(1000),
kMinOnlineChangeTimeout,
kMaxOnlineChangeTimeout);
}
TimeMs OnlineChangeTimeout(not_null<UserData*> user, TimeId now) {
if (isServiceUser(user->id) || user->botInfo) {
return kMaxOnlineChangeTimeout;
}
return OnlineChangeTimeout(user->onlineTill, now);
}
QString OnlineText(TimeId online, TimeId now) {
if (const auto common = OnlineTextCommon(online, now)) {
return *common;
}
const auto minutes = (now - online) / 60;
if (!minutes) {
return lang(lng_status_lastseen_now);
} else if (minutes < 60) {
return lng_status_lastseen_minutes(lt_count, minutes);
}
const auto hours = (now - online) / 3600;
if (hours < 12) {
return lng_status_lastseen_hours(lt_count, hours);
}
const auto onlineFull = ::date(online);
const auto nowFull = ::date(now);
if (onlineFull.date() == nowFull.date()) {
const auto onlineTime = onlineFull.time().toString(cTimeFormat());
return lng_status_lastseen_today(lt_time, onlineTime);
} else if (onlineFull.date().addDays(1) == nowFull.date()) {
const auto onlineTime = onlineFull.time().toString(cTimeFormat());
return lng_status_lastseen_yesterday(lt_time, onlineTime);
}
const auto date = onlineFull.date().toString(qsl("dd.MM.yy"));
return lng_status_lastseen_date(lt_date, date);
}
QString OnlineText(not_null<UserData*> user, TimeId now) {
if (const auto special = OnlineTextSpecial(user)) {
return *special;
}
return OnlineText(user->onlineTill, now);
}
QString OnlineTextFull(not_null<UserData*> user, TimeId now) {
if (const auto special = OnlineTextSpecial(user)) {
return *special;
} else if (const auto common = OnlineTextCommon(user->onlineTill, now)) {
return *common;
}
const auto onlineFull = ::date(user->onlineTill);
const auto nowFull = ::date(now);
if (onlineFull.date() == nowFull.date()) {
const auto onlineTime = onlineFull.time().toString(cTimeFormat());
return lng_status_lastseen_today(lt_time, onlineTime);
} else if (onlineFull.date().addDays(1) == nowFull.date()) {
const auto onlineTime = onlineFull.time().toString(cTimeFormat());
return lng_status_lastseen_yesterday(lt_time, onlineTime);
}
const auto date = onlineFull.date().toString(qsl("dd.MM.yy"));
const auto time = onlineFull.time().toString(cTimeFormat());
return lng_status_lastseen_date_time(lt_date, date, lt_time, time);
}
bool OnlineTextActive(TimeId online, TimeId now) {
if (online <= 0) {
switch (online) {
case 0:
case -1:
case -2:
case -3:
case -4: return false;
}
return (-online > now);
}
return (online > now);
}
bool OnlineTextActive(not_null<UserData*> user, TimeId now) {
if (isServiceUser(user->id) || user->botInfo) {
return false;
}
return OnlineTextActive(user->onlineTill, now);
}
} // namespace Data } // namespace Data

View File

@ -121,4 +121,13 @@ rpl::producer<bool> CanWriteValue(ChatData *chat);
rpl::producer<bool> CanWriteValue(ChannelData *channel); rpl::producer<bool> CanWriteValue(ChannelData *channel);
rpl::producer<bool> CanWriteValue(not_null<PeerData*> peer); rpl::producer<bool> CanWriteValue(not_null<PeerData*> peer);
TimeId SortByOnlineValue(not_null<UserData*> user, TimeId now);
TimeMs OnlineChangeTimeout(TimeId online, TimeId now);
TimeMs OnlineChangeTimeout(not_null<UserData*> user, TimeId now);
QString OnlineText(TimeId online, TimeId now);
QString OnlineText(not_null<UserData*> user, TimeId now);
QString OnlineTextFull(not_null<UserData*> user, TimeId now);
bool OnlineTextActive(TimeId online, TimeId now);
bool OnlineTextActive(not_null<UserData*> user, TimeId now);
} // namespace Data } // namespace Data

View File

@ -21,6 +21,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "dialogs/dialogs_search_from_controllers.h" #include "dialogs/dialogs_search_from_controllers.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "data/data_peer_values.h"
#include "observer_peer.h" #include "observer_peer.h"
#include "auth_session.h" #include "auth_session.h"
#include "apiwrap.h" #include "apiwrap.h"
@ -94,19 +95,22 @@ void ChatSearchFromController::rebuildRows() {
auto wasEmpty = !delegate()->peerListFullRowsCount(); auto wasEmpty = !delegate()->peerListFullRowsCount();
auto now = unixtime(); auto now = unixtime();
QMultiMap<int32, UserData*> ordered; const auto byOnline = [&](not_null<UserData*> user) {
return Data::SortByOnlineValue(user, now);
};
auto ordered = QMultiMap<TimeId, not_null<UserData*>>();
if (_chat->noParticipantInfo()) { if (_chat->noParticipantInfo()) {
Auth().api().requestFullPeer(_chat); Auth().api().requestFullPeer(_chat);
} else if (!_chat->participants.empty()) { } else if (!_chat->participants.empty()) {
for (const auto [user, version] : _chat->participants) { for (const auto [user, version] : _chat->participants) {
ordered.insertMulti(App::onlineForSort(user, now), user); ordered.insertMulti(byOnline(user), user);
} }
} }
for_const (auto user, _chat->lastAuthors) { for_const (auto user, _chat->lastAuthors) {
if (user->isInaccessible()) continue; if (user->isInaccessible()) continue;
appendRow(user); appendRow(user);
if (!ordered.isEmpty()) { if (!ordered.isEmpty()) {
ordered.remove(App::onlineForSort(user, now), user); ordered.remove(byOnline(user), user);
} }
} }
if (!ordered.isEmpty()) { if (!ordered.isEmpty()) {

View File

@ -24,6 +24,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "ui/widgets/checkbox.h" #include "ui/widgets/checkbox.h"
#include "ui/effects/ripple_animation.h" #include "ui/effects/ripple_animation.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "data/data_peer_values.h"
namespace AdminLog { namespace AdminLog {
namespace { namespace {
@ -79,8 +80,8 @@ UserCheckbox::UserCheckbox(QWidget *parent, not_null<UserData*> user, bool check
setChecked(!this->checked()); setChecked(!this->checked());
}); });
auto now = unixtime(); auto now = unixtime();
_statusText = App::onlineText(_user, now); _statusText = Data::OnlineText(_user, now);
_statusOnline = App::onlineColorUse(_user, now); _statusOnline = Data::OnlineTextActive(_user, now);
auto checkSize = _check->getSize(); auto checkSize = _check->getSize();
_checkRect = { QPoint(_st.margin.left(), (st::contactsPhotoSize - checkSize.height()) / 2), checkSize }; _checkRect = { QPoint(_st.margin.left(), (st::contactsPhotoSize - checkSize.height()) / 2), checkSize };
} }

View File

@ -43,6 +43,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "window/window_controller.h" #include "window/window_controller.h"
#include "window/window_peer_menu.h" #include "window/window_peer_menu.h"
#include "calls/calls_instance.h" #include "calls/calls_instance.h"
#include "data/data_peer_values.h"
#include "observer_peer.h" #include "observer_peer.h"
#include "apiwrap.h" #include "apiwrap.h"
@ -664,12 +665,12 @@ void HistoryTopBarWidget::updateOnlineDisplay() {
if (!_historyPeer) return; if (!_historyPeer) return;
QString text; QString text;
int32 t = unixtime(); const auto now = unixtime();
bool titlePeerTextOnline = false; bool titlePeerTextOnline = false;
if (auto user = _historyPeer->asUser()) { if (const auto user = _historyPeer->asUser()) {
text = App::onlineText(user, t); text = Data::OnlineText(user, now);
titlePeerTextOnline = App::onlineColorUse(user, t); titlePeerTextOnline = Data::OnlineTextActive(user, now);
} else if (auto chat = _historyPeer->asChat()) { } else if (const auto chat = _historyPeer->asChat()) {
if (!chat->amIn()) { if (!chat->amIn()) {
text = lang(lng_chat_status_unaccessible); text = lang(lng_chat_status_unaccessible);
} else if (chat->participants.empty()) { } else if (chat->participants.empty()) {
@ -684,7 +685,7 @@ void HistoryTopBarWidget::updateOnlineDisplay() {
auto online = 0; auto online = 0;
auto onlyMe = true; auto onlyMe = true;
for (auto [user, v] : chat->participants) { for (auto [user, v] : chat->participants) {
if (user->onlineTill > t) { if (user->onlineTill > now) {
++online; ++online;
if (onlyMe && user != App::self()) onlyMe = false; if (onlyMe && user != App::self()) onlyMe = false;
} }
@ -707,7 +708,7 @@ void HistoryTopBarWidget::updateOnlineDisplay() {
auto online = 0; auto online = 0;
bool onlyMe = true; bool onlyMe = true;
for (auto &participant : std::as_const(channel->mgInfo->lastParticipants)) { for (auto &participant : std::as_const(channel->mgInfo->lastParticipants)) {
if (participant->onlineTill > t) { if (participant->onlineTill > now) {
++online; ++online;
if (onlyMe && participant != App::self()) { if (onlyMe && participant != App::self()) {
onlyMe = false; onlyMe = false;
@ -743,11 +744,10 @@ void HistoryTopBarWidget::updateOnlineDisplayTimer() {
if (!_historyPeer) return; if (!_historyPeer) return;
const auto now = unixtime(); const auto now = unixtime();
auto minIn = TimeId(86400); auto minTimeout = TimeMs(86400);
const auto handleUser = [&](not_null<UserData*> user) { const auto handleUser = [&](not_null<UserData*> user) {
auto hisMinIn = App::onlineWillChangeIn(user, now); auto hisTimeout = Data::OnlineChangeTimeout(user, now);
Assert(hisMinIn >= 0 && hisMinIn <= 86400); accumulate_min(minTimeout, hisTimeout);
accumulate_min(minIn, hisMinIn);
}; };
if (const auto user = _historyPeer->asUser()) { if (const auto user = _historyPeer->asUser()) {
handleUser(user); handleUser(user);
@ -757,7 +757,7 @@ void HistoryTopBarWidget::updateOnlineDisplayTimer() {
} }
} else if (_historyPeer->isChannel()) { } else if (_historyPeer->isChannel()) {
} }
updateOnlineDisplayIn(minIn * 1000); updateOnlineDisplayIn(minTimeout);
} }
void HistoryTopBarWidget::updateOnlineDisplayIn(TimeMs timeout) { void HistoryTopBarWidget::updateOnlineDisplayIn(TimeMs timeout) {

View File

@ -23,6 +23,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include <rpl/never.h> #include <rpl/never.h>
#include <rpl/combine.h> #include <rpl/combine.h>
#include "data/data_photo.h" #include "data/data_photo.h"
#include "data/data_peer_values.h"
#include "info/profile/info_profile_values.h" #include "info/profile/info_profile_values.h"
#include "info/info_controller.h" #include "info/info_controller.h"
#include "info/info_memento.h" #include "info/info_memento.h"
@ -360,11 +361,11 @@ void Cover::refreshStatusText() {
auto statusText = [&] { auto statusText = [&] {
auto currentTime = unixtime(); auto currentTime = unixtime();
if (auto user = _peer->asUser()) { if (auto user = _peer->asUser()) {
const auto result = App::onlineText(user, currentTime, true); const auto result = Data::OnlineTextFull(user, currentTime);
const auto showOnline = App::onlineColorUse(user, currentTime); const auto showOnline = Data::OnlineTextActive(user, currentTime);
const auto updateIn = App::onlineWillChangeIn(user, currentTime); const auto updateIn = Data::OnlineChangeTimeout(user, currentTime);
if (showOnline) { if (showOnline) {
_refreshStatusTimer.callOnce(updateIn * 1000LL); _refreshStatusTimer.callOnce(updateIn);
} }
return showOnline return showOnline
? textcmdLink(1, result) ? textcmdLink(1, result)

View File

@ -32,6 +32,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "boxes/confirm_box.h" #include "boxes/confirm_box.h"
#include "window/window_controller.h" #include "window/window_controller.h"
#include "styles/style_info.h" #include "styles/style_info.h"
#include "data/data_peer_values.h"
namespace Info { namespace Info {
namespace Profile { namespace Profile {
@ -141,8 +142,8 @@ void ChatMembersController::sortByOnline() {
delegate()->peerListSortRows([now]( delegate()->peerListSortRows([now](
const PeerListRow &a, const PeerListRow &a,
const PeerListRow &b) { const PeerListRow &b) {
return App::onlineForSort(a.peer()->asUser(), now) > return Data::SortByOnlineValue(a.peer()->asUser(), now) >
App::onlineForSort(b.peer()->asUser(), now); Data::SortByOnlineValue(b.peer()->asUser(), now);
}); });
refreshOnlineCount(); refreshOnlineCount();
} }
@ -214,7 +215,7 @@ void ChatMembersController::refreshOnlineCount() {
while (right > left) { while (right > left) {
auto middle = (left + right) / 2; auto middle = (left + right) / 2;
auto row = delegate()->peerListRowAt(middle); auto row = delegate()->peerListRowAt(middle);
if (App::onlineColorUse(row->peer()->asUser(), now)) { if (Data::OnlineTextActive(row->peer()->asUser(), now)) {
left = middle + 1; left = middle + 1;
} else { } else {
right = middle; right = middle;

View File

@ -25,6 +25,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "boxes/confirm_box.h" #include "boxes/confirm_box.h"
#include "boxes/edit_participant_box.h" #include "boxes/edit_participant_box.h"
#include "ui/widgets/popup_menu.h" #include "ui/widgets/popup_menu.h"
#include "data/data_peer_values.h"
#include "mainwidget.h" #include "mainwidget.h"
#include "apiwrap.h" #include "apiwrap.h"
#include "observer_peer.h" #include "observer_peer.h"
@ -169,9 +170,11 @@ void GroupMembersWidget::refreshUserOnline(UserData *user) {
_now = unixtime(); _now = unixtime();
auto member = getMember(it.value()); auto member = getMember(it.value());
member->statusHasOnlineColor = !user->botInfo && App::onlineColorUse(user->onlineTill, _now); member->statusHasOnlineColor = !user->botInfo && Data::OnlineTextActive(user->onlineTill, _now);
member->onlineTill = user->onlineTill; member->onlineTill = user->onlineTill;
member->onlineForSort = user->isSelf() ? INT_MAX : App::onlineForSort(user, _now); member->onlineForSort = user->isSelf()
? std::numeric_limits<TimeId>::max()
: Data::SortByOnlineValue(user, _now);
member->statusText = QString(); member->statusText = QString();
sortMembers(); sortMembers();
@ -276,9 +279,12 @@ void GroupMembersWidget::updateItemStatusText(Item *item) {
member->statusText = lang(seesAllMessages ? lng_status_bot_reads_all : lng_status_bot_not_reads_all); member->statusText = lang(seesAllMessages ? lng_status_bot_reads_all : lng_status_bot_not_reads_all);
member->onlineTextTill = _now + 86400; member->onlineTextTill = _now + 86400;
} else { } else {
member->statusHasOnlineColor = App::onlineColorUse(member->onlineTill, _now); member->statusHasOnlineColor = Data::OnlineTextActive(member->onlineTill, _now);
member->statusText = App::onlineText(member->onlineTill, _now); member->statusText = Data::OnlineText(member->onlineTill, _now);
member->onlineTextTill = _now + App::onlineWillChangeIn(member->onlineTill, _now); const auto changeInMs = Data::OnlineChangeTimeout(
member->onlineTill,
_now);
member->onlineTextTill = _now + TimeId(changeInMs / 1000);
} }
} }
if (_updateOnlineAt <= _now || _updateOnlineAt > member->onlineTextTill) { if (_updateOnlineAt <= _now || _updateOnlineAt > member->onlineTextTill) {
@ -365,7 +371,7 @@ void GroupMembersWidget::updateOnlineCount() {
for_const (auto item, items()) { for_const (auto item, items()) {
auto member = getMember(item); auto member = getMember(item);
auto user = member->user(); auto user = member->user();
auto isOnline = !user->botInfo && App::onlineColorUse(member->onlineTill, _now); auto isOnline = !user->botInfo && Data::OnlineTextActive(member->onlineTill, _now);
if (member->statusHasOnlineColor != isOnline) { if (member->statusHasOnlineColor != isOnline) {
member->statusHasOnlineColor = isOnline; member->statusHasOnlineColor = isOnline;
member->statusText = QString(); member->statusText = QString();
@ -402,7 +408,8 @@ void GroupMembersWidget::fillChatMembers(ChatData *chat) {
_sortByOnline = true; _sortByOnline = true;
reserveItemsForSize(chat->participants.size()); reserveItemsForSize(chat->participants.size());
addUser(chat, App::self())->onlineForSort = INT_MAX; // Put me on the first place. addUser(chat, App::self())->onlineForSort
= std::numeric_limits<TimeId>::max();
for (auto [user, v] : chat->participants) { for (auto [user, v] : chat->participants) {
if (!user->isSelf()) { if (!user->isSelf()) {
addUser(chat, user); addUser(chat, user);
@ -451,7 +458,8 @@ void GroupMembersWidget::fillMegagroupMembers(ChannelData *megagroup) {
clearItems(); clearItems();
reserveItemsForSize(membersList.size()); reserveItemsForSize(membersList.size());
if (megagroup->amIn()) { if (megagroup->amIn()) {
addUser(megagroup, App::self())->onlineForSort = INT_MAX; addUser(megagroup, App::self())->onlineForSort
= std::numeric_limits<TimeId>::max();
} }
} else if (membersList.size() >= itemsCount()) { } else if (membersList.size() >= itemsCount()) {
if (addUsersToEnd(megagroup)) { if (addUsersToEnd(megagroup)) {
@ -517,9 +525,10 @@ GroupMembersWidget::Member *GroupMembersWidget::computeMember(UserData *user) {
if (it == _membersByUser.cend()) { if (it == _membersByUser.cend()) {
auto member = new Member(user); auto member = new Member(user);
it = _membersByUser.insert(user, member); it = _membersByUser.insert(user, member);
member->statusHasOnlineColor = !user->botInfo && App::onlineColorUse(user->onlineTill, _now); member->statusHasOnlineColor = !user->botInfo
&& Data::OnlineTextActive(user->onlineTill, _now);
member->onlineTill = user->onlineTill; member->onlineTill = user->onlineTill;
member->onlineForSort = App::onlineForSort(user, _now); member->onlineForSort = Data::SortByOnlineValue(user, _now);
} }
return it.value(); return it.value();
} }
@ -538,7 +547,8 @@ void GroupMembersWidget::onUpdateOnlineDisplay() {
} }
} }
auto member = getMember(item); auto member = getMember(item);
bool isOnline = !member->user()->botInfo && App::onlineColorUse(member->onlineTill, _now); bool isOnline = !member->user()->botInfo
&& Data::OnlineTextActive(member->onlineTill, _now);
if (!isOnline) { if (!isOnline) {
changed = true; changed = true;
} }

View File

@ -32,6 +32,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "mainwidget.h" #include "mainwidget.h"
#include "observer_peer.h" #include "observer_peer.h"
#include "dialogs/dialogs_indexed_list.h" #include "dialogs/dialogs_indexed_list.h"
#include "data/data_peer_values.h"
#include "ui/widgets/popup_menu.h" #include "ui/widgets/popup_menu.h"
#include "window/window_controller.h" #include "window/window_controller.h"
@ -122,8 +123,8 @@ void ParticipantsBoxController::sortByOnline() {
delegate()->peerListSortRows([now]( delegate()->peerListSortRows([now](
const PeerListRow &a, const PeerListRow &a,
const PeerListRow &b) { const PeerListRow &b) {
return App::onlineForSort(a.peer()->asUser(), now) > return Data::SortByOnlineValue(a.peer()->asUser(), now) >
App::onlineForSort(b.peer()->asUser(), now); Data::SortByOnlineValue(b.peer()->asUser(), now);
}); });
refreshOnlineCount(); refreshOnlineCount();
} }
@ -137,7 +138,7 @@ void ParticipantsBoxController::refreshOnlineCount() {
while (right > left) { while (right > left) {
auto middle = (left + right) / 2; auto middle = (left + right) / 2;
auto row = delegate()->peerListRowAt(middle); auto row = delegate()->peerListRowAt(middle);
if (App::onlineColorUse(row->peer()->asUser(), now)) { if (Data::OnlineTextActive(row->peer()->asUser(), now)) {
left = middle + 1; left = middle + 1;
} else { } else {
right = middle; right = middle;