2
0
mirror of https://github.com/telegramdesktop/tdesktop synced 2025-08-30 22:16:14 +00:00

sticker packs done

This commit is contained in:
John Preston
2015-05-19 18:46:45 +03:00
parent 136fd5c8e1
commit 92858dc7d3
39 changed files with 2312 additions and 702 deletions

View File

@@ -701,6 +701,13 @@ void HistoryList::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
_menu->addAction(lang(lng_context_reply_msg), historyWidget, SLOT(onReplyToMessage()));
}
if (item && !isUponSelected && !_contextMenuLnk) {
if (HistorySticker *sticker = dynamic_cast<HistorySticker*>(msg->getMedia())) {
DocumentData *doc = sticker->document();
if (doc && doc->sticker && doc->sticker->set.type() != mtpc_inputStickerSetEmpty) {
if (!_menu) _menu = new ContextMenu(this);
_menu->addAction(lang(lng_context_pack_info), historyWidget, SLOT(onStickerPackInfo()));
}
}
QString contextMenuText = item->selectedText(FullItemSel);
if (!contextMenuText.isEmpty() && (!msg || !msg->getMedia() || msg->getMedia()->type() != MediaTypeSticker)) {
if (!_menu) _menu = new ContextMenu(this);
@@ -771,7 +778,9 @@ void HistoryList::onMenuDestroy(QObject *obj) {
}
void HistoryList::copySelectedText() {
QApplication::clipboard()->setText(getSelectedText());
QString sel = getSelectedText();
DEBUG_LOG(("Setting selected text to clipboard: %1").arg(sel));
QApplication::clipboard()->setText(sel);
}
void HistoryList::openContextUrl() {
@@ -784,6 +793,7 @@ void HistoryList::openContextUrl() {
void HistoryList::copyContextUrl() {
QString enc = _contextMenuLnk->encoded();
if (!enc.isEmpty()) {
DEBUG_LOG(("Setting text to clipboard from context url: %1").arg(enc));
QApplication::clipboard()->setText(enc);
}
}
@@ -857,6 +867,7 @@ void HistoryList::copyContextText() {
QString contextMenuText = item->selectedText(FullItemSel);
if (!contextMenuText.isEmpty()) {
DEBUG_LOG(("Setting text to clipboard from context menu: %1").arg(contextMenuText));
QApplication::clipboard()->setText(contextMenuText);
}
}
@@ -1569,7 +1580,6 @@ HistoryWidget::HistoryWidget(QWidget *parent) : QWidget(parent)
, _previewCancelled(false)
, _replyForwardPressed(false)
, _replyReturn(0)
, _lastStickersUpdate(0)
, _stickersUpdateRequest(0)
, _loadingMessages(false)
, histRequestsCount(0)
@@ -1687,6 +1697,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : QWidget(parent)
}
void HistoryWidget::start() {
connect(App::main(), SIGNAL(stickersUpdated()), &_emojiPan, SLOT(refreshStickers()));
updateRecentStickers();
connect(App::api(), SIGNAL(fullPeerLoaded(PeerData*)), this, SLOT(onPeerLoaded(PeerData*)));
}
@@ -1766,6 +1777,10 @@ void HistoryWidget::updateRecentStickers() {
_emojiPan.refreshStickers();
}
void HistoryWidget::stickersInstalled(uint64 setId) {
_emojiPan.stickersInstalled(setId);
}
void HistoryWidget::typingDone(const MTPBool &result, mtpRequestId req) {
if (_typingRequest == req) {
_typingRequest = 0;
@@ -1795,116 +1810,210 @@ void HistoryWidget::activate() {
}
void HistoryWidget::updateStickers() {
if (_lastStickersUpdate && getms(true) < _lastStickersUpdate + StickersUpdateTimeout) return;
if (cLastStickersUpdate() && getms(true) < cLastStickersUpdate() + StickersUpdateTimeout) return;
if (_stickersUpdateRequest) return;
_stickersUpdateRequest = MTP::send(MTPmessages_GetAllStickers(MTP_string(cStickersHash())), rpcDone(&HistoryWidget::stickersGot), rpcFail(&HistoryWidget::stickersFailed));
}
void HistoryWidget::stickersGot(const MTPmessages_AllStickers &stickers) {
_lastStickersUpdate = getms(true);
cSetLastStickersUpdate(getms(true));
_stickersUpdateRequest = 0;
if (stickers.type() == mtpc_messages_allStickers) {
const MTPDmessages_allStickers &d(stickers.c_messages_allStickers());
if (stickers.type() != mtpc_messages_allStickers) return;
const MTPDmessages_allStickers &d(stickers.c_messages_allStickers());
EmojiStickersMap map;
AllStickers all;
EmojiStickersMap map;
const QVector<MTPDocument> &d_docs(d.vdocuments.c_vector().v);
const QVector<MTPStickerSet> &d_sets(d.vsets.c_vector().v);
const QVector<MTPDocument> &docs(d.vdocuments.c_vector().v);
QByteArray wasHash = cStickersHash();
cSetStickersHash(qba(d.vhash));
QSet<DocumentData*> found;
const RecentStickerPack &recent(cRecentStickers());
RecentStickerPack add;
add.reserve(docs.size());
ushort addValue = recent.isEmpty() ? 1 : qAbs(recent.front().second);
for (int32 i = 0, l = docs.size(); i < l; ++i) {
DocumentData *doc = App::feedDocument(docs.at(i));
if (!doc) continue;
int32 j = 0, s = recent.size();
for (; j < s; ++j) {
if (doc == recent.at(j).first) {
StickerSets &sets(cRefStickerSets());
StickerSets::iterator def = sets.find(DefaultStickerSetId);
if (def == sets.cend()) {
def = sets.insert(DefaultStickerSetId, StickerSet(DefaultStickerSetId, 0, qsl("Great Minds"), QString()));
}
for (int32 i = 0; i < d_sets.size(); ++i) {
if (d_sets.at(i).type() == mtpc_stickerSet) {
const MTPDstickerSet &set(d_sets.at(i).c_stickerSet());
StickerSets::iterator i = sets.find(set.vid.v);
if (i == sets.cend()) {
i = sets.insert(set.vid.v, StickerSet(set.vid.v, set.vaccess_hash.v, qs(set.vtitle), qs(set.vshort_name)));
} else {
i->access = set.vaccess_hash.v;
i->title = qs(set.vtitle);
i->shortName = qs(set.vshort_name);
}
}
}
StickerSets::iterator custom = sets.find(CustomStickerSetId);
bool added = false, removed = false;
QSet<DocumentData*> found;
QMap<uint64, int32> wasCount;
for (int32 i = 0, l = d_docs.size(); i < l; ++i) {
DocumentData *doc = App::feedDocument(d_docs.at(i));
if (!doc || !doc->sticker) continue;
switch (doc->sticker->set.type()) {
case mtpc_inputStickerSetEmpty: { // default set - great minds
if (!wasCount.contains(DefaultStickerSetId)) wasCount.insert(DefaultStickerSetId, def->stickers.size());
if (def->stickers.indexOf(doc) < 0) {
def->stickers.push_back(doc);
added = true;
} else {
found.insert(doc);
}
} break;
case mtpc_inputStickerSetID: {
StickerSets::iterator it = sets.find(doc->sticker->set.c_inputStickerSetID().vid.v);
if (it == sets.cend()) {
LOG(("Sticker Set not found by ID: %1").arg(doc->sticker->set.c_inputStickerSetID().vid.v));
} else {
if (!wasCount.contains(it->id)) wasCount.insert(it->id, it->stickers.size());
if (it->stickers.indexOf(doc) < 0) {
it->stickers.push_back(doc);
added = true;
} else {
found.insert(doc);
}
}
} break;
case mtpc_inputStickerSetShortName: {
QString name = qs(doc->sticker->set.c_inputStickerSetShortName().vshort_name).toLower().trimmed();
StickerSets::iterator it = sets.begin();
for (; it != sets.cend(); ++it) {
if (it->shortName.toLower().trimmed() == name) {
break;
}
}
if (j < s) continue;
add.push_back(qMakePair(doc, addValue));
if (it == sets.cend()) {
LOG(("Sticker Set not found by name: %1").arg(name));
} else {
if (!wasCount.contains(it->id)) wasCount.insert(it->id, it->stickers.size());
if (it->stickers.indexOf(doc) < 0) {
it->stickers.push_back(doc);
added = true;
} else {
found.insert(doc);
}
}
} break;
}
bool needRemove = false;
for (int32 i = 0, l = recent.size(); i < l; ++i) {
if (recent.at(i).second > 0 && !found.contains(recent.at(i).first)) {
needRemove = true;
break;
if (custom != sets.cend()) {
int32 index = custom->stickers.indexOf(doc);
if (index >= 0) {
custom->stickers.removeAt(index);
removed = true;
}
}
if (!add.isEmpty() || needRemove) {
if (needRemove) {
for (int32 i = 0, l = recent.size(); i < l; ++i) {
if (recent.at(i).second <= 0 || found.contains(recent.at(i).first)) {
add.push_back(recent.at(i));
}
if (custom != sets.cend() && custom->stickers.isEmpty()) {
sets.erase(custom);
custom = sets.end();
}
bool writeRecent = false;
RecentStickerPack &recent(cGetRecentStickers());
for (StickerSets::iterator it = sets.begin(); it != sets.cend();) {
if (it->id == CustomStickerSetId || it->id == RecentStickerSetId) {
++it;
continue;
}
QMap<uint64, int32>::const_iterator was = wasCount.constFind(it->id);
if (was == wasCount.cend()) { // no such stickers added
for (RecentStickerPack::iterator i = recent.begin(); i != recent.cend();) {
if (it->stickers.indexOf(i->first) >= 0) {
i = recent.erase(i);
writeRecent = true;
} else {
++i;
}
}
it = sets.erase(it);
removed = true;
} else {
for (int32 j = 0, l = was.value(); j < l;) {
if (found.contains(it->stickers.at(j))) {
++j;
} else {
for (RecentStickerPack::iterator i = recent.begin(); i != recent.cend();) {
if (it->stickers.at(j) == i->first) {
i = recent.erase(i);
writeRecent = true;
} else {
++i;
}
}
it->stickers.removeAt(j);
--l;
removed = true;
}
}
if (it->stickers.isEmpty()) {
it = sets.erase(it);
} else {
++it;
}
}
}
if (added || removed || cStickersHash() != wasHash) {
Local::writeStickers();
}
if (writeRecent) {
Local::writeUserSettings();
}
const QVector<MTPStickerPack> &packs(d.vpacks.c_vector().v);
for (int32 i = 0, l = packs.size(); i < l; ++i) {
if (packs.at(i).type() == mtpc_stickerPack) {
const MTPDstickerPack &p(packs.at(i).c_stickerPack());
QString emoticon(qs(p.vemoticon));
EmojiPtr e = 0;
for (const QChar *ch = emoticon.constData(), *end = emoticon.constEnd(); ch != end; ++ch) {
int len = 0;
e = emojiFromText(ch, end, len);
if (e) break;
if (ch + 1 < end && ch->isHighSurrogate() && (ch + 1)->isLowSurrogate()) ++ch;
}
if (e) {
const QVector<MTPlong> docs(p.vdocuments.c_vector().v);
if (!docs.isEmpty()) {
for (int32 j = 0, s = docs.size(); j < s; ++j) {
DocumentData *doc = App::document(docs.at(j).v);
map.insert(doc, e);
}
}
} else {
add += recent;
}
cSetRecentStickers(add);
Local::writeRecentStickers();
}
const QVector<MTPStickerPack> &packs(d.vpacks.c_vector().v);
for (int32 i = 0, l = packs.size(); i < l; ++i) {
if (packs.at(i).type() == mtpc_stickerPack) {
const MTPDstickerPack &p(packs.at(i).c_stickerPack());
QString emoticon(qs(p.vemoticon));
EmojiPtr e = 0;
for (const QChar *ch = emoticon.constData(), *end = emoticon.constEnd(); ch != end; ++ch) {
int len = 0;
e = emojiFromText(ch, end, len);
if (e) break;
if (ch + 1 < end && ch->isHighSurrogate() && (ch + 1)->isLowSurrogate()) ++ch;
}
if (e) {
const QVector<MTPlong> docs(p.vdocuments.c_vector().v);
if (!docs.isEmpty()) {
StickerPack &pack(all[e]);
pack.reserve(pack.size() + docs.size());
for (int32 j = 0, s = docs.size(); j < s; ++j) {
DocumentData *doc = App::document(docs.at(j).v);
pack.push_back(doc);
map.insert(doc, e);
}
}
} else {
LOG(("Sticker Error: Could not find emoji for string: %1").arg(emoticon));
}
LOG(("Sticker Error: Could not find emoji for string: %1").arg(emoticon));
}
}
cSetStickers(all);
cSetStickersHash(qba(d.vhash));
cSetEmojiStickers(map);
const DocumentItems &items(App::documentItems());
for (EmojiStickersMap::const_iterator i = map.cbegin(), e = map.cend(); i != e; ++i) {
DocumentItems::const_iterator j = items.constFind(i.key());
if (j != items.cend()) {
for (HistoryItemsMap::const_iterator k = j->cbegin(), end = j->cend(); k != end; ++k) {
k.key()->updateStickerEmoji();
}
}
}
// updateStickerPan();
_emojiPan.refreshStickers();
}
cSetEmojiStickers(map);
const DocumentItems &items(App::documentItems());
for (EmojiStickersMap::const_iterator i = map.cbegin(), e = map.cend(); i != e; ++i) {
DocumentItems::const_iterator j = items.constFind(i.key());
if (j != items.cend()) {
for (HistoryItemsMap::const_iterator k = j->cbegin(), end = j->cend(); k != end; ++k) {
k.key()->updateStickerEmoji();
}
}
}
// updateStickerPan();
if (App::main()) emit App::main()->stickersUpdated();
}
bool HistoryWidget::stickersFailed(const RPCError &error) {
if (error.type().startsWith(qsl("FLOOD_WAIT_"))) return false;
_lastStickersUpdate = getms(true);
cSetLastStickersUpdate(getms(true));
_stickersUpdateRequest = 0;
return true;
}
@@ -3683,6 +3792,16 @@ void HistoryWidget::onReplyForwardPreviewCancel() {
}
}
void HistoryWidget::onStickerPackInfo() {
if (HistoryMessage *item = dynamic_cast<HistoryMessage*>(App::contextItem())) {
if (HistorySticker *sticker = dynamic_cast<HistorySticker*>(item->getMedia())) {
if (sticker->document() && sticker->document()->sticker && sticker->document()->sticker->set.type() != mtpc_inputStickerSetEmpty) {
App::main()->stickersBox(sticker->document()->sticker->set);
}
}
}
}
void HistoryWidget::previewCancel() {
MTP::cancel(_previewRequest);
_previewRequest = 0;