Update API scheme to layer 169. Multigifts.

This commit is contained in:
John Preston 2023-12-20 21:16:07 -04:00
parent ed7212f864
commit 41ae1f56ed
11 changed files with 127 additions and 37 deletions

View File

@ -4258,6 +4258,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_request_peer_confirm_rights" = "This will also add {bot} to {chat} with the following rights: {rights}.";
"lng_request_peer_confirm_send" = "Send";
"lng_request_user_title" = "Choose User";
"lng_request_users_title" = "Choose Users";
"lng_request_user_premium_yes" = "The user should have a Premium subscription.";
"lng_request_user_premium_no" = "The user shouldn't have a Premium subscription.";
"lng_request_user_no" = "No such users";

View File

@ -415,12 +415,16 @@ void ActivateBotCommand(ClickHandlerContext context, int row, int column) {
const auto peer = item->history()->peer;
const auto itemId = item->id;
const auto id = int32(button->buttonId);
const auto chosen = [=](not_null<PeerData*> result) {
const auto chosen = [=](std::vector<not_null<PeerData*>> result) {
peer->session().api().request(MTPmessages_SendBotRequestedPeer(
peer->input,
MTP_int(itemId),
MTP_int(id),
result->input
MTP_vector_from_range(
result
| ranges::views::transform([](
not_null<PeerData*> peer) {
return MTPInputPeer(peer->input); }))
)).done([=](const MTPUpdates &result) {
peer->session().api().applyUpdates(result);
}).send();

View File

@ -40,11 +40,14 @@ public:
not_null<Window::SessionNavigation*> navigation,
not_null<UserData*> bot,
RequestPeerQuery query,
Fn<void(not_null<PeerData*>)> callback);
Fn<void(std::vector<not_null<PeerData*>>)> callback);
Main::Session &session() const override;
void rowClicked(not_null<PeerListRow*> row) override;
[[nodiscard]] rpl::producer<int> selectedCountValue() const;
void submit();
QString savedMessagesChatStatus() const override {
return tr::lng_saved_forward_here(tr::now);
}
@ -60,7 +63,9 @@ private:
not_null<UserData*> _bot;
RequestPeerQuery _query;
base::flat_set<not_null<PeerData*>> _commonGroups;
Fn<void(not_null<PeerData*>)> _callback;
base::flat_set<not_null<PeerData*>> _selected;
rpl::variable<int> _selectedCount;
Fn<void(std::vector<not_null<PeerData*>>)> _callback;
};
@ -253,10 +258,10 @@ object_ptr<Ui::BoxContent> CreatePeerByQueryBox(
not_null<Window::SessionNavigation*> navigation,
not_null<UserData*> bot,
RequestPeerQuery query,
Fn<void(not_null<PeerData*>)> done) {
Fn<void(std::vector<not_null<PeerData*>>)> done) {
const auto weak = std::make_shared<QPointer<Ui::BoxContent>>();
auto callback = [=](not_null<PeerData*> peer) {
done(peer);
done({ peer });
if (const auto strong = weak->data()) {
strong->closeBox();
}
@ -332,7 +337,7 @@ ChoosePeerBoxController::ChoosePeerBoxController(
not_null<Window::SessionNavigation*> navigation,
not_null<UserData*> bot,
RequestPeerQuery query,
Fn<void(not_null<PeerData*>)> callback)
Fn<void(std::vector<not_null<PeerData*>>)> callback)
: ChatsListBoxController(&navigation->session())
, _navigation(navigation)
, _bot(bot)
@ -415,6 +420,8 @@ void ChoosePeerBoxController::prepareViewHook() {
switch (_query.type) {
case Type::User: return (_query.userIsBot == Restriction::Yes)
? tr::lng_request_bot_title()
: (_query.maxQuantity > 1)
? tr::lng_request_users_title()
: tr::lng_request_user_title();
case Type::Group: return tr::lng_request_group_title();
case Type::Broadcast: return tr::lng_request_channel_title();
@ -425,10 +432,24 @@ void ChoosePeerBoxController::prepareViewHook() {
}
void ChoosePeerBoxController::rowClicked(not_null<PeerListRow*> row) {
const auto limit = _query.maxQuantity;
const auto multiselect = (limit > 1);
const auto peer = row->peer();
if (multiselect) {
if (_selected.contains(peer) || _selected.size() < limit) {
delegate()->peerListSetRowChecked(row, !row->checked());
if (row->checked()) {
_selected.emplace(peer);
} else {
_selected.remove(peer);
}
_selectedCount = int(_selected.size());
}
return;
}
const auto done = [callback = _callback, peer] {
const auto onstack = callback;
onstack(peer);
onstack({ peer });
};
if (const auto user = peer->asUser()) {
done();
@ -438,6 +459,15 @@ void ChoosePeerBoxController::rowClicked(not_null<PeerListRow*> row) {
}
}
rpl::producer<int> ChoosePeerBoxController::selectedCountValue() const {
return _selectedCount.value();
}
void ChoosePeerBoxController::submit() {
const auto onstack = _callback;
onstack(ranges::to_vector(_selected));
}
auto ChoosePeerBoxController::createRow(not_null<History*> history)
-> std::unique_ptr<Row> {
return FilterPeerByQuery(history->peer, _query, _commonGroups)
@ -474,7 +504,7 @@ void ShowChoosePeerBox(
not_null<Window::SessionNavigation*> navigation,
not_null<UserData*> bot,
RequestPeerQuery query,
Fn<void(not_null<PeerData*>)> chosen) {
Fn<void(std::vector<not_null<PeerData*>>)> chosen) {
const auto needCommonGroups = query.isBotParticipant
&& (query.type == RequestPeerQuery::Type::Group)
&& !query.myRights;
@ -488,22 +518,39 @@ void ShowChoosePeerBox(
return;
}
const auto weak = std::make_shared<QPointer<Ui::BoxContent>>();
auto initBox = [=](not_null<PeerListBox*> box) {
box->addButton(tr::lng_cancel(), [box] {
box->closeBox();
});
};
auto callback = [=, done = std::move(chosen)](not_null<PeerData*> peer) {
done(peer);
auto callback = [=, done = std::move(chosen)](
std::vector<not_null<PeerData*>> peers) {
done(std::move(peers));
if (const auto strong = weak->data()) {
strong->closeBox();
}
};
const auto limit = query.maxQuantity;
auto controller = std::make_unique<ChoosePeerBoxController>(
navigation,
bot,
query,
std::move(callback));
auto initBox = [=, ptr = controller.get()](not_null<PeerListBox*> box) {
ptr->selectedCountValue() | rpl::start_with_next([=](int count) {
box->clearButtons();
if (limit > 1) {
box->setAdditionalTitle(rpl::single(u"%1 / %2"_q.arg(count).arg(limit)));
}
if (count > 0) {
box->addButton(tr::lng_intro_submit(), [=] {
ptr->submit();
if (*weak) {
(*weak)->closeBox();
}
});
}
box->addButton(tr::lng_cancel(), [box] {
box->closeBox();
});
}, box->lifetime());
};
*weak = navigation->parentController()->show(Box<PeerListBox>(
std::make_unique<ChoosePeerBoxController>(
navigation,
bot,
query,
std::move(callback)),
std::move(controller),
std::move(initBox)));
}

View File

@ -21,4 +21,4 @@ void ShowChoosePeerBox(
not_null<Window::SessionNavigation*> navigation,
not_null<UserData*> bot,
RequestPeerQuery query,
Fn<void(not_null<PeerData*>)> chosen);
Fn<void(std::vector<not_null<PeerData*>>)> chosen);

View File

@ -1435,7 +1435,9 @@ ServiceAction ParseServiceAction(
result.content = content;
}, [&](const MTPDmessageActionRequestedPeer &data) {
auto content = ActionRequestedPeer();
content.peerId = ParsePeerId(data.vpeer());
for (const auto &peer : data.vpeers().v) {
content.peers.push_back(ParsePeerId(peer));
}
content.buttonId = data.vbutton_id().v;
result.content = content;
}, [&](const MTPDmessageActionGiftCode &data) {

View File

@ -547,7 +547,7 @@ struct ActionGiftCode {
};
struct ActionRequestedPeer {
PeerId peerId = 0;
std::vector<PeerId> peers;
int buttonId = 0;
};

View File

@ -592,7 +592,11 @@ QByteArray SerializeMessage(
pushActor();
pushAction("requested_peer");
push("button_id", data.buttonId);
push("peer_id", data.peerId.value);
auto values = std::vector<QByteArray>();
for (const auto &one : data.peers) {
values.push_back(Data::NumberToString(one.value));
}
push("peers", SerializeArray(context, values));
}, [&](const ActionGiftCode &data) {
pushAction("gift_code_prize");
push("gift_code", data.code);

View File

@ -4476,18 +4476,45 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) {
auto prepareRequestedPeer = [&](
const MTPDmessageActionRequestedPeer &action) {
const auto peerId = peerFromMTP(action.vpeer());
const auto peer = history()->owner().peer(peerId);
auto result = PreparedServiceText{};
result.links.push_back(fromLink());
const auto &list = action.vpeers().v;
for (auto i = 0, count = int(list.size()); i != count; ++i) {
const auto id = peerFromMTP(list[i]);
auto user = _history->owner().peer(id);
result.links.push_back(user->createOpenLink());
auto linkText = Ui::Text::Link(user->name(), 2 + i);
if (i == 0) {
result.text = linkText;
} else if (i + 1 == count) {
result.text = tr::lng_action_add_users_and_last(
tr::now,
lt_accumulated,
result.text,
lt_user,
linkText,
Ui::Text::WithEntities);
} else {
result.text = tr::lng_action_add_users_and_one(
tr::now,
lt_accumulated,
result.text,
lt_user,
linkText,
Ui::Text::WithEntities);
}
}
result.text = tr::lng_action_shared_chat_with_bot(
tr::now,
lt_chat,
Ui::Text::Link(peer->name(), 1),
result.text,
lt_bot,
Ui::Text::Link(history()->peer->name(), 2),
Ui::Text::WithEntities);
result.links.push_back(peer->createOpenLink());
result.links.push_back(history()->peer->createOpenLink());
return result;
};

View File

@ -37,10 +37,11 @@ namespace {
}
[[nodiscard]] RequestPeerQuery RequestPeerQueryFromTL(
const MTPRequestPeerType &query) {
const MTPDkeyboardButtonRequestPeer &query) {
using Type = RequestPeerQuery::Type;
using Restriction = RequestPeerQuery::Restriction;
auto result = RequestPeerQuery();
result.maxQuantity = query.vmax_quantity().v;
const auto restriction = [](const MTPBool *value) {
return !value
? Restriction::Any
@ -51,7 +52,7 @@ namespace {
const auto rights = [](const MTPChatAdminRights *value) {
return value ? ChatAdminRightsInfo(*value).flags : ChatAdminRights();
};
query.match([&](const MTPDrequestPeerTypeUser &data) {
query.vpeer_type().match([&](const MTPDrequestPeerTypeUser &data) {
result.type = Type::User;
result.userIsBot = restriction(data.vbot());
result.userIsPremium = restriction(data.vpremium());
@ -134,7 +135,7 @@ void HistoryMessageMarkupData::fillRows(
}, [&](const MTPDkeyboardButtonRequestPhone &data) {
row.emplace_back(Type::RequestPhone, qs(data.vtext()));
}, [&](const MTPDkeyboardButtonRequestPeer &data) {
const auto query = RequestPeerQueryFromTL(data.vpeer_type());
const auto query = RequestPeerQueryFromTL(data);
row.emplace_back(
Type::RequestPeer,
qs(data.vtext()),

View File

@ -45,6 +45,8 @@ struct RequestPeerQuery {
Yes,
No,
};
int maxQuantity = 0;
Type type = Type::User;
Restriction userIsBot = Restriction::Any;
Restriction userIsPremium = Restriction::Any;

View File

@ -170,7 +170,7 @@ messageActionGiftPremium#c83d6aec flags:# currency:string amount:long months:int
messageActionTopicCreate#d999256 flags:# title:string icon_color:int icon_emoji_id:flags.0?long = MessageAction;
messageActionTopicEdit#c0944820 flags:# title:flags.0?string icon_emoji_id:flags.1?long closed:flags.2?Bool hidden:flags.3?Bool = MessageAction;
messageActionSuggestProfilePhoto#57de635e photo:Photo = MessageAction;
messageActionRequestedPeer#fe77345d button_id:int peer:Peer = MessageAction;
messageActionRequestedPeer#31518e9b button_id:int peers:Vector<Peer> = MessageAction;
messageActionSetChatWallPaper#5060a3f4 flags:# same:flags.0?true for_both:flags.1?true wallpaper:WallPaper = MessageAction;
messageActionGiftCode#678c2e09 flags:# via_giveaway:flags.0?true unclaimed:flags.2?true boost_peer:flags.1?Peer months:int slug:string currency:flags.2?string amount:flags.2?long crypto_currency:flags.3?string crypto_amount:flags.3?long = MessageAction;
messageActionGiveawayLaunch#332ba9ed = MessageAction;
@ -594,6 +594,7 @@ inputStickerSetPremiumGifts#c88b3b02 = InputStickerSet;
inputStickerSetEmojiGenericAnimations#4c4d4ce = InputStickerSet;
inputStickerSetEmojiDefaultStatuses#29d0f5ee = InputStickerSet;
inputStickerSetEmojiDefaultTopicIcons#44c1f8e9 = InputStickerSet;
inputStickerSetEmojiChannelDefaultStatuses#49748553 = InputStickerSet;
stickerSet#2dd14edc flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true animated:flags.5?true videos:flags.6?true emojis:flags.7?true text_color:flags.9?true channel_emoji_status:flags.10?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumbs:flags.4?Vector<PhotoSize> thumb_dc_id:flags.4?int thumb_version:flags.4?int thumb_document_id:flags.8?long count:int hash:int = StickerSet;
@ -619,7 +620,7 @@ inputKeyboardButtonUserProfile#e988037b text:string user_id:InputUser = Keyboard
keyboardButtonUserProfile#308660c1 text:string user_id:long = KeyboardButton;
keyboardButtonWebView#13767230 text:string url:string = KeyboardButton;
keyboardButtonSimpleWebView#a0c0505c text:string url:string = KeyboardButton;
keyboardButtonRequestPeer#d0b468c text:string button_id:int peer_type:RequestPeerType = KeyboardButton;
keyboardButtonRequestPeer#53d7bfd8 text:string button_id:int peer_type:RequestPeerType max_quantity:int = KeyboardButton;
keyboardButtonRow#77608b83 buttons:Vector<KeyboardButton> = KeyboardButtonRow;
@ -1757,6 +1758,7 @@ account.deleteAutoSaveExceptions#53bc0020 = Bool;
account.invalidateSignInCodes#ca8ae8ba codes:Vector<string> = Bool;
account.updateColor#7cefa15d flags:# for_profile:flags.1?true color:flags.2?int background_emoji_id:flags.0?long = Bool;
account.getDefaultBackgroundEmojis#a60ab9ce hash:long = EmojiList;
account.getChannelDefaultEmojiStatuses#7727a7d5 hash:long = account.EmojiStatuses;
account.getChannelRestrictedStatusEmojis#35a9e0d5 hash:long = EmojiList;
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
@ -1967,7 +1969,7 @@ messages.clearRecentReactions#9dfeefb4 = Bool;
messages.getExtendedMedia#84f80814 peer:InputPeer id:Vector<int> = Updates;
messages.setDefaultHistoryTTL#9eb51445 period:int = Bool;
messages.getDefaultHistoryTTL#658b7188 = DefaultHistoryTTL;
messages.sendBotRequestedPeer#fe38d01b peer:InputPeer msg_id:int button_id:int requested_peer:InputPeer = Updates;
messages.sendBotRequestedPeer#91b2d060 peer:InputPeer msg_id:int button_id:int requested_peers:Vector<InputPeer> = Updates;
messages.getEmojiGroups#7488ce5b hash:int = messages.EmojiGroups;
messages.getEmojiStatusGroups#2ecd56cd hash:int = messages.EmojiGroups;
messages.getEmojiProfilePhotoGroups#21a548f3 hash:int = messages.EmojiGroups;
@ -2219,4 +2221,4 @@ premium.applyBoost#6b7da746 flags:# slots:flags.0?Vector<int> peer:InputPeer = p
premium.getBoostsStatus#42f1f61 peer:InputPeer = premium.BoostsStatus;
premium.getUserBoosts#39854d1f peer:InputPeer user_id:InputUser = premium.BoostsList;
// LAYER 168
// LAYER 169