Added support of inline markup reply to JSON export.

This commit is contained in:
23rd 2023-12-07 01:44:33 +03:00 committed by John Preston
parent f41a3fe01f
commit 563b8d1468
3 changed files with 212 additions and 0 deletions

View File

@ -52,6 +52,112 @@ QString PrepareStoryFileName(
+ extension;
}
std::vector<std::vector<HistoryMessageMarkupButton>> ButtonRowsFromTL(
const MTPDreplyInlineMarkup &data) {
const auto &list = data.vrows().v;
if (list.isEmpty()) {
return {};
}
using Type = HistoryMessageMarkupButton::Type;
auto rows = std::vector<std::vector<HistoryMessageMarkupButton>>();
rows.reserve(list.size());
for (const auto &tlRow : list) {
auto row = std::vector<HistoryMessageMarkupButton>();
row.reserve(tlRow.data().vbuttons().v.size());
for (const auto &button : tlRow.data().vbuttons().v) {
button.match([&](const MTPDkeyboardButton &data) {
row.push_back({ Type::Default, qs(data.vtext()) });
}, [&](const MTPDkeyboardButtonCallback &data) {
row.push_back({
(data.is_requires_password()
? Type::CallbackWithPassword
: Type::Callback),
qs(data.vtext()),
qba(data.vdata())
});
}, [&](const MTPDkeyboardButtonRequestGeoLocation &data) {
row.push_back({ Type::RequestLocation, qs(data.vtext()) });
}, [&](const MTPDkeyboardButtonRequestPhone &data) {
row.push_back({ Type::RequestPhone, qs(data.vtext()) });
}, [&](const MTPDkeyboardButtonRequestPeer &data) {
row.push_back({
Type::RequestPeer,
qs(data.vtext()),
QByteArray("unsupported"),
QString(),
int64(data.vbutton_id().v),
});
}, [&](const MTPDkeyboardButtonUrl &data) {
row.push_back({
Type::Url,
qs(data.vtext()),
qba(data.vurl())
});
}, [&](const MTPDkeyboardButtonSwitchInline &data) {
const auto type = data.is_same_peer()
? Type::SwitchInlineSame
: Type::SwitchInline;
row.push_back({ type, qs(data.vtext()), qba(data.vquery()) });
}, [&](const MTPDkeyboardButtonGame &data) {
row.push_back({ Type::Game, qs(data.vtext()) });
}, [&](const MTPDkeyboardButtonBuy &data) {
row.push_back({ Type::Buy, qs(data.vtext()) });
}, [&](const MTPDkeyboardButtonUrlAuth &data) {
row.push_back({
Type::Auth,
qs(data.vtext()),
qba(data.vurl()),
qs(data.vfwd_text().value_or_empty()),
data.vbutton_id().v,
});
}, [&](const MTPDkeyboardButtonRequestPoll &data) {
const auto quiz = [&] {
if (!data.vquiz()) {
return QByteArray();
}
return data.vquiz()->match([&](const MTPDboolTrue&) {
return QByteArray(1, 1);
}, [&](const MTPDboolFalse&) {
return QByteArray(1, 0);
});
}();
row.push_back({
Type::RequestPoll,
qs(data.vtext()),
quiz
});
}, [&](const MTPDkeyboardButtonUserProfile &data) {
row.push_back({
Type::UserProfile,
qs(data.vtext()),
QByteArray::number(data.vuser_id().v)
});
}, [&](const MTPDinputKeyboardButtonUrlAuth &data) {
}, [&](const MTPDinputKeyboardButtonUserProfile &data) {
}, [&](const MTPDkeyboardButtonWebView &data) {
row.push_back({
Type::WebView,
qs(data.vtext()),
data.vurl().v
});
}, [&](const MTPDkeyboardButtonSimpleWebView &data) {
row.push_back({
Type::SimpleWebView,
qs(data.vtext()),
data.vurl().v
});
});
}
if (!row.empty()) {
rows.push_back(std::move(row));
}
}
return rows;
}
} // namespace
uint8 PeerColorIndex(BareId bareId) {
@ -1496,6 +1602,14 @@ Message ParseMessage(
}
context.botId = 0;
}
if (const auto replyMarkup = data.vreply_markup()) {
replyMarkup->match([](const MTPDreplyKeyboardMarkup &) {
}, [&](const MTPDreplyInlineMarkup &data) {
result.inlineButtonRows = ButtonRowsFromTL(data);
}, [](const MTPDreplyKeyboardHide &) {
}, [](const MTPDreplyKeyboardForceReply &) {
});
}
result.text = ParseText(
data.vmessage(),
data.ventities().value_or_empty());

View File

@ -665,6 +665,33 @@ inline bool operator>=(MessageId a, MessageId b) {
return !(a < b);
}
struct HistoryMessageMarkupButton {
enum class Type {
Default,
Url,
Callback,
CallbackWithPassword,
RequestPhone,
RequestLocation,
RequestPoll,
RequestPeer,
SwitchInline,
SwitchInlineSame,
Game,
Buy,
Auth,
UserProfile,
WebView,
SimpleWebView,
};
Type type;
QString text;
QByteArray data;
QString forwardText;
int64 buttonId = 0;
};
struct Message {
int32 id = 0;
TimeId date = 0;
@ -686,6 +713,7 @@ struct Message {
Media media;
ServiceAction action;
bool out = false;
std::vector<std::vector<HistoryMessageMarkupButton>> inlineButtonRows;
File &file();
const File &file() const;

View File

@ -776,6 +776,76 @@ QByteArray SerializeMessage(
pushBare("text", SerializeText(context, message.text));
pushBare("text_entities", SerializeText(context, message.text, true));
if (!message.inlineButtonRows.empty()) {
const auto typeString = [](
const HistoryMessageMarkupButton &entry) -> QByteArray {
using Type = HistoryMessageMarkupButton::Type;
switch (entry.type) {
case Type::Default: return "default";
case Type::Url: return "url";
case Type::Callback: return "callback";
case Type::CallbackWithPassword: return "callback_with_password";
case Type::RequestPhone: return "request_phone";
case Type::RequestLocation: return "request_location";
case Type::RequestPoll: return "request_poll";
case Type::RequestPeer: return "request_peer";
case Type::SwitchInline: return "switch_inline";
case Type::SwitchInlineSame: return "switch_inline_same";
case Type::Game: return "game";
case Type::Buy: return "buy";
case Type::Auth: return "auth";
case Type::UserProfile: return "user_profile";
case Type::WebView: return "web_view";
case Type::SimpleWebView: return "simple_web_view";
}
Unexpected("Type in HistoryMessageMarkupButton::Type.");
};
const auto serializeRow = [&](
const std::vector<HistoryMessageMarkupButton> &row) {
context.nesting.push_back(Context::kArray);
const auto buttons = ranges::views::all(
row
) | ranges::views::transform([&](
const HistoryMessageMarkupButton &entry) {
auto pairs = std::vector<std::pair<QByteArray, QByteArray>>();
pairs.push_back({
"type",
SerializeString(typeString(entry)),
});
if (!entry.text.isEmpty()) {
pairs.push_back({
"text",
SerializeString(entry.text.toUtf8()),
});
}
if (!entry.data.isEmpty()) {
pairs.push_back({ "data", SerializeString(entry.data) });
}
if (!entry.forwardText.isEmpty()) {
pairs.push_back({
"forward_text",
SerializeString(entry.forwardText.toUtf8()),
});
}
if (entry.buttonId) {
pairs.push_back({
"button_id",
NumberToString(entry.buttonId),
});
}
return SerializeObject(context, pairs);
}) | ranges::to_vector;
context.nesting.pop_back();
return SerializeArray(context, buttons);
};
context.nesting.push_back(Context::kArray);
const auto rows = ranges::views::all(
message.inlineButtonRows
) | ranges::views::transform(serializeRow) | ranges::to_vector;
context.nesting.pop_back();
pushBare("inline_bot_buttons", SerializeArray(context, rows));
}
return serialized();
}