mirror of https://github.com/procxx/kepka.git
Emoji display added to sticker preview. Reading featured sticker sets.
Reading featured sticker sets one by one while scrolling through them, only when the row was fully visible and the image was already loaded.
This commit is contained in:
parent
ff657347b8
commit
8419a56e10
|
@ -49,25 +49,6 @@ confirmInviteUserName: flatLabel(labelDefFlat) {
|
||||||
}
|
}
|
||||||
confirmInviteUserNameTop: 227px;
|
confirmInviteUserNameTop: 227px;
|
||||||
|
|
||||||
stickersAddIcon: icon {
|
|
||||||
{ "stickers_add", #ffffff },
|
|
||||||
};
|
|
||||||
stickersAddSize: size(30px, 24px);
|
|
||||||
|
|
||||||
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 }
|
|
||||||
};
|
|
||||||
|
|
||||||
confirmPhoneAboutLabel: flatLabel(labelDefFlat) {
|
confirmPhoneAboutLabel: flatLabel(labelDefFlat) {
|
||||||
width: 282px;
|
width: 282px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
#include "localstorage.h"
|
#include "localstorage.h"
|
||||||
#include "dialogs/dialogs_layout.h"
|
#include "dialogs/dialogs_layout.h"
|
||||||
#include "styles/style_boxes.h"
|
#include "styles/style_boxes.h"
|
||||||
|
#include "styles/style_stickers.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -423,7 +424,7 @@ void StickerSetBox::resizeEvent(QResizeEvent *e) {
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
StickersInner::StickersInner(StickersBox::Section section) : TWidget()
|
StickersInner::StickersInner(StickersBox::Section section) : ScrolledWidget()
|
||||||
, _section(section)
|
, _section(section)
|
||||||
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
|
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
|
||||||
, _a_shifting(animation(this, &StickersInner::step_shifting))
|
, _a_shifting(animation(this, &StickersInner::step_shifting))
|
||||||
|
@ -436,7 +437,7 @@ StickersInner::StickersInner(StickersBox::Section section) : TWidget()
|
||||||
setup();
|
setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
StickersInner::StickersInner(const Stickers::Order &archivedIds) : TWidget()
|
StickersInner::StickersInner(const Stickers::Order &archivedIds) : ScrolledWidget()
|
||||||
, _section(StickersBox::Section::ArchivedPart)
|
, _section(StickersBox::Section::ArchivedPart)
|
||||||
, _archivedIds(archivedIds)
|
, _archivedIds(archivedIds)
|
||||||
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
|
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
|
||||||
|
@ -451,10 +452,15 @@ StickersInner::StickersInner(const Stickers::Order &archivedIds) : TWidget()
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersInner::setup() {
|
void StickersInner::setup() {
|
||||||
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
|
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(onImageLoaded()));
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StickersInner::onImageLoaded() {
|
||||||
|
update();
|
||||||
|
readVisibleSets();
|
||||||
|
}
|
||||||
|
|
||||||
void StickersInner::paintButton(Painter &p, int y, bool selected, const QString &text, int badgeCounter) const {
|
void StickersInner::paintButton(Painter &p, int y, bool selected, const QString &text, int badgeCounter) const {
|
||||||
if (selected) {
|
if (selected) {
|
||||||
p.fillRect(0, y, width(), _buttonHeight, st::contactsBgOver);
|
p.fillRect(0, y, width(), _buttonHeight, st::contactsBgOver);
|
||||||
|
@ -587,18 +593,18 @@ void StickersInner::paintRow(Painter &p, int32 index) {
|
||||||
int statusx = namex;
|
int statusx = namex;
|
||||||
int statusy = st::contactsPadding.top() + st::contactsStatusTop;
|
int statusy = st::contactsPadding.top() + st::contactsStatusTop;
|
||||||
|
|
||||||
|
p.setFont(st::contactsNameFont);
|
||||||
|
p.setPen(st::black);
|
||||||
|
p.drawTextLeft(namex, namey, width(), s->title, s->titleWidth);
|
||||||
|
|
||||||
if (s->unread) {
|
if (s->unread) {
|
||||||
p.setPen(Qt::NoPen);
|
p.setPen(Qt::NoPen);
|
||||||
p.setBrush(st::stickersFeaturedUnreadBg);
|
p.setBrush(st::stickersFeaturedUnreadBg);
|
||||||
|
|
||||||
p.setRenderHint(QPainter::HighQualityAntialiasing, true);
|
p.setRenderHint(QPainter::HighQualityAntialiasing, true);
|
||||||
p.drawEllipse(rtlrect(namex, namey + st::stickersFeaturedUnreadTop, st::stickersFeaturedUnreadSize, st::stickersFeaturedUnreadSize, width()));
|
p.drawEllipse(rtlrect(namex + s->titleWidth + st::stickersFeaturedUnreadSkip, namey + st::stickersFeaturedUnreadTop, st::stickersFeaturedUnreadSize, st::stickersFeaturedUnreadSize, width()));
|
||||||
p.setRenderHint(QPainter::HighQualityAntialiasing, false);
|
p.setRenderHint(QPainter::HighQualityAntialiasing, false);
|
||||||
namex += st::stickersFeaturedUnreadSize + st::stickersFeaturedUnreadSkip;
|
|
||||||
}
|
}
|
||||||
p.setFont(st::contactsNameFont);
|
|
||||||
p.setPen(st::black);
|
|
||||||
p.drawTextLeft(namex, namey, width(), s->title);
|
|
||||||
|
|
||||||
p.setFont(st::contactsStatusFont);
|
p.setFont(st::contactsStatusFont);
|
||||||
p.setPen(st::contactsStatusFg);
|
p.setPen(st::contactsStatusFg);
|
||||||
|
@ -967,19 +973,6 @@ void StickersInner::rebuild() {
|
||||||
}
|
}
|
||||||
App::api()->requestStickerSets();
|
App::api()->requestStickerSets();
|
||||||
updateSize();
|
updateSize();
|
||||||
|
|
||||||
if (_section == Section::Featured && Global::FeaturedStickerSetsUnreadCount()) {
|
|
||||||
Global::SetFeaturedStickerSetsUnreadCount(0);
|
|
||||||
QVector<MTPlong> readIds;
|
|
||||||
readIds.reserve(Global::StickerSets().size());
|
|
||||||
for (auto &set : Global::RefStickerSets()) {
|
|
||||||
if (set.flags & MTPDstickerSet_ClientFlag::f_unread) {
|
|
||||||
set.flags &= ~MTPDstickerSet_ClientFlag::f_unread;
|
|
||||||
readIds.push_back(MTP_long(set.id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MTP::send(MTPmessages_ReadFeaturedStickers(MTP_vector<MTPlong>(readIds)), rpcDone(&StickersInner::readFeaturedDone), rpcFail(&StickersInner::readFeaturedFail));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersInner::updateSize() {
|
void StickersInner::updateSize() {
|
||||||
|
@ -1007,7 +1000,7 @@ void StickersInner::updateRows() {
|
||||||
if (_section == Section::Installed) {
|
if (_section == Section::Installed) {
|
||||||
row->disabled = false;
|
row->disabled = false;
|
||||||
}
|
}
|
||||||
row->title = fillSetTitle(set, maxNameWidth);
|
row->title = fillSetTitle(set, maxNameWidth, &row->titleWidth);
|
||||||
row->count = fillSetCount(set);
|
row->count = fillSetCount(set);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1031,6 +1024,7 @@ int StickersInner::countMaxNameWidth() const {
|
||||||
namew -= qMax(qMax(qMax(_returnWidth, _removeWidth), _restoreWidth), _clearWidth);
|
namew -= qMax(qMax(qMax(_returnWidth, _removeWidth), _restoreWidth), _clearWidth);
|
||||||
} else {
|
} else {
|
||||||
namew -= st::stickersAddIcon.width() - st::defaultActiveButton.width;
|
namew -= st::stickersAddIcon.width() - st::defaultActiveButton.width;
|
||||||
|
namew -= st::stickersFeaturedUnreadSize + st::stickersFeaturedUnreadSkip;
|
||||||
}
|
}
|
||||||
return namew;
|
return namew;
|
||||||
}
|
}
|
||||||
|
@ -1046,10 +1040,11 @@ void StickersInner::rebuildAppendSet(const Stickers::Set &set, int maxNameWidth)
|
||||||
int pixw = 0, pixh = 0;
|
int pixw = 0, pixh = 0;
|
||||||
fillSetCover(set, &sticker, &pixw, &pixh);
|
fillSetCover(set, &sticker, &pixw, &pixh);
|
||||||
|
|
||||||
QString title = fillSetTitle(set, maxNameWidth);
|
int titleWidth = 0;
|
||||||
|
QString title = fillSetTitle(set, maxNameWidth, &titleWidth);
|
||||||
int count = fillSetCount(set);
|
int count = fillSetCount(set);
|
||||||
|
|
||||||
_rows.push_back(new StickerSetRow(set.id, sticker, count, title, installed, official, unread, disabled, recent, pixw, pixh));
|
_rows.push_back(new StickerSetRow(set.id, sticker, count, title, titleWidth, installed, official, unread, disabled, recent, pixw, pixh));
|
||||||
_animStartTimes.push_back(0);
|
_animStartTimes.push_back(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1097,11 +1092,15 @@ int StickersInner::fillSetCount(const Stickers::Set &set) const {
|
||||||
return result + added;
|
return result + added;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString StickersInner::fillSetTitle(const Stickers::Set &set, int maxNameWidth) const {
|
QString StickersInner::fillSetTitle(const Stickers::Set &set, int maxNameWidth, int *outTitleWidth) const {
|
||||||
auto result = set.title;
|
auto result = set.title;
|
||||||
int32 titleWidth = st::contactsNameFont->width(result);
|
int titleWidth = st::contactsNameFont->width(result);
|
||||||
if (titleWidth > maxNameWidth) {
|
if (titleWidth > maxNameWidth) {
|
||||||
result = st::contactsNameFont->elided(result, maxNameWidth);
|
result = st::contactsNameFont->elided(result, maxNameWidth);
|
||||||
|
titleWidth = st::contactsNameFont->width(result);
|
||||||
|
}
|
||||||
|
if (outTitleWidth) {
|
||||||
|
*outTitleWidth = titleWidth;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1117,35 +1116,11 @@ void StickersInner::fillSetFlags(const Stickers::Set &set, bool *outRecent, bool
|
||||||
*outOfficial = (set.flags & MTPDstickerSet::Flag::f_official);
|
*outOfficial = (set.flags & MTPDstickerSet::Flag::f_official);
|
||||||
*outDisabled = (set.flags & MTPDstickerSet::Flag::f_archived);
|
*outDisabled = (set.flags & MTPDstickerSet::Flag::f_archived);
|
||||||
if (_section == Section::Featured) {
|
if (_section == Section::Featured) {
|
||||||
*outUnread = _unreadSets.contains(set.id);
|
*outUnread = (set.flags & MTPDstickerSet_ClientFlag::f_unread);
|
||||||
if (!*outUnread && (set.flags & MTPDstickerSet_ClientFlag::f_unread)) {
|
|
||||||
*outUnread = true;
|
|
||||||
_unreadSets.insert(set.id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersInner::readFeaturedDone(const MTPBool &result) {
|
|
||||||
Local::writeFeaturedStickers();
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
Stickers::Order StickersInner::getOrder() const {
|
Stickers::Order StickersInner::getOrder() const {
|
||||||
Stickers::Order result;
|
Stickers::Order result;
|
||||||
result.reserve(_rows.size());
|
result.reserve(_rows.size());
|
||||||
|
@ -1169,6 +1144,32 @@ Stickers::Order StickersInner::getDisabledSets() const {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StickersInner::setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
||||||
|
if (_section == Section::Featured) {
|
||||||
|
_visibleTop = visibleTop;
|
||||||
|
_visibleBottom = visibleBottom;
|
||||||
|
readVisibleSets();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersInner::readVisibleSets() {
|
||||||
|
auto itemsVisibleTop = _visibleTop - _itemsTop;
|
||||||
|
auto itemsVisibleBottom = _visibleBottom - _itemsTop;
|
||||||
|
int rowFrom = floorclamp(itemsVisibleTop, _rowHeight, 0, _rows.size());
|
||||||
|
int rowTo = ceilclamp(itemsVisibleBottom, _rowHeight, 0, _rows.size());
|
||||||
|
for (int i = rowFrom; i < rowTo; ++i) {
|
||||||
|
if (!_rows[i]->unread) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (i * _rowHeight < itemsVisibleTop || (i + 1) * _rowHeight > itemsVisibleBottom) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!_rows[i]->sticker || _rows[i]->sticker->thumb->loaded() || _rows[i]->sticker->loaded()) {
|
||||||
|
Stickers::markFeaturedAsRead(_rows[i]->id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void StickersInner::setVisibleScrollbar(int32 width) {
|
void StickersInner::setVisibleScrollbar(int32 width) {
|
||||||
_scrollbar = width;
|
_scrollbar = width;
|
||||||
}
|
}
|
||||||
|
@ -1329,9 +1330,16 @@ void StickersBox::setup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersBox::onScroll() {
|
void StickersBox::onScroll() {
|
||||||
|
updateVisibleTopBottom();
|
||||||
checkLoadMoreArchived();
|
checkLoadMoreArchived();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StickersBox::updateVisibleTopBottom() {
|
||||||
|
auto visibleTop = scrollArea()->scrollTop();
|
||||||
|
auto visibleBottom = visibleTop + scrollArea()->height();
|
||||||
|
_inner->setVisibleTopBottom(visibleTop, visibleBottom);
|
||||||
|
}
|
||||||
|
|
||||||
void StickersBox::checkLoadMoreArchived() {
|
void StickersBox::checkLoadMoreArchived() {
|
||||||
if (_section != Section::Archived) return;
|
if (_section != Section::Archived) return;
|
||||||
|
|
||||||
|
@ -1456,6 +1464,7 @@ void StickersBox::resizeEvent(QResizeEvent *e) {
|
||||||
ItemListBox::resizeEvent(e);
|
ItemListBox::resizeEvent(e);
|
||||||
_inner->resize(width(), _inner->height());
|
_inner->resize(width(), _inner->height());
|
||||||
_inner->setVisibleScrollbar((scrollArea()->scrollTopMax() > 0) ? (st::boxScroll.width - st::boxScroll.deltax) : 0);
|
_inner->setVisibleScrollbar((scrollArea()->scrollTopMax() > 0) ? (st::boxScroll.width - st::boxScroll.deltax) : 0);
|
||||||
|
updateVisibleTopBottom();
|
||||||
if (_topShadow) {
|
if (_topShadow) {
|
||||||
_topShadow->setGeometry(0, st::boxTitleHeight + _aboutHeight, width(), st::lineWidth);
|
_topShadow->setGeometry(0, st::boxTitleHeight + _aboutHeight, width(), st::lineWidth);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@ class StickerSetInner : public TWidget, public RPCSender {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
StickerSetInner(const MTPInputStickerSet &set);
|
StickerSetInner(const MTPInputStickerSet &set);
|
||||||
|
|
||||||
void mousePressEvent(QMouseEvent *e);
|
void mousePressEvent(QMouseEvent *e);
|
||||||
|
@ -49,16 +48,13 @@ public:
|
||||||
~StickerSetInner();
|
~StickerSetInner();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void onPreview();
|
void onPreview();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void updateButtons();
|
void updateButtons();
|
||||||
void installed(uint64 id);
|
void installed(uint64 id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
int32 stickerFromGlobalPos(const QPoint &p) const;
|
int32 stickerFromGlobalPos(const QPoint &p) const;
|
||||||
|
|
||||||
void gotSet(const MTPmessages_StickerSet &set);
|
void gotSet(const MTPmessages_StickerSet &set);
|
||||||
|
@ -169,6 +165,7 @@ private:
|
||||||
bool reorderFail(const RPCError &result);
|
bool reorderFail(const RPCError &result);
|
||||||
void saveOrder();
|
void saveOrder();
|
||||||
|
|
||||||
|
void updateVisibleTopBottom();
|
||||||
void checkLoadMoreArchived();
|
void checkLoadMoreArchived();
|
||||||
void getArchivedDone(uint64 offsetId, const MTPmessages_ArchivedStickers &result);
|
void getArchivedDone(uint64 offsetId, const MTPmessages_ArchivedStickers &result);
|
||||||
|
|
||||||
|
@ -198,7 +195,7 @@ int32 stickerPacksCount(bool includeDisabledOfficial = false);
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
class StickersInner : public TWidget, public RPCSender {
|
class StickersInner : public ScrolledWidget, public RPCSender {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -220,6 +217,7 @@ public:
|
||||||
Stickers::Order getDisabledSets() const;
|
Stickers::Order getDisabledSets() const;
|
||||||
|
|
||||||
void setVisibleScrollbar(int32 width);
|
void setVisibleScrollbar(int32 width);
|
||||||
|
void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
|
||||||
|
|
||||||
~StickersInner();
|
~StickersInner();
|
||||||
|
|
||||||
|
@ -239,6 +237,9 @@ public slots:
|
||||||
void onClearRecent();
|
void onClearRecent();
|
||||||
void onClearBoxDestroyed(QObject *box);
|
void onClearBoxDestroyed(QObject *box);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onImageLoaded();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setup();
|
void setup();
|
||||||
void paintButton(Painter &p, int y, bool selected, const QString &text, int badgeCounter) const;
|
void paintButton(Painter &p, int y, bool selected, const QString &text, int badgeCounter) const;
|
||||||
|
@ -249,21 +250,22 @@ private:
|
||||||
void setActionSel(int32 actionSel);
|
void setActionSel(int32 actionSel);
|
||||||
float64 aboveShadowOpacity() const;
|
float64 aboveShadowOpacity() const;
|
||||||
|
|
||||||
|
void readVisibleSets();
|
||||||
|
|
||||||
void installSet(uint64 setId);
|
void installSet(uint64 setId);
|
||||||
void installDone(const MTPmessages_StickerSetInstallResult &result);
|
void installDone(const MTPmessages_StickerSetInstallResult &result);
|
||||||
bool installFail(uint64 setId, const RPCError &error);
|
bool installFail(uint64 setId, const RPCError &error);
|
||||||
void readFeaturedDone(const MTPBool &result);
|
|
||||||
bool readFeaturedFail(const RPCError &error);
|
|
||||||
|
|
||||||
Section _section;
|
Section _section;
|
||||||
Stickers::Order _archivedIds;
|
Stickers::Order _archivedIds;
|
||||||
|
|
||||||
int32 _rowHeight;
|
int32 _rowHeight;
|
||||||
struct StickerSetRow {
|
struct StickerSetRow {
|
||||||
StickerSetRow(uint64 id, DocumentData *sticker, int32 count, const QString &title, bool installed, bool official, bool unread, bool disabled, bool recent, int32 pixw, int32 pixh) : id(id)
|
StickerSetRow(uint64 id, DocumentData *sticker, int32 count, const QString &title, int titleWidth, bool installed, bool official, bool unread, bool disabled, bool recent, int32 pixw, int32 pixh) : id(id)
|
||||||
, sticker(sticker)
|
, sticker(sticker)
|
||||||
, count(count)
|
, count(count)
|
||||||
, title(title)
|
, title(title)
|
||||||
|
, titleWidth(titleWidth)
|
||||||
, installed(installed)
|
, installed(installed)
|
||||||
, official(official)
|
, official(official)
|
||||||
, unread(unread)
|
, unread(unread)
|
||||||
|
@ -277,6 +279,7 @@ private:
|
||||||
DocumentData *sticker;
|
DocumentData *sticker;
|
||||||
int32 count;
|
int32 count;
|
||||||
QString title;
|
QString title;
|
||||||
|
int titleWidth;
|
||||||
bool installed, official, unread, disabled, recent;
|
bool installed, official, unread, disabled, recent;
|
||||||
int32 pixw, pixh;
|
int32 pixw, pixh;
|
||||||
anim::ivalue yadd;
|
anim::ivalue yadd;
|
||||||
|
@ -286,7 +289,7 @@ private:
|
||||||
void rebuildAppendSet(const Stickers::Set &set, int maxNameWidth);
|
void rebuildAppendSet(const Stickers::Set &set, int maxNameWidth);
|
||||||
void fillSetCover(const Stickers::Set &set, DocumentData **outSticker, int *outWidth, int *outHeight) const;
|
void fillSetCover(const Stickers::Set &set, DocumentData **outSticker, int *outWidth, int *outHeight) const;
|
||||||
int fillSetCount(const Stickers::Set &set) const;
|
int fillSetCount(const Stickers::Set &set) const;
|
||||||
QString fillSetTitle(const Stickers::Set &set, int maxNameWidth) const;
|
QString fillSetTitle(const Stickers::Set &set, int maxNameWidth, int *outTitleWidth) const;
|
||||||
void fillSetFlags(const Stickers::Set &set, bool *outRecent, bool *outInstalled, bool *outOfficial, bool *outUnread, bool *outDisabled);
|
void fillSetFlags(const Stickers::Set &set, bool *outRecent, bool *outInstalled, bool *outOfficial, bool *outUnread, bool *outDisabled);
|
||||||
|
|
||||||
int countMaxNameWidth() const;
|
int countMaxNameWidth() const;
|
||||||
|
@ -297,7 +300,9 @@ private:
|
||||||
anim::fvalue _aboveShadowFadeOpacity = { 0., 0. };
|
anim::fvalue _aboveShadowFadeOpacity = { 0., 0. };
|
||||||
Animation _a_shifting;
|
Animation _a_shifting;
|
||||||
|
|
||||||
int32 _itemsTop;
|
int _visibleTop = 0;
|
||||||
|
int _visibleBottom = 0;
|
||||||
|
int _itemsTop = 0;
|
||||||
|
|
||||||
bool _saving = false;
|
bool _saving = false;
|
||||||
|
|
||||||
|
@ -312,9 +317,6 @@ private:
|
||||||
bool _hasFeaturedButton = false;
|
bool _hasFeaturedButton = false;
|
||||||
bool _hasArchivedButton = false;
|
bool _hasArchivedButton = false;
|
||||||
|
|
||||||
// Remember all the unread set ids to display unread dots.
|
|
||||||
OrderedSet<uint64> _unreadSets;
|
|
||||||
|
|
||||||
QPoint _mouse;
|
QPoint _mouse;
|
||||||
int _selected = -3; // -2 - featured stickers button, -1 - archived stickers button
|
int _selected = -3; // -2 - featured stickers button, -1 - archived stickers button
|
||||||
int _pressed = -2;
|
int _pressed = -2;
|
||||||
|
|
|
@ -3836,14 +3836,14 @@ void HistoryWidget::featuredStickersGot(const MTPmessages_FeaturedStickers &stic
|
||||||
_featuredStickersUpdateRequest = 0;
|
_featuredStickersUpdateRequest = 0;
|
||||||
|
|
||||||
if (stickers.type() != mtpc_messages_featuredStickers) return;
|
if (stickers.type() != mtpc_messages_featuredStickers) return;
|
||||||
auto &d(stickers.c_messages_featuredStickers());
|
auto &d = stickers.c_messages_featuredStickers();
|
||||||
|
|
||||||
OrderedSet<uint64> unread;
|
OrderedSet<uint64> unread;
|
||||||
for_const (auto &unreadSetId, d.vunread.c_vector().v) {
|
for_const (auto &unreadSetId, d.vunread.c_vector().v) {
|
||||||
unread.insert(unreadSetId.v);
|
unread.insert(unreadSetId.v);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &d_sets(d.vsets.c_vector().v);
|
auto &d_sets = d.vsets.c_vector().v;
|
||||||
|
|
||||||
auto &setsOrder = Global::RefFeaturedStickerSetsOrder();
|
auto &setsOrder = Global::RefFeaturedStickerSetsOrder();
|
||||||
setsOrder.clear();
|
setsOrder.clear();
|
||||||
|
|
|
@ -27,6 +27,13 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "ui/filedialog.h"
|
#include "ui/filedialog.h"
|
||||||
|
#include "styles/style_stickers.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr int kStickerPreviewEmojiLimit = 10;
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
void LayerWidget::setInnerFocus() {
|
void LayerWidget::setInnerFocus() {
|
||||||
auto focused = App::wnd()->focusWidget();
|
auto focused = App::wnd()->focusWidget();
|
||||||
|
@ -339,6 +346,7 @@ void LayerStackWidget::activateLayer(LayerWidget *l) {
|
||||||
startShow();
|
startShow();
|
||||||
} else {
|
} else {
|
||||||
l->show();
|
l->show();
|
||||||
|
l->showDone();
|
||||||
if (App::wnd()) App::wnd()->setInnerFocus();
|
if (App::wnd()) App::wnd()->setInnerFocus();
|
||||||
updateLayerBox();
|
updateLayerBox();
|
||||||
}
|
}
|
||||||
|
@ -426,7 +434,8 @@ LayerStackWidget::~LayerStackWidget() {
|
||||||
|
|
||||||
MediaPreviewWidget::MediaPreviewWidget(QWidget *parent) : TWidget(parent)
|
MediaPreviewWidget::MediaPreviewWidget(QWidget *parent) : TWidget(parent)
|
||||||
, a_shown(0, 0)
|
, a_shown(0, 0)
|
||||||
, _a_shown(animation(this, &MediaPreviewWidget::step_shown)) {
|
, _a_shown(animation(this, &MediaPreviewWidget::step_shown))
|
||||||
|
, _emojiSize(EmojiSizes[EIndex + 1] / cIntRetinaFactor()) {
|
||||||
setAttribute(Qt::WA_TransparentForMouseEvents);
|
setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
|
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
|
||||||
}
|
}
|
||||||
|
@ -435,8 +444,8 @@ void MediaPreviewWidget::paintEvent(QPaintEvent *e) {
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
QRect r(e->rect());
|
QRect r(e->rect());
|
||||||
|
|
||||||
const QPixmap &draw(currentImage());
|
auto &image = currentImage();
|
||||||
int w = draw.width() / cIntRetinaFactor(), h = draw.height() / cIntRetinaFactor();
|
int w = image.width() / cIntRetinaFactor(), h = image.height() / cIntRetinaFactor();
|
||||||
if (_a_shown.animating()) {
|
if (_a_shown.animating()) {
|
||||||
float64 shown = a_shown.current();
|
float64 shown = a_shown.current();
|
||||||
p.setOpacity(shown);
|
p.setOpacity(shown);
|
||||||
|
@ -444,7 +453,17 @@ void MediaPreviewWidget::paintEvent(QPaintEvent *e) {
|
||||||
// h = qMax(qRound(h * (st::stickerPreviewMin + ((1. - st::stickerPreviewMin) * shown)) / 2.) * 2 + int(h % 2), 1);
|
// h = qMax(qRound(h * (st::stickerPreviewMin + ((1. - st::stickerPreviewMin) * shown)) / 2.) * 2 + int(h % 2), 1);
|
||||||
}
|
}
|
||||||
p.fillRect(r, st::stickerPreviewBg);
|
p.fillRect(r, st::stickerPreviewBg);
|
||||||
p.drawPixmap((width() - w) / 2, (height() - h) / 2, draw);
|
p.drawPixmap((width() - w) / 2, (height() - h) / 2, image);
|
||||||
|
if (!_emojiList.isEmpty()) {
|
||||||
|
int emojiCount = _emojiList.size();
|
||||||
|
int emojiWidth = emojiCount * _emojiSize + (emojiCount - 1) * st::stickerEmojiSkip;
|
||||||
|
int emojiLeft = (width() - emojiWidth) / 2;
|
||||||
|
int esize = _emojiSize * cIntRetinaFactor();
|
||||||
|
for_const (auto emoji, _emojiList) {
|
||||||
|
p.drawPixmapLeft(emojiLeft, (height() - h) / 2 - _emojiSize * 2, width(), App::emojiLarge(), QRect(emoji->x * esize, emoji->y * esize, esize, esize));
|
||||||
|
emojiLeft += _emojiSize + st::stickerEmojiSkip;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaPreviewWidget::resizeEvent(QResizeEvent *e) {
|
void MediaPreviewWidget::resizeEvent(QResizeEvent *e) {
|
||||||
|
@ -472,6 +491,7 @@ void MediaPreviewWidget::showPreview(DocumentData *document) {
|
||||||
startShow();
|
startShow();
|
||||||
_photo = nullptr;
|
_photo = nullptr;
|
||||||
_document = document;
|
_document = document;
|
||||||
|
fillEmojiString();
|
||||||
resetGifAndCache();
|
resetGifAndCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -510,6 +530,42 @@ void MediaPreviewWidget::hidePreview() {
|
||||||
resetGifAndCache();
|
resetGifAndCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MediaPreviewWidget::fillEmojiString() {
|
||||||
|
auto getStickerEmojiList = [this](uint64 setId) {
|
||||||
|
QList<EmojiPtr> result;
|
||||||
|
auto &sets = Global::StickerSets();
|
||||||
|
auto it = sets.constFind(setId);
|
||||||
|
if (it == sets.cend()) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
for (auto i = it->emoji.cbegin(), e = it->emoji.cend(); i != e; ++i) {
|
||||||
|
for_const (auto document, *i) {
|
||||||
|
if (document == _document) {
|
||||||
|
result.append(i.key());
|
||||||
|
if (result.size() >= kStickerPreviewEmojiLimit) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (auto sticker = _document->sticker()) {
|
||||||
|
auto &inputSet = sticker->set;
|
||||||
|
if (inputSet.type() == mtpc_inputStickerSetID) {
|
||||||
|
_emojiList = getStickerEmojiList(inputSet.c_inputStickerSetID().vid.v);
|
||||||
|
} else {
|
||||||
|
_emojiList.clear();
|
||||||
|
if (auto emoji = emojiFromText(sticker->alt)) {
|
||||||
|
_emojiList.append(emoji);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_emojiList.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MediaPreviewWidget::resetGifAndCache() {
|
void MediaPreviewWidget::resetGifAndCache() {
|
||||||
if (_gif) {
|
if (_gif) {
|
||||||
if (gif()) {
|
if (gif()) {
|
||||||
|
|
|
@ -133,7 +133,6 @@ class MediaPreviewWidget : public TWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
MediaPreviewWidget(QWidget *parent);
|
MediaPreviewWidget(QWidget *parent);
|
||||||
|
|
||||||
void paintEvent(QPaintEvent *e);
|
void paintEvent(QPaintEvent *e);
|
||||||
|
@ -148,10 +147,10 @@ public:
|
||||||
~MediaPreviewWidget();
|
~MediaPreviewWidget();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
QSize currentDimensions() const;
|
QSize currentDimensions() const;
|
||||||
QPixmap currentImage() const;
|
QPixmap currentImage() const;
|
||||||
void startShow();
|
void startShow();
|
||||||
|
void fillEmojiString();
|
||||||
void resetGifAndCache();
|
void resetGifAndCache();
|
||||||
|
|
||||||
anim::fvalue a_shown;
|
anim::fvalue a_shown;
|
||||||
|
@ -163,6 +162,9 @@ private:
|
||||||
return (!_gif || _gif == Media::Clip::BadReader) ? false : true;
|
return (!_gif || _gif == Media::Clip::BadReader) ? false : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _emojiSize;
|
||||||
|
QList<EmojiPtr> _emojiList;
|
||||||
|
|
||||||
void clipCallback(Media::Clip::Notification notification);
|
void clipCallback(Media::Clip::Notification notification);
|
||||||
|
|
||||||
enum CacheStatus {
|
enum CacheStatus {
|
||||||
|
|
|
@ -3215,6 +3215,7 @@ namespace Local {
|
||||||
it = sets.insert(setId, Stickers::Set(setId, setAccess, setTitle, setShortName, 0, setHash, MTPDstickerSet::Flags(setFlags)));
|
it = sets.insert(setId, Stickers::Set(setId, setAccess, setTitle, setShortName, 0, setHash, MTPDstickerSet::Flags(setFlags)));
|
||||||
}
|
}
|
||||||
auto &set = it.value();
|
auto &set = it.value();
|
||||||
|
auto inputSet = MTP_inputStickerSetID(MTP_long(set.id), MTP_long(set.access));
|
||||||
|
|
||||||
if (scnt < 0) { // disabled not loaded set
|
if (scnt < 0) { // disabled not loaded set
|
||||||
if (!set.count || set.stickers.isEmpty()) {
|
if (!set.count || set.stickers.isEmpty()) {
|
||||||
|
@ -3240,6 +3241,11 @@ namespace Local {
|
||||||
|
|
||||||
if (fillStickers) {
|
if (fillStickers) {
|
||||||
set.stickers.push_back(document);
|
set.stickers.push_back(document);
|
||||||
|
if (!(set.flags & MTPDstickerSet_ClientFlag::f_special)) {
|
||||||
|
if (document->sticker()->set.type() != mtpc_inputStickerSetID) {
|
||||||
|
document->sticker()->set = inputSet;
|
||||||
|
}
|
||||||
|
}
|
||||||
++set.count;
|
++set.count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3287,6 +3293,8 @@ namespace Local {
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeInstalledStickers() {
|
void writeInstalledStickers() {
|
||||||
|
if (!Global::started()) return;
|
||||||
|
|
||||||
_writeStickerSets(_installedStickersKey, [](const Stickers::Set &set) {
|
_writeStickerSets(_installedStickersKey, [](const Stickers::Set &set) {
|
||||||
if (set.id == Stickers::CloudRecentSetId) { // separate file for recent
|
if (set.id == Stickers::CloudRecentSetId) { // separate file for recent
|
||||||
return StickerSetCheckResult::Skip;
|
return StickerSetCheckResult::Skip;
|
||||||
|
@ -3306,6 +3314,8 @@ namespace Local {
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeFeaturedStickers() {
|
void writeFeaturedStickers() {
|
||||||
|
if (!Global::started()) return;
|
||||||
|
|
||||||
_writeStickerSets(_featuredStickersKey, [](const Stickers::Set &set) {
|
_writeStickerSets(_featuredStickersKey, [](const Stickers::Set &set) {
|
||||||
if (set.id == Stickers::CloudRecentSetId) { // separate file for recent
|
if (set.id == Stickers::CloudRecentSetId) { // separate file for recent
|
||||||
return StickerSetCheckResult::Skip;
|
return StickerSetCheckResult::Skip;
|
||||||
|
@ -3323,6 +3333,8 @@ namespace Local {
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeRecentStickers() {
|
void writeRecentStickers() {
|
||||||
|
if (!Global::started()) return;
|
||||||
|
|
||||||
_writeStickerSets(_recentStickersKey, [](const Stickers::Set &set) {
|
_writeStickerSets(_recentStickersKey, [](const Stickers::Set &set) {
|
||||||
if (set.id != Stickers::CloudRecentSetId || set.stickers.isEmpty()) {
|
if (set.id != Stickers::CloudRecentSetId || set.stickers.isEmpty()) {
|
||||||
return StickerSetCheckResult::Skip;
|
return StickerSetCheckResult::Skip;
|
||||||
|
@ -3332,6 +3344,8 @@ namespace Local {
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeArchivedStickers() {
|
void writeArchivedStickers() {
|
||||||
|
if (!Global::started()) return;
|
||||||
|
|
||||||
_writeStickerSets(_archivedStickersKey, [](const Stickers::Set &set) {
|
_writeStickerSets(_archivedStickersKey, [](const Stickers::Set &set) {
|
||||||
if (!(set.flags & MTPDstickerSet::Flag::f_archived) || set.stickers.isEmpty()) {
|
if (!(set.flags & MTPDstickerSet::Flag::f_archived) || set.stickers.isEmpty()) {
|
||||||
return StickerSetCheckResult::Skip;
|
return StickerSetCheckResult::Skip;
|
||||||
|
|
|
@ -4691,15 +4691,18 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||||
writeArchived = true;
|
writeArchived = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
auto inputSet = MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access));
|
||||||
const auto &v(set.vdocuments.c_vector().v);
|
auto &v = set.vdocuments.c_vector().v;
|
||||||
it->stickers.clear();
|
it->stickers.clear();
|
||||||
it->stickers.reserve(v.size());
|
it->stickers.reserve(v.size());
|
||||||
for (int32 i = 0, l = v.size(); i < l; ++i) {
|
for (int32 i = 0, l = v.size(); i < l; ++i) {
|
||||||
DocumentData *doc = App::feedDocument(v.at(i));
|
auto doc = App::feedDocument(v.at(i));
|
||||||
if (!doc || !doc->sticker()) continue;
|
if (!doc || !doc->sticker()) continue;
|
||||||
|
|
||||||
it->stickers.push_back(doc);
|
it->stickers.push_back(doc);
|
||||||
|
if (doc->sticker()->set.type() != mtpc_inputStickerSetID) {
|
||||||
|
doc->sticker()->set = inputSet;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
it->emoji.clear();
|
it->emoji.clear();
|
||||||
auto &packs = set.vpacks.c_vector().v;
|
auto &packs = set.vpacks.c_vector().v;
|
||||||
|
@ -4780,16 +4783,11 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case mtpc_updateReadFeaturedStickers: {
|
case mtpc_updateReadFeaturedStickers: {
|
||||||
for (auto &set : Global::RefStickerSets()) {
|
// We read some of the featured stickers, perhaps not all of them.
|
||||||
if (set.flags & MTPDstickerSet_ClientFlag::f_unread) {
|
// Here we don't know what featured sticker sets were read, so we
|
||||||
set.flags &= ~MTPDstickerSet_ClientFlag::f_unread;
|
// request all of them once again.
|
||||||
}
|
Global::SetLastFeaturedStickersUpdate(0);
|
||||||
}
|
App::main()->updateStickers();
|
||||||
if (Global::FeaturedStickerSetsUnreadCount()) {
|
|
||||||
Global::SetFeaturedStickerSetsUnreadCount(0);
|
|
||||||
Local::writeFeaturedStickers();
|
|
||||||
emit stickersUpdated();
|
|
||||||
}
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
////// Cloud saved GIFs
|
////// Cloud saved GIFs
|
||||||
|
|
|
@ -287,7 +287,7 @@ void EmojiColorPicker::drawVariant(Painter &p, int variant) {
|
||||||
p.drawPixmapLeft(w.x() + (st::emojiPanSize.width() - (esize / cIntRetinaFactor())) / 2, w.y() + (st::emojiPanSize.height() - (esize / cIntRetinaFactor())) / 2, width(), App::emojiLarge(), QRect(_variants[variant]->x * esize, _variants[variant]->y * esize, esize, esize));
|
p.drawPixmapLeft(w.x() + (st::emojiPanSize.width() - (esize / cIntRetinaFactor())) / 2, w.y() + (st::emojiPanSize.height() - (esize / cIntRetinaFactor())) / 2, width(), App::emojiLarge(), QRect(_variants[variant]->x * esize, _variants[variant]->y * esize, esize, esize));
|
||||||
}
|
}
|
||||||
|
|
||||||
EmojiPanInner::EmojiPanInner() : TWidget()
|
EmojiPanInner::EmojiPanInner() : ScrolledWidget()
|
||||||
, _maxHeight(int(st::emojiPanMaxHeight) - st::rbEmoji.height)
|
, _maxHeight(int(st::emojiPanMaxHeight) - st::rbEmoji.height)
|
||||||
, _a_selected(animation(this, &EmojiPanInner::step_selected)) {
|
, _a_selected(animation(this, &EmojiPanInner::step_selected)) {
|
||||||
resize(st::emojiPanWidth - st::emojiScroll.width, countHeight());
|
resize(st::emojiPanWidth - st::emojiScroll.width, countHeight());
|
||||||
|
@ -316,8 +316,9 @@ void EmojiPanInner::setMaxHeight(int32 h) {
|
||||||
resize(st::emojiPanWidth - st::emojiScroll.width, countHeight());
|
resize(st::emojiPanWidth - st::emojiScroll.width, countHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmojiPanInner::setScrollTop(int top) {
|
void EmojiPanInner::setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
||||||
_top = top;
|
_visibleTop = visibleTop;
|
||||||
|
_visibleBottom = visibleBottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
int EmojiPanInner::countHeight() {
|
int EmojiPanInner::countHeight() {
|
||||||
|
@ -519,7 +520,7 @@ void EmojiPanInner::onShowPicker() {
|
||||||
int32 size = (c == tab) ? (sel - (sel % EmojiPanPerRow)) : _counts[c], rows = (size / EmojiPanPerRow) + ((size % EmojiPanPerRow) ? 1 : 0);
|
int32 size = (c == tab) ? (sel - (sel % EmojiPanPerRow)) : _counts[c], rows = (size / EmojiPanPerRow) + ((size % EmojiPanPerRow) ? 1 : 0);
|
||||||
y += st::emojiPanHeader + (rows * st::emojiPanSize.height());
|
y += st::emojiPanHeader + (rows * st::emojiPanSize.height());
|
||||||
}
|
}
|
||||||
y -= _picker.height() - st::buttonRadius + _top;
|
y -= _picker.height() - st::buttonRadius + _visibleTop;
|
||||||
if (y < 0) {
|
if (y < 0) {
|
||||||
y += _picker.height() - st::buttonRadius + st::emojiPanSize.height() - st::buttonRadius;
|
y += _picker.height() - st::buttonRadius + st::emojiPanSize.height() - st::buttonRadius;
|
||||||
}
|
}
|
||||||
|
@ -788,7 +789,7 @@ void EmojiPanInner::showEmojiPack(DBIEmojiTab packIndex) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
StickerPanInner::StickerPanInner() : TWidget()
|
StickerPanInner::StickerPanInner() : ScrolledWidget()
|
||||||
, _a_selected(animation(this, &StickerPanInner::step_selected))
|
, _a_selected(animation(this, &StickerPanInner::step_selected))
|
||||||
, _section(cShowingSavedGifs() ? Section::Gifs : Section::Stickers)
|
, _section(cShowingSavedGifs() ? Section::Gifs : Section::Stickers)
|
||||||
, _addText(lang(lng_stickers_featured_add).toUpper())
|
, _addText(lang(lng_stickers_featured_add).toUpper())
|
||||||
|
@ -800,7 +801,7 @@ StickerPanInner::StickerPanInner() : TWidget()
|
||||||
setFocusPolicy(Qt::NoFocus);
|
setFocusPolicy(Qt::NoFocus);
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||||
|
|
||||||
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
|
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(onImageLoaded()));
|
||||||
connect(&_settings, SIGNAL(clicked()), this, SLOT(onSettings()));
|
connect(&_settings, SIGNAL(clicked()), this, SLOT(onSettings()));
|
||||||
|
|
||||||
_previewTimer.setSingleShot(true);
|
_previewTimer.setSingleShot(true);
|
||||||
|
@ -816,11 +817,47 @@ void StickerPanInner::setMaxHeight(int32 h) {
|
||||||
_settings.moveToLeft((st::emojiPanWidth - _settings.width()) / 2, height() / 3);
|
_settings.moveToLeft((st::emojiPanWidth - _settings.width()) / 2, height() / 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickerPanInner::setScrollTop(int top) {
|
void StickerPanInner::setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
||||||
if (top == _top) return;
|
_visibleBottom = visibleBottom;
|
||||||
|
if (_visibleTop != visibleTop) {
|
||||||
|
_visibleTop = visibleTop;
|
||||||
|
_lastScrolled = getms();
|
||||||
|
}
|
||||||
|
if (_section == Section::Featured) {
|
||||||
|
readVisibleSets();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_lastScrolled = getms();
|
void StickerPanInner::readVisibleSets() {
|
||||||
_top = top;
|
auto itemsVisibleTop = _visibleTop - st::emojiPanHeader;
|
||||||
|
auto itemsVisibleBottom = _visibleBottom - st::emojiPanHeader;
|
||||||
|
auto rowHeight = featuredRowHeight();
|
||||||
|
int rowFrom = floorclamp(itemsVisibleTop, rowHeight, 0, _featuredSets.size());
|
||||||
|
int rowTo = ceilclamp(itemsVisibleBottom, rowHeight, 0, _featuredSets.size());
|
||||||
|
for (int i = rowFrom; i < rowTo; ++i) {
|
||||||
|
auto &set = _featuredSets[i];
|
||||||
|
if (!(set.flags & MTPDstickerSet_ClientFlag::f_unread)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (i * rowHeight < itemsVisibleTop || (i + 1) * rowHeight > itemsVisibleBottom) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int count = qMin(set.pack.size(), static_cast<int>(StickerPanPerRow));
|
||||||
|
int loaded = 0;
|
||||||
|
for (int j = 0; j < count; ++j) {
|
||||||
|
if (set.pack[j]->thumb->loaded() || set.pack[j]->loaded()) {
|
||||||
|
++loaded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (loaded == count) {
|
||||||
|
Stickers::markFeaturedAsRead(set.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickerPanInner::onImageLoaded() {
|
||||||
|
update();
|
||||||
|
readVisibleSets();
|
||||||
}
|
}
|
||||||
|
|
||||||
int StickerPanInner::featuredRowHeight() const {
|
int StickerPanInner::featuredRowHeight() const {
|
||||||
|
@ -973,6 +1010,9 @@ void StickerPanInner::paintStickers(Painter &p, const QRect &r) {
|
||||||
|
|
||||||
widthForTitle -= add.width() - (st::featuredStickersAdd.width / 2);
|
widthForTitle -= add.width() - (st::featuredStickersAdd.width / 2);
|
||||||
}
|
}
|
||||||
|
if (set.flags & MTPDstickerSet_ClientFlag::f_unread) {
|
||||||
|
widthForTitle -= st::stickersFeaturedUnreadSize + st::stickersFeaturedUnreadSkip;
|
||||||
|
}
|
||||||
|
|
||||||
auto titleText = set.title;
|
auto titleText = set.title;
|
||||||
auto titleWidth = st::featuredStickersHeaderFont->width(titleText);
|
auto titleWidth = st::featuredStickersHeaderFont->width(titleText);
|
||||||
|
@ -984,6 +1024,15 @@ void StickerPanInner::paintStickers(Painter &p, const QRect &r) {
|
||||||
p.setPen(st::featuredStickersHeaderFg);
|
p.setPen(st::featuredStickersHeaderFg);
|
||||||
p.drawTextLeft(st::emojiPanHeaderLeft, y + st::featuredStickersHeaderTop, width(), titleText, titleWidth);
|
p.drawTextLeft(st::emojiPanHeaderLeft, y + st::featuredStickersHeaderTop, width(), titleText, titleWidth);
|
||||||
|
|
||||||
|
if (set.flags & MTPDstickerSet_ClientFlag::f_unread) {
|
||||||
|
p.setPen(Qt::NoPen);
|
||||||
|
p.setBrush(st::stickersFeaturedUnreadBg);
|
||||||
|
|
||||||
|
p.setRenderHint(QPainter::HighQualityAntialiasing, true);
|
||||||
|
p.drawEllipse(rtlrect(st::emojiPanHeaderLeft + titleWidth + st::stickersFeaturedUnreadSkip, y + st::featuredStickersHeaderTop + st::stickersFeaturedUnreadTop, st::stickersFeaturedUnreadSize, st::stickersFeaturedUnreadSize, width()));
|
||||||
|
p.setRenderHint(QPainter::HighQualityAntialiasing, false);
|
||||||
|
}
|
||||||
|
|
||||||
p.setFont(st::featuredStickersSubheaderFont);
|
p.setFont(st::featuredStickersSubheaderFont);
|
||||||
p.setPen(st::featuredStickersSubheaderFg);
|
p.setPen(st::featuredStickersSubheaderFg);
|
||||||
p.drawTextLeft(st::emojiPanHeaderLeft, y + st::featuredStickersSubheaderTop, width(), lng_stickers_count(lt_count, size));
|
p.drawTextLeft(st::emojiPanHeaderLeft, y + st::featuredStickersSubheaderTop, width(), lng_stickers_count(lt_count, size));
|
||||||
|
@ -1246,7 +1295,6 @@ bool StickerPanInner::showSectionIcons() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickerPanInner::clearSelection(bool fast) {
|
void StickerPanInner::clearSelection(bool fast) {
|
||||||
_lastMousePos = mapToGlobal(QPoint(-10, -10));
|
|
||||||
if (fast) {
|
if (fast) {
|
||||||
if (showingInlineItems()) {
|
if (showingInlineItems()) {
|
||||||
if (_selected >= 0) {
|
if (_selected >= 0) {
|
||||||
|
@ -1287,7 +1335,10 @@ void StickerPanInner::clearSelection(bool fast) {
|
||||||
_a_selected.stop();
|
_a_selected.stop();
|
||||||
update();
|
update();
|
||||||
} else {
|
} else {
|
||||||
|
auto pos = _lastMousePos;
|
||||||
|
_lastMousePos = mapToGlobal(QPoint(-10, -10));
|
||||||
updateSelected();
|
updateSelected();
|
||||||
|
_lastMousePos = pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1324,35 +1375,62 @@ void StickerPanInner::hideFinish(bool completely) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickerPanInner::refreshStickers() {
|
void StickerPanInner::refreshStickers() {
|
||||||
clearSelection(true);
|
auto stickersShown = (_section == Section::Stickers || _section == Section::Featured);
|
||||||
|
if (stickersShown) {
|
||||||
|
clearSelection(true);
|
||||||
|
}
|
||||||
|
|
||||||
_mySets.clear();
|
_mySets.clear();
|
||||||
_mySets.reserve(Global::StickerSetsOrder().size() + 1);
|
_mySets.reserve(Global::StickerSetsOrder().size() + 1);
|
||||||
|
|
||||||
refreshRecentStickers(false);
|
refreshRecentStickers(false);
|
||||||
for_const (auto setId, Global::StickerSetsOrder()) {
|
for_const (auto setId, Global::StickerSetsOrder()) {
|
||||||
appendSet(_mySets, setId);
|
appendSet(_mySets, setId, AppendSkip::Archived);
|
||||||
}
|
}
|
||||||
|
|
||||||
_featuredSets.clear();
|
_featuredSets.clear();
|
||||||
_featuredSets.reserve(Global::FeaturedStickerSetsOrder().size());
|
_featuredSets.reserve(Global::FeaturedStickerSetsOrder().size());
|
||||||
|
|
||||||
for_const (auto setId, Global::FeaturedStickerSetsOrder()) {
|
for_const (auto setId, Global::FeaturedStickerSetsOrder()) {
|
||||||
appendSet(_featuredSets, setId);
|
appendSet(_featuredSets, setId, AppendSkip::Installed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_section == Section::Stickers) {
|
if (stickersShown) {
|
||||||
int h = countHeight();
|
int h = countHeight();
|
||||||
if (h != height()) resize(width(), h);
|
if (h != height()) resize(width(), h);
|
||||||
|
|
||||||
_settings.setVisible(_mySets.isEmpty());
|
_settings.setVisible(_section == Section::Stickers && _mySets.isEmpty());
|
||||||
} else {
|
} else {
|
||||||
_settings.hide();
|
_settings.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
emit refreshIcons();
|
emit refreshIcons();
|
||||||
|
|
||||||
updateSelected();
|
// Hack: skip over animations to the very end,
|
||||||
|
// so that currently selected sticker won't get
|
||||||
|
// blinking background when refreshing stickers.
|
||||||
|
if (stickersShown) {
|
||||||
|
updateSelected();
|
||||||
|
int sel = _selected, tab = sel / MatrixRowShift, xsel = -1;
|
||||||
|
if (sel >= 0) {
|
||||||
|
auto &sets = shownSets();
|
||||||
|
if (tab < sets.size() && sets[tab].id == Stickers::RecentSetId && sel >= tab * MatrixRowShift + sets[tab].pack.size()) {
|
||||||
|
xsel = sel;
|
||||||
|
sel -= sets[tab].pack.size();
|
||||||
|
}
|
||||||
|
auto i = _animations.find(sel + 1);
|
||||||
|
if (i != _animations.cend()) {
|
||||||
|
i.value() = (i.value() >= st::emojiPanDuration) ? (i.value() - st::emojiPanDuration) : 0;
|
||||||
|
}
|
||||||
|
if (xsel >= 0) {
|
||||||
|
auto j = _animations.find(xsel + 1);
|
||||||
|
if (j != _animations.cend()) {
|
||||||
|
j.value() = (j.value() >= st::emojiPanDuration) ? (j.value() - st::emojiPanDuration) : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
step_selected(getms(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StickerPanInner::inlineRowsAddItem(DocumentData *savedGif, InlineResult *result, InlineRow &row, int32 &sumWidth) {
|
bool StickerPanInner::inlineRowsAddItem(DocumentData *savedGif, InlineResult *result, InlineRow &row, int32 &sumWidth) {
|
||||||
|
@ -1790,17 +1868,19 @@ bool StickerPanInner::ui_isInlineItemVisible(const InlineItem *layout) {
|
||||||
top += _inlineRows.at(i).height;
|
top += _inlineRows.at(i).height;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (top < _top + _maxHeight) && (top + _inlineRows.at(row).items.at(col)->height() > _top);
|
return (top < _visibleTop + _maxHeight) && (top + _inlineRows[row].items[col]->height() > _visibleTop);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StickerPanInner::ui_isInlineItemBeingChosen() {
|
bool StickerPanInner::ui_isInlineItemBeingChosen() {
|
||||||
return showingInlineItems();
|
return showingInlineItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickerPanInner::appendSet(Sets &to, uint64 setId) {
|
void StickerPanInner::appendSet(Sets &to, uint64 setId, AppendSkip skip) {
|
||||||
auto &sets = Global::StickerSets();
|
auto &sets = Global::StickerSets();
|
||||||
auto it = sets.constFind(setId);
|
auto it = sets.constFind(setId);
|
||||||
if (it == sets.cend() || (it->flags & MTPDstickerSet::Flag::f_archived) || it->stickers.isEmpty()) return;
|
if (it == sets.cend() || it->stickers.isEmpty()) return;
|
||||||
|
if ((skip == AppendSkip::Archived) && (it->flags & MTPDstickerSet::Flag::f_archived)) return;
|
||||||
|
if ((skip == AppendSkip::Installed) && (it->flags & MTPDstickerSet::Flag::f_installed) && !(it->flags & MTPDstickerSet::Flag::f_archived)) return;
|
||||||
|
|
||||||
to.push_back(Set(it->id, it->flags, it->title, it->stickers.size() + 1, it->stickers));
|
to.push_back(Set(it->id, it->flags, it->title, it->stickers.size() + 1, it->stickers));
|
||||||
}
|
}
|
||||||
|
@ -1879,7 +1959,7 @@ void StickerPanInner::fillIcons(QList<StickerIcon> &icons) {
|
||||||
if (!cSavedGifs().isEmpty()) {
|
if (!cSavedGifs().isEmpty()) {
|
||||||
icons.push_back(StickerIcon(Stickers::NoneSetId));
|
icons.push_back(StickerIcon(Stickers::NoneSetId));
|
||||||
}
|
}
|
||||||
if (Global::FeaturedStickerSetsUnreadCount()) {
|
if (Global::FeaturedStickerSetsUnreadCount() && !_featuredSets.isEmpty()) {
|
||||||
icons.push_back(StickerIcon(Stickers::FeaturedSetId));
|
icons.push_back(StickerIcon(Stickers::FeaturedSetId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1906,7 +1986,7 @@ void StickerPanInner::fillIcons(QList<StickerIcon> &icons) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Global::FeaturedStickerSetsUnreadCount() && !Global::FeaturedStickerSetsOrder().empty()) {
|
if (!Global::FeaturedStickerSetsUnreadCount() && !_featuredSets.isEmpty()) {
|
||||||
icons.push_back(StickerIcon(Stickers::FeaturedSetId));
|
icons.push_back(StickerIcon(Stickers::FeaturedSetId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2671,14 +2751,14 @@ void EmojiPan::paintEvent(QPaintEvent *e) {
|
||||||
p.drawPixmapLeft(x + (st::rbEmoji.width - s.pixw) / 2, _iconsTop + (st::rbEmoji.height - s.pixh) / 2, width(), pix);
|
p.drawPixmapLeft(x + (st::rbEmoji.width - s.pixw) / 2, _iconsTop + (st::rbEmoji.height - s.pixh) / 2, width(), pix);
|
||||||
x += st::rbEmoji.width;
|
x += st::rbEmoji.width;
|
||||||
} else {
|
} else {
|
||||||
if (selxrel != x) {
|
if (true || selxrel != x) {
|
||||||
p.drawSpriteLeft(x + st::rbEmojiRecent.imagePos.x(), _iconsTop + st::rbEmojiRecent.imagePos.y(), width(), getSpecialSetIcon(s.setId, false));
|
p.drawSpriteLeft(x + st::rbEmojiRecent.imagePos.x(), _iconsTop + st::rbEmojiRecent.imagePos.y(), width(), getSpecialSetIcon(s.setId, false));
|
||||||
}
|
}
|
||||||
if (selxrel < x + st::rbEmoji.width && selxrel > x - st::rbEmoji.width) {
|
//if (selxrel < x + st::rbEmoji.width && selxrel > x - st::rbEmoji.width) {
|
||||||
p.setOpacity(1 - (qAbs(selxrel - x) / float64(st::rbEmoji.width)));
|
// p.setOpacity(1 - (qAbs(selxrel - x) / float64(st::rbEmoji.width)));
|
||||||
p.drawSpriteLeft(x + st::rbEmojiRecent.imagePos.x(), _iconsTop + st::rbEmojiRecent.imagePos.y(), width(), getSpecialSetIcon(s.setId, true));
|
// p.drawSpriteLeft(x + st::rbEmojiRecent.imagePos.x(), _iconsTop + st::rbEmojiRecent.imagePos.y(), width(), getSpecialSetIcon(s.setId, true));
|
||||||
p.setOpacity(1);
|
// p.setOpacity(1);
|
||||||
}
|
//}
|
||||||
if (s.setId == Stickers::FeaturedSetId) {
|
if (s.setId == Stickers::FeaturedSetId) {
|
||||||
paintFeaturedStickerSetsBadge(p, x);
|
paintFeaturedStickerSetsBadge(p, x);
|
||||||
}
|
}
|
||||||
|
@ -3330,7 +3410,7 @@ void EmojiPan::onScrollEmoji() {
|
||||||
_noTabUpdate = false;
|
_noTabUpdate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
e_inner.setScrollTop(st);
|
e_inner.setVisibleTopBottom(st, st + e_scroll.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmojiPan::onScrollStickers() {
|
void EmojiPan::onScrollStickers() {
|
||||||
|
@ -3343,7 +3423,7 @@ void EmojiPan::onScrollStickers() {
|
||||||
onInlineRequest();
|
onInlineRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
s_inner.setScrollTop(st);
|
s_inner.setVisibleTopBottom(st, st + s_scroll.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmojiPan::validateSelectedIcon(bool animated) {
|
void EmojiPan::validateSelectedIcon(bool animated) {
|
||||||
|
|
|
@ -113,7 +113,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
class EmojiPanel;
|
class EmojiPanel;
|
||||||
class EmojiPanInner : public TWidget {
|
class EmojiPanInner : public ScrolledWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -122,13 +122,6 @@ public:
|
||||||
void setMaxHeight(int32 h);
|
void setMaxHeight(int32 h);
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
|
||||||
void mousePressEvent(QMouseEvent *e) override;
|
|
||||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
|
||||||
void mouseMoveEvent(QMouseEvent *e) override;
|
|
||||||
void leaveEvent(QEvent *e) override;
|
|
||||||
void leaveToChildEvent(QEvent *e, QWidget *child) override;
|
|
||||||
void enterFromChildEvent(QEvent *e, QWidget *child) override;
|
|
||||||
|
|
||||||
void step_selected(uint64 ms, bool timer);
|
void step_selected(uint64 ms, bool timer);
|
||||||
void hideFinish();
|
void hideFinish();
|
||||||
|
|
||||||
|
@ -140,13 +133,20 @@ public:
|
||||||
|
|
||||||
void refreshRecent();
|
void refreshRecent();
|
||||||
|
|
||||||
void setScrollTop(int top);
|
void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
|
||||||
|
|
||||||
void fillPanels(QVector<EmojiPanel*> &panels);
|
void fillPanels(QVector<EmojiPanel*> &panels);
|
||||||
void refreshPanels(QVector<EmojiPanel*> &panels);
|
void refreshPanels(QVector<EmojiPanel*> &panels);
|
||||||
|
|
||||||
public slots:
|
protected:
|
||||||
|
void mousePressEvent(QMouseEvent *e) override;
|
||||||
|
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||||
|
void mouseMoveEvent(QMouseEvent *e) override;
|
||||||
|
void leaveEvent(QEvent *e) override;
|
||||||
|
void leaveToChildEvent(QEvent *e, QWidget *child) override;
|
||||||
|
void enterFromChildEvent(QEvent *e, QWidget *child) override;
|
||||||
|
|
||||||
|
public slots:
|
||||||
void updateSelected();
|
void updateSelected();
|
||||||
|
|
||||||
void onShowPicker();
|
void onShowPicker();
|
||||||
|
@ -156,7 +156,6 @@ public slots:
|
||||||
bool checkPickerHide();
|
bool checkPickerHide();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void selected(EmojiPtr emoji);
|
void selected(EmojiPtr emoji);
|
||||||
|
|
||||||
void switchToStickers();
|
void switchToStickers();
|
||||||
|
@ -168,7 +167,6 @@ signals:
|
||||||
void saveConfigDelayed(int32 delay);
|
void saveConfigDelayed(int32 delay);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
int32 _maxHeight;
|
int32 _maxHeight;
|
||||||
|
|
||||||
int countHeight();
|
int countHeight();
|
||||||
|
@ -180,7 +178,9 @@ private:
|
||||||
Animations _animations;
|
Animations _animations;
|
||||||
Animation _a_selected;
|
Animation _a_selected;
|
||||||
|
|
||||||
int _top = 0, _counts[emojiTabCount];
|
int _visibleTop = 0;
|
||||||
|
int _visibleBottom = 0;
|
||||||
|
int _counts[emojiTabCount];
|
||||||
|
|
||||||
QVector<EmojiPtr> _emojis[emojiTabCount];
|
QVector<EmojiPtr> _emojis[emojiTabCount];
|
||||||
QVector<float64> _hovers[emojiTabCount];
|
QVector<float64> _hovers[emojiTabCount];
|
||||||
|
@ -207,23 +207,15 @@ struct StickerIcon {
|
||||||
int pixh = 0;
|
int pixh = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class StickerPanInner : public TWidget {
|
class StickerPanInner : public ScrolledWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
StickerPanInner();
|
StickerPanInner();
|
||||||
|
|
||||||
void setMaxHeight(int32 h);
|
void setMaxHeight(int32 h);
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
|
||||||
void mousePressEvent(QMouseEvent *e) override;
|
|
||||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
|
||||||
void mouseMoveEvent(QMouseEvent *e) override;
|
|
||||||
void leaveEvent(QEvent *e) override;
|
|
||||||
void leaveToChildEvent(QEvent *e, QWidget *child) override;
|
|
||||||
void enterFromChildEvent(QEvent *e, QWidget *child) override;
|
|
||||||
|
|
||||||
void step_selected(uint64 ms, bool timer);
|
void step_selected(uint64 ms, bool timer);
|
||||||
|
|
||||||
void hideFinish(bool completely);
|
void hideFinish(bool completely);
|
||||||
|
@ -247,7 +239,7 @@ public:
|
||||||
void fillPanels(QVector<EmojiPanel*> &panels);
|
void fillPanels(QVector<EmojiPanel*> &panels);
|
||||||
void refreshPanels(QVector<EmojiPanel*> &panels);
|
void refreshPanels(QVector<EmojiPanel*> &panels);
|
||||||
|
|
||||||
void setScrollTop(int top);
|
void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
|
||||||
void preloadImages();
|
void preloadImages();
|
||||||
|
|
||||||
uint64 currentSet(int yOffset) const;
|
uint64 currentSet(int yOffset) const;
|
||||||
|
@ -264,12 +256,21 @@ public:
|
||||||
|
|
||||||
~StickerPanInner();
|
~StickerPanInner();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void mousePressEvent(QMouseEvent *e) override;
|
||||||
|
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||||
|
void mouseMoveEvent(QMouseEvent *e) override;
|
||||||
|
void leaveEvent(QEvent *e) override;
|
||||||
|
void leaveToChildEvent(QEvent *e, QWidget *child) override;
|
||||||
|
void enterFromChildEvent(QEvent *e, QWidget *child) override;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void updateSelected();
|
void updateSelected();
|
||||||
void onSettings();
|
void onSettings();
|
||||||
void onPreview();
|
void onPreview();
|
||||||
void onUpdateInlineItems();
|
void onUpdateInlineItems();
|
||||||
void onSwitchPm();
|
void onSwitchPm();
|
||||||
|
void onImageLoaded();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void selected(DocumentData *sticker);
|
void selected(DocumentData *sticker);
|
||||||
|
@ -310,6 +311,7 @@ private:
|
||||||
return const_cast<StickerPanInner*>(this)->shownSets();
|
return const_cast<StickerPanInner*>(this)->shownSets();
|
||||||
}
|
}
|
||||||
int featuredRowHeight() const;
|
int featuredRowHeight() const;
|
||||||
|
void readVisibleSets();
|
||||||
|
|
||||||
bool showingInlineItems() const { // Gifs or Inline results
|
bool showingInlineItems() const { // Gifs or Inline results
|
||||||
return (_section == Section::Inlines) || (_section == Section::Gifs);
|
return (_section == Section::Inlines) || (_section == Section::Gifs);
|
||||||
|
@ -324,7 +326,11 @@ private:
|
||||||
|
|
||||||
void refreshSwitchPmButton(const InlineCacheEntry *entry);
|
void refreshSwitchPmButton(const InlineCacheEntry *entry);
|
||||||
|
|
||||||
void appendSet(Sets &to, uint64 setId);
|
enum class AppendSkip {
|
||||||
|
Archived,
|
||||||
|
Installed,
|
||||||
|
};
|
||||||
|
void appendSet(Sets &to, uint64 setId, AppendSkip skip);
|
||||||
|
|
||||||
void selectEmoji(EmojiPtr emoji);
|
void selectEmoji(EmojiPtr emoji);
|
||||||
QRect stickerRect(int tab, int sel);
|
QRect stickerRect(int tab, int sel);
|
||||||
|
@ -335,7 +341,8 @@ private:
|
||||||
Animations _animations;
|
Animations _animations;
|
||||||
Animation _a_selected;
|
Animation _a_selected;
|
||||||
|
|
||||||
int _top = 0;
|
int _visibleTop = 0;
|
||||||
|
int _visibleBottom = 0;
|
||||||
|
|
||||||
Sets _mySets;
|
Sets _mySets;
|
||||||
Sets _featuredSets;
|
Sets _featuredSets;
|
||||||
|
|
|
@ -19,15 +19,22 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "lang.h"
|
#include "stickers.h"
|
||||||
|
|
||||||
#include "boxes/stickersetbox.h"
|
#include "boxes/stickersetbox.h"
|
||||||
#include "boxes/confirmbox.h"
|
#include "boxes/confirmbox.h"
|
||||||
|
#include "lang.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "localstorage.h"
|
#include "localstorage.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
|
|
||||||
namespace Stickers {
|
namespace Stickers {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr int kReadFeaturedSetsTimeoutMs = 1000;
|
||||||
|
internal::FeaturedReader *FeaturedReaderInstance = nullptr;
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
void applyArchivedResult(const MTPDmessages_stickerSetInstallResultArchive &d) {
|
void applyArchivedResult(const MTPDmessages_stickerSetInstallResultArchive &d) {
|
||||||
auto &v = d.vsets.c_vector().v;
|
auto &v = d.vsets.c_vector().v;
|
||||||
|
@ -140,4 +147,61 @@ void undoInstallLocally(uint64 setId) {
|
||||||
Ui::showLayer(new InformBox(lang(lng_stickers_not_found)), KeepOtherLayers);
|
Ui::showLayer(new InformBox(lang(lng_stickers_not_found)), KeepOtherLayers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void markFeaturedAsRead(uint64 setId) {
|
||||||
|
if (!FeaturedReaderInstance) {
|
||||||
|
if (auto main = App::main()) {
|
||||||
|
FeaturedReaderInstance = new internal::FeaturedReader(main);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FeaturedReaderInstance->scheduleRead(setId);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
void readFeaturedDone() {
|
||||||
|
Local::writeFeaturedStickers();
|
||||||
|
if (App::main()) {
|
||||||
|
emit App::main()->stickersUpdated();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FeaturedReader::FeaturedReader(QObject *parent) : QObject(parent)
|
||||||
|
, _timer(new QTimer(this)) {
|
||||||
|
_timer->setSingleShot(true);
|
||||||
|
connect(_timer, SIGNAL(timeout()), this, SLOT(onReadSets()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FeaturedReader::scheduleRead(uint64 setId) {
|
||||||
|
if (!_setIds.contains(setId)) {
|
||||||
|
_setIds.insert(setId);
|
||||||
|
_timer->start(kReadFeaturedSetsTimeoutMs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FeaturedReader::onReadSets() {
|
||||||
|
auto &sets = Global::RefStickerSets();
|
||||||
|
auto count = Global::FeaturedStickerSetsUnreadCount();
|
||||||
|
QVector<MTPlong> wrappedIds;
|
||||||
|
wrappedIds.reserve(_setIds.size());
|
||||||
|
for_const (auto setId, _setIds) {
|
||||||
|
auto it = sets.find(setId);
|
||||||
|
if (it != sets.cend()) {
|
||||||
|
it->flags &= ~MTPDstickerSet_ClientFlag::f_unread;
|
||||||
|
wrappedIds.append(MTP_long(setId));
|
||||||
|
if (count) {
|
||||||
|
--count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_setIds.clear();
|
||||||
|
|
||||||
|
if (!wrappedIds.empty()) {
|
||||||
|
MTP::send(MTPmessages_ReadFeaturedStickers(MTP_vector<MTPlong>(wrappedIds)), rpcDone(&readFeaturedDone));
|
||||||
|
Global::SetFeaturedStickerSetsUnreadCount(count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
} // namespace Stickers
|
} // namespace Stickers
|
||||||
|
|
|
@ -25,5 +25,25 @@ namespace Stickers {
|
||||||
void applyArchivedResult(const MTPDmessages_stickerSetInstallResultArchive &d);
|
void applyArchivedResult(const MTPDmessages_stickerSetInstallResultArchive &d);
|
||||||
void installLocally(uint64 setId);
|
void installLocally(uint64 setId);
|
||||||
void undoInstallLocally(uint64 setId);
|
void undoInstallLocally(uint64 setId);
|
||||||
|
void markFeaturedAsRead(uint64 setId);
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
class FeaturedReader : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
FeaturedReader(QObject *parent);
|
||||||
|
void scheduleRead(uint64 setId);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onReadSets();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QTimer *_timer;
|
||||||
|
OrderedSet<uint64> _setIds;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
} // namespace Stickers
|
} // namespace Stickers
|
||||||
|
|
|
@ -37,3 +37,24 @@ featuredStickersAdd: RoundButton(defaultActiveButton) {
|
||||||
textTop: 4px;
|
textTop: 4px;
|
||||||
downTextTop: 5px;
|
downTextTop: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stickerEmojiSkip: 5px;
|
||||||
|
|
||||||
|
stickersAddIcon: icon {
|
||||||
|
{ "stickers_add", #ffffff },
|
||||||
|
};
|
||||||
|
stickersAddSize: size(30px, 24px);
|
||||||
|
|
||||||
|
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 }
|
||||||
|
};
|
||||||
|
|
|
@ -1155,7 +1155,9 @@ void DocumentData::setattributes(const QVector<MTPDocumentAttribute> &attributes
|
||||||
}
|
}
|
||||||
if (sticker()) {
|
if (sticker()) {
|
||||||
sticker()->alt = qs(d.valt);
|
sticker()->alt = qs(d.valt);
|
||||||
sticker()->set = d.vstickerset;
|
if (sticker()->set.type() != mtpc_inputStickerSetID || d.vstickerset.type() == mtpc_inputStickerSetID) {
|
||||||
|
sticker()->set = d.vstickerset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case mtpc_documentAttributeVideo: {
|
case mtpc_documentAttributeVideo: {
|
||||||
|
|
|
@ -1029,12 +1029,10 @@ struct DocumentAdditionalData {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StickerData : public DocumentAdditionalData {
|
struct StickerData : public DocumentAdditionalData {
|
||||||
StickerData() : set(MTP_inputStickerSetEmpty()) {
|
|
||||||
}
|
|
||||||
ImagePtr img;
|
ImagePtr img;
|
||||||
QString alt;
|
QString alt;
|
||||||
|
|
||||||
MTPInputStickerSet set;
|
MTPInputStickerSet set = MTP_inputStickerSetEmpty();
|
||||||
bool setInstalled() const;
|
bool setInstalled() const;
|
||||||
|
|
||||||
StorageImageLocation loc; // doc thumb location
|
StorageImageLocation loc; // doc thumb location
|
||||||
|
|
Loading…
Reference in New Issue