mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Emoji status selector in MainMenu/Settings.
This commit is contained in:
parent
64bd4f0926
commit
bd089f20a8
18 changed files with 504 additions and 381 deletions
|
@ -653,27 +653,45 @@ void PeerListRow::invalidatePixmapsCache() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int PeerListRow::nameIconWidth() const {
|
int PeerListRow::paintNameIconGetWidth(
|
||||||
return special()
|
|
||||||
? 0
|
|
||||||
: _peer->isVerified()
|
|
||||||
? st::dialogsVerifiedIcon.width()
|
|
||||||
: (_peer->isPremium() && !_peer->isSelf())
|
|
||||||
? st::dialogsPremiumIcon.width()
|
|
||||||
: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PeerListRow::paintNameIcon(
|
|
||||||
Painter &p,
|
Painter &p,
|
||||||
int x,
|
Fn<void()> repaint,
|
||||||
int y,
|
crl::time now,
|
||||||
|
int nameLeft,
|
||||||
|
int nameTop,
|
||||||
|
int nameWidth,
|
||||||
|
int availableWidth,
|
||||||
int outerWidth,
|
int outerWidth,
|
||||||
bool selected) {
|
bool selected) {
|
||||||
if (_peer->isVerified()) {
|
if (special()
|
||||||
st::dialogsVerifiedIcon.paint(p, x, y, outerWidth);
|
|| _isSavedMessagesChat
|
||||||
} else if (_peer->isPremium() && !_peer->isSelf()) {
|
|| _isRepliesMessagesChat
|
||||||
st::dialogsPremiumIcon.paint(p, x, y, outerWidth);
|
|| !_peer->isUser()) {
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
return _bagde.drawGetWidth(
|
||||||
|
p,
|
||||||
|
QRect(
|
||||||
|
nameLeft,
|
||||||
|
nameTop,
|
||||||
|
availableWidth,
|
||||||
|
st::msgNameStyle.font->height),
|
||||||
|
nameWidth,
|
||||||
|
outerWidth,
|
||||||
|
{
|
||||||
|
.peer = _peer,
|
||||||
|
.verified = &(selected
|
||||||
|
? st::dialogsVerifiedIconOver
|
||||||
|
: st::dialogsVerifiedIcon),
|
||||||
|
.premium = &(selected
|
||||||
|
? st::dialogsPremiumIconOver
|
||||||
|
: st::dialogsPremiumIcon),
|
||||||
|
.scam = &(selected ? st::dialogsScamFgOver : st::dialogsScamFg),
|
||||||
|
.preview = st::windowBgOver->c,
|
||||||
|
.customEmojiRepaint = repaint,
|
||||||
|
.now = now,
|
||||||
|
.paused = false,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerListRow::paintStatusText(
|
void PeerListRow::paintStatusText(
|
||||||
|
@ -829,7 +847,7 @@ PeerListContent::PeerListContent(
|
||||||
|
|
||||||
using UpdateFlag = Data::PeerUpdate::Flag;
|
using UpdateFlag = Data::PeerUpdate::Flag;
|
||||||
_controller->session().changes().peerUpdates(
|
_controller->session().changes().peerUpdates(
|
||||||
UpdateFlag::Name | UpdateFlag::Photo
|
UpdateFlag::Name | UpdateFlag::Photo | UpdateFlag::EmojiStatus
|
||||||
) | rpl::start_with_next([=](const Data::PeerUpdate &update) {
|
) | rpl::start_with_next([=](const Data::PeerUpdate &update) {
|
||||||
if (update.flags & UpdateFlag::Name) {
|
if (update.flags & UpdateFlag::Name) {
|
||||||
handleNameChanged(update.peer);
|
handleNameChanged(update.peer);
|
||||||
|
@ -1564,15 +1582,16 @@ crl::time PeerListContent::paintRow(
|
||||||
- skipRight;
|
- skipRight;
|
||||||
}
|
}
|
||||||
auto statusw = namew;
|
auto statusw = namew;
|
||||||
if (auto iconWidth = row->nameIconWidth()) {
|
namew -= row->paintNameIconGetWidth(
|
||||||
namew -= iconWidth;
|
p,
|
||||||
row->paintNameIcon(
|
[=] { updateRow(row); },
|
||||||
p,
|
now,
|
||||||
namex + qMin(name.maxWidth(), namew),
|
namex,
|
||||||
_st.item.namePosition.y(),
|
_st.item.namePosition.y(),
|
||||||
width(),
|
name.maxWidth(),
|
||||||
selected);
|
namew,
|
||||||
}
|
width(),
|
||||||
|
selected);
|
||||||
auto nameCheckedRatio = row->disabled() ? 0. : row->checkedRatio();
|
auto nameCheckedRatio = row->disabled() ? 0. : row->checkedRatio();
|
||||||
p.setPen(anim::pen(_st.item.nameFg, _st.item.nameFgChecked, nameCheckedRatio));
|
p.setPen(anim::pen(_st.item.nameFg, _st.item.nameFgChecked, nameCheckedRatio));
|
||||||
name.drawLeftElided(p, namex, _st.item.namePosition.y(), namew, width());
|
name.drawLeftElided(p, namex, _st.item.namePosition.y(), namew, width());
|
||||||
|
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "ui/rp_widget.h"
|
#include "ui/rp_widget.h"
|
||||||
#include "ui/empty_userpic.h"
|
#include "ui/empty_userpic.h"
|
||||||
|
#include "ui/unread_badge.h"
|
||||||
#include "boxes/abstract_box.h"
|
#include "boxes/abstract_box.h"
|
||||||
#include "mtproto/sender.h"
|
#include "mtproto/sender.h"
|
||||||
#include "data/data_cloud_file.h"
|
#include "data/data_cloud_file.h"
|
||||||
|
@ -94,11 +95,14 @@ public:
|
||||||
void clearCustomStatus();
|
void clearCustomStatus();
|
||||||
|
|
||||||
// Box interface.
|
// Box interface.
|
||||||
virtual int nameIconWidth() const;
|
virtual int paintNameIconGetWidth(
|
||||||
virtual void paintNameIcon(
|
|
||||||
Painter &p,
|
Painter &p,
|
||||||
int x,
|
Fn<void()> repaint,
|
||||||
int y,
|
crl::time now,
|
||||||
|
int nameLeft,
|
||||||
|
int nameTop,
|
||||||
|
int nameWidth,
|
||||||
|
int availableWidth,
|
||||||
int outerWidth,
|
int outerWidth,
|
||||||
bool selected);
|
bool selected);
|
||||||
|
|
||||||
|
@ -258,6 +262,7 @@ private:
|
||||||
std::unique_ptr<Ui::RoundImageCheckbox> _checkbox;
|
std::unique_ptr<Ui::RoundImageCheckbox> _checkbox;
|
||||||
Ui::Text::String _name;
|
Ui::Text::String _name;
|
||||||
Ui::Text::String _status;
|
Ui::Text::String _status;
|
||||||
|
Ui::PeerBadge _bagde;
|
||||||
StatusType _statusType = StatusType::Online;
|
StatusType _statusType = StatusType::Online;
|
||||||
crl::time _statusValidTill = 0;
|
crl::time _statusValidTill = 0;
|
||||||
base::flat_set<QChar> _nameFirstLetters;
|
base::flat_set<QChar> _nameFirstLetters;
|
||||||
|
|
|
@ -1932,18 +1932,6 @@ auto ParticipantsBoxController::computeType(
|
||||||
? Rights::Admin
|
? Rights::Admin
|
||||||
: Rights::Normal;
|
: Rights::Normal;
|
||||||
result.adminRank = user ? _additional.adminRank(user) : QString();
|
result.adminRank = user ? _additional.adminRank(user) : QString();
|
||||||
using Badge = Info::Profile::Badge;
|
|
||||||
result.badge = !user
|
|
||||||
? Badge::None
|
|
||||||
: user->isScam()
|
|
||||||
? Badge::Scam
|
|
||||||
: user->isFake()
|
|
||||||
? Badge::Fake
|
|
||||||
: user->isVerified()
|
|
||||||
? Badge::Verified
|
|
||||||
: (user->isPremium() && participant->session().premiumBadgesShown())
|
|
||||||
? Badge::Premium
|
|
||||||
: Badge::None;
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1952,7 +1940,8 @@ void ParticipantsBoxController::recomputeTypeFor(
|
||||||
if (_role != Role::Profile) {
|
if (_role != Role::Profile) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (const auto row = delegate()->peerListFindRow(participant->id.value)) {
|
const auto row = delegate()->peerListFindRow(participant->id.value);
|
||||||
|
if (row) {
|
||||||
static_cast<Row*>(row)->setType(computeType(participant));
|
static_cast<Row*>(row)->setType(computeType(participant));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,16 @@ public:
|
||||||
Fn<void()> updateCallback) override;
|
Fn<void()> updateCallback) override;
|
||||||
void rightActionStopLastRipple() override;
|
void rightActionStopLastRipple() override;
|
||||||
|
|
||||||
int nameIconWidth() const override {
|
int paintNameIconGetWidth(
|
||||||
|
Painter &p,
|
||||||
|
Fn<void()> repaint,
|
||||||
|
crl::time now,
|
||||||
|
int nameLeft,
|
||||||
|
int nameTop,
|
||||||
|
int nameWidth,
|
||||||
|
int availableWidth,
|
||||||
|
int outerWidth,
|
||||||
|
bool selected) override {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
QSize rightActionSize() const override {
|
QSize rightActionSize() const override {
|
||||||
|
|
|
@ -227,7 +227,11 @@ void TabbedPanel::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabbedPanel::moveHorizontally() {
|
void TabbedPanel::moveHorizontally() {
|
||||||
const auto right = std::max(parentWidget()->width() - _right, 0);
|
const auto padding = innerPadding();
|
||||||
|
const auto width = innerRect().width() + padding.left() + padding.right();
|
||||||
|
const auto right = std::max(
|
||||||
|
parentWidget()->width() - std::max(_right, width),
|
||||||
|
0);
|
||||||
moveToRight(right, y());
|
moveToRight(right, y());
|
||||||
updateContentHeight();
|
updateContentHeight();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,13 @@ InfoToggle {
|
||||||
rippleAreaPadding: pixels;
|
rippleAreaPadding: pixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InfoPeerBadge {
|
||||||
|
verified: icon;
|
||||||
|
premium: icon;
|
||||||
|
position: point;
|
||||||
|
sizeTag: int;
|
||||||
|
}
|
||||||
|
|
||||||
infoMediaHeaderFg: windowFg;
|
infoMediaHeaderFg: windowFg;
|
||||||
|
|
||||||
infoToggleCheckbox: Checkbox(defaultCheckbox) {
|
infoToggleCheckbox: Checkbox(defaultCheckbox) {
|
||||||
|
@ -306,6 +313,13 @@ infoVerifiedCheck: icon {
|
||||||
};
|
};
|
||||||
infoPremiumStar: icon {{ "profile_premium", profileVerifiedCheckBg }};
|
infoPremiumStar: icon {{ "profile_premium", profileVerifiedCheckBg }};
|
||||||
|
|
||||||
|
infoPeerBadge: InfoPeerBadge {
|
||||||
|
verified: infoVerifiedCheck;
|
||||||
|
premium: infoPremiumStar;
|
||||||
|
position: infoVerifiedCheckPosition;
|
||||||
|
sizeTag: 1; // Large
|
||||||
|
}
|
||||||
|
|
||||||
infoIconFg: windowBoldFg;
|
infoIconFg: windowBoldFg;
|
||||||
|
|
||||||
infoProfileSkip: 7px;
|
infoProfileSkip: 7px;
|
||||||
|
|
|
@ -81,6 +81,217 @@ auto ChatStatusText(int fullCount, int onlineCount, bool isGroup) {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
BadgeView::BadgeView(
|
||||||
|
not_null<QWidget*> parent,
|
||||||
|
const style::InfoPeerBadge &st,
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
Fn<bool()> animationPaused,
|
||||||
|
base::flags<Badge> allowed)
|
||||||
|
: _parent(parent)
|
||||||
|
, _st(st)
|
||||||
|
, _peer(peer)
|
||||||
|
, _allowed(allowed)
|
||||||
|
, _animationPaused(std::move(animationPaused)) {
|
||||||
|
rpl::combine(
|
||||||
|
BadgeValue(peer),
|
||||||
|
EmojiStatusIdValue(peer)
|
||||||
|
) | rpl::start_with_next([=](Badge badge, DocumentId emojiStatusId) {
|
||||||
|
setBadge(badge, emojiStatusId);
|
||||||
|
}, _lifetime);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ui::RpWidget *BadgeView::widget() const {
|
||||||
|
return _view.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BadgeView::setBadge(Badge badge, DocumentId emojiStatusId) {
|
||||||
|
if ((!_peer->session().premiumBadgesShown() && badge == Badge::Premium)
|
||||||
|
|| !(_allowed & badge)) {
|
||||||
|
badge = Badge::None;
|
||||||
|
}
|
||||||
|
if (!(_allowed & badge)) {
|
||||||
|
badge = Badge::None;
|
||||||
|
}
|
||||||
|
if (badge != Badge::Premium) {
|
||||||
|
emojiStatusId = 0;
|
||||||
|
}
|
||||||
|
if (_badge == badge && _emojiStatusId == emojiStatusId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_badge = badge;
|
||||||
|
_emojiStatusId = emojiStatusId;
|
||||||
|
_emojiStatus = nullptr;
|
||||||
|
_view.destroy();
|
||||||
|
if (_badge == Badge::None) {
|
||||||
|
_updated.fire({});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_view.create(_parent);
|
||||||
|
_view->show();
|
||||||
|
switch (_badge) {
|
||||||
|
case Badge::Verified:
|
||||||
|
case Badge::Premium: {
|
||||||
|
if (_emojiStatusId) {
|
||||||
|
using SizeTag = Data::CustomEmojiManager::SizeTag;
|
||||||
|
const auto tag = (_st.sizeTag == 2)
|
||||||
|
? SizeTag::Isolated
|
||||||
|
: (_st.sizeTag == 1)
|
||||||
|
? SizeTag::Large
|
||||||
|
: SizeTag::Normal;
|
||||||
|
_emojiStatus = _peer->owner().customEmojiManager().create(
|
||||||
|
_emojiStatusId,
|
||||||
|
[raw = _view.data()]{ raw->update(); },
|
||||||
|
tag);
|
||||||
|
const auto emoji = Data::FrameSizeFromTag(tag)
|
||||||
|
/ style::DevicePixelRatio();
|
||||||
|
_view->resize(emoji, emoji);
|
||||||
|
_view->paintRequest(
|
||||||
|
) | rpl::start_with_next([=, check = _view.data()]{
|
||||||
|
Painter p(check);
|
||||||
|
_emojiStatus->paint(
|
||||||
|
p,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
crl::now(),
|
||||||
|
st::windowBgOver->c,
|
||||||
|
_animationPaused && _animationPaused());
|
||||||
|
}, _view->lifetime());
|
||||||
|
} else {
|
||||||
|
const auto icon = (_badge == Badge::Verified)
|
||||||
|
? &_st.verified
|
||||||
|
: &_st.premium;
|
||||||
|
_view->resize(icon->size());
|
||||||
|
_view->paintRequest(
|
||||||
|
) | rpl::start_with_next([=, check = _view.data()]{
|
||||||
|
Painter p(check);
|
||||||
|
icon->paint(p, 0, 0, check->width());
|
||||||
|
}, _view->lifetime());
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case Badge::Scam:
|
||||||
|
case Badge::Fake: {
|
||||||
|
const auto fake = (_badge == Badge::Fake);
|
||||||
|
const auto size = Ui::ScamBadgeSize(fake);
|
||||||
|
const auto skip = st::infoVerifiedCheckPosition.x();
|
||||||
|
_view->resize(
|
||||||
|
size.width() + 2 * skip,
|
||||||
|
size.height() + 2 * skip);
|
||||||
|
_view->paintRequest(
|
||||||
|
) | rpl::start_with_next([=, badge = _view.data()]{
|
||||||
|
Painter p(badge);
|
||||||
|
Ui::DrawScamBadge(
|
||||||
|
fake,
|
||||||
|
p,
|
||||||
|
badge->rect().marginsRemoved({ skip, skip, skip, skip }),
|
||||||
|
badge->width(),
|
||||||
|
st::attentionButtonFg);
|
||||||
|
}, _view->lifetime());
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_badge != Badge::Premium || !_premiumClickCallback) {
|
||||||
|
_view->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
} else {
|
||||||
|
_view->setClickedCallback(_premiumClickCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
_updated.fire({});
|
||||||
|
}
|
||||||
|
|
||||||
|
void BadgeView::setPremiumClickCallback(Fn<void()> callback) {
|
||||||
|
_premiumClickCallback = std::move(callback);
|
||||||
|
if (_view && _badge == Badge::Premium) {
|
||||||
|
if (!_premiumClickCallback) {
|
||||||
|
_view->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
} else {
|
||||||
|
_view->setAttribute(Qt::WA_TransparentForMouseEvents, false);
|
||||||
|
_view->setClickedCallback(_premiumClickCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<> BadgeView::updated() const {
|
||||||
|
return _updated.events();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BadgeView::move(int left, int top, int bottom) {
|
||||||
|
if (!_view) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto star = !_emojiStatus
|
||||||
|
&& (_badge == Badge::Premium || _badge == Badge::Verified);
|
||||||
|
const auto fake = !_emojiStatus && !star;
|
||||||
|
const auto skip = fake ? 0 : _st.position.x();
|
||||||
|
const auto badgeLeft = left + skip;
|
||||||
|
const auto badgeTop = top
|
||||||
|
+ (star
|
||||||
|
? st::infoVerifiedCheckPosition.y()
|
||||||
|
: (bottom - top - _view->height()) / 2);
|
||||||
|
_view->moveToLeft(badgeLeft, badgeTop);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmojiStatusPanel::show(
|
||||||
|
not_null<Window::SessionController*> controller,
|
||||||
|
not_null<QWidget*> button) {
|
||||||
|
if (!_panel) {
|
||||||
|
create(controller);
|
||||||
|
|
||||||
|
using namespace rpl::mappers;
|
||||||
|
_panel->shownValue(
|
||||||
|
) | rpl::filter(
|
||||||
|
!_1
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
button->removeEventFilter(_panel.get());
|
||||||
|
}, _panel->lifetime());
|
||||||
|
}
|
||||||
|
const auto parent = _panel->parentWidget();
|
||||||
|
const auto global = button->mapToGlobal({ 0, 0 });
|
||||||
|
const auto local = parent->mapFromGlobal(global);
|
||||||
|
_panel->moveTopRight(
|
||||||
|
local.y() + button->height(),
|
||||||
|
local.x() + button->width() * 3);
|
||||||
|
_panel->toggleAnimated();
|
||||||
|
button->installEventFilter(_panel.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmojiStatusPanel::create(
|
||||||
|
not_null<Window::SessionController*> controller) {
|
||||||
|
using Selector = ChatHelpers::TabbedSelector;
|
||||||
|
_panel = base::make_unique_q<ChatHelpers::TabbedPanel>(
|
||||||
|
controller->window().widget()->bodyWidget(),
|
||||||
|
controller,
|
||||||
|
object_ptr<Selector>(
|
||||||
|
nullptr,
|
||||||
|
controller,
|
||||||
|
Window::GifPauseReason::Layer,
|
||||||
|
ChatHelpers::TabbedSelector::Mode::EmojiStatus));
|
||||||
|
_panel->setDropDown(true);
|
||||||
|
_panel->setDesiredHeightValues(
|
||||||
|
1.,
|
||||||
|
st::emojiPanMinHeight / 2,
|
||||||
|
st::emojiPanMinHeight);
|
||||||
|
_panel->hide();
|
||||||
|
_panel->selector()->setAllowEmojiWithoutPremium(false);
|
||||||
|
|
||||||
|
auto statusChosen = _panel->selector()->customEmojiChosen(
|
||||||
|
) | rpl::map([=](Selector::FileChosen data) {
|
||||||
|
return data.document->id;
|
||||||
|
});
|
||||||
|
|
||||||
|
rpl::merge(
|
||||||
|
std::move(statusChosen),
|
||||||
|
_panel->selector()->emojiChosen() | rpl::map_to(DocumentId())
|
||||||
|
) | rpl::start_with_next([=](DocumentId id) {
|
||||||
|
controller->session().user()->setEmojiStatus(id);
|
||||||
|
controller->session().api().request(MTPaccount_UpdateEmojiStatus(
|
||||||
|
id ? MTP_emojiStatus(MTP_long(id)) : MTP_emojiStatusEmpty()
|
||||||
|
)).send();
|
||||||
|
_panel->hideAnimated();
|
||||||
|
}, _panel->lifetime());
|
||||||
|
|
||||||
|
_panel->selector()->showPromoForPremiumEmoji();
|
||||||
|
}
|
||||||
|
|
||||||
Cover::Cover(
|
Cover::Cover(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
|
@ -104,6 +315,14 @@ Cover::Cover(
|
||||||
+ st::infoProfilePhotoBottom)
|
+ st::infoProfilePhotoBottom)
|
||||||
, _controller(controller)
|
, _controller(controller)
|
||||||
, _peer(peer)
|
, _peer(peer)
|
||||||
|
, _badge(
|
||||||
|
this,
|
||||||
|
st::infoPeerBadge,
|
||||||
|
peer,
|
||||||
|
[=] {
|
||||||
|
return controller->isGifPausedAtLeastFor(
|
||||||
|
Window::GifPauseReason::Layer);
|
||||||
|
})
|
||||||
, _userpic(
|
, _userpic(
|
||||||
this,
|
this,
|
||||||
controller,
|
controller,
|
||||||
|
@ -126,6 +345,19 @@ Cover::Cover(
|
||||||
_status->setAttribute(Qt::WA_TransparentForMouseEvents);
|
_status->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_badge.setPremiumClickCallback([=] {
|
||||||
|
if (_peer->isSelf()) {
|
||||||
|
_emojiStatusPanel.show(_controller, _badge.widget());
|
||||||
|
} else {
|
||||||
|
::Settings::ShowPremium(
|
||||||
|
_controller,
|
||||||
|
u"profile__%1"_q.arg(peerToUser(_peer->id).bare));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
_badge.updated() | rpl::start_with_next([=] {
|
||||||
|
refreshNameGeometry(width());
|
||||||
|
}, _name->lifetime());
|
||||||
|
|
||||||
initViewers(std::move(title));
|
initViewers(std::move(title));
|
||||||
setupChildGeometry();
|
setupChildGeometry();
|
||||||
|
|
||||||
|
@ -184,12 +416,6 @@ void Cover::initViewers(rpl::producer<QString> title) {
|
||||||
} else if (_peer->isSelf()) {
|
} else if (_peer->isSelf()) {
|
||||||
refreshUploadPhotoOverlay();
|
refreshUploadPhotoOverlay();
|
||||||
}
|
}
|
||||||
rpl::combine(
|
|
||||||
BadgeValue(_peer),
|
|
||||||
EmojiStatusIdValue(_peer)
|
|
||||||
) | rpl::start_with_next([=](Badge badge, DocumentId emojiStatusId) {
|
|
||||||
setBadge(badge, emojiStatusId);
|
|
||||||
}, lifetime());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cover::refreshUploadPhotoOverlay() {
|
void Cover::refreshUploadPhotoOverlay() {
|
||||||
|
@ -203,151 +429,6 @@ void Cover::refreshUploadPhotoOverlay() {
|
||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cover::setBadge(Badge badge, DocumentId emojiStatusId) {
|
|
||||||
if (!_peer->session().premiumBadgesShown() && badge == Badge::Premium) {
|
|
||||||
badge = Badge::None;
|
|
||||||
}
|
|
||||||
if (badge != Badge::Premium) {
|
|
||||||
emojiStatusId = 0;
|
|
||||||
}
|
|
||||||
if (_badge == badge && _emojiStatusId == emojiStatusId) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_badge = badge;
|
|
||||||
_emojiStatusId = emojiStatusId;
|
|
||||||
_emojiStatus = nullptr;
|
|
||||||
_badgeView.destroy();
|
|
||||||
switch (_badge) {
|
|
||||||
case Badge::Verified:
|
|
||||||
case Badge::Premium: {
|
|
||||||
_badgeView.create(this);
|
|
||||||
_badgeView->show();
|
|
||||||
if (_emojiStatusId) {
|
|
||||||
auto &owner = _controller->session().data();
|
|
||||||
_emojiStatus = owner.customEmojiManager().create(
|
|
||||||
_emojiStatusId,
|
|
||||||
[raw = _badgeView.data()]{ raw->update(); },
|
|
||||||
Data::CustomEmojiManager::SizeTag::Large);
|
|
||||||
const auto size = Ui::Emoji::GetSizeLarge()
|
|
||||||
/ style::DevicePixelRatio();
|
|
||||||
const auto emoji = Ui::Text::AdjustCustomEmojiSize(size);
|
|
||||||
_badgeView->resize(emoji, emoji);
|
|
||||||
_badgeView->paintRequest(
|
|
||||||
) | rpl::start_with_next([=, check = _badgeView.data()]{
|
|
||||||
Painter p(check);
|
|
||||||
_emojiStatus->paint(
|
|
||||||
p,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
crl::now(),
|
|
||||||
st::windowBgOver->c,
|
|
||||||
_controller->isGifPausedAtLeastFor(
|
|
||||||
Window::GifPauseReason::Layer));
|
|
||||||
}, _badgeView->lifetime());
|
|
||||||
} else {
|
|
||||||
const auto icon = (_badge == Badge::Verified)
|
|
||||||
? &st::infoVerifiedCheck
|
|
||||||
: &st::infoPremiumStar;
|
|
||||||
_badgeView->resize(icon->size());
|
|
||||||
_badgeView->paintRequest(
|
|
||||||
) | rpl::start_with_next([=, check = _badgeView.data()]{
|
|
||||||
Painter p(check);
|
|
||||||
icon->paint(p, 0, 0, check->width());
|
|
||||||
}, _badgeView->lifetime());
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case Badge::Scam:
|
|
||||||
case Badge::Fake: {
|
|
||||||
const auto fake = (_badge == Badge::Fake);
|
|
||||||
const auto size = Ui::ScamBadgeSize(fake);
|
|
||||||
const auto skip = st::infoVerifiedCheckPosition.x();
|
|
||||||
_badgeView.create(this);
|
|
||||||
_badgeView->show();
|
|
||||||
_badgeView->resize(
|
|
||||||
size.width() + 2 * skip,
|
|
||||||
size.height() + 2 * skip);
|
|
||||||
_badgeView->paintRequest(
|
|
||||||
) | rpl::start_with_next([=, badge = _badgeView.data()]{
|
|
||||||
Painter p(badge);
|
|
||||||
Ui::DrawScamBadge(
|
|
||||||
fake,
|
|
||||||
p,
|
|
||||||
badge->rect().marginsRemoved({ skip, skip, skip, skip }),
|
|
||||||
badge->width(),
|
|
||||||
st::attentionButtonFg);
|
|
||||||
}, _badgeView->lifetime());
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_badge == Badge::Premium) {
|
|
||||||
const auto userId = peerToUser(_peer->id).bare;
|
|
||||||
_badgeView->setClickedCallback([=] {
|
|
||||||
if (_peer->isSelf()) {
|
|
||||||
showEmojiStatusSelector();
|
|
||||||
} else {
|
|
||||||
::Settings::ShowPremium(
|
|
||||||
_controller,
|
|
||||||
u"profile__%1"_q.arg(userId));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
_badgeView->setAttribute(Qt::WA_TransparentForMouseEvents);
|
|
||||||
}
|
|
||||||
|
|
||||||
refreshNameGeometry(width());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cover::showEmojiStatusSelector() {
|
|
||||||
Expects(_badgeView != nullptr);
|
|
||||||
|
|
||||||
if (!_emojiStatusPanel) {
|
|
||||||
createEmojiStatusSelector();
|
|
||||||
}
|
|
||||||
const auto parent = _emojiStatusPanel->parentWidget();
|
|
||||||
const auto global = _badgeView->mapToGlobal({ 0, 0 });
|
|
||||||
const auto local = parent->mapFromGlobal(global);
|
|
||||||
_emojiStatusPanel->moveTopRight(
|
|
||||||
local.y() + _badgeView->height(),
|
|
||||||
local.x() + _badgeView->width() * 3);
|
|
||||||
_emojiStatusPanel->toggleAnimated();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cover::createEmojiStatusSelector() {
|
|
||||||
const auto set = [=](DocumentId id) {
|
|
||||||
_controller->session().user()->setEmojiStatus(id);
|
|
||||||
_controller->session().api().request(MTPaccount_UpdateEmojiStatus(
|
|
||||||
id ? MTP_emojiStatus(MTP_long(id)) : MTP_emojiStatusEmpty()
|
|
||||||
)).send();
|
|
||||||
_emojiStatusPanel->hideAnimated();
|
|
||||||
};
|
|
||||||
const auto container = _controller->window().widget()->bodyWidget();
|
|
||||||
using Selector = ChatHelpers::TabbedSelector;
|
|
||||||
_emojiStatusPanel = base::make_unique_q<ChatHelpers::TabbedPanel>(
|
|
||||||
container,
|
|
||||||
_controller,
|
|
||||||
object_ptr<Selector>(
|
|
||||||
nullptr,
|
|
||||||
_controller,
|
|
||||||
Window::GifPauseReason::Layer,
|
|
||||||
ChatHelpers::TabbedSelector::Mode::EmojiStatus));
|
|
||||||
_emojiStatusPanel->setDropDown(true);
|
|
||||||
_emojiStatusPanel->setDesiredHeightValues(
|
|
||||||
1.,
|
|
||||||
st::emojiPanMinHeight / 2,
|
|
||||||
st::emojiPanMinHeight);
|
|
||||||
_emojiStatusPanel->hide();
|
|
||||||
_emojiStatusPanel->selector()->setAllowEmojiWithoutPremium(false);
|
|
||||||
_emojiStatusPanel->selector()->emojiChosen(
|
|
||||||
) | rpl::start_with_next([=] {
|
|
||||||
set(0);
|
|
||||||
}, _emojiStatusPanel->lifetime());
|
|
||||||
_emojiStatusPanel->selector()->customEmojiChosen(
|
|
||||||
) | rpl::start_with_next([=](Selector::FileChosen data) {
|
|
||||||
set(data.document->id);
|
|
||||||
}, _emojiStatusPanel->lifetime());
|
|
||||||
_emojiStatusPanel->selector()->showPromoForPremiumEmoji();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cover::refreshStatusText() {
|
void Cover::refreshStatusText() {
|
||||||
auto hasMembersLink = [&] {
|
auto hasMembersLink = [&] {
|
||||||
if (auto megagroup = _peer->asMegagroup()) {
|
if (auto megagroup = _peer->asMegagroup()) {
|
||||||
|
@ -406,23 +487,15 @@ void Cover::refreshNameGeometry(int newWidth) {
|
||||||
auto nameWidth = newWidth
|
auto nameWidth = newWidth
|
||||||
- nameLeft
|
- nameLeft
|
||||||
- st::infoProfileNameRight;
|
- st::infoProfileNameRight;
|
||||||
if (_badgeView) {
|
if (const auto width = _badge.widget() ? _badge.widget()->width() : 0) {
|
||||||
nameWidth -= st::infoVerifiedCheckPosition.x() + _badgeView->width();
|
nameWidth -= st::infoVerifiedCheckPosition.x() + width;
|
||||||
}
|
}
|
||||||
_name->resizeToNaturalWidth(nameWidth);
|
_name->resizeToNaturalWidth(nameWidth);
|
||||||
_name->moveToLeft(nameLeft, nameTop, newWidth);
|
_name->moveToLeft(nameLeft, nameTop, newWidth);
|
||||||
if (_badgeView) {
|
const auto badgeLeft = nameLeft + _name->width();
|
||||||
const auto star = !_emojiStatus
|
const auto badgeTop = nameTop;
|
||||||
&& (_badge == Badge::Premium || _badge == Badge::Verified);
|
const auto badgeBottom = nameTop + _name->height();
|
||||||
const auto fake = !_emojiStatus && !star;
|
_badge.move(badgeLeft, badgeTop, badgeBottom);
|
||||||
const auto skip = fake ? 0 : st::infoVerifiedCheckPosition.x();
|
|
||||||
const auto badgeLeft = nameLeft + _name->width() + skip;
|
|
||||||
const auto badgeTop = nameTop
|
|
||||||
+ (star
|
|
||||||
? st::infoVerifiedCheckPosition.y()
|
|
||||||
: (_name->height() - _badgeView->height()) / 2);
|
|
||||||
_badgeView->moveToLeft(badgeLeft, badgeTop, newWidth);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cover::refreshStatusGeometry(int newWidth) {
|
void Cover::refreshStatusGeometry(int newWidth) {
|
||||||
|
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/wrap/padding_wrap.h"
|
#include "ui/wrap/padding_wrap.h"
|
||||||
#include "ui/widgets/checkbox.h"
|
#include "ui/widgets/checkbox.h"
|
||||||
#include "base/timer.h"
|
#include "base/timer.h"
|
||||||
|
#include "base/flags.h"
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
class SessionController;
|
class SessionController;
|
||||||
|
@ -17,6 +18,7 @@ class SessionController;
|
||||||
|
|
||||||
namespace style {
|
namespace style {
|
||||||
struct InfoToggle;
|
struct InfoToggle;
|
||||||
|
struct InfoPeerBadge;
|
||||||
} // namespace style
|
} // namespace style
|
||||||
|
|
||||||
namespace ChatHelpers {
|
namespace ChatHelpers {
|
||||||
|
@ -39,9 +41,62 @@ class Section;
|
||||||
namespace Info {
|
namespace Info {
|
||||||
namespace Profile {
|
namespace Profile {
|
||||||
|
|
||||||
enum class Badge;
|
enum class Badge {
|
||||||
|
None = 0x00,
|
||||||
|
Verified = 0x01,
|
||||||
|
Premium = 0x02,
|
||||||
|
Scam = 0x04,
|
||||||
|
Fake = 0x08,
|
||||||
|
};
|
||||||
|
inline constexpr bool is_flag_type(Badge) { return true; }
|
||||||
|
|
||||||
class Cover : public Ui::FixedHeightWidget {
|
class BadgeView final {
|
||||||
|
public:
|
||||||
|
BadgeView(
|
||||||
|
not_null<QWidget*> parent,
|
||||||
|
const style::InfoPeerBadge &st,
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
Fn<bool()> animationPaused,
|
||||||
|
base::flags<Badge> allowed = base::flags<Badge>::from_raw(-1));
|
||||||
|
|
||||||
|
[[nodiscard]] Ui::RpWidget *widget() const;
|
||||||
|
|
||||||
|
void setPremiumClickCallback(Fn<void()> callback);
|
||||||
|
[[nodiscrd]] rpl::producer<> updated() const;
|
||||||
|
void move(int left, int top, int bottom);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setBadge(Badge badge, DocumentId emojiStatusId);
|
||||||
|
|
||||||
|
const not_null<QWidget*> _parent;
|
||||||
|
const style::InfoPeerBadge &_st;
|
||||||
|
const not_null<PeerData*> _peer;
|
||||||
|
DocumentId _emojiStatusId = 0;
|
||||||
|
std::unique_ptr<Ui::Text::CustomEmoji> _emojiStatus;
|
||||||
|
base::flags<Badge> _allowed;
|
||||||
|
Badge _badge = Badge();
|
||||||
|
Fn<void()> _premiumClickCallback;
|
||||||
|
Fn<bool()> _animationPaused;
|
||||||
|
object_ptr<Ui::AbstractButton> _view = { nullptr };
|
||||||
|
rpl::event_stream<> _updated;
|
||||||
|
rpl::lifetime _lifetime;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class EmojiStatusPanel final {
|
||||||
|
public:
|
||||||
|
void show(
|
||||||
|
not_null<Window::SessionController*> controller,
|
||||||
|
not_null<QWidget*> button);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void create(not_null<Window::SessionController*> controller);
|
||||||
|
|
||||||
|
base::unique_qptr<ChatHelpers::TabbedPanel> _panel;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class Cover final : public Ui::FixedHeightWidget {
|
||||||
public:
|
public:
|
||||||
Cover(
|
Cover(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
|
@ -68,21 +123,15 @@ private:
|
||||||
void refreshNameGeometry(int newWidth);
|
void refreshNameGeometry(int newWidth);
|
||||||
void refreshStatusGeometry(int newWidth);
|
void refreshStatusGeometry(int newWidth);
|
||||||
void refreshUploadPhotoOverlay();
|
void refreshUploadPhotoOverlay();
|
||||||
void setBadge(Badge badge, DocumentId emojiStatusId);
|
|
||||||
void createEmojiStatusSelector();
|
|
||||||
void showEmojiStatusSelector();
|
|
||||||
|
|
||||||
const not_null<Window::SessionController*> _controller;
|
const not_null<Window::SessionController*> _controller;
|
||||||
const not_null<PeerData*> _peer;
|
const not_null<PeerData*> _peer;
|
||||||
DocumentId _emojiStatusId = 0;
|
BadgeView _badge;
|
||||||
std::unique_ptr<Ui::Text::CustomEmoji> _emojiStatus;
|
EmojiStatusPanel _emojiStatusPanel;
|
||||||
base::unique_qptr<ChatHelpers::TabbedPanel> _emojiStatusPanel;
|
|
||||||
int _onlineCount = 0;
|
int _onlineCount = 0;
|
||||||
Badge _badge = Badge();
|
|
||||||
|
|
||||||
object_ptr<Ui::UserpicButton> _userpic;
|
object_ptr<Ui::UserpicButton> _userpic;
|
||||||
object_ptr<Ui::FlatLabel> _name = { nullptr };
|
object_ptr<Ui::FlatLabel> _name = { nullptr };
|
||||||
object_ptr<Ui::AbstractButton> _badgeView = { nullptr };
|
|
||||||
object_ptr<Ui::FlatLabel> _status = { nullptr };
|
object_ptr<Ui::FlatLabel> _status = { nullptr };
|
||||||
//object_ptr<CoverDropArea> _dropArea = { nullptr };
|
//object_ptr<CoverDropArea> _dropArea = { nullptr };
|
||||||
base::Timer _refreshStatusTimer;
|
base::Timer _refreshStatusTimer;
|
||||||
|
|
|
@ -30,11 +30,6 @@ MemberListRow::MemberListRow(
|
||||||
|
|
||||||
void MemberListRow::setType(Type type) {
|
void MemberListRow::setType(Type type) {
|
||||||
_type = type;
|
_type = type;
|
||||||
_fakeScamSize = (_type.badge == Badge::Fake)
|
|
||||||
? Ui::ScamBadgeSize(true)
|
|
||||||
: (_type.badge == Badge::Scam)
|
|
||||||
? Ui::ScamBadgeSize(false)
|
|
||||||
: QSize();
|
|
||||||
PeerListRowWithLink::setActionLink(!_type.adminRank.isEmpty()
|
PeerListRowWithLink::setActionLink(!_type.adminRank.isEmpty()
|
||||||
? _type.adminRank
|
? _type.adminRank
|
||||||
: (_type.rights == Rights::Creator)
|
: (_type.rights == Rights::Creator)
|
||||||
|
@ -57,55 +52,10 @@ QMargins MemberListRow::rightActionMargins() const {
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MemberListRow::nameIconWidth() const {
|
|
||||||
switch (_type.badge) {
|
|
||||||
case Badge::None: return 0;
|
|
||||||
case Badge::Verified: return st::dialogsVerifiedIcon.width();
|
|
||||||
case Badge::Premium: return st::dialogsPremiumIcon.width();
|
|
||||||
case Badge::Scam:
|
|
||||||
case Badge::Fake:
|
|
||||||
return st::dialogsScamSkip + _fakeScamSize.width();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
not_null<UserData*> MemberListRow::user() const {
|
not_null<UserData*> MemberListRow::user() const {
|
||||||
return peer()->asUser();
|
return peer()->asUser();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemberListRow::paintNameIcon(
|
|
||||||
Painter &p,
|
|
||||||
int x,
|
|
||||||
int y,
|
|
||||||
int outerWidth,
|
|
||||||
bool selected) {
|
|
||||||
switch (_type.badge) {
|
|
||||||
case Badge::None: return;
|
|
||||||
case Badge::Verified:
|
|
||||||
(selected
|
|
||||||
? st::dialogsVerifiedIconOver
|
|
||||||
: st::dialogsVerifiedIcon).paint(p, x, y, outerWidth);
|
|
||||||
break;
|
|
||||||
case Badge::Premium:
|
|
||||||
(selected
|
|
||||||
? st::dialogsPremiumIconOver
|
|
||||||
: st::dialogsPremiumIcon).paint(p, x, y, outerWidth);
|
|
||||||
break;
|
|
||||||
case Badge::Scam:
|
|
||||||
case Badge::Fake:
|
|
||||||
return Ui::DrawScamBadge(
|
|
||||||
(_type.badge == Badge::Fake),
|
|
||||||
p,
|
|
||||||
QRect(
|
|
||||||
x + st::dialogsScamSkip,
|
|
||||||
y + (st::normalFont->height - _fakeScamSize.height()) / 2,
|
|
||||||
_fakeScamSize.width(),
|
|
||||||
_fakeScamSize.height()),
|
|
||||||
outerWidth,
|
|
||||||
(selected ? st::dialogsScamFgOver : st::dialogsScamFg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MemberListRow::refreshStatus() {
|
void MemberListRow::refreshStatus() {
|
||||||
if (user()->isBot()) {
|
if (user()->isBot()) {
|
||||||
const auto seesAllMessages = (user()->botInfo->readsAllHistory
|
const auto seesAllMessages = (user()->botInfo->readsAllHistory
|
||||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "boxes/peer_list_controllers.h"
|
#include "boxes/peer_list_controllers.h"
|
||||||
|
#include "ui/unread_badge.h"
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
class SessionNavigation;
|
class SessionNavigation;
|
||||||
|
@ -16,8 +17,6 @@ class SessionNavigation;
|
||||||
namespace Info {
|
namespace Info {
|
||||||
namespace Profile {
|
namespace Profile {
|
||||||
|
|
||||||
enum class Badge;
|
|
||||||
|
|
||||||
class MemberListRow final : public PeerListRowWithLink {
|
class MemberListRow final : public PeerListRowWithLink {
|
||||||
public:
|
public:
|
||||||
enum class Rights {
|
enum class Rights {
|
||||||
|
@ -26,7 +25,6 @@ public:
|
||||||
Creator,
|
Creator,
|
||||||
};
|
};
|
||||||
struct Type {
|
struct Type {
|
||||||
Badge badge;
|
|
||||||
Rights rights;
|
Rights rights;
|
||||||
QString adminRank;
|
QString adminRank;
|
||||||
};
|
};
|
||||||
|
@ -36,20 +34,12 @@ public:
|
||||||
void setType(Type type);
|
void setType(Type type);
|
||||||
bool rightActionDisabled() const override;
|
bool rightActionDisabled() const override;
|
||||||
QMargins rightActionMargins() const override;
|
QMargins rightActionMargins() const override;
|
||||||
int nameIconWidth() const override;
|
|
||||||
void paintNameIcon(
|
|
||||||
Painter &p,
|
|
||||||
int x,
|
|
||||||
int y,
|
|
||||||
int outerWidth,
|
|
||||||
bool selected) override;
|
|
||||||
void refreshStatus() override;
|
void refreshStatus() override;
|
||||||
|
|
||||||
not_null<UserData*> user() const;
|
not_null<UserData*> user() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Type _type;
|
Type _type;
|
||||||
QSize _fakeScamSize;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "info/profile/info_profile_values.h"
|
#include "info/profile/info_profile_values.h"
|
||||||
|
|
||||||
|
#include "info/profile/info_profile_cover.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "core/click_handler_types.h"
|
#include "core/click_handler_types.h"
|
||||||
#include "countries/countries_instance.h"
|
#include "countries/countries_instance.h"
|
||||||
|
|
|
@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "base/flags.h"
|
||||||
|
|
||||||
#include <rpl/producer.h>
|
#include <rpl/producer.h>
|
||||||
#include <rpl/map.h>
|
#include <rpl/map.h>
|
||||||
|
|
||||||
|
@ -90,13 +92,7 @@ rpl::producer<not_null<PeerData*>> MigratedOrMeValue(
|
||||||
[[nodiscard]] rpl::producer<int> AllowedReactionsCountValue(
|
[[nodiscard]] rpl::producer<int> AllowedReactionsCountValue(
|
||||||
not_null<PeerData*> peer);
|
not_null<PeerData*> peer);
|
||||||
|
|
||||||
enum class Badge {
|
enum class Badge;
|
||||||
None,
|
|
||||||
Verified,
|
|
||||||
Premium,
|
|
||||||
Scam,
|
|
||||||
Fake,
|
|
||||||
};
|
|
||||||
[[nodiscard]] rpl::producer<Badge> BadgeValue(not_null<PeerData*> peer);
|
[[nodiscard]] rpl::producer<Badge> BadgeValue(not_null<PeerData*> peer);
|
||||||
[[nodiscard]] rpl::producer<DocumentId> EmojiStatusIdValue(
|
[[nodiscard]] rpl::producer<DocumentId> EmojiStatusIdValue(
|
||||||
not_null<PeerData*> peer);
|
not_null<PeerData*> peer);
|
||||||
|
|
|
@ -184,6 +184,10 @@ settingsInfoPhotoTop: 0px;
|
||||||
settingsInfoPhotoSkip: 7px;
|
settingsInfoPhotoSkip: 7px;
|
||||||
settingsInfoNameSkip: -1px;
|
settingsInfoNameSkip: -1px;
|
||||||
settingsInfoUploadLeft: 6px;
|
settingsInfoUploadLeft: 6px;
|
||||||
|
settingsInfoPeerBadge: InfoPeerBadge {
|
||||||
|
verified: icon {{ "dialogs/dialogs_premium", dialogsVerifiedIconBg }};
|
||||||
|
sizeTag: 0; // Normal
|
||||||
|
}
|
||||||
|
|
||||||
settingsBio: InputField(defaultInputField) {
|
settingsBio: InputField(defaultInputField) {
|
||||||
textBg: transparent;
|
textBg: transparent;
|
||||||
|
|
|
@ -36,6 +36,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_premium_limits.h"
|
#include "data/data_premium_limits.h"
|
||||||
#include "dialogs/ui/dialogs_layout.h"
|
#include "dialogs/ui/dialogs_layout.h"
|
||||||
#include "info/profile/info_profile_values.h"
|
#include "info/profile/info_profile_values.h"
|
||||||
|
#include "info/profile/info_profile_cover.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "main/main_account.h"
|
#include "main/main_account.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
|
@ -71,7 +72,8 @@ public:
|
||||||
not_null<Ui::SettingsButton*> button,
|
not_null<Ui::SettingsButton*> button,
|
||||||
not_null<Main::Session*> session,
|
not_null<Main::Session*> session,
|
||||||
rpl::producer<QString> &&text,
|
rpl::producer<QString> &&text,
|
||||||
bool hasUnread);
|
bool hasUnread,
|
||||||
|
Fn<bool()> animationPaused);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
rpl::variable<QString> _text;
|
rpl::variable<QString> _text;
|
||||||
|
@ -79,7 +81,7 @@ private:
|
||||||
rpl::event_stream<int> _premiumWidth;
|
rpl::event_stream<int> _premiumWidth;
|
||||||
|
|
||||||
QPointer<Ui::RpWidget> _unread;
|
QPointer<Ui::RpWidget> _unread;
|
||||||
QPointer<Ui::RpWidget> _premium;
|
Info::Profile::BadgeView _badge;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -88,9 +90,16 @@ ComposedBadge::ComposedBadge(
|
||||||
not_null<Ui::SettingsButton*> button,
|
not_null<Ui::SettingsButton*> button,
|
||||||
not_null<Main::Session*> session,
|
not_null<Main::Session*> session,
|
||||||
rpl::producer<QString> &&text,
|
rpl::producer<QString> &&text,
|
||||||
bool hasUnread)
|
bool hasUnread,
|
||||||
|
Fn<bool()> animationPaused)
|
||||||
: Ui::RpWidget(parent)
|
: Ui::RpWidget(parent)
|
||||||
, _text(std::move(text)) {
|
, _text(std::move(text))
|
||||||
|
, _badge(
|
||||||
|
this,
|
||||||
|
st::settingsInfoPeerBadge,
|
||||||
|
session->user(),
|
||||||
|
std::move(animationPaused),
|
||||||
|
Info::Profile::Badge::Premium) {
|
||||||
if (hasUnread) {
|
if (hasUnread) {
|
||||||
_unread = CreateUnread(this, rpl::single(
|
_unread = CreateUnread(this, rpl::single(
|
||||||
rpl::empty
|
rpl::empty
|
||||||
|
@ -111,35 +120,19 @@ ComposedBadge::ComposedBadge(
|
||||||
}) | rpl::start_to_stream(_unreadWidth, _unread->lifetime());
|
}) | rpl::start_to_stream(_unreadWidth, _unread->lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
Data::AmPremiumValue(
|
_badge.updated(
|
||||||
session
|
) | rpl::start_with_next([=] {
|
||||||
) | rpl::start_with_next([=](bool hasPremium) {
|
if (const auto button = _badge.widget()) {
|
||||||
if (hasPremium && !_premium) {
|
button->widthValue(
|
||||||
_premium = Ui::CreateChild<Ui::RpWidget>(this);
|
) | rpl::start_to_stream(_premiumWidth, button->lifetime());
|
||||||
const auto offset = st::dialogsPremiumIconOffset;
|
} else {
|
||||||
_premium->resize(
|
|
||||||
st::dialogsPremiumIcon.width() - offset.x(),
|
|
||||||
st::dialogsPremiumIcon.height() - offset.y());
|
|
||||||
_premium->paintRequest(
|
|
||||||
) | rpl::start_with_next([=](const QRect &r) {
|
|
||||||
Painter p(_premium);
|
|
||||||
st::dialogsPremiumIcon.paint(
|
|
||||||
p,
|
|
||||||
-offset.x(),
|
|
||||||
-offset.y(),
|
|
||||||
_premium->width());
|
|
||||||
}, _premium->lifetime());
|
|
||||||
_premium->widthValue(
|
|
||||||
) | rpl::start_to_stream(_premiumWidth, _premium->lifetime());
|
|
||||||
} else if (!hasPremium && _premium) {
|
|
||||||
_premium = nullptr;
|
|
||||||
_premiumWidth.fire(0);
|
_premiumWidth.fire(0);
|
||||||
}
|
}
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
rpl::combine(
|
rpl::combine(
|
||||||
_unreadWidth.events_starting_with(_unread ? _unread->width() : 0),
|
_unreadWidth.events_starting_with(_unread ? _unread->width() : 0),
|
||||||
_premiumWidth.events_starting_with(_premium ? _premium->width() : 0),
|
_premiumWidth.events_starting_with(0),
|
||||||
_text.value(),
|
_text.value(),
|
||||||
button->sizeValue()
|
button->sizeValue()
|
||||||
) | rpl::start_with_next([=](
|
) | rpl::start_with_next([=](
|
||||||
|
@ -151,7 +144,7 @@ ComposedBadge::ComposedBadge(
|
||||||
const auto skip = st.style.font->spacew;
|
const auto skip = st.style.font->spacew;
|
||||||
const auto textRightPosition = st.padding.left()
|
const auto textRightPosition = st.padding.left()
|
||||||
+ st.style.font->width(text)
|
+ st.style.font->width(text)
|
||||||
+ skip * 2;
|
+ skip;
|
||||||
const auto minWidth = unreadWidth + premiumWidth + skip;
|
const auto minWidth = unreadWidth + premiumWidth + skip;
|
||||||
const auto maxTextWidth = buttonSize.width()
|
const auto maxTextWidth = buttonSize.width()
|
||||||
- minWidth
|
- minWidth
|
||||||
|
@ -163,9 +156,7 @@ ComposedBadge::ComposedBadge(
|
||||||
buttonSize.width() - st.padding.right() - finalTextRight,
|
buttonSize.width() - st.padding.right() - finalTextRight,
|
||||||
buttonSize.height());
|
buttonSize.height());
|
||||||
|
|
||||||
if (_premium) {
|
_badge.move(0, 0, buttonSize.height());
|
||||||
_premium->moveToLeft(0, st.padding.top());
|
|
||||||
}
|
|
||||||
if (_unread) {
|
if (_unread) {
|
||||||
_unread->moveToRight(
|
_unread->moveToRight(
|
||||||
0,
|
0,
|
||||||
|
@ -618,7 +609,9 @@ void SetupAccountsWrap(
|
||||||
raw,
|
raw,
|
||||||
session,
|
session,
|
||||||
std::move(text),
|
std::move(text),
|
||||||
!active);
|
!active,
|
||||||
|
[=] { return window->isGifPausedAtLeastFor(
|
||||||
|
Window::GifPauseReason::Layer); });
|
||||||
composedBadge->sizeValue(
|
composedBadge->sizeValue(
|
||||||
) | rpl::start_with_next([=](const QSize &s) {
|
) | rpl::start_with_next([=](const QSize &s) {
|
||||||
container->resize(s);
|
container->resize(s);
|
||||||
|
@ -986,9 +979,7 @@ not_null<Ui::RpWidget*> AddRight(
|
||||||
padding.right(),
|
padding.right(),
|
||||||
(outer.height() - inner.height()) / 2,
|
(outer.height() - inner.height()) / 2,
|
||||||
outer.width());
|
outer.width());
|
||||||
padding.setRight(padding.right()
|
padding.setRight(padding.right() + inner.width());
|
||||||
+ inner.width()
|
|
||||||
+ button->st().style.font->spacew);
|
|
||||||
}
|
}
|
||||||
button->setPaddingOverride(padding);
|
button->setPaddingOverride(padding);
|
||||||
button->update();
|
button->update();
|
||||||
|
|
|
@ -85,12 +85,13 @@ private:
|
||||||
|
|
||||||
const not_null<Window::SessionController*> _controller;
|
const not_null<Window::SessionController*> _controller;
|
||||||
const not_null<UserData*> _user;
|
const not_null<UserData*> _user;
|
||||||
|
Info::Profile::BadgeView _badge;
|
||||||
|
Info::Profile::EmojiStatusPanel _emojiStatusPanel;
|
||||||
|
|
||||||
object_ptr<Ui::UserpicButton> _userpic;
|
object_ptr<Ui::UserpicButton> _userpic;
|
||||||
object_ptr<Ui::FlatLabel> _name = { nullptr };
|
object_ptr<Ui::FlatLabel> _name = { nullptr };
|
||||||
object_ptr<Ui::FlatLabel> _phone = { nullptr };
|
object_ptr<Ui::FlatLabel> _phone = { nullptr };
|
||||||
object_ptr<Ui::FlatLabel> _username = { nullptr };
|
object_ptr<Ui::FlatLabel> _username = { nullptr };
|
||||||
object_ptr<Ui::RpWidget> _badge = { nullptr };
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -105,6 +106,15 @@ Cover::Cover(
|
||||||
+ st::settingsPhotoBottom)
|
+ st::settingsPhotoBottom)
|
||||||
, _controller(controller)
|
, _controller(controller)
|
||||||
, _user(user)
|
, _user(user)
|
||||||
|
, _badge(
|
||||||
|
this,
|
||||||
|
st::infoPeerBadge,
|
||||||
|
user,
|
||||||
|
[=] {
|
||||||
|
return controller->isGifPausedAtLeastFor(
|
||||||
|
Window::GifPauseReason::Layer);
|
||||||
|
},
|
||||||
|
Info::Profile::Badge::Premium)
|
||||||
, _userpic(
|
, _userpic(
|
||||||
this,
|
this,
|
||||||
controller,
|
controller,
|
||||||
|
@ -133,23 +143,12 @@ Cover::Cover(
|
||||||
_userpic->takeResultImage());
|
_userpic->takeResultImage());
|
||||||
}, _userpic->lifetime());
|
}, _userpic->lifetime());
|
||||||
|
|
||||||
Data::AmPremiumValue(
|
_badge.setPremiumClickCallback([=] {
|
||||||
&controller->session()
|
_emojiStatusPanel.show(_controller, _badge.widget());
|
||||||
) | rpl::start_with_next([=](bool hasPremium) {
|
});
|
||||||
if (hasPremium && !_badge) {
|
_badge.updated() | rpl::start_with_next([=] {
|
||||||
const auto icon = &st::infoPremiumStar;
|
refreshNameGeometry(width());
|
||||||
_badge.create(this);
|
}, _name->lifetime());
|
||||||
_badge->show();
|
|
||||||
_badge->resize(icon->size());
|
|
||||||
_badge->paintRequest(
|
|
||||||
) | rpl::start_with_next([icon, check = _badge.data()] {
|
|
||||||
Painter p(check);
|
|
||||||
icon->paint(p, 0, 0, check->width());
|
|
||||||
}, _badge->lifetime());
|
|
||||||
} else if (!hasPremium && _badge) {
|
|
||||||
_badge.destroy();
|
|
||||||
}
|
|
||||||
}, lifetime());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Cover::~Cover() = default;
|
Cover::~Cover() = default;
|
||||||
|
@ -210,19 +209,18 @@ void Cover::initViewers() {
|
||||||
void Cover::refreshNameGeometry(int newWidth) {
|
void Cover::refreshNameGeometry(int newWidth) {
|
||||||
const auto nameLeft = st::settingsNameLeft;
|
const auto nameLeft = st::settingsNameLeft;
|
||||||
const auto nameTop = st::settingsNameTop;
|
const auto nameTop = st::settingsNameTop;
|
||||||
const auto nameWidth = newWidth
|
auto nameWidth = newWidth
|
||||||
- nameLeft
|
- nameLeft
|
||||||
- st::infoProfileNameRight
|
- st::infoProfileNameRight;
|
||||||
- (!_badge ? 0 : _badge->width() + st::infoVerifiedCheckPosition.x());
|
if (const auto width = _badge.widget() ? _badge.widget()->width() : 0) {
|
||||||
|
nameWidth -= st::infoVerifiedCheckPosition.x() + width;
|
||||||
|
}
|
||||||
_name->resizeToNaturalWidth(nameWidth);
|
_name->resizeToNaturalWidth(nameWidth);
|
||||||
_name->moveToLeft(nameLeft, nameTop, newWidth);
|
_name->moveToLeft(nameLeft, nameTop, newWidth);
|
||||||
|
const auto badgeLeft = nameLeft + _name->width();
|
||||||
if (_badge) {
|
const auto badgeTop = nameTop;
|
||||||
const auto &pos = st::infoVerifiedCheckPosition;
|
const auto badgeBottom = nameTop + _name->height();
|
||||||
const auto badgeLeft = nameLeft + _name->width() + pos.x();
|
_badge.move(badgeLeft, badgeTop, badgeBottom);
|
||||||
const auto badgeTop = nameTop + pos.y();
|
|
||||||
_badge->moveToLeft(badgeLeft, badgeTop, newWidth);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cover::refreshPhoneGeometry(int newWidth) {
|
void Cover::refreshPhoneGeometry(int newWidth) {
|
||||||
|
|
|
@ -182,12 +182,12 @@ int PeerBadge::drawGetWidth(
|
||||||
}
|
}
|
||||||
_emojiStatus->emoji->paint(
|
_emojiStatus->emoji->paint(
|
||||||
p,
|
p,
|
||||||
iconx - _emojiStatus->skip,
|
iconx - 2 * _emojiStatus->skip,
|
||||||
icony + _emojiStatus->skip,
|
icony + _emojiStatus->skip,
|
||||||
descriptor.now,
|
descriptor.now,
|
||||||
descriptor.preview,
|
descriptor.preview,
|
||||||
descriptor.paused);
|
descriptor.paused);
|
||||||
return iconw - 2 * _emojiStatus->skip;
|
return iconw - 4 * _emojiStatus->skip;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "settings/settings_common.h"
|
#include "settings/settings_common.h"
|
||||||
#include "settings/settings_calls.h"
|
#include "settings/settings_calls.h"
|
||||||
#include "settings/settings_information.h"
|
#include "settings/settings_information.h"
|
||||||
|
#include "info/profile/info_profile_cover.h"
|
||||||
#include "base/qt_signal_producer.h"
|
#include "base/qt_signal_producer.h"
|
||||||
#include "boxes/about_box.h"
|
#include "boxes/about_box.h"
|
||||||
#include "ui/boxes/confirm_box.h"
|
#include "ui/boxes/confirm_box.h"
|
||||||
|
@ -120,7 +121,10 @@ public:
|
||||||
explicit ToggleAccountsButton(QWidget *parent);
|
explicit ToggleAccountsButton(QWidget *parent);
|
||||||
|
|
||||||
[[nodiscard]] int rightSkip() const {
|
[[nodiscard]] int rightSkip() const {
|
||||||
return _rightSkip;
|
return _rightSkip.current();
|
||||||
|
}
|
||||||
|
[[nodiscard]] rpl::producer<int> rightSkipValue() const {
|
||||||
|
return _rightSkip.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -130,7 +134,7 @@ private:
|
||||||
void validateUnreadBadge();
|
void validateUnreadBadge();
|
||||||
[[nodiscard]] QString computeUnreadBadge() const;
|
[[nodiscard]] QString computeUnreadBadge() const;
|
||||||
|
|
||||||
int _rightSkip = 0;
|
rpl::variable<int> _rightSkip = 0;
|
||||||
Ui::Animations::Simple _toggledAnimation;
|
Ui::Animations::Simple _toggledAnimation;
|
||||||
bool _toggled = false;
|
bool _toggled = false;
|
||||||
|
|
||||||
|
@ -258,12 +262,13 @@ void MainMenu::ToggleAccountsButton::validateUnreadBadge() {
|
||||||
}
|
}
|
||||||
_unreadBadge = computeUnreadBadge();
|
_unreadBadge = computeUnreadBadge();
|
||||||
|
|
||||||
_rightSkip = base;
|
auto skip = base;
|
||||||
if (!_unreadBadge.isEmpty()) {
|
if (!_unreadBadge.isEmpty()) {
|
||||||
const auto st = Settings::Badge::Style();
|
const auto st = Settings::Badge::Style();
|
||||||
_rightSkip += 2 * st::mainMenuToggleSize
|
skip += 2 * st::mainMenuToggleSize
|
||||||
+ Dialogs::Ui::CountUnreadBadgeSize(_unreadBadge, st).width();
|
+ Dialogs::Ui::CountUnreadBadgeSize(_unreadBadge, st).width();
|
||||||
}
|
}
|
||||||
|
_rightSkip = skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MainMenu::ToggleAccountsButton::computeUnreadBadge() const {
|
QString MainMenu::ToggleAccountsButton::computeUnreadBadge() const {
|
||||||
|
@ -331,6 +336,13 @@ MainMenu::MainMenu(
|
||||||
Ui::UserpicButton::Role::Custom,
|
Ui::UserpicButton::Role::Custom,
|
||||||
st::mainMenuUserpic)
|
st::mainMenuUserpic)
|
||||||
, _toggleAccounts(this)
|
, _toggleAccounts(this)
|
||||||
|
, _badge(std::make_unique<Info::Profile::BadgeView>(
|
||||||
|
this,
|
||||||
|
st::settingsInfoPeerBadge,
|
||||||
|
controller->session().user(),
|
||||||
|
[=] { return controller->isGifPausedAtLeastFor(GifPauseReason::Layer); },
|
||||||
|
Info::Profile::Badge::Premium))
|
||||||
|
, _emojiStatusPanel(std::make_unique<Info::Profile::EmojiStatusPanel>())
|
||||||
, _scroll(this, st::defaultSolidScroll)
|
, _scroll(this, st::defaultSolidScroll)
|
||||||
, _inner(_scroll->setOwnedWidget(
|
, _inner(_scroll->setOwnedWidget(
|
||||||
object_ptr<Ui::VerticalLayout>(_scroll.data())))
|
object_ptr<Ui::VerticalLayout>(_scroll.data())))
|
||||||
|
@ -416,6 +428,16 @@ MainMenu::MainMenu(
|
||||||
controller->show(Box<AboutBox>());
|
controller->show(Box<AboutBox>());
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
rpl::combine(
|
||||||
|
_toggleAccounts->rightSkipValue(),
|
||||||
|
rpl::single(rpl::empty) | rpl::then(_badge->updated())
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
moveBadge();
|
||||||
|
}, lifetime());
|
||||||
|
_badge->setPremiumClickCallback([=] {
|
||||||
|
_emojiStatusPanel->show(_controller, _badge->widget());
|
||||||
|
});
|
||||||
|
|
||||||
_controller->session().downloaderTaskFinished(
|
_controller->session().downloaderTaskFinished(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
update();
|
update();
|
||||||
|
@ -432,6 +454,24 @@ MainMenu::MainMenu(
|
||||||
initResetScaleButton();
|
initResetScaleButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MainMenu::~MainMenu() = default;
|
||||||
|
|
||||||
|
void MainMenu::moveBadge() {
|
||||||
|
if (!_badge->widget()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto available = width()
|
||||||
|
- st::mainMenuCoverNameLeft
|
||||||
|
- _toggleAccounts->rightSkip()
|
||||||
|
- _badge->widget()->width();
|
||||||
|
const auto left = st::mainMenuCoverNameLeft
|
||||||
|
+ std::min(_name.maxWidth() + st::semiboldFont->spacew, available);
|
||||||
|
_badge->move(
|
||||||
|
left,
|
||||||
|
st::mainMenuCoverNameTop,
|
||||||
|
st::mainMenuCoverNameTop + st::msgNameStyle.font->height);
|
||||||
|
}
|
||||||
|
|
||||||
void MainMenu::setupArchive() {
|
void MainMenu::setupArchive() {
|
||||||
using namespace Settings;
|
using namespace Settings;
|
||||||
|
|
||||||
|
@ -771,30 +811,10 @@ void MainMenu::paintEvent(QPaintEvent *e) {
|
||||||
st::msgNameStyle,
|
st::msgNameStyle,
|
||||||
user->name(),
|
user->name(),
|
||||||
Ui::NameTextOptions());
|
Ui::NameTextOptions());
|
||||||
|
moveBadge();
|
||||||
}
|
}
|
||||||
const auto paused = _controller->isGifPausedAtLeastFor(
|
const auto paused = _controller->isGifPausedAtLeastFor(
|
||||||
GifPauseReason::Layer);
|
GifPauseReason::Layer);
|
||||||
const auto badgeWidth = user->emojiStatusId()
|
|
||||||
? _badge.drawGetWidth(
|
|
||||||
p,
|
|
||||||
QRect(
|
|
||||||
st::mainMenuCoverNameLeft,
|
|
||||||
st::mainMenuCoverNameTop,
|
|
||||||
widthText,
|
|
||||||
st::msgNameStyle.font->height),
|
|
||||||
_name.maxWidth(),
|
|
||||||
width(),
|
|
||||||
{
|
|
||||||
.peer = user,
|
|
||||||
.verified = nullptr,
|
|
||||||
.premium = &st::dialogsPremiumIcon,
|
|
||||||
.scam = nullptr,
|
|
||||||
.preview = st::windowBgOver->c,
|
|
||||||
.customEmojiRepaint = [=] { update(); },
|
|
||||||
.now = crl::now(),
|
|
||||||
.paused = paused,
|
|
||||||
})
|
|
||||||
: 0;
|
|
||||||
|
|
||||||
p.setFont(st::semiboldFont);
|
p.setFont(st::semiboldFont);
|
||||||
p.setPen(st::windowBoldFg);
|
p.setPen(st::windowBoldFg);
|
||||||
|
@ -802,7 +822,10 @@ void MainMenu::paintEvent(QPaintEvent *e) {
|
||||||
p,
|
p,
|
||||||
st::mainMenuCoverNameLeft,
|
st::mainMenuCoverNameLeft,
|
||||||
st::mainMenuCoverNameTop,
|
st::mainMenuCoverNameTop,
|
||||||
widthText - badgeWidth,
|
(widthText
|
||||||
|
- (_badge->widget()
|
||||||
|
? (st::semiboldFont->spacew + _badge->widget()->width())
|
||||||
|
: 0)),
|
||||||
width());
|
width());
|
||||||
p.setFont(st::mainMenuPhoneFont);
|
p.setFont(st::mainMenuPhoneFont);
|
||||||
p.setPen(st::windowSubTextFg);
|
p.setPen(st::windowSubTextFg);
|
||||||
|
|
|
@ -28,6 +28,11 @@ template <typename Widget>
|
||||||
class SlideWrap;
|
class SlideWrap;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
|
namespace Info::Profile {
|
||||||
|
class BadgeView;
|
||||||
|
class EmojiStatusPanel;
|
||||||
|
} // namespace Info::Profile
|
||||||
|
|
||||||
namespace Main {
|
namespace Main {
|
||||||
class Account;
|
class Account;
|
||||||
} // namespace Main
|
} // namespace Main
|
||||||
|
@ -39,6 +44,7 @@ class SessionController;
|
||||||
class MainMenu final : public Ui::LayerWidget {
|
class MainMenu final : public Ui::LayerWidget {
|
||||||
public:
|
public:
|
||||||
MainMenu(QWidget *parent, not_null<SessionController*> controller);
|
MainMenu(QWidget *parent, not_null<SessionController*> controller);
|
||||||
|
~MainMenu();
|
||||||
|
|
||||||
void parentResized() override;
|
void parentResized() override;
|
||||||
|
|
||||||
|
@ -54,6 +60,7 @@ private:
|
||||||
class ToggleAccountsButton;
|
class ToggleAccountsButton;
|
||||||
class ResetScaleButton;
|
class ResetScaleButton;
|
||||||
|
|
||||||
|
void moveBadge();
|
||||||
void setupUserpicButton();
|
void setupUserpicButton();
|
||||||
void setupAccounts();
|
void setupAccounts();
|
||||||
void setupAccountsToggle();
|
void setupAccountsToggle();
|
||||||
|
@ -67,10 +74,11 @@ private:
|
||||||
|
|
||||||
const not_null<SessionController*> _controller;
|
const not_null<SessionController*> _controller;
|
||||||
object_ptr<Ui::UserpicButton> _userpicButton;
|
object_ptr<Ui::UserpicButton> _userpicButton;
|
||||||
Ui::PeerBadge _badge;
|
|
||||||
Ui::Text::String _name;
|
Ui::Text::String _name;
|
||||||
int _nameVersion = 0;
|
int _nameVersion = 0;
|
||||||
object_ptr<ToggleAccountsButton> _toggleAccounts;
|
object_ptr<ToggleAccountsButton> _toggleAccounts;
|
||||||
|
std::unique_ptr<Info::Profile::BadgeView> _badge;
|
||||||
|
std::unique_ptr<Info::Profile::EmojiStatusPanel> _emojiStatusPanel;
|
||||||
object_ptr<ResetScaleButton> _resetScaleButton = { nullptr };
|
object_ptr<ResetScaleButton> _resetScaleButton = { nullptr };
|
||||||
object_ptr<Ui::ScrollArea> _scroll;
|
object_ptr<Ui::ScrollArea> _scroll;
|
||||||
not_null<Ui::VerticalLayout*> _inner;
|
not_null<Ui::VerticalLayout*> _inner;
|
||||||
|
|
Loading…
Add table
Reference in a new issue