mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Update API scheme to layer 198.
This commit is contained in:
parent
37d32b32f8
commit
d0132c0f7b
25 changed files with 251 additions and 114 deletions
|
@ -283,6 +283,7 @@ mtpRequestId EditTextMessage(
|
||||||
return MTP_inputMediaDocument(
|
return MTP_inputMediaDocument(
|
||||||
MTP_flags(flags),
|
MTP_flags(flags),
|
||||||
document->mtpInput(),
|
document->mtpInput(),
|
||||||
|
MTPInputPhoto(), // video_cover
|
||||||
MTP_int(media->ttlSeconds()),
|
MTP_int(media->ttlSeconds()),
|
||||||
MTPstring()); // query
|
MTPstring()); // query
|
||||||
};
|
};
|
||||||
|
|
|
@ -121,6 +121,7 @@ MTPInputMedia PrepareUploadedDocument(
|
||||||
ComposeSendingDocumentAttributes(document),
|
ComposeSendingDocumentAttributes(document),
|
||||||
MTP_vector<MTPInputDocument>(
|
MTP_vector<MTPInputDocument>(
|
||||||
ranges::to<QVector<MTPInputDocument>>(info.attachedStickers)),
|
ranges::to<QVector<MTPInputDocument>>(info.attachedStickers)),
|
||||||
|
MTPInputPhoto(), // video_cover
|
||||||
MTP_int(ttlSeconds));
|
MTP_int(ttlSeconds));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -272,6 +272,7 @@ void SendExistingDocument(
|
||||||
return MTP_inputMediaDocument(
|
return MTP_inputMediaDocument(
|
||||||
MTP_flags(0),
|
MTP_flags(0),
|
||||||
document->mtpInput(),
|
document->mtpInput(),
|
||||||
|
MTPInputPhoto(), // video_cover
|
||||||
MTPint(), // ttl_seconds
|
MTPint(), // ttl_seconds
|
||||||
MTPstring()); // query
|
MTPstring()); // query
|
||||||
};
|
};
|
||||||
|
@ -550,6 +551,7 @@ void SendConfirmedFile(
|
||||||
| (file->spoiler ? Flag::f_spoiler : Flag())),
|
| (file->spoiler ? Flag::f_spoiler : Flag())),
|
||||||
file->document,
|
file->document,
|
||||||
MTPVector<MTPDocument>(), // alt_documents
|
MTPVector<MTPDocument>(), // alt_documents
|
||||||
|
MTPPhoto(), // video_cover
|
||||||
MTPint());
|
MTPint());
|
||||||
} else if (file->type == SendMediaType::Audio) {
|
} else if (file->type == SendMediaType::Audio) {
|
||||||
const auto ttlSeconds = file->to.options.ttlSeconds;
|
const auto ttlSeconds = file->to.options.ttlSeconds;
|
||||||
|
@ -560,6 +562,7 @@ void SendConfirmedFile(
|
||||||
| (ttlSeconds ? Flag::f_ttl_seconds : Flag())),
|
| (ttlSeconds ? Flag::f_ttl_seconds : Flag())),
|
||||||
file->document,
|
file->document,
|
||||||
MTPVector<MTPDocument>(), // alt_documents
|
MTPVector<MTPDocument>(), // alt_documents
|
||||||
|
MTPPhoto(), // video_cover
|
||||||
MTP_int(ttlSeconds));
|
MTP_int(ttlSeconds));
|
||||||
} else if (file->type == SendMediaType::Round) {
|
} else if (file->type == SendMediaType::Round) {
|
||||||
using Flag = MTPDmessageMediaDocument::Flag;
|
using Flag = MTPDmessageMediaDocument::Flag;
|
||||||
|
@ -571,6 +574,7 @@ void SendConfirmedFile(
|
||||||
| (file->spoiler ? Flag::f_spoiler : Flag())),
|
| (file->spoiler ? Flag::f_spoiler : Flag())),
|
||||||
file->document,
|
file->document,
|
||||||
MTPVector<MTPDocument>(), // alt_documents
|
MTPVector<MTPDocument>(), // alt_documents
|
||||||
|
MTPPhoto(), // video_cover
|
||||||
MTP_int(ttlSeconds));
|
MTP_int(ttlSeconds));
|
||||||
} else {
|
} else {
|
||||||
Unexpected("Type in sendFilesConfirmed.");
|
Unexpected("Type in sendFilesConfirmed.");
|
||||||
|
|
|
@ -4146,6 +4146,7 @@ void ApiWrap::uploadAlbumMedia(
|
||||||
fields.vid(),
|
fields.vid(),
|
||||||
fields.vaccess_hash(),
|
fields.vaccess_hash(),
|
||||||
fields.vfile_reference()),
|
fields.vfile_reference()),
|
||||||
|
MTPInputPhoto(), // video_cover
|
||||||
MTP_int(data.vttl_seconds().value_or_empty()),
|
MTP_int(data.vttl_seconds().value_or_empty()),
|
||||||
MTPstring()); // query
|
MTPstring()); // query
|
||||||
sendAlbumWithUploaded(item, groupId, media);
|
sendAlbumWithUploaded(item, groupId, media);
|
||||||
|
|
|
@ -526,7 +526,7 @@ void LevelBadge::paintEvent(QPaintEvent *e) {
|
||||||
struct SetValues {
|
struct SetValues {
|
||||||
uint8 colorIndex = 0;
|
uint8 colorIndex = 0;
|
||||||
DocumentId backgroundEmojiId = 0;
|
DocumentId backgroundEmojiId = 0;
|
||||||
DocumentId statusId = 0;
|
EmojiStatusId statusId;
|
||||||
TimeId statusUntil = 0;
|
TimeId statusUntil = 0;
|
||||||
bool statusChanged = false;
|
bool statusChanged = false;
|
||||||
};
|
};
|
||||||
|
@ -808,7 +808,7 @@ int ColorSelector::resizeGetHeight(int newWidth) {
|
||||||
const auto state = right->lifetime().make_state<State>();
|
const auto state = right->lifetime().make_state<State>();
|
||||||
state->panel.someCustomChosen(
|
state->panel.someCustomChosen(
|
||||||
) | rpl::start_with_next([=](EmojiStatusPanel::CustomChosen chosen) {
|
) | rpl::start_with_next([=](EmojiStatusPanel::CustomChosen chosen) {
|
||||||
emojiIdChosen(chosen.id);
|
emojiIdChosen(chosen.id.documentId);
|
||||||
}, raw->lifetime());
|
}, raw->lifetime());
|
||||||
|
|
||||||
std::move(colorIndexValue) | rpl::start_with_next([=](uint8 index) {
|
std::move(colorIndexValue) | rpl::start_with_next([=](uint8 index) {
|
||||||
|
@ -901,8 +901,8 @@ int ColorSelector::resizeGetHeight(int newWidth) {
|
||||||
not_null<Ui::RpWidget*> parent,
|
not_null<Ui::RpWidget*> parent,
|
||||||
std::shared_ptr<ChatHelpers::Show> show,
|
std::shared_ptr<ChatHelpers::Show> show,
|
||||||
not_null<ChannelData*> channel,
|
not_null<ChannelData*> channel,
|
||||||
rpl::producer<DocumentId> statusIdValue,
|
rpl::producer<EmojiStatusId> statusIdValue,
|
||||||
Fn<void(DocumentId,TimeId)> statusIdChosen,
|
Fn<void(EmojiStatusId,TimeId)> statusIdChosen,
|
||||||
bool group) {
|
bool group) {
|
||||||
const auto button = ButtonStyleWithRightEmoji(
|
const auto button = ButtonStyleWithRightEmoji(
|
||||||
parent,
|
parent,
|
||||||
|
@ -924,20 +924,24 @@ int ColorSelector::resizeGetHeight(int newWidth) {
|
||||||
struct State {
|
struct State {
|
||||||
EmojiStatusPanel panel;
|
EmojiStatusPanel panel;
|
||||||
std::unique_ptr<Ui::Text::CustomEmoji> emoji;
|
std::unique_ptr<Ui::Text::CustomEmoji> emoji;
|
||||||
DocumentId statusId = 0;
|
EmojiStatusId statusId;
|
||||||
};
|
};
|
||||||
const auto state = right->lifetime().make_state<State>();
|
const auto state = right->lifetime().make_state<State>();
|
||||||
state->panel.someCustomChosen(
|
state->panel.someCustomChosen(
|
||||||
) | rpl::start_with_next([=](EmojiStatusPanel::CustomChosen chosen) {
|
) | rpl::start_with_next([=](EmojiStatusPanel::CustomChosen chosen) {
|
||||||
statusIdChosen(chosen.id, chosen.until);
|
statusIdChosen({ chosen.id }, chosen.until);
|
||||||
}, raw->lifetime());
|
}, raw->lifetime());
|
||||||
|
|
||||||
const auto session = &show->session();
|
const auto session = &show->session();
|
||||||
std::move(statusIdValue) | rpl::start_with_next([=](DocumentId id) {
|
std::move(statusIdValue) | rpl::start_with_next([=](EmojiStatusId id) {
|
||||||
state->statusId = id;
|
state->statusId = id;
|
||||||
state->emoji = id
|
state->emoji = id.collectible // todo collectibles
|
||||||
? session->data().customEmojiManager().create(
|
? session->data().customEmojiManager().create(
|
||||||
id,
|
id.collectible->documentId,
|
||||||
|
[=] { right->update(); })
|
||||||
|
: id.documentId
|
||||||
|
? session->data().customEmojiManager().create(
|
||||||
|
id.documentId,
|
||||||
[=] { right->update(); })
|
[=] { right->update(); })
|
||||||
: nullptr;
|
: nullptr;
|
||||||
right->resize(
|
right->resize(
|
||||||
|
@ -990,7 +994,7 @@ int ColorSelector::resizeGetHeight(int newWidth) {
|
||||||
state->panel.show({
|
state->panel.show({
|
||||||
.controller = controller,
|
.controller = controller,
|
||||||
.button = right,
|
.button = right,
|
||||||
.ensureAddedEmojiId = state->statusId,
|
.ensureAddedEmojiId = state->statusId.documentId,
|
||||||
.channelStatusMode = true,
|
.channelStatusMode = true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1182,7 +1186,7 @@ void EditPeerColorBox(
|
||||||
struct State {
|
struct State {
|
||||||
rpl::variable<uint8> index;
|
rpl::variable<uint8> index;
|
||||||
rpl::variable<DocumentId> emojiId;
|
rpl::variable<DocumentId> emojiId;
|
||||||
rpl::variable<DocumentId> statusId;
|
rpl::variable<EmojiStatusId> statusId;
|
||||||
TimeId statusUntil = 0;
|
TimeId statusUntil = 0;
|
||||||
bool statusChanged = false;
|
bool statusChanged = false;
|
||||||
bool changing = false;
|
bool changing = false;
|
||||||
|
@ -1319,7 +1323,7 @@ void EditPeerColorBox(
|
||||||
show,
|
show,
|
||||||
channel,
|
channel,
|
||||||
state->statusId.value(),
|
state->statusId.value(),
|
||||||
[=](DocumentId id, TimeId until) {
|
[=](EmojiStatusId id, TimeId until) {
|
||||||
state->statusId = id;
|
state->statusId = id;
|
||||||
state->statusUntil = until;
|
state->statusUntil = until;
|
||||||
state->statusChanged = true;
|
state->statusChanged = true;
|
||||||
|
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
|
#include "data/data_wall_paper.h"
|
||||||
#include "data/stickers/data_stickers.h"
|
#include "data/stickers/data_stickers.h"
|
||||||
#include "base/unixtime.h"
|
#include "base/unixtime.h"
|
||||||
#include "base/timer_rpl.h"
|
#include "base/timer_rpl.h"
|
||||||
|
@ -26,20 +27,19 @@ constexpr auto kRefreshDefaultListEach = 60 * 60 * crl::time(1000);
|
||||||
constexpr auto kRecentRequestTimeout = 10 * crl::time(1000);
|
constexpr auto kRecentRequestTimeout = 10 * crl::time(1000);
|
||||||
constexpr auto kMaxTimeout = 6 * 60 * 60 * crl::time(1000);
|
constexpr auto kMaxTimeout = 6 * 60 * 60 * crl::time(1000);
|
||||||
|
|
||||||
[[nodiscard]] std::vector<DocumentId> ListFromMTP(
|
[[nodiscard]] EmojiStatusCollectible ParseEmojiStatusCollectible(
|
||||||
const MTPDaccount_emojiStatuses &data) {
|
const MTPDemojiStatusCollectible &data) {
|
||||||
const auto &list = data.vstatuses().v;
|
return EmojiStatusCollectible{
|
||||||
auto result = std::vector<DocumentId>();
|
.id = data.vcollectible_id().v,
|
||||||
result.reserve(list.size());
|
.documentId = data.vdocument_id().v,
|
||||||
for (const auto &status : list) {
|
.title = qs(data.vtitle()),
|
||||||
const auto parsed = ParseEmojiStatus(status);
|
.slug = qs(data.vslug()),
|
||||||
if (!parsed.id) {
|
.patternDocumentId = data.vpattern_document_id().v,
|
||||||
LOG(("API Error: emojiStatusEmpty in account.emojiStatuses."));
|
.centerColor = Ui::ColorFromSerialized(data.vcenter_color()),
|
||||||
} else {
|
.edgeColor = Ui::ColorFromSerialized(data.vedge_color()),
|
||||||
result.push_back(parsed.id);
|
.patternColor = Ui::ColorFromSerialized(data.vpattern_color()),
|
||||||
}
|
.textColor = Ui::ColorFromSerialized(data.vtext_color()),
|
||||||
}
|
};
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -96,7 +96,7 @@ void EmojiStatuses::refreshRecentDelayed() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<DocumentId> &EmojiStatuses::list(Type type) const {
|
const std::vector<EmojiStatusId> &EmojiStatuses::list(Type type) const {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Type::Recent: return _recent;
|
case Type::Recent: return _recent;
|
||||||
case Type::Default: return _default;
|
case Type::Default: return _default;
|
||||||
|
@ -107,6 +107,30 @@ const std::vector<DocumentId> &EmojiStatuses::list(Type type) const {
|
||||||
Unexpected("Type in EmojiStatuses::list.");
|
Unexpected("Type in EmojiStatuses::list.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EmojiStatusData EmojiStatuses::parse(const MTPEmojiStatus &status) {
|
||||||
|
return status.match([](const MTPDemojiStatus &data) {
|
||||||
|
return EmojiStatusData{
|
||||||
|
.id = { .documentId = data.vdocument_id().v },
|
||||||
|
.until = data.vuntil().value_or_empty(),
|
||||||
|
};
|
||||||
|
}, [&](const MTPDemojiStatusCollectible &data) {
|
||||||
|
const auto collectibleId = data.vcollectible_id().v;
|
||||||
|
auto &collectible = _collectibleData[collectibleId];
|
||||||
|
if (!collectible) {
|
||||||
|
collectible = std::make_shared<EmojiStatusCollectible>(
|
||||||
|
ParseEmojiStatusCollectible(data));
|
||||||
|
}
|
||||||
|
return EmojiStatusData{
|
||||||
|
.id = { .collectible = collectible },
|
||||||
|
.until = data.vuntil().value_or_empty(),
|
||||||
|
};
|
||||||
|
}, [](const MTPDinputEmojiStatusCollectible &) {
|
||||||
|
return EmojiStatusData();
|
||||||
|
}, [](const MTPDemojiStatusEmpty &) {
|
||||||
|
return EmojiStatusData();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
rpl::producer<> EmojiStatuses::recentUpdates() const {
|
rpl::producer<> EmojiStatuses::recentUpdates() const {
|
||||||
return _recentUpdated.events();
|
return _recentUpdated.events();
|
||||||
}
|
}
|
||||||
|
@ -119,6 +143,10 @@ rpl::producer<> EmojiStatuses::channelDefaultUpdates() const {
|
||||||
return _channelDefaultUpdated.events();
|
return _channelDefaultUpdated.events();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpl::producer<> EmojiStatuses::collectiblesUpdates() const {
|
||||||
|
return _collectiblesUpdated.events();
|
||||||
|
}
|
||||||
|
|
||||||
void EmojiStatuses::registerAutomaticClear(
|
void EmojiStatuses::registerAutomaticClear(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
TimeId until) {
|
TimeId until) {
|
||||||
|
@ -253,7 +281,7 @@ void EmojiStatuses::processClearing() {
|
||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
} else {
|
} else {
|
||||||
i->first->setEmojiStatus(0, 0);
|
i->first->setEmojiStatus(EmojiStatusId());
|
||||||
i = clearing.erase(i);
|
i = clearing.erase(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -271,6 +299,22 @@ void EmojiStatuses::processClearing() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<EmojiStatusId> EmojiStatuses::parse(
|
||||||
|
const MTPDaccount_emojiStatuses &data) {
|
||||||
|
const auto &list = data.vstatuses().v;
|
||||||
|
auto result = std::vector<EmojiStatusId>();
|
||||||
|
result.reserve(list.size());
|
||||||
|
for (const auto &status : list) {
|
||||||
|
const auto parsed = parse(status);
|
||||||
|
if (!parsed.id) {
|
||||||
|
LOG(("API Error: empty status in account.emojiStatuses."));
|
||||||
|
} else {
|
||||||
|
result.push_back(parsed.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void EmojiStatuses::processClearingIn(TimeId wait) {
|
void EmojiStatuses::processClearingIn(TimeId wait) {
|
||||||
const auto waitms = wait * crl::time(1000);
|
const auto waitms = wait * crl::time(1000);
|
||||||
_clearingTimer.callOnce(std::min(waitms, kMaxTimeout));
|
_clearingTimer.callOnce(std::min(waitms, kMaxTimeout));
|
||||||
|
@ -376,13 +420,13 @@ void EmojiStatuses::requestChannelColored() {
|
||||||
|
|
||||||
void EmojiStatuses::updateRecent(const MTPDaccount_emojiStatuses &data) {
|
void EmojiStatuses::updateRecent(const MTPDaccount_emojiStatuses &data) {
|
||||||
_recentHash = data.vhash().v;
|
_recentHash = data.vhash().v;
|
||||||
_recent = ListFromMTP(data);
|
_recent = parse(data);
|
||||||
_recentUpdated.fire({});
|
_recentUpdated.fire({});
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmojiStatuses::updateDefault(const MTPDaccount_emojiStatuses &data) {
|
void EmojiStatuses::updateDefault(const MTPDaccount_emojiStatuses &data) {
|
||||||
_defaultHash = data.vhash().v;
|
_defaultHash = data.vhash().v;
|
||||||
_default = ListFromMTP(data);
|
_default = parse(data);
|
||||||
_defaultUpdated.fire({});
|
_defaultUpdated.fire({});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,7 +435,9 @@ void EmojiStatuses::updateColored(const MTPDmessages_stickerSet &data) {
|
||||||
_colored.clear();
|
_colored.clear();
|
||||||
_colored.reserve(list.size());
|
_colored.reserve(list.size());
|
||||||
for (const auto &sticker : data.vdocuments().v) {
|
for (const auto &sticker : data.vdocuments().v) {
|
||||||
_colored.push_back(_owner->processDocument(sticker)->id);
|
_colored.push_back({
|
||||||
|
.documentId = _owner->processDocument(sticker)->id,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
_coloredUpdated.fire({});
|
_coloredUpdated.fire({});
|
||||||
}
|
}
|
||||||
|
@ -399,7 +445,7 @@ void EmojiStatuses::updateColored(const MTPDmessages_stickerSet &data) {
|
||||||
void EmojiStatuses::updateChannelDefault(
|
void EmojiStatuses::updateChannelDefault(
|
||||||
const MTPDaccount_emojiStatuses &data) {
|
const MTPDaccount_emojiStatuses &data) {
|
||||||
_channelDefaultHash = data.vhash().v;
|
_channelDefaultHash = data.vhash().v;
|
||||||
_channelDefault = ListFromMTP(data);
|
_channelDefault = parse(data);
|
||||||
_channelDefaultUpdated.fire({});
|
_channelDefaultUpdated.fire({});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,18 +455,20 @@ void EmojiStatuses::updateChannelColored(
|
||||||
_channelColored.clear();
|
_channelColored.clear();
|
||||||
_channelColored.reserve(list.size());
|
_channelColored.reserve(list.size());
|
||||||
for (const auto &sticker : data.vdocuments().v) {
|
for (const auto &sticker : data.vdocuments().v) {
|
||||||
_channelColored.push_back(_owner->processDocument(sticker)->id);
|
_channelColored.push_back({
|
||||||
|
.documentId = _owner->processDocument(sticker)->id,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
_channelColoredUpdated.fire({});
|
_channelColoredUpdated.fire({});
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmojiStatuses::set(DocumentId id, TimeId until) {
|
void EmojiStatuses::set(EmojiStatusId id, TimeId until) {
|
||||||
set(_owner->session().user(), id, until);
|
set(_owner->session().user(), id, until);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmojiStatuses::set(
|
void EmojiStatuses::set(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
DocumentId id,
|
EmojiStatusId id,
|
||||||
TimeId until) {
|
TimeId until) {
|
||||||
auto &api = _owner->session().api();
|
auto &api = _owner->session().api();
|
||||||
auto &requestId = _sentRequests[peer];
|
auto &requestId = _sentRequests[peer];
|
||||||
|
@ -437,11 +485,19 @@ void EmojiStatuses::set(
|
||||||
_sentRequests.remove(peer);
|
_sentRequests.remove(peer);
|
||||||
}).send();
|
}).send();
|
||||||
};
|
};
|
||||||
|
using EFlag = MTPDemojiStatus::Flag;
|
||||||
|
using CFlag = MTPDinputEmojiStatusCollectible::Flag;
|
||||||
const auto status = !id
|
const auto status = !id
|
||||||
? MTP_emojiStatusEmpty()
|
? MTP_emojiStatusEmpty()
|
||||||
: !until
|
: id.collectible
|
||||||
? MTP_emojiStatus(MTP_long(id))
|
? MTP_inputEmojiStatusCollectible(
|
||||||
: MTP_emojiStatusUntil(MTP_long(id), MTP_int(until));
|
MTP_flags(until ? CFlag::f_until : CFlag()),
|
||||||
|
MTP_long(id.collectible->id),
|
||||||
|
MTP_int(until))
|
||||||
|
: MTP_emojiStatus(
|
||||||
|
MTP_flags(until ? EFlag::f_until : EFlag()),
|
||||||
|
MTP_long(id.documentId),
|
||||||
|
MTP_int(until));
|
||||||
if (peer->isSelf()) {
|
if (peer->isSelf()) {
|
||||||
send(MTPaccount_UpdateEmojiStatus(status));
|
send(MTPaccount_UpdateEmojiStatus(status));
|
||||||
} else if (const auto channel = peer->asChannel()) {
|
} else if (const auto channel = peer->asChannel()) {
|
||||||
|
@ -449,14 +505,4 @@ void EmojiStatuses::set(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EmojiStatusData ParseEmojiStatus(const MTPEmojiStatus &status) {
|
|
||||||
return status.match([](const MTPDemojiStatus &data) {
|
|
||||||
return EmojiStatusData{ data.vdocument_id().v };
|
|
||||||
}, [](const MTPDemojiStatusUntil &data) {
|
|
||||||
return EmojiStatusData{ data.vdocument_id().v, data.vuntil().v };
|
|
||||||
}, [](const MTPDemojiStatusEmpty &) {
|
|
||||||
return EmojiStatusData();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
|
@ -22,6 +22,26 @@ namespace Data {
|
||||||
class DocumentMedia;
|
class DocumentMedia;
|
||||||
class Session;
|
class Session;
|
||||||
|
|
||||||
|
struct EmojiStatusCollectible {
|
||||||
|
CollectibleId id = 0;
|
||||||
|
DocumentId documentId = 0;
|
||||||
|
QString title;
|
||||||
|
QString slug;
|
||||||
|
DocumentId patternDocumentId = 0;
|
||||||
|
QColor centerColor;
|
||||||
|
QColor edgeColor;
|
||||||
|
QColor patternColor;
|
||||||
|
QColor textColor;
|
||||||
|
|
||||||
|
explicit operator bool() const {
|
||||||
|
return id != 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct EmojiStatusData {
|
||||||
|
EmojiStatusId id;
|
||||||
|
TimeId until = 0;
|
||||||
|
};
|
||||||
|
|
||||||
class EmojiStatuses final {
|
class EmojiStatuses final {
|
||||||
public:
|
public:
|
||||||
explicit EmojiStatuses(not_null<Session*> owner);
|
explicit EmojiStatuses(not_null<Session*> owner);
|
||||||
|
@ -45,15 +65,19 @@ public:
|
||||||
Colored,
|
Colored,
|
||||||
ChannelDefault,
|
ChannelDefault,
|
||||||
ChannelColored,
|
ChannelColored,
|
||||||
|
Collectibles,
|
||||||
};
|
};
|
||||||
[[nodiscard]] const std::vector<DocumentId> &list(Type type) const;
|
[[nodiscard]] const std::vector<EmojiStatusId> &list(Type type) const;
|
||||||
|
|
||||||
|
[[nodiscard]] EmojiStatusData parse(const MTPEmojiStatus &status);
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<> recentUpdates() const;
|
[[nodiscard]] rpl::producer<> recentUpdates() const;
|
||||||
[[nodiscard]] rpl::producer<> defaultUpdates() const;
|
[[nodiscard]] rpl::producer<> defaultUpdates() const;
|
||||||
[[nodiscard]] rpl::producer<> channelDefaultUpdates() const;
|
[[nodiscard]] rpl::producer<> channelDefaultUpdates() const;
|
||||||
|
[[nodiscard]] rpl::producer<> collectiblesUpdates() const;
|
||||||
|
|
||||||
void set(DocumentId id, TimeId until = 0);
|
void set(EmojiStatusId id, TimeId until = 0);
|
||||||
void set(not_null<PeerData*> peer, DocumentId id, TimeId until = 0);
|
void set(not_null<PeerData*> peer, EmojiStatusId id, TimeId until = 0);
|
||||||
|
|
||||||
void registerAutomaticClear(not_null<PeerData*> peer, TimeId until);
|
void registerAutomaticClear(not_null<PeerData*> peer, TimeId until);
|
||||||
|
|
||||||
|
@ -89,21 +113,30 @@ private:
|
||||||
void processClearingIn(TimeId wait);
|
void processClearingIn(TimeId wait);
|
||||||
void processClearing();
|
void processClearing();
|
||||||
|
|
||||||
|
[[nodiscard]] std::vector<EmojiStatusId> parse(
|
||||||
|
const MTPDaccount_emojiStatuses &data);
|
||||||
|
|
||||||
template <typename Request>
|
template <typename Request>
|
||||||
void requestGroups(not_null<GroupsType*> type, Request &&request);
|
void requestGroups(not_null<GroupsType*> type, Request &&request);
|
||||||
|
|
||||||
const not_null<Session*> _owner;
|
const not_null<Session*> _owner;
|
||||||
|
|
||||||
std::vector<DocumentId> _recent;
|
std::vector<EmojiStatusId> _recent;
|
||||||
std::vector<DocumentId> _default;
|
std::vector<EmojiStatusId> _default;
|
||||||
std::vector<DocumentId> _colored;
|
std::vector<EmojiStatusId> _colored;
|
||||||
std::vector<DocumentId> _channelDefault;
|
std::vector<EmojiStatusId> _channelDefault;
|
||||||
std::vector<DocumentId> _channelColored;
|
std::vector<EmojiStatusId> _channelColored;
|
||||||
|
std::vector<EmojiStatusId> _collectibles;
|
||||||
rpl::event_stream<> _recentUpdated;
|
rpl::event_stream<> _recentUpdated;
|
||||||
rpl::event_stream<> _defaultUpdated;
|
rpl::event_stream<> _defaultUpdated;
|
||||||
rpl::event_stream<> _coloredUpdated;
|
rpl::event_stream<> _coloredUpdated;
|
||||||
rpl::event_stream<> _channelDefaultUpdated;
|
rpl::event_stream<> _channelDefaultUpdated;
|
||||||
rpl::event_stream<> _channelColoredUpdated;
|
rpl::event_stream<> _channelColoredUpdated;
|
||||||
|
rpl::event_stream<> _collectiblesUpdated;
|
||||||
|
|
||||||
|
base::flat_map<
|
||||||
|
CollectibleId,
|
||||||
|
std::shared_ptr<EmojiStatusCollectible>> _collectibleData;
|
||||||
|
|
||||||
mtpRequestId _recentRequestId = 0;
|
mtpRequestId _recentRequestId = 0;
|
||||||
bool _recentRequestScheduled = false;
|
bool _recentRequestScheduled = false;
|
||||||
|
@ -119,6 +152,8 @@ private:
|
||||||
|
|
||||||
mtpRequestId _channelColoredRequestId = 0;
|
mtpRequestId _channelColoredRequestId = 0;
|
||||||
|
|
||||||
|
mtpRequestId _collectiblesRequestId = 0;
|
||||||
|
|
||||||
base::flat_map<not_null<PeerData*>, mtpRequestId> _sentRequests;
|
base::flat_map<not_null<PeerData*>, mtpRequestId> _sentRequests;
|
||||||
|
|
||||||
base::flat_map<not_null<PeerData*>, TimeId> _clearing;
|
base::flat_map<not_null<PeerData*>, TimeId> _clearing;
|
||||||
|
@ -133,10 +168,4 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EmojiStatusData {
|
|
||||||
DocumentId id = 0;
|
|
||||||
TimeId until = 0;
|
|
||||||
};
|
|
||||||
[[nodiscard]] EmojiStatusData ParseEmojiStatus(const MTPEmojiStatus &status);
|
|
||||||
|
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
|
@ -1115,11 +1115,11 @@ bool PeerData::changeBackgroundEmojiId(DocumentId id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerData::setEmojiStatus(const MTPEmojiStatus &status) {
|
void PeerData::setEmojiStatus(const MTPEmojiStatus &status) {
|
||||||
const auto parsed = Data::ParseEmojiStatus(status);
|
const auto parsed = owner().emojiStatuses().parse(status);
|
||||||
setEmojiStatus(parsed.id, parsed.until);
|
setEmojiStatus(parsed.id, parsed.until);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerData::setEmojiStatus(DocumentId emojiStatusId, TimeId until) {
|
void PeerData::setEmojiStatus(EmojiStatusId emojiStatusId, TimeId until) {
|
||||||
if (_emojiStatusId != emojiStatusId) {
|
if (_emojiStatusId != emojiStatusId) {
|
||||||
_emojiStatusId = emojiStatusId;
|
_emojiStatusId = emojiStatusId;
|
||||||
session().changes().peerUpdated(this, UpdateFlag::EmojiStatus);
|
session().changes().peerUpdated(this, UpdateFlag::EmojiStatus);
|
||||||
|
@ -1127,7 +1127,7 @@ void PeerData::setEmojiStatus(DocumentId emojiStatusId, TimeId until) {
|
||||||
owner().emojiStatuses().registerAutomaticClear(this, until);
|
owner().emojiStatuses().registerAutomaticClear(this, until);
|
||||||
}
|
}
|
||||||
|
|
||||||
DocumentId PeerData::emojiStatusId() const {
|
EmojiStatusId PeerData::emojiStatusId() const {
|
||||||
return _emojiStatusId;
|
return _emojiStatusId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -206,8 +206,8 @@ public:
|
||||||
bool changeBackgroundEmojiId(DocumentId id);
|
bool changeBackgroundEmojiId(DocumentId id);
|
||||||
|
|
||||||
void setEmojiStatus(const MTPEmojiStatus &status);
|
void setEmojiStatus(const MTPEmojiStatus &status);
|
||||||
void setEmojiStatus(DocumentId emojiStatusId, TimeId until = 0);
|
void setEmojiStatus(EmojiStatusId emojiStatusId, TimeId until = 0);
|
||||||
[[nodiscard]] DocumentId emojiStatusId() const;
|
[[nodiscard]] EmojiStatusId emojiStatusId() const;
|
||||||
|
|
||||||
[[nodiscard]] bool isUser() const {
|
[[nodiscard]] bool isUser() const {
|
||||||
return peerIsUser(id);
|
return peerIsUser(id);
|
||||||
|
@ -523,7 +523,7 @@ private:
|
||||||
base::flat_set<QString> _nameWords; // for filtering
|
base::flat_set<QString> _nameWords; // for filtering
|
||||||
base::flat_set<QChar> _nameFirstLetters;
|
base::flat_set<QChar> _nameFirstLetters;
|
||||||
|
|
||||||
DocumentId _emojiStatusId = 0;
|
EmojiStatusId _emojiStatusId;
|
||||||
DocumentId _backgroundEmojiId = 0;
|
DocumentId _backgroundEmojiId = 0;
|
||||||
crl::time _lastFullUpdate = 0;
|
crl::time _lastFullUpdate = 0;
|
||||||
|
|
||||||
|
|
|
@ -695,7 +695,7 @@ not_null<UserData*> Session::processUser(const MTPUser &data) {
|
||||||
if (const auto &status = data.vemoji_status()) {
|
if (const auto &status = data.vemoji_status()) {
|
||||||
result->setEmojiStatus(*status);
|
result->setEmojiStatus(*status);
|
||||||
} else {
|
} else {
|
||||||
result->setEmojiStatus(0);
|
result->setEmojiStatus(EmojiStatusId());
|
||||||
}
|
}
|
||||||
if (!minimal) {
|
if (!minimal) {
|
||||||
if (const auto botInfoVersion = data.vbot_info_version()) {
|
if (const auto botInfoVersion = data.vbot_info_version()) {
|
||||||
|
@ -886,7 +886,7 @@ not_null<PeerData*> Session::processChat(const MTPChat &data) {
|
||||||
if (const auto &status = data.vemoji_status()) {
|
if (const auto &status = data.vemoji_status()) {
|
||||||
channel->setEmojiStatus(*status);
|
channel->setEmojiStatus(*status);
|
||||||
} else {
|
} else {
|
||||||
channel->setEmojiStatus(0);
|
channel->setEmojiStatus(EmojiStatusId());
|
||||||
}
|
}
|
||||||
if (minimal) {
|
if (minimal) {
|
||||||
if (channel->input.type() == mtpc_inputPeerEmpty
|
if (channel->input.type() == mtpc_inputPeerEmpty
|
||||||
|
|
|
@ -37,6 +37,7 @@ using Options = base::flags<Option>;
|
||||||
namespace Data {
|
namespace Data {
|
||||||
|
|
||||||
struct FileOrigin;
|
struct FileOrigin;
|
||||||
|
struct EmojiStatusCollectible;
|
||||||
|
|
||||||
struct UploadState {
|
struct UploadState {
|
||||||
explicit UploadState(int64 size) : size(size) {
|
explicit UploadState(int64 size) : size(size) {
|
||||||
|
@ -139,6 +140,23 @@ using WallPaperId = uint64;
|
||||||
using CallId = uint64;
|
using CallId = uint64;
|
||||||
using BotAppId = uint64;
|
using BotAppId = uint64;
|
||||||
using EffectId = uint64;
|
using EffectId = uint64;
|
||||||
|
using CollectibleId = uint64;
|
||||||
|
|
||||||
|
struct EmojiStatusId {
|
||||||
|
DocumentId documentId = 0;
|
||||||
|
std::shared_ptr<Data::EmojiStatusCollectible> collectible;
|
||||||
|
|
||||||
|
explicit operator bool() const {
|
||||||
|
return documentId || collectible;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend inline auto operator<=>(
|
||||||
|
const EmojiStatusId &,
|
||||||
|
const EmojiStatusId &) = default;
|
||||||
|
friend inline bool operator==(
|
||||||
|
const EmojiStatusId &,
|
||||||
|
const EmojiStatusId &) = default;
|
||||||
|
};
|
||||||
|
|
||||||
constexpr auto CancelledWebPageId = WebPageId(0xFFFFFFFFFFFFFFFFULL);
|
constexpr auto CancelledWebPageId = WebPageId(0xFFFFFFFFFFFFFFFFULL);
|
||||||
|
|
||||||
|
|
|
@ -2003,17 +2003,19 @@ void GenerateItems(
|
||||||
return status.match([](
|
return status.match([](
|
||||||
const MTPDemojiStatus &data) {
|
const MTPDemojiStatus &data) {
|
||||||
return data.vdocument_id().v;
|
return data.vdocument_id().v;
|
||||||
|
}, [](const MTPDemojiStatusCollectible &data) {
|
||||||
|
return data.vdocument_id().v;
|
||||||
}, [](const MTPDemojiStatusEmpty &) {
|
}, [](const MTPDemojiStatusEmpty &) {
|
||||||
return DocumentId();
|
return DocumentId();
|
||||||
}, [](const MTPDemojiStatusUntil &data) {
|
}, [](const MTPDinputEmojiStatusCollectible &) {
|
||||||
return data.vdocument_id().v;
|
return DocumentId();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const auto prevEmoji = parse(data.vprev_value());
|
const auto prevEmoji = parse(data.vprev_value());
|
||||||
const auto nextEmoji = parse(data.vnew_value());
|
const auto nextEmoji = parse(data.vnew_value());
|
||||||
const auto nextUntil = data.vnew_value().match([](
|
const auto nextUntil = data.vnew_value().match([](
|
||||||
const MTPDemojiStatusUntil &data) {
|
const MTPDemojiStatus &data) {
|
||||||
return data.vuntil().v;
|
return TimeId(data.vuntil().value_or_empty());
|
||||||
}, [](const auto &) { return TimeId(); });
|
}, [](const auto &) { return TimeId(); });
|
||||||
|
|
||||||
const auto text = !prevEmoji
|
const auto text = !prevEmoji
|
||||||
|
|
|
@ -25,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "core/ui_integration.h"
|
#include "core/ui_integration.h"
|
||||||
#include "data/business/data_business_chatbots.h"
|
#include "data/business/data_business_chatbots.h"
|
||||||
#include "data/notify/data_notify_settings.h"
|
#include "data/notify/data_notify_settings.h"
|
||||||
|
#include "data/data_emoji_statuses.h"
|
||||||
#include "data/data_peer.h"
|
#include "data/data_peer.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "data/data_chat.h"
|
#include "data/data_chat.h"
|
||||||
|
@ -112,8 +113,11 @@ namespace {
|
||||||
Data::PeerUpdate::Flag::EmojiStatus
|
Data::PeerUpdate::Flag::EmojiStatus
|
||||||
) | rpl::map([=] {
|
) | rpl::map([=] {
|
||||||
const auto id = peer->emojiStatusId();
|
const auto id = peer->emojiStatusId();
|
||||||
return id
|
const auto documentId = id.collectible
|
||||||
? ResolveIsCustom(owner, id)
|
? id.collectible->documentId
|
||||||
|
: id.documentId;
|
||||||
|
return documentId
|
||||||
|
? ResolveIsCustom(owner, documentId)
|
||||||
: rpl::single(TextWithEntities());
|
: rpl::single(TextWithEntities());
|
||||||
}) | rpl::flatten_latest() | rpl::distinct_until_changed();
|
}) | rpl::flatten_latest() | rpl::distinct_until_changed();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1767,8 +1767,8 @@ void Message::paintFromName(
|
||||||
+ std::min(availableWidth - statusWidth, nameText->maxWidth());
|
+ std::min(availableWidth - statusWidth, nameText->maxWidth());
|
||||||
const auto y = trect.top();
|
const auto y = trect.top();
|
||||||
auto color = nameFg;
|
auto color = nameFg;
|
||||||
color.setAlpha(115);
|
color.setAlpha(115); // todo collectibles
|
||||||
const auto id = from ? from->emojiStatusId() : 0;
|
const auto id = from ? from->emojiStatusId().documentId : 0;
|
||||||
if (_fromNameStatus->id != id) {
|
if (_fromNameStatus->id != id) {
|
||||||
const auto that = const_cast<Message*>(this);
|
const auto that = const_cast<Message*>(this);
|
||||||
_fromNameStatus->custom = id
|
_fromNameStatus->custom = id
|
||||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "info/profile/info_profile_badge.h"
|
#include "info/profile/info_profile_badge.h"
|
||||||
|
|
||||||
|
#include "data/data_emoji_statuses.h"
|
||||||
#include "data/data_peer.h"
|
#include "data/data_peer.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
|
@ -29,9 +30,9 @@ namespace {
|
||||||
return rpl::combine(
|
return rpl::combine(
|
||||||
BadgeValue(peer),
|
BadgeValue(peer),
|
||||||
EmojiStatusIdValue(peer)
|
EmojiStatusIdValue(peer)
|
||||||
) | rpl::map([=](BadgeType badge, DocumentId emojiStatusId) {
|
) | rpl::map([=](BadgeType badge, EmojiStatusId emojiStatusId) {
|
||||||
if (statusOnlyForPremium && badge != BadgeType::Premium) {
|
if (statusOnlyForPremium && badge != BadgeType::Premium) {
|
||||||
emojiStatusId = 0;
|
emojiStatusId = EmojiStatusId();
|
||||||
} else if (emojiStatusId && badge == BadgeType::None) {
|
} else if (emojiStatusId && badge == BadgeType::None) {
|
||||||
badge = BadgeType::Premium;
|
badge = BadgeType::Premium;
|
||||||
}
|
}
|
||||||
|
@ -129,9 +130,12 @@ void Badge::setContent(Content content) {
|
||||||
: id
|
: id
|
||||||
? nullptr
|
? nullptr
|
||||||
: &_st.premium;
|
: &_st.premium;
|
||||||
if (id) {
|
const auto documentId = id.collectible
|
||||||
|
? id.collectible->documentId
|
||||||
|
: id.documentId;
|
||||||
|
if (documentId) {
|
||||||
_emojiStatus = _session->data().customEmojiManager().create(
|
_emojiStatus = _session->data().customEmojiManager().create(
|
||||||
id,
|
documentId,
|
||||||
[raw = _view.data()] { raw->update(); },
|
[raw = _view.data()] { raw->update(); },
|
||||||
sizeTag());
|
sizeTag());
|
||||||
if (_customStatusLoopsLimit > 0) {
|
if (_customStatusLoopsLimit > 0) {
|
||||||
|
|
|
@ -59,7 +59,7 @@ public:
|
||||||
|
|
||||||
struct Content {
|
struct Content {
|
||||||
BadgeType badge = BadgeType::None;
|
BadgeType badge = BadgeType::None;
|
||||||
DocumentId emojiStatusId = 0;
|
EmojiStatusId emojiStatusId;
|
||||||
|
|
||||||
friend inline constexpr bool operator==(Content, Content) = default;
|
friend inline constexpr bool operator==(Content, Content) = default;
|
||||||
};
|
};
|
||||||
|
|
|
@ -111,18 +111,28 @@ void EmojiStatusPanel::show(Descriptor &&descriptor) {
|
||||||
_panelButton = button;
|
_panelButton = button;
|
||||||
_animationSizeTag = descriptor.animationSizeTag;
|
_animationSizeTag = descriptor.animationSizeTag;
|
||||||
const auto feed = [=, now = descriptor.ensureAddedEmojiId](
|
const auto feed = [=, now = descriptor.ensureAddedEmojiId](
|
||||||
std::vector<DocumentId> list) {
|
std::vector<EmojiStatusId> list) {
|
||||||
list.insert(begin(list), 0);
|
list.insert(begin(list), EmojiStatusId());
|
||||||
if (now && !ranges::contains(list, now)) {
|
if (now && !ranges::contains(list, now)) {
|
||||||
list.push_back(now);
|
list.push_back(now);
|
||||||
}
|
}
|
||||||
_panel->selector()->provideRecentEmoji(list);
|
auto tmp = std::vector<DocumentId>();
|
||||||
|
for (const auto &id : list) {
|
||||||
|
if (id.documentId) { // todo collectibles
|
||||||
|
tmp.push_back(id.documentId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_panel->selector()->provideRecentEmoji(tmp);
|
||||||
};
|
};
|
||||||
if (descriptor.backgroundEmojiMode) {
|
if (descriptor.backgroundEmojiMode) {
|
||||||
controller->session().api().peerPhoto().emojiListValue(
|
controller->session().api().peerPhoto().emojiListValue(
|
||||||
Api::PeerPhoto::EmojiListType::Background
|
Api::PeerPhoto::EmojiListType::Background
|
||||||
) | rpl::start_with_next([=](std::vector<DocumentId> &&list) {
|
) | rpl::start_with_next([=](std::vector<DocumentId> &&list) {
|
||||||
feed(std::move(list));
|
auto tmp = std::vector<EmojiStatusId>();
|
||||||
|
for (const auto &id : list) { // todo collectibles
|
||||||
|
tmp.push_back(EmojiStatusId{ .documentId = id });
|
||||||
|
}
|
||||||
|
feed(std::move(tmp));
|
||||||
}, _panel->lifetime());
|
}, _panel->lifetime());
|
||||||
} else if (descriptor.channelStatusMode) {
|
} else if (descriptor.channelStatusMode) {
|
||||||
const auto &statuses = controller->session().data().emojiStatuses();
|
const auto &statuses = controller->session().data().emojiStatuses();
|
||||||
|
@ -254,8 +264,8 @@ void EmojiStatusPanel::create(const Descriptor &descriptor) {
|
||||||
) | rpl::start_with_next([=](const Chosen &chosen) {
|
) | rpl::start_with_next([=](const Chosen &chosen) {
|
||||||
const auto owner = &controller->session().data();
|
const auto owner = &controller->session().data();
|
||||||
startAnimation(owner, body, chosen.id, chosen.animation);
|
startAnimation(owner, body, chosen.id, chosen.animation);
|
||||||
_someCustomChosen.fire({ chosen.id, chosen.until });
|
_someCustomChosen.fire({ { chosen.id }, chosen.until });
|
||||||
_panel->hideAnimated();
|
_panel->hideAnimated(); // todo collectibles
|
||||||
}, _panel->lifetime());
|
}, _panel->lifetime());
|
||||||
} else {
|
} else {
|
||||||
const auto weak = Ui::MakeWeak(_panel.get());
|
const auto weak = Ui::MakeWeak(_panel.get());
|
||||||
|
@ -266,8 +276,8 @@ void EmojiStatusPanel::create(const Descriptor &descriptor) {
|
||||||
const auto owner = &controller->session().data();
|
const auto owner = &controller->session().data();
|
||||||
if (weak) {
|
if (weak) {
|
||||||
startAnimation(owner, body, chosen.id, chosen.animation);
|
startAnimation(owner, body, chosen.id, chosen.animation);
|
||||||
}
|
} // todo collectibles
|
||||||
owner->emojiStatuses().set(chosen.id, chosen.until);
|
owner->emojiStatuses().set({ chosen.id }, chosen.until);
|
||||||
};
|
};
|
||||||
|
|
||||||
rpl::merge(
|
rpl::merge(
|
||||||
|
|
|
@ -52,7 +52,7 @@ public:
|
||||||
not_null<Window::SessionController*> controller;
|
not_null<Window::SessionController*> controller;
|
||||||
not_null<QWidget*> button;
|
not_null<QWidget*> button;
|
||||||
Data::CustomEmojiSizeTag animationSizeTag = {};
|
Data::CustomEmojiSizeTag animationSizeTag = {};
|
||||||
DocumentId ensureAddedEmojiId = 0;
|
EmojiStatusId ensureAddedEmojiId;
|
||||||
Fn<QColor()> customTextColor;
|
Fn<QColor()> customTextColor;
|
||||||
bool backgroundEmojiMode = false;
|
bool backgroundEmojiMode = false;
|
||||||
bool channelStatusMode = false;
|
bool channelStatusMode = false;
|
||||||
|
@ -61,7 +61,7 @@ public:
|
||||||
void repaint();
|
void repaint();
|
||||||
|
|
||||||
struct CustomChosen {
|
struct CustomChosen {
|
||||||
DocumentId id = 0;
|
EmojiStatusId id;
|
||||||
TimeId until = 0;
|
TimeId until = 0;
|
||||||
};
|
};
|
||||||
[[nodiscard]] rpl::producer<CustomChosen> someCustomChosen() const {
|
[[nodiscard]] rpl::producer<CustomChosen> someCustomChosen() const {
|
||||||
|
|
|
@ -676,9 +676,9 @@ rpl::producer<BadgeType> BadgeValue(not_null<PeerData*> peer) {
|
||||||
return rpl::single(BadgeType::None);
|
return rpl::single(BadgeType::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<DocumentId> EmojiStatusIdValue(not_null<PeerData*> peer) {
|
rpl::producer<EmojiStatusId> EmojiStatusIdValue(not_null<PeerData*> peer) {
|
||||||
if (peer->isChat()) {
|
if (peer->isChat()) {
|
||||||
return rpl::single(DocumentId(0));
|
return rpl::single(EmojiStatusId());
|
||||||
}
|
}
|
||||||
return peer->session().changes().peerFlagsValue(
|
return peer->session().changes().peerFlagsValue(
|
||||||
peer,
|
peer,
|
||||||
|
|
|
@ -132,7 +132,7 @@ struct LinkWithUrl {
|
||||||
|
|
||||||
enum class BadgeType;
|
enum class BadgeType;
|
||||||
[[nodiscard]] rpl::producer<BadgeType> BadgeValue(not_null<PeerData*> peer);
|
[[nodiscard]] rpl::producer<BadgeType> BadgeValue(not_null<PeerData*> peer);
|
||||||
[[nodiscard]] rpl::producer<DocumentId> EmojiStatusIdValue(
|
[[nodiscard]] rpl::producer<EmojiStatusId> EmojiStatusIdValue(
|
||||||
not_null<PeerData*> peer);
|
not_null<PeerData*> peer);
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<QString> BirthdayLabelText(
|
[[nodiscard]] rpl::producer<QString> BirthdayLabelText(
|
||||||
|
|
|
@ -590,7 +590,7 @@ void ConfirmEmojiStatusBox(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
document->owner().emojiStatuses().set(
|
document->owner().emojiStatuses().set(
|
||||||
document->id,
|
{ document->id },
|
||||||
duration ? (base::unixtime::now() + duration) : 0);
|
duration ? (base::unixtime::now() + duration) : 0);
|
||||||
*set = true;
|
*set = true;
|
||||||
box->closeBox();
|
box->closeBox();
|
||||||
|
|
|
@ -33,8 +33,8 @@ inputMediaUploadedPhoto#1e287d04 flags:# spoiler:flags.2?true file:InputFile sti
|
||||||
inputMediaPhoto#b3ba0635 flags:# spoiler:flags.1?true id:InputPhoto ttl_seconds:flags.0?int = InputMedia;
|
inputMediaPhoto#b3ba0635 flags:# spoiler:flags.1?true id:InputPhoto ttl_seconds:flags.0?int = InputMedia;
|
||||||
inputMediaGeoPoint#f9c44144 geo_point:InputGeoPoint = InputMedia;
|
inputMediaGeoPoint#f9c44144 geo_point:InputGeoPoint = InputMedia;
|
||||||
inputMediaContact#f8ab7dfb phone_number:string first_name:string last_name:string vcard:string = InputMedia;
|
inputMediaContact#f8ab7dfb phone_number:string first_name:string last_name:string vcard:string = InputMedia;
|
||||||
inputMediaUploadedDocument#5b38c6c1 flags:# nosound_video:flags.3?true force_file:flags.4?true spoiler:flags.5?true file:InputFile thumb:flags.2?InputFile mime_type:string attributes:Vector<DocumentAttribute> stickers:flags.0?Vector<InputDocument> ttl_seconds:flags.1?int = InputMedia;
|
inputMediaUploadedDocument#f041c42d flags:# nosound_video:flags.3?true force_file:flags.4?true spoiler:flags.5?true file:InputFile thumb:flags.2?InputFile mime_type:string attributes:Vector<DocumentAttribute> stickers:flags.0?Vector<InputDocument> video_cover:flags.6?InputPhoto ttl_seconds:flags.1?int = InputMedia;
|
||||||
inputMediaDocument#33473058 flags:# spoiler:flags.2?true id:InputDocument ttl_seconds:flags.0?int query:flags.1?string = InputMedia;
|
inputMediaDocument#74067321 flags:# spoiler:flags.2?true id:InputDocument video_cover:flags.3?InputPhoto ttl_seconds:flags.0?int query:flags.1?string = InputMedia;
|
||||||
inputMediaVenue#c13d1c11 geo_point:InputGeoPoint title:string address:string provider:string venue_id:string venue_type:string = InputMedia;
|
inputMediaVenue#c13d1c11 geo_point:InputGeoPoint title:string address:string provider:string venue_id:string venue_type:string = InputMedia;
|
||||||
inputMediaPhotoExternal#e5bbfe1a flags:# spoiler:flags.1?true url:string ttl_seconds:flags.0?int = InputMedia;
|
inputMediaPhotoExternal#e5bbfe1a flags:# spoiler:flags.1?true url:string ttl_seconds:flags.0?int = InputMedia;
|
||||||
inputMediaDocumentExternal#fb52dc99 flags:# spoiler:flags.1?true url:string ttl_seconds:flags.0?int = InputMedia;
|
inputMediaDocumentExternal#fb52dc99 flags:# spoiler:flags.1?true url:string ttl_seconds:flags.0?int = InputMedia;
|
||||||
|
@ -124,7 +124,7 @@ messageMediaPhoto#695150d7 flags:# spoiler:flags.3?true photo:flags.0?Photo ttl_
|
||||||
messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia;
|
messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia;
|
||||||
messageMediaContact#70322949 phone_number:string first_name:string last_name:string vcard:string user_id:long = MessageMedia;
|
messageMediaContact#70322949 phone_number:string first_name:string last_name:string vcard:string user_id:long = MessageMedia;
|
||||||
messageMediaUnsupported#9f84f49e = MessageMedia;
|
messageMediaUnsupported#9f84f49e = MessageMedia;
|
||||||
messageMediaDocument#dd570bd5 flags:# nopremium:flags.3?true spoiler:flags.4?true video:flags.6?true round:flags.7?true voice:flags.8?true document:flags.0?Document alt_documents:flags.5?Vector<Document> ttl_seconds:flags.2?int = MessageMedia;
|
messageMediaDocument#dbbdf614 flags:# nopremium:flags.3?true spoiler:flags.4?true video:flags.6?true round:flags.7?true voice:flags.8?true document:flags.0?Document alt_documents:flags.5?Vector<Document> video_cover:flags.9?Photo ttl_seconds:flags.2?int = MessageMedia;
|
||||||
messageMediaWebPage#ddf10c3b flags:# force_large_media:flags.0?true force_small_media:flags.1?true manual:flags.3?true safe:flags.4?true webpage:WebPage = MessageMedia;
|
messageMediaWebPage#ddf10c3b flags:# force_large_media:flags.0?true force_small_media:flags.1?true manual:flags.3?true safe:flags.4?true webpage:WebPage = MessageMedia;
|
||||||
messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string = MessageMedia;
|
messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string = MessageMedia;
|
||||||
messageMediaGame#fdb19008 game:Game = MessageMedia;
|
messageMediaGame#fdb19008 game:Game = MessageMedia;
|
||||||
|
@ -1498,8 +1498,9 @@ premiumGiftOption#74c34319 flags:# months:int currency:string amount:long bot_ur
|
||||||
paymentFormMethod#88f8f21b url:string title:string = PaymentFormMethod;
|
paymentFormMethod#88f8f21b url:string title:string = PaymentFormMethod;
|
||||||
|
|
||||||
emojiStatusEmpty#2de11aae = EmojiStatus;
|
emojiStatusEmpty#2de11aae = EmojiStatus;
|
||||||
emojiStatus#929b619d document_id:long = EmojiStatus;
|
emojiStatus#e7ff068a flags:# document_id:long until:flags.0?int = EmojiStatus;
|
||||||
emojiStatusUntil#fa30a8c7 document_id:long until:int = EmojiStatus;
|
emojiStatusCollectible#7184603b flags:# collectible_id:long document_id:long title:string slug:string pattern_document_id:long center_color:int edge_color:int pattern_color:int text_color:int until:flags.0?int = EmojiStatus;
|
||||||
|
inputEmojiStatusCollectible#7141dbf flags:# collectible_id:long until:flags.0?int = EmojiStatus;
|
||||||
|
|
||||||
account.emojiStatusesNotModified#d08ce645 = account.EmojiStatuses;
|
account.emojiStatusesNotModified#d08ce645 = account.EmojiStatuses;
|
||||||
account.emojiStatuses#90c467d1 hash:long statuses:Vector<EmojiStatus> = account.EmojiStatuses;
|
account.emojiStatuses#90c467d1 hash:long statuses:Vector<EmojiStatus> = account.EmojiStatuses;
|
||||||
|
@ -2077,6 +2078,7 @@ account.updatePersonalChannel#d94305e0 channel:InputChannel = Bool;
|
||||||
account.toggleSponsoredMessages#b9d9a38d enabled:Bool = Bool;
|
account.toggleSponsoredMessages#b9d9a38d enabled:Bool = Bool;
|
||||||
account.getReactionsNotifySettings#6dd654c = ReactionsNotifySettings;
|
account.getReactionsNotifySettings#6dd654c = ReactionsNotifySettings;
|
||||||
account.setReactionsNotifySettings#316ce548 settings:ReactionsNotifySettings = ReactionsNotifySettings;
|
account.setReactionsNotifySettings#316ce548 settings:ReactionsNotifySettings = ReactionsNotifySettings;
|
||||||
|
account.getCollectibleEmojiStatuses#2e7b4543 hash:long = account.EmojiStatuses;
|
||||||
|
|
||||||
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
|
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
|
||||||
users.getFullUser#b60f5918 id:InputUser = users.UserFull;
|
users.getFullUser#b60f5918 id:InputUser = users.UserFull;
|
||||||
|
@ -2639,4 +2641,4 @@ smsjobs.finishJob#4f1ebf24 flags:# job_id:string error:flags.0?string = Bool;
|
||||||
|
|
||||||
fragment.getCollectibleInfo#be1e85ba collectible:InputCollectible = fragment.CollectibleInfo;
|
fragment.getCollectibleInfo#be1e85ba collectible:InputCollectible = fragment.CollectibleInfo;
|
||||||
|
|
||||||
// LAYER 197
|
// LAYER 198
|
||||||
|
|
|
@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "core/ui_integration.h" // MarkedTextContext.
|
#include "core/ui_integration.h" // MarkedTextContext.
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
#include "data/data_document_media.h"
|
#include "data/data_document_media.h"
|
||||||
|
#include "data/data_emoji_statuses.h"
|
||||||
#include "data/data_peer_values.h"
|
#include "data/data_peer_values.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/stickers/data_custom_emoji.h" // SerializeCustomEmojiId.
|
#include "data/stickers/data_custom_emoji.h" // SerializeCustomEmojiId.
|
||||||
|
@ -606,9 +607,12 @@ TopBarUser::TopBarUser(
|
||||||
|
|
||||||
auto documentValue = Info::Profile::EmojiStatusIdValue(
|
auto documentValue = Info::Profile::EmojiStatusIdValue(
|
||||||
peer
|
peer
|
||||||
) | rpl::map([=](DocumentId id) -> DocumentData* {
|
) | rpl::map([=](EmojiStatusId id) -> DocumentData* {
|
||||||
const auto document = id
|
const auto documentId = id.collectible
|
||||||
? controller->session().data().document(id).get()
|
? id.collectible->documentId
|
||||||
|
: id.documentId;
|
||||||
|
const auto document = documentId
|
||||||
|
? controller->session().data().document(documentId).get()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
return (document && document->sticker()) ? document : nullptr;
|
return (document && document->sticker()) ? document : nullptr;
|
||||||
});
|
});
|
||||||
|
@ -1184,7 +1188,7 @@ QPointer<Ui::RpWidget> Premium::createPinnedToBottom(
|
||||||
if (const auto peer = data.peer(emojiStatusData.peerId)) {
|
if (const auto peer = data.peer(emojiStatusData.peerId)) {
|
||||||
return Info::Profile::EmojiStatusIdValue(
|
return Info::Profile::EmojiStatusIdValue(
|
||||||
peer
|
peer
|
||||||
) | rpl::map([=](DocumentId id) {
|
) | rpl::map([=](EmojiStatusId id) {
|
||||||
return id
|
return id
|
||||||
? tr::lng_premium_emoji_status_button()
|
? tr::lng_premium_emoji_status_button()
|
||||||
: _buttonText.value();
|
: _buttonText.value();
|
||||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "ui/unread_badge.h"
|
#include "ui/unread_badge.h"
|
||||||
|
|
||||||
|
#include "data/data_emoji_statuses.h"
|
||||||
#include "data/data_peer.h"
|
#include "data/data_peer.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
@ -26,7 +27,7 @@ constexpr auto kPlayStatusLimit = 2;
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
struct PeerBadge::EmojiStatus {
|
struct PeerBadge::EmojiStatus {
|
||||||
DocumentId id = 0;
|
EmojiStatusId id;
|
||||||
std::unique_ptr<Ui::Text::CustomEmoji> emoji;
|
std::unique_ptr<Ui::Text::CustomEmoji> emoji;
|
||||||
int skip = 0;
|
int skip = 0;
|
||||||
};
|
};
|
||||||
|
@ -238,11 +239,17 @@ int PeerBadge::drawPremiumEmojiStatus(
|
||||||
using namespace Ui::Text;
|
using namespace Ui::Text;
|
||||||
auto &manager = peer->session().data().customEmojiManager();
|
auto &manager = peer->session().data().customEmojiManager();
|
||||||
_emojiStatus->id = id;
|
_emojiStatus->id = id;
|
||||||
_emojiStatus->emoji = std::make_unique<LimitedLoopsEmoji>(
|
_emojiStatus->emoji = id.collectible // todo collectibles
|
||||||
manager.create(
|
? std::make_unique<LimitedLoopsEmoji>(
|
||||||
id,
|
manager.create(
|
||||||
descriptor.customEmojiRepaint),
|
id.collectible->documentId,
|
||||||
kPlayStatusLimit);
|
descriptor.customEmojiRepaint),
|
||||||
|
kPlayStatusLimit)
|
||||||
|
: std::make_unique<LimitedLoopsEmoji>(
|
||||||
|
manager.create(
|
||||||
|
id.documentId,
|
||||||
|
descriptor.customEmojiRepaint),
|
||||||
|
kPlayStatusLimit);
|
||||||
}
|
}
|
||||||
_emojiStatus->emoji->paint(p, {
|
_emojiStatus->emoji->paint(p, {
|
||||||
.textColor = (*descriptor.premiumFg)->c,
|
.textColor = (*descriptor.premiumFg)->c,
|
||||||
|
|
|
@ -179,7 +179,7 @@ void ShowCallsBox(not_null<Window::SessionController*> window) {
|
||||||
self,
|
self,
|
||||||
Data::PeerUpdate::Flag::EmojiStatus
|
Data::PeerUpdate::Flag::EmojiStatus
|
||||||
) | rpl::map([=] {
|
) | rpl::map([=] {
|
||||||
return (self->emojiStatusId() != 0);
|
return !!self->emojiStatusId();
|
||||||
}) | rpl::distinct_until_changed() | rpl::map([](bool has) {
|
}) | rpl::distinct_until_changed() | rpl::map([](bool has) {
|
||||||
const auto makeLink = [](const QString &text) {
|
const auto makeLink = [](const QString &text) {
|
||||||
return Ui::Text::Link(text);
|
return Ui::Text::Link(text);
|
||||||
|
|
Loading…
Add table
Reference in a new issue