Added support of inline markup reply to JSON export.
This commit is contained in:
parent
f41a3fe01f
commit
563b8d1468
|
@ -52,6 +52,112 @@ QString PrepareStoryFileName(
|
||||||
+ extension;
|
+ 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
|
} // namespace
|
||||||
|
|
||||||
uint8 PeerColorIndex(BareId bareId) {
|
uint8 PeerColorIndex(BareId bareId) {
|
||||||
|
@ -1496,6 +1602,14 @@ Message ParseMessage(
|
||||||
}
|
}
|
||||||
context.botId = 0;
|
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(
|
result.text = ParseText(
|
||||||
data.vmessage(),
|
data.vmessage(),
|
||||||
data.ventities().value_or_empty());
|
data.ventities().value_or_empty());
|
||||||
|
|
|
@ -665,6 +665,33 @@ inline bool operator>=(MessageId a, MessageId b) {
|
||||||
return !(a < 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 {
|
struct Message {
|
||||||
int32 id = 0;
|
int32 id = 0;
|
||||||
TimeId date = 0;
|
TimeId date = 0;
|
||||||
|
@ -686,6 +713,7 @@ struct Message {
|
||||||
Media media;
|
Media media;
|
||||||
ServiceAction action;
|
ServiceAction action;
|
||||||
bool out = false;
|
bool out = false;
|
||||||
|
std::vector<std::vector<HistoryMessageMarkupButton>> inlineButtonRows;
|
||||||
|
|
||||||
File &file();
|
File &file();
|
||||||
const File &file() const;
|
const File &file() const;
|
||||||
|
|
|
@ -776,6 +776,76 @@ QByteArray SerializeMessage(
|
||||||
pushBare("text", SerializeText(context, message.text));
|
pushBare("text", SerializeText(context, message.text));
|
||||||
pushBare("text_entities", SerializeText(context, message.text, true));
|
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();
|
return serialized();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue