diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index a6ce204ffa..1b86c2cd1e 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -188,8 +188,6 @@ PRIVATE boxes/passcode_box.h boxes/photo_crop_box.cpp boxes/photo_crop_box.h - boxes/poll_results_box.cpp - boxes/poll_results_box.h boxes/rate_call_box.cpp boxes/rate_call_box.h boxes/report_box.cpp @@ -520,6 +518,10 @@ PRIVATE info/media/info_media_widget.h info/members/info_members_widget.cpp info/members/info_members_widget.h + info/polls/info_polls_results_inner_widget.cpp + info/polls/info_polls_results_inner_widget.h + info/polls/info_polls_results_widget.cpp + info/polls/info_polls_results_widget.h info/profile/info_profile_actions.cpp info/profile/info_profile_actions.h info/profile/info_profile_cover.cpp diff --git a/Telegram/SourceFiles/boxes/poll_results_box.h b/Telegram/SourceFiles/boxes/poll_results_box.h deleted file mode 100644 index 7128258ca2..0000000000 --- a/Telegram/SourceFiles/boxes/poll_results_box.h +++ /dev/null @@ -1,23 +0,0 @@ -/* -This file is part of Telegram Desktop, -the official desktop application for the Telegram messaging service. - -For license and copyright information please follow this link: -https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL -*/ -#pragma once - -#include "ui/layers/generic_box.h" - -class PollData; -class HistoryItem; - -namespace Window { -class SessionController; -} // namespace Window - -void PollResultsBox( - not_null box, - not_null window, - not_null poll, - FullMsgId context); diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index 60dc565876..62690eed2d 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -34,7 +34,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/confirm_box.h" #include "boxes/report_box.h" #include "boxes/sticker_set_box.h" -#include "boxes/poll_results_box.h" #include "chat_helpers/message_field.h" #include "chat_helpers/stickers.h" #include "history/history_widget.h" @@ -2423,8 +2422,7 @@ void HistoryInner::elementStartStickerLoop( void HistoryInner::elementShowPollResults( not_null poll, FullMsgId context) { - _controller->window().show( - Box(PollResultsBox, _controller, poll, context)); + _controller->showPollResults(poll, context); } auto HistoryInner::getSelectionState() const diff --git a/Telegram/SourceFiles/history/view/media/history_view_poll.cpp b/Telegram/SourceFiles/history/view/media/history_view_poll.cpp index b89eb1eff5..a68711ffa4 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_poll.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_poll.cpp @@ -18,7 +18,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/effects/animations.h" #include "ui/effects/radial_animation.h" #include "ui/effects/ripple_animation.h" -#include "boxes/poll_results_box.h" #include "data/data_media_types.h" #include "data/data_poll.h" #include "data/data_user.h" diff --git a/Telegram/SourceFiles/info/info_content_widget.cpp b/Telegram/SourceFiles/info/info_content_widget.cpp index ba0fd759ca..61b56c7c32 100644 --- a/Telegram/SourceFiles/info/info_content_widget.cpp +++ b/Telegram/SourceFiles/info/info_content_widget.cpp @@ -266,6 +266,8 @@ Key ContentMemento::key() const { return Key(Auth().data().peer(peerId)); //} else if (const auto feed = this->feed()) { // #feed // return Key(feed); + } else if (const auto poll = this->poll()) { + return Key(poll, pollContextId()); } else { return Settings::Tag{ settingsSelf() }; } diff --git a/Telegram/SourceFiles/info/info_content_widget.h b/Telegram/SourceFiles/info/info_content_widget.h index 1b2c50987a..9620a165f2 100644 --- a/Telegram/SourceFiles/info/info_content_widget.h +++ b/Telegram/SourceFiles/info/info_content_widget.h @@ -123,6 +123,10 @@ public: //explicit ContentMemento(not_null feed) : _feed(feed) { // #feed //} explicit ContentMemento(Settings::Tag settings); + ContentMemento(not_null poll, FullMsgId contextId) + : _poll(poll) + , _pollContextId(contextId) { + } virtual object_ptr createWidget( QWidget *parent, @@ -141,6 +145,12 @@ public: UserData *settingsSelf() const { return _settingsSelf; } + PollData *poll() const { + return _poll; + } + FullMsgId pollContextId() const { + return _pollContextId; + } Key key() const; virtual Section section() const = 0; @@ -177,6 +187,9 @@ private: const PeerId _migratedPeerId = 0; //Data::Feed * const _feed = nullptr; // #feed UserData * const _settingsSelf = nullptr; + PollData * const _poll = nullptr; + const FullMsgId _pollContextId; + int _scrollTop = 0; QString _searchFieldQuery; bool _searchEnabledByContent = false; diff --git a/Telegram/SourceFiles/info/info_controller.cpp b/Telegram/SourceFiles/info/info_controller.cpp index 41f6951f68..8d44e38009 100644 --- a/Telegram/SourceFiles/info/info_controller.cpp +++ b/Telegram/SourceFiles/info/info_controller.cpp @@ -19,6 +19,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_channel.h" #include "data/data_chat.h" #include "data/data_session.h" +#include "data/data_media_types.h" +#include "history/history_item.h" #include "main/main_session.h" #include "window/window_session_controller.h" @@ -46,6 +48,10 @@ Key::Key(not_null peer) : _value(peer) { Key::Key(Settings::Tag settings) : _value(settings) { } +Key::Key(not_null poll, FullMsgId contextId) +: _value(PollKey{ poll, contextId }) { +} + PeerData *Key::peer() const { if (const auto peer = base::get_if>(&_value)) { return *peer; @@ -67,6 +73,20 @@ UserData *Key::settingsSelf() const { return nullptr; } +PollData *Key::poll() const { + if (const auto data = base::get_if(&_value)) { + return data->poll; + } + return nullptr; +} + +FullMsgId Key::pollContextId() const { + if (const auto data = base::get_if(&_value)) { + return data->contextId; + } + return FullMsgId(); +} + rpl::producer AbstractController::mediaSource( SparseIdsMergedSlice::UniversalMsgId aroundId, int limitBefore, @@ -106,6 +126,15 @@ PeerId AbstractController::migratedPeerId() const { return PeerId(0); } +PollData *AbstractController::poll() const { + if (const auto item = session().data().message(pollContextId())) { + if (const auto media = item->media()) { + return media->poll(); + } + } + return nullptr; +} + void AbstractController::showSection( Window::SectionMemento &&memento, const Window::SectionShow ¶ms) { diff --git a/Telegram/SourceFiles/info/info_controller.h b/Telegram/SourceFiles/info/info_controller.h index 9017e5d2ae..de2c5f8b3c 100644 --- a/Telegram/SourceFiles/info/info_controller.h +++ b/Telegram/SourceFiles/info/info_controller.h @@ -33,16 +33,24 @@ public: Key(not_null peer); //Key(not_null feed); // #feed Key(Settings::Tag settings); + Key(not_null poll, FullMsgId contextId); PeerData *peer() const; //Data::Feed *feed() const; // #feed UserData *settingsSelf() const; + PollData *poll() const; + FullMsgId pollContextId() const; private: + struct PollKey { + not_null poll; + FullMsgId contextId; + }; base::variant< not_null, //not_null, // #feed - Settings::Tag> _value; + Settings::Tag, + PollKey> _value; }; @@ -60,6 +68,7 @@ public: Members, //Channels, // #feed Settings, + PollResults, }; using SettingsType = ::Settings::Type; using MediaType = Storage::SharedMediaType; @@ -113,6 +122,10 @@ public: UserData *settingsSelf() const { return key().settingsSelf(); } + PollData *poll() const; + FullMsgId pollContextId() const { + return key().pollContextId(); + } virtual void setSearchEnabledByContent(bool enabled) { } diff --git a/Telegram/SourceFiles/info/info_memento.cpp b/Telegram/SourceFiles/info/info_memento.cpp index f7d75ef633..97fe6142d7 100644 --- a/Telegram/SourceFiles/info/info_memento.cpp +++ b/Telegram/SourceFiles/info/info_memento.cpp @@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "info/common_groups/info_common_groups_widget.h" //#include "info/feed/info_feed_profile_widget.h" // #feed #include "info/settings/info_settings_widget.h" +#include "info/polls/info_polls_results_widget.h" #include "info/info_section_widget.h" #include "info/info_layer_widget.h" #include "info/info_controller.h" @@ -42,6 +43,10 @@ Memento::Memento(Settings::Tag settings, Section section) : Memento(DefaultStack(settings, section)) { } +Memento::Memento(not_null poll, FullMsgId contextId) +: Memento(DefaultStack(poll, contextId)) { +} + Memento::Memento(std::vector> stack) : _stack(std::move(stack)) { } @@ -72,6 +77,14 @@ std::vector> Memento::DefaultStack( return result; } +std::vector> Memento::DefaultStack( + not_null poll, + FullMsgId contextId) { + auto result = std::vector>(); + result.push_back(std::make_unique(poll, contextId)); + return result; +} + Section Memento::DefaultSection(not_null peer) { if (peer->isSelf()) { return Section(Section::MediaType::Photo); diff --git a/Telegram/SourceFiles/info/info_memento.h b/Telegram/SourceFiles/info/info_memento.h index 45e41dff41..58b604f4c4 100644 --- a/Telegram/SourceFiles/info/info_memento.h +++ b/Telegram/SourceFiles/info/info_memento.h @@ -36,6 +36,7 @@ public: Memento(PeerId peerId, Section section); //Memento(not_null feed, Section section); // #feed Memento(Settings::Tag settings, Section section); + Memento(not_null poll, FullMsgId contextId); explicit Memento(std::vector> stack); object_ptr createWidget( @@ -76,10 +77,13 @@ private: static std::vector> DefaultStack( Settings::Tag settings, Section section); + static std::vector> DefaultStack( + not_null poll, + FullMsgId contextId); + //static std::unique_ptr DefaultContent( // #feed // not_null feed, // Section section); - static std::unique_ptr DefaultContent( PeerId peerId, Section section); diff --git a/Telegram/SourceFiles/info/info_top_bar.cpp b/Telegram/SourceFiles/info/info_top_bar.cpp index 8f089fc42a..dae0245cbe 100644 --- a/Telegram/SourceFiles/info/info_top_bar.cpp +++ b/Telegram/SourceFiles/info/info_top_bar.cpp @@ -628,6 +628,11 @@ rpl::producer TitleValue( return tr::lng_settings_section_call_settings(); } Unexpected("Bad settings type in Info::TitleValue()"); + + case Section::Type::PollResults: + return key.poll()->quiz() + ? tr::lng_polls_quiz_results_title() + : tr::lng_polls_poll_results_title(); } Unexpected("Bad section type in Info::TitleValue()"); } diff --git a/Telegram/SourceFiles/boxes/poll_results_box.cpp b/Telegram/SourceFiles/info/polls/info_polls_results_inner_widget.cpp similarity index 56% rename from Telegram/SourceFiles/boxes/poll_results_box.cpp rename to Telegram/SourceFiles/info/polls/info_polls_results_inner_widget.cpp index b1a7465213..e2d540fd61 100644 --- a/Telegram/SourceFiles/boxes/poll_results_box.cpp +++ b/Telegram/SourceFiles/info/polls/info_polls_results_inner_widget.cpp @@ -5,8 +5,9 @@ the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ -#include "boxes/poll_results_box.h" +#include "info/polls/info_polls_results_inner_widget.h" +#include "info/info_controller.h" #include "lang/lang_keys.h" #include "data/data_poll.h" #include "data/data_peer.h" @@ -14,11 +15,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_session.h" #include "ui/widgets/labels.h" #include "ui/widgets/buttons.h" +#include "ui/wrap/vertical_layout.h" #include "ui/wrap/padding_wrap.h" #include "ui/wrap/slide_wrap.h" #include "ui/text/text_utilities.h" #include "boxes/peer_list_box.h" -#include "window/window_session_controller.h" #include "main/main_session.h" #include "history/history.h" #include "history/history_item.h" @@ -27,12 +28,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "styles/style_boxes.h" #include "styles/style_info.h" +namespace Info { +namespace Polls { namespace { constexpr auto kFirstPage = 10; constexpr auto kPerPage = 100; -class Delegate final : public PeerListContentDelegate { +class ListDelegate final : public PeerListContentDelegate { public: void peerListSetTitle(rpl::producer title) override; void peerListSetAdditionalTitle(rpl::producer title) override; @@ -48,10 +51,10 @@ public: }; -class Controller final : public PeerListController { +class ListController final : public PeerListController { public: - Controller( - not_null window, + ListController( + not_null session, not_null poll, FullMsgId context, QByteArray option); @@ -63,11 +66,13 @@ public: void allowLoadAll(); + rpl::producer> showPeerInfoRequests() const; + private: bool appendRow(not_null user); std::unique_ptr createRow(not_null user) const; - const not_null _window; + const not_null _session; const not_null _poll; const FullMsgId _context; const QByteArray _option; @@ -80,62 +85,65 @@ private: bool _allLoaded = false; bool _loadingAll = false; + rpl::event_stream> _showPeerInfoRequests; + }; -void Delegate::peerListSetTitle(rpl::producer title) { +void ListDelegate::peerListSetTitle(rpl::producer title) { } -void Delegate::peerListSetAdditionalTitle(rpl::producer title) { +void ListDelegate::peerListSetAdditionalTitle(rpl::producer title) { } -bool Delegate::peerListIsRowSelected(not_null peer) { +bool ListDelegate::peerListIsRowSelected(not_null peer) { return false; } -int Delegate::peerListSelectedRowsCount() { +int ListDelegate::peerListSelectedRowsCount() { return 0; } -std::vector> Delegate::peerListCollectSelectedRows() { +auto ListDelegate::peerListCollectSelectedRows() +-> std::vector> { return {}; } -void Delegate::peerListScrollToTop() { +void ListDelegate::peerListScrollToTop() { } -void Delegate::peerListAddSelectedRowInBunch(not_null peer) { +void ListDelegate::peerListAddSelectedRowInBunch(not_null peer) { Unexpected("Item selection in Info::Profile::Members."); } -void Delegate::peerListFinishSelectedRowsBunch() { +void ListDelegate::peerListFinishSelectedRowsBunch() { } -void Delegate::peerListSetDescription( +void ListDelegate::peerListSetDescription( object_ptr description) { description.destroy(); } -Controller::Controller( - not_null window, +ListController::ListController( + not_null session, not_null poll, FullMsgId context, QByteArray option) -: _window(window) +: _session(session) , _poll(poll) , _context(context) , _option(option) -, _api(_window->session().api().instance()) { +, _api(_session->api().instance()) { } -Main::Session &Controller::session() const { - return _window->session(); +Main::Session &ListController::session() const { + return *_session; } -void Controller::prepare() { +void ListController::prepare() { delegate()->peerListRefreshRows(); } -void Controller::loadMoreRows() { +void ListController::loadMoreRows() { if (_loadRequestId || _allLoaded || (!_loadingAll && !_offset.isEmpty())) { @@ -180,16 +188,21 @@ void Controller::loadMoreRows() { }).send(); } -void Controller::allowLoadAll() { +void ListController::allowLoadAll() { _loadingAll = true; loadMoreRows(); } -void Controller::rowClicked(not_null row) { - _window->showPeerHistory(row->peer(), Window::SectionShow::Way::Forward); +auto ListController::showPeerInfoRequests() const +-> rpl::producer> { + return _showPeerInfoRequests.events(); } -bool Controller::appendRow(not_null user) { +void ListController::rowClicked(not_null row) { + _showPeerInfoRequests.fire(row->peer()); +} + +bool ListController::appendRow(not_null user) { if (delegate()->peerListFindRow(user->id)) { return false; } @@ -197,21 +210,21 @@ bool Controller::appendRow(not_null user) { return true; } -std::unique_ptr Controller::createRow( +std::unique_ptr ListController::createRow( not_null user) const { auto row = std::make_unique(user); row->setCustomStatus(QString()); return row; } -void CreateAnswerRows( - not_null box, - not_null window, +ListController *CreateAnswerRows( + not_null container, + not_null session, not_null poll, FullMsgId context, const PollAnswer &answer) { if (!answer.votes) { - return; + return nullptr; } const auto percent = answer.votes * 100 / poll->totalVoters; @@ -224,12 +237,12 @@ void CreateAnswerRows( const auto &font = st::boxDividerLabel.style.font; const auto rightWidth = font->width(rightText); const auto rightSkip = rightWidth + font->spacew * 4; - const auto header = box->addRow( + const auto header = container->add( object_ptr( - box, + container, object_ptr( - box, - (answer.text.repeated(20) + container, + (answer.text + QString::fromUtf8(" \xe2\x80\x94 ") + QString::number(percent) + "%"), @@ -238,8 +251,7 @@ void CreateAnswerRows( st::pollResultsHeaderPadding.left(), st::pollResultsHeaderPadding.top(), st::pollResultsHeaderPadding.right() + rightSkip, - st::pollResultsHeaderPadding.bottom())), - style::margins()); + st::pollResultsHeaderPadding.bottom()))); const auto votes = Ui::CreateChild( header, rightText, @@ -251,72 +263,128 @@ void CreateAnswerRows( st::pollResultsHeaderPadding.top(), width); }, votes->lifetime()); - box->addRow(object_ptr(box, st::boxLittleSkip)); + container->add(object_ptr( + container, + st::boxLittleSkip)); - const auto delegate = box->lifetime().make_state(); - const auto controller = box->lifetime().make_state( - window, + const auto delegate = container->lifetime().make_state(); + const auto controller = container->lifetime().make_state( + session, poll, context, answer.option); - const auto content = box->addRow( - object_ptr( - box, - controller, - st::infoCommonGroupsList), - style::margins()); + const auto content = container->add(object_ptr( + container, + controller, + st::infoCommonGroupsList)); delegate->setContent(content); controller->setDelegate(delegate); - const auto more = box->addRow( + const auto more = container->add( object_ptr>( - box, + container, object_ptr( - box, + container, tr::lng_polls_show_more( lt_count_decimal, rpl::single(answer.votes + 0.), Ui::Text::Upper), - st::pollResultsShowMore)), - style::margins()); + st::pollResultsShowMore))); more->toggle(answer.votes > kFirstPage, anim::type::instant); more->entity()->setClickedCallback([=] { controller->allowLoadAll(); more->hide(anim::type::instant); }); - box->addRow(object_ptr(box, st::boxLittleSkip)); + container->add(object_ptr( + container, + st::boxLittleSkip)); + + return controller; } } // namespace -void PollResultsBox( - not_null box, - not_null window, - not_null poll, - FullMsgId context) { - const auto quiz = poll->quiz(); - box->setWidth(st::boxWideWidth); - box->setTitle(quiz - ? tr::lng_polls_quiz_results_title() - : tr::lng_polls_poll_results_title()); - box->setAdditionalTitle((quiz - ? tr::lng_polls_answers_count - : tr::lng_polls_votes_count)( - lt_count_decimal, - rpl::single(poll->totalVoters * 1.))); - box->addRow( +InnerWidget::InnerWidget( + QWidget *parent, + not_null controller, + not_null poll, + FullMsgId contextId) +: RpWidget(parent) +, _controller(controller) +, _poll(poll) +, _contextId(contextId) +, _content(setupContent(this)) { +} + +void InnerWidget::visibleTopBottomUpdated( + int visibleTop, + int visibleBottom) { + setChildVisibleTopBottom(_content, visibleTop, visibleBottom); +} + +void InnerWidget::saveState(not_null memento) { + //memento->setListState(_listController->saveState()); +} + +void InnerWidget::restoreState(not_null memento) { + //_listController->restoreState(memento->listState()); +} + +int InnerWidget::desiredHeight() const { + auto desired = 0; + //auto count = qMax(_user->commonChatsCount(), 1); + //desired += qMax(count, _list->fullRowsCount()) + // * st::infoCommonGroupsList.item.height; + return qMax(height(), desired); +} + +object_ptr InnerWidget::setupContent( + RpWidget *parent) { + auto result = object_ptr(parent); + + const auto quiz = _poll->quiz(); + result->add( object_ptr( - box, - poll->question, + result, + _poll->question, st::pollResultsQuestion), style::margins{ st::boxRowPadding.left(), 0, st::boxRowPadding.right(), st::boxMediumSkip }); - for (const auto &answer : poll->answers) { - CreateAnswerRows(box, window, poll, context, answer); + for (const auto &answer : _poll->answers) { + const auto session = &_controller->parentController()->session(); + const auto controller = CreateAnswerRows( + result, + session, + _poll, + _contextId, + answer); + if (controller) { + controller->showPeerInfoRequests( + ) | rpl::start_to_stream( + _showPeerInfoRequests, + lifetime()); + } } - box->addButton(tr::lng_close(), [=] { box->closeBox(); }); + parent->widthValue( + ) | rpl::start_with_next([content = result.data()](int newWidth) { + content->resizeToWidth(newWidth); + }, result->lifetime()); + result->heightValue( + ) | rpl::start_with_next([=](int height) { + parent->resize(parent->width(), height); + }, result->lifetime()); + return result; } + +auto InnerWidget::showPeerInfoRequests() const +-> rpl::producer> { + return _showPeerInfoRequests.events(); +} + +} // namespace Polls +} // namespace Info + diff --git a/Telegram/SourceFiles/info/polls/info_polls_results_inner_widget.h b/Telegram/SourceFiles/info/polls/info_polls_results_inner_widget.h new file mode 100644 index 0000000000..1bd49441a6 --- /dev/null +++ b/Telegram/SourceFiles/info/polls/info_polls_results_inner_widget.h @@ -0,0 +1,65 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +#include "ui/rp_widget.h" +#include "base/object_ptr.h" + +namespace Ui { +class VerticalLayout; +} // namespace Ui + +namespace Info { + +class Controller; + +namespace Polls { + +class Memento; + +class InnerWidget final : public Ui::RpWidget { +public: + InnerWidget( + QWidget *parent, + not_null controller, + not_null poll, + FullMsgId contextId); + + [[nodiscard]] not_null poll() const { + return _poll; + } + [[nodiscard]] FullMsgId contextId() const { + return _contextId; + } + + [[nodiscard]] auto showPeerInfoRequests() const + -> rpl::producer>; + + [[nodiscard]] int desiredHeight() const; + + void saveState(not_null memento); + void restoreState(not_null memento); + +protected: + void visibleTopBottomUpdated( + int visibleTop, + int visibleBottom) override; + +private: + object_ptr setupContent(RpWidget *parent); + + not_null _controller; + not_null _poll; + FullMsgId _contextId; + object_ptr _content; + rpl::event_stream> _showPeerInfoRequests; + +}; + +} // namespace Polls +} // namespace Info diff --git a/Telegram/SourceFiles/info/polls/info_polls_results_widget.cpp b/Telegram/SourceFiles/info/polls/info_polls_results_widget.cpp new file mode 100644 index 0000000000..82bd5ec669 --- /dev/null +++ b/Telegram/SourceFiles/info/polls/info_polls_results_widget.cpp @@ -0,0 +1,93 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "info/polls/info_polls_results_widget.h" + +#include "info/polls/info_polls_results_inner_widget.h" + +namespace Info { +namespace Polls { + +Memento::Memento(not_null poll, FullMsgId contextId) +: ContentMemento(poll, contextId) { +} + +Section Memento::section() const { + return Section(Section::Type::PollResults); +} + +object_ptr Memento::createWidget( + QWidget *parent, + not_null controller, + const QRect &geometry) { + auto result = object_ptr(parent, controller); + result->setInternalState(geometry, this); + return result; +} + +Memento::~Memento() = default; + +Widget::Widget(QWidget *parent, not_null controller) +: ContentWidget(parent, controller) +, _inner(setInnerWidget( + object_ptr( + this, + controller, + controller->poll(), + controller->pollContextId()))) { + _inner->showPeerInfoRequests( + ) | rpl::start_with_next([=](not_null peer) { + controller->showPeerInfo(peer); + }, _inner->lifetime()); + + controller->setCanSaveChanges(rpl::single(false)); +} + +not_null Widget::poll() const { + return _inner->poll(); +} + +FullMsgId Widget::contextId() const { + return _inner->contextId(); +} + +bool Widget::showInternal(not_null memento) { + //if (const auto myMemento = dynamic_cast(memento.get())) { + // Assert(myMemento->self() == self()); + + // if (_inner->showInternal(myMemento)) { + // return true; + // } + //} + return false; +} + +void Widget::setInternalState( + const QRect &geometry, + not_null memento) { + setGeometry(geometry); + Ui::SendPendingMoveResizeEvents(this); + restoreState(memento); +} + +std::unique_ptr Widget::doCreateMemento() { + auto result = std::make_unique(poll(), contextId()); + saveState(result.get()); + return result; +} + +void Widget::saveState(not_null memento) { + memento->setScrollTop(scrollTopSave()); +} + +void Widget::restoreState(not_null memento) { + const auto scrollTop = memento->scrollTop(); + scrollTopRestore(memento->scrollTop()); +} + +} // namespace Polls +} // namespace Info diff --git a/Telegram/SourceFiles/info/polls/info_polls_results_widget.h b/Telegram/SourceFiles/info/polls/info_polls_results_widget.h new file mode 100644 index 0000000000..efce0460cc --- /dev/null +++ b/Telegram/SourceFiles/info/polls/info_polls_results_widget.h @@ -0,0 +1,58 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +#include "info/info_content_widget.h" +#include "info/info_controller.h" + +namespace Info { +namespace Polls { + +class InnerWidget; + +class Memento final : public ContentMemento { +public: + Memento(not_null poll, FullMsgId contextId); + + object_ptr createWidget( + QWidget *parent, + not_null controller, + const QRect &geometry) override; + + Section section() const override; + + ~Memento(); + +}; + +class Widget final : public ContentWidget { +public: + Widget(QWidget *parent, not_null controller); + + [[nodiscard]] not_null poll() const; + [[nodiscard]] FullMsgId contextId() const; + + bool showInternal( + not_null memento) override; + + void setInternalState( + const QRect &geometry, + not_null memento); + +private: + void saveState(not_null memento); + void restoreState(not_null memento); + + std::unique_ptr doCreateMemento() override; + + not_null _inner; + +}; + +} // namespace Settings +} // namespace Info diff --git a/Telegram/SourceFiles/info/settings/info_settings_widget.h b/Telegram/SourceFiles/info/settings/info_settings_widget.h index d6a8845e75..f4c2413500 100644 --- a/Telegram/SourceFiles/info/settings/info_settings_widget.h +++ b/Telegram/SourceFiles/info/settings/info_settings_widget.h @@ -20,7 +20,6 @@ namespace Settings { using Type = Section::SettingsType; struct Tag; -class InnerWidget; class Memento final : public ContentMemento { public: diff --git a/Telegram/SourceFiles/window/window_session_controller.cpp b/Telegram/SourceFiles/window/window_session_controller.cpp index 34ee9a7add..0856bd0749 100644 --- a/Telegram/SourceFiles/window/window_session_controller.cpp +++ b/Telegram/SourceFiles/window/window_session_controller.cpp @@ -100,6 +100,13 @@ void SessionNavigation::showSettings(const SectionShow ¶ms) { showSettings(Settings::Type::Main, params); } +void SessionNavigation::showPollResults( + not_null poll, + FullMsgId contextId, + const SectionShow ¶ms) { + showSection(Info::Memento(poll, contextId), params); +} + SessionController::SessionController( not_null session, not_null window) diff --git a/Telegram/SourceFiles/window/window_session_controller.h b/Telegram/SourceFiles/window/window_session_controller.h index 2673dacecb..245b5edde9 100644 --- a/Telegram/SourceFiles/window/window_session_controller.h +++ b/Telegram/SourceFiles/window/window_session_controller.h @@ -148,6 +148,11 @@ public: const SectionShow ¶ms = SectionShow()); void showSettings(const SectionShow ¶ms = SectionShow()); + void showPollResults( + not_null poll, + FullMsgId contextId, + const SectionShow ¶ms = SectionShow()); + virtual ~SessionNavigation() = default; private: