mirror of https://github.com/procxx/kepka.git
Add SCAM badge for users and channels.
This commit is contained in:
parent
88b7387a40
commit
352839337d
|
@ -195,6 +195,7 @@ dialogsUnreadBgMuted: #bbbbbb; // chat list unread badge background for muted ch
|
||||||
dialogsUnreadFg: windowFgActive; // chat list unread badge text
|
dialogsUnreadFg: windowFgActive; // chat list unread badge text
|
||||||
dialogsArchiveFg: #525252 | dialogsNameFg; // chat list archive name text
|
dialogsArchiveFg: #525252 | dialogsNameFg; // chat list archive name text
|
||||||
dialogsOnlineBadgeFg: #4dc920 | dialogsUnreadBg; // chat list online status
|
dialogsOnlineBadgeFg: #4dc920 | dialogsUnreadBg; // chat list online status
|
||||||
|
dialogsScamFg: dialogsDraftFg; // chat list scam label
|
||||||
|
|
||||||
dialogsBgOver: windowBgOver; // chat list background with mouse over
|
dialogsBgOver: windowBgOver; // chat list background with mouse over
|
||||||
dialogsNameFgOver: windowBoldFgOver; // chat list name text with mouse over
|
dialogsNameFgOver: windowBoldFgOver; // chat list name text with mouse over
|
||||||
|
@ -210,7 +211,8 @@ dialogsSentIconFgOver: dialogsSentIconFg; // chat list sent message tick / doubl
|
||||||
dialogsUnreadBgOver: dialogsUnreadBg; // chat list unread badge background for not muted chat with mouse over
|
dialogsUnreadBgOver: dialogsUnreadBg; // chat list unread badge background for not muted chat with mouse over
|
||||||
dialogsUnreadBgMutedOver: dialogsUnreadBgMuted; // chat list unread badge background for muted chat with mouse over
|
dialogsUnreadBgMutedOver: dialogsUnreadBgMuted; // chat list unread badge background for muted chat with mouse over
|
||||||
dialogsUnreadFgOver: dialogsUnreadFg; // chat list unread badge text with mouse over
|
dialogsUnreadFgOver: dialogsUnreadFg; // chat list unread badge text with mouse over
|
||||||
dialogsArchiveFgOver: #525252 | dialogsNameFgOver; // chat list archive name text
|
dialogsArchiveFgOver: #525252 | dialogsNameFgOver; // chat list archive name text with mouse over
|
||||||
|
dialogsScamFgOver: dialogsDraftFgOver; // chat list scam label with mouse over
|
||||||
|
|
||||||
dialogsBgActive: #419fd9; // chat list background for current (active) chat
|
dialogsBgActive: #419fd9; // chat list background for current (active) chat
|
||||||
dialogsNameFgActive: windowFgActive; // chat list name text for current (active) chat
|
dialogsNameFgActive: windowFgActive; // chat list name text for current (active) chat
|
||||||
|
@ -227,6 +229,7 @@ dialogsUnreadBgActive: dialogsTextFgActive; // chat list unread badge background
|
||||||
dialogsUnreadBgMutedActive: dialogsDraftFgActive; // chat list unread badge background for muted chat for current (active) chat
|
dialogsUnreadBgMutedActive: dialogsDraftFgActive; // chat list unread badge background for muted chat for current (active) chat
|
||||||
dialogsUnreadFgActive: dialogsBgActive; // chat list unread badge text for current (active) chat
|
dialogsUnreadFgActive: dialogsBgActive; // chat list unread badge text for current (active) chat
|
||||||
dialogsOnlineBadgeFgActive: #ffffff; // chat list online status for current (active) chat
|
dialogsOnlineBadgeFgActive: #ffffff; // chat list online status for current (active) chat
|
||||||
|
dialogsScamFgActive: dialogsDraftFgActive; // chat list scam label for current (active) chat
|
||||||
|
|
||||||
dialogsRippleBg: windowBgRipple; // chat list background ripple effect
|
dialogsRippleBg: windowBgRipple; // chat list background ripple effect
|
||||||
dialogsRippleBgActive: activeButtonBgRipple; // chat list background ripple effect for current (active) chat
|
dialogsRippleBgActive: activeButtonBgRipple; // chat list background ripple effect for current (active) chat
|
||||||
|
|
|
@ -119,6 +119,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
"lng_channel_status" = "channel";
|
"lng_channel_status" = "channel";
|
||||||
"lng_group_status" = "group";
|
"lng_group_status" = "group";
|
||||||
|
"lng_scam_badge" = "SCAM";
|
||||||
|
|
||||||
"lng_flood_error" = "Too many tries. Please try again later.";
|
"lng_flood_error" = "Too many tries. Please try again later.";
|
||||||
"lng_gif_error" = "An error has occurred while reading GIF animation :(";
|
"lng_gif_error" = "An error has occurred while reading GIF animation :(";
|
||||||
|
|
|
@ -28,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/toast/toast.h"
|
#include "ui/toast/toast.h"
|
||||||
#include "ui/special_buttons.h"
|
#include "ui/special_buttons.h"
|
||||||
#include "ui/text_options.h"
|
#include "ui/text_options.h"
|
||||||
|
#include "ui/unread_badge.h"
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
#include "data/data_chat.h"
|
#include "data/data_chat.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
|
@ -1399,11 +1400,21 @@ void RevokePublicLinkBox::Inner::paintChat(Painter &p, const ChatRow &row, bool
|
||||||
|
|
||||||
int32 namex = st::contactsPadding.left() + st::contactsPhotoSize + st::contactsPadding.left();
|
int32 namex = st::contactsPadding.left() + st::contactsPhotoSize + st::contactsPadding.left();
|
||||||
int32 namew = width() - namex - st::contactsPadding.right() - (_revokeWidth + st::contactsCheckPosition.x() * 2);
|
int32 namew = width() - namex - st::contactsPadding.right() - (_revokeWidth + st::contactsCheckPosition.x() * 2);
|
||||||
if (peer->isVerified()) {
|
|
||||||
auto icon = &st::dialogsVerifiedIcon;
|
const auto badgeStyle = Ui::PeerBadgeStyle{
|
||||||
namew -= icon->width();
|
&st::dialogsVerifiedIcon,
|
||||||
icon->paint(p, namex + qMin(row.name.maxWidth(), namew), st::contactsPadding.top() + st::contactsNameTop, width());
|
&st::attentionButtonFg };
|
||||||
}
|
namew -= Ui::DrawPeerBadgeGetWidth(
|
||||||
|
peer,
|
||||||
|
p,
|
||||||
|
QRect(
|
||||||
|
namex,
|
||||||
|
st::contactsPadding.top() + st::contactsNameTop,
|
||||||
|
row.name.maxWidth(),
|
||||||
|
st::contactsNameStyle.font->height),
|
||||||
|
namew,
|
||||||
|
width(),
|
||||||
|
badgeStyle);
|
||||||
row.name.drawLeftElided(p, namex, st::contactsPadding.top() + st::contactsNameTop, namew, width());
|
row.name.drawLeftElided(p, namex, st::contactsPadding.top() + st::contactsNameTop, namew, width());
|
||||||
|
|
||||||
p.setFont(selected ? st::linkOverFont : st::linkFont);
|
p.setFont(selected ? st::linkOverFont : st::linkFont);
|
||||||
|
|
|
@ -91,6 +91,7 @@ public:
|
||||||
| MTPDchannel_ClientFlag::f_forbidden
|
| MTPDchannel_ClientFlag::f_forbidden
|
||||||
| MTPDchannel::Flag::f_broadcast
|
| MTPDchannel::Flag::f_broadcast
|
||||||
| MTPDchannel::Flag::f_verified
|
| MTPDchannel::Flag::f_verified
|
||||||
|
| MTPDchannel::Flag::f_scam
|
||||||
| MTPDchannel::Flag::f_megagroup
|
| MTPDchannel::Flag::f_megagroup
|
||||||
| MTPDchannel::Flag::f_restricted
|
| MTPDchannel::Flag::f_restricted
|
||||||
| MTPDchannel::Flag::f_signatures
|
| MTPDchannel::Flag::f_signatures
|
||||||
|
@ -192,6 +193,9 @@ public:
|
||||||
bool isVerified() const {
|
bool isVerified() const {
|
||||||
return flags() & MTPDchannel::Flag::f_verified;
|
return flags() & MTPDchannel::Flag::f_verified;
|
||||||
}
|
}
|
||||||
|
bool isScam() const {
|
||||||
|
return flags() & MTPDchannel::Flag::f_scam;
|
||||||
|
}
|
||||||
|
|
||||||
static MTPChatBannedRights KickedRestrictedRights();
|
static MTPChatBannedRights KickedRestrictedRights();
|
||||||
static constexpr auto kRestrictUntilForever = TimeId(INT_MAX);
|
static constexpr auto kRestrictUntilForever = TimeId(INT_MAX);
|
||||||
|
|
|
@ -618,19 +618,30 @@ const QString &PeerData::shortName() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PeerData::userName() const {
|
QString PeerData::userName() const {
|
||||||
return isUser()
|
if (const auto user = asUser()) {
|
||||||
? asUser()->username
|
return user->username;
|
||||||
: isChannel()
|
} else if (const auto channel = asChannel()) {
|
||||||
? asChannel()->username
|
return channel->username;
|
||||||
: QString();
|
}
|
||||||
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PeerData::isVerified() const {
|
bool PeerData::isVerified() const {
|
||||||
return isUser()
|
if (const auto user = asUser()) {
|
||||||
? asUser()->isVerified()
|
return user->isVerified();
|
||||||
: isChannel()
|
} else if (const auto channel = asChannel()) {
|
||||||
? asChannel()->isVerified()
|
return channel->isVerified();
|
||||||
: false;
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PeerData::isScam() const {
|
||||||
|
if (const auto user = asUser()) {
|
||||||
|
return user->isScam();
|
||||||
|
} else if (const auto channel = asChannel()) {
|
||||||
|
return channel->isScam();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PeerData::isMegagroup() const {
|
bool PeerData::isMegagroup() const {
|
||||||
|
@ -638,13 +649,14 @@ bool PeerData::isMegagroup() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PeerData::canWrite() const {
|
bool PeerData::canWrite() const {
|
||||||
return isChannel()
|
if (const auto user = asUser()) {
|
||||||
? asChannel()->canWrite()
|
return user->canWrite();
|
||||||
: isChat()
|
} else if (const auto channel = asChannel()) {
|
||||||
? asChat()->canWrite()
|
return channel->canWrite();
|
||||||
: isUser()
|
} else if (const auto chat = asChat()) {
|
||||||
? asUser()->canWrite()
|
return chat->canWrite();
|
||||||
: false;
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Data::RestrictionCheckResult PeerData::amRestricted(
|
Data::RestrictionCheckResult PeerData::amRestricted(
|
||||||
|
|
|
@ -141,6 +141,7 @@ public:
|
||||||
return (input.type() == mtpc_inputPeerSelf);
|
return (input.type() == mtpc_inputPeerSelf);
|
||||||
}
|
}
|
||||||
[[nodiscard]] bool isVerified() const;
|
[[nodiscard]] bool isVerified() const;
|
||||||
|
[[nodiscard]] bool isScam() const;
|
||||||
[[nodiscard]] bool isMegagroup() const;
|
[[nodiscard]] bool isMegagroup() const;
|
||||||
|
|
||||||
[[nodiscard]] bool isNotificationsUser() const {
|
[[nodiscard]] bool isNotificationsUser() const {
|
||||||
|
|
|
@ -48,6 +48,7 @@ public:
|
||||||
| MTPDuser::Flag::f_bot_chat_history
|
| MTPDuser::Flag::f_bot_chat_history
|
||||||
| MTPDuser::Flag::f_bot_nochats
|
| MTPDuser::Flag::f_bot_nochats
|
||||||
| MTPDuser::Flag::f_verified
|
| MTPDuser::Flag::f_verified
|
||||||
|
| MTPDuser::Flag::f_scam
|
||||||
| MTPDuser::Flag::f_restricted
|
| MTPDuser::Flag::f_restricted
|
||||||
| MTPDuser::Flag::f_bot_inline_geo;
|
| MTPDuser::Flag::f_bot_inline_geo;
|
||||||
using Flags = Data::Flags<
|
using Flags = Data::Flags<
|
||||||
|
@ -119,6 +120,9 @@ public:
|
||||||
bool isVerified() const {
|
bool isVerified() const {
|
||||||
return flags() & MTPDuser::Flag::f_verified;
|
return flags() & MTPDuser::Flag::f_verified;
|
||||||
}
|
}
|
||||||
|
bool isScam() const {
|
||||||
|
return flags() & MTPDuser::Flag::f_scam;
|
||||||
|
}
|
||||||
bool isBotInlineGeo() const {
|
bool isBotInlineGeo() const {
|
||||||
return flags() & MTPDuser::Flag::f_bot_inline_geo;
|
return flags() & MTPDuser::Flag::f_bot_inline_geo;
|
||||||
}
|
}
|
||||||
|
|
|
@ -268,3 +268,9 @@ dialogsSearchFromStyle: TextStyle(defaultTextStyle) {
|
||||||
dialogsSearchFromPalette: TextPalette(defaultTextPalette) {
|
dialogsSearchFromPalette: TextPalette(defaultTextPalette) {
|
||||||
linkFg: dialogsNameFg;
|
linkFg: dialogsNameFg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dialogsScamPadding: margins(2px, 0px, 2px, 0px);
|
||||||
|
dialogsScamFont: font(9px semibold);
|
||||||
|
dialogsScamSkip: 4px;
|
||||||
|
dialogsScamRadius: 2px;
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "window/window_peer_menu.h"
|
#include "window/window_peer_menu.h"
|
||||||
#include "ui/widgets/multi_select.h"
|
#include "ui/widgets/multi_select.h"
|
||||||
#include "ui/empty_userpic.h"
|
#include "ui/empty_userpic.h"
|
||||||
|
#include "ui/unread_badge.h"
|
||||||
#include "styles/style_dialogs.h"
|
#include "styles/style_dialogs.h"
|
||||||
#include "styles/style_chat_helpers.h"
|
#include "styles/style_chat_helpers.h"
|
||||||
#include "styles/style_window.h"
|
#include "styles/style_window.h"
|
||||||
|
@ -736,11 +737,25 @@ void InnerWidget::paintPeerSearchResult(
|
||||||
chatTypeIcon->paint(p, rectForName.topLeft(), fullWidth);
|
chatTypeIcon->paint(p, rectForName.topLeft(), fullWidth);
|
||||||
rectForName.setLeft(rectForName.left() + st::dialogsChatTypeSkip);
|
rectForName.setLeft(rectForName.left() + st::dialogsChatTypeSkip);
|
||||||
}
|
}
|
||||||
if (peer->isVerified()) {
|
const auto badgeStyle = Ui::PeerBadgeStyle{
|
||||||
auto icon = &(active ? st::dialogsVerifiedIconActive : (selected ? st::dialogsVerifiedIconOver : st::dialogsVerifiedIcon));
|
(active
|
||||||
rectForName.setWidth(rectForName.width() - icon->width());
|
? &st::dialogsVerifiedIconActive
|
||||||
icon->paint(p, rectForName.topLeft() + QPoint(qMin(peer->nameText().maxWidth(), rectForName.width()), 0), fullWidth);
|
: selected
|
||||||
}
|
? &st::dialogsVerifiedIconOver
|
||||||
|
: &st::dialogsVerifiedIcon),
|
||||||
|
(active
|
||||||
|
? &st::dialogsScamFgActive
|
||||||
|
: selected
|
||||||
|
? &st::dialogsScamFgOver
|
||||||
|
: &st::dialogsScamFg) };
|
||||||
|
const auto badgeWidth = Ui::DrawPeerBadgeGetWidth(
|
||||||
|
peer,
|
||||||
|
p,
|
||||||
|
rectForName,
|
||||||
|
peer->nameText().maxWidth(),
|
||||||
|
fullWidth,
|
||||||
|
badgeStyle);
|
||||||
|
rectForName.setWidth(rectForName.width() - badgeWidth);
|
||||||
|
|
||||||
QRect tr(nameleft, st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip, namewidth, st::dialogsTextFont->height);
|
QRect tr(nameleft, st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip, namewidth, st::dialogsTextFont->height);
|
||||||
p.setFont(st::dialogsTextFont);
|
p.setFont(st::dialogsTextFont);
|
||||||
|
|
|
@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "storage/localstorage.h"
|
#include "storage/localstorage.h"
|
||||||
#include "ui/empty_userpic.h"
|
#include "ui/empty_userpic.h"
|
||||||
#include "ui/text_options.h"
|
#include "ui/text_options.h"
|
||||||
|
#include "ui/unread_badge.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "support/support_helper.h"
|
#include "support/support_helper.h"
|
||||||
#include "history/history_item_components.h"
|
#include "history/history_item_components.h"
|
||||||
|
@ -406,26 +407,46 @@ void paintRow(
|
||||||
sendStateIcon->paint(p, rectForName.topLeft() + QPoint(rectForName.width(), 0), fullWidth);
|
sendStateIcon->paint(p, rectForName.topLeft() + QPoint(rectForName.width(), 0), fullWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto nameFg = active
|
|
||||||
? st::dialogsNameFgActive
|
|
||||||
: (selected
|
|
||||||
? st::dialogsNameFgOver
|
|
||||||
: st::dialogsNameFg);
|
|
||||||
p.setPen(nameFg);
|
|
||||||
if (flags & Flag::SavedMessages) {
|
if (flags & Flag::SavedMessages) {
|
||||||
p.setFont(st::msgNameFont);
|
|
||||||
auto text = tr::lng_saved_messages(tr::now);
|
auto text = tr::lng_saved_messages(tr::now);
|
||||||
auto textWidth = st::msgNameFont->width(text);
|
const auto textWidth = st::msgNameFont->width(text);
|
||||||
if (textWidth > rectForName.width()) {
|
if (textWidth > rectForName.width()) {
|
||||||
text = st::msgNameFont->elided(text, rectForName.width());
|
text = st::msgNameFont->elided(text, rectForName.width());
|
||||||
}
|
}
|
||||||
|
p.setFont(st::msgNameFont);
|
||||||
|
p.setPen(active
|
||||||
|
? st::dialogsNameFgActive
|
||||||
|
: selected
|
||||||
|
? st::dialogsNameFgOver
|
||||||
|
: st::dialogsNameFg);
|
||||||
p.drawTextLeft(rectForName.left(), rectForName.top(), fullWidth, text);
|
p.drawTextLeft(rectForName.left(), rectForName.top(), fullWidth, text);
|
||||||
} else if (from) {
|
} else if (from) {
|
||||||
if (!(flags & Flag::SearchResult) && from->isVerified()) {
|
if (!(flags & Flag::SearchResult)) {
|
||||||
auto icon = &(active ? st::dialogsVerifiedIconActive : (selected ? st::dialogsVerifiedIconOver : st::dialogsVerifiedIcon));
|
const auto badgeStyle = Ui::PeerBadgeStyle{
|
||||||
rectForName.setWidth(rectForName.width() - icon->width());
|
(active
|
||||||
icon->paint(p, rectForName.topLeft() + QPoint(qMin(from->nameText().maxWidth(), rectForName.width()), 0), fullWidth);
|
? &st::dialogsVerifiedIconActive
|
||||||
|
: selected
|
||||||
|
? &st::dialogsVerifiedIconOver
|
||||||
|
: &st::dialogsVerifiedIcon),
|
||||||
|
(active
|
||||||
|
? &st::dialogsScamFgActive
|
||||||
|
: selected
|
||||||
|
? &st::dialogsScamFgOver
|
||||||
|
: &st::dialogsScamFg) };
|
||||||
|
const auto badgeWidth = Ui::DrawPeerBadgeGetWidth(
|
||||||
|
from,
|
||||||
|
p,
|
||||||
|
rectForName,
|
||||||
|
from->nameText().maxWidth(),
|
||||||
|
fullWidth,
|
||||||
|
badgeStyle);
|
||||||
|
rectForName.setWidth(rectForName.width() - badgeWidth);
|
||||||
}
|
}
|
||||||
|
p.setPen(active
|
||||||
|
? st::dialogsNameFgActive
|
||||||
|
: selected
|
||||||
|
? st::dialogsNameFgOver
|
||||||
|
: st::dialogsNameFg);
|
||||||
from->nameText().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width());
|
from->nameText().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width());
|
||||||
} else if (hiddenSenderInfo) {
|
} else if (hiddenSenderInfo) {
|
||||||
hiddenSenderInfo->nameText.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width());
|
hiddenSenderInfo->nameText.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width());
|
||||||
|
|
|
@ -304,17 +304,17 @@ void TopBarWidget::paintTopBar(Painter &p) {
|
||||||
auto nameleft = _leftTaken;
|
auto nameleft = _leftTaken;
|
||||||
auto nametop = st::topBarArrowPadding.top();
|
auto nametop = st::topBarArrowPadding.top();
|
||||||
auto statustop = st::topBarHeight - st::topBarArrowPadding.bottom() - st::dialogsTextFont->height;
|
auto statustop = st::topBarHeight - st::topBarArrowPadding.bottom() - st::dialogsTextFont->height;
|
||||||
auto namewidth = width() - _rightTaken - nameleft;
|
auto availableWidth = width() - _rightTaken - nameleft;
|
||||||
|
|
||||||
auto history = _activeChat.history();
|
auto history = _activeChat.history();
|
||||||
|
|
||||||
p.setPen(st::dialogsNameFg);
|
|
||||||
if (const auto folder = _activeChat.folder()) {
|
if (const auto folder = _activeChat.folder()) {
|
||||||
auto text = folder->chatListName(); // TODO feed name emoji
|
auto text = folder->chatListName(); // TODO feed name emoji
|
||||||
auto textWidth = st::historySavedFont->width(text);
|
const auto textWidth = st::historySavedFont->width(text);
|
||||||
if (namewidth < textWidth) {
|
if (availableWidth < textWidth) {
|
||||||
text = st::historySavedFont->elided(text, namewidth);
|
text = st::historySavedFont->elided(text, availableWidth);
|
||||||
}
|
}
|
||||||
|
p.setPen(st::dialogsNameFg);
|
||||||
p.setFont(st::historySavedFont);
|
p.setFont(st::historySavedFont);
|
||||||
p.drawTextLeft(
|
p.drawTextLeft(
|
||||||
nameleft,
|
nameleft,
|
||||||
|
@ -323,10 +323,11 @@ void TopBarWidget::paintTopBar(Painter &p) {
|
||||||
text);
|
text);
|
||||||
} else if (_activeChat.peer()->isSelf()) {
|
} else if (_activeChat.peer()->isSelf()) {
|
||||||
auto text = tr::lng_saved_messages(tr::now);
|
auto text = tr::lng_saved_messages(tr::now);
|
||||||
auto textWidth = st::historySavedFont->width(text);
|
const auto textWidth = st::historySavedFont->width(text);
|
||||||
if (namewidth < textWidth) {
|
if (availableWidth < textWidth) {
|
||||||
text = st::historySavedFont->elided(text, namewidth);
|
text = st::historySavedFont->elided(text, availableWidth);
|
||||||
}
|
}
|
||||||
|
p.setPen(st::dialogsNameFg);
|
||||||
p.setFont(st::historySavedFont);
|
p.setFont(st::historySavedFont);
|
||||||
p.drawTextLeft(
|
p.drawTextLeft(
|
||||||
nameleft,
|
nameleft,
|
||||||
|
@ -334,7 +335,30 @@ void TopBarWidget::paintTopBar(Painter &p) {
|
||||||
width(),
|
width(),
|
||||||
text);
|
text);
|
||||||
} else if (const auto history = _activeChat.history()) {
|
} else if (const auto history = _activeChat.history()) {
|
||||||
history->peer->topBarNameText().drawElided(p, nameleft, nametop, namewidth);
|
const auto peer = history->peer;
|
||||||
|
const auto &text = peer->topBarNameText();
|
||||||
|
const auto badgeStyle = Ui::PeerBadgeStyle{
|
||||||
|
nullptr,
|
||||||
|
&st::attentionButtonFg };
|
||||||
|
const auto badgeWidth = Ui::DrawPeerBadgeGetWidth(
|
||||||
|
peer,
|
||||||
|
p,
|
||||||
|
QRect(
|
||||||
|
nameleft,
|
||||||
|
nametop,
|
||||||
|
availableWidth,
|
||||||
|
st::msgNameStyle.font->height),
|
||||||
|
text.maxWidth(),
|
||||||
|
width(),
|
||||||
|
badgeStyle);
|
||||||
|
const auto namewidth = availableWidth - badgeWidth;
|
||||||
|
|
||||||
|
p.setPen(st::dialogsNameFg);
|
||||||
|
peer->topBarNameText().drawElided(
|
||||||
|
p,
|
||||||
|
nameleft,
|
||||||
|
nametop,
|
||||||
|
namewidth);
|
||||||
|
|
||||||
p.setFont(st::dialogsTextFont);
|
p.setFont(st::dialogsTextFont);
|
||||||
if (paintConnectingState(p, nameleft, statustop, width())) {
|
if (paintConnectingState(p, nameleft, statustop, width())) {
|
||||||
|
@ -343,13 +367,13 @@ void TopBarWidget::paintTopBar(Painter &p) {
|
||||||
p,
|
p,
|
||||||
nameleft,
|
nameleft,
|
||||||
statustop,
|
statustop,
|
||||||
namewidth,
|
availableWidth,
|
||||||
width(),
|
width(),
|
||||||
st::historyStatusFgTyping,
|
st::historyStatusFgTyping,
|
||||||
crl::now())) {
|
crl::now())) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
paintStatus(p, nameleft, statustop, namewidth, width());
|
paintStatus(p, nameleft, statustop, availableWidth, width());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/effects/ripple_animation.h"
|
#include "ui/effects/ripple_animation.h"
|
||||||
#include "ui/text/text_utilities.h" // Ui::Text::ToUpper
|
#include "ui/text/text_utilities.h" // Ui::Text::ToUpper
|
||||||
#include "ui/special_buttons.h"
|
#include "ui/special_buttons.h"
|
||||||
|
#include "ui/unread_badge.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "observer_peer.h"
|
#include "observer_peer.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
|
@ -316,9 +317,14 @@ void Cover::initViewers(rpl::producer<QString> title) {
|
||||||
}
|
}
|
||||||
VerifiedValue(
|
VerifiedValue(
|
||||||
_peer
|
_peer
|
||||||
) | rpl::start_with_next(
|
) | rpl::start_with_next([=](bool verified) {
|
||||||
[=](bool verified) { setVerified(verified); },
|
setVerified(verified);
|
||||||
lifetime());
|
}, lifetime());
|
||||||
|
ScamValue(
|
||||||
|
_peer
|
||||||
|
) | rpl::start_with_next([=](bool scam) {
|
||||||
|
setScam(scam);
|
||||||
|
}, lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cover::refreshUploadPhotoOverlay() {
|
void Cover::refreshUploadPhotoOverlay() {
|
||||||
|
@ -337,6 +343,7 @@ void Cover::setVerified(bool verified) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (verified) {
|
if (verified) {
|
||||||
|
_scamBadge.destroy();
|
||||||
_verifiedCheck.create(this);
|
_verifiedCheck.create(this);
|
||||||
_verifiedCheck->show();
|
_verifiedCheck->show();
|
||||||
_verifiedCheck->resize(st::infoVerifiedCheck.size());
|
_verifiedCheck->resize(st::infoVerifiedCheck.size());
|
||||||
|
@ -351,6 +358,34 @@ void Cover::setVerified(bool verified) {
|
||||||
refreshNameGeometry(width());
|
refreshNameGeometry(width());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Cover::setScam(bool scam) {
|
||||||
|
if ((_scamBadge != nullptr) == scam) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (scam) {
|
||||||
|
_verifiedCheck.destroy();
|
||||||
|
const auto size = Ui::ScamBadgeSize();
|
||||||
|
const auto skip = st::infoVerifiedCheckPosition.x();
|
||||||
|
_scamBadge.create(this);
|
||||||
|
_scamBadge->show();
|
||||||
|
_scamBadge->resize(
|
||||||
|
size.width() + 2 * skip,
|
||||||
|
size.height() + 2 * skip);
|
||||||
|
_scamBadge->paintRequest(
|
||||||
|
) | rpl::start_with_next([=, badge = _scamBadge.data()] {
|
||||||
|
Painter p(badge);
|
||||||
|
Ui::DrawScamBadge(
|
||||||
|
p,
|
||||||
|
badge->rect().marginsRemoved({ skip, skip, skip, skip }),
|
||||||
|
badge->width(),
|
||||||
|
st::attentionButtonFg);
|
||||||
|
}, _scamBadge->lifetime());
|
||||||
|
} else {
|
||||||
|
_scamBadge.destroy();
|
||||||
|
}
|
||||||
|
refreshNameGeometry(width());
|
||||||
|
}
|
||||||
|
|
||||||
void Cover::refreshStatusText() {
|
void Cover::refreshStatusText() {
|
||||||
auto hasMembersLink = [&] {
|
auto hasMembersLink = [&] {
|
||||||
if (auto megagroup = _peer->asMegagroup()) {
|
if (auto megagroup = _peer->asMegagroup()) {
|
||||||
|
@ -409,17 +444,29 @@ void Cover::refreshNameGeometry(int newWidth) {
|
||||||
- toggleSkip();
|
- toggleSkip();
|
||||||
if (_verifiedCheck) {
|
if (_verifiedCheck) {
|
||||||
nameWidth -= st::infoVerifiedCheckPosition.x()
|
nameWidth -= st::infoVerifiedCheckPosition.x()
|
||||||
+ st::infoVerifiedCheck.width();
|
+ _verifiedCheck->width();
|
||||||
|
} else if (_scamBadge) {
|
||||||
|
nameWidth -= st::infoVerifiedCheckPosition.x()
|
||||||
|
+ _scamBadge->width();
|
||||||
}
|
}
|
||||||
_name->resizeToNaturalWidth(nameWidth);
|
_name->resizeToNaturalWidth(nameWidth);
|
||||||
_name->moveToLeft(nameLeft, nameTop, newWidth);
|
_name->moveToLeft(nameLeft, nameTop, newWidth);
|
||||||
if (_verifiedCheck) {
|
if (_verifiedCheck) {
|
||||||
auto checkLeft = nameLeft
|
const auto checkLeft = nameLeft
|
||||||
+ _name->width()
|
+ _name->width()
|
||||||
+ st::infoVerifiedCheckPosition.x();
|
+ st::infoVerifiedCheckPosition.x();
|
||||||
auto checkTop = nameTop
|
const auto checkTop = nameTop
|
||||||
+ st::infoVerifiedCheckPosition.y();
|
+ st::infoVerifiedCheckPosition.y();
|
||||||
_verifiedCheck->moveToLeft(checkLeft, checkTop, newWidth);
|
_verifiedCheck->moveToLeft(checkLeft, checkTop, newWidth);
|
||||||
|
} else if (_scamBadge) {
|
||||||
|
const auto skip = st::infoVerifiedCheckPosition.x();
|
||||||
|
const auto badgeLeft = nameLeft
|
||||||
|
+ _name->width()
|
||||||
|
+ st::infoVerifiedCheckPosition.x()
|
||||||
|
- skip;
|
||||||
|
const auto badgeTop = nameTop
|
||||||
|
+ (_name->height() - _scamBadge->height()) / 2;
|
||||||
|
_scamBadge->moveToLeft(badgeLeft, badgeTop, newWidth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,7 @@ private:
|
||||||
void refreshStatusGeometry(int newWidth);
|
void refreshStatusGeometry(int newWidth);
|
||||||
void refreshUploadPhotoOverlay();
|
void refreshUploadPhotoOverlay();
|
||||||
void setVerified(bool verified);
|
void setVerified(bool verified);
|
||||||
|
void setScam(bool scam);
|
||||||
|
|
||||||
not_null<PeerData*> _peer;
|
not_null<PeerData*> _peer;
|
||||||
int _onlineCount = 0;
|
int _onlineCount = 0;
|
||||||
|
@ -93,6 +94,7 @@ private:
|
||||||
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::RpWidget> _verifiedCheck = { nullptr };
|
object_ptr<Ui::RpWidget> _verifiedCheck = { nullptr };
|
||||||
|
object_ptr<Ui::RpWidget> _scamBadge = { 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;
|
||||||
|
|
|
@ -310,14 +310,14 @@ rpl::producer<int> CommonGroupsCountValue(not_null<UserData*> user) {
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<bool> CanAddMemberValue(not_null<PeerData*> peer) {
|
rpl::producer<bool> CanAddMemberValue(not_null<PeerData*> peer) {
|
||||||
if (auto chat = peer->asChat()) {
|
if (const auto chat = peer->asChat()) {
|
||||||
return Notify::PeerUpdateValue(
|
return Notify::PeerUpdateValue(
|
||||||
chat,
|
chat,
|
||||||
Notify::PeerUpdate::Flag::RightsChanged
|
Notify::PeerUpdate::Flag::RightsChanged
|
||||||
) | rpl::map([=] {
|
) | rpl::map([=] {
|
||||||
return chat->canAddMembers();
|
return chat->canAddMembers();
|
||||||
});
|
});
|
||||||
} else if (auto channel = peer->asChannel()) {
|
} else if (const auto channel = peer->asChannel()) {
|
||||||
return Notify::PeerUpdateValue(
|
return Notify::PeerUpdateValue(
|
||||||
channel,
|
channel,
|
||||||
Notify::PeerUpdate::Flag::RightsChanged
|
Notify::PeerUpdate::Flag::RightsChanged
|
||||||
|
@ -329,15 +329,26 @@ rpl::producer<bool> CanAddMemberValue(not_null<PeerData*> peer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<bool> VerifiedValue(not_null<PeerData*> peer) {
|
rpl::producer<bool> VerifiedValue(not_null<PeerData*> peer) {
|
||||||
if (auto user = peer->asUser()) {
|
if (const auto user = peer->asUser()) {
|
||||||
return Data::PeerFlagValue(user, MTPDuser::Flag::f_verified);
|
return Data::PeerFlagValue(user, MTPDuser::Flag::f_verified);
|
||||||
} else if (auto channel = peer->asChannel()) {
|
} else if (const auto channel = peer->asChannel()) {
|
||||||
return Data::PeerFlagValue(
|
return Data::PeerFlagValue(
|
||||||
channel,
|
channel,
|
||||||
MTPDchannel::Flag::f_verified);
|
MTPDchannel::Flag::f_verified);
|
||||||
}
|
}
|
||||||
return rpl::single(false);
|
return rpl::single(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpl::producer<bool> ScamValue(not_null<PeerData*> peer) {
|
||||||
|
if (const auto user = peer->asUser()) {
|
||||||
|
return Data::PeerFlagValue(user, MTPDuser::Flag::f_scam);
|
||||||
|
} else if (const auto channel = peer->asChannel()) {
|
||||||
|
return Data::PeerFlagValue(
|
||||||
|
channel,
|
||||||
|
MTPDchannel::Flag::f_scam);
|
||||||
|
}
|
||||||
|
return rpl::single(false);
|
||||||
|
}
|
||||||
// // #feed
|
// // #feed
|
||||||
//rpl::producer<int> FeedChannelsCountValue(not_null<Data::Feed*> feed) {
|
//rpl::producer<int> FeedChannelsCountValue(not_null<Data::Feed*> feed) {
|
||||||
// using Flag = Data::FeedUpdateFlag;
|
// using Flag = Data::FeedUpdateFlag;
|
||||||
|
|
|
@ -58,6 +58,7 @@ rpl::producer<int> SharedMediaCountValue(
|
||||||
rpl::producer<int> CommonGroupsCountValue(not_null<UserData*> user);
|
rpl::producer<int> CommonGroupsCountValue(not_null<UserData*> user);
|
||||||
rpl::producer<bool> CanAddMemberValue(not_null<PeerData*> peer);
|
rpl::producer<bool> CanAddMemberValue(not_null<PeerData*> peer);
|
||||||
rpl::producer<bool> VerifiedValue(not_null<PeerData*> peer);
|
rpl::producer<bool> VerifiedValue(not_null<PeerData*> peer);
|
||||||
|
rpl::producer<bool> ScamValue(not_null<PeerData*> peer);
|
||||||
|
|
||||||
//rpl::producer<int> FeedChannelsCountValue(not_null<Data::Feed*> feed); // #feed
|
//rpl::producer<int> FeedChannelsCountValue(not_null<Data::Feed*> feed); // #feed
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "ui/unread_badge.h"
|
#include "ui/unread_badge.h"
|
||||||
|
|
||||||
|
#include "data/data_peer.h"
|
||||||
#include "dialogs/dialogs_layout.h"
|
#include "dialogs/dialogs_layout.h"
|
||||||
|
#include "lang/lang_keys.h"
|
||||||
|
#include "styles/style_dialogs.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
||||||
|
@ -45,4 +48,91 @@ void UnreadBadge::paintEvent(QPaintEvent *e) {
|
||||||
unreadSt);
|
unreadSt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QSize ScamBadgeSize() {
|
||||||
|
const auto phrase = tr::lng_scam_badge(tr::now);
|
||||||
|
const auto phraseWidth = st::dialogsScamFont->width(phrase);
|
||||||
|
const auto width = st::dialogsScamPadding.left()
|
||||||
|
+ phraseWidth
|
||||||
|
+ st::dialogsScamPadding.right();
|
||||||
|
const auto height = st::dialogsScamPadding.top()
|
||||||
|
+ st::dialogsScamFont->height
|
||||||
|
+ st::dialogsScamPadding.bottom();
|
||||||
|
return { width, height };
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawScamBadge(
|
||||||
|
Painter &p,
|
||||||
|
QRect rect,
|
||||||
|
int outerWidth,
|
||||||
|
const style::color &color,
|
||||||
|
const QString &phrase,
|
||||||
|
int phraseWidth) {
|
||||||
|
PainterHighQualityEnabler hq(p);
|
||||||
|
auto pen = color->p;
|
||||||
|
pen.setWidth(st::lineWidth);
|
||||||
|
p.setPen(pen);
|
||||||
|
p.setBrush(Qt::NoBrush);
|
||||||
|
p.drawRoundedRect(rect, st::dialogsScamRadius, st::dialogsScamRadius);
|
||||||
|
p.setFont(st::dialogsScamFont);
|
||||||
|
p.drawTextLeft(
|
||||||
|
rect.x() + st::dialogsScamPadding.left(),
|
||||||
|
rect.y() + st::dialogsScamPadding.top(),
|
||||||
|
outerWidth,
|
||||||
|
phrase,
|
||||||
|
phraseWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawScamBadge(
|
||||||
|
Painter &p,
|
||||||
|
QRect rect,
|
||||||
|
int outerWidth,
|
||||||
|
const style::color &color) {
|
||||||
|
const auto phrase = tr::lng_scam_badge(tr::now);
|
||||||
|
DrawScamBadge(
|
||||||
|
p,
|
||||||
|
rect,
|
||||||
|
outerWidth,
|
||||||
|
color,
|
||||||
|
phrase,
|
||||||
|
st::dialogsScamFont->width(phrase));
|
||||||
|
}
|
||||||
|
|
||||||
|
int DrawPeerBadgeGetWidth(
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
Painter &p,
|
||||||
|
QRect rectForName,
|
||||||
|
int nameWidth,
|
||||||
|
int outerWidth,
|
||||||
|
const PeerBadgeStyle &st) {
|
||||||
|
if (peer->isVerified() && st.verified) {
|
||||||
|
const auto iconw = st.verified->width();
|
||||||
|
st.verified->paint(
|
||||||
|
p,
|
||||||
|
rectForName.x() + qMin(nameWidth, rectForName.width() - iconw),
|
||||||
|
rectForName.y(),
|
||||||
|
outerWidth);
|
||||||
|
return iconw;
|
||||||
|
} else if (peer->isScam() && st.scam) {
|
||||||
|
const auto phrase = tr::lng_scam_badge(tr::now);
|
||||||
|
const auto phraseWidth = st::dialogsScamFont->width(phrase);
|
||||||
|
const auto width = st::dialogsScamPadding.left()
|
||||||
|
+ phraseWidth
|
||||||
|
+ st::dialogsScamPadding.right();
|
||||||
|
const auto height = st::dialogsScamPadding.top()
|
||||||
|
+ st::dialogsScamFont->height
|
||||||
|
+ st::dialogsScamPadding.bottom();
|
||||||
|
const auto rect = QRect(
|
||||||
|
(rectForName.x()
|
||||||
|
+ qMin(
|
||||||
|
nameWidth + st::dialogsScamSkip,
|
||||||
|
rectForName.width() - width)),
|
||||||
|
rectForName.y() + (rectForName.height() - height) / 2,
|
||||||
|
width,
|
||||||
|
height);
|
||||||
|
DrawScamBadge(p, rect, outerWidth, *st.scam, phrase, phraseWidth);
|
||||||
|
return st::dialogsScamSkip + width;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
|
@ -27,4 +27,22 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PeerBadgeStyle {
|
||||||
|
const style::icon *verified = nullptr;
|
||||||
|
const style::color *scam = nullptr;
|
||||||
|
};
|
||||||
|
int DrawPeerBadgeGetWidth(
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
Painter &p,
|
||||||
|
QRect rectForName,
|
||||||
|
int nameWidth,
|
||||||
|
int outerWidth,
|
||||||
|
const PeerBadgeStyle &st);
|
||||||
|
QSize ScamBadgeSize();
|
||||||
|
void DrawScamBadge(
|
||||||
|
Painter &p,
|
||||||
|
QRect rect,
|
||||||
|
int outerWidth,
|
||||||
|
const style::color &color);
|
||||||
|
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
Loading…
Reference in New Issue