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