mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-25 04:38:23 +00:00
Featured stickers fully supported (unread badges, box, adding, etc).
This commit is contained in:
parent
991c6ddd99
commit
cd696ade4e
Binary file not shown.
Before Width: | Height: | Size: 176 KiB After Width: | Height: | Size: 176 KiB |
Binary file not shown.
Before Width: | Height: | Size: 239 KiB After Width: | Height: | Size: 238 KiB |
@ -1838,6 +1838,20 @@ stickersReorderFg: #777;
|
||||
stickersRowDisabledOpacity: 0.4;
|
||||
stickersRowDuration: 200;
|
||||
|
||||
stickersFeaturedHeight: 32px;
|
||||
stickersFeaturedFont: contactsNameFont;
|
||||
stickersFeaturedPosition: point(16px, 6px);
|
||||
stickersFeaturedBadgeFont: semiboldFont;
|
||||
stickersFeaturedBadgeSize: 21px;
|
||||
stickersFeaturedPen: contactsNewItemFg;
|
||||
stickersFeaturedUnreadBg: msgFileInBg;
|
||||
stickersFeaturedUnreadSize: 5px;
|
||||
stickersFeaturedUnreadSkip: 5px;
|
||||
stickersFeaturedUnreadTop: 7px;
|
||||
stickersFeaturedInstalled: icon {
|
||||
{ "mediaview_save_check", #40ace3 }
|
||||
};
|
||||
|
||||
emojiScroll: flatScroll(solidScroll) {
|
||||
deltat: 48px;
|
||||
}
|
||||
@ -1861,6 +1875,9 @@ stickersSettings: sprite(140px, 124px, 21px, 22px);
|
||||
savedGifsOver: sprite(329px, 286px, 21px, 22px);
|
||||
savedGifsActive: sprite(350px, 286px, 21px, 22px);
|
||||
|
||||
stickersSettingsUnreadSize: 17px;
|
||||
stickersSettingsUnreadPosition: point(4px, 5px);
|
||||
|
||||
emojiPanCategories: #f7f7f7;
|
||||
|
||||
rbEmoji: flatCheckbox {
|
||||
@ -2133,7 +2150,9 @@ mvCaptionRadius: 2px;
|
||||
mvCaptionBg: #11111180;
|
||||
mvCaptionFont: font(fsize);
|
||||
|
||||
medviewSaveMsgCheck: sprite(311px, 309px, 22px, 18px);
|
||||
medviewSaveMsgCheck: icon {
|
||||
{ "mediaview_save_check", #ffffff }
|
||||
};
|
||||
medviewSaveMsgFont: font(16px);
|
||||
medviewSaveMsgPadding: margins(55px, 19px, 29px, 20px);
|
||||
medviewSaveMsgCheckPos: point(23px, 21px);
|
||||
|
BIN
Telegram/Resources/icons/mediaview_save_check.png
Normal file
BIN
Telegram/Resources/icons/mediaview_save_check.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 454 B |
BIN
Telegram/Resources/icons/mediaview_save_check@2x.png
Normal file
BIN
Telegram/Resources/icons/mediaview_save_check@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 882 B |
@ -685,9 +685,11 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
"lng_stickers_you_have" = "Manage and reorder sticker packs";
|
||||
"lng_stickers_packs" = "Sticker Packs";
|
||||
"lng_stickers_reorder" = "Click and drag to reorder sticker packs";
|
||||
"lng_stickers_featured" = "Featured Stickers";
|
||||
"lng_stickers_remove" = "Delete";
|
||||
"lng_stickers_return" = "Undo";
|
||||
"lng_stickers_restore" = "Restore";
|
||||
"lng_stickers_add" = "Add";
|
||||
"lng_stickers_count" = "{count:Loading...|# sticker|# stickers}";
|
||||
|
||||
"lng_in_dlg_photo" = "Photo";
|
||||
|
@ -924,10 +924,10 @@ void ApiWrap::gotStickerSet(uint64 setId, const MTPmessages_StickerSet &result)
|
||||
_stickerSetRequests.remove(setId);
|
||||
|
||||
if (result.type() != mtpc_messages_stickerSet) return;
|
||||
const auto &d(result.c_messages_stickerSet());
|
||||
auto &d(result.c_messages_stickerSet());
|
||||
|
||||
if (d.vset.type() != mtpc_stickerSet) return;
|
||||
const auto &s(d.vset.c_stickerSet());
|
||||
auto &s(d.vset.c_stickerSet());
|
||||
|
||||
auto &sets = Global::RefStickerSets();
|
||||
auto it = sets.find(setId);
|
||||
@ -937,7 +937,7 @@ void ApiWrap::gotStickerSet(uint64 setId, const MTPmessages_StickerSet &result)
|
||||
it->hash = s.vhash.v;
|
||||
it->shortName = qs(s.vshort_name);
|
||||
it->title = stickerSetTitle(s);
|
||||
auto clientFlags = it->flags & (MTPDstickerSet_ClientFlag::f_featured | MTPDstickerSet_ClientFlag::f_not_loaded);
|
||||
auto clientFlags = it->flags & (MTPDstickerSet_ClientFlag::f_featured | MTPDstickerSet_ClientFlag::f_unread | MTPDstickerSet_ClientFlag::f_not_loaded);
|
||||
it->flags = s.vflags.v | clientFlags;
|
||||
it->flags &= ~MTPDstickerSet_ClientFlag::f_not_loaded;
|
||||
|
||||
|
@ -1979,6 +1979,9 @@ namespace {
|
||||
Global::SetStickerSets(Stickers::Sets());
|
||||
Global::SetStickerSetsOrder(Stickers::Order());
|
||||
Global::SetLastStickersUpdate(0);
|
||||
Global::SetFeaturedStickerSetsOrder(Stickers::Order());
|
||||
Global::SetFeaturedStickerSetsUnreadCount(0);
|
||||
Global::SetLastFeaturedStickersUpdate(0);
|
||||
cSetSavedGifs(SavedGifs());
|
||||
cSetLastSavedGifsUpdate(0);
|
||||
cSetReportSpamStatuses(ReportSpamStatuses());
|
||||
|
@ -28,6 +28,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "boxes/confirmbox.h"
|
||||
#include "apiwrap.h"
|
||||
#include "localstorage.h"
|
||||
#include "dialogs/dialogs_layout.h"
|
||||
|
||||
StickerSetInner::StickerSetInner(const MTPInputStickerSet &set) : TWidget()
|
||||
, _input(set) {
|
||||
@ -47,21 +48,21 @@ void StickerSetInner::gotSet(const MTPmessages_StickerSet &set) {
|
||||
_pack.clear();
|
||||
_emoji.clear();
|
||||
if (set.type() == mtpc_messages_stickerSet) {
|
||||
const auto &d(set.c_messages_stickerSet());
|
||||
const auto &v(d.vdocuments.c_vector().v);
|
||||
auto &d(set.c_messages_stickerSet());
|
||||
auto &v(d.vdocuments.c_vector().v);
|
||||
_pack.reserve(v.size());
|
||||
for (int32 i = 0, l = v.size(); i < l; ++i) {
|
||||
DocumentData *doc = App::feedDocument(v.at(i));
|
||||
for (int i = 0, l = v.size(); i < l; ++i) {
|
||||
auto doc = App::feedDocument(v.at(i));
|
||||
if (!doc || !doc->sticker()) continue;
|
||||
|
||||
_pack.push_back(doc);
|
||||
}
|
||||
const auto &packs(d.vpacks.c_vector().v);
|
||||
for (int32 i = 0, l = packs.size(); i < l; ++i) {
|
||||
auto &packs(d.vpacks.c_vector().v);
|
||||
for (int i = 0, l = packs.size(); i < l; ++i) {
|
||||
if (packs.at(i).type() != mtpc_stickerPack) continue;
|
||||
const auto &pack(packs.at(i).c_stickerPack());
|
||||
if (EmojiPtr e = emojiGetNoColor(emojiFromText(qs(pack.vemoticon)))) {
|
||||
const auto &stickers(pack.vdocuments.c_vector().v);
|
||||
auto &pack(packs.at(i).c_stickerPack());
|
||||
if (auto e = emojiGetNoColor(emojiFromText(qs(pack.vemoticon)))) {
|
||||
auto &stickers(pack.vdocuments.c_vector().v);
|
||||
StickerPack p;
|
||||
p.reserve(stickers.size());
|
||||
for (int32 j = 0, c = stickers.size(); j < c; ++j) {
|
||||
@ -74,7 +75,7 @@ void StickerSetInner::gotSet(const MTPmessages_StickerSet &set) {
|
||||
}
|
||||
}
|
||||
if (d.vset.type() == mtpc_stickerSet) {
|
||||
const auto &s(d.vset.c_stickerSet());
|
||||
auto &s(d.vset.c_stickerSet());
|
||||
_setTitle = stickerSetTitle(s);
|
||||
_title = st::boxTitleFont->elided(_setTitle, width() - st::boxTitlePosition.x() - st::boxTitleHeight);
|
||||
_setShortName = qs(s.vshort_name);
|
||||
@ -83,6 +84,15 @@ void StickerSetInner::gotSet(const MTPmessages_StickerSet &set) {
|
||||
_setCount = s.vcount.v;
|
||||
_setHash = s.vhash.v;
|
||||
_setFlags = s.vflags.v;
|
||||
auto &sets = Global::RefStickerSets();
|
||||
auto it = sets.find(_setId);
|
||||
if (it != sets.cend()) {
|
||||
auto clientFlags = it->flags & (MTPDstickerSet_ClientFlag::f_featured | MTPDstickerSet_ClientFlag::f_not_loaded | MTPDstickerSet_ClientFlag::f_unread);
|
||||
_setFlags |= clientFlags;
|
||||
it->flags = _setFlags;
|
||||
it->stickers = _pack;
|
||||
it->emoji = _emoji;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,13 +126,13 @@ void StickerSetInner::installDone(const MTPBool &result) {
|
||||
if (it == sets.cend()) {
|
||||
it = sets.insert(_setId, Stickers::Set(_setId, _setAccess, _setTitle, _setShortName, _setCount, _setHash, _setFlags));
|
||||
} else {
|
||||
it.value().flags = _setFlags;
|
||||
it->flags = _setFlags;
|
||||
}
|
||||
it.value().stickers = _pack;
|
||||
it.value().emoji = _emoji;
|
||||
it->stickers = _pack;
|
||||
it->emoji = _emoji;
|
||||
|
||||
auto &order = Global::RefStickerSetsOrder();
|
||||
int32 insertAtIndex = 0, currentIndex = order.indexOf(_setId);
|
||||
int insertAtIndex = 0, currentIndex = order.indexOf(_setId);
|
||||
if (currentIndex != insertAtIndex) {
|
||||
if (currentIndex > 0) {
|
||||
order.removeAt(currentIndex);
|
||||
@ -132,8 +142,8 @@ void StickerSetInner::installDone(const MTPBool &result) {
|
||||
|
||||
auto custom = sets.find(Stickers::CustomSetId);
|
||||
if (custom != sets.cend()) {
|
||||
for (int32 i = 0, l = _pack.size(); i < l; ++i) {
|
||||
int32 removeIndex = custom->stickers.indexOf(_pack.at(i));
|
||||
for_const (auto sticker, _pack) {
|
||||
int removeIndex = custom->stickers.indexOf(sticker);
|
||||
if (removeIndex >= 0) custom->stickers.removeAt(removeIndex);
|
||||
}
|
||||
if (custom->stickers.isEmpty()) {
|
||||
@ -141,8 +151,8 @@ void StickerSetInner::installDone(const MTPBool &result) {
|
||||
}
|
||||
}
|
||||
Local::writeStickers();
|
||||
emit App::main()->stickersUpdated();
|
||||
emit installed(_setId);
|
||||
Ui::hideLayer();
|
||||
}
|
||||
|
||||
bool StickerSetInner::installFailed(const RPCError &error) {
|
||||
@ -295,7 +305,7 @@ StickerSetBox::StickerSetBox(const MTPInputStickerSet &set) : ScrollableBox(st::
|
||||
connect(&_inner, SIGNAL(updateButtons()), this, SLOT(onUpdateButtons()));
|
||||
connect(&_scroll, SIGNAL(scrolled()), this, SLOT(onScroll()));
|
||||
|
||||
connect(&_inner, SIGNAL(installed(uint64)), this, SIGNAL(installed(uint64)));
|
||||
connect(&_inner, SIGNAL(installed(uint64)), this, SLOT(onInstalled(uint64)));
|
||||
|
||||
onStickersUpdated();
|
||||
|
||||
@ -304,6 +314,11 @@ StickerSetBox::StickerSetBox(const MTPInputStickerSet &set) : ScrollableBox(st::
|
||||
prepare();
|
||||
}
|
||||
|
||||
void StickerSetBox::onInstalled(uint64 setId) {
|
||||
emit installed(setId);
|
||||
onClose();
|
||||
}
|
||||
|
||||
void StickerSetBox::onStickersUpdated() {
|
||||
showAll();
|
||||
}
|
||||
@ -392,28 +407,44 @@ void StickerSetBox::resizeEvent(QResizeEvent *e) {
|
||||
}
|
||||
}
|
||||
|
||||
StickersInner::StickersInner() : TWidget()
|
||||
namespace internal {
|
||||
|
||||
StickersInner::StickersInner(StickersBox::Section section) : TWidget()
|
||||
, _section(section)
|
||||
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
|
||||
, _aboveShadowFadeStart(0)
|
||||
, _aboveShadowFadeOpacity(0, 0)
|
||||
, _a_shifting(animation(this, &StickersInner::step_shifting))
|
||||
, _itemsTop(st::membersPadding.top())
|
||||
, _saving(false)
|
||||
, _removeSel(-1)
|
||||
, _removeDown(-1)
|
||||
, _removeWidth(st::normalFont->width(lang(lng_stickers_remove)))
|
||||
, _returnWidth(st::normalFont->width(lang(lng_stickers_return)))
|
||||
, _restoreWidth(st::normalFont->width(lang(lng_stickers_restore)))
|
||||
, _selected(-1)
|
||||
, _started(-1)
|
||||
, _dragging(-1)
|
||||
, _above(-1)
|
||||
, _aboveShadow(st::boxShadow)
|
||||
, _scrollbar(0) {
|
||||
, _addText(lang(lng_stickers_add).toUpper())
|
||||
, _addWidth(st::defaultActiveButton.font->width(_addText))
|
||||
, _aboveShadow(st::boxShadow) {
|
||||
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
|
||||
setMouseTracking(true);
|
||||
}
|
||||
|
||||
void StickersInner::paintFeaturedButton(Painter &p) const {
|
||||
if (!_featuredHeight) return;
|
||||
|
||||
if (_selected == -1) {
|
||||
p.fillRect(0, st::membersPadding.top(), width(), _featuredHeight, st::contactsBgOver);
|
||||
}
|
||||
p.setFont(st::stickersFeaturedFont);
|
||||
p.setPen(st::stickersFeaturedPen);
|
||||
p.drawTextLeft(st::stickersFeaturedPosition.x(), st::membersPadding.top() + st::stickersFeaturedPosition.y(), width(), lang(lng_stickers_featured));
|
||||
|
||||
if (auto unread = Global::FeaturedStickerSetsUnreadCount()) {
|
||||
Dialogs::Layout::UnreadBadgeStyle unreadSt;
|
||||
unreadSt.sizeId = Dialogs::Layout::UnreadBadgeInStickersBox;
|
||||
unreadSt.size = st::stickersFeaturedBadgeSize;
|
||||
int unreadRight = width() - (st::contactsPadding.right() + st::contactsCheckPosition.x());
|
||||
if (rtl()) unreadRight = width() - unreadRight;
|
||||
int unreadTop = st::membersPadding.top() + (_featuredHeight - st::stickersFeaturedBadgeSize) / 2;
|
||||
Dialogs::Layout::paintUnreadCount(p, QString::number(unread), unreadRight, unreadTop, unreadSt);
|
||||
}
|
||||
}
|
||||
|
||||
void StickersInner::paintEvent(QPaintEvent *e) {
|
||||
QRect r(e->rect());
|
||||
Painter p(this);
|
||||
@ -422,10 +453,13 @@ void StickersInner::paintEvent(QPaintEvent *e) {
|
||||
|
||||
p.fillRect(r, st::white);
|
||||
p.setClipRect(r);
|
||||
|
||||
paintFeaturedButton(p);
|
||||
|
||||
if (_rows.isEmpty()) {
|
||||
p.setFont(st::noContactsFont->f);
|
||||
p.setPen(st::noContactsColor->p);
|
||||
p.drawText(QRect(0, 0, width(), st::noContactsHeight), lang(lng_contacts_loading), style::al_center);
|
||||
p.setFont(st::noContactsFont);
|
||||
p.setPen(st::noContactsColor);
|
||||
p.drawText(QRect(0, _featuredHeight, width(), st::noContactsHeight), lang(lng_contacts_loading), style::al_center);
|
||||
} else {
|
||||
p.translate(0, _itemsTop);
|
||||
|
||||
@ -452,33 +486,50 @@ void StickersInner::paintRow(Painter &p, int32 index) {
|
||||
int32 xadd = 0, yadd = s->yadd.current();
|
||||
if (xadd || yadd) p.translate(xadd, yadd);
|
||||
|
||||
bool removeSel = (index == _removeSel && (_removeDown < 0 || index == _removeDown));
|
||||
bool removeDown = removeSel && (index == _removeDown);
|
||||
if (_section == Section::Installed) {
|
||||
bool removeSel = (index == _actionSel && (_actionDown < 0 || index == _actionDown));
|
||||
bool removeDown = removeSel && (index == _actionDown);
|
||||
|
||||
p.setFont((removeSel ? st::linkOverFont : st::linkFont)->f);
|
||||
if (removeDown) {
|
||||
p.setPen(st::btnDefLink.downColor->p);
|
||||
} else {
|
||||
p.setPen(st::btnDefLink.color->p);
|
||||
}
|
||||
int32 remWidth = s->disabled ? (s->official ? _restoreWidth : _returnWidth) : _removeWidth;
|
||||
QString remText = lang(s->disabled ? (s->official ? lng_stickers_restore : lng_stickers_return) : lng_stickers_remove);
|
||||
p.drawTextRight(st::contactsPadding.right() + st::contactsCheckPosition.x(), st::contactsPadding.top() + (st::contactsPhotoSize - st::normalFont->height) / 2, width(), remText, remWidth);
|
||||
|
||||
if (index == _above) {
|
||||
float64 current = _aboveShadowFadeOpacity.current();
|
||||
if (_started >= 0) {
|
||||
float64 o = aboveShadowOpacity();
|
||||
if (o > current) {
|
||||
_aboveShadowFadeOpacity = anim::fvalue(o, o);
|
||||
current = o;
|
||||
}
|
||||
p.setFont(removeSel ? st::linkOverFont : st::linkFont);
|
||||
if (removeDown) {
|
||||
p.setPen(st::btnDefLink.downColor);
|
||||
} else {
|
||||
p.setPen(st::btnDefLink.color);
|
||||
}
|
||||
p.setOpacity(current);
|
||||
QRect row(myrtlrect(_aboveShadow.getDimensions(st::boxShadowShift).left(), st::contactsPadding.top() / 2, width() - (st::contactsPadding.left() / 2) - _scrollbar - _aboveShadow.getDimensions(st::boxShadowShift).right(), _rowHeight - ((st::contactsPadding.top() + st::contactsPadding.bottom()) / 2)));
|
||||
_aboveShadow.paint(p, row, st::boxShadowShift);
|
||||
p.fillRect(row, st::white);
|
||||
p.setOpacity(1);
|
||||
int32 remWidth = s->disabled ? (s->official ? _restoreWidth : _returnWidth) : _removeWidth;
|
||||
QString remText = lang(s->disabled ? (s->official ? lng_stickers_restore : lng_stickers_return) : lng_stickers_remove);
|
||||
p.drawTextRight(st::contactsPadding.right() + st::contactsCheckPosition.x(), st::contactsPadding.top() + (st::contactsPhotoSize - st::normalFont->height) / 2, width(), remText, remWidth);
|
||||
|
||||
if (index == _above) {
|
||||
float64 current = _aboveShadowFadeOpacity.current();
|
||||
if (_started >= 0) {
|
||||
float64 o = aboveShadowOpacity();
|
||||
if (o > current) {
|
||||
_aboveShadowFadeOpacity = anim::fvalue(o, o);
|
||||
current = o;
|
||||
}
|
||||
}
|
||||
p.setOpacity(current);
|
||||
QRect row(myrtlrect(_aboveShadow.getDimensions(st::boxShadowShift).left(), st::contactsPadding.top() / 2, width() - (st::contactsPadding.left() / 2) - _scrollbar - _aboveShadow.getDimensions(st::boxShadowShift).right(), _rowHeight - ((st::contactsPadding.top() + st::contactsPadding.bottom()) / 2)));
|
||||
_aboveShadow.paint(p, row, st::boxShadowShift);
|
||||
p.fillRect(row, st::white);
|
||||
p.setOpacity(1);
|
||||
}
|
||||
} else if (s->installed) {
|
||||
int addw = _addWidth - st::defaultActiveButton.width;
|
||||
int checkx = width() - (st::contactsPadding.right() + st::contactsCheckPosition.x() + (addw + st::stickersFeaturedInstalled.width()) / 2);
|
||||
int checky = st::contactsPadding.top() + (st::contactsPhotoSize - st::stickersFeaturedInstalled.height()) / 2;
|
||||
st::stickersFeaturedInstalled.paint(p, QPoint(checkx, checky), width());
|
||||
} else {
|
||||
int addw = _addWidth - st::defaultActiveButton.width;
|
||||
int addx = width() - st::contactsPadding.right() - st::contactsCheckPosition.x() - addw;
|
||||
int addy = st::contactsPadding.top() + (st::contactsPhotoSize - st::defaultActiveButton.height) / 2;
|
||||
QRect add(myrtlrect(addx, addy, addw, st::defaultActiveButton.height));
|
||||
|
||||
App::roundRect(p, add, st::defaultActiveButton.textBgOver);
|
||||
p.setFont(st::defaultActiveButton.font);
|
||||
p.setPen(st::defaultActiveButton.textFg);
|
||||
p.drawTextLeft(addx - st::defaultActiveButton.width / 2, addy + st::defaultActiveButton.textTop, width(), _addText, _addWidth);
|
||||
}
|
||||
|
||||
if (s->disabled) p.setOpacity(st::stickersRowDisabledOpacity);
|
||||
@ -487,15 +538,28 @@ void StickersInner::paintRow(Painter &p, int32 index) {
|
||||
QPixmap pix(s->sticker->thumb->pix(s->pixw, s->pixh));
|
||||
p.drawPixmapLeft(st::contactsPadding.left() + (st::contactsPhotoSize - s->pixw) / 2, st::contactsPadding.top() + (st::contactsPhotoSize - s->pixh) / 2, width(), pix);
|
||||
}
|
||||
|
||||
int namex = st::contactsPadding.left() + st::contactsPhotoSize + st::contactsPadding.left();
|
||||
int namey = st::contactsPadding.top() + st::contactsNameTop;
|
||||
int statusx = namex;
|
||||
int statusy = st::contactsPadding.top() + st::contactsStatusTop;
|
||||
|
||||
if (s->unread) {
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(st::stickersFeaturedUnreadBg);
|
||||
|
||||
p.setRenderHint(QPainter::HighQualityAntialiasing, true);
|
||||
p.drawEllipse(rtlrect(namex, namey + st::stickersFeaturedUnreadTop, st::stickersFeaturedUnreadSize, st::stickersFeaturedUnreadSize, width()));
|
||||
p.setRenderHint(QPainter::HighQualityAntialiasing, false);
|
||||
namex += st::stickersFeaturedUnreadSize + st::stickersFeaturedUnreadSkip;
|
||||
}
|
||||
p.setFont(st::contactsNameFont);
|
||||
p.setPen(st::black);
|
||||
|
||||
int32 namex = st::contactsPadding.left() + st::contactsPhotoSize + st::contactsPadding.left();
|
||||
p.drawTextLeft(namex, st::contactsPadding.top() + st::contactsNameTop, width(), s->title);
|
||||
p.drawTextLeft(namex, namey, width(), s->title);
|
||||
|
||||
p.setFont(st::contactsStatusFont);
|
||||
p.setPen(st::contactsStatusFg);
|
||||
p.drawTextLeft(namex, st::contactsPadding.top() + st::contactsStatusTop, width(), lng_stickers_count(lt_count, s->count));
|
||||
p.drawTextLeft(statusx, statusy, width(), lng_stickers_count(lt_count, s->count));
|
||||
|
||||
p.setOpacity(1);
|
||||
if (xadd || yadd) p.translate(-xadd, -yadd);
|
||||
@ -506,10 +570,12 @@ void StickersInner::mousePressEvent(QMouseEvent *e) {
|
||||
if (_dragging >= 0) mouseReleaseEvent(e);
|
||||
_mouse = e->globalPos();
|
||||
onUpdateSelected();
|
||||
if (_removeSel >= 0) {
|
||||
_removeDown = _removeSel;
|
||||
update(0, _itemsTop + _removeSel * _rowHeight, width(), _rowHeight);
|
||||
} else if (_selected >= 0) {
|
||||
|
||||
_pressed = _selected;
|
||||
if (_actionSel >= 0) {
|
||||
_actionDown = _actionSel;
|
||||
update(0, _itemsTop + _actionSel * _rowHeight, width(), _rowHeight);
|
||||
} else if (_selected >= 0 && _section == Section::Installed) {
|
||||
_above = _dragging = _started = _selected;
|
||||
_dragStart = mapFromGlobal(_mouse);
|
||||
}
|
||||
@ -557,15 +623,39 @@ void StickersInner::onUpdateSelected() {
|
||||
emit checkDraggingScroll(local.y());
|
||||
} else {
|
||||
bool in = rect().marginsRemoved(QMargins(0, _itemsTop, 0, st::membersPadding.bottom())).contains(local);
|
||||
_selected = in ? floorclamp(local.y() - _itemsTop, _rowHeight, 0, _rows.size() - 1) : -1;
|
||||
int32 removeSel = -1;
|
||||
int selected = -2;
|
||||
int actionSel = -1;
|
||||
if (in) {
|
||||
selected = floorclamp(local.y() - _itemsTop, _rowHeight, 0, _rows.size() - 1);
|
||||
|
||||
if (_selected >= 0) {
|
||||
int32 remw = _rows.at(_selected)->disabled ? (_rows.at(_selected)->official ? _restoreWidth : _returnWidth) : _removeWidth;
|
||||
QRect rem(myrtlrect(width() - st::contactsPadding.right() - st::contactsCheckPosition.x() - remw, st::contactsPadding.top() + (st::contactsPhotoSize - st::normalFont->height) / 2, remw, st::normalFont->height));
|
||||
removeSel = rem.contains(local.x(), local.y() - _itemsTop - _selected * _rowHeight) ? _selected : -1;
|
||||
if (_section == Section::Installed) {
|
||||
int remw = _rows.at(selected)->disabled ? (_rows.at(selected)->official ? _restoreWidth : _returnWidth) : _removeWidth;
|
||||
QRect rem(myrtlrect(width() - st::contactsPadding.right() - st::contactsCheckPosition.x() - remw, st::contactsPadding.top() + (st::contactsPhotoSize - st::normalFont->height) / 2, remw, st::normalFont->height));
|
||||
actionSel = rem.contains(local.x(), local.y() - _itemsTop - selected * _rowHeight) ? selected : -1;
|
||||
} else if (_rows.at(selected)->installed) {
|
||||
actionSel = -1;
|
||||
} else {
|
||||
int addw = _addWidth - st::defaultActiveButton.width;
|
||||
int addx = width() - st::contactsPadding.right() - st::contactsCheckPosition.x() - addw;
|
||||
int addy = st::contactsPadding.top() + (st::contactsPhotoSize - st::defaultActiveButton.height) / 2;
|
||||
QRect add(myrtlrect(addx, addy, addw, st::defaultActiveButton.height));
|
||||
actionSel = add.contains(local.x(), local.y() - _itemsTop - selected * _rowHeight) ? selected : -1;
|
||||
}
|
||||
} else if (_featuredHeight && QRect(0, st::membersPadding.top(), width(), _featuredHeight).contains(local)) {
|
||||
selected = -1;
|
||||
} else {
|
||||
selected = -2;
|
||||
}
|
||||
setRemoveSel(removeSel);
|
||||
if (_selected != selected) {
|
||||
if ((_selected == -1) != (selected == -1)) {
|
||||
update();
|
||||
}
|
||||
if (_section == Section::Featured && ((_selected >= 0 || _pressed >= 0) != (selected >= 0 || _pressed >= 0))) {
|
||||
setCursor((selected >= 0 || _pressed >= 0) ? style::cur_pointer : style::cur_default);
|
||||
}
|
||||
_selected = selected;
|
||||
}
|
||||
setActionSel(actionSel);
|
||||
emit noDraggingScroll();
|
||||
}
|
||||
}
|
||||
@ -579,11 +669,23 @@ float64 StickersInner::aboveShadowOpacity() const {
|
||||
}
|
||||
|
||||
void StickersInner::mouseReleaseEvent(QMouseEvent *e) {
|
||||
auto pressed = _pressed;
|
||||
_pressed = -2;
|
||||
|
||||
if (_section == Section::Featured && _selected < 0 && pressed >= 0) {
|
||||
setCursor(style::cur_default);
|
||||
}
|
||||
|
||||
if (_saving) return;
|
||||
|
||||
_mouse = e->globalPos();
|
||||
onUpdateSelected();
|
||||
if (_removeDown == _removeSel && _removeSel >= 0) {
|
||||
_rows[_removeDown]->disabled = !_rows[_removeDown]->disabled;
|
||||
if (_actionDown == _actionSel && _actionSel >= 0) {
|
||||
if (_section == Section::Installed) {
|
||||
_rows[_actionDown]->disabled = !_rows[_actionDown]->disabled;
|
||||
} else {
|
||||
installSet(_rows[_actionDown]->id);
|
||||
}
|
||||
} else if (_dragging >= 0) {
|
||||
QPoint local(mapFromGlobal(_mouse));
|
||||
_rows[_dragging]->yadd.start(0);
|
||||
@ -594,13 +696,66 @@ void StickersInner::mouseReleaseEvent(QMouseEvent *e) {
|
||||
}
|
||||
|
||||
_dragging = _started = -1;
|
||||
} else if (pressed == _selected) {
|
||||
if (_selected == -1) {
|
||||
_selected = -2;
|
||||
Ui::showLayer(new StickersBox(Section::Featured), KeepOtherLayers);
|
||||
} else if (_selected >= 0 && _section == Section::Featured) {
|
||||
auto &sets = Global::RefStickerSets();
|
||||
auto it = sets.find(_rows.at(pressed)->id);
|
||||
if (it != sets.cend()) {
|
||||
_selected = -2;
|
||||
Ui::showLayer(new StickerSetBox(Stickers::inputSetId(*it)), KeepOtherLayers);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_removeDown >= 0) {
|
||||
update(0, _itemsTop + _removeDown * _rowHeight, width(), _rowHeight);
|
||||
_removeDown = -1;
|
||||
if (_actionDown >= 0) {
|
||||
update(0, _itemsTop + _actionDown * _rowHeight, width(), _rowHeight);
|
||||
_actionDown = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void StickersInner::leaveEvent(QEvent *e) {
|
||||
_mouse = QPoint(-1, -1);
|
||||
onUpdateSelected();
|
||||
}
|
||||
|
||||
void StickersInner::installSet(uint64 setId) {
|
||||
auto &sets = Global::RefStickerSets();
|
||||
auto it = sets.find(setId);
|
||||
if (it == sets.cend()) {
|
||||
rebuild();
|
||||
return;
|
||||
}
|
||||
|
||||
MTP::send(MTPmessages_InstallStickerSet(Stickers::inputSetId(*it), MTP_boolFalse()));
|
||||
|
||||
it->flags &= ~(MTPDstickerSet::Flag::f_disabled | MTPDstickerSet_ClientFlag::f_unread);
|
||||
it->flags |= MTPDstickerSet::Flag::f_installed;
|
||||
|
||||
auto &order = Global::RefStickerSetsOrder();
|
||||
int insertAtIndex = 0, currentIndex = order.indexOf(setId);
|
||||
if (currentIndex != insertAtIndex) {
|
||||
if (currentIndex > 0) {
|
||||
order.removeAt(currentIndex);
|
||||
}
|
||||
order.insert(insertAtIndex, setId);
|
||||
}
|
||||
|
||||
auto custom = sets.find(Stickers::CustomSetId);
|
||||
if (custom != sets.cend()) {
|
||||
for_const (auto sticker, it->stickers) {
|
||||
int removeIndex = custom->stickers.indexOf(sticker);
|
||||
if (removeIndex >= 0) custom->stickers.removeAt(removeIndex);
|
||||
}
|
||||
if (custom->stickers.isEmpty()) {
|
||||
sets.erase(custom);
|
||||
}
|
||||
}
|
||||
Local::writeStickers();
|
||||
emit App::main()->stickersUpdated();
|
||||
}
|
||||
|
||||
void StickersInner::step_shifting(uint64 ms, bool timer) {
|
||||
bool animating = false;
|
||||
int32 updateMin = -1, updateMax = 0;
|
||||
@ -653,72 +808,123 @@ void StickersInner::clear() {
|
||||
_aboveShadowFadeStart = 0;
|
||||
_aboveShadowFadeOpacity = anim::fvalue(0, 0);
|
||||
_a_shifting.stop();
|
||||
_above = _dragging = _started = -1;
|
||||
_selected = -1;
|
||||
_removeDown = -1;
|
||||
setRemoveSel(-1);
|
||||
update();
|
||||
_above = _dragging = _started = -1;
|
||||
_selected = -2;
|
||||
_pressed = -2;
|
||||
_actionDown = -1;
|
||||
setActionSel(-1);
|
||||
update();
|
||||
}
|
||||
|
||||
void StickersInner::setRemoveSel(int32 removeSel) {
|
||||
if (removeSel != _removeSel) {
|
||||
if (_removeSel >= 0) update(0, _itemsTop + _removeSel * _rowHeight, width(), _rowHeight);
|
||||
_removeSel = removeSel;
|
||||
if (_removeSel >= 0) update(0, _itemsTop + _removeSel * _rowHeight, width(), _rowHeight);
|
||||
setCursor((_removeSel >= 0 && (_removeDown < 0 || _removeDown == _removeSel)) ? style::cur_pointer : style::cur_default);
|
||||
void StickersInner::setActionSel(int32 actionSel) {
|
||||
if (actionSel != _actionSel) {
|
||||
if (_actionSel >= 0) update(0, _itemsTop + _actionSel * _rowHeight, width(), _rowHeight);
|
||||
_actionSel = actionSel;
|
||||
if (_actionSel >= 0) update(0, _itemsTop + _actionSel * _rowHeight, width(), _rowHeight);
|
||||
if (_section == Section::Installed) {
|
||||
setCursor((_actionSel >= 0 && (_actionDown < 0 || _actionDown == _actionSel)) ? style::cur_pointer : style::cur_default);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StickersInner::rebuild() {
|
||||
QList<StickerSetRow*> rows, rowsDisabled;
|
||||
|
||||
int32 namex = st::contactsPadding.left() + st::contactsPhotoSize + st::contactsPadding.left();
|
||||
int32 namew = st::boxWideWidth - namex - st::contactsPadding.right() - st::contactsCheckPosition.x() - qMax(qMax(_returnWidth, _removeWidth), _restoreWidth);
|
||||
_itemsTop = st::membersPadding.top();
|
||||
_featuredHeight = 0;
|
||||
if (_section == Section::Installed && !Global::FeaturedStickerSetsOrder().isEmpty()) {
|
||||
_featuredHeight = st::stickersFeaturedHeight;
|
||||
_itemsTop += _featuredHeight + st::membersPadding.top();
|
||||
}
|
||||
|
||||
int namex = st::contactsPadding.left() + st::contactsPhotoSize + st::contactsPadding.left();
|
||||
int namew = st::boxWideWidth - namex - st::contactsPadding.right() - st::contactsCheckPosition.x();
|
||||
if (_section == Section::Installed) {
|
||||
namew -= qMax(qMax(_returnWidth, _removeWidth), _restoreWidth);
|
||||
} else {
|
||||
namew -= _addWidth - st::defaultActiveButton.width;
|
||||
}
|
||||
|
||||
clear();
|
||||
auto &order = Global::StickerSetsOrder();
|
||||
auto &order = (_section == Section::Installed) ? Global::StickerSetsOrder() : Global::FeaturedStickerSetsOrder();
|
||||
_animStartTimes.reserve(order.size());
|
||||
|
||||
auto &sets = Global::StickerSets();
|
||||
for (int i = 0, l = order.size(); i < l; ++i) {
|
||||
auto it = sets.constFind(order.at(i));
|
||||
if (it != sets.cend()) {
|
||||
bool disabled = (it->flags & MTPDstickerSet::Flag::f_disabled);
|
||||
for_const (auto setId, order) {
|
||||
auto it = sets.constFind(setId);
|
||||
if (it == sets.cend()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DocumentData *sticker = it->stickers.isEmpty() ? 0 : it->stickers.at(0);
|
||||
int32 pixw = 0, pixh = 0;
|
||||
if (sticker) {
|
||||
pixw = sticker->thumb->width();
|
||||
pixh = sticker->thumb->height();
|
||||
if (pixw > st::contactsPhotoSize) {
|
||||
if (pixw > pixh) {
|
||||
pixh = (pixh * st::contactsPhotoSize) / pixw;
|
||||
pixw = st::contactsPhotoSize;
|
||||
} else {
|
||||
pixw = (pixw * st::contactsPhotoSize) / pixh;
|
||||
pixh = st::contactsPhotoSize;
|
||||
}
|
||||
} else if (pixh > st::contactsPhotoSize) {
|
||||
bool installed = (it->flags & MTPDstickerSet::Flag::f_installed);
|
||||
bool disabled = (_section == Section::Installed) && (it->flags & MTPDstickerSet::Flag::f_disabled);
|
||||
bool official = (it->flags & MTPDstickerSet::Flag::f_official);
|
||||
bool unread = (_section == Section::Featured) && _unreadSets.contains(it->id);
|
||||
if (!unread && _section == Section::Featured && (it->flags & MTPDstickerSet_ClientFlag::f_unread)) {
|
||||
unread = true;
|
||||
_unreadSets.insert(it->id);
|
||||
}
|
||||
|
||||
DocumentData *sticker = it->stickers.isEmpty() ? 0 : it->stickers.at(0);
|
||||
int32 pixw = 0, pixh = 0;
|
||||
if (sticker) {
|
||||
pixw = sticker->thumb->width();
|
||||
pixh = sticker->thumb->height();
|
||||
if (pixw > st::contactsPhotoSize) {
|
||||
if (pixw > pixh) {
|
||||
pixh = (pixh * st::contactsPhotoSize) / pixw;
|
||||
pixw = st::contactsPhotoSize;
|
||||
} else {
|
||||
pixw = (pixw * st::contactsPhotoSize) / pixh;
|
||||
pixh = st::contactsPhotoSize;
|
||||
}
|
||||
} else if (pixh > st::contactsPhotoSize) {
|
||||
pixw = (pixw * st::contactsPhotoSize) / pixh;
|
||||
pixh = st::contactsPhotoSize;
|
||||
}
|
||||
QString title = it->title;
|
||||
int32 titleWidth = st::contactsNameFont->width(title);
|
||||
if (titleWidth > namew) {
|
||||
title = st::contactsNameFont->elided(title, namew);
|
||||
}
|
||||
bool official = (it->flags & MTPDstickerSet::Flag::f_official);
|
||||
(disabled ? rowsDisabled : rows).push_back(new StickerSetRow(it->id, sticker, it->stickers.size(), title, official, disabled, pixw, pixh));
|
||||
_animStartTimes.push_back(0);
|
||||
if (it->stickers.isEmpty() || (it->flags & MTPDstickerSet_ClientFlag::f_not_loaded)) {
|
||||
App::api()->scheduleStickerSetRequest(it->id, it->access);
|
||||
}
|
||||
}
|
||||
QString title = it->title;
|
||||
int32 titleWidth = st::contactsNameFont->width(title);
|
||||
if (titleWidth > namew) {
|
||||
title = st::contactsNameFont->elided(title, namew);
|
||||
}
|
||||
(disabled ? rowsDisabled : rows).push_back(new StickerSetRow(it->id, sticker, it->stickers.size(), title, installed, official, unread, disabled, pixw, pixh));
|
||||
_animStartTimes.push_back(0);
|
||||
if (it->stickers.isEmpty() || (it->flags & MTPDstickerSet_ClientFlag::f_not_loaded)) {
|
||||
App::api()->scheduleStickerSetRequest(it->id, it->access);
|
||||
}
|
||||
}
|
||||
App::api()->requestStickerSets();
|
||||
_rows = rows + rowsDisabled;
|
||||
resize(width(), _itemsTop + _rows.size() * _rowHeight + st::membersPadding.bottom());
|
||||
|
||||
if (_section == Section::Featured && Global::FeaturedStickerSetsUnreadCount()) {
|
||||
Global::SetFeaturedStickerSetsUnreadCount(0);
|
||||
for (auto &set : Global::RefStickerSets()) {
|
||||
set.flags &= ~MTPDstickerSet_ClientFlag::f_unread;
|
||||
}
|
||||
MTP::send(MTPmessages_ReadFeaturedStickers(), rpcDone(&StickersInner::readFeaturedDone), rpcFail(&StickersInner::readFeaturedFail));
|
||||
}
|
||||
}
|
||||
|
||||
void StickersInner::readFeaturedDone(const MTPBool &result) {
|
||||
Local::writeStickers();
|
||||
emit App::main()->stickersUpdated();
|
||||
}
|
||||
|
||||
bool StickersInner::readFeaturedFail(const RPCError &error) {
|
||||
if (MTP::isDefaultHandledError(error)) return false;
|
||||
|
||||
int unreadCount = 0;
|
||||
for_const (auto &set, Global::StickerSets()) {
|
||||
if (!(set.flags & MTPDstickerSet::Flag::f_installed)) {
|
||||
if (set.flags & MTPDstickerSet_ClientFlag::f_unread) {
|
||||
++unreadCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
Global::SetFeaturedStickerSetsUnreadCount(unreadCount);
|
||||
return true;
|
||||
}
|
||||
|
||||
QVector<uint64> StickersInner::getOrder() const {
|
||||
@ -755,27 +961,38 @@ StickersInner::~StickersInner() {
|
||||
clear();
|
||||
}
|
||||
|
||||
StickersBox::StickersBox() : ItemListBox(st::boxScroll)
|
||||
, _save(this, lang(lng_settings_save), st::defaultBoxButton)
|
||||
, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
|
||||
} // namespace internal
|
||||
|
||||
StickersBox::StickersBox(Section section) : ItemListBox(st::boxScroll)
|
||||
, _section(section)
|
||||
, _inner(section)
|
||||
, _reorderRequest(0)
|
||||
, _topShadow(this, st::contactsAboutShadow)
|
||||
, _bottomShadow(this)
|
||||
, _scrollDelta(0)
|
||||
, _aboutWidth(st::boxWideWidth - st::contactsPadding.left() - st::contactsPadding.left())
|
||||
, _about(st::boxTextFont, lang(lng_stickers_reorder), _defaultOptions, _aboutWidth)
|
||||
, _aboutHeight(st::stickersReorderPadding.top() + _about.countHeight(_aboutWidth) + st::stickersReorderPadding.bottom()) {
|
||||
ItemListBox::init(&_inner, st::boxButtonPadding.top() + _save.height() + st::boxButtonPadding.bottom(), st::boxTitleHeight + _aboutHeight);
|
||||
, _about(st::boxTextFont, lang(lng_stickers_reorder), _defaultOptions, _aboutWidth) {
|
||||
|
||||
int bottomSkip = st::boxPadding.bottom();
|
||||
if (_section == Section::Installed) {
|
||||
_aboutHeight = st::stickersReorderPadding.top() + _about.countHeight(_aboutWidth) + st::stickersReorderPadding.bottom();
|
||||
|
||||
_save = new BoxButton(this, lang(lng_settings_save), st::defaultBoxButton);
|
||||
connect(_save, SIGNAL(clicked()), this, SLOT(onSave()));
|
||||
|
||||
_cancel = new BoxButton(this, lang(lng_cancel), st::cancelBoxButton);
|
||||
connect(_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
|
||||
|
||||
_bottomShadow = new ScrollableBoxShadow(this);
|
||||
bottomSkip = st::boxButtonPadding.top() + _save->height() + st::boxButtonPadding.bottom();
|
||||
}
|
||||
ItemListBox::init(_inner, bottomSkip, st::boxTitleHeight + _aboutHeight);
|
||||
setMaxHeight(snap(countHeight(), int32(st::sessionsHeight), int32(st::boxMaxListHeight)));
|
||||
|
||||
connect(App::main(), SIGNAL(stickersUpdated()), this, SLOT(onStickersUpdated()));
|
||||
App::main()->updateStickers();
|
||||
|
||||
connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
|
||||
connect(&_save, SIGNAL(clicked()), this, SLOT(onSave()));
|
||||
|
||||
connect(&_inner, SIGNAL(checkDraggingScroll(int)), this, SLOT(onCheckDraggingScroll(int)));
|
||||
connect(&_inner, SIGNAL(noDraggingScroll()), this, SLOT(onNoDraggingScroll()));
|
||||
connect(_inner, SIGNAL(checkDraggingScroll(int)), this, SLOT(onCheckDraggingScroll(int)));
|
||||
connect(_inner, SIGNAL(noDraggingScroll()), this, SLOT(onNoDraggingScroll()));
|
||||
connect(&_scrollTimer, SIGNAL(timeout()), this, SLOT(onScrollTimer()));
|
||||
_scrollTimer.setSingleShot(false);
|
||||
|
||||
@ -785,7 +1002,11 @@ StickersBox::StickersBox() : ItemListBox(st::boxScroll)
|
||||
}
|
||||
|
||||
int32 StickersBox::countHeight() const {
|
||||
return st::boxTitleHeight + _aboutHeight + _inner.height() + st::boxButtonPadding.top() + _save.height() + st::boxButtonPadding.bottom();
|
||||
int bottomSkip = st::boxPadding.bottom();
|
||||
if (_section == Section::Installed) {
|
||||
bottomSkip = st::boxButtonPadding.top() + _save->height() + st::boxButtonPadding.bottom();
|
||||
}
|
||||
return st::boxTitleHeight + _aboutHeight + _inner->height() + bottomSkip;
|
||||
}
|
||||
|
||||
void StickersBox::disenableDone(const MTPBool & result, mtpRequestId req) {
|
||||
@ -805,7 +1026,7 @@ bool StickersBox::disenableFail(const RPCError &error, mtpRequestId req) {
|
||||
}
|
||||
|
||||
void StickersBox::saveOrder() {
|
||||
QVector<uint64> order = _inner.getOrder();
|
||||
auto order = _inner->getOrder();
|
||||
if (order.size() > 1) {
|
||||
QVector<MTPlong> mtpOrder;
|
||||
mtpOrder.reserve(order.size());
|
||||
@ -839,9 +1060,11 @@ void StickersBox::paintEvent(QPaintEvent *e) {
|
||||
paintTitle(p, lang(lng_stickers_packs));
|
||||
p.translate(0, st::boxTitleHeight);
|
||||
|
||||
p.fillRect(0, 0, width(), _aboutHeight, st::contactsAboutBg);
|
||||
p.setPen(st::stickersReorderFg);
|
||||
_about.draw(p, st::contactsPadding.left(), st::stickersReorderPadding.top(), _aboutWidth, style::al_center);
|
||||
if (_aboutHeight > 0) {
|
||||
p.fillRect(0, 0, width(), _aboutHeight, st::contactsAboutBg);
|
||||
p.setPen(st::stickersReorderFg);
|
||||
_about.draw(p, st::contactsPadding.left(), st::stickersReorderPadding.top(), _aboutWidth, style::al_center);
|
||||
}
|
||||
}
|
||||
|
||||
void StickersBox::closePressed() {
|
||||
@ -862,18 +1085,20 @@ void StickersBox::closePressed() {
|
||||
|
||||
void StickersBox::resizeEvent(QResizeEvent *e) {
|
||||
ItemListBox::resizeEvent(e);
|
||||
_save.moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _save.height());
|
||||
_cancel.moveToRight(st::boxButtonPadding.right() + _save.width() + st::boxButtonPadding.left(), _save.y());
|
||||
_inner.resize(width(), _inner.height());
|
||||
_inner->resize(width(), _inner->height());
|
||||
_topShadow.setGeometry(0, st::boxTitleHeight + _aboutHeight, width(), st::lineWidth);
|
||||
_bottomShadow.setGeometry(0, height() - st::boxButtonPadding.bottom() - _save.height() - st::boxButtonPadding.top() - st::lineWidth, width(), st::lineWidth);
|
||||
_inner.setVisibleScrollbar((_scroll.scrollTopMax() > 0) ? (st::boxScroll.width - st::boxScroll.deltax) : 0);
|
||||
_inner->setVisibleScrollbar((_scroll.scrollTopMax() > 0) ? (st::boxScroll.width - st::boxScroll.deltax) : 0);
|
||||
if (_save) {
|
||||
_save->moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _save->height());
|
||||
_cancel->moveToRight(st::boxButtonPadding.right() + _save->width() + st::boxButtonPadding.left(), _save->y());
|
||||
_bottomShadow->setGeometry(0, height() - st::boxButtonPadding.bottom() - _save->height() - st::boxButtonPadding.top() - st::lineWidth, width(), st::lineWidth);
|
||||
}
|
||||
}
|
||||
|
||||
void StickersBox::onStickersUpdated() {
|
||||
_inner.rebuild();
|
||||
_inner->rebuild();
|
||||
setMaxHeight(snap(countHeight(), int32(st::sessionsHeight), int32(st::boxMaxListHeight)));
|
||||
_inner.setVisibleScrollbar((_scroll.scrollTopMax() > 0) ? (st::boxScroll.width - st::boxScroll.deltax) : 0);
|
||||
_inner->setVisibleScrollbar((_scroll.scrollTopMax() > 0) ? (st::boxScroll.width - st::boxScroll.deltax) : 0);
|
||||
}
|
||||
|
||||
void StickersBox::onCheckDraggingScroll(int localY) {
|
||||
@ -901,7 +1126,7 @@ void StickersBox::onScrollTimer() {
|
||||
}
|
||||
|
||||
void StickersBox::onSave() {
|
||||
if (!_inner.savingStart()) {
|
||||
if (!_inner->savingStart()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -909,7 +1134,7 @@ void StickersBox::onSave() {
|
||||
RecentStickerPack &recent(cGetRecentStickers());
|
||||
auto &sets = Global::RefStickerSets();
|
||||
|
||||
QVector<uint64> reorder = _inner.getOrder(), disabled = _inner.getDisabledSets();
|
||||
QVector<uint64> reorder = _inner->getOrder(), disabled = _inner->getDisabledSets();
|
||||
for (int32 i = 0, l = disabled.size(); i < l; ++i) {
|
||||
auto it = sets.find(disabled.at(i));
|
||||
if (it != sets.cend()) {
|
||||
@ -932,12 +1157,20 @@ void StickersBox::onSave() {
|
||||
if (removeIndex >= 0) Global::RefStickerSetsOrder().removeAt(removeIndex);
|
||||
if (!(it->flags & MTPDstickerSet_ClientFlag::f_featured)) {
|
||||
sets.erase(it);
|
||||
} else {
|
||||
it->flags &= ~(MTPDstickerSet::Flag::f_installed | MTPDstickerSet::Flag::f_disabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Stickers::Order &order(Global::RefStickerSetsOrder());
|
||||
|
||||
// Clear all installed flags, set only for sets from order.
|
||||
for (auto &set : sets) {
|
||||
set.flags &= ~MTPDstickerSet::Flag::f_installed;
|
||||
}
|
||||
|
||||
auto &order(Global::RefStickerSetsOrder());
|
||||
order.clear();
|
||||
for (int i = 0, l = reorder.size(); i < l; ++i) {
|
||||
auto it = sets.find(reorder.at(i));
|
||||
@ -948,13 +1181,14 @@ void StickersBox::onSave() {
|
||||
it->flags &= ~MTPDstickerSet::Flag::f_disabled;
|
||||
}
|
||||
order.push_back(reorder.at(i));
|
||||
it->flags |= MTPDstickerSet::Flag::f_installed;
|
||||
}
|
||||
}
|
||||
for (auto it = sets.begin(); it != sets.cend();) {
|
||||
if (it->id == Stickers::CustomSetId
|
||||
|| it->id == Stickers::RecentSetId
|
||||
|| (it->flags & MTPDstickerSet_ClientFlag::f_featured)
|
||||
|| order.contains(it->id)) {
|
||||
|| (it->flags & MTPDstickerSet::Flag::f_installed)) {
|
||||
++it;
|
||||
} else {
|
||||
it = sets.erase(it);
|
||||
@ -973,18 +1207,22 @@ void StickersBox::onSave() {
|
||||
}
|
||||
|
||||
void StickersBox::hideAll() {
|
||||
_save.hide();
|
||||
_cancel.hide();
|
||||
_topShadow.hide();
|
||||
_bottomShadow.hide();
|
||||
if (_save) {
|
||||
_save->hide();
|
||||
_cancel->hide();
|
||||
_bottomShadow->hide();
|
||||
}
|
||||
ItemListBox::hideAll();
|
||||
}
|
||||
|
||||
void StickersBox::showAll() {
|
||||
_save.show();
|
||||
_cancel.show();
|
||||
_topShadow.show();
|
||||
_bottomShadow.show();
|
||||
if (_save) {
|
||||
_save->show();
|
||||
_cancel->show();
|
||||
_bottomShadow->show();
|
||||
}
|
||||
ItemListBox::showAll();
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,6 @@ public:
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
|
||||
public slots:
|
||||
|
||||
void onStickersUpdated();
|
||||
void onAddStickers();
|
||||
void onShareStickers();
|
||||
@ -103,115 +102,38 @@ public slots:
|
||||
|
||||
void onScroll();
|
||||
|
||||
signals:
|
||||
private slots:
|
||||
void onInstalled(uint64 id);
|
||||
|
||||
signals:
|
||||
void installed(uint64 id);
|
||||
|
||||
protected:
|
||||
|
||||
void hideAll();
|
||||
void showAll();
|
||||
|
||||
private:
|
||||
|
||||
StickerSetInner _inner;
|
||||
ScrollableBoxShadow _shadow;
|
||||
BoxButton _add, _share, _cancel, _done;
|
||||
QString _title;
|
||||
|
||||
};
|
||||
|
||||
class StickersInner : public TWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
StickersInner();
|
||||
|
||||
void paintEvent(QPaintEvent *e);
|
||||
void mousePressEvent(QMouseEvent *e);
|
||||
void mouseMoveEvent(QMouseEvent *e);
|
||||
void mouseReleaseEvent(QMouseEvent *e);
|
||||
|
||||
void rebuild();
|
||||
bool savingStart() {
|
||||
if (_saving) return false;
|
||||
_saving = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
QVector<uint64> getOrder() const;
|
||||
QVector<uint64> getDisabledSets() const;
|
||||
|
||||
void setVisibleScrollbar(int32 width);
|
||||
|
||||
~StickersInner();
|
||||
|
||||
signals:
|
||||
|
||||
void checkDraggingScroll(int localY);
|
||||
void noDraggingScroll();
|
||||
|
||||
public slots:
|
||||
|
||||
void onUpdateSelected();
|
||||
|
||||
private:
|
||||
|
||||
void step_shifting(uint64 ms, bool timer);
|
||||
void paintRow(Painter &p, int32 index);
|
||||
void clear();
|
||||
void setRemoveSel(int32 removeSel);
|
||||
float64 aboveShadowOpacity() const;
|
||||
|
||||
int32 _rowHeight;
|
||||
struct StickerSetRow {
|
||||
StickerSetRow(uint64 id, DocumentData *sticker, int32 count, const QString &title, bool official, bool disabled, int32 pixw, int32 pixh) : id(id)
|
||||
, sticker(sticker)
|
||||
, count(count)
|
||||
, title(title)
|
||||
, official(official)
|
||||
, disabled(disabled)
|
||||
, pixw(pixw)
|
||||
, pixh(pixh)
|
||||
, yadd(0, 0) {
|
||||
}
|
||||
uint64 id;
|
||||
DocumentData *sticker;
|
||||
int32 count;
|
||||
QString title;
|
||||
bool official, disabled;
|
||||
int32 pixw, pixh;
|
||||
anim::ivalue yadd;
|
||||
};
|
||||
typedef QList<StickerSetRow*> StickerSetRows;
|
||||
StickerSetRows _rows;
|
||||
QList<uint64> _animStartTimes;
|
||||
uint64 _aboveShadowFadeStart;
|
||||
anim::fvalue _aboveShadowFadeOpacity;
|
||||
Animation _a_shifting;
|
||||
|
||||
int32 _itemsTop;
|
||||
|
||||
bool _saving;
|
||||
|
||||
int32 _removeSel, _removeDown, _removeWidth, _returnWidth, _restoreWidth;
|
||||
|
||||
QPoint _mouse;
|
||||
int32 _selected;
|
||||
QPoint _dragStart;
|
||||
int32 _started, _dragging, _above;
|
||||
|
||||
BoxShadow _aboveShadow;
|
||||
|
||||
int32 _scrollbar;
|
||||
};
|
||||
namespace internal {
|
||||
class StickersInner;
|
||||
} // namespace internal
|
||||
|
||||
class StickersBox : public ItemListBox, public RPCSender {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
StickersBox();
|
||||
enum class Section {
|
||||
Installed,
|
||||
Featured,
|
||||
};
|
||||
StickersBox(Section section = Section::Installed);
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
void paintEvent(QPaintEvent *e);
|
||||
|
||||
@ -242,20 +164,135 @@ private:
|
||||
bool reorderFail(const RPCError &result);
|
||||
void saveOrder();
|
||||
|
||||
StickersInner _inner;
|
||||
BoxButton _save, _cancel;
|
||||
Section _section;
|
||||
|
||||
ChildWidget<internal::StickersInner> _inner;
|
||||
ChildWidget<BoxButton> _save = { nullptr };
|
||||
ChildWidget<BoxButton> _cancel = { nullptr };
|
||||
QMap<mtpRequestId, NullType> _disenableRequests;
|
||||
mtpRequestId _reorderRequest;
|
||||
PlainShadow _topShadow;
|
||||
ScrollableBoxShadow _bottomShadow;
|
||||
ChildWidget<ScrollableBoxShadow> _bottomShadow = { nullptr };
|
||||
|
||||
QTimer _scrollTimer;
|
||||
int32 _scrollDelta;
|
||||
|
||||
int32 _aboutWidth;
|
||||
int _aboutWidth = 0;
|
||||
Text _about;
|
||||
int32 _aboutHeight;
|
||||
int _aboutHeight = 0;
|
||||
|
||||
};
|
||||
|
||||
int32 stickerPacksCount(bool includeDisabledOfficial = false);
|
||||
|
||||
namespace internal {
|
||||
|
||||
class StickersInner : public TWidget, public RPCSender {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using Section = StickersBox::Section;
|
||||
StickersInner(Section section);
|
||||
|
||||
void rebuild();
|
||||
bool savingStart() {
|
||||
if (_saving) return false;
|
||||
_saving = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
QVector<uint64> getOrder() const;
|
||||
QVector<uint64> getDisabledSets() const;
|
||||
|
||||
void setVisibleScrollbar(int32 width);
|
||||
|
||||
~StickersInner();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
void mousePressEvent(QMouseEvent *e) override;
|
||||
void mouseMoveEvent(QMouseEvent *e) override;
|
||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||
void leaveEvent(QEvent *e) override;
|
||||
|
||||
signals:
|
||||
void checkDraggingScroll(int localY);
|
||||
void noDraggingScroll();
|
||||
|
||||
public slots:
|
||||
void onUpdateSelected();
|
||||
|
||||
private:
|
||||
void paintFeaturedButton(Painter &p) const;
|
||||
|
||||
void step_shifting(uint64 ms, bool timer);
|
||||
void paintRow(Painter &p, int32 index);
|
||||
void clear();
|
||||
void setActionSel(int32 actionSel);
|
||||
float64 aboveShadowOpacity() const;
|
||||
|
||||
void installSet(uint64 setId);
|
||||
void readFeaturedDone(const MTPBool &result);
|
||||
bool readFeaturedFail(const RPCError &error);
|
||||
|
||||
Section _section;
|
||||
|
||||
int32 _rowHeight;
|
||||
struct StickerSetRow {
|
||||
StickerSetRow(uint64 id, DocumentData *sticker, int32 count, const QString &title, bool installed, bool official, bool unread, bool disabled, int32 pixw, int32 pixh) : id(id)
|
||||
, sticker(sticker)
|
||||
, count(count)
|
||||
, title(title)
|
||||
, installed(installed)
|
||||
, official(official)
|
||||
, unread(unread)
|
||||
, disabled(disabled)
|
||||
, pixw(pixw)
|
||||
, pixh(pixh)
|
||||
, yadd(0, 0) {
|
||||
}
|
||||
uint64 id;
|
||||
DocumentData *sticker;
|
||||
int32 count;
|
||||
QString title;
|
||||
bool installed, official, unread, disabled;
|
||||
int32 pixw, pixh;
|
||||
anim::ivalue yadd;
|
||||
};
|
||||
typedef QList<StickerSetRow*> StickerSetRows;
|
||||
StickerSetRows _rows;
|
||||
QList<uint64> _animStartTimes;
|
||||
uint64 _aboveShadowFadeStart = 0;
|
||||
anim::fvalue _aboveShadowFadeOpacity = { 0., 0. };
|
||||
Animation _a_shifting;
|
||||
|
||||
int32 _itemsTop;
|
||||
|
||||
bool _saving = false;
|
||||
|
||||
int _actionSel = -1;
|
||||
int _actionDown = -1;
|
||||
|
||||
int _removeWidth, _returnWidth, _restoreWidth;
|
||||
|
||||
QString _addText;
|
||||
int _addWidth;
|
||||
|
||||
int _featuredHeight = 0;
|
||||
// Remember all the unread set ids to display unread dots.
|
||||
OrderedSet<uint64> _unreadSets;
|
||||
|
||||
QPoint _mouse;
|
||||
int _selected = -2; // -1 - featured stickers button
|
||||
int _pressed = -2;
|
||||
QPoint _dragStart;
|
||||
int _started = -1;
|
||||
int _dragging = -1;
|
||||
int _above = -1;
|
||||
|
||||
BoxShadow _aboveShadow;
|
||||
|
||||
int32 _scrollbar = 0;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
@ -29,7 +29,6 @@ dialogsUnreadBgActive: #ffffff;
|
||||
dialogsUnreadBgMutedActive: #d3e2ee;
|
||||
dialogsUnreadFont: font(12px bold);
|
||||
dialogsUnreadHeight: 19px;
|
||||
dialogsUnreadTop: 1px;
|
||||
dialogsUnreadPadding: 5px;
|
||||
|
||||
dialogsBg: windowBg;
|
||||
|
@ -222,7 +222,7 @@ void paintUnreadCount(Painter &p, const QString &text, int x, int y, const Unrea
|
||||
|
||||
p.setFont(st.font);
|
||||
p.setPen(st.active ? st::dialogsUnreadFgActive : st::dialogsUnreadFg);
|
||||
p.drawText(unreadRectLeft + (unreadRectWidth - unreadWidth) / 2, unreadRectTop + st::dialogsUnreadTop + st.font->ascent, text);
|
||||
p.drawText(unreadRectLeft + (unreadRectWidth - unreadWidth) / 2, unreadRectTop + (unreadRectHeight - st.font->height) / 2 + st.font->ascent, text);
|
||||
}
|
||||
|
||||
void RowPainter::paint(Painter &p, const Row *row, int w, bool active, bool selected, bool onlyBackground) {
|
||||
@ -258,7 +258,7 @@ void RowPainter::paint(Painter &p, const Row *row, int w, bool active, bool sele
|
||||
auto counter = QString::number(unreadCount);
|
||||
auto mutedCounter = history->mute();
|
||||
int unreadRight = w - st::dialogsPadding.x();
|
||||
int unreadTop = texttop + st::dialogsTextFont->ascent - st::dialogsUnreadFont->ascent - st::dialogsUnreadTop;
|
||||
int unreadTop = texttop + st::dialogsTextFont->ascent - st::dialogsUnreadFont->ascent - (st::dialogsUnreadHeight - st::dialogsUnreadFont->height) / 2;
|
||||
int unreadWidth = 0;
|
||||
|
||||
UnreadBadgeStyle st;
|
||||
@ -297,7 +297,7 @@ void paintImportantSwitch(Painter &p, Mode current, int w, bool selected, bool o
|
||||
int unreadTop = (st::dialogsImportantBarHeight - st::dialogsUnreadHeight) / 2;
|
||||
bool mutedHidden = (current == Dialogs::Mode::Important);
|
||||
QString text = mutedHidden ? qsl("Show all chats") : qsl("Hide muted chats");
|
||||
int textBaseline = unreadTop + st::dialogsUnreadTop + st::dialogsUnreadFont->ascent;
|
||||
int textBaseline = unreadTop + (st::dialogsUnreadHeight - st::dialogsUnreadFont->height) / 2 + st::dialogsUnreadFont->ascent;
|
||||
p.drawText(st::dialogsPadding.x(), textBaseline, text);
|
||||
|
||||
if (mutedHidden) {
|
||||
|
@ -38,6 +38,8 @@ void paintImportantSwitch(Painter &p, Mode current, int w, bool selected, bool o
|
||||
enum UnreadBadgeSize {
|
||||
UnreadBadgeInDialogs = 0,
|
||||
UnreadBadgeInHistoryToDown,
|
||||
UnreadBadgeInStickersPanel,
|
||||
UnreadBadgeInStickersBox,
|
||||
|
||||
UnreadBadgeSizesCount
|
||||
};
|
||||
|
@ -25,6 +25,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "boxes/stickersetbox.h"
|
||||
#include "inline_bots/inline_bot_result.h"
|
||||
#include "inline_bots/inline_bot_layout_item.h"
|
||||
#include "dialogs/dialogs_layout.h"
|
||||
#include "historywidget.h"
|
||||
#include "localstorage.h"
|
||||
#include "lang.h"
|
||||
@ -2829,6 +2830,20 @@ void EmojiPan::onSaveConfigDelayed(int32 delay) {
|
||||
_saveConfigTimer.start(delay);
|
||||
}
|
||||
|
||||
void EmojiPan::paintStickerSettingsIcon(Painter &p) const {
|
||||
int settingsLeft = _iconsLeft + 7 * st::rbEmoji.width;
|
||||
p.drawSpriteLeft(settingsLeft + st::rbEmojiRecent.imagePos.x(), _iconsTop + st::rbEmojiRecent.imagePos.y(), width(), st::stickersSettings);
|
||||
if (auto unread = Global::FeaturedStickerSetsUnreadCount()) {
|
||||
Dialogs::Layout::UnreadBadgeStyle unreadSt;
|
||||
unreadSt.sizeId = Dialogs::Layout::UnreadBadgeInStickersPanel;
|
||||
unreadSt.size = st::stickersSettingsUnreadSize;
|
||||
int unreadRight = settingsLeft + st::rbEmoji.width - st::stickersSettingsUnreadPosition.x();
|
||||
if (rtl()) unreadRight = width() - unreadRight;
|
||||
int unreadTop = _iconsTop + st::stickersSettingsUnreadPosition.y();
|
||||
Dialogs::Layout::paintUnreadCount(p, QString::number(unread), unreadRight, unreadTop, unreadSt);
|
||||
}
|
||||
}
|
||||
|
||||
void EmojiPan::paintEvent(QPaintEvent *e) {
|
||||
Painter p(this);
|
||||
|
||||
@ -2846,7 +2861,7 @@ void EmojiPan::paintEvent(QPaintEvent *e) {
|
||||
p.fillRect(myrtlrect(r.x() + r.width() - st::emojiScroll.width, r.y(), st::emojiScroll.width, e_scroll.height()), st::white->b);
|
||||
if (_stickersShown && s_inner.showSectionIcons()) {
|
||||
p.fillRect(r.left(), _iconsTop, r.width(), st::rbEmoji.height, st::emojiPanCategories);
|
||||
p.drawSpriteLeft(_iconsLeft + 7 * st::rbEmoji.width + st::rbEmojiRecent.imagePos.x(), _iconsTop + st::rbEmojiRecent.imagePos.y(), width(), st::stickersSettings);
|
||||
paintStickerSettingsIcon(p);
|
||||
|
||||
if (!_icons.isEmpty()) {
|
||||
int32 x = _iconsLeft, i = 0, selxrel = _iconsLeft + _iconSelX.current(), selx = selxrel - _iconsX.current();
|
||||
@ -3093,6 +3108,7 @@ void EmojiPan::refreshStickers() {
|
||||
if (!_stickersShown) {
|
||||
s_inner.preloadImages();
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
void EmojiPan::refreshSavedGifs() {
|
||||
|
@ -656,6 +656,7 @@ signals:
|
||||
void updateStickers();
|
||||
|
||||
private:
|
||||
void paintStickerSettingsIcon(Painter &p) const;
|
||||
|
||||
void validateSelectedIcon(bool animated = false);
|
||||
|
||||
|
@ -561,7 +561,7 @@ struct Data {
|
||||
Stickers::Order StickerSetsOrder;
|
||||
uint64 LastStickersUpdate = 0;
|
||||
Stickers::Order FeaturedStickerSetsOrder;
|
||||
Stickers::UnreadMap FeaturedUnreadSets;
|
||||
int FeaturedStickerSetsUnreadCount = 0;
|
||||
uint64 LastFeaturedStickersUpdate = 0;
|
||||
|
||||
MTP::DcOptions DcOptions;
|
||||
@ -630,7 +630,7 @@ DefineVar(Global, Stickers::Sets, StickerSets);
|
||||
DefineVar(Global, Stickers::Order, StickerSetsOrder);
|
||||
DefineVar(Global, uint64, LastStickersUpdate);
|
||||
DefineVar(Global, Stickers::Order, FeaturedStickerSetsOrder);
|
||||
DefineVar(Global, Stickers::UnreadMap, FeaturedUnreadSets);
|
||||
DefineVar(Global, int, FeaturedStickerSetsUnreadCount);
|
||||
DefineVar(Global, uint64, LastFeaturedStickersUpdate);
|
||||
|
||||
DefineVar(Global, MTP::DcOptions, DcOptions);
|
||||
|
@ -199,7 +199,13 @@ struct Set {
|
||||
};
|
||||
using Sets = QMap<uint64, Set>;
|
||||
using Order = QList<uint64>;
|
||||
using UnreadMap = OrderedSet<uint64>;
|
||||
|
||||
inline MTPInputStickerSet inputSetId(const Set &set) {
|
||||
if (set.id && set.access) {
|
||||
return MTP_inputStickerSetID(MTP_long(set.id), MTP_long(set.access));
|
||||
}
|
||||
return MTP_inputStickerSetShortName(MTP_string(set.shortName));
|
||||
}
|
||||
|
||||
} // namespace Stickers
|
||||
|
||||
@ -250,7 +256,7 @@ DeclareVar(Stickers::Sets, StickerSets);
|
||||
DeclareVar(Stickers::Order, StickerSetsOrder);
|
||||
DeclareVar(uint64, LastStickersUpdate);
|
||||
DeclareVar(Stickers::Order, FeaturedStickerSetsOrder);
|
||||
DeclareVar(Stickers::UnreadMap, FeaturedUnreadSets);
|
||||
DeclareVar(int, FeaturedStickerSetsUnreadCount);
|
||||
DeclareVar(uint64, LastFeaturedStickersUpdate);
|
||||
|
||||
DeclareVar(MTP::DcOptions, DcOptions);
|
||||
|
@ -196,14 +196,14 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) {
|
||||
}
|
||||
return true;
|
||||
};
|
||||
auto filterNotPassedByName = [this](UserData *user) -> bool {
|
||||
auto filterNotPassedByName = [this, &filterNotPassedByUsername](UserData *user) -> bool {
|
||||
for_const (auto &namePart, user->names) {
|
||||
if (namePart.startsWith(_filter, Qt::CaseInsensitive)) {
|
||||
bool exactUsername = (user->username.compare(_filter, Qt::CaseInsensitive) == 0);
|
||||
return exactUsername;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return filterNotPassedByUsername(user);
|
||||
};
|
||||
|
||||
bool listAllSuggestions = _filter.isEmpty();
|
||||
|
@ -29,6 +29,8 @@ historyToDownArrow: icon {
|
||||
{ "history_down_arrow", #b9b9b9, point(14px, 19px) },
|
||||
};
|
||||
historyToDownPaddingTop: 10px;
|
||||
historyToDownBadgeFont: semiboldFont;
|
||||
historyToDownBadgeSize: 22px;
|
||||
|
||||
membersInnerScroll: flatScroll(solidScroll) {
|
||||
deltat: 3px;
|
||||
@ -42,5 +44,3 @@ membersInnerDropdown: InnerDropdown(defaultInnerDropdown) {
|
||||
scrollMargin: margins(0px, 5px, 0px, 5px);
|
||||
scrollPadding: margins(0px, 3px, 8px, 3px);
|
||||
}
|
||||
historyToDownBadgeFont: semiboldFont;
|
||||
historyToDownBadgeSize: 22px;
|
||||
|
@ -3667,7 +3667,7 @@ void HistoryWidget::stickersGot(const MTPmessages_AllStickers &stickers) {
|
||||
it->access = set.vaccess_hash.v;
|
||||
it->title = title;
|
||||
it->shortName = qs(set.vshort_name);
|
||||
auto clientFlags = it->flags & (MTPDstickerSet_ClientFlag::f_featured | MTPDstickerSet_ClientFlag::f_not_loaded);
|
||||
auto clientFlags = it->flags & (MTPDstickerSet_ClientFlag::f_featured | MTPDstickerSet_ClientFlag::f_unread | MTPDstickerSet_ClientFlag::f_not_loaded);
|
||||
it->flags = set.vflags.v | clientFlags;
|
||||
if (it->count != set.vcount.v || it->hash != set.vhash.v || it->emoji.isEmpty()) {
|
||||
it->count = set.vcount.v;
|
||||
@ -3739,6 +3739,11 @@ void HistoryWidget::featuredStickersGot(const MTPmessages_FeaturedStickers &stic
|
||||
if (stickers.type() != mtpc_messages_featuredStickers) return;
|
||||
auto &d(stickers.c_messages_featuredStickers());
|
||||
|
||||
OrderedSet<uint64> unread;
|
||||
for_const (auto &unreadSetId, d.vunread.c_vector().v) {
|
||||
unread.insert(unreadSetId.v);
|
||||
}
|
||||
|
||||
auto &d_sets(d.vsets.c_vector().v);
|
||||
|
||||
auto &setsOrder = Global::RefFeaturedStickerSetsOrder();
|
||||
@ -3755,13 +3760,23 @@ void HistoryWidget::featuredStickersGot(const MTPmessages_FeaturedStickers &stic
|
||||
auto it = sets.find(set.vid.v);
|
||||
QString title = stickerSetTitle(set);
|
||||
if (it == sets.cend()) {
|
||||
it = sets.insert(set.vid.v, Stickers::Set(set.vid.v, set.vaccess_hash.v, title, qs(set.vshort_name), set.vcount.v, set.vhash.v, set.vflags.v | MTPDstickerSet_ClientFlag::f_featured | MTPDstickerSet_ClientFlag::f_not_loaded));
|
||||
auto clientFlags = MTPDstickerSet_ClientFlag::f_featured | MTPDstickerSet_ClientFlag::f_not_loaded;
|
||||
if (unread.contains(set.vid.v)) {
|
||||
clientFlags |= MTPDstickerSet_ClientFlag::f_unread;
|
||||
}
|
||||
it = sets.insert(set.vid.v, Stickers::Set(set.vid.v, set.vaccess_hash.v, title, qs(set.vshort_name), set.vcount.v, set.vhash.v, set.vflags.v | clientFlags));
|
||||
} else {
|
||||
it->access = set.vaccess_hash.v;
|
||||
it->title = title;
|
||||
it->shortName = qs(set.vshort_name);
|
||||
auto clientFlags = it->flags & (MTPDstickerSet_ClientFlag::f_featured | MTPDstickerSet_ClientFlag::f_not_loaded);
|
||||
it->flags = set.vflags.v | clientFlags | MTPDstickerSet_ClientFlag::f_featured;
|
||||
auto clientFlags = it->flags & (MTPDstickerSet_ClientFlag::f_featured | MTPDstickerSet_ClientFlag::f_unread | MTPDstickerSet_ClientFlag::f_not_loaded);
|
||||
it->flags = set.vflags.v | clientFlags;
|
||||
it->flags |= MTPDstickerSet_ClientFlag::f_featured;
|
||||
if (unread.contains(it->id)) {
|
||||
it->flags |= MTPDstickerSet_ClientFlag::f_unread;
|
||||
} else {
|
||||
it->flags &= ~MTPDstickerSet_ClientFlag::f_unread;
|
||||
}
|
||||
if (it->count != set.vcount.v || it->hash != set.vhash.v || it->emoji.isEmpty()) {
|
||||
it->count = set.vcount.v;
|
||||
it->hash = set.vhash.v;
|
||||
@ -3774,21 +3789,21 @@ void HistoryWidget::featuredStickersGot(const MTPmessages_FeaturedStickers &stic
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Stickers::Sets::iterator it = sets.begin(), e = sets.end(); it != e;) {
|
||||
|
||||
int unreadCount = 0;
|
||||
for (auto it = sets.begin(), e = sets.end(); it != e;) {
|
||||
bool installed = (it->flags & MTPDstickerSet::Flag::f_installed);
|
||||
bool featured = (it->flags & MTPDstickerSet_ClientFlag::f_featured);
|
||||
if (installed || featured) {
|
||||
if (featured && (it->flags & MTPDstickerSet_ClientFlag::f_unread)) {
|
||||
++unreadCount;
|
||||
}
|
||||
++it;
|
||||
} else {
|
||||
it = sets.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
auto &unreadFeatured = Global::RefFeaturedUnreadSets();
|
||||
unreadFeatured.clear();
|
||||
for_const (auto &unreadSetId, d.vunread.c_vector().v) {
|
||||
unreadFeatured.insert(unreadSetId.v);
|
||||
}
|
||||
Global::SetFeaturedStickerSetsUnreadCount(unreadCount);
|
||||
|
||||
if (Local::countFeaturedStickersHash() != d.vhash.v) {
|
||||
LOG(("API Error: received featured stickers hash %1 while counted hash is %2").arg(d.vhash.v).arg(Local::countFeaturedStickersHash()));
|
||||
|
@ -3079,7 +3079,6 @@ namespace Local {
|
||||
}
|
||||
size += sizeof(qint32) + (Global::StickerSetsOrder().size() * sizeof(quint64));
|
||||
size += sizeof(qint32) + (Global::FeaturedStickerSetsOrder().size() * sizeof(quint64));
|
||||
size += sizeof(qint32) + (Global::FeaturedUnreadSets().size() * sizeof(quint64));
|
||||
|
||||
if (!_stickersKey) {
|
||||
_stickersKey = genKey();
|
||||
@ -3094,11 +3093,6 @@ namespace Local {
|
||||
data.stream << Global::StickerSetsOrder();
|
||||
data.stream << Global::FeaturedStickerSetsOrder();
|
||||
|
||||
data.stream << qint32(Global::FeaturedUnreadSets().size());
|
||||
for_const (auto setId, Global::FeaturedUnreadSets()) {
|
||||
data.stream << quint64(setId);
|
||||
}
|
||||
|
||||
FileWriteDescriptor file(_stickersKey);
|
||||
file.writeEncrypted(data);
|
||||
}
|
||||
@ -3200,9 +3194,6 @@ namespace Local {
|
||||
auto &featuredOrder = Global::RefFeaturedStickerSetsOrder();
|
||||
featuredOrder.clear();
|
||||
|
||||
auto &unreadFeatured = Global::RefFeaturedUnreadSets();
|
||||
unreadFeatured.clear();
|
||||
|
||||
quint32 cnt;
|
||||
QByteArray hash;
|
||||
stickers.stream >> cnt >> hash; // ignore hash, it is counted
|
||||
@ -3244,6 +3235,8 @@ namespace Local {
|
||||
}
|
||||
|
||||
auto &set = sets.insert(setId, Stickers::Set(setId, setAccess, setTitle, setShortName, 0, setHash, MTPDstickerSet::Flags(setFlags))).value();
|
||||
// We will set this flags from order lists below.
|
||||
set.flags &= ~(MTPDstickerSet::Flag::f_installed | MTPDstickerSet_ClientFlag::f_featured);
|
||||
if (scnt < 0) { // disabled not loaded set
|
||||
set.count = -scnt;
|
||||
continue;
|
||||
@ -3293,23 +3286,32 @@ namespace Local {
|
||||
stickers.stream >> order;
|
||||
stickers.stream >> featuredOrder;
|
||||
|
||||
qint32 unreadCount = 0;
|
||||
stickers.stream >> unreadCount;
|
||||
for (int i = 0; i < unreadCount; ++i) {
|
||||
quint64 setId = 0;
|
||||
stickers.stream >> setId;
|
||||
if (setId) {
|
||||
unreadFeatured.insert(setId);
|
||||
// Set flags and count unread featured sets.
|
||||
for_const (auto setId, order) {
|
||||
auto it = sets.find(setId);
|
||||
if (it != sets.cend()) {
|
||||
it->flags |= MTPDstickerSet::Flag::f_installed;
|
||||
}
|
||||
}
|
||||
int unreadCount = 0;
|
||||
for_const (auto setId, featuredOrder) {
|
||||
auto it = sets.find(setId);
|
||||
if (it != sets.cend()) {
|
||||
it->flags |= MTPDstickerSet_ClientFlag::f_featured;
|
||||
if (it->flags & MTPDstickerSet_ClientFlag::f_unread) {
|
||||
++unreadCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
Global::SetFeaturedStickerSetsUnreadCount(unreadCount);
|
||||
}
|
||||
}
|
||||
|
||||
int32 countStickersHash(bool checkOfficial) {
|
||||
uint32 acc = 0;
|
||||
bool foundOfficial = false, foundBad = false;;
|
||||
const Stickers::Sets &sets(Global::StickerSets());
|
||||
const Stickers::Order &order(Global::StickerSetsOrder());
|
||||
auto &sets = Global::StickerSets();
|
||||
auto &order = Global::StickerSetsOrder();
|
||||
for (auto i = order.cbegin(), e = order.cend(); i != e; ++i) {
|
||||
auto j = sets.constFind(*i);
|
||||
if (j != sets.cend()) {
|
||||
@ -3328,11 +3330,14 @@ namespace Local {
|
||||
|
||||
int32 countFeaturedStickersHash() {
|
||||
uint32 acc = 0;
|
||||
auto &featured(Global::FeaturedStickerSetsOrder());
|
||||
auto &sets = Global::StickerSets();
|
||||
auto &featured = Global::FeaturedStickerSetsOrder();
|
||||
for_const (auto setId, featured) {
|
||||
acc = (acc * 20261) + uint32(setId >> 32);
|
||||
acc = (acc * 20261) + uint32(setId & 0xFFFFFFFF);
|
||||
if (Global::FeaturedUnreadSets().contains(setId)) {
|
||||
|
||||
auto it = sets.constFind(setId);
|
||||
if (it != sets.cend() && (it->flags & MTPDstickerSet_ClientFlag::f_unread)) {
|
||||
acc = (acc * 20261) + 1U;
|
||||
}
|
||||
}
|
||||
|
@ -3378,7 +3378,6 @@ void MainWidget::stickersBox(const MTPInputStickerSet &set) {
|
||||
}
|
||||
|
||||
void MainWidget::onStickersInstalled(uint64 setId) {
|
||||
emit stickersUpdated();
|
||||
_history->stickersInstalled(setId);
|
||||
}
|
||||
|
||||
@ -4731,9 +4730,16 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||
} break;
|
||||
|
||||
case mtpc_updateReadFeaturedStickers: {
|
||||
Global::RefFeaturedUnreadSets().clear();
|
||||
Local::writeStickers();
|
||||
emit stickersUpdated();
|
||||
for (auto &set : Global::RefStickerSets()) {
|
||||
if (set.flags & MTPDstickerSet_ClientFlag::f_unread) {
|
||||
set.flags &= ~MTPDstickerSet_ClientFlag::f_unread;
|
||||
}
|
||||
}
|
||||
if (Global::FeaturedStickerSetsUnreadCount()) {
|
||||
Global::SetFeaturedStickerSetsUnreadCount(0);
|
||||
Local::writeStickers();
|
||||
emit stickersUpdated();
|
||||
}
|
||||
} break;
|
||||
|
||||
////// Cloud saved GIFs
|
||||
|
@ -1291,7 +1291,7 @@ void MediaView::paintEvent(QPaintEvent *e) {
|
||||
if (_saveMsgOpacity.current() > 0) {
|
||||
p.setOpacity(_saveMsgOpacity.current());
|
||||
App::roundRect(p, _saveMsg, st::medviewSaveMsg, MediaviewSaveCorners);
|
||||
p.drawSprite(_saveMsg.topLeft() + st::medviewSaveMsgCheckPos, st::medviewSaveMsgCheck);
|
||||
st::medviewSaveMsgCheck.paint(p, _saveMsg.topLeft() + st::medviewSaveMsgCheckPos, width());
|
||||
|
||||
p.setPen(st::white->p);
|
||||
textstyleSet(&st::medviewSaveAsTextStyle);
|
||||
|
@ -1063,8 +1063,11 @@ enum class MTPDstickerSet_ClientFlag : int32 {
|
||||
// sticker set is one of featured (should be saved locally)
|
||||
f_featured = (1 << 29),
|
||||
|
||||
// sticker set is an unread featured set
|
||||
f_unread = (1 << 28),
|
||||
|
||||
// update this when adding new client side flags
|
||||
MIN_FIELD = (1 << 29),
|
||||
MIN_FIELD = (1 << 28),
|
||||
};
|
||||
DEFINE_MTP_CLIENT_FLAGS(MTPDstickerSet)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user