mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-04-01 00:08:02 +00:00
parent
0cba9e4a22
commit
ed895ace66
@ -945,6 +945,7 @@ void Updates::updateOnline(crl::time lastNonIdleTime, bool gotOtherOffline) {
|
|||||||
Data::PeerUpdate::Flag::OnlineStatus);
|
Data::PeerUpdate::Flag::OnlineStatus);
|
||||||
if (!isOnline) { // Went offline, so we need to save message draft to the cloud.
|
if (!isOnline) { // Went offline, so we need to save message draft to the cloud.
|
||||||
api().saveCurrentDraftToCloud();
|
api().saveCurrentDraftToCloud();
|
||||||
|
session().data().maybeStopWatchForOffline(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
_lastSetOnline = ms;
|
_lastSetOnline = ms;
|
||||||
@ -1856,6 +1857,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
|
|||||||
session().changes().peerUpdated(
|
session().changes().peerUpdated(
|
||||||
user,
|
user,
|
||||||
Data::PeerUpdate::Flag::OnlineStatus);
|
Data::PeerUpdate::Flag::OnlineStatus);
|
||||||
|
session().data().maybeStopWatchForOffline(user);
|
||||||
}
|
}
|
||||||
if (UserId(d.vuser_id()) == session().userId()) {
|
if (UserId(d.vuser_id()) == session().userId()) {
|
||||||
if (d.vstatus().type() == mtpc_userStatusOffline
|
if (d.vstatus().type() == mtpc_userStatusOffline
|
||||||
|
@ -1843,6 +1843,7 @@ void ApiWrap::updatePrivacyLastSeens() {
|
|||||||
session().changes().peerUpdated(
|
session().changes().peerUpdated(
|
||||||
user,
|
user,
|
||||||
Data::PeerUpdate::Flag::OnlineStatus);
|
Data::PeerUpdate::Flag::OnlineStatus);
|
||||||
|
session().data().maybeStopWatchForOffline(user);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (_contactsStatusesRequestId) {
|
if (_contactsStatusesRequestId) {
|
||||||
@ -1856,12 +1857,15 @@ void ApiWrap::updatePrivacyLastSeens() {
|
|||||||
auto &data = item.c_contactStatus();
|
auto &data = item.c_contactStatus();
|
||||||
if (auto user = _session->data().userLoaded(data.vuser_id())) {
|
if (auto user = _session->data().userLoaded(data.vuser_id())) {
|
||||||
auto oldOnlineTill = user->onlineTill;
|
auto oldOnlineTill = user->onlineTill;
|
||||||
auto newOnlineTill = OnlineTillFromStatus(data.vstatus(), oldOnlineTill);
|
auto newOnlineTill = OnlineTillFromStatus(
|
||||||
|
data.vstatus(),
|
||||||
|
oldOnlineTill);
|
||||||
if (oldOnlineTill != newOnlineTill) {
|
if (oldOnlineTill != newOnlineTill) {
|
||||||
user->onlineTill = newOnlineTill;
|
user->onlineTill = newOnlineTill;
|
||||||
session().changes().peerUpdated(
|
session().changes().peerUpdated(
|
||||||
user,
|
user,
|
||||||
Data::PeerUpdate::Flag::OnlineStatus);
|
Data::PeerUpdate::Flag::OnlineStatus);
|
||||||
|
session().data().maybeStopWatchForOffline(user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -460,8 +460,11 @@ bool OnlineTextActive(not_null<UserData*> user, TimeId now) {
|
|||||||
return OnlineTextActive(user->onlineTill, now);
|
return OnlineTextActive(user->onlineTill, now);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsUserOnline(not_null<UserData*> user) {
|
bool IsUserOnline(not_null<UserData*> user, TimeId now) {
|
||||||
return OnlineTextActive(user, base::unixtime::now());
|
if (!now) {
|
||||||
|
now = base::unixtime::now();
|
||||||
|
}
|
||||||
|
return OnlineTextActive(user, now);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChannelHasActiveCall(not_null<ChannelData*> channel) {
|
bool ChannelHasActiveCall(not_null<ChannelData*> channel) {
|
||||||
|
@ -122,7 +122,7 @@ inline auto PeerFullFlagValue(
|
|||||||
[[nodiscard]] QString OnlineTextFull(not_null<UserData*> user, TimeId now);
|
[[nodiscard]] QString OnlineTextFull(not_null<UserData*> user, TimeId now);
|
||||||
[[nodiscard]] bool OnlineTextActive(TimeId online, TimeId now);
|
[[nodiscard]] bool OnlineTextActive(TimeId online, TimeId now);
|
||||||
[[nodiscard]] bool OnlineTextActive(not_null<UserData*> user, TimeId now);
|
[[nodiscard]] bool OnlineTextActive(not_null<UserData*> user, TimeId now);
|
||||||
[[nodiscard]] bool IsUserOnline(not_null<UserData*> user);
|
[[nodiscard]] bool IsUserOnline(not_null<UserData*> user, TimeId now = 0);
|
||||||
[[nodiscard]] bool ChannelHasActiveCall(not_null<ChannelData*> channel);
|
[[nodiscard]] bool ChannelHasActiveCall(not_null<ChannelData*> channel);
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<QImage> PeerUserpicImageValue(
|
[[nodiscard]] rpl::producer<QImage> PeerUserpicImageValue(
|
||||||
|
@ -246,6 +246,7 @@ Session::Session(not_null<Main::Session*> session)
|
|||||||
, _ttlCheckTimer([=] { checkTTLs(); })
|
, _ttlCheckTimer([=] { checkTTLs(); })
|
||||||
, _selfDestructTimer([=] { checkSelfDestructItems(); })
|
, _selfDestructTimer([=] { checkSelfDestructItems(); })
|
||||||
, _pollsClosingTimer([=] { checkPollsClosings(); })
|
, _pollsClosingTimer([=] { checkPollsClosings(); })
|
||||||
|
, _watchForOfflineTimer([=] { checkLocalUsersWentOffline(); })
|
||||||
, _groups(this)
|
, _groups(this)
|
||||||
, _chatsFilters(std::make_unique<ChatFilters>(this))
|
, _chatsFilters(std::make_unique<ChatFilters>(this))
|
||||||
, _scheduledMessages(std::make_unique<ScheduledMessages>(this))
|
, _scheduledMessages(std::make_unique<ScheduledMessages>(this))
|
||||||
@ -644,6 +645,7 @@ not_null<UserData*> Session::processUser(const MTPUser &data) {
|
|||||||
if (oldOnlineTill != newOnlineTill) {
|
if (oldOnlineTill != newOnlineTill) {
|
||||||
result->onlineTill = newOnlineTill;
|
result->onlineTill = newOnlineTill;
|
||||||
flags |= UpdateFlag::OnlineStatus;
|
flags |= UpdateFlag::OnlineStatus;
|
||||||
|
session().data().maybeStopWatchForOffline(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -968,6 +970,64 @@ GroupCall *Session::groupCall(CallId callId) const {
|
|||||||
return (i != end(_groupCalls)) ? i->second.get() : nullptr;
|
return (i != end(_groupCalls)) ? i->second.get() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Session::watchForOffline(not_null<UserData*> user, TimeId now) {
|
||||||
|
if (!now) {
|
||||||
|
now = base::unixtime::now();
|
||||||
|
}
|
||||||
|
if (!Data::IsUserOnline(user, now)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto till = user->onlineTill;
|
||||||
|
const auto [i, ok] = _watchingForOffline.emplace(user, till);
|
||||||
|
if (!ok) {
|
||||||
|
if (i->second == till) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
i->second = till;
|
||||||
|
}
|
||||||
|
const auto timeout = Data::OnlineChangeTimeout(till, now);
|
||||||
|
const auto fires = _watchForOfflineTimer.isActive()
|
||||||
|
? _watchForOfflineTimer.remainingTime()
|
||||||
|
: -1;
|
||||||
|
if (fires >= 0 && fires <= timeout) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_watchForOfflineTimer.callOnce(std::max(timeout, crl::time(1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Session::maybeStopWatchForOffline(not_null<UserData*> user) {
|
||||||
|
if (Data::IsUserOnline(user)) {
|
||||||
|
return;
|
||||||
|
} else if (_watchingForOffline.remove(user)
|
||||||
|
&& _watchingForOffline.empty()) {
|
||||||
|
_watchForOfflineTimer.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Session::checkLocalUsersWentOffline() {
|
||||||
|
_watchForOfflineTimer.cancel();
|
||||||
|
|
||||||
|
auto minimal = 86400 * crl::time(1000);
|
||||||
|
const auto now = base::unixtime::now();
|
||||||
|
for (auto i = begin(_watchingForOffline)
|
||||||
|
; i != end(_watchingForOffline);) {
|
||||||
|
const auto user = i->first;
|
||||||
|
if (!Data::IsUserOnline(user, now)) {
|
||||||
|
i = _watchingForOffline.erase(i);
|
||||||
|
session().changes().peerUpdated(
|
||||||
|
user,
|
||||||
|
PeerUpdate::Flag::OnlineStatus);
|
||||||
|
} else {
|
||||||
|
const auto timeout = Data::OnlineChangeTimeout(user, now);
|
||||||
|
accumulate_min(minimal, timeout);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!_watchingForOffline.empty()) {
|
||||||
|
_watchForOfflineTimer.callOnce(std::max(minimal, crl::time(1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto Session::invitedToCallUsers(CallId callId) const
|
auto Session::invitedToCallUsers(CallId callId) const
|
||||||
-> const base::flat_set<not_null<UserData*>> & {
|
-> const base::flat_set<not_null<UserData*>> & {
|
||||||
static const base::flat_set<not_null<UserData*>> kEmpty;
|
static const base::flat_set<not_null<UserData*>> kEmpty;
|
||||||
|
@ -192,6 +192,9 @@ public:
|
|||||||
void unregisterGroupCall(not_null<GroupCall*> call);
|
void unregisterGroupCall(not_null<GroupCall*> call);
|
||||||
GroupCall *groupCall(CallId callId) const;
|
GroupCall *groupCall(CallId callId) const;
|
||||||
|
|
||||||
|
void watchForOffline(not_null<UserData*> user, TimeId now = 0);
|
||||||
|
void maybeStopWatchForOffline(not_null<UserData*> user);
|
||||||
|
|
||||||
[[nodiscard]] auto invitedToCallUsers(CallId callId) const
|
[[nodiscard]] auto invitedToCallUsers(CallId callId) const
|
||||||
-> const base::flat_set<not_null<UserData*>> &;
|
-> const base::flat_set<not_null<UserData*>> &;
|
||||||
void registerInvitedToCallUser(
|
void registerInvitedToCallUser(
|
||||||
@ -717,6 +720,7 @@ private:
|
|||||||
void setupUserIsContactViewer();
|
void setupUserIsContactViewer();
|
||||||
|
|
||||||
void checkSelfDestructItems();
|
void checkSelfDestructItems();
|
||||||
|
void checkLocalUsersWentOffline();
|
||||||
|
|
||||||
void scheduleNextTTLs();
|
void scheduleNextTTLs();
|
||||||
void checkTTLs();
|
void checkTTLs();
|
||||||
@ -976,6 +980,9 @@ private:
|
|||||||
std::vector<WallPaper> _wallpapers;
|
std::vector<WallPaper> _wallpapers;
|
||||||
uint64 _wallpapersHash = 0;
|
uint64 _wallpapersHash = 0;
|
||||||
|
|
||||||
|
base::flat_map<not_null<UserData*>, TimeId> _watchingForOffline;
|
||||||
|
base::Timer _watchForOfflineTimer;
|
||||||
|
|
||||||
rpl::event_stream<WebViewResultSent> _webViewResultSent;
|
rpl::event_stream<WebViewResultSent> _webViewResultSent;
|
||||||
|
|
||||||
Groups _groups;
|
Groups _groups;
|
||||||
|
@ -193,7 +193,7 @@ InnerWidget::InnerWidget(
|
|||||||
|
|
||||||
session().data().sendActionManager().speakingAnimationUpdated(
|
session().data().sendActionManager().speakingAnimationUpdated(
|
||||||
) | rpl::start_with_next([=](not_null<History*> history) {
|
) | rpl::start_with_next([=](not_null<History*> history) {
|
||||||
updateDialogRowCornerStatus(history);
|
repaintDialogRowCornerStatus(history);
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
setupOnlineStatusCheck();
|
setupOnlineStatusCheck();
|
||||||
@ -3181,15 +3181,15 @@ void InnerWidget::setupOnlineStatusCheck() {
|
|||||||
Data::PeerUpdate::Flag::OnlineStatus
|
Data::PeerUpdate::Flag::OnlineStatus
|
||||||
| Data::PeerUpdate::Flag::GroupCall
|
| Data::PeerUpdate::Flag::GroupCall
|
||||||
) | rpl::start_with_next([=](const Data::PeerUpdate &update) {
|
) | rpl::start_with_next([=](const Data::PeerUpdate &update) {
|
||||||
if (update.peer->isUser()) {
|
if (const auto user = update.peer->asUser()) {
|
||||||
userOnlineUpdated(update.peer);
|
userOnlineUpdated(user);
|
||||||
} else {
|
} else {
|
||||||
groupHasCallUpdated(update.peer);
|
groupHasCallUpdated(update.peer);
|
||||||
}
|
}
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerWidget::updateDialogRowCornerStatus(not_null<History*> history) {
|
void InnerWidget::repaintDialogRowCornerStatus(not_null<History*> history) {
|
||||||
const auto user = history->peer->isUser();
|
const auto user = history->peer->isUser();
|
||||||
const auto size = user
|
const auto size = user
|
||||||
? st::dialogsOnlineBadgeSize
|
? st::dialogsOnlineBadgeSize
|
||||||
@ -3217,16 +3217,15 @@ void InnerWidget::updateDialogRowCornerStatus(not_null<History*> history) {
|
|||||||
UpdateRowSection::Default | UpdateRowSection::Filtered);
|
UpdateRowSection::Default | UpdateRowSection::Filtered);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerWidget::userOnlineUpdated(not_null<PeerData*> peer) {
|
void InnerWidget::userOnlineUpdated(not_null<UserData*> user) {
|
||||||
const auto user = peer->isSelf() ? nullptr : peer->asUser();
|
if (!user->isSelf()) {
|
||||||
if (!user) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto history = session().data().historyLoaded(user);
|
const auto history = session().data().historyLoaded(user);
|
||||||
if (!history) {
|
if (!history) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
updateRowCornerStatusShown(history, Data::IsUserOnline(user));
|
updateRowCornerStatusShown(history);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerWidget::groupHasCallUpdated(not_null<PeerData*> peer) {
|
void InnerWidget::groupHasCallUpdated(not_null<PeerData*> peer) {
|
||||||
@ -3238,14 +3237,12 @@ void InnerWidget::groupHasCallUpdated(not_null<PeerData*> peer) {
|
|||||||
if (!history) {
|
if (!history) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
updateRowCornerStatusShown(history, Data::ChannelHasActiveCall(group));
|
updateRowCornerStatusShown(history);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerWidget::updateRowCornerStatusShown(
|
void InnerWidget::updateRowCornerStatusShown(not_null<History*> history) {
|
||||||
not_null<History*> history,
|
|
||||||
bool shown) {
|
|
||||||
const auto repaint = [=] {
|
const auto repaint = [=] {
|
||||||
updateDialogRowCornerStatus(history);
|
repaintDialogRowCornerStatus(history);
|
||||||
};
|
};
|
||||||
repaint();
|
repaint();
|
||||||
|
|
||||||
|
@ -248,13 +248,11 @@ private:
|
|||||||
|
|
||||||
int defaultRowTop(not_null<Row*> row) const;
|
int defaultRowTop(not_null<Row*> row) const;
|
||||||
void setupOnlineStatusCheck();
|
void setupOnlineStatusCheck();
|
||||||
void userOnlineUpdated(not_null<PeerData*> peer);
|
void userOnlineUpdated(not_null<UserData*> user);
|
||||||
void groupHasCallUpdated(not_null<PeerData*> peer);
|
void groupHasCallUpdated(not_null<PeerData*> peer);
|
||||||
|
|
||||||
void updateRowCornerStatusShown(
|
void updateRowCornerStatusShown(not_null<History*> history);
|
||||||
not_null<History*> history,
|
void repaintDialogRowCornerStatus(not_null<History*> history);
|
||||||
bool shown);
|
|
||||||
void updateDialogRowCornerStatus(not_null<History*> history);
|
|
||||||
|
|
||||||
void setupShortcuts();
|
void setupShortcuts();
|
||||||
RowDescriptor computeJump(
|
RowDescriptor computeJump(
|
||||||
|
@ -15,10 +15,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "dialogs/ui/dialogs_video_userpic.h"
|
#include "dialogs/ui/dialogs_video_userpic.h"
|
||||||
#include "dialogs/ui/dialogs_layout.h"
|
#include "dialogs/ui/dialogs_layout.h"
|
||||||
#include "data/data_folder.h"
|
#include "data/data_folder.h"
|
||||||
|
#include "data/data_session.h"
|
||||||
#include "data/data_peer_values.h"
|
#include "data/data_peer_values.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "history/history_item.h"
|
#include "history/history_item.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
|
#include "base/unixtime.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "styles/style_dialogs.h"
|
#include "styles/style_dialogs.h"
|
||||||
|
|
||||||
@ -196,15 +198,20 @@ void Row::setCornerBadgeShown(
|
|||||||
void Row::updateCornerBadgeShown(
|
void Row::updateCornerBadgeShown(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
Fn<void()> updateCallback) const {
|
Fn<void()> updateCallback) const {
|
||||||
|
const auto user = peer->asUser();
|
||||||
|
const auto now = user ? base::unixtime::now() : TimeId();
|
||||||
const auto shown = [&] {
|
const auto shown = [&] {
|
||||||
if (const auto user = peer->asUser()) {
|
if (user) {
|
||||||
return Data::IsUserOnline(user);
|
return Data::IsUserOnline(user, now);
|
||||||
} else if (const auto channel = peer->asChannel()) {
|
} else if (const auto channel = peer->asChannel()) {
|
||||||
return Data::ChannelHasActiveCall(channel);
|
return Data::ChannelHasActiveCall(channel);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}();
|
}();
|
||||||
setCornerBadgeShown(shown, std::move(updateCallback));
|
setCornerBadgeShown(shown, std::move(updateCallback));
|
||||||
|
if (shown && user) {
|
||||||
|
peer->owner().watchForOffline(user, now);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Row::ensureCornerBadgeUserpic() const {
|
void Row::ensureCornerBadgeUserpic() const {
|
||||||
|
@ -1338,9 +1338,9 @@ void TopBarWidget::updateOnlineDisplayTimer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto now = base::unixtime::now();
|
const auto now = base::unixtime::now();
|
||||||
auto minTimeout = crl::time(86400);
|
auto minTimeout = 86400 * crl::time(1000);
|
||||||
const auto handleUser = [&](not_null<UserData*> user) {
|
const auto handleUser = [&](not_null<UserData*> user) {
|
||||||
auto hisTimeout = Data::OnlineChangeTimeout(user, now);
|
const auto hisTimeout = Data::OnlineChangeTimeout(user, now);
|
||||||
accumulate_min(minTimeout, hisTimeout);
|
accumulate_min(minTimeout, hisTimeout);
|
||||||
};
|
};
|
||||||
if (const auto user = peer->asUser()) {
|
if (const auto user = peer->asUser()) {
|
||||||
|
Loading…
Reference in New Issue
Block a user