mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 22:54:01 +02:00
Add verified/fake/scam badge to ConfirmInviteBox.
This commit is contained in:
parent
dbd4aecc56
commit
a6b844408a
4 changed files with 139 additions and 35 deletions
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
|
#include "info/profile/info_profile_badge.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "ui/empty_userpic.h"
|
#include "ui/empty_userpic.h"
|
||||||
|
@ -25,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/toast/toast.h"
|
#include "ui/toast/toast.h"
|
||||||
#include "boxes/premium_limits_box.h"
|
#include "boxes/premium_limits_box.h"
|
||||||
#include "styles/style_boxes.h"
|
#include "styles/style_boxes.h"
|
||||||
|
#include "styles/style_info.h"
|
||||||
#include "styles/style_layers.h"
|
#include "styles/style_layers.h"
|
||||||
|
|
||||||
namespace Api {
|
namespace Api {
|
||||||
|
@ -195,6 +197,13 @@ ConfirmInviteBox::ConfirmInviteBox(
|
||||||
: _session(session)
|
: _session(session)
|
||||||
, _submit(std::move(submit))
|
, _submit(std::move(submit))
|
||||||
, _title(this, st::confirmInviteTitle)
|
, _title(this, st::confirmInviteTitle)
|
||||||
|
, _badge(std::make_unique<Info::Profile::Badge>(
|
||||||
|
this,
|
||||||
|
st::infoPeerBadge,
|
||||||
|
_session,
|
||||||
|
rpl::single(Info::Profile::Badge::Content{ BadgeForInvite(invite) }),
|
||||||
|
nullptr,
|
||||||
|
[=] { return false; }))
|
||||||
, _status(this, st::confirmInviteStatus)
|
, _status(this, st::confirmInviteStatus)
|
||||||
, _about(this, st::confirmInviteAbout)
|
, _about(this, st::confirmInviteAbout)
|
||||||
, _aboutRequests(this, st::confirmInviteStatus)
|
, _aboutRequests(this, st::confirmInviteStatus)
|
||||||
|
@ -275,9 +284,24 @@ ConfirmInviteBox::ChatInvite ConfirmInviteBox::Parse(
|
||||||
.isMegagroup = data.is_megagroup(),
|
.isMegagroup = data.is_megagroup(),
|
||||||
.isBroadcast = data.is_broadcast(),
|
.isBroadcast = data.is_broadcast(),
|
||||||
.isRequestNeeded = data.is_request_needed(),
|
.isRequestNeeded = data.is_request_needed(),
|
||||||
|
.isFake = data.is_fake(),
|
||||||
|
.isScam = data.is_scam(),
|
||||||
|
.isVerified = data.is_verified(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] Info::Profile::BadgeType ConfirmInviteBox::BadgeForInvite(
|
||||||
|
const ChatInvite &invite) {
|
||||||
|
using Type = Info::Profile::BadgeType;
|
||||||
|
return invite.isVerified
|
||||||
|
? Type::Verified
|
||||||
|
: invite.isScam
|
||||||
|
? Type::Scam
|
||||||
|
: invite.isFake
|
||||||
|
? Type::Fake
|
||||||
|
: Type::None;
|
||||||
|
}
|
||||||
|
|
||||||
void ConfirmInviteBox::prepare() {
|
void ConfirmInviteBox::prepare() {
|
||||||
addButton(
|
addButton(
|
||||||
(_requestApprove
|
(_requestApprove
|
||||||
|
@ -326,8 +350,26 @@ void ConfirmInviteBox::prepare() {
|
||||||
|
|
||||||
void ConfirmInviteBox::resizeEvent(QResizeEvent *e) {
|
void ConfirmInviteBox::resizeEvent(QResizeEvent *e) {
|
||||||
BoxContent::resizeEvent(e);
|
BoxContent::resizeEvent(e);
|
||||||
_title->move((width() - _title->width()) / 2, st::confirmInviteTitleTop);
|
|
||||||
_status->move((width() - _status->width()) / 2, st::confirmInviteStatusTop);
|
const auto padding = st::boxRowPadding;
|
||||||
|
auto nameWidth = width() - padding.left() - padding.right();
|
||||||
|
auto badgeWidth = 0;
|
||||||
|
if (const auto widget = _badge->widget()) {
|
||||||
|
badgeWidth = st::infoVerifiedCheckPosition.x() + widget->width();
|
||||||
|
nameWidth -= badgeWidth;
|
||||||
|
}
|
||||||
|
_title->resizeToWidth(std::min(nameWidth, _title->textMaxWidth()));
|
||||||
|
_title->moveToLeft(
|
||||||
|
(width() - _title->width() - badgeWidth) / 2,
|
||||||
|
st::confirmInviteTitleTop);
|
||||||
|
const auto badgeLeft = _title->x() + _title->width();
|
||||||
|
const auto badgeTop = _title->y();
|
||||||
|
const auto badgeBottom = _title->y() + _title->height();
|
||||||
|
_badge->move(badgeLeft, badgeTop, badgeBottom);
|
||||||
|
|
||||||
|
_status->move(
|
||||||
|
(width() - _status->width()) / 2,
|
||||||
|
st::confirmInviteStatusTop);
|
||||||
auto bottom = _status->y()
|
auto bottom = _status->y()
|
||||||
+ _status->height()
|
+ _status->height()
|
||||||
+ st::boxPadding.bottom()
|
+ st::boxPadding.bottom()
|
||||||
|
|
|
@ -12,6 +12,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
class UserData;
|
class UserData;
|
||||||
class ChannelData;
|
class ChannelData;
|
||||||
|
|
||||||
|
namespace Info::Profile {
|
||||||
|
class Badge;
|
||||||
|
enum class BadgeType;
|
||||||
|
} // namespace Info::Profile
|
||||||
|
|
||||||
namespace Main {
|
namespace Main {
|
||||||
class Session;
|
class Session;
|
||||||
} // namespace Main
|
} // namespace Main
|
||||||
|
@ -66,10 +71,15 @@ private:
|
||||||
bool isMegagroup = false;
|
bool isMegagroup = false;
|
||||||
bool isBroadcast = false;
|
bool isBroadcast = false;
|
||||||
bool isRequestNeeded = false;
|
bool isRequestNeeded = false;
|
||||||
|
bool isFake = false;
|
||||||
|
bool isScam = false;
|
||||||
|
bool isVerified = false;
|
||||||
};
|
};
|
||||||
[[nodiscard]] static ChatInvite Parse(
|
[[nodiscard]] static ChatInvite Parse(
|
||||||
not_null<Main::Session*> session,
|
not_null<Main::Session*> session,
|
||||||
const MTPDchatInvite &data);
|
const MTPDchatInvite &data);
|
||||||
|
[[nodiscard]] Info::Profile::BadgeType BadgeForInvite(
|
||||||
|
const ChatInvite &invite);
|
||||||
|
|
||||||
ConfirmInviteBox(
|
ConfirmInviteBox(
|
||||||
not_null<Main::Session*> session,
|
not_null<Main::Session*> session,
|
||||||
|
@ -81,12 +91,14 @@ private:
|
||||||
|
|
||||||
Fn<void()> _submit;
|
Fn<void()> _submit;
|
||||||
object_ptr<Ui::FlatLabel> _title;
|
object_ptr<Ui::FlatLabel> _title;
|
||||||
|
std::unique_ptr<Info::Profile::Badge> _badge;
|
||||||
object_ptr<Ui::FlatLabel> _status;
|
object_ptr<Ui::FlatLabel> _status;
|
||||||
object_ptr<Ui::FlatLabel> _about;
|
object_ptr<Ui::FlatLabel> _about;
|
||||||
object_ptr<Ui::FlatLabel> _aboutRequests;
|
object_ptr<Ui::FlatLabel> _aboutRequests;
|
||||||
std::shared_ptr<Data::PhotoMedia> _photo;
|
std::shared_ptr<Data::PhotoMedia> _photo;
|
||||||
std::unique_ptr<Ui::EmptyUserpic> _photoEmpty;
|
std::unique_ptr<Ui::EmptyUserpic> _photoEmpty;
|
||||||
std::vector<Participant> _participants;
|
std::vector<Participant> _participants;
|
||||||
|
|
||||||
bool _isChannel = false;
|
bool _isChannel = false;
|
||||||
bool _requestApprove = false;
|
bool _requestApprove = false;
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
namespace Info::Profile {
|
namespace Info::Profile {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
[[nodiscard]] rpl::producer<Badge::Content> ContentForPeer(
|
||||||
|
not_null<PeerData*> peer) {
|
||||||
|
return rpl::combine(
|
||||||
|
BadgeValue(peer),
|
||||||
|
EmojiStatusIdValue(peer)
|
||||||
|
) | rpl::map([=](BadgeType badge, DocumentId emojiStatusId) {
|
||||||
|
return Badge::Content{ badge, emojiStatusId };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Badge::Badge(
|
Badge::Badge(
|
||||||
|
@ -32,18 +42,37 @@ Badge::Badge(
|
||||||
Fn<bool()> animationPaused,
|
Fn<bool()> animationPaused,
|
||||||
int customStatusLoopsLimit,
|
int customStatusLoopsLimit,
|
||||||
base::flags<BadgeType> allowed)
|
base::flags<BadgeType> allowed)
|
||||||
|
: Badge(
|
||||||
|
parent,
|
||||||
|
st,
|
||||||
|
&peer->session(),
|
||||||
|
ContentForPeer(peer),
|
||||||
|
emojiStatusPanel,
|
||||||
|
std::move(animationPaused),
|
||||||
|
customStatusLoopsLimit,
|
||||||
|
allowed) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Badge::Badge(
|
||||||
|
not_null<QWidget*> parent,
|
||||||
|
const style::InfoPeerBadge &st,
|
||||||
|
not_null<Main::Session*> session,
|
||||||
|
rpl::producer<Content> content,
|
||||||
|
EmojiStatusPanel *emojiStatusPanel,
|
||||||
|
Fn<bool()> animationPaused,
|
||||||
|
int customStatusLoopsLimit,
|
||||||
|
base::flags<BadgeType> allowed)
|
||||||
: _parent(parent)
|
: _parent(parent)
|
||||||
, _st(st)
|
, _st(st)
|
||||||
, _peer(peer)
|
, _session(session)
|
||||||
, _emojiStatusPanel(emojiStatusPanel)
|
, _emojiStatusPanel(emojiStatusPanel)
|
||||||
, _customStatusLoopsLimit(customStatusLoopsLimit)
|
, _customStatusLoopsLimit(customStatusLoopsLimit)
|
||||||
, _allowed(allowed)
|
, _allowed(allowed)
|
||||||
, _animationPaused(std::move(animationPaused)) {
|
, _animationPaused(std::move(animationPaused)) {
|
||||||
rpl::combine(
|
std::move(
|
||||||
BadgeValue(peer),
|
content
|
||||||
EmojiStatusIdValue(peer)
|
) | rpl::start_with_next([=](Content content) {
|
||||||
) | rpl::start_with_next([=](BadgeType badge, DocumentId emojiStatusId) {
|
setContent(content);
|
||||||
setBadge(badge, emojiStatusId);
|
|
||||||
}, _lifetime);
|
}, _lifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,37 +80,36 @@ Ui::RpWidget *Badge::widget() const {
|
||||||
return _view.data();
|
return _view.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Badge::setBadge(BadgeType badge, DocumentId emojiStatusId) {
|
void Badge::setContent(Content content) {
|
||||||
if (!(_allowed & badge)
|
if (!(_allowed & content.badge)
|
||||||
|| (!_peer->session().premiumBadgesShown()
|
|| (!_session->premiumBadgesShown()
|
||||||
&& badge == BadgeType::Premium)) {
|
&& content.badge == BadgeType::Premium)) {
|
||||||
badge = BadgeType::None;
|
content.badge = BadgeType::None;
|
||||||
}
|
}
|
||||||
if (!(_allowed & badge)) {
|
if (!(_allowed & content.badge)) {
|
||||||
badge = BadgeType::None;
|
content.badge = BadgeType::None;
|
||||||
}
|
}
|
||||||
if (badge != BadgeType::Premium) {
|
if (content.badge != BadgeType::Premium) {
|
||||||
emojiStatusId = 0;
|
content.emojiStatusId = 0;
|
||||||
}
|
}
|
||||||
if (_badge == badge && _emojiStatusId == emojiStatusId) {
|
if (_content == content) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_badge = badge;
|
_content = content;
|
||||||
_emojiStatusId = emojiStatusId;
|
|
||||||
_emojiStatus = nullptr;
|
_emojiStatus = nullptr;
|
||||||
_view.destroy();
|
_view.destroy();
|
||||||
if (_badge == BadgeType::None) {
|
if (_content.badge == BadgeType::None) {
|
||||||
_updated.fire({});
|
_updated.fire({});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_view.create(_parent);
|
_view.create(_parent);
|
||||||
_view->show();
|
_view->show();
|
||||||
switch (_badge) {
|
switch (_content.badge) {
|
||||||
case BadgeType::Verified:
|
case BadgeType::Verified:
|
||||||
case BadgeType::Premium: {
|
case BadgeType::Premium: {
|
||||||
if (_emojiStatusId) {
|
if (const auto id = _content.emojiStatusId) {
|
||||||
_emojiStatus = _peer->owner().customEmojiManager().create(
|
_emojiStatus = _session->data().customEmojiManager().create(
|
||||||
_emojiStatusId,
|
id,
|
||||||
[raw = _view.data()] { raw->update(); },
|
[raw = _view.data()] { raw->update(); },
|
||||||
sizeTag());
|
sizeTag());
|
||||||
if (_customStatusLoopsLimit > 0) {
|
if (_customStatusLoopsLimit > 0) {
|
||||||
|
@ -107,7 +135,7 @@ void Badge::setBadge(BadgeType badge, DocumentId emojiStatusId) {
|
||||||
}
|
}
|
||||||
}, _view->lifetime());
|
}, _view->lifetime());
|
||||||
} else {
|
} else {
|
||||||
const auto icon = (_badge == BadgeType::Verified)
|
const auto icon = (_content.badge == BadgeType::Verified)
|
||||||
? &_st.verified
|
? &_st.verified
|
||||||
: &_st.premium;
|
: &_st.premium;
|
||||||
_view->resize(icon->size());
|
_view->resize(icon->size());
|
||||||
|
@ -120,7 +148,7 @@ void Badge::setBadge(BadgeType badge, DocumentId emojiStatusId) {
|
||||||
} break;
|
} break;
|
||||||
case BadgeType::Scam:
|
case BadgeType::Scam:
|
||||||
case BadgeType::Fake: {
|
case BadgeType::Fake: {
|
||||||
const auto fake = (_badge == BadgeType::Fake);
|
const auto fake = (_content.badge == BadgeType::Fake);
|
||||||
const auto size = Ui::ScamBadgeSize(fake);
|
const auto size = Ui::ScamBadgeSize(fake);
|
||||||
const auto skip = st::infoVerifiedCheckPosition.x();
|
const auto skip = st::infoVerifiedCheckPosition.x();
|
||||||
_view->resize(
|
_view->resize(
|
||||||
|
@ -139,7 +167,7 @@ void Badge::setBadge(BadgeType badge, DocumentId emojiStatusId) {
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_badge != BadgeType::Premium || !_premiumClickCallback) {
|
if (_content.badge != BadgeType::Premium || !_premiumClickCallback) {
|
||||||
_view->setAttribute(Qt::WA_TransparentForMouseEvents);
|
_view->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
} else {
|
} else {
|
||||||
_view->setClickedCallback(_premiumClickCallback);
|
_view->setClickedCallback(_premiumClickCallback);
|
||||||
|
@ -150,7 +178,7 @@ void Badge::setBadge(BadgeType badge, DocumentId emojiStatusId) {
|
||||||
|
|
||||||
void Badge::setPremiumClickCallback(Fn<void()> callback) {
|
void Badge::setPremiumClickCallback(Fn<void()> callback) {
|
||||||
_premiumClickCallback = std::move(callback);
|
_premiumClickCallback = std::move(callback);
|
||||||
if (_view && _badge == BadgeType::Premium) {
|
if (_view && _content.badge == BadgeType::Premium) {
|
||||||
if (!_premiumClickCallback) {
|
if (!_premiumClickCallback) {
|
||||||
_view->setAttribute(Qt::WA_TransparentForMouseEvents);
|
_view->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
} else {
|
} else {
|
||||||
|
@ -169,7 +197,8 @@ void Badge::move(int left, int top, int bottom) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto star = !_emojiStatus
|
const auto star = !_emojiStatus
|
||||||
&& (_badge == BadgeType::Premium || _badge == BadgeType::Verified);
|
&& (_content.badge == BadgeType::Premium
|
||||||
|
|| _content.badge == BadgeType::Verified);
|
||||||
const auto fake = !_emojiStatus && !star;
|
const auto fake = !_emojiStatus && !star;
|
||||||
const auto skip = fake ? 0 : _st.position.x();
|
const auto skip = fake ? 0 : _st.position.x();
|
||||||
const auto badgeLeft = left + skip;
|
const auto badgeLeft = left + skip;
|
||||||
|
|
|
@ -18,6 +18,10 @@ namespace Data {
|
||||||
enum class CustomEmojiSizeTag : uchar;
|
enum class CustomEmojiSizeTag : uchar;
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
||||||
|
namespace Main {
|
||||||
|
class Session;
|
||||||
|
} // namespace Main
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class RpWidget;
|
class RpWidget;
|
||||||
class AbstractButton;
|
class AbstractButton;
|
||||||
|
@ -45,7 +49,25 @@ public:
|
||||||
EmojiStatusPanel *emojiStatusPanel,
|
EmojiStatusPanel *emojiStatusPanel,
|
||||||
Fn<bool()> animationPaused,
|
Fn<bool()> animationPaused,
|
||||||
int customStatusLoopsLimit = 0,
|
int customStatusLoopsLimit = 0,
|
||||||
base::flags<BadgeType> allowed = base::flags<BadgeType>::from_raw(-1));
|
base::flags<BadgeType> allowed
|
||||||
|
= base::flags<BadgeType>::from_raw(-1));
|
||||||
|
|
||||||
|
struct Content {
|
||||||
|
BadgeType badge = BadgeType::None;
|
||||||
|
DocumentId emojiStatusId = 0;
|
||||||
|
|
||||||
|
friend inline constexpr bool operator==(Content, Content) = default;
|
||||||
|
};
|
||||||
|
Badge(
|
||||||
|
not_null<QWidget*> parent,
|
||||||
|
const style::InfoPeerBadge &st,
|
||||||
|
not_null<Main::Session*> session,
|
||||||
|
rpl::producer<Content> content,
|
||||||
|
EmojiStatusPanel *emojiStatusPanel,
|
||||||
|
Fn<bool()> animationPaused,
|
||||||
|
int customStatusLoopsLimit = 0,
|
||||||
|
base::flags<BadgeType> allowed
|
||||||
|
= base::flags<BadgeType>::from_raw(-1));
|
||||||
|
|
||||||
[[nodiscard]] Ui::RpWidget *widget() const;
|
[[nodiscard]] Ui::RpWidget *widget() const;
|
||||||
|
|
||||||
|
@ -56,17 +78,16 @@ public:
|
||||||
[[nodiscard]] Data::CustomEmojiSizeTag sizeTag() const;
|
[[nodiscard]] Data::CustomEmojiSizeTag sizeTag() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setBadge(BadgeType badge, DocumentId emojiStatusId);
|
void setContent(Content content);
|
||||||
|
|
||||||
const not_null<QWidget*> _parent;
|
const not_null<QWidget*> _parent;
|
||||||
const style::InfoPeerBadge &_st;
|
const style::InfoPeerBadge &_st;
|
||||||
const not_null<PeerData*> _peer;
|
const not_null<Main::Session*> _session;
|
||||||
EmojiStatusPanel *_emojiStatusPanel = nullptr;
|
EmojiStatusPanel *_emojiStatusPanel = nullptr;
|
||||||
const int _customStatusLoopsLimit = 0;
|
const int _customStatusLoopsLimit = 0;
|
||||||
DocumentId _emojiStatusId = 0;
|
|
||||||
std::unique_ptr<Ui::Text::CustomEmoji> _emojiStatus;
|
std::unique_ptr<Ui::Text::CustomEmoji> _emojiStatus;
|
||||||
base::flags<BadgeType> _allowed;
|
base::flags<BadgeType> _allowed;
|
||||||
BadgeType _badge = BadgeType();
|
Content _content;
|
||||||
Fn<void()> _premiumClickCallback;
|
Fn<void()> _premiumClickCallback;
|
||||||
Fn<bool()> _animationPaused;
|
Fn<bool()> _animationPaused;
|
||||||
object_ptr<Ui::AbstractButton> _view = { nullptr };
|
object_ptr<Ui::AbstractButton> _view = { nullptr };
|
||||||
|
|
Loading…
Add table
Reference in a new issue