mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Update API scheme on layer 166.
This commit is contained in:
parent
744c1b925e
commit
926aae6847
18 changed files with 801 additions and 75 deletions
|
@ -677,6 +677,8 @@ PRIVATE
|
||||||
history/view/media/history_view_game.h
|
history/view/media/history_view_game.h
|
||||||
history/view/media/history_view_gif.cpp
|
history/view/media/history_view_gif.cpp
|
||||||
history/view/media/history_view_gif.h
|
history/view/media/history_view_gif.h
|
||||||
|
history/view/media/history_view_giveaway.cpp
|
||||||
|
history/view/media/history_view_giveaway.h
|
||||||
history/view/media/history_view_invoice.cpp
|
history/view/media/history_view_invoice.cpp
|
||||||
history/view/media/history_view_invoice.h
|
history/view/media/history_view_invoice.h
|
||||||
history/view/media/history_view_large_emoji.cpp
|
history/view/media/history_view_large_emoji.cpp
|
||||||
|
|
|
@ -2076,13 +2076,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
"lng_prize_title" = "Congratulations!";
|
"lng_prize_title" = "Congratulations!";
|
||||||
"lng_prize_about" = "You won a prize in a giveaway organized by {channel}.";
|
"lng_prize_about" = "You won a prize in a giveaway organized by {channel}.";
|
||||||
"lng_prize_duration" = "Your prize is **Telegram Premium** subscription for {duration}.";
|
"lng_prize_duration" = "Your prize is a **Telegram Premium** subscription for {duration}.";
|
||||||
|
"lng_prize_gift_about" = "You've received a gift from {channel}.";
|
||||||
|
"lng_prize_gift_duration" = "Your gift is a **Telegram Premium** subscription for {duration}.";
|
||||||
"lng_prize_open" = "Open Gift Link";
|
"lng_prize_open" = "Open Gift Link";
|
||||||
|
|
||||||
"lng_prizes_title#one" = "Giveaway Prize";
|
"lng_prizes_title#one" = "Giveaway Prize";
|
||||||
"lng_prizes_title#other" = "Giveaway Prizes";
|
"lng_prizes_title#other" = "Giveaway Prizes";
|
||||||
"lng_prizes_about#one" = "{count} Telegram Premium Subscription for {duration}.";
|
"lng_prizes_about#one" = "**{count}** Telegram Premium Subscription for {duration}.";
|
||||||
"lng_prizes_about#other" = "{count} Telegram Premium Subscriptions for {duration}.";
|
"lng_prizes_about#other" = "**{count}** Telegram Premium Subscriptions for {duration}.";
|
||||||
"lng_prizes_participants" = "Participants";
|
"lng_prizes_participants" = "Participants";
|
||||||
"lng_prizes_participants_all#one" = "All subscribers of the channel:";
|
"lng_prizes_participants_all#one" = "All subscribers of the channel:";
|
||||||
"lng_prizes_participants_all#other" = "All subscribers of the channels:";
|
"lng_prizes_participants_all#other" = "All subscribers of the channels:";
|
||||||
|
|
|
@ -2134,15 +2134,16 @@ void ApiWrap::saveDraftsToCloud() {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto flags = MTPmessages_SaveDraft::Flags(0);
|
auto flags = MTPmessages_SaveDraft::Flags(0);
|
||||||
|
auto replyFlags = MTPDinputReplyToMessage::Flags(0);
|
||||||
auto &textWithTags = cloudDraft->textWithTags;
|
auto &textWithTags = cloudDraft->textWithTags;
|
||||||
if (cloudDraft->previewState != Data::PreviewState::Allowed) {
|
if (cloudDraft->previewState != Data::PreviewState::Allowed) {
|
||||||
flags |= MTPmessages_SaveDraft::Flag::f_no_webpage;
|
flags |= MTPmessages_SaveDraft::Flag::f_no_webpage;
|
||||||
}
|
}
|
||||||
if (cloudDraft->msgId) {
|
if (cloudDraft->msgId || cloudDraft->topicRootId) {
|
||||||
flags |= MTPmessages_SaveDraft::Flag::f_reply_to_msg_id;
|
flags |= MTPmessages_SaveDraft::Flag::f_reply_to;
|
||||||
}
|
if (cloudDraft->topicRootId) {
|
||||||
if (cloudDraft->topicRootId) {
|
replyFlags |= MTPDinputReplyToMessage::Flag::f_top_msg_id;
|
||||||
flags |= MTPmessages_SaveDraft::Flag::f_top_msg_id;
|
}
|
||||||
}
|
}
|
||||||
if (!textWithTags.tags.isEmpty()) {
|
if (!textWithTags.tags.isEmpty()) {
|
||||||
flags |= MTPmessages_SaveDraft::Flag::f_entities;
|
flags |= MTPmessages_SaveDraft::Flag::f_entities;
|
||||||
|
@ -2155,8 +2156,15 @@ void ApiWrap::saveDraftsToCloud() {
|
||||||
history->startSavingCloudDraft(topicRootId);
|
history->startSavingCloudDraft(topicRootId);
|
||||||
cloudDraft->saveRequestId = request(MTPmessages_SaveDraft(
|
cloudDraft->saveRequestId = request(MTPmessages_SaveDraft(
|
||||||
MTP_flags(flags),
|
MTP_flags(flags),
|
||||||
MTP_int(cloudDraft->msgId),
|
MTP_inputReplyToMessage(
|
||||||
MTP_int(cloudDraft->topicRootId),
|
MTP_flags(replyFlags),
|
||||||
|
MTP_int(cloudDraft->msgId
|
||||||
|
? cloudDraft->msgId
|
||||||
|
: cloudDraft->topicRootId),
|
||||||
|
MTP_int(cloudDraft->topicRootId),
|
||||||
|
MTPInputPeer(), // reply_to_peer_id
|
||||||
|
MTPstring(), // quote_text
|
||||||
|
MTPVector<MTPMessageEntity>()), // quote_entities
|
||||||
history->peer->input,
|
history->peer->input,
|
||||||
MTP_string(textWithTags.text),
|
MTP_string(textWithTags.text),
|
||||||
entities
|
entities
|
||||||
|
|
|
@ -64,7 +64,18 @@ void ApplyPeerCloudDraft(
|
||||||
session,
|
session,
|
||||||
draft.ventities().value_or_empty()))
|
draft.ventities().value_or_empty()))
|
||||||
};
|
};
|
||||||
const auto replyTo = draft.vreply_to_msg_id().value_or_empty();
|
auto replyTo = MsgId();
|
||||||
|
if (const auto reply = draft.vreply_to()) {
|
||||||
|
reply->match([&](const MTPDmessageReplyHeader &data) {
|
||||||
|
if (!data.vreply_to_peer_id()
|
||||||
|
|| (peerFromMTP(*data.vreply_to_peer_id()) == peerId)) {
|
||||||
|
replyTo = data.vreply_to_msg_id().value_or_empty();
|
||||||
|
} else {
|
||||||
|
// #TODO replies
|
||||||
|
}
|
||||||
|
}, [&](const MTPDmessageReplyStoryHeader &data) {
|
||||||
|
});
|
||||||
|
}
|
||||||
auto cloudDraft = std::make_unique<Draft>(
|
auto cloudDraft = std::make_unique<Draft>(
|
||||||
textWithTags,
|
textWithTags,
|
||||||
replyTo,
|
replyTo,
|
||||||
|
|
|
@ -45,12 +45,15 @@ MTPInputReplyTo ReplyToForMTP(
|
||||||
}
|
}
|
||||||
} else if (replyTo.msgId || replyTo.topicRootId) {
|
} else if (replyTo.msgId || replyTo.topicRootId) {
|
||||||
using Flag = MTPDinputReplyToMessage::Flag;
|
using Flag = MTPDinputReplyToMessage::Flag;
|
||||||
return MTP_inputReplyToMessage(
|
return MTP_inputReplyToMessage( // #TODO replies
|
||||||
(replyTo.topicRootId
|
(replyTo.topicRootId
|
||||||
? MTP_flags(Flag::f_top_msg_id)
|
? MTP_flags(Flag::f_top_msg_id)
|
||||||
: MTP_flags(0)),
|
: MTP_flags(0)),
|
||||||
MTP_int(replyTo.msgId ? replyTo.msgId : replyTo.topicRootId),
|
MTP_int(replyTo.msgId ? replyTo.msgId : replyTo.topicRootId),
|
||||||
MTP_int(replyTo.topicRootId));
|
MTP_int(replyTo.topicRootId),
|
||||||
|
MTPInputPeer(), // reply_to_peer_id
|
||||||
|
MTPstring(), // quote_text
|
||||||
|
MTPVector<MTPMessageEntity>()); // quote_entities
|
||||||
}
|
}
|
||||||
return MTPInputReplyTo();
|
return MTPInputReplyTo();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/view/media/history_view_contact.h"
|
#include "history/view/media/history_view_contact.h"
|
||||||
#include "history/view/media/history_view_location.h"
|
#include "history/view/media/history_view_location.h"
|
||||||
#include "history/view/media/history_view_game.h"
|
#include "history/view/media/history_view_game.h"
|
||||||
|
#include "history/view/media/history_view_giveaway.h"
|
||||||
#include "history/view/media/history_view_invoice.h"
|
#include "history/view/media/history_view_invoice.h"
|
||||||
#include "history/view/media/history_view_call.h"
|
#include "history/view/media/history_view_call.h"
|
||||||
#include "history/view/media/history_view_web_page.h"
|
#include "history/view/media/history_view_web_page.h"
|
||||||
|
@ -361,6 +362,22 @@ Call ComputeCallData(const MTPDmessageActionPhoneCall &call) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Giveaway ComputeGiveawayData(
|
||||||
|
not_null<HistoryItem*> item,
|
||||||
|
const MTPDmessageMediaGiveaway &data) {
|
||||||
|
auto result = Giveaway{
|
||||||
|
.untilDate = data.vuntil_date().v,
|
||||||
|
.quantity = data.vquantity().v,
|
||||||
|
.months = data.vmonths().v,
|
||||||
|
};
|
||||||
|
result.channels.reserve(data.vchannels().v.size());
|
||||||
|
const auto owner = &item->history()->owner();
|
||||||
|
for (const auto &id : data.vchannels().v) {
|
||||||
|
result.channels.push_back(owner->channel(ChannelId(id)));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
Media::Media(not_null<HistoryItem*> parent) : _parent(parent) {
|
Media::Media(not_null<HistoryItem*> parent) : _parent(parent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,6 +437,10 @@ bool Media::storyMention() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Giveaway *Media::giveaway() const {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool Media::uploading() const {
|
bool Media::uploading() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2144,4 +2165,50 @@ std::unique_ptr<HistoryView::Media> MediaStory::createView(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MediaGiveaway::MediaGiveaway(
|
||||||
|
not_null<HistoryItem*> parent,
|
||||||
|
const Giveaway &data)
|
||||||
|
: Media(parent)
|
||||||
|
, _giveaway(data) {
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Media> MediaGiveaway::clone(not_null<HistoryItem*> parent) {
|
||||||
|
return std::make_unique<MediaGiveaway>(parent, _giveaway);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Giveaway *MediaGiveaway::giveaway() const {
|
||||||
|
return &_giveaway;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextWithEntities MediaGiveaway::notificationText() const {
|
||||||
|
return {
|
||||||
|
.text = tr::lng_prizes_title(tr::now, lt_count, _giveaway.quantity),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
QString MediaGiveaway::pinnedTextSubstring() const {
|
||||||
|
return QString::fromUtf8("\xC2\xAB")
|
||||||
|
+ notificationText().text
|
||||||
|
+ QString::fromUtf8("\xC2\xBB");
|
||||||
|
}
|
||||||
|
|
||||||
|
TextForMimeData MediaGiveaway::clipboardText() const {
|
||||||
|
return TextForMimeData();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MediaGiveaway::updateInlineResultMedia(const MTPMessageMedia &media) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MediaGiveaway::updateSentMedia(const MTPMessageMedia &media) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<HistoryView::Media> MediaGiveaway::createView(
|
||||||
|
not_null<HistoryView::Element*> message,
|
||||||
|
not_null<HistoryItem*> realParent,
|
||||||
|
HistoryView::Element *replacing) {
|
||||||
|
return std::make_unique<HistoryView::Giveaway>(message, &_giveaway);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
|
@ -90,6 +90,14 @@ struct Invoice {
|
||||||
bool isTest = false;
|
bool isTest = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Giveaway {
|
||||||
|
std::vector<not_null<ChannelData*>> channels;
|
||||||
|
TimeId untilDate = 0;
|
||||||
|
int quantity = 0;
|
||||||
|
int months = 0;
|
||||||
|
bool all = false;
|
||||||
|
};
|
||||||
|
|
||||||
class Media {
|
class Media {
|
||||||
public:
|
public:
|
||||||
Media(not_null<HistoryItem*> parent);
|
Media(not_null<HistoryItem*> parent);
|
||||||
|
@ -116,6 +124,7 @@ public:
|
||||||
virtual FullStoryId storyId() const;
|
virtual FullStoryId storyId() const;
|
||||||
virtual bool storyExpired(bool revalidate = false);
|
virtual bool storyExpired(bool revalidate = false);
|
||||||
virtual bool storyMention() const;
|
virtual bool storyMention() const;
|
||||||
|
virtual const Giveaway *giveaway() const;
|
||||||
|
|
||||||
virtual bool uploading() const;
|
virtual bool uploading() const;
|
||||||
virtual Storage::SharedMediaTypesMask sharedMediaTypes() const;
|
virtual Storage::SharedMediaTypesMask sharedMediaTypes() const;
|
||||||
|
@ -605,6 +614,32 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MediaGiveaway final : public Media {
|
||||||
|
public:
|
||||||
|
MediaGiveaway(
|
||||||
|
not_null<HistoryItem*> parent,
|
||||||
|
const Giveaway &data);
|
||||||
|
|
||||||
|
std::unique_ptr<Media> clone(not_null<HistoryItem*> parent) override;
|
||||||
|
|
||||||
|
const Giveaway *giveaway() const override;
|
||||||
|
|
||||||
|
TextWithEntities notificationText() const override;
|
||||||
|
QString pinnedTextSubstring() const override;
|
||||||
|
TextForMimeData clipboardText() const override;
|
||||||
|
|
||||||
|
bool updateInlineResultMedia(const MTPMessageMedia &media) override;
|
||||||
|
bool updateSentMedia(const MTPMessageMedia &media) override;
|
||||||
|
std::unique_ptr<HistoryView::Media> createView(
|
||||||
|
not_null<HistoryView::Element*> message,
|
||||||
|
not_null<HistoryItem*> realParent,
|
||||||
|
HistoryView::Element *replacing = nullptr) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Giveaway _giveaway;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
[[nodiscard]] TextForMimeData WithCaptionClipboardText(
|
[[nodiscard]] TextForMimeData WithCaptionClipboardText(
|
||||||
const QString &attachType,
|
const QString &attachType,
|
||||||
TextForMimeData &&caption);
|
TextForMimeData &&caption);
|
||||||
|
@ -615,4 +650,8 @@ private:
|
||||||
|
|
||||||
[[nodiscard]] Call ComputeCallData(const MTPDmessageActionPhoneCall &call);
|
[[nodiscard]] Call ComputeCallData(const MTPDmessageActionPhoneCall &call);
|
||||||
|
|
||||||
|
[[nodiscard]] Giveaway ComputeGiveawayData(
|
||||||
|
not_null<HistoryItem*> item,
|
||||||
|
const MTPDmessageMediaGiveaway &data);
|
||||||
|
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
|
@ -576,6 +576,18 @@ Poll ParsePoll(const MTPDmessageMediaPoll &data) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Giveaway ParseGiveaway(const MTPDmessageMediaGiveaway &data) {
|
||||||
|
auto result = Giveaway{
|
||||||
|
.untilDate = data.vuntil_date().v,
|
||||||
|
.quantity = data.vquantity().v,
|
||||||
|
.months = data.vmonths().v,
|
||||||
|
};
|
||||||
|
for (const auto &id : data.vchannels().v) {
|
||||||
|
result.channels.push_back(ChannelId(id));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
UserpicsSlice ParseUserpicsSlice(
|
UserpicsSlice ParseUserpicsSlice(
|
||||||
const MTPVector<MTPPhoto> &data,
|
const MTPVector<MTPPhoto> &data,
|
||||||
int baseIndex) {
|
int baseIndex) {
|
||||||
|
@ -1057,7 +1069,9 @@ Media ParseMedia(
|
||||||
}, [](const MTPDmessageMediaDice &data) {
|
}, [](const MTPDmessageMediaDice &data) {
|
||||||
// #TODO dice
|
// #TODO dice
|
||||||
}, [](const MTPDmessageMediaStory &data) {
|
}, [](const MTPDmessageMediaStory &data) {
|
||||||
// #TODO stories export
|
// #TODO export stories
|
||||||
|
}, [&](const MTPDmessageMediaGiveaway &data) {
|
||||||
|
result.content = ParseGiveaway(data);
|
||||||
}, [](const MTPDmessageMediaEmpty &data) {});
|
}, [](const MTPDmessageMediaEmpty &data) {});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1298,6 +1312,14 @@ ServiceAction ParseServiceAction(
|
||||||
content.peerId = ParsePeerId(data.vpeer());
|
content.peerId = ParsePeerId(data.vpeer());
|
||||||
content.buttonId = data.vbutton_id().v;
|
content.buttonId = data.vbutton_id().v;
|
||||||
result.content = content;
|
result.content = content;
|
||||||
|
}, [&](const MTPDmessageActionGiftCode &data) {
|
||||||
|
auto content = ActionGiftCode();
|
||||||
|
content.boostPeerId = data.vboost_peer()
|
||||||
|
? peerFromMTP(*data.vboost_peer())
|
||||||
|
: PeerId();
|
||||||
|
content.viaGiveaway = data.is_via_giveaway();
|
||||||
|
content.months = data.vmonths().v;
|
||||||
|
content.code = data.vslug().v;
|
||||||
}, [](const MTPDmessageActionEmpty &data) {});
|
}, [](const MTPDmessageActionEmpty &data) {});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1358,15 +1380,19 @@ Message ParseMessage(
|
||||||
}
|
}
|
||||||
if (const auto replyTo = data.vreply_to()) {
|
if (const auto replyTo = data.vreply_to()) {
|
||||||
replyTo->match([&](const MTPDmessageReplyHeader &data) {
|
replyTo->match([&](const MTPDmessageReplyHeader &data) {
|
||||||
result.replyToMsgId = data.vreply_to_msg_id().v;
|
if (const auto replyToMsg = data.vreply_to_msg_id()) {
|
||||||
result.replyToPeerId = data.vreply_to_peer_id()
|
result.replyToMsgId = replyToMsg->v;
|
||||||
? ParsePeerId(*data.vreply_to_peer_id())
|
result.replyToPeerId = data.vreply_to_peer_id()
|
||||||
: 0;
|
? ParsePeerId(*data.vreply_to_peer_id())
|
||||||
if (result.replyToPeerId == result.peerId) {
|
: 0;
|
||||||
result.replyToPeerId = 0;
|
if (result.replyToPeerId == result.peerId) {
|
||||||
|
result.replyToPeerId = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// #TODO export replies
|
||||||
}
|
}
|
||||||
}, [&](const MTPDmessageReplyStoryHeader &data) {
|
}, [&](const MTPDmessageReplyStoryHeader &data) {
|
||||||
// #TODO stories export
|
// #TODO export stories
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1410,12 +1436,16 @@ Message ParseMessage(
|
||||||
}
|
}
|
||||||
if (const auto replyTo = data.vreply_to()) {
|
if (const auto replyTo = data.vreply_to()) {
|
||||||
replyTo->match([&](const MTPDmessageReplyHeader &data) {
|
replyTo->match([&](const MTPDmessageReplyHeader &data) {
|
||||||
result.replyToMsgId = data.vreply_to_msg_id().v;
|
if (const auto replyToMsg = data.vreply_to_msg_id()) {
|
||||||
result.replyToPeerId = data.vreply_to_peer_id()
|
result.replyToMsgId = replyToMsg->v;
|
||||||
? ParsePeerId(*data.vreply_to_peer_id())
|
result.replyToPeerId = data.vreply_to_peer_id()
|
||||||
: PeerId(0);
|
? ParsePeerId(*data.vreply_to_peer_id())
|
||||||
|
: PeerId(0);
|
||||||
|
} else {
|
||||||
|
// #TODO export replies
|
||||||
|
}
|
||||||
}, [&](const MTPDmessageReplyStoryHeader &data) {
|
}, [&](const MTPDmessageReplyStoryHeader &data) {
|
||||||
// #TODO stories export
|
// #TODO export stories
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (const auto viaBotId = data.vvia_bot_id()) {
|
if (const auto viaBotId = data.vvia_bot_id()) {
|
||||||
|
|
|
@ -196,6 +196,13 @@ struct Poll {
|
||||||
bool closed = false;
|
bool closed = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Giveaway {
|
||||||
|
std::vector<ChannelId> channels;
|
||||||
|
TimeId untilDate = 0;
|
||||||
|
int quantity = 0;
|
||||||
|
int months = 0;
|
||||||
|
};
|
||||||
|
|
||||||
struct UserpicsSlice {
|
struct UserpicsSlice {
|
||||||
std::vector<Photo> list;
|
std::vector<Photo> list;
|
||||||
};
|
};
|
||||||
|
@ -325,6 +332,7 @@ struct Media {
|
||||||
Game,
|
Game,
|
||||||
Invoice,
|
Invoice,
|
||||||
Poll,
|
Poll,
|
||||||
|
Giveaway,
|
||||||
UnsupportedMedia> content;
|
UnsupportedMedia> content;
|
||||||
TimeId ttl = 0;
|
TimeId ttl = 0;
|
||||||
|
|
||||||
|
@ -527,6 +535,13 @@ struct ActionSetChatWallPaper {
|
||||||
struct ActionSetSameChatWallPaper {
|
struct ActionSetSameChatWallPaper {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ActionGiftCode {
|
||||||
|
QByteArray code;
|
||||||
|
PeerId boostPeerId = 0;
|
||||||
|
int months = 0;
|
||||||
|
bool viaGiveaway = false;
|
||||||
|
};
|
||||||
|
|
||||||
struct ActionRequestedPeer {
|
struct ActionRequestedPeer {
|
||||||
PeerId peerId = 0;
|
PeerId peerId = 0;
|
||||||
int buttonId = 0;
|
int buttonId = 0;
|
||||||
|
@ -570,7 +585,8 @@ struct ServiceAction {
|
||||||
ActionSuggestProfilePhoto,
|
ActionSuggestProfilePhoto,
|
||||||
ActionRequestedPeer,
|
ActionRequestedPeer,
|
||||||
ActionSetChatWallPaper,
|
ActionSetChatWallPaper,
|
||||||
ActionSetSameChatWallPaper> content;
|
ActionSetSameChatWallPaper,
|
||||||
|
ActionGiftCode> content;
|
||||||
};
|
};
|
||||||
|
|
||||||
ServiceAction ParseServiceAction(
|
ServiceAction ParseServiceAction(
|
||||||
|
|
|
@ -611,6 +611,9 @@ private:
|
||||||
const Data::Photo &data,
|
const Data::Photo &data,
|
||||||
const QString &basePath);
|
const QString &basePath);
|
||||||
[[nodiscard]] QByteArray pushPoll(const Data::Poll &data);
|
[[nodiscard]] QByteArray pushPoll(const Data::Poll &data);
|
||||||
|
[[nodiscard]] QByteArray pushGiveaway(
|
||||||
|
const PeersMap &peers,
|
||||||
|
const Data::Giveaway &data);
|
||||||
|
|
||||||
File _file;
|
File _file;
|
||||||
QByteArray _composedStart;
|
QByteArray _composedStart;
|
||||||
|
@ -1276,6 +1279,16 @@ auto HtmlWriter::Wrap::pushMessage(
|
||||||
+ " set "
|
+ " set "
|
||||||
+ wrapReplyToLink("the same background")
|
+ wrapReplyToLink("the same background")
|
||||||
+ " for this chat";
|
+ " for this chat";
|
||||||
|
}, [&](const ActionGiftCode &data) {
|
||||||
|
return data.viaGiveaway
|
||||||
|
? ("You won a Telegram Premium for "
|
||||||
|
+ NumberToString(data.months)
|
||||||
|
+ (data.months > 1 ? " months" : "month")
|
||||||
|
+ " prize in a giveaway organized by a channel.")
|
||||||
|
: ("You've received a Telegram Premium for "
|
||||||
|
+ NumberToString(data.months)
|
||||||
|
+ (data.months > 1 ? " months" : "month")
|
||||||
|
+ " gift from a channel.");
|
||||||
}, [](v::null_t) { return QByteArray(); });
|
}, [](v::null_t) { return QByteArray(); });
|
||||||
|
|
||||||
if (!serviceText.isEmpty()) {
|
if (!serviceText.isEmpty()) {
|
||||||
|
@ -1459,8 +1472,9 @@ QByteArray HtmlWriter::Wrap::pushMedia(
|
||||||
if (!data.classes.isEmpty()) {
|
if (!data.classes.isEmpty()) {
|
||||||
return pushGenericMedia(data);
|
return pushGenericMedia(data);
|
||||||
}
|
}
|
||||||
|
using namespace Data;
|
||||||
const auto &content = message.media.content;
|
const auto &content = message.media.content;
|
||||||
if (const auto document = std::get_if<Data::Document>(&content)) {
|
if (const auto document = std::get_if<Document>(&content)) {
|
||||||
Assert(!message.media.ttl);
|
Assert(!message.media.ttl);
|
||||||
if (document->isSticker) {
|
if (document->isSticker) {
|
||||||
return pushStickerMedia(*document, basePath);
|
return pushStickerMedia(*document, basePath);
|
||||||
|
@ -1470,11 +1484,13 @@ QByteArray HtmlWriter::Wrap::pushMedia(
|
||||||
return pushVideoFileMedia(*document, basePath);
|
return pushVideoFileMedia(*document, basePath);
|
||||||
}
|
}
|
||||||
Unexpected("Non generic document in HtmlWriter::Wrap::pushMedia.");
|
Unexpected("Non generic document in HtmlWriter::Wrap::pushMedia.");
|
||||||
} else if (const auto photo = std::get_if<Data::Photo>(&content)) {
|
} else if (const auto photo = std::get_if<Photo>(&content)) {
|
||||||
Assert(!message.media.ttl);
|
Assert(!message.media.ttl);
|
||||||
return pushPhotoMedia(*photo, basePath);
|
return pushPhotoMedia(*photo, basePath);
|
||||||
} else if (const auto poll = std::get_if<Data::Poll>(&content)) {
|
} else if (const auto poll = std::get_if<Poll>(&content)) {
|
||||||
return pushPoll(*poll);
|
return pushPoll(*poll);
|
||||||
|
} else if (const auto giveaway = std::get_if<Giveaway>(&content)) {
|
||||||
|
return pushGiveaway(peers, *giveaway);
|
||||||
}
|
}
|
||||||
Assert(v::is_null(content));
|
Assert(v::is_null(content));
|
||||||
return QByteArray();
|
return QByteArray();
|
||||||
|
@ -1796,6 +1812,52 @@ QByteArray HtmlWriter::Wrap::pushPoll(const Data::Poll &data) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray HtmlWriter::Wrap::pushGiveaway(
|
||||||
|
const PeersMap &peers,
|
||||||
|
const Data::Giveaway &data) {
|
||||||
|
auto result = pushDiv("media_wrap clearfix");
|
||||||
|
result.append(pushDiv("media_giveaway"));
|
||||||
|
|
||||||
|
result.append(pushDiv("section_title bold"));
|
||||||
|
result.append(SerializeString("Giveaway Prizes"));
|
||||||
|
result.append(popTag());
|
||||||
|
result.append(pushDiv("section_body"));
|
||||||
|
result.append("<b>"
|
||||||
|
+ Data::NumberToString(data.quantity)
|
||||||
|
+ "</b> "
|
||||||
|
+ SerializeString((data.quantity > 1)
|
||||||
|
? "Telegram Premium Subscriptions"
|
||||||
|
: "Telegram Premium Subscription")
|
||||||
|
+ " for <b>" + Data::NumberToString(data.months) + "</b> "
|
||||||
|
+ (data.months > 1 ? "months." : "month."));
|
||||||
|
result.append(popTag());
|
||||||
|
|
||||||
|
result.append(pushDiv("section_title bold"));
|
||||||
|
result.append(SerializeString("Participants"));
|
||||||
|
result.append(popTag());
|
||||||
|
result.append(pushDiv("section_body"));
|
||||||
|
auto channels = QByteArrayList();
|
||||||
|
for (const auto &channel : data.channels) {
|
||||||
|
channels.append("<b>" + peers.wrapPeerName(channel) + "</b>");
|
||||||
|
}
|
||||||
|
result.append(SerializeString((channels.size() > 1)
|
||||||
|
? "All subscribers of those channels: "
|
||||||
|
: "All subscribers of the channel: ")
|
||||||
|
+ channels.join(", "));
|
||||||
|
result.append(popTag());
|
||||||
|
|
||||||
|
result.append(pushDiv("section_title bold"));
|
||||||
|
result.append(SerializeString("Winners Selection Date"));
|
||||||
|
result.append(popTag());
|
||||||
|
result.append(pushDiv("section_body"));
|
||||||
|
result.append(Data::FormatDateTime(data.untilDate));
|
||||||
|
result.append(popTag());
|
||||||
|
|
||||||
|
result.append(popTag());
|
||||||
|
result.append(popTag());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
MediaData HtmlWriter::Wrap::prepareMediaData(
|
MediaData HtmlWriter::Wrap::prepareMediaData(
|
||||||
const Data::Message &message,
|
const Data::Message &message,
|
||||||
const QString &basePath,
|
const QString &basePath,
|
||||||
|
@ -1954,6 +2016,7 @@ MediaData HtmlWriter::Wrap::prepareMediaData(
|
||||||
result.description = data.description;
|
result.description = data.description;
|
||||||
result.status = Data::FormatMoneyAmount(data.amount, data.currency);
|
result.status = Data::FormatMoneyAmount(data.amount, data.currency);
|
||||||
}, [](const Poll &data) {
|
}, [](const Poll &data) {
|
||||||
|
}, [](const Giveaway &data) {
|
||||||
}, [](const UnsupportedMedia &data) {
|
}, [](const UnsupportedMedia &data) {
|
||||||
Unexpected("Unsupported message.");
|
Unexpected("Unsupported message.");
|
||||||
}, [](v::null_t) {});
|
}, [](v::null_t) {});
|
||||||
|
|
|
@ -287,11 +287,12 @@ QByteArray SerializeMessage(
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto push = [&](const QByteArray &key, const auto &value) {
|
const auto push = [&](const QByteArray &key, const auto &value) {
|
||||||
if constexpr (std::is_arithmetic_v<std::decay_t<decltype(value)>>) {
|
using V = std::decay_t<decltype(value)>;
|
||||||
|
if constexpr (std::is_same_v<V, bool>) {
|
||||||
|
pushBare(key, value ? "true" : "false");
|
||||||
|
} else if constexpr (std::is_arithmetic_v<V>) {
|
||||||
pushBare(key, Data::NumberToString(value));
|
pushBare(key, Data::NumberToString(value));
|
||||||
} else if constexpr (std::is_same_v<
|
} else if constexpr (std::is_same_v<V, PeerId>) {
|
||||||
std::decay_t<decltype(value)>,
|
|
||||||
PeerId>) {
|
|
||||||
if (const auto chat = peerToChat(value)) {
|
if (const auto chat = peerToChat(value)) {
|
||||||
pushBare(
|
pushBare(
|
||||||
key,
|
key,
|
||||||
|
@ -592,6 +593,14 @@ QByteArray SerializeMessage(
|
||||||
pushAction("requested_peer");
|
pushAction("requested_peer");
|
||||||
push("button_id", data.buttonId);
|
push("button_id", data.buttonId);
|
||||||
push("peer_id", data.peerId.value);
|
push("peer_id", data.peerId.value);
|
||||||
|
}, [&](const ActionGiftCode &data) {
|
||||||
|
pushAction("gift_code_prize");
|
||||||
|
push("gift_code", data.code);
|
||||||
|
if (data.boostPeerId) {
|
||||||
|
push("boost_peer_id", data.boostPeerId);
|
||||||
|
}
|
||||||
|
push("months", data.months);
|
||||||
|
push("via_giveaway", data.viaGiveaway);
|
||||||
}, [&](const ActionSetChatWallPaper &data) {
|
}, [&](const ActionSetChatWallPaper &data) {
|
||||||
pushActor();
|
pushActor();
|
||||||
pushAction("set_chat_wallpaper");
|
pushAction("set_chat_wallpaper");
|
||||||
|
@ -738,6 +747,22 @@ QByteArray SerializeMessage(
|
||||||
{ "total_voters", NumberToString(data.totalVotes) },
|
{ "total_voters", NumberToString(data.totalVotes) },
|
||||||
{ "answers", serialized }
|
{ "answers", serialized }
|
||||||
}));
|
}));
|
||||||
|
}, [&](const Giveaway &data) {
|
||||||
|
context.nesting.push_back(Context::kObject);
|
||||||
|
const auto channels = ranges::views::all(
|
||||||
|
data.channels
|
||||||
|
) | ranges::views::transform([&](ChannelId id) {
|
||||||
|
return NumberToString(id.bare);
|
||||||
|
}) | ranges::to_vector;
|
||||||
|
const auto serialized = SerializeArray(context, channels);
|
||||||
|
context.nesting.pop_back();
|
||||||
|
|
||||||
|
push("giveaway_information", SerializeObject(context, {
|
||||||
|
{ "quantity", NumberToString(data.quantity) },
|
||||||
|
{ "months", NumberToString(data.months) },
|
||||||
|
{ "until_date", SerializeDate(data.untilDate) },
|
||||||
|
{ "channels", serialized },
|
||||||
|
}));
|
||||||
}, [](const UnsupportedMedia &data) {
|
}, [](const UnsupportedMedia &data) {
|
||||||
Unexpected("Unsupported message.");
|
Unexpected("Unsupported message.");
|
||||||
}, [](v::null_t) {});
|
}, [](v::null_t) {});
|
||||||
|
|
|
@ -1127,8 +1127,8 @@ void History::applyServiceChanges(
|
||||||
}, [&](const MTPDmessageActionPinMessage &data) {
|
}, [&](const MTPDmessageActionPinMessage &data) {
|
||||||
if (replyTo) {
|
if (replyTo) {
|
||||||
replyTo->match([&](const MTPDmessageReplyHeader &data) {
|
replyTo->match([&](const MTPDmessageReplyHeader &data) {
|
||||||
const auto id = data.vreply_to_msg_id().v;
|
const auto id = data.vreply_to_msg_id().value_or_empty();
|
||||||
if (item) {
|
if (id && item) {
|
||||||
session().storage().add(Storage::SharedMediaAddSlice(
|
session().storage().add(Storage::SharedMediaAddSlice(
|
||||||
peer->id,
|
peer->id,
|
||||||
MsgId(0),
|
MsgId(0),
|
||||||
|
|
|
@ -291,6 +291,10 @@ std::unique_ptr<Data::Media> HistoryItem::CreateMedia(
|
||||||
peerFromMTP(media.vpeer()),
|
peerFromMTP(media.vpeer()),
|
||||||
media.vid().v,
|
media.vid().v,
|
||||||
}, media.is_via_mention());
|
}, media.is_via_mention());
|
||||||
|
}, [&](const MTPDmessageMediaGiveaway &media) -> Result {
|
||||||
|
return std::make_unique<Data::MediaGiveaway>(
|
||||||
|
item,
|
||||||
|
Data::ComputeGiveawayData(item, media));
|
||||||
}, [](const MTPDmessageMediaEmpty &) -> Result {
|
}, [](const MTPDmessageMediaEmpty &) -> Result {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}, [](const MTPDmessageMediaUnsupported &) -> Result {
|
}, [](const MTPDmessageMediaUnsupported &) -> Result {
|
||||||
|
@ -1621,11 +1625,18 @@ void HistoryItem::applySentMessage(const MTPDmessage &data) {
|
||||||
setForwardsCount(data.vforwards().value_or(-1));
|
setForwardsCount(data.vforwards().value_or(-1));
|
||||||
if (const auto reply = data.vreply_to()) {
|
if (const auto reply = data.vreply_to()) {
|
||||||
reply->match([&](const MTPDmessageReplyHeader &data) {
|
reply->match([&](const MTPDmessageReplyHeader &data) {
|
||||||
setReplyFields(
|
// #TODO replies
|
||||||
data.vreply_to_msg_id().v,
|
const auto replyToPeer = data.vreply_to_peer_id()
|
||||||
data.vreply_to_top_id().value_or(
|
? peerFromMTP(*data.vreply_to_peer_id())
|
||||||
data.vreply_to_msg_id().v),
|
: PeerId();
|
||||||
data.is_forum_topic());
|
if (!replyToPeer || replyToPeer == history()->peer->id) {
|
||||||
|
if (const auto replyToId = data.vreply_to_msg_id()) {
|
||||||
|
setReplyFields(
|
||||||
|
replyToId->v,
|
||||||
|
data.vreply_to_top_id().value_or(replyToId->v),
|
||||||
|
data.is_forum_topic());
|
||||||
|
}
|
||||||
|
}
|
||||||
}, [](const MTPDmessageReplyStoryHeader &data) {
|
}, [](const MTPDmessageReplyStoryHeader &data) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -3382,18 +3393,21 @@ void HistoryItem::createComponents(const MTPDmessage &data) {
|
||||||
}
|
}
|
||||||
if (const auto reply = data.vreply_to()) {
|
if (const auto reply = data.vreply_to()) {
|
||||||
reply->match([&](const MTPDmessageReplyHeader &data) {
|
reply->match([&](const MTPDmessageReplyHeader &data) {
|
||||||
if (const auto peer = data.vreply_to_peer_id()) {
|
// #TODO replies
|
||||||
config.replyToPeer = peerFromMTP(*peer);
|
if (const auto id = data.vreply_to_msg_id().value_or_empty()) {
|
||||||
if (config.replyToPeer == _history->peer->id) {
|
if (const auto peer = data.vreply_to_peer_id()) {
|
||||||
config.replyToPeer = 0;
|
config.replyToPeer = peerFromMTP(*peer);
|
||||||
|
if (config.replyToPeer == _history->peer->id) {
|
||||||
|
config.replyToPeer = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
const auto owner = &_history->owner();
|
||||||
|
config.replyTo = data.is_reply_to_scheduled()
|
||||||
|
? owner->scheduledMessages().localMessageId(id)
|
||||||
|
: id;
|
||||||
|
config.replyToTop = data.vreply_to_top_id().value_or(id);
|
||||||
|
config.replyIsTopicPost = data.is_forum_topic();
|
||||||
}
|
}
|
||||||
const auto id = data.vreply_to_msg_id().v;
|
|
||||||
config.replyTo = data.is_reply_to_scheduled()
|
|
||||||
? _history->owner().scheduledMessages().localMessageId(id)
|
|
||||||
: id;
|
|
||||||
config.replyToTop = data.vreply_to_top_id().value_or(id);
|
|
||||||
config.replyIsTopicPost = data.is_forum_topic();
|
|
||||||
}, [&](const MTPDmessageReplyStoryHeader &data) {
|
}, [&](const MTPDmessageReplyStoryHeader &data) {
|
||||||
config.replyToPeer = peerFromUser(data.vuser_id());
|
config.replyToPeer = peerFromUser(data.vuser_id());
|
||||||
config.replyToStory = data.vstory_id().v;
|
config.replyToStory = data.vstory_id().v;
|
||||||
|
@ -3631,21 +3645,23 @@ void HistoryItem::createServiceFromMtp(const MTPDmessageService &message) {
|
||||||
? peerFromMTP(*data.vreply_to_peer_id())
|
? peerFromMTP(*data.vreply_to_peer_id())
|
||||||
: _history->peer->id;
|
: _history->peer->id;
|
||||||
if (const auto dependent = GetServiceDependentData()) {
|
if (const auto dependent = GetServiceDependentData()) {
|
||||||
dependent->peerId = (peerId != _history->peer->id)
|
const auto id = data.vreply_to_msg_id().value_or_empty();
|
||||||
? peerId
|
if (id) {
|
||||||
: 0;
|
dependent->peerId = (peerId != _history->peer->id)
|
||||||
const auto id = data.vreply_to_msg_id().v;
|
? peerId
|
||||||
dependent->msgId = id;
|
: 0;
|
||||||
dependent->topId = data.vreply_to_top_id().value_or(id);
|
dependent->msgId = id;
|
||||||
dependent->topicPost = data.is_forum_topic()
|
dependent->topId = data.vreply_to_top_id().value_or(id);
|
||||||
|| Has<HistoryServiceTopicInfo>();
|
dependent->topicPost = data.is_forum_topic()
|
||||||
if (!updateServiceDependent()) {
|
|| Has<HistoryServiceTopicInfo>();
|
||||||
RequestDependentMessageItem(
|
if (!updateServiceDependent()) {
|
||||||
this,
|
RequestDependentMessageItem(
|
||||||
(dependent->peerId
|
this,
|
||||||
? dependent->peerId
|
(dependent->peerId
|
||||||
: _history->peer->id),
|
? dependent->peerId
|
||||||
dependent->msgId);
|
: _history->peer->id),
|
||||||
|
dependent->msgId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [](const MTPDmessageReplyStoryHeader &data) {
|
}, [](const MTPDmessageReplyStoryHeader &data) {
|
||||||
|
@ -4426,6 +4442,25 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) {
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto prepareGiftCode = [&](const MTPDmessageActionGiftCode &action) {
|
||||||
|
auto result = PreparedServiceText();
|
||||||
|
_history->session().giftBoxStickersPacks().load();
|
||||||
|
const auto months = action.vmonths().v;
|
||||||
|
|
||||||
|
result.text = {
|
||||||
|
(action.is_via_giveaway()
|
||||||
|
? tr::lng_prize_about
|
||||||
|
: tr::lng_prize_gift_about)(
|
||||||
|
tr::now,
|
||||||
|
lt_channel,
|
||||||
|
(action.vboost_peer()
|
||||||
|
? _from->owner().peer(
|
||||||
|
peerFromMTP(*action.vboost_peer()))->name()
|
||||||
|
: "a channel")),
|
||||||
|
};
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
setServiceText(action.match([&](
|
setServiceText(action.match([&](
|
||||||
const MTPDmessageActionChatAddUser &data) {
|
const MTPDmessageActionChatAddUser &data) {
|
||||||
return prepareChatAddUserText(data);
|
return prepareChatAddUserText(data);
|
||||||
|
@ -4506,6 +4541,8 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) {
|
||||||
return prepareSetChatWallPaper(data);
|
return prepareSetChatWallPaper(data);
|
||||||
}, [&](const MTPDmessageActionSetSameChatWallPaper &data) {
|
}, [&](const MTPDmessageActionSetSameChatWallPaper &data) {
|
||||||
return prepareSetSameChatWallPaper(data);
|
return prepareSetSameChatWallPaper(data);
|
||||||
|
}, [&](const MTPDmessageActionGiftCode &data) {
|
||||||
|
return prepareGiftCode(data);
|
||||||
}, [](const MTPDmessageActionEmpty &) {
|
}, [](const MTPDmessageActionEmpty &) {
|
||||||
return PreparedServiceText{ { tr::lng_message_empty(tr::now) } };
|
return PreparedServiceText{ { tr::lng_message_empty(tr::now) } };
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -370,13 +370,19 @@ MTPMessageReplyHeader NewMessageReplyHeader(const Api::SendAction &action) {
|
||||||
: Flag(0))),
|
: Flag(0))),
|
||||||
MTP_int(replyTo.msgId),
|
MTP_int(replyTo.msgId),
|
||||||
MTPPeer(),
|
MTPPeer(),
|
||||||
MTP_int(replyToTop));
|
MTPMessageFwdHeader(), // reply_header
|
||||||
|
MTP_int(replyToTop),
|
||||||
|
MTPstring(), // quote_text
|
||||||
|
MTPVector<MTPMessageEntity>()); // quote_entities
|
||||||
}
|
}
|
||||||
return MTP_messageReplyHeader(
|
return MTP_messageReplyHeader(
|
||||||
MTP_flags(0),
|
MTP_flags(0),
|
||||||
MTP_int(replyTo.msgId),
|
MTP_int(replyTo.msgId),
|
||||||
MTPPeer(),
|
MTPPeer(), // reply_to_peer_id
|
||||||
MTPint());
|
MTPMessageFwdHeader(), // reply_header
|
||||||
|
MTPint(), // reply_to_top_id
|
||||||
|
MTPstring(), // quote_text
|
||||||
|
MTPVector<MTPMessageEntity>()); // quote_entities
|
||||||
}
|
}
|
||||||
return MTPMessageReplyHeader();
|
return MTPMessageReplyHeader();
|
||||||
}
|
}
|
||||||
|
@ -453,6 +459,8 @@ MediaCheckResult CheckMessageMedia(const MTPMessageMedia &media) {
|
||||||
return data.is_via_mention()
|
return data.is_via_mention()
|
||||||
? Result::HasStoryMention
|
? Result::HasStoryMention
|
||||||
: Result::Good;
|
: Result::Good;
|
||||||
|
}, [](const MTPDmessageMediaGiveaway &) {
|
||||||
|
return Result::Good;
|
||||||
}, [](const MTPDmessageMediaUnsupported &) {
|
}, [](const MTPDmessageMediaUnsupported &) {
|
||||||
return Result::Unsupported;
|
return Result::Unsupported;
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,298 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#include "history/view/media/history_view_giveaway.h"
|
||||||
|
|
||||||
|
#include "base/unixtime.h"
|
||||||
|
#include "data/data_channel.h"
|
||||||
|
#include "data/data_media_types.h"
|
||||||
|
#include "lang/lang_keys.h"
|
||||||
|
#include "history/history_item.h"
|
||||||
|
#include "history/view/history_view_element.h"
|
||||||
|
#include "history/view/history_view_cursor_state.h"
|
||||||
|
#include "ui/chat/chat_style.h"
|
||||||
|
#include "ui/text/text_utilities.h"
|
||||||
|
#include "styles/style_chat.h"
|
||||||
|
|
||||||
|
namespace HistoryView {
|
||||||
|
|
||||||
|
void TextRows::add(Ui::Text::String text, int skipTop) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextRows::isEmpty() const {
|
||||||
|
return _rows.empty()
|
||||||
|
|| (_rows.size() == 1 && _rows.front().text.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
int TextRows::maxWidth() const {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TextRows::minHeight() const {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TextRows::countHeight(int newWidth) const {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TextRows::length() const {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextSelection UnshiftItemSelection(
|
||||||
|
TextSelection selection,
|
||||||
|
const TextRows &byText) {
|
||||||
|
return UnshiftItemSelection(selection, byText.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
TextSelection ShiftItemSelection(
|
||||||
|
TextSelection selection,
|
||||||
|
const TextRows &byText) {
|
||||||
|
return ShiftItemSelection(selection, byText.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
Giveaway::Giveaway(
|
||||||
|
not_null<Element*> parent,
|
||||||
|
not_null<Data::Giveaway*> giveaway)
|
||||||
|
: Media(parent) {
|
||||||
|
fillFromData(giveaway);
|
||||||
|
}
|
||||||
|
|
||||||
|
Giveaway::~Giveaway() = default;
|
||||||
|
|
||||||
|
void Giveaway::fillFromData(not_null<Data::Giveaway*> giveaway) {
|
||||||
|
_rows.add(Ui::Text::String(
|
||||||
|
st::semiboldTextStyle,
|
||||||
|
tr::lng_prizes_title(tr::now, lt_count, giveaway->quantity),
|
||||||
|
kDefaultTextOptions,
|
||||||
|
st::msgMinWidth), st::chatGiveawayPrizesTop);
|
||||||
|
|
||||||
|
const auto duration = (giveaway->months < 12)
|
||||||
|
? tr::lng_months(tr::now, lt_count, giveaway->months)
|
||||||
|
: tr::lng_years(tr::now, lt_count, giveaway->months / 12);
|
||||||
|
_rows.add(Ui::Text::String(
|
||||||
|
st::defaultTextStyle,
|
||||||
|
tr::lng_prizes_about(
|
||||||
|
tr::now,
|
||||||
|
lt_count,
|
||||||
|
giveaway->quantity,
|
||||||
|
lt_duration,
|
||||||
|
Ui::Text::Bold(duration),
|
||||||
|
Ui::Text::RichLangValue),
|
||||||
|
kDefaultTextOptions,
|
||||||
|
st::msgMinWidth), st::chatGiveawayPrizesSkip);
|
||||||
|
|
||||||
|
_rows.add(Ui::Text::String(
|
||||||
|
st::semiboldTextStyle,
|
||||||
|
tr::lng_prizes_participants(tr::now),
|
||||||
|
kDefaultTextOptions,
|
||||||
|
st::msgMinWidth), st::chatGiveawayParticipantsTop);
|
||||||
|
|
||||||
|
for (const auto &channel : giveaway->channels) {
|
||||||
|
_channels.push_back({ Ui::Text::String(
|
||||||
|
st::semiboldTextStyle,
|
||||||
|
channel->name(),
|
||||||
|
kDefaultTextOptions,
|
||||||
|
st::msgMinWidth)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto channels = int(_channels.size());
|
||||||
|
_rows.add(Ui::Text::String(
|
||||||
|
st::defaultTextStyle,
|
||||||
|
(giveaway->all
|
||||||
|
? tr::lng_prizes_participants_all
|
||||||
|
: tr::lng_prizes_participants_new)(tr::now, lt_count, channels),
|
||||||
|
kDefaultTextOptions,
|
||||||
|
st::msgMinWidth), st::chatGiveawayParticipantsSkip);
|
||||||
|
|
||||||
|
_date.add(Ui::Text::String(
|
||||||
|
st::semiboldTextStyle,
|
||||||
|
tr::lng_prizes_date(tr::now),
|
||||||
|
kDefaultTextOptions,
|
||||||
|
st::msgMinWidth), st::chatGiveawayDateTop);
|
||||||
|
|
||||||
|
_rows.add(Ui::Text::String(
|
||||||
|
st::defaultTextStyle,
|
||||||
|
langDateTime(base::unixtime::parse(giveaway->untilDate)),
|
||||||
|
kDefaultTextOptions,
|
||||||
|
st::msgMinWidth), st::chatGiveawayDateSkip);
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize Giveaway::countOptimalSize() {
|
||||||
|
// init dimensions
|
||||||
|
auto skipBlockWidth = _parent->skipBlockWidth();
|
||||||
|
auto maxWidth = skipBlockWidth;
|
||||||
|
auto minHeight = 0;
|
||||||
|
|
||||||
|
accumulate_max(maxWidth, _rows.maxWidth());
|
||||||
|
minHeight += _rows.minHeight();
|
||||||
|
|
||||||
|
//minHeight +=
|
||||||
|
|
||||||
|
accumulate_max(maxWidth, _date.maxWidth());
|
||||||
|
minHeight += _date.minHeight();
|
||||||
|
|
||||||
|
auto padding = inBubblePadding();
|
||||||
|
maxWidth += padding.left() + padding.right();
|
||||||
|
minHeight += padding.top() + padding.bottom();
|
||||||
|
return { maxWidth, minHeight };
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize Giveaway::countCurrentSize(int newWidth) {
|
||||||
|
accumulate_min(newWidth, maxWidth());
|
||||||
|
auto innerWidth = newWidth
|
||||||
|
- st::msgPadding.left()
|
||||||
|
- st::msgPadding.right();
|
||||||
|
|
||||||
|
auto newHeight = 0;
|
||||||
|
_rowsHeight = _rows.countHeight(innerWidth);
|
||||||
|
newHeight += _rowsHeight;
|
||||||
|
|
||||||
|
//newHeight +=
|
||||||
|
|
||||||
|
newHeight += _date.countHeight(innerWidth);
|
||||||
|
_dateHeight = _date.minHeight();
|
||||||
|
newHeight += _dateHeight;
|
||||||
|
|
||||||
|
auto padding = inBubblePadding();
|
||||||
|
newHeight += padding.top() + padding.bottom();
|
||||||
|
|
||||||
|
return { newWidth, newHeight };
|
||||||
|
}
|
||||||
|
|
||||||
|
TextSelection Giveaway::toDateSelection(TextSelection selection) const {
|
||||||
|
return UnshiftItemSelection(selection, _rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
TextSelection Giveaway::fromDateSelection(TextSelection selection) const {
|
||||||
|
return ShiftItemSelection(selection, _rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Giveaway::draw(Painter &p, const PaintContext &context) const {
|
||||||
|
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) return;
|
||||||
|
|
||||||
|
const auto st = context.st;
|
||||||
|
const auto sti = context.imageStyle();
|
||||||
|
const auto stm = context.messageStyle();
|
||||||
|
|
||||||
|
auto &semibold = stm->msgServiceFg;
|
||||||
|
|
||||||
|
auto padding = inBubblePadding();
|
||||||
|
auto tshift = padding.top();
|
||||||
|
|
||||||
|
//_rows.draw(p, {
|
||||||
|
// .position = { padding.left(), tshift },
|
||||||
|
// .outerWidth = width(),
|
||||||
|
// .availableWidth = paintw,
|
||||||
|
// .now = context.now,
|
||||||
|
// .selection = context.selection,
|
||||||
|
//});
|
||||||
|
//tshift += _rows.countHeight(paintw);
|
||||||
|
|
||||||
|
//_date.draw(p, {
|
||||||
|
// .position = { padding.left(), tshift },
|
||||||
|
// .outerWidth = width(),
|
||||||
|
// .availableWidth = paintw,
|
||||||
|
// .now = context.now,
|
||||||
|
// .selection = toDateSelection(context.selection),
|
||||||
|
//});
|
||||||
|
}
|
||||||
|
|
||||||
|
TextState Giveaway::textState(QPoint point, StateRequest request) const {
|
||||||
|
auto result = TextState(_parent);
|
||||||
|
|
||||||
|
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto padding = inBubblePadding();
|
||||||
|
auto tshift = padding.top();
|
||||||
|
auto bshift = padding.bottom();
|
||||||
|
|
||||||
|
auto symbolAdd = 0;
|
||||||
|
if (_rowsHeight > 0) {
|
||||||
|
if (point.y() >= tshift && point.y() < tshift + _rowsHeight) {
|
||||||
|
//result = TextState(_parent, _rows.getState(
|
||||||
|
// point - QPoint(padding.left(), tshift),
|
||||||
|
// paintw,
|
||||||
|
// width(),
|
||||||
|
// request.forText()));
|
||||||
|
} else if (point.y() >= tshift + _rowsHeight) {
|
||||||
|
symbolAdd += _rows.length();
|
||||||
|
}
|
||||||
|
tshift += _rowsHeight;
|
||||||
|
}
|
||||||
|
if (_channelsHeight > 0) {
|
||||||
|
tshift += _channelsHeight;
|
||||||
|
}
|
||||||
|
if (_dateHeight > 0) {
|
||||||
|
if (point.y() >= tshift && point.y() < tshift + _dateHeight) {
|
||||||
|
//result = TextState(_parent, _date.getState(
|
||||||
|
// point - QPoint(padding.left(), tshift),
|
||||||
|
// paintw,
|
||||||
|
// width(),
|
||||||
|
// request.forText()));
|
||||||
|
} else if (point.y() >= tshift + _dateHeight) {
|
||||||
|
symbolAdd += _date.length();
|
||||||
|
}
|
||||||
|
tshift += _dateHeight;
|
||||||
|
}
|
||||||
|
result.symbol += symbolAdd;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextSelection Giveaway::adjustSelection(
|
||||||
|
TextSelection selection,
|
||||||
|
TextSelectType type) const {
|
||||||
|
//if (_date.isEmpty() || selection.to <= _rows.length()) {
|
||||||
|
// return _rows.adjustSelection(selection, type);
|
||||||
|
//}
|
||||||
|
//const auto dateSelection = _date.adjustSelection(
|
||||||
|
// toDateSelection(selection),
|
||||||
|
// type);
|
||||||
|
//if (selection.from >= _rows.length()) {
|
||||||
|
// return fromDateSelection(dateSelection);
|
||||||
|
//}
|
||||||
|
//const auto rowsSelection = _rows.adjustSelection(selection, type);
|
||||||
|
//return { rowsSelection.from, fromDateSelection(dateSelection).to };
|
||||||
|
return selection;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Giveaway::hasHeavyPart() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Giveaway::unloadHeavyPart() {
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 Giveaway::fullSelectionLength() const {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextForMimeData Giveaway::selectedText(TextSelection selection) const {
|
||||||
|
//auto rowsResult = _rows.toTextForMimeData(selection);
|
||||||
|
//auto dateResult = _date.toTextForMimeData(toDateSelection(selection));
|
||||||
|
//if (rowsResult.empty()) {
|
||||||
|
// return dateResult;
|
||||||
|
//} else if (dateResult.empty()) {
|
||||||
|
// return rowsResult;
|
||||||
|
//}
|
||||||
|
//return rowsResult.append('\n').append(std::move(dateResult));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
QMargins Giveaway::inBubblePadding() const {
|
||||||
|
auto lshift = st::msgPadding.left();
|
||||||
|
auto rshift = st::msgPadding.right();
|
||||||
|
auto bshift = isBubbleBottom() ? st::msgPadding.top() : st::mediaInBubbleSkip;
|
||||||
|
auto tshift = isBubbleTop() ? st::msgPadding.bottom() : st::mediaInBubbleSkip;
|
||||||
|
return QMargins(lshift, tshift, rshift, bshift);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace HistoryView
|
102
Telegram/SourceFiles/history/view/media/history_view_giveaway.h
Normal file
102
Telegram/SourceFiles/history/view/media/history_view_giveaway.h
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "history/view/media/history_view_media.h"
|
||||||
|
|
||||||
|
namespace Data {
|
||||||
|
struct Giveaway;
|
||||||
|
} // namespace Data
|
||||||
|
|
||||||
|
namespace HistoryView {
|
||||||
|
|
||||||
|
class TextRows final {
|
||||||
|
public:
|
||||||
|
void add(Ui::Text::String text, int skipTop);
|
||||||
|
|
||||||
|
[[nodiscard]] bool isEmpty() const;
|
||||||
|
[[nodiscard]] int maxWidth() const;
|
||||||
|
[[nodiscard]] int minHeight() const;
|
||||||
|
|
||||||
|
[[nodiscard]] int countHeight(int newWidth) const;
|
||||||
|
|
||||||
|
[[nodiscard]] int length() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Row {
|
||||||
|
Ui::Text::String text;
|
||||||
|
int skipTop = 0;
|
||||||
|
};
|
||||||
|
std::vector<Row> _rows;
|
||||||
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] TextSelection UnshiftItemSelection(
|
||||||
|
TextSelection selection,
|
||||||
|
const TextRows &byText);
|
||||||
|
[[nodiscard]] TextSelection ShiftItemSelection(
|
||||||
|
TextSelection selection,
|
||||||
|
const TextRows &byText);
|
||||||
|
|
||||||
|
class Giveaway final : public Media {
|
||||||
|
public:
|
||||||
|
Giveaway(
|
||||||
|
not_null<Element*> parent,
|
||||||
|
not_null<Data::Giveaway*> giveaway);
|
||||||
|
~Giveaway();
|
||||||
|
|
||||||
|
void draw(Painter &p, const PaintContext &context) const override;
|
||||||
|
TextState textState(QPoint point, StateRequest request) const override;
|
||||||
|
|
||||||
|
bool needsBubble() const override {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool customInfoLayout() const override {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool toggleSelectionByHandlerClick(
|
||||||
|
const ClickHandlerPtr &p) const override {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool dragItemByHandler(const ClickHandlerPtr &p) const override {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] TextSelection adjustSelection(
|
||||||
|
TextSelection selection,
|
||||||
|
TextSelectType type) const override;
|
||||||
|
uint16 fullSelectionLength() const override;
|
||||||
|
TextForMimeData selectedText(TextSelection selection) const override;
|
||||||
|
|
||||||
|
void unloadHeavyPart() override;
|
||||||
|
bool hasHeavyPart() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Channel {
|
||||||
|
Ui::Text::String name;
|
||||||
|
};
|
||||||
|
|
||||||
|
QSize countOptimalSize() override;
|
||||||
|
QSize countCurrentSize(int newWidth) override;
|
||||||
|
|
||||||
|
void fillFromData(not_null<Data::Giveaway*> giveaway);
|
||||||
|
|
||||||
|
TextSelection toDateSelection(TextSelection selection) const;
|
||||||
|
TextSelection fromDateSelection(TextSelection selection) const;
|
||||||
|
QMargins inBubblePadding() const;
|
||||||
|
|
||||||
|
TextRows _rows;
|
||||||
|
std::vector<Channel> _channels;
|
||||||
|
TextRows _date;
|
||||||
|
int _rowsHeight = 0;
|
||||||
|
int _channelsHeight = 0;
|
||||||
|
int _dateHeight = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace HistoryView
|
|
@ -130,6 +130,7 @@ messageMediaGeoLive#b940c666 flags:# geo:GeoPoint heading:flags.0?int period:int
|
||||||
messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia;
|
messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia;
|
||||||
messageMediaDice#3f7ee58b value:int emoticon:string = MessageMedia;
|
messageMediaDice#3f7ee58b value:int emoticon:string = MessageMedia;
|
||||||
messageMediaStory#68cb6283 flags:# via_mention:flags.1?true peer:Peer id:int story:flags.0?StoryItem = MessageMedia;
|
messageMediaStory#68cb6283 flags:# via_mention:flags.1?true peer:Peer id:int story:flags.0?StoryItem = MessageMedia;
|
||||||
|
messageMediaGiveaway#4291677c flags:# only_new_subscribers:flags.0?true channels:Vector<long> quantity:int months:int until_date:int = MessageMedia;
|
||||||
|
|
||||||
messageActionEmpty#b6aef7b0 = MessageAction;
|
messageActionEmpty#b6aef7b0 = MessageAction;
|
||||||
messageActionChatCreate#bd47cbad title:string users:Vector<long> = MessageAction;
|
messageActionChatCreate#bd47cbad title:string users:Vector<long> = MessageAction;
|
||||||
|
@ -170,6 +171,7 @@ messageActionSuggestProfilePhoto#57de635e photo:Photo = MessageAction;
|
||||||
messageActionRequestedPeer#fe77345d button_id:int peer:Peer = MessageAction;
|
messageActionRequestedPeer#fe77345d button_id:int peer:Peer = MessageAction;
|
||||||
messageActionSetChatWallPaper#bc44a927 wallpaper:WallPaper = MessageAction;
|
messageActionSetChatWallPaper#bc44a927 wallpaper:WallPaper = MessageAction;
|
||||||
messageActionSetSameChatWallPaper#c0787d6d wallpaper:WallPaper = MessageAction;
|
messageActionSetSameChatWallPaper#c0787d6d wallpaper:WallPaper = MessageAction;
|
||||||
|
messageActionGiftCode#d2cfdb0e flags:# via_giveaway:flags.0?true boost_peer:flags.1?Peer months:int slug:string = MessageAction;
|
||||||
|
|
||||||
dialog#d58a08c6 flags:# pinned:flags.2?true unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int ttl_period:flags.5?int = Dialog;
|
dialog#d58a08c6 flags:# pinned:flags.2?true unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int ttl_period:flags.5?int = Dialog;
|
||||||
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
|
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
|
||||||
|
@ -755,7 +757,7 @@ contacts.topPeers#70b772a8 categories:Vector<TopPeerCategoryPeers> chats:Vector<
|
||||||
contacts.topPeersDisabled#b52c939d = contacts.TopPeers;
|
contacts.topPeersDisabled#b52c939d = contacts.TopPeers;
|
||||||
|
|
||||||
draftMessageEmpty#1b0c841a flags:# date:flags.0?int = DraftMessage;
|
draftMessageEmpty#1b0c841a flags:# date:flags.0?int = DraftMessage;
|
||||||
draftMessage#fd8e711f flags:# no_webpage:flags.1?true reply_to_msg_id:flags.0?int message:string entities:flags.3?Vector<MessageEntity> date:int = DraftMessage;
|
draftMessage#95b0528b flags:# no_webpage:flags.1?true reply_to:flags.4?MessageReplyHeader message:string entities:flags.3?Vector<MessageEntity> date:int = DraftMessage;
|
||||||
|
|
||||||
messages.featuredStickersNotModified#c6dc0c66 count:int = messages.FeaturedStickers;
|
messages.featuredStickersNotModified#c6dc0c66 count:int = messages.FeaturedStickers;
|
||||||
messages.featuredStickers#be382906 flags:# premium:flags.0?true hash:long count:int sets:Vector<StickerSetCovered> unread:Vector<long> = messages.FeaturedStickers;
|
messages.featuredStickers#be382906 flags:# premium:flags.0?true hash:long count:int sets:Vector<StickerSetCovered> unread:Vector<long> = messages.FeaturedStickers;
|
||||||
|
@ -1256,7 +1258,7 @@ messages.messageViews#b6c4f543 views:Vector<MessageViews> chats:Vector<Chat> use
|
||||||
|
|
||||||
messages.discussionMessage#a6341782 flags:# messages:Vector<Message> max_id:flags.0?int read_inbox_max_id:flags.1?int read_outbox_max_id:flags.2?int unread_count:int chats:Vector<Chat> users:Vector<User> = messages.DiscussionMessage;
|
messages.discussionMessage#a6341782 flags:# messages:Vector<Message> max_id:flags.0?int read_inbox_max_id:flags.1?int read_outbox_max_id:flags.2?int unread_count:int chats:Vector<Chat> users:Vector<User> = messages.DiscussionMessage;
|
||||||
|
|
||||||
messageReplyHeader#a6d57763 flags:# reply_to_scheduled:flags.2?true forum_topic:flags.3?true reply_to_msg_id:int reply_to_peer_id:flags.0?Peer reply_to_top_id:flags.1?int = MessageReplyHeader;
|
messageReplyHeader#3d5c1693 flags:# reply_to_scheduled:flags.2?true forum_topic:flags.3?true reply_to_msg_id:flags.4?int reply_to_peer_id:flags.0?Peer reply_header:flags.5?MessageFwdHeader reply_to_top_id:flags.1?int quote_text:flags.6?string quote_entities:flags.7?Vector<MessageEntity> = MessageReplyHeader;
|
||||||
messageReplyStoryHeader#9c98bfc1 user_id:long story_id:int = MessageReplyHeader;
|
messageReplyStoryHeader#9c98bfc1 user_id:long story_id:int = MessageReplyHeader;
|
||||||
|
|
||||||
messageReplies#83d60fc2 flags:# comments:flags.0?true replies:int replies_pts:int recent_repliers:flags.1?Vector<Peer> channel_id:flags.0?long max_id:flags.2?int read_max_id:flags.3?int = MessageReplies;
|
messageReplies#83d60fc2 flags:# comments:flags.0?true replies:int replies_pts:int recent_repliers:flags.1?Vector<Peer> channel_id:flags.0?long max_id:flags.2?int read_max_id:flags.3?int = MessageReplies;
|
||||||
|
@ -1406,6 +1408,7 @@ attachMenuPeerTypeBroadcast#7bfbdefc = AttachMenuPeerType;
|
||||||
|
|
||||||
inputInvoiceMessage#c5b56859 peer:InputPeer msg_id:int = InputInvoice;
|
inputInvoiceMessage#c5b56859 peer:InputPeer msg_id:int = InputInvoice;
|
||||||
inputInvoiceSlug#c326caef slug:string = InputInvoice;
|
inputInvoiceSlug#c326caef slug:string = InputInvoice;
|
||||||
|
inputInvoicePremiumGiftCode#98986c0d purpose:InputStorePaymentPurpose option:PremiumGiftCodeOption = InputInvoice;
|
||||||
|
|
||||||
payments.exportedInvoice#aed0cbd9 url:string = payments.ExportedInvoice;
|
payments.exportedInvoice#aed0cbd9 url:string = payments.ExportedInvoice;
|
||||||
|
|
||||||
|
@ -1416,6 +1419,7 @@ help.premiumPromo#5334759c status_text:string status_entities:Vector<MessageEnti
|
||||||
inputStorePaymentPremiumSubscription#a6751e66 flags:# restore:flags.0?true upgrade:flags.1?true = InputStorePaymentPurpose;
|
inputStorePaymentPremiumSubscription#a6751e66 flags:# restore:flags.0?true upgrade:flags.1?true = InputStorePaymentPurpose;
|
||||||
inputStorePaymentGiftPremium#616f7fe8 user_id:InputUser currency:string amount:long = InputStorePaymentPurpose;
|
inputStorePaymentGiftPremium#616f7fe8 user_id:InputUser currency:string amount:long = InputStorePaymentPurpose;
|
||||||
inputStorePaymentPremiumGiftCode#a3805f3f flags:# users:Vector<InputUser> boost_peer:flags.0?InputPeer currency:string amount:long = InputStorePaymentPurpose;
|
inputStorePaymentPremiumGiftCode#a3805f3f flags:# users:Vector<InputUser> boost_peer:flags.0?InputPeer currency:string amount:long = InputStorePaymentPurpose;
|
||||||
|
inputStorePaymentPremiumGiveaway#e94a2529 flags:# only_new_subscribers:flags.0?true boost_peer:InputPeer additional_peers:flags.1?Vector<InputPeer> random_id:long until_date:int currency:string amount:long = InputStorePaymentPurpose;
|
||||||
|
|
||||||
premiumGiftOption#74c34319 flags:# months:int currency:string amount:long bot_url:string store_product:flags.0?string = PremiumGiftOption;
|
premiumGiftOption#74c34319 flags:# months:int currency:string amount:long bot_url:string store_product:flags.0?string = PremiumGiftOption;
|
||||||
|
|
||||||
|
@ -1547,7 +1551,7 @@ stories.storyViewsList#46e9b9ec flags:# count:int reactions_count:int views:Vect
|
||||||
|
|
||||||
stories.storyViews#de9eed1d views:Vector<StoryViews> users:Vector<User> = stories.StoryViews;
|
stories.storyViews#de9eed1d views:Vector<StoryViews> users:Vector<User> = stories.StoryViews;
|
||||||
|
|
||||||
inputReplyToMessage#9c5386e4 flags:# reply_to_msg_id:int top_msg_id:flags.0?int = InputReplyTo;
|
inputReplyToMessage#73ec805 flags:# reply_to_msg_id:int top_msg_id:flags.0?int reply_to_peer_id:flags.1?InputPeer quote_text:flags.2?string quote_entities:flags.3?Vector<MessageEntity> = InputReplyTo;
|
||||||
inputReplyToStory#15b0f283 user_id:InputUser story_id:int = InputReplyTo;
|
inputReplyToStory#15b0f283 user_id:InputUser story_id:int = InputReplyTo;
|
||||||
|
|
||||||
exportedStoryLink#3fc9053b link:string = ExportedStoryLink;
|
exportedStoryLink#3fc9053b link:string = ExportedStoryLink;
|
||||||
|
@ -1576,9 +1580,12 @@ stories.boostersList#f3dd3d1d flags:# count:int boosters:Vector<Booster> next_of
|
||||||
|
|
||||||
messages.webPage#fd5e12bd webpage:WebPage chats:Vector<Chat> users:Vector<User> = messages.WebPage;
|
messages.webPage#fd5e12bd webpage:WebPage chats:Vector<Chat> users:Vector<User> = messages.WebPage;
|
||||||
|
|
||||||
premiumGiftCodeOption#d579436c flags:# users:int months:int store_product:flags.0?string = PremiumGiftCodeOption;
|
premiumGiftCodeOption#257e962b flags:# users:int months:int store_product:flags.0?string store_quantity:flags.1?int currency:string amount:long = PremiumGiftCodeOption;
|
||||||
|
|
||||||
payments.checkedGiftCode#ff70298c flags:# from_id:Peer to_id:flags.0?long date:int months:int used_date:flags.1?int chats:Vector<Chat> users:Vector<User> = payments.CheckedGiftCode;
|
payments.checkedGiftCode#b722f158 flags:# via_giveaway:flags.2?true from_id:Peer giveaway_msg_id:flags.3?int to_id:flags.0?long date:int months:int used_date:flags.1?int chats:Vector<Chat> users:Vector<User> = payments.CheckedGiftCode;
|
||||||
|
|
||||||
|
payments.giveawayInfo#7a7bdc5a flags:# participating:flags.0?true preparing_results:flags.3?true joined_too_early_date:flags.1?int admin_disallowed_chat_id:flags.2?long = payments.GiveawayInfo;
|
||||||
|
payments.giveawayInfoResults#38c32424 flags:# winner:flags.0?true refunded:flags.1?true gift_code_slug:flags.0?string finish_date:int winners_count:int activated_count:int = payments.GiveawayInfo;
|
||||||
|
|
||||||
---functions---
|
---functions---
|
||||||
|
|
||||||
|
@ -1793,7 +1800,7 @@ messages.editInlineBotMessage#83557dba flags:# no_webpage:flags.1?true id:InputB
|
||||||
messages.getBotCallbackAnswer#9342ca07 flags:# game:flags.1?true peer:InputPeer msg_id:int data:flags.0?bytes password:flags.2?InputCheckPasswordSRP = messages.BotCallbackAnswer;
|
messages.getBotCallbackAnswer#9342ca07 flags:# game:flags.1?true peer:InputPeer msg_id:int data:flags.0?bytes password:flags.2?InputCheckPasswordSRP = messages.BotCallbackAnswer;
|
||||||
messages.setBotCallbackAnswer#d58f130a flags:# alert:flags.1?true query_id:long message:flags.0?string url:flags.2?string cache_time:int = Bool;
|
messages.setBotCallbackAnswer#d58f130a flags:# alert:flags.1?true query_id:long message:flags.0?string url:flags.2?string cache_time:int = Bool;
|
||||||
messages.getPeerDialogs#e470bcfd peers:Vector<InputDialogPeer> = messages.PeerDialogs;
|
messages.getPeerDialogs#e470bcfd peers:Vector<InputDialogPeer> = messages.PeerDialogs;
|
||||||
messages.saveDraft#b4331e3f flags:# no_webpage:flags.1?true reply_to_msg_id:flags.0?int top_msg_id:flags.2?int peer:InputPeer message:string entities:flags.3?Vector<MessageEntity> = Bool;
|
messages.saveDraft#64a3026c flags:# no_webpage:flags.1?true reply_to:flags.0?InputReplyTo peer:InputPeer message:string entities:flags.3?Vector<MessageEntity> = Bool;
|
||||||
messages.getAllDrafts#6a3f8d65 = Updates;
|
messages.getAllDrafts#6a3f8d65 = Updates;
|
||||||
messages.getFeaturedStickers#64780b14 hash:long = messages.FeaturedStickers;
|
messages.getFeaturedStickers#64780b14 hash:long = messages.FeaturedStickers;
|
||||||
messages.readFeaturedStickers#5b118126 id:Vector<long> = Bool;
|
messages.readFeaturedStickers#5b118126 id:Vector<long> = Bool;
|
||||||
|
@ -2051,6 +2058,7 @@ payments.canPurchasePremium#9fc19eb6 purpose:InputStorePaymentPurpose = Bool;
|
||||||
payments.getPremiumGiftCodeOptions#2757ba54 flags:# boost_peer:flags.0?InputPeer = Vector<PremiumGiftCodeOption>;
|
payments.getPremiumGiftCodeOptions#2757ba54 flags:# boost_peer:flags.0?InputPeer = Vector<PremiumGiftCodeOption>;
|
||||||
payments.checkGiftCode#8e51b4c1 slug:string = payments.CheckedGiftCode;
|
payments.checkGiftCode#8e51b4c1 slug:string = payments.CheckedGiftCode;
|
||||||
payments.applyGiftCode#f6e26854 slug:string = Updates;
|
payments.applyGiftCode#f6e26854 slug:string = Updates;
|
||||||
|
payments.getGiveawayInfo#f4239425 peer:InputPeer msg_id:int = payments.GiveawayInfo;
|
||||||
|
|
||||||
stickers.createStickerSet#9021ab67 flags:# masks:flags.0?true animated:flags.1?true videos:flags.4?true emojis:flags.5?true text_color:flags.6?true user_id:InputUser title:string short_name:string thumb:flags.2?InputDocument stickers:Vector<InputStickerSetItem> software:flags.3?string = messages.StickerSet;
|
stickers.createStickerSet#9021ab67 flags:# masks:flags.0?true animated:flags.1?true videos:flags.4?true emojis:flags.5?true text_color:flags.6?true user_id:InputUser title:string short_name:string thumb:flags.2?InputDocument stickers:Vector<InputStickerSetItem> software:flags.3?string = messages.StickerSet;
|
||||||
stickers.removeStickerFromSet#f7760f51 sticker:InputDocument = messages.StickerSet;
|
stickers.removeStickerFromSet#f7760f51 sticker:InputDocument = messages.StickerSet;
|
||||||
|
|
|
@ -931,3 +931,10 @@ storyMentionUnreadStrokeTwice: 6px;
|
||||||
storyMentionReadSkipTwice: 7px;
|
storyMentionReadSkipTwice: 7px;
|
||||||
storyMentionReadStrokeTwice: 3px;
|
storyMentionReadStrokeTwice: 3px;
|
||||||
storyMentionButtonSkip: 5px;
|
storyMentionButtonSkip: 5px;
|
||||||
|
|
||||||
|
chatGiveawayPrizesTop: 4px;
|
||||||
|
chatGiveawayPrizesSkip: 4px;
|
||||||
|
chatGiveawayParticipantsTop: 16px;
|
||||||
|
chatGiveawayParticipantsSkip: 4px;
|
||||||
|
chatGiveawayDateTop: 16px;
|
||||||
|
chatGiveawayDateSkip: 4px;
|
||||||
|
|
Loading…
Add table
Reference in a new issue