mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +02:00
Check test/production DC in recent emoji.
This commit is contained in:
parent
323c2a6aa5
commit
240b47da86
6 changed files with 127 additions and 52 deletions
|
@ -40,6 +40,9 @@ namespace {
|
|||
|
||||
constexpr auto kFakeEmojiDocumentIdBase = 0x7777'FFFF'FFFF'0000ULL;
|
||||
|
||||
using Core::RecentEmojiId;
|
||||
using Core::RecentEmojiDocument;
|
||||
|
||||
[[nodiscard]] DocumentId FakeEmojiDocumentId(EmojiPtr emoji) {
|
||||
return kFakeEmojiDocumentIdBase + emoji->index();
|
||||
}
|
||||
|
@ -177,6 +180,11 @@ struct EmojiListWidget::CustomInstance {
|
|||
bool recentOnly = false;
|
||||
};
|
||||
|
||||
struct EmojiListWidget::RecentOne {
|
||||
not_null<CustomInstance*> instance;
|
||||
RecentEmojiId id;
|
||||
};
|
||||
|
||||
EmojiListWidget::CustomInstance::CustomInstance(
|
||||
std::unique_ptr<Ui::CustomEmoji::Loader> loader,
|
||||
Fn<void(
|
||||
|
@ -435,11 +443,9 @@ EmojiListWidget::EmojiListWidget(
|
|||
|
||||
_esize = Ui::Emoji::GetSizeLarge();
|
||||
|
||||
for (auto i = 0; i != kEmojiSectionCount; ++i) {
|
||||
for (auto i = 1; i != kEmojiSectionCount; ++i) {
|
||||
const auto section = static_cast<Section>(i);
|
||||
_counts[i] = (section == Section::Recent)
|
||||
? int(Core::App().settings().recentEmoji().size())
|
||||
: Ui::Emoji::GetSectionCount(section);
|
||||
_counts[i] = Ui::Emoji::GetSectionCount(section);
|
||||
}
|
||||
|
||||
_picker->chosen(
|
||||
|
@ -646,7 +652,7 @@ bool EmojiListWidget::enumerateSections(Callback callback) const {
|
|||
};
|
||||
for (; i != kEmojiSectionCount; ++i) {
|
||||
info.section = i;
|
||||
info.count = _counts[i];
|
||||
info.count = i ? _counts[i] : _recent.size();
|
||||
if (!next()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -752,17 +758,24 @@ void EmojiListWidget::fillRecent() {
|
|||
_recentCustomIds.clear();
|
||||
|
||||
const auto &list = Core::App().settings().recentEmoji();
|
||||
_recent.reserve(list.size());
|
||||
_recent.reserve(std::min(int(list.size()), Core::kRecentEmojiLimit));
|
||||
const auto test = controller()->session().isTestMode();
|
||||
for (const auto &one : list) {
|
||||
const auto document = std::get_if<RecentEmojiDocument>(&one.id.data);
|
||||
if (document && document->test != test) {
|
||||
continue;
|
||||
}
|
||||
_recent.push_back({
|
||||
.instance = resolveCustomInstance(one.id.data),
|
||||
.id = one.id.data,
|
||||
.instance = resolveCustomInstance(one.id),
|
||||
.id = one.id,
|
||||
});
|
||||
if (const auto documentId = std::get_if<DocumentId>(&one.id.data)) {
|
||||
_recentCustomIds.emplace(*documentId);
|
||||
if (document) {
|
||||
_recentCustomIds.emplace(document->id);
|
||||
}
|
||||
if (_recent.size() >= Core::kRecentEmojiLimit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
_counts[0] = _recent.size();
|
||||
}
|
||||
|
||||
void EmojiListWidget::paintEvent(QPaintEvent *e) {
|
||||
|
@ -962,8 +975,8 @@ EmojiPtr EmojiListWidget::lookupOverEmoji(const OverEmoji *over) const {
|
|||
const auto index = over ? over->index : -1;
|
||||
return (section == int(Section::Recent)
|
||||
&& index < _recent.size()
|
||||
&& v::is<EmojiPtr>(_recent[index].id))
|
||||
? v::get<EmojiPtr>(_recent[index].id)
|
||||
&& v::is<EmojiPtr>(_recent[index].id.data))
|
||||
? v::get<EmojiPtr>(_recent[index].id.data)
|
||||
: (section > int(Section::Recent)
|
||||
&& section < kEmojiSectionCount
|
||||
&& index < _emoji[section].size())
|
||||
|
@ -1033,12 +1046,13 @@ void EmojiListWidget::mouseReleaseEvent(QMouseEvent *e) {
|
|||
selectEmoji(emoji);
|
||||
} else if (section == int(Section::Recent)
|
||||
&& index < _recent.size()) {
|
||||
const auto id = std::get_if<DocumentId>(&_recent[index].id);
|
||||
const auto document = id
|
||||
? session().data().document(*id).get()
|
||||
const auto document = std::get_if<RecentEmojiDocument>(
|
||||
&_recent[index].id.data);
|
||||
const auto custom = document
|
||||
? session().data().document(document->id).get()
|
||||
: nullptr;
|
||||
if (document && document->sticker()) {
|
||||
selectCustom(document);
|
||||
if (custom && custom->sticker()) {
|
||||
selectCustom(custom);
|
||||
}
|
||||
} else if (section >= kEmojiSectionCount
|
||||
&& index < _custom[section - kEmojiSectionCount].list.size()) {
|
||||
|
@ -1086,7 +1100,10 @@ void EmojiListWidget::selectCustom(not_null<DocumentData*> document) {
|
|||
PremiumPreview::AnimatedEmoji);
|
||||
return;
|
||||
}
|
||||
Core::App().settings().incrementRecentEmoji({ document->id });
|
||||
Core::App().settings().incrementRecentEmoji({ RecentEmojiDocument{
|
||||
document->id,
|
||||
document->session().isTestMode(),
|
||||
} });
|
||||
_customChosen.fire({ .document = document });
|
||||
}
|
||||
|
||||
|
@ -1381,11 +1398,12 @@ auto EmojiListWidget::resolveCustomInstance(
|
|||
}
|
||||
|
||||
auto EmojiListWidget::resolveCustomInstance(
|
||||
std::variant<EmojiPtr, DocumentId> customId)
|
||||
RecentEmojiId customId)
|
||||
-> not_null<CustomInstance*> {
|
||||
if (const auto documentId = std::get_if<DocumentId>(&customId)) {
|
||||
return resolveCustomInstance(*documentId);
|
||||
} else if (const auto emoji = std::get_if<EmojiPtr>(&customId)) {
|
||||
const auto &data = customId.data;
|
||||
if (const auto document = std::get_if<RecentEmojiDocument>(&data)) {
|
||||
return resolveCustomInstance(document->id);
|
||||
} else if (const auto emoji = std::get_if<EmojiPtr>(&data)) {
|
||||
return resolveCustomInstance(FakeEmojiDocumentId(*emoji), *emoji);
|
||||
}
|
||||
Unexpected("Custom recent emoji id.");
|
||||
|
|
|
@ -11,6 +11,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/widgets/tooltip.h"
|
||||
#include "base/timer.h"
|
||||
|
||||
namespace Core {
|
||||
struct RecentEmojiId;
|
||||
} // namespace Core
|
||||
|
||||
namespace Data {
|
||||
class StickersSet;
|
||||
} // namespace Data
|
||||
|
@ -119,10 +123,7 @@ private:
|
|||
bool painted = false;
|
||||
bool premium = false;
|
||||
};
|
||||
struct RecentOne {
|
||||
not_null<CustomInstance*> instance;
|
||||
std::variant<EmojiPtr, DocumentId> id;
|
||||
};
|
||||
struct RecentOne;
|
||||
struct RepaintSet {
|
||||
base::flat_set<uint64> ids;
|
||||
crl::time when = 0;
|
||||
|
@ -234,7 +235,7 @@ private:
|
|||
not_null<DocumentData*> document,
|
||||
uint64 setId);
|
||||
[[nodiscard]] not_null<CustomInstance*> resolveCustomInstance(
|
||||
std::variant<EmojiPtr, DocumentId> customId);
|
||||
Core::RecentEmojiId customId);
|
||||
[[nodiscard]] not_null<CustomInstance*> resolveCustomInstance(
|
||||
DocumentId fakeId,
|
||||
EmojiPtr emoji);
|
||||
|
|
|
@ -22,8 +22,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
namespace Core {
|
||||
namespace {
|
||||
|
||||
constexpr auto kRecentEmojiLimit = 42;
|
||||
|
||||
[[nodiscard]] WindowPosition Deserialize(const QByteArray &data) {
|
||||
QDataStream stream(data);
|
||||
stream.setVersion(QDataStream::Qt_5_1);
|
||||
|
@ -67,6 +65,24 @@ constexpr auto kRecentEmojiLimit = 42;
|
|||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] QString Serialize(RecentEmojiDocument document) {
|
||||
return u"%1-%2"_q.arg(document.id).arg(document.test ? 1 : 0);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::optional<RecentEmojiDocument> ParseRecentEmojiDocument(
|
||||
const QString &serialized) {
|
||||
const auto parts = QStringView(serialized).split('-');
|
||||
if (parts.size() != 2 || parts[1].size() != 1) {
|
||||
return {};
|
||||
}
|
||||
const auto id = parts[0].toULongLong();
|
||||
const auto test = parts[1][0];
|
||||
if (!id || (test != '0' && test != '1')) {
|
||||
return {};
|
||||
}
|
||||
return RecentEmojiDocument{ id, (test == '1') };
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Settings::Settings()
|
||||
|
@ -86,8 +102,9 @@ QByteArray Settings::serialize() const {
|
|||
recentEmojiPreloadGenerated.reserve(_recentEmoji.size());
|
||||
for (const auto &[id, rating] : _recentEmoji) {
|
||||
auto string = QString();
|
||||
if (const auto documentId = std::get_if<DocumentId>(&id.data)) {
|
||||
string = QString::number(*documentId);
|
||||
if (const auto document = std::get_if<RecentEmojiDocument>(
|
||||
&id.data)) {
|
||||
string = Serialize(*document);
|
||||
} else if (const auto emoji = std::get_if<EmojiPtr>(&id.data)) {
|
||||
string = (*emoji)->id();
|
||||
}
|
||||
|
@ -788,7 +805,7 @@ rpl::producer<int> Settings::thirdColumnWidthChanges() const {
|
|||
return _thirdColumnWidth.changes();
|
||||
}
|
||||
|
||||
const std::vector<Settings::RecentEmoji> &Settings::recentEmoji() const {
|
||||
const std::vector<RecentEmoji> &Settings::recentEmoji() const {
|
||||
if (_recentEmoji.empty()) {
|
||||
resolveRecentEmoji();
|
||||
}
|
||||
|
@ -802,6 +819,8 @@ void Settings::resolveRecentEmoji() const {
|
|||
id,
|
||||
[](const RecentEmoji &data) { return data.id; });
|
||||
};
|
||||
auto testCount = 0;
|
||||
auto nonTestCount = 0;
|
||||
if (!_recentEmojiPreload.empty()) {
|
||||
_recentEmoji.reserve(_recentEmojiPreload.size());
|
||||
for (const auto &[id, rating] : base::take(_recentEmojiPreload)) {
|
||||
|
@ -811,16 +830,22 @@ void Settings::resolveRecentEmoji() const {
|
|||
if (!haveAlready({ emoji })) {
|
||||
_recentEmoji.push_back({ { emoji }, rating });
|
||||
}
|
||||
} else if (const auto documentId = id.toULongLong()) {
|
||||
if (!haveAlready({ documentId })) {
|
||||
_recentEmoji.push_back({ { documentId }, rating });
|
||||
} else if (const auto document = ParseRecentEmojiDocument(id)) {
|
||||
if (!haveAlready({ *document })) {
|
||||
_recentEmoji.push_back({ { *document }, rating });
|
||||
if (document->test) {
|
||||
++testCount;
|
||||
} else {
|
||||
++nonTestCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_recentEmojiPreload.clear();
|
||||
}
|
||||
const auto specialCount = std::max(testCount, nonTestCount);
|
||||
for (const auto emoji : Ui::Emoji::GetDefaultRecent()) {
|
||||
if (_recentEmoji.size() >= kRecentEmojiLimit) {
|
||||
if (_recentEmoji.size() >= specialCount + kRecentEmojiLimit) {
|
||||
break;
|
||||
} else if (!haveAlready({ emoji })) {
|
||||
_recentEmoji.push_back({ { emoji }, 1 });
|
||||
|
@ -854,9 +879,6 @@ void Settings::incrementRecentEmoji(RecentEmojiId id) {
|
|||
}
|
||||
}
|
||||
if (i == e) {
|
||||
while (_recentEmoji.size() >= kRecentEmojiLimit) {
|
||||
_recentEmoji.pop_back();
|
||||
}
|
||||
_recentEmoji.push_back({ id, 1 });
|
||||
for (i = _recentEmoji.end() - 1; i != _recentEmoji.begin(); --i) {
|
||||
if ((i - 1)->rating > i->rating) {
|
||||
|
@ -864,6 +886,22 @@ void Settings::incrementRecentEmoji(RecentEmojiId id) {
|
|||
}
|
||||
std::swap(*i, *(i - 1));
|
||||
}
|
||||
auto testCount = 0;
|
||||
auto nonTestCount = 0;
|
||||
for (const auto &emoji : _recentEmoji) {
|
||||
const auto id = &emoji.id.data;
|
||||
if (const auto document = std::get_if<RecentEmojiDocument>(id)) {
|
||||
if (document->test) {
|
||||
++testCount;
|
||||
} else {
|
||||
++nonTestCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
const auto specialCount = std::max(testCount, nonTestCount);
|
||||
while (_recentEmoji.size() >= specialCount + kRecentEmojiLimit) {
|
||||
_recentEmoji.pop_back();
|
||||
}
|
||||
}
|
||||
_recentEmojiUpdated.fire({});
|
||||
_saveDelayed.fire({});
|
||||
|
|
|
@ -53,6 +53,30 @@ struct WindowPosition {
|
|||
int h = 0;
|
||||
};
|
||||
|
||||
constexpr auto kRecentEmojiLimit = 42;
|
||||
|
||||
struct RecentEmojiDocument {
|
||||
DocumentId id = 0;
|
||||
bool test = false;
|
||||
|
||||
friend inline auto operator<=>(
|
||||
RecentEmojiDocument,
|
||||
RecentEmojiDocument) = default;
|
||||
};
|
||||
|
||||
struct RecentEmojiId {
|
||||
std::variant<EmojiPtr, RecentEmojiDocument> data;
|
||||
|
||||
friend inline auto operator<=>(
|
||||
RecentEmojiId,
|
||||
RecentEmojiId) = default;
|
||||
};
|
||||
|
||||
struct RecentEmoji {
|
||||
RecentEmojiId id;
|
||||
ushort rating = 0;
|
||||
};
|
||||
|
||||
class Settings final {
|
||||
public:
|
||||
enum class ScreenCorner {
|
||||
|
@ -573,17 +597,6 @@ public:
|
|||
return _workMode.changes();
|
||||
}
|
||||
|
||||
struct RecentEmojiId {
|
||||
std::variant<EmojiPtr, DocumentId> data;
|
||||
|
||||
friend inline auto operator<=>(
|
||||
RecentEmojiId,
|
||||
RecentEmojiId) = default;
|
||||
};
|
||||
struct RecentEmoji {
|
||||
RecentEmojiId id;
|
||||
ushort rating = 0;
|
||||
};
|
||||
[[nodiscard]] const std::vector<RecentEmoji> &recentEmoji() const;
|
||||
void incrementRecentEmoji(RecentEmojiId id);
|
||||
void setLegacyRecentEmojiPreload(QVector<QPair<QString, ushort>> data);
|
||||
|
|
|
@ -258,10 +258,14 @@ rpl::producer<bool> Session::premiumPossibleValue() const {
|
|||
_1 || _2);
|
||||
}
|
||||
|
||||
bool Session::isTestMode() const {
|
||||
return mtp().isTestMode();
|
||||
}
|
||||
|
||||
uint64 Session::uniqueId() const {
|
||||
// See also Account::willHaveSessionUniqueId.
|
||||
return userId().bare
|
||||
| (mtp().isTestMode() ? 0x0100'0000'0000'0000ULL : 0ULL);
|
||||
| (isTestMode() ? 0x0100'0000'0000'0000ULL : 0ULL);
|
||||
}
|
||||
|
||||
UserId Session::userId() const {
|
||||
|
|
|
@ -86,6 +86,7 @@ public:
|
|||
[[nodiscard]] rpl::producer<bool> premiumPossibleValue() const;
|
||||
[[nodiscard]] bool premiumBadgesShown() const;
|
||||
|
||||
[[nodiscard]] bool isTestMode() const;
|
||||
[[nodiscard]] uint64 uniqueId() const; // userId() with TestDC shift.
|
||||
[[nodiscard]] UserId userId() const;
|
||||
[[nodiscard]] PeerId userPeerId() const;
|
||||
|
|
Loading…
Add table
Reference in a new issue