TopBar::adjustColors recreates the status label when the top bar colors change, for example after switching night mode, and the new label started without the online count. The count is only sent again when it changes, so the group status showed just the members count until then. Carry the online count over to the new label, like its link callbacks.
235 lines
6.2 KiB
C++
235 lines
6.2 KiB
C++
/*
|
|
This file is part of Telegram Desktop,
|
|
the official desktop application for the Telegram messaging service.
|
|
|
|
For license and copyright information please follow this link:
|
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
*/
|
|
#include "info/profile/info_profile_status_label.h"
|
|
|
|
#include "data/data_changes.h"
|
|
#include "data/data_channel.h"
|
|
#include "data/data_chat.h"
|
|
#include "data/data_community.h"
|
|
#include "data/data_peer.h"
|
|
#include "data/data_peer_values.h"
|
|
#include "data/data_session.h"
|
|
#include "data/data_user.h"
|
|
#include "lang/lang_keys.h"
|
|
#include "main/main_session.h"
|
|
#include "ui/widgets/labels.h"
|
|
#include "ui/text/text_utilities.h"
|
|
#include "ui/basic_click_handlers.h"
|
|
#include "base/unixtime.h"
|
|
|
|
#include "styles/style_info.h"
|
|
|
|
namespace Info::Profile {
|
|
namespace {
|
|
|
|
[[nodiscard]] auto MembersStatusText(int count) {
|
|
return tr::lng_chat_status_members(tr::now, lt_count_decimal, count);
|
|
};
|
|
|
|
[[nodiscard]] auto OnlineStatusText(int count) {
|
|
return tr::lng_chat_status_online(tr::now, lt_count_decimal, count);
|
|
};
|
|
|
|
[[nodiscard]] auto ChatStatusText(
|
|
int fullCount,
|
|
int onlineCount,
|
|
bool isGroup) {
|
|
if (onlineCount > 1 && onlineCount <= fullCount) {
|
|
return tr::lng_chat_status_members_online(
|
|
tr::now,
|
|
lt_members_count,
|
|
MembersStatusText(fullCount),
|
|
lt_online_count,
|
|
OnlineStatusText(onlineCount));
|
|
} else if (fullCount > 0) {
|
|
return isGroup
|
|
? tr::lng_chat_status_members(
|
|
tr::now,
|
|
lt_count_decimal,
|
|
fullCount)
|
|
: tr::lng_chat_status_subscribers(
|
|
tr::now,
|
|
lt_count_decimal,
|
|
fullCount);
|
|
}
|
|
return isGroup
|
|
? tr::lng_group_status(tr::now)
|
|
: tr::lng_channel_status(tr::now);
|
|
};
|
|
|
|
[[nodiscard]] auto ChannelTypeText(not_null<ChannelData*> channel) {
|
|
const auto isPublic = channel->isPublic();
|
|
const auto isMegagroup = channel->isMegagroup();
|
|
return (isPublic
|
|
? (isMegagroup
|
|
? tr::lng_create_public_group_title(tr::now)
|
|
: tr::lng_create_public_channel_title(tr::now))
|
|
: (isMegagroup
|
|
? tr::lng_create_private_group_title(tr::now)
|
|
: tr::lng_create_private_channel_title(tr::now))).toLower();
|
|
};
|
|
|
|
[[nodiscard]] bool PeerHiddenInCommunity(not_null<PeerData*> peer) {
|
|
const auto communityId = Data::PeerLinkedCommunityId(peer);
|
|
if (!communityId) {
|
|
return false;
|
|
}
|
|
const auto community = peer->owner().channel(communityId);
|
|
const auto info = community->communityInfo();
|
|
return info && info->isHidden(peer);
|
|
}
|
|
|
|
[[nodiscard]] TextWithEntities MaybeHiddenPrefixed(
|
|
TextWithEntities body,
|
|
bool hidden) {
|
|
if (!hidden) {
|
|
return body;
|
|
}
|
|
using namespace Ui::Text;
|
|
return IconEmoji(&st::infoStatusHiddenIcon)
|
|
.append(' ')
|
|
.append(Link(tr::lng_community_hidden_status(tr::now), 2))
|
|
.append(QString::fromUtf8(" \xC2\xB7 "))
|
|
.append(std::move(body));
|
|
}
|
|
|
|
} // namespace
|
|
|
|
StatusLabel::StatusLabel(
|
|
not_null<Ui::FlatLabel*> label,
|
|
not_null<PeerData*> peer)
|
|
: _label(label)
|
|
, _peer(peer)
|
|
, _refreshTimer([=] { refresh(); }) {
|
|
if (const auto communityId = Data::PeerLinkedCommunityId(_peer)) {
|
|
const auto community = _peer->owner().channel(communityId);
|
|
community->session().changes().peerFlagsValue(
|
|
community,
|
|
Data::PeerUpdate::Flag::FullInfo
|
|
) | rpl::on_next([=] {
|
|
refresh();
|
|
}, _lifetime);
|
|
}
|
|
}
|
|
|
|
void StatusLabel::setOnlineCount(int count) {
|
|
_onlineCount = count;
|
|
refresh();
|
|
}
|
|
|
|
int StatusLabel::onlineCount() const {
|
|
return _onlineCount;
|
|
}
|
|
|
|
void StatusLabel::refresh() {
|
|
const auto hidden = PeerHiddenInCommunity(_peer);
|
|
auto hasMembersLink = [&] {
|
|
if (auto megagroup = _peer->asMegagroup()) {
|
|
return megagroup->canViewMembers();
|
|
}
|
|
return false;
|
|
}();
|
|
auto statusText = [&]() -> TextWithEntities {
|
|
using namespace Ui::Text;
|
|
auto currentTime = base::unixtime::now();
|
|
if (auto user = _peer->asUser()) {
|
|
const auto result = Data::OnlineTextFull(user, currentTime);
|
|
const auto showOnline = Data::OnlineTextActive(
|
|
user,
|
|
currentTime);
|
|
const auto updateIn = Data::OnlineChangeTimeout(
|
|
user,
|
|
currentTime);
|
|
if (showOnline) {
|
|
_refreshTimer.callOnce(updateIn);
|
|
}
|
|
return MaybeHiddenPrefixed(
|
|
(showOnline && _colorized)
|
|
? Ui::Text::Colorized(result)
|
|
: TextWithEntities{ .text = result },
|
|
hidden);
|
|
} else if (auto chat = _peer->asChat()) {
|
|
if (!chat->amIn()) {
|
|
return tr::lng_chat_status_unaccessible(
|
|
{},
|
|
WithEntities);
|
|
}
|
|
const auto onlineCount = _onlineCount;
|
|
const auto fullCount = std::max(
|
|
chat->count,
|
|
int(chat->participants.size()));
|
|
return MaybeHiddenPrefixed(
|
|
{ .text = ChatStatusText(fullCount, onlineCount, true) },
|
|
hidden);
|
|
} else if (auto broadcast = _peer->monoforumBroadcast()) {
|
|
if (!broadcast->membersCountKnown()) {
|
|
return TextWithEntities{ .text = ChannelTypeText(broadcast) };
|
|
}
|
|
auto result = ChatStatusText(
|
|
broadcast->membersCount(),
|
|
0,
|
|
false);
|
|
return TextWithEntities{ .text = result };
|
|
} else if (auto channel = _peer->asChannel()) {
|
|
if (!channel->membersCountKnown()) {
|
|
auto result = ChannelTypeText(channel);
|
|
return MaybeHiddenPrefixed(
|
|
hasMembersLink
|
|
? tr::link(result)
|
|
: TextWithEntities{ .text = result },
|
|
hidden);
|
|
}
|
|
const auto onlineCount = _onlineCount;
|
|
const auto fullCount = channel->membersCount();
|
|
auto result = ChatStatusText(
|
|
fullCount,
|
|
onlineCount,
|
|
channel->isMegagroup());
|
|
return MaybeHiddenPrefixed(
|
|
hasMembersLink
|
|
? tr::link(result)
|
|
: TextWithEntities{ .text = result },
|
|
hidden);
|
|
}
|
|
return tr::lng_chat_status_unaccessible(tr::now, WithEntities);
|
|
}();
|
|
_label->setMarkedText(statusText);
|
|
if (hasMembersLink && _membersLinkCallback) {
|
|
_label->setLink(
|
|
1,
|
|
std::make_shared<LambdaClickHandler>(_membersLinkCallback));
|
|
}
|
|
if (hidden && _hiddenLinkCallback) {
|
|
_label->setLink(
|
|
2,
|
|
std::make_shared<LambdaClickHandler>(_hiddenLinkCallback));
|
|
}
|
|
}
|
|
|
|
void StatusLabel::setHiddenLinkCallback(Fn<void()> callback) {
|
|
_hiddenLinkCallback = std::move(callback);
|
|
}
|
|
|
|
Fn<void()> StatusLabel::hiddenLinkCallback() const {
|
|
return _hiddenLinkCallback;
|
|
}
|
|
|
|
void StatusLabel::setMembersLinkCallback(Fn<void()> callback) {
|
|
_membersLinkCallback = std::move(callback);
|
|
}
|
|
|
|
Fn<void()> StatusLabel::membersLinkCallback() const {
|
|
return _membersLinkCallback;
|
|
}
|
|
|
|
void StatusLabel::setColorized(bool enabled) {
|
|
_colorized = enabled;
|
|
refresh();
|
|
}
|
|
|
|
} // namespace Info::Profile
|