From 13d22947dfef5ad81613ca2ce4dcb9d9a570cb1e Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 6 Apr 2020 18:55:31 +0400 Subject: [PATCH] Send poll solution with entities. --- Telegram/SourceFiles/apiwrap.cpp | 34 +----------- .../SourceFiles/boxes/create_poll_box.cpp | 18 ++++++- Telegram/SourceFiles/data/data_poll.cpp | 53 +++++++++++++++++-- Telegram/SourceFiles/data/data_poll.h | 13 +++-- 4 files changed, 78 insertions(+), 40 deletions(-) diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 4a476ef9b..a06bd750b 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -5754,16 +5754,6 @@ void ApiWrap::createPoll( if (action.options.scheduled) { sendFlags |= MTPmessages_SendMedia::Flag::f_schedule_date; } - - const auto inputFlags = data.quiz() - ? MTPDinputMediaPoll::Flag::f_correct_answers - : MTPDinputMediaPoll::Flag(0); - auto correct = QVector(); - for (const auto &answer : data.answers) { - if (answer.correct) { - correct.push_back(MTP_bytes(answer.option)); - } - } auto &histories = history->owner().histories(); const auto requestType = Data::Histories::RequestType::Send; histories.sendRequest(history, requestType, [=](Fn finish) { @@ -5772,12 +5762,7 @@ void ApiWrap::createPoll( MTP_flags(sendFlags), peer->input, MTP_int(replyTo), - MTP_inputMediaPoll( - MTP_flags(inputFlags), - PollDataToMTP(&data), - MTP_vector(correct), - MTPstring(), // #TODO polls solution - MTPvector()), + PollDataToInputMedia(&data), MTP_string(), MTP_long(rand_value()), MTPReplyMarkup(), @@ -5854,27 +5839,12 @@ void ApiWrap::closePoll(not_null item) { if (!poll) { return; } - - const auto inputFlags = poll->quiz() - ? MTPDinputMediaPoll::Flag::f_correct_answers - : MTPDinputMediaPoll::Flag(0); - auto correct = QVector(); - for (const auto &answer : poll->answers) { - if (answer.correct) { - correct.push_back(MTP_bytes(answer.option)); - } - } const auto requestId = request(MTPmessages_EditMessage( MTP_flags(MTPmessages_EditMessage::Flag::f_media), item->history()->peer->input, MTP_int(item->id), MTPstring(), - MTP_inputMediaPoll( - MTP_flags(inputFlags), - PollDataToMTP(poll, true), - MTP_vector(correct), - MTPstring(), // #TODO polls solution - MTPvector()), + PollDataToInputMedia(poll, true), MTPReplyMarkup(), MTPVector(), MTP_int(0) // schedule_date diff --git a/Telegram/SourceFiles/boxes/create_poll_box.cpp b/Telegram/SourceFiles/boxes/create_poll_box.cpp index 15e9969da..ff132f2a0 100644 --- a/Telegram/SourceFiles/boxes/create_poll_box.cpp +++ b/Telegram/SourceFiles/boxes/create_poll_box.cpp @@ -38,6 +38,7 @@ constexpr auto kMaxOptionsCount = PollData::kMaxOptions; constexpr auto kOptionLimit = 100; constexpr auto kWarnQuestionLimit = 80; constexpr auto kWarnOptionLimit = 30; +constexpr auto kSolutionLimit = 400; constexpr auto kErrorLimit = 99; class Options { @@ -816,7 +817,13 @@ not_null CreatePollBox::setupSolution( tr::lng_polls_solution_placeholder()), st::createPollFieldPadding); InitField(getDelegate()->outerContainer(), solution, _session); - solution->setMaxLength(kQuestionLimit + kErrorLimit); + solution->setMaxLength(kSolutionLimit + kErrorLimit); + solution->setInstantReplaces(Ui::InstantReplaces::Default()); + solution->setInstantReplacesEnabled( + _session->settings().replaceEmojiValue()); + solution->setMarkdownReplacesEnabled(rpl::single(true)); + solution->setEditLinkCallback( + DefaultEditLinkCallback(_session, solution)); inner->add( object_ptr( @@ -901,7 +908,7 @@ object_ptr CreatePollBox::setupContent() { st::defaultCheckbox), st::createPollCheckboxMargin); - const auto explanation = setupSolution( + const auto solution = setupSolution( container, rpl::single(quiz->checked()) | rpl::then(quiz->checkedChanges())); @@ -950,6 +957,13 @@ object_ptr CreatePollBox::setupContent() { auto result = PollData(&_session->data(), id); result.question = question->getLastText().trimmed(); result.answers = options->toPollAnswers(); + const auto solutionWithTags = quiz->checked() + ? solution->getTextWithAppliedMarkdown() + : TextWithTags(); + result.solution = TextWithEntities{ + solutionWithTags.text, + TextUtilities::ConvertTextTagsToEntities(solutionWithTags.tags) + }; const auto publicVotes = (anonymous && !anonymous->checked()); const auto multiChoice = (multiple && multiple->checked()); result.setFlags(Flag(0) diff --git a/Telegram/SourceFiles/data/data_poll.cpp b/Telegram/SourceFiles/data/data_poll.cpp index 6972710bd..de7509bbf 100644 --- a/Telegram/SourceFiles/data/data_poll.cpp +++ b/Telegram/SourceFiles/data/data_poll.cpp @@ -11,6 +11,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_user.h" #include "data/data_session.h" #include "main/main_session.h" +#include "api/api_text_entities.h" +#include "ui/text_options.h" namespace { @@ -123,6 +125,15 @@ bool PollData::applyResults(const MTPPollResults &results) { }) | ranges::to_vector; } } + auto newSolution = TextWithEntities{ + results.vsolution().value_or_empty(), + Api::EntitiesFromMTP( + results.vsolution_entities().value_or_empty()) + }; + if (solution != newSolution) { + solution = std::move(newSolution); + changed = true; + } if (!changed) { return false; } @@ -226,12 +237,48 @@ MTPPoll PollDataToMTP(not_null poll, bool close) { const auto flags = ((poll->closed() || close) ? Flag::f_closed : Flag(0)) | (poll->multiChoice() ? Flag::f_multiple_choice : Flag(0)) | (poll->publicVotes() ? Flag::f_public_voters : Flag(0)) - | (poll->quiz() ? Flag::f_quiz : Flag(0)); + | (poll->quiz() ? Flag::f_quiz : Flag(0)) + | (poll->closePeriod > 0 ? Flag::f_close_period : Flag(0)); return MTP_poll( MTP_long(poll->id), MTP_flags(flags), MTP_string(poll->question), MTP_vector(answers), - MTPint(), // #TODO polls close_period - MTPint()); + MTP_int(poll->closePeriod), + MTP_int(poll->closeDate)); +} + +MTPInputMedia PollDataToInputMedia( + not_null poll, + bool close) { + auto inputFlags = MTPDinputMediaPoll::Flag(0) + | (poll->quiz() + ? MTPDinputMediaPoll::Flag::f_correct_answers + : MTPDinputMediaPoll::Flag(0)); + auto correct = QVector(); + for (const auto &answer : poll->answers) { + if (answer.correct) { + correct.push_back(MTP_bytes(answer.option)); + } + } + + auto solution = poll->solution; + const auto prepareFlags = Ui::ItemTextDefaultOptions().flags; + TextUtilities::PrepareForSending(solution, prepareFlags); + TextUtilities::Trim(solution); + const auto sentEntities = Api::EntitiesToMTP( + solution.entities, + Api::ConvertOption::SkipLocal); + if (!solution.text.isEmpty()) { + inputFlags |= MTPDinputMediaPoll::Flag::f_solution; + } + if (!sentEntities.v.isEmpty()) { + inputFlags |= MTPDinputMediaPoll::Flag::f_solution_entities; + } + return MTP_inputMediaPoll( + MTP_flags(inputFlags), + PollDataToMTP(poll, close), + MTP_vector(correct), + MTP_string(solution.text), + sentEntities); } diff --git a/Telegram/SourceFiles/data/data_poll.h b/Telegram/SourceFiles/data/data_poll.h index 590747955..ded89a318 100644 --- a/Telegram/SourceFiles/data/data_poll.h +++ b/Telegram/SourceFiles/data/data_poll.h @@ -60,10 +60,12 @@ struct PollData { QString question; std::vector answers; std::vector> recentVoters; - int totalVoters = 0; std::vector sendingVotes; crl::time lastResultsUpdate = 0; - + TextWithEntities solution; + TimeId closePeriod = -1; + TimeId closeDate = -1; + int totalVoters = 0; int version = 0; static constexpr auto kMaxOptions = 10; @@ -78,4 +80,9 @@ private: }; -MTPPoll PollDataToMTP(not_null poll, bool close = false); +[[nodiscard]] MTPPoll PollDataToMTP( + not_null poll, + bool close = false); +[[nodiscard]] MTPInputMedia PollDataToInputMedia( + not_null poll, + bool close = false);