Update scheme to layer 102.

Support different dice-like media.
This commit is contained in:
John Preston 2020-04-06 13:07:49 +04:00
parent 41d39012d2
commit 3e2f4bed50
20 changed files with 135 additions and 64 deletions

Binary file not shown.

View File

@ -1329,7 +1329,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_dialogs_skip_archive_in_search" = "Skip results from archive"; "lng_dialogs_skip_archive_in_search" = "Skip results from archive";
"lng_dialogs_show_archive_in_search" = "With results from archive"; "lng_dialogs_show_archive_in_search" = "With results from archive";
"lng_about_dice" = "Send a 🎲 emoji to any chat to get a random number from Telegram."; "lng_about_random" = "Send a {emoji} emoji to any chat to get a random number from Telegram.";
"lng_open_this_link" = "Open this link?"; "lng_open_this_link" = "Open this link?";
"lng_open_link" = "Open"; "lng_open_link" = "Open";

View File

@ -48,6 +48,7 @@
<file alias="art/logo_256_no_margin.png">../../art/logo_256_no_margin.png</file> <file alias="art/logo_256_no_margin.png">../../art/logo_256_no_margin.png</file>
<file alias="art/sunrise.jpg">../../art/sunrise.jpg</file> <file alias="art/sunrise.jpg">../../art/sunrise.jpg</file>
<file alias="art/dice_idle.tgs">../../art/dice_idle.tgs</file> <file alias="art/dice_idle.tgs">../../art/dice_idle.tgs</file>
<file alias="art/dart_idle.tgs">../../art/dart_idle.tgs</file>
<file alias="day-blue.tdesktop-theme">../../day-blue.tdesktop-theme</file> <file alias="day-blue.tdesktop-theme">../../day-blue.tdesktop-theme</file>
<file alias="night.tdesktop-theme">../../night.tdesktop-theme</file> <file alias="night.tdesktop-theme">../../night.tdesktop-theme</file>
<file alias="night-green.tdesktop-theme">../../night-green.tdesktop-theme</file> <file alias="night-green.tdesktop-theme">../../night-green.tdesktop-theme</file>

View File

@ -71,8 +71,8 @@ inputMediaDocumentExternal#fb52dc99 flags:# url:string ttl_seconds:flags.0?int =
inputMediaGame#d33f43f3 id:InputGame = InputMedia; inputMediaGame#d33f43f3 id:InputGame = InputMedia;
inputMediaInvoice#f4e096c3 flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:string provider_data:DataJSON start_param:string = InputMedia; inputMediaInvoice#f4e096c3 flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:string provider_data:DataJSON start_param:string = InputMedia;
inputMediaGeoLive#ce4e82fd flags:# stopped:flags.0?true geo_point:InputGeoPoint period:flags.1?int = InputMedia; inputMediaGeoLive#ce4e82fd flags:# stopped:flags.0?true geo_point:InputGeoPoint period:flags.1?int = InputMedia;
inputMediaPoll#abe9ca25 flags:# poll:Poll correct_answers:flags.0?Vector<bytes> = InputMedia; inputMediaPoll#f94e5f1 flags:# poll:Poll correct_answers:flags.0?Vector<bytes> solution:flags.1?string solution_entities:flags.1?Vector<MessageEntity> = InputMedia;
inputMediaDice#aeffa807 = InputMedia; inputMediaDice#e66fbf7b emoticon:string = InputMedia;
inputChatPhotoEmpty#1ca48f57 = InputChatPhoto; inputChatPhotoEmpty#1ca48f57 = InputChatPhoto;
inputChatUploadedPhoto#927c55b4 file:InputFile = InputChatPhoto; inputChatUploadedPhoto#927c55b4 file:InputFile = InputChatPhoto;
@ -157,7 +157,7 @@ messageMediaGame#fdb19008 game:Game = MessageMedia;
messageMediaInvoice#84551347 flags:# shipping_address_requested:flags.1?true test:flags.3?true title:string description:string photo:flags.0?WebDocument receipt_msg_id:flags.2?int currency:string total_amount:long start_param:string = MessageMedia; messageMediaInvoice#84551347 flags:# shipping_address_requested:flags.1?true test:flags.3?true title:string description:string photo:flags.0?WebDocument receipt_msg_id:flags.2?int currency:string total_amount:long start_param:string = MessageMedia;
messageMediaGeoLive#7c3c2609 geo:GeoPoint period:int = MessageMedia; messageMediaGeoLive#7c3c2609 geo:GeoPoint period:int = MessageMedia;
messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia; messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia;
messageMediaDice#638fe46b value:int = MessageMedia; messageMediaDice#3f7ee58b value:int emoticon:string = MessageMedia;
messageActionEmpty#b6aef7b0 = MessageAction; messageActionEmpty#b6aef7b0 = MessageAction;
messageActionChatCreate#a6638b9a title:string users:Vector<int> = MessageAction; messageActionChatCreate#a6638b9a title:string users:Vector<int> = MessageAction;
@ -533,7 +533,7 @@ inputStickerSetEmpty#ffb62b95 = InputStickerSet;
inputStickerSetID#9de7a269 id:long access_hash:long = InputStickerSet; inputStickerSetID#9de7a269 id:long access_hash:long = InputStickerSet;
inputStickerSetShortName#861cc8a0 short_name:string = InputStickerSet; inputStickerSetShortName#861cc8a0 short_name:string = InputStickerSet;
inputStickerSetAnimatedEmoji#28703c8 = InputStickerSet; inputStickerSetAnimatedEmoji#28703c8 = InputStickerSet;
inputStickerSetDice#79e21a53 = InputStickerSet; inputStickerSetDice#e67f520e emoticon:string = InputStickerSet;
stickerSet#eeb46f27 flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true animated:flags.5?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumb:flags.4?PhotoSize thumb_dc_id:flags.4?int count:int hash:int = StickerSet; stickerSet#eeb46f27 flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true animated:flags.5?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumb:flags.4?PhotoSize thumb_dc_id:flags.4?int count:int hash:int = StickerSet;
@ -692,8 +692,8 @@ 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#fd8e711f flags:# no_webpage:flags.1?true reply_to_msg_id:flags.0?int message:string entities:flags.3?Vector<MessageEntity> date:int = DraftMessage;
messages.featuredStickersNotModified#4ede3cf = messages.FeaturedStickers; messages.featuredStickersNotModified#c6dc0c66 count:int = messages.FeaturedStickers;
messages.featuredStickers#f89d88e5 hash:int sets:Vector<StickerSetCovered> unread:Vector<long> = messages.FeaturedStickers; messages.featuredStickers#b6abc341 hash:int count:int sets:Vector<StickerSetCovered> unread:Vector<long> = messages.FeaturedStickers;
messages.recentStickersNotModified#b17f890 = messages.RecentStickers; messages.recentStickersNotModified#b17f890 = messages.RecentStickers;
messages.recentStickers#22f3afb3 hash:int packs:Vector<StickerPack> stickers:Vector<Document> dates:Vector<int> = messages.RecentStickers; messages.recentStickers#22f3afb3 hash:int packs:Vector<StickerPack> stickers:Vector<Document> dates:Vector<int> = messages.RecentStickers;
@ -1024,11 +1024,11 @@ help.userInfo#1eb3758 message:string entities:Vector<MessageEntity> author:strin
pollAnswer#6ca9c2e9 text:string option:bytes = PollAnswer; pollAnswer#6ca9c2e9 text:string option:bytes = PollAnswer;
poll#d5529d06 id:long flags:# closed:flags.0?true public_voters:flags.1?true multiple_choice:flags.2?true quiz:flags.3?true question:string answers:Vector<PollAnswer> = Poll; poll#86e18161 id:long flags:# closed:flags.0?true public_voters:flags.1?true multiple_choice:flags.2?true quiz:flags.3?true question:string answers:Vector<PollAnswer> close_period:flags.4?int close_date:flags.5?int = Poll;
pollAnswerVoters#3b6ddad2 flags:# chosen:flags.0?true correct:flags.1?true option:bytes voters:int = PollAnswerVoters; pollAnswerVoters#3b6ddad2 flags:# chosen:flags.0?true correct:flags.1?true option:bytes voters:int = PollAnswerVoters;
pollResults#c87024a2 flags:# min:flags.0?true results:flags.1?Vector<PollAnswerVoters> total_voters:flags.2?int recent_voters:flags.3?Vector<int> = PollResults; pollResults#badcc1a3 flags:# min:flags.0?true results:flags.1?Vector<PollAnswerVoters> total_voters:flags.2?int recent_voters:flags.3?Vector<int> solution:flags.4?string solution_entities:flags.4?Vector<MessageEntity> = PollResults;
chatOnlines#f041e250 onlines:int = ChatOnlines; chatOnlines#f041e250 onlines:int = ChatOnlines;
@ -1144,7 +1144,7 @@ stats.broadcastStats#bdf78394 period:StatsDateRangeDays followers:StatsAbsValueA
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
invokeAfterMsgs#3dc4b4f0 {X:Type} msg_ids:Vector<long> query:!X = X; invokeAfterMsgs#3dc4b4f0 {X:Type} msg_ids:Vector<long> query:!X = X;
initConnection#785188b8 {X:Type} flags:# api_id:int device_model:string system_version:string app_version:string system_lang_code:string lang_pack:string lang_code:string proxy:flags.0?InputClientProxy query:!X = X; initConnection#785188b8 {X:Type} flags:# api_id:int device_model:string system_version:string app_version:string system_lang_code:string lang_pack:string lang_code:string proxy:flags.0?InputClientProxy params:flags.1?JSONValue query:!X = X;
invokeWithLayer#da9b0d0d {X:Type} layer:int query:!X = X; invokeWithLayer#da9b0d0d {X:Type} layer:int query:!X = X;
invokeWithoutUpdates#bf9459b7 {X:Type} query:!X = X; invokeWithoutUpdates#bf9459b7 {X:Type} query:!X = X;
invokeWithMessagesRange#365275f2 {X:Type} range:MessageRange query:!X = X; invokeWithMessagesRange#365275f2 {X:Type} range:MessageRange query:!X = X;
@ -1382,6 +1382,7 @@ messages.getDialogFilters#f19ed96d = Vector<DialogFilter>;
messages.getSuggestedDialogFilters#a29cd42c = Vector<DialogFilterSuggested>; messages.getSuggestedDialogFilters#a29cd42c = Vector<DialogFilterSuggested>;
messages.updateDialogFilter#1ad4a04a flags:# id:int filter:flags.0?DialogFilter = Bool; messages.updateDialogFilter#1ad4a04a flags:# id:int filter:flags.0?DialogFilter = Bool;
messages.updateDialogFiltersOrder#c563c1e4 order:Vector<int> = Bool; messages.updateDialogFiltersOrder#c563c1e4 order:Vector<int> = Bool;
messages.getOldFeaturedStickers#5fe7025b offset:int limit:int hash:int = messages.FeaturedStickers;
updates.getState#edd4882a = updates.State; updates.getState#edd4882a = updates.State;
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference; updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
@ -1459,6 +1460,7 @@ channels.getInactiveChannels#11e831ee = messages.InactiveChats;
bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON; bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON;
bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool; bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool;
bots.setBotCommands#805d46f6 commands:Vector<BotCommand> = Bool;
payments.getPaymentForm#99f09745 msg_id:int = payments.PaymentForm; payments.getPaymentForm#99f09745 msg_id:int = payments.PaymentForm;
payments.getPaymentReceipt#a092a980 msg_id:int = payments.PaymentReceipt; payments.getPaymentReceipt#a092a980 msg_id:int = payments.PaymentReceipt;
@ -1468,10 +1470,11 @@ payments.getSavedInfo#227d824b = payments.SavedInfo;
payments.clearSavedInfo#d83d70c1 flags:# credentials:flags.0?true info:flags.1?true = Bool; payments.clearSavedInfo#d83d70c1 flags:# credentials:flags.0?true info:flags.1?true = Bool;
payments.getBankCardData#2e79d779 number:string = payments.BankCardData; payments.getBankCardData#2e79d779 number:string = payments.BankCardData;
stickers.createStickerSet#9bd86e6a flags:# masks:flags.0?true user_id:InputUser title:string short_name:string stickers:Vector<InputStickerSetItem> = messages.StickerSet; stickers.createStickerSet#f1036780 flags:# masks:flags.0?true animated:flags.1?true user_id:InputUser title:string short_name:string thumb:flags.2?InputDocument stickers:Vector<InputStickerSetItem> = messages.StickerSet;
stickers.removeStickerFromSet#f7760f51 sticker:InputDocument = messages.StickerSet; stickers.removeStickerFromSet#f7760f51 sticker:InputDocument = messages.StickerSet;
stickers.changeStickerPosition#ffb6d4ca sticker:InputDocument position:int = messages.StickerSet; stickers.changeStickerPosition#ffb6d4ca sticker:InputDocument position:int = messages.StickerSet;
stickers.addStickerToSet#8653febe stickerset:InputStickerSet sticker:InputStickerSetItem = messages.StickerSet; stickers.addStickerToSet#8653febe stickerset:InputStickerSet sticker:InputStickerSetItem = messages.StickerSet;
stickers.setStickerSetThumb#9a364e30 stickerset:InputStickerSet thumb:InputDocument = messages.StickerSet;
phone.getCallConfig#55451fa9 = DataJSON; phone.getCallConfig#55451fa9 = DataJSON;
phone.requestCall#42ff96ed flags:# video:flags.0?true user_id:InputUser random_id:int g_a_hash:bytes protocol:PhoneCallProtocol = phone.PhoneCall; phone.requestCall#42ff96ed flags:# video:flags.0?true user_id:InputUser random_id:int g_a_hash:bytes protocol:PhoneCallProtocol = phone.PhoneCall;
@ -1491,7 +1494,7 @@ langpack.getLanguage#6a596502 lang_pack:string lang_code:string = LangPackLangua
folders.editPeerFolders#6847d0ab folder_peers:Vector<InputFolderPeer> = Updates; folders.editPeerFolders#6847d0ab folder_peers:Vector<InputFolderPeer> = Updates;
folders.deleteFolder#1c295881 folder_id:int = Updates; folders.deleteFolder#1c295881 folder_id:int = Updates;
stats.getBroadcastStats#ab42441a flags:# dark:flags.0?true channel:InputChannel = stats.BroadcastStats; stats.getBroadcastStats#e6300dba flags:# dark:flags.0?true channel:InputChannel tz_offset:int = stats.BroadcastStats;
stats.loadAsyncGraph#621d5fa0 flags:# token:string x:flags.0?long = StatsGraph; stats.loadAsyncGraph#621d5fa0 flags:# token:string x:flags.0?long = StatsGraph;
// LAYER 111 // LAYER 112

View File

@ -200,9 +200,12 @@ void SendExistingPhoto(
bool SendDice(Api::MessageToSend &message) { bool SendDice(Api::MessageToSend &message) {
static const auto kDiceString = QString::fromUtf8("\xF0\x9F\x8E\xB2"); static const auto kDiceString = QString::fromUtf8("\xF0\x9F\x8E\xB2");
if (message.textWithTags.text.midRef(0).trimmed() != kDiceString) { static const auto kDartString = QString::fromUtf8("\xF0\x9F\x8E\xAF");
const auto full = message.textWithTags.text.midRef(0).trimmed();
if (full != kDiceString && full != kDartString) {
return false; return false;
} }
const auto emoji = full.toString();
const auto history = message.action.history; const auto history = message.action.history;
const auto peer = history->peer; const auto peer = history->peer;
const auto session = &history->session(); const auto session = &history->session();
@ -266,7 +269,7 @@ bool SendDice(Api::MessageToSend &message) {
MTP_int(HistoryItem::NewMessageDate( MTP_int(HistoryItem::NewMessageDate(
message.action.options.scheduled)), message.action.options.scheduled)),
MTP_string(), MTP_string(),
MTP_messageMediaDice(MTP_int(0)), MTP_messageMediaDice(MTP_int(0), MTP_string(emoji)),
MTPReplyMarkup(), MTPReplyMarkup(),
MTP_vector<MTPMessageEntity>(), MTP_vector<MTPMessageEntity>(),
MTP_int(1), MTP_int(1),
@ -284,7 +287,7 @@ bool SendDice(Api::MessageToSend &message) {
MTP_flags(sendFlags), MTP_flags(sendFlags),
peer->input, peer->input,
MTP_int(replyTo), MTP_int(replyTo),
MTP_inputMediaDice(), MTP_inputMediaDice(MTP_string(emoji)),
MTP_string(), MTP_string(),
MTP_long(randomId), MTP_long(randomId),
MTPReplyMarkup(), MTPReplyMarkup(),

View File

@ -5775,7 +5775,9 @@ void ApiWrap::createPoll(
MTP_inputMediaPoll( MTP_inputMediaPoll(
MTP_flags(inputFlags), MTP_flags(inputFlags),
PollDataToMTP(&data), PollDataToMTP(&data),
MTP_vector<MTPbytes>(correct)), MTP_vector<MTPbytes>(correct),
MTPstring(), // #TODO polls solution
MTPvector<MTPMessageEntity>()),
MTP_string(), MTP_string(),
MTP_long(rand_value<uint64>()), MTP_long(rand_value<uint64>()),
MTPReplyMarkup(), MTPReplyMarkup(),
@ -5870,7 +5872,9 @@ void ApiWrap::closePoll(not_null<HistoryItem*> item) {
MTP_inputMediaPoll( MTP_inputMediaPoll(
MTP_flags(inputFlags), MTP_flags(inputFlags),
PollDataToMTP(poll, true), PollDataToMTP(poll, true),
MTP_vector<MTPbytes>(correct)), MTP_vector<MTPbytes>(correct),
MTPstring(), // #TODO polls solution
MTPvector<MTPMessageEntity>()),
MTPReplyMarkup(), MTPReplyMarkup(),
MTPVector<MTPMessageEntity>(), MTPVector<MTPMessageEntity>(),
MTP_int(0) // schedule_date MTP_int(0) // schedule_date

View File

@ -24,8 +24,9 @@ constexpr auto kZeroDiceDocumentId = 0xa3b83c9f84fa9e83ULL;
} // namespace } // namespace
DicePack::DicePack(not_null<Main::Session*> session) DicePack::DicePack(not_null<Main::Session*> session, const QString &emoji)
: _session(session) { : _session(session)
, _emoji(emoji) {
} }
DicePack::~DicePack() = default; DicePack::~DicePack() = default;
@ -47,7 +48,7 @@ void DicePack::load() {
return; return;
} }
_requestId = _session->api().request(MTPmessages_GetStickerSet( _requestId = _session->api().request(MTPmessages_GetStickerSet(
MTP_inputStickerSetDice() MTP_inputStickerSetDice(MTP_string(_emoji))
)).done([=](const MTPmessages_StickerSet &result) { )).done([=](const MTPmessages_StickerSet &result) {
result.match([&](const MTPDmessages_stickerSet &data) { result.match([&](const MTPDmessages_stickerSet &data) {
applySet(data); applySet(data);
@ -73,7 +74,11 @@ void DicePack::ensureZeroGenerated() {
return; return;
} }
const auto path = qsl(":/gui/art/dice_idle.tgs"); static const auto kDiceString = QString::fromUtf8("\xF0\x9F\x8E\xB2");
static const auto kDartString = QString::fromUtf8("\xF0\x9F\x8E\xAF");
const auto path = QString((_emoji == kDiceString)
? ":/gui/art/dice_idle.tgs"
: ":/gui/art/dart_idle.tgs");
auto task = FileLoadTask( auto task = FileLoadTask(
path, path,
QByteArray(), QByteArray(),
@ -93,4 +98,18 @@ void DicePack::ensureZeroGenerated() {
Ensures(_zero->sticker()->animated); Ensures(_zero->sticker()->animated);
} }
DicePacks::DicePacks(not_null<Main::Session*> session) : _session(session) {
}
DocumentData *DicePacks::lookup(const QString &emoji, int value) {
const auto i = _packs.find(emoji);
if (i != end(_packs)) {
return i->second->lookup(value);
}
return _packs.emplace(
emoji,
std::make_unique<DicePack>(_session, emoji)
).first->second->lookup(value);
}
} // namespace Stickers } // namespace Stickers

View File

@ -17,7 +17,7 @@ namespace Stickers {
class DicePack final { class DicePack final {
public: public:
explicit DicePack(not_null<Main::Session*> session); DicePack(not_null<Main::Session*> session, const QString &emoji);
~DicePack(); ~DicePack();
DocumentData *lookup(int value); DocumentData *lookup(int value);
@ -27,11 +27,25 @@ private:
void applySet(const MTPDmessages_stickerSet &data); void applySet(const MTPDmessages_stickerSet &data);
void ensureZeroGenerated(); void ensureZeroGenerated();
not_null<Main::Session*> _session; const not_null<Main::Session*> _session;
QString _emoji;
base::flat_map<int, not_null<DocumentData*>> _map; base::flat_map<int, not_null<DocumentData*>> _map;
DocumentData *_zero = nullptr; DocumentData *_zero = nullptr;
mtpRequestId _requestId = 0; mtpRequestId _requestId = 0;
}; };
class DicePacks final {
public:
explicit DicePacks(not_null<Main::Session*> session);
DocumentData *lookup(const QString &emoji, int value);
private:
const not_null<Main::Session*> _session;
base::flat_map<QString, std::unique_ptr<DicePack>> _packs;
};
} // namespace Stickers } // namespace Stickers

View File

@ -53,6 +53,7 @@ generate({
'ipPortSecret#37982646', 'ipPortSecret#37982646',
'accessPointRule#4679b65f', 'accessPointRule#4679b65f',
'help.configSimple#5a592a6c', 'help.configSimple#5a592a6c',
'initConnection#785188b8',
], ],
'renamedTypes': { 'renamedTypes': {

View File

@ -1326,21 +1326,26 @@ std::unique_ptr<HistoryView::Media> MediaPoll::createView(
return std::make_unique<HistoryView::Poll>(message, _poll); return std::make_unique<HistoryView::Poll>(message, _poll);
} }
MediaDice::MediaDice(not_null<HistoryItem*> parent, int value) MediaDice::MediaDice(not_null<HistoryItem*> parent, QString emoji, int value)
: Media(parent) : Media(parent)
, _emoji(emoji)
, _value(value) { , _value(value) {
} }
std::unique_ptr<Media> MediaDice::clone(not_null<HistoryItem*> parent) { std::unique_ptr<Media> MediaDice::clone(not_null<HistoryItem*> parent) {
return std::make_unique<MediaDice>(parent, _value); return std::make_unique<MediaDice>(parent, _emoji, _value);
} }
int MediaDice::diceValue() const { QString MediaDice::emoji() const {
return _emoji;
}
int MediaDice::value() const {
return _value; return _value;
} }
QString MediaDice::notificationText() const { QString MediaDice::notificationText() const {
return QString::fromUtf8("\xF0\x9F\x8E\xB2"); return _emoji;
} }
QString MediaDice::pinnedTextSubstring() const { QString MediaDice::pinnedTextSubstring() const {

View File

@ -407,11 +407,12 @@ private:
class MediaDice final : public Media { class MediaDice final : public Media {
public: public:
MediaDice(not_null<HistoryItem*> parent, int value); MediaDice(not_null<HistoryItem*> parent, QString emoji, int value);
std::unique_ptr<Media> clone(not_null<HistoryItem*> parent) override; std::unique_ptr<Media> clone(not_null<HistoryItem*> parent) override;
int diceValue() const; [[nodiscard]] QString emoji() const;
[[nodiscard]] int value() const;
QString notificationText() const override; QString notificationText() const override;
QString pinnedTextSubstring() const override; QString pinnedTextSubstring() const override;
@ -423,6 +424,7 @@ public:
not_null<HistoryItem*> realParent) override; not_null<HistoryItem*> realParent) override;
private: private:
QString _emoji;
int _value = 0; int _value = 0;
}; };

View File

@ -231,5 +231,7 @@ MTPPoll PollDataToMTP(not_null<const PollData*> poll, bool close) {
MTP_long(poll->id), MTP_long(poll->id),
MTP_flags(flags), MTP_flags(flags),
MTP_string(poll->question), MTP_string(poll->question),
MTP_vector<MTPPollAnswer>(answers)); MTP_vector<MTPPollAnswer>(answers),
MTPint(), // #TODO polls close_period
MTPint());
} }

View File

@ -1025,7 +1025,10 @@ std::unique_ptr<Data::Media> HistoryMessage::CreateMedia(
item, item,
item->history()->owner().processPoll(media)); item->history()->owner().processPoll(media));
}, [&](const MTPDmessageMediaDice &media) -> Result { }, [&](const MTPDmessageMediaDice &media) -> Result {
return std::make_unique<Data::MediaDice>(item, media.vvalue().v); return std::make_unique<Data::MediaDice>(
item,
qs(media.vemoticon()),
media.vvalue().v);
}, [](const MTPDmessageMediaEmpty &) -> Result { }, [](const MTPDmessageMediaEmpty &) -> Result {
return nullptr; return nullptr;
}, [](const MTPDmessageMediaUnsupported &) -> Result { }, [](const MTPDmessageMediaUnsupported &) -> Result {

View File

@ -20,9 +20,22 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace HistoryView { namespace HistoryView {
namespace { namespace {
DocumentData *Lookup(not_null<Element*> view, int value) { [[nodiscard]] DocumentData *Lookup(
not_null<Element*> view,
const QString &emoji,
int value) {
const auto &session = view->data()->history()->session(); const auto &session = view->data()->history()->session();
return session.diceStickersPack().lookup(value); return session.diceStickersPacks().lookup(emoji, value);
}
[[nodiscard]] ClickHandlerPtr MakeDiceHandler(const QString &emoji) {
return std::make_shared<LambdaClickHandler>([=] {
auto config = Ui::Toast::Config();
config.multiline = true;
config.minWidth = st::msgMinWidth;
config.text = { tr::lng_about_random(tr::now, lt_emoji, emoji) };
Ui::Toast::Show(config);
});
} }
} // namespace } // namespace
@ -30,9 +43,12 @@ DocumentData *Lookup(not_null<Element*> view, int value) {
Dice::Dice(not_null<Element*> parent, not_null<Data::MediaDice*> dice) Dice::Dice(not_null<Element*> parent, not_null<Data::MediaDice*> dice)
: _parent(parent) : _parent(parent)
, _dice(dice) , _dice(dice)
, _start(parent, Lookup(parent, 0)) { , _link(_parent->data()->Has<HistoryMessageForwarded>()
? nullptr
: MakeDiceHandler(dice->emoji()))
, _start(parent, Lookup(parent, dice->emoji(), 0)) {
_showLastFrame = _parent->data()->Has<HistoryMessageForwarded>(); _showLastFrame = _parent->data()->Has<HistoryMessageForwarded>();
_start.setDiceIndex(0); _start.setDiceIndex(_dice->emoji(), 0);
if (_showLastFrame) { if (_showLastFrame) {
_drawingEnd = true; _drawingEnd = true;
} }
@ -45,24 +61,14 @@ QSize Dice::size() {
} }
ClickHandlerPtr Dice::link() { ClickHandlerPtr Dice::link() {
if (_parent->data()->Has<HistoryMessageForwarded>()) { return _link;
return nullptr;
}
static auto kHandler = std::make_shared<LambdaClickHandler>([] {
auto config = Ui::Toast::Config();
config.multiline = true;
config.minWidth = st::msgMinWidth;
config.text = { tr::lng_about_dice(tr::now) };
Ui::Toast::Show(config);
});
return kHandler;
} }
void Dice::draw(Painter &p, const QRect &r, bool selected) { void Dice::draw(Painter &p, const QRect &r, bool selected) {
if (const auto value = _end ? 0 : _dice->diceValue()) { if (const auto value = _end ? 0 : _dice->value()) {
if (const auto document = Lookup(_parent, value)) { if (const auto document = Lookup(_parent, _dice->emoji(), value)) {
_end.emplace(_parent, document); _end.emplace(_parent, document);
_end->setDiceIndex(value); _end->setDiceIndex(_dice->emoji(), value);
_end->initSize(); _end->initSize();
} }
} }

View File

@ -41,6 +41,7 @@ public:
private: private:
const not_null<Element*> _parent; const not_null<Element*> _parent;
const not_null<Data::MediaDice*> _dice; const not_null<Data::MediaDice*> _dice;
ClickHandlerPtr _link;
std::optional<Sticker> _end; std::optional<Sticker> _end;
Sticker _start; Sticker _start;
mutable bool _showLastFrame = false; mutable bool _showLastFrame = false;

View File

@ -37,13 +37,17 @@ namespace {
0.625); 0.625);
} }
[[nodiscard]] QImage CacheDiceImage(int index, const QImage &image) { [[nodiscard]] QImage CacheDiceImage(
static auto Cache = base::flat_map<int, QImage>(); const QString &emoji,
const auto i = Cache.find(index); int index,
const QImage &image) {
static auto Cache = base::flat_map<std::pair<QString, int>, QImage>();
const auto key = std::make_pair(emoji, index);
const auto i = Cache.find(key);
if (i != end(Cache) && i->second.size() == image.size()) { if (i != end(Cache) && i->second.size() == image.size()) {
return i->second; return i->second;
} }
Cache[index] = image; Cache[key] = image;
return image; return image;
} }
@ -126,7 +130,7 @@ void Sticker::paintLottie(Painter &p, const QRect &r, bool selected) {
: Lottie::Animation::FrameInfo(); : Lottie::Animation::FrameInfo();
if (_nextLastDiceFrame) { if (_nextLastDiceFrame) {
_nextLastDiceFrame = false; _nextLastDiceFrame = false;
_lastDiceFrame = CacheDiceImage(_diceIndex, frame.image); _lastDiceFrame = CacheDiceImage(_diceEmoji, _diceIndex, frame.image);
} }
const auto &image = _lastDiceFrame.isNull() const auto &image = _lastDiceFrame.isNull()
? frame.image ? frame.image
@ -237,7 +241,8 @@ void Sticker::refreshLink() {
} }
} }
void Sticker::setDiceIndex(int index) { void Sticker::setDiceIndex(const QString &emoji, int index) {
_diceEmoji = emoji;
_diceIndex = index; _diceIndex = index;
} }

View File

@ -49,7 +49,7 @@ public:
} }
void refreshLink() override; void refreshLink() override;
void setDiceIndex(int index); void setDiceIndex(const QString &emoji, int index);
[[nodiscard]] bool atTheEnd() const { [[nodiscard]] bool atTheEnd() const {
return _atTheEnd; return _atTheEnd;
} }
@ -71,6 +71,7 @@ private:
ClickHandlerPtr _link; ClickHandlerPtr _link;
QSize _size; QSize _size;
QImage _lastDiceFrame; QImage _lastDiceFrame;
QString _diceEmoji;
int _diceIndex = -1; int _diceIndex = -1;
mutable bool _lottieOncePlayed = false; mutable bool _lottieOncePlayed = false;
mutable bool _atTheEnd = false; mutable bool _atTheEnd = false;

View File

@ -57,7 +57,7 @@ Session::Session(
, _data(std::make_unique<Data::Session>(this)) , _data(std::make_unique<Data::Session>(this))
, _user(_data->processUser(user)) , _user(_data->processUser(user))
, _emojiStickersPack(std::make_unique<Stickers::EmojiPack>(this)) , _emojiStickersPack(std::make_unique<Stickers::EmojiPack>(this))
, _diceStickersPack(std::make_unique<Stickers::DicePack>(this)) , _diceStickersPacks(std::make_unique<Stickers::DicePacks>(this))
, _changelogs(Core::Changelogs::Create(this)) , _changelogs(Core::Changelogs::Create(this))
, _supportHelper(Support::Helper::Create(this)) { , _supportHelper(Support::Helper::Create(this)) {
Core::App().passcodeLockChanges( Core::App().passcodeLockChanges(

View File

@ -46,7 +46,7 @@ class Instance;
namespace Stickers { namespace Stickers {
class EmojiPack; class EmojiPack;
class DicePack; class DicePacks;
} // namespace Stickers; } // namespace Stickers;
namespace Core { namespace Core {
@ -93,8 +93,8 @@ public:
[[nodiscard]] Stickers::EmojiPack &emojiStickersPack() const { [[nodiscard]] Stickers::EmojiPack &emojiStickersPack() const {
return *_emojiStickersPack; return *_emojiStickersPack;
} }
[[nodiscard]] Stickers::DicePack &diceStickersPack() const { [[nodiscard]] Stickers::DicePacks &diceStickersPacks() const {
return *_diceStickersPack; return *_diceStickersPacks;
} }
[[nodiscard]] base::Observable<void> &downloaderTaskFinished(); [[nodiscard]] base::Observable<void> &downloaderTaskFinished();
@ -161,7 +161,7 @@ private:
// _emojiStickersPack depends on _data. // _emojiStickersPack depends on _data.
const std::unique_ptr<Stickers::EmojiPack> _emojiStickersPack; const std::unique_ptr<Stickers::EmojiPack> _emojiStickersPack;
const std::unique_ptr<Stickers::DicePack> _diceStickersPack; const std::unique_ptr<Stickers::DicePacks> _diceStickersPacks;
// _changelogs depends on _data, subscribes on chats loading event. // _changelogs depends on _data, subscribes on chats loading event.
const std::unique_ptr<Core::Changelogs> _changelogs; const std::unique_ptr<Core::Changelogs> _changelogs;

View File

@ -621,6 +621,7 @@ void SessionPrivate::tryToSend() {
MTP_string(langPackName), MTP_string(langPackName),
MTP_string(cloudLangCode), MTP_string(cloudLangCode),
clientProxyFields, clientProxyFields,
MTPJSONValue(), // #TODO polls timezone
SerializedRequest()); SerializedRequest());
initSizeInInts = (tl::count_length(initWrapper) >> 2) + 2; initSizeInInts = (tl::count_length(initWrapper) >> 2) + 2;
initSize = initSizeInInts * sizeof(mtpPrime); initSize = initSizeInInts * sizeof(mtpPrime);