Mark hidden chats with a userpic badge in community view.

This commit is contained in:
John Preston
2026-06-17 01:48:43 +04:00
parent 442c0a7313
commit 3b44f5c193
7 changed files with 101 additions and 7 deletions
@@ -132,6 +132,13 @@ void CommunityInfo::applyLinkedPeers(const QVector<MTPCommunityPeer> &list) {
}
_linkedPeers = std::move(now);
_hiddenPeers.clear();
for (const auto &linked : _linkedPeers) {
if (linked.visible.has_value() && !*linked.visible) {
_hiddenPeers.emplace(linked.peer);
}
}
const auto communityId = peerToChannel(_channel->id);
for (const auto &linked : _linkedPeers) {
if (const auto channel = linked.peer->asChannel()) {
@@ -163,6 +170,10 @@ rpl::producer<> CommunityInfo::linkedPeersValue() const {
) | rpl::then(_linkedPeersChanges.events());
}
bool CommunityInfo::isHidden(not_null<PeerData*> peer) const {
return _hiddenPeers.contains(peer);
}
bool CommunityInfo::collapsedInDialogs() const {
return _channel->flags() & ChannelDataFlag::CommunityCollapsed;
}
@@ -39,6 +39,7 @@ public:
return _linkedPeers;
}
[[nodiscard]] rpl::producer<> linkedPeersValue() const;
[[nodiscard]] bool isHidden(not_null<PeerData*> peer) const;
[[nodiscard]] bool collapsedInDialogs() const;
void collapsedChanged();
@@ -78,6 +79,7 @@ private:
const not_null<ChannelData*> _channel;
std::vector<CommunityLinkedPeer> _linkedPeers;
base::flat_set<not_null<PeerData*>> _hiddenPeers;
rpl::event_stream<> _linkedPeersChanges;
base::flat_set<not_null<History*>> _histories;
@@ -159,6 +159,13 @@ dialogsCommunityBadgeSkip: point(-3px, -3px);
dialogsCommunityBadgeStroke: 2px;
dialogsCommunityBadgeLine: 1px;
dialogsCommunityHiddenBadgeSize: 16px;
dialogsCommunityHiddenBadgeSkip: point(-3px, -3px);
dialogsCommunityHiddenBadgeStroke: 2px;
dialogsCommunityHiddenBadgeLine: 1px;
dialogsCommunityHiddenBadgePupil: 1px;
dialogsCommunityHiddenBadgeFg: menuIconFg;
dialogsTTLBadgeSize: 20px;
dialogsTTLBadgeInnerMargins: margins(2px, 2px, 2px, 2px);
// Relative to a photo place, not a whole userpic place.
@@ -1002,6 +1002,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
.topicJumpCache = _topicJumpCache.get(),
.folder = _openedFolder,
.forum = _openedForum,
.community = _openedCommunity,
.currentBg = currentBg(),
.filter = _filterId,
.now = ms,
+73 -5
View File
@@ -24,6 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "dialogs/ui/dialogs_video_userpic.h"
#include "dialogs/ui/dialogs_layout.h"
#include "data/data_channel.h"
#include "data/data_community.h"
#include "data/data_folder.h"
#include "data/data_forum.h"
#include "data/data_session.h"
@@ -359,13 +360,16 @@ void Row::updateCornerBadgeShown(
not_null<PeerData*> peer,
Fn<void()> updateCallback,
bool hasUnreadBadgesAbove,
bool insideCommunity) const {
bool insideCommunity,
bool hidden) const {
const auto user = peer->asUser();
const auto now = user ? base::unixtime::now() : TimeId();
const auto channel = user ? nullptr : peer->asChannel();
const auto nextLayer = [&] {
if (hasUnreadBadgesAbove) {
return kNoneLayer;
} else if (hidden) {
return kTopLayer;
} else if (user && Data::IsUserOnline(user, now)) {
return kTopLayer;
} else if (channel
@@ -400,7 +404,8 @@ void Row::PaintCornerBadgeFrame(
Ui::PeerUserpicView &view,
const Ui::PaintContext &context,
bool subscribed,
bool communityMember) {
bool communityMember,
bool hidden) {
data->frame.fill(Qt::transparent);
Painter q(&data->frame);
@@ -490,6 +495,61 @@ void Row::PaintCornerBadgeFrame(
return;
}
if (hidden) {
if (!hq) {
hq.emplace(q);
}
q.setCompositionMode(QPainter::CompositionMode_Source);
const auto size = st::dialogsCommunityHiddenBadgeSize;
const auto &skip = st::dialogsCommunityHiddenBadgeSkip;
const auto rect = QRectF(
photoSize - skip.x() - size,
photoSize - skip.y() - size,
size,
size);
auto pen = QPen(Qt::transparent);
pen.setWidthF(st::dialogsCommunityHiddenBadgeStroke);
q.setPen(pen);
q.setBrush(st::dialogsCommunityHiddenBadgeFg);
q.drawEllipse(rect);
q.setCompositionMode(QPainter::CompositionMode_SourceOver);
const auto center = rect.center();
const auto eyeWidth = size / 3.;
const auto eyeHeight = size / 5.;
auto glyph = QPen(st::windowBg->c);
glyph.setWidthF(st::dialogsCommunityHiddenBadgeLine);
glyph.setCapStyle(Qt::RoundCap);
glyph.setJoinStyle(Qt::RoundJoin);
q.setPen(glyph);
q.setBrush(Qt::NoBrush);
auto eye = QPainterPath();
eye.moveTo(center.x() - eyeWidth, center.y());
eye.quadTo(
center.x(),
center.y() - eyeHeight * 2.,
center.x() + eyeWidth,
center.y());
eye.quadTo(
center.x(),
center.y() + eyeHeight * 2.,
center.x() - eyeWidth,
center.y());
q.drawPath(eye);
q.setPen(Qt::NoPen);
q.setBrush(st::windowBg->c);
const auto pupil = st::dialogsCommunityHiddenBadgePupil;
q.drawEllipse(center, pupil, pupil);
q.setPen(glyph);
q.setBrush(Qt::NoBrush);
q.drawLine(
QPointF(center.x() - eyeWidth, center.y() + eyeWidth),
QPointF(center.x() + eyeWidth, center.y() - eyeWidth));
return;
}
if (communityMember) {
if (!hq) {
hq.emplace(q);
@@ -594,12 +654,16 @@ void Row::paintUserpic(
_communityUserpicEffect = nullptr;
}
const auto insideCommunity = context.insideCommunity;
const auto hidden = context.community
&& peer
&& context.community->isHidden(peer);
if (peer) {
updateCornerBadgeShown(
peer,
nullptr,
hasUnreadBadgesAbove,
insideCommunity);
insideCommunity,
hidden);
}
const auto cornerBadgeShown = !_cornerBadgeUserpic
@@ -687,6 +751,7 @@ void Row::paintUserpic(
|| _cornerBadgeUserpic->storiesCount != storiesCount
|| _cornerBadgeUserpic->storiesUnreadCount != storiesUnreadCount
|| _cornerBadgeUserpic->storiesHasVideoStream != storiesHasVideoStream
|| _cornerBadgeUserpic->hidden != hidden
|| videoUserpic) {
_cornerBadgeUserpic->key = key;
_cornerBadgeUserpic->paletteVersion = paletteVersion;
@@ -695,6 +760,7 @@ void Row::paintUserpic(
_cornerBadgeUserpic->storiesUnreadCount = storiesUnreadCount;
_cornerBadgeUserpic->storiesHasVideoStream = storiesHasVideoStream;
_cornerBadgeUserpic->frameIndex = frameIndex;
_cornerBadgeUserpic->hidden = hidden;
_cornerBadgeUserpic->layersManager.markFrameShown();
PaintCornerBadgeFrame(
_cornerBadgeUserpic.get(),
@@ -705,7 +771,8 @@ void Row::paintUserpic(
userpicView(),
context,
subscribed,
communityMember);
communityMember,
hidden);
}
p.drawImage(
context.st->padding.left() - framePadding,
@@ -715,7 +782,8 @@ void Row::paintUserpic(
if (!history
|| history->peer->isUser()
|| subscribed
|| communityMember) {
|| communityMember
|| hidden) {
return;
}
const auto actionPainter = history->sendActionPainter();
+5 -2
View File
@@ -106,7 +106,8 @@ public:
not_null<PeerData*> peer,
Fn<void()> updateCallback = nullptr,
bool hasUnreadBadgesAbove = false,
bool insideCommunity = false) const;
bool insideCommunity = false,
bool hidden = false) const;
void paintUserpic(
Painter &p,
not_null<Entry*> entry,
@@ -189,6 +190,7 @@ private:
uint32 storiesUnreadCount : 7 = 0;
uint32 storiesHasVideoStream : 1 = 0;
uint32 active : 1 = 0;
uint32 hidden : 1 = 0;
};
void setCornerBadgeShown(
@@ -204,7 +206,8 @@ private:
Ui::PeerUserpicView &view,
const Ui::PaintContext &context,
bool subscribed,
bool communityMember);
bool communityMember,
bool hidden);
Key _id;
mutable std::unique_ptr<CornerBadgeUserpic> _cornerBadgeUserpic;
@@ -23,6 +23,7 @@ namespace Data {
class Forum;
class Folder;
class Thread;
class CommunityInfo;
} // namespace Data
namespace Dialogs {
@@ -61,6 +62,7 @@ struct PaintContext {
TopicJumpCache *topicJumpCache = nullptr;
Data::Folder *folder = nullptr;
Data::Forum *forum = nullptr;
Data::CommunityInfo *community = nullptr;
required<QBrush> currentBg;
FilterId filter = 0;
float64 topicsExpanded = 0.;