mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 06:07:06 +02:00
Added TTL badge to dialogs list.
This commit is contained in:
parent
cbbbcd877c
commit
92756f418b
7 changed files with 157 additions and 38 deletions
|
@ -99,6 +99,11 @@ dialogsOnlineBadgeDuration: 150;
|
|||
dialogsCallBadgeSize: 16px;
|
||||
dialogsCallBadgeSkip: point(-3px, -3px);
|
||||
|
||||
dialogsTTLBadgeSize: 20px;
|
||||
dialogsTTLBadgeInnerMargins: margins(2px, 2px, 2px, 2px);
|
||||
// Relative to a photo place, not a whole userpic place.
|
||||
dialogsTTLBadgeSkip: point(1px, 1px);
|
||||
|
||||
dialogsSpeakingStrokeNumerator: 16px;
|
||||
dialogsSpeakingDenominator: 8.;
|
||||
|
||||
|
|
|
@ -3530,11 +3530,24 @@ void InnerWidget::setupOnlineStatusCheck() {
|
|||
session().changes().peerUpdates(
|
||||
Data::PeerUpdate::Flag::OnlineStatus
|
||||
| Data::PeerUpdate::Flag::GroupCall
|
||||
| Data::PeerUpdate::Flag::MessagesTTL
|
||||
) | rpl::start_with_next([=](const Data::PeerUpdate &update) {
|
||||
if (const auto user = update.peer->asUser()) {
|
||||
userOnlineUpdated(user);
|
||||
} else {
|
||||
groupHasCallUpdated(update.peer);
|
||||
const auto &peer = update.peer;
|
||||
if (const auto user = peer->asUser()) {
|
||||
if (user->isSelf()) {
|
||||
return;
|
||||
}
|
||||
if (const auto history = session().data().historyLoaded(user)) {
|
||||
updateRowCornerStatusShown(history);
|
||||
}
|
||||
} else if (const auto group = peer->asMegagroup()) {
|
||||
if (const auto history = session().data().historyLoaded(group)) {
|
||||
updateRowCornerStatusShown(history);
|
||||
}
|
||||
} else if (peer->messagesTTL()) {
|
||||
if (const auto history = session().data().historyLoaded(peer)) {
|
||||
updateRowCornerStatusShown(history);
|
||||
}
|
||||
}
|
||||
}, lifetime());
|
||||
}
|
||||
|
@ -3559,37 +3572,22 @@ void InnerWidget::repaintDialogRowCornerStatus(not_null<History*> history) {
|
|||
st::defaultDialogRow.padding.left(),
|
||||
st::defaultDialogRow.padding.top()
|
||||
);
|
||||
const auto ttlUpdateRect = !history->peer->messagesTTL()
|
||||
? QRect()
|
||||
: Dialogs::CornerBadgeTTLRect(
|
||||
_st->photoSize
|
||||
).translated(
|
||||
st::defaultDialogRow.padding.left(),
|
||||
st::defaultDialogRow.padding.top()
|
||||
);
|
||||
updateDialogRow(
|
||||
RowDescriptor(
|
||||
history,
|
||||
FullMsgId()),
|
||||
updateRect,
|
||||
updateRect.united(ttlUpdateRect),
|
||||
UpdateRowSection::Default | UpdateRowSection::Filtered);
|
||||
}
|
||||
|
||||
void InnerWidget::userOnlineUpdated(not_null<UserData*> user) {
|
||||
if (user->isSelf()) {
|
||||
return;
|
||||
}
|
||||
const auto history = session().data().historyLoaded(user);
|
||||
if (!history) {
|
||||
return;
|
||||
}
|
||||
updateRowCornerStatusShown(history);
|
||||
}
|
||||
|
||||
void InnerWidget::groupHasCallUpdated(not_null<PeerData*> peer) {
|
||||
const auto group = peer->asMegagroup();
|
||||
if (!group) {
|
||||
return;
|
||||
}
|
||||
const auto history = session().data().historyLoaded(group);
|
||||
if (!history) {
|
||||
return;
|
||||
}
|
||||
updateRowCornerStatusShown(history);
|
||||
}
|
||||
|
||||
void InnerWidget::updateRowCornerStatusShown(not_null<History*> history) {
|
||||
const auto repaint = [=] {
|
||||
repaintDialogRowCornerStatus(history);
|
||||
|
|
|
@ -276,8 +276,6 @@ private:
|
|||
|
||||
int defaultRowTop(not_null<Row*> row) const;
|
||||
void setupOnlineStatusCheck();
|
||||
void userOnlineUpdated(not_null<UserData*> user);
|
||||
void groupHasCallUpdated(not_null<PeerData*> peer);
|
||||
|
||||
void updateRowCornerStatusShown(not_null<History*> history);
|
||||
void repaintDialogRowCornerStatus(not_null<History*> history);
|
||||
|
|
|
@ -7,7 +7,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#include "dialogs/dialogs_row.h"
|
||||
|
||||
#include "ui/chat/chat_theme.h" // CountAverageColor.
|
||||
#include "ui/color_contrast.h"
|
||||
#include "ui/effects/ripple_animation.h"
|
||||
#include "ui/image/image_prepare.h"
|
||||
#include "ui/text/format_values.h"
|
||||
#include "ui/text/text_options.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/painter.h"
|
||||
|
@ -22,14 +26,112 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/history_item.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "mainwidget.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
|
||||
namespace Dialogs {
|
||||
namespace {
|
||||
|
||||
constexpr auto kTopLayer = 1;
|
||||
constexpr auto kTopLayer = 2;
|
||||
constexpr auto kBottomLayer = 1;
|
||||
constexpr auto kNoneLayer = 0;
|
||||
|
||||
void PaintCornerBadgeTTLFrame(
|
||||
QPainter &q,
|
||||
not_null<PeerData*> peer,
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
float64 progress,
|
||||
int photoSize) {
|
||||
const auto ttl = peer->messagesTTL();
|
||||
if (!ttl || !view) {
|
||||
return;
|
||||
}
|
||||
using Radius = ImageRoundRadius;
|
||||
constexpr auto kBlurRadius = 24;
|
||||
PainterHighQualityEnabler hq(q);
|
||||
|
||||
q.setOpacity(progress);
|
||||
|
||||
const auto ratio = style::DevicePixelRatio();
|
||||
const auto fullSize = photoSize;
|
||||
const auto blurredFull = Images::BlurLargeImage(
|
||||
peer->generateUserpicImage(view, fullSize * ratio, Radius::None),
|
||||
kBlurRadius);
|
||||
const auto partRect = CornerBadgeTTLRect(fullSize);
|
||||
const auto &partSize = partRect.width();
|
||||
if (progress <= 1.) {
|
||||
q.save();
|
||||
q.translate(partRect.center());
|
||||
q.scale(progress, progress);
|
||||
q.translate(-partRect.center());
|
||||
q.restore();
|
||||
}
|
||||
{
|
||||
auto blurredPart = blurredFull.copy(
|
||||
blurredFull.width() - partSize * ratio,
|
||||
blurredFull.height() - partSize * ratio,
|
||||
partSize * ratio,
|
||||
partSize * ratio);
|
||||
blurredPart.setDevicePixelRatio(ratio);
|
||||
|
||||
constexpr auto kMinAcceptableContrast = 4.5;
|
||||
const auto averageColor = Ui::CountAverageColor(blurredPart);
|
||||
const auto contrast = Ui::CountContrast(
|
||||
averageColor,
|
||||
st::premiumButtonFg->c);
|
||||
if (contrast < kMinAcceptableContrast) {
|
||||
constexpr auto kDarkerBy = 0.2;
|
||||
auto painterPart = QPainter(&blurredPart);
|
||||
painterPart.setOpacity(kDarkerBy);
|
||||
painterPart.fillRect(
|
||||
QRect(QPoint(), partRect.size()),
|
||||
Qt::black);
|
||||
}
|
||||
q.drawImage(
|
||||
partRect.topLeft(),
|
||||
Images::Circle(std::move(blurredPart)));
|
||||
}
|
||||
const auto innerRect = partRect - st::dialogsTTLBadgeInnerMargins;
|
||||
const auto ttlText = Ui::FormatTTLTiny(ttl);
|
||||
|
||||
q.setFont(st::dialogsScamFont);
|
||||
q.setPen(st::premiumButtonFg);
|
||||
q.drawText(
|
||||
innerRect,
|
||||
(ttlText.size() > 2) ? ttlText.mid(0, 2) : ttlText,
|
||||
style::al_center);
|
||||
|
||||
constexpr auto kPenWidth = 1.5;
|
||||
constexpr auto kAngleStart = 90 * 16;
|
||||
constexpr auto kAngleSpan = 180 * 16;
|
||||
|
||||
auto pen = QPen(st::premiumButtonFg);
|
||||
pen.setJoinStyle(Qt::RoundJoin);
|
||||
pen.setCapStyle(Qt::RoundCap);
|
||||
pen.setWidthF(kPenWidth);
|
||||
|
||||
q.setPen(pen);
|
||||
q.setBrush(Qt::NoBrush);
|
||||
q.drawArc(innerRect, kAngleStart, kAngleSpan);
|
||||
|
||||
q.setClipRect(partRect - QMargins(partRect.width() / 2, 0, 0, 0));
|
||||
pen.setStyle(Qt::DotLine);
|
||||
q.setPen(pen);
|
||||
q.drawEllipse(innerRect);
|
||||
|
||||
q.setOpacity(1.);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
QRect CornerBadgeTTLRect(int photoSize) {
|
||||
const auto &partSize = st::dialogsTTLBadgeSize;
|
||||
return QRect(
|
||||
photoSize - partSize + st::dialogsTTLBadgeSkip.x(),
|
||||
photoSize - partSize + st::dialogsTTLBadgeSkip.y(),
|
||||
partSize,
|
||||
partSize);
|
||||
}
|
||||
|
||||
Row::CornerLayersManager::CornerLayersManager() = default;
|
||||
|
||||
bool Row::CornerLayersManager::isSameLayer(Layer layer) const {
|
||||
|
@ -214,6 +316,8 @@ void Row::updateCornerBadgeShown(
|
|||
} else if (peer->isChannel()
|
||||
&& Data::ChannelHasActiveCall(peer->asChannel())) {
|
||||
return kTopLayer;
|
||||
} else if (peer->messagesTTL()) {
|
||||
return kBottomLayer;
|
||||
}
|
||||
return kNoneLayer;
|
||||
}();
|
||||
|
@ -250,10 +354,18 @@ void Row::PaintCornerBadgeFrame(
|
|||
context.st->photoSize,
|
||||
context.paused);
|
||||
|
||||
const auto &manager = data->layersManager;
|
||||
if (const auto p = manager.progressForLayer(kBottomLayer); p) {
|
||||
PaintCornerBadgeTTLFrame(q, peer, view, p, context.st->photoSize);
|
||||
}
|
||||
const auto topLayerProgress = manager.progressForLayer(kTopLayer);
|
||||
if (!topLayerProgress) {
|
||||
return;
|
||||
}
|
||||
|
||||
PainterHighQualityEnabler hq(q);
|
||||
q.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
|
||||
const auto progress = data->layersManager.progressForLayer(kTopLayer);
|
||||
const auto size = peer->isUser()
|
||||
? st::dialogsOnlineBadgeSize
|
||||
: st::dialogsCallBadgeSize;
|
||||
|
@ -261,10 +373,10 @@ void Row::PaintCornerBadgeFrame(
|
|||
const auto skip = peer->isUser()
|
||||
? st::dialogsOnlineBadgeSkip
|
||||
: st::dialogsCallBadgeSkip;
|
||||
const auto shrink = (size / 2) * (1. - progress);
|
||||
const auto shrink = (size / 2) * (1. - topLayerProgress);
|
||||
|
||||
auto pen = QPen(Qt::transparent);
|
||||
pen.setWidthF(stroke * progress);
|
||||
pen.setWidthF(stroke * topLayerProgress);
|
||||
q.setPen(pen);
|
||||
q.setBrush(data->active
|
||||
? st::dialogsOnlineBadgeFgActive
|
||||
|
@ -315,7 +427,8 @@ void Row::paintUserpic(
|
|||
QImage::Format_ARGB32_Premultiplied);
|
||||
_cornerBadgeUserpic->frame.setDevicePixelRatio(ratio);
|
||||
}
|
||||
const auto key = peer->userpicUniqueKey(userpicView());
|
||||
auto key = peer->userpicUniqueKey(userpicView());
|
||||
key.first += peer->messagesTTL();
|
||||
const auto frameIndex = videoUserpic ? videoUserpic->frameIndex() : -1;
|
||||
if (!_cornerBadgeUserpic->layersManager.isFinished()
|
||||
|| _cornerBadgeUserpic->key != key
|
||||
|
|
|
@ -40,6 +40,8 @@ namespace Dialogs {
|
|||
|
||||
enum class SortMode;
|
||||
|
||||
[[nodiscard]] QRect CornerBadgeTTLRect(int photoSize);
|
||||
|
||||
class BasicRow {
|
||||
public:
|
||||
BasicRow();
|
||||
|
|
|
@ -2764,6 +2764,9 @@ void History::applyDialog(
|
|||
MsgId(0), // topicRootId
|
||||
draft->c_draftMessage());
|
||||
}
|
||||
if (const auto ttl = data.vttl_period()) {
|
||||
peer->setMessagesTTL(ttl->v);
|
||||
}
|
||||
owner().histories().dialogEntryApplied(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -119,10 +119,10 @@ bool TTLValidator::can() const {
|
|||
&& !_peer->isNotificationsUser()
|
||||
&& !_peer->asUser()->isInaccessible())
|
||||
|| (_peer->isChat()
|
||||
&& _peer->asChat()->canDeleteMessages()
|
||||
&& _peer->asChat()->canEditInformation()
|
||||
&& _peer->asChat()->amIn())
|
||||
|| (_peer->isChannel()
|
||||
&& _peer->asChannel()->canDeleteMessages()
|
||||
&& _peer->asChannel()->canEditInformation()
|
||||
&& _peer->asChannel()->amIn());
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue