mirror of https://github.com/procxx/kepka.git
Save poll results state when viewing profiles.
This commit is contained in:
parent
8c11e1724a
commit
ebae0d71b8
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "info/polls/info_polls_results_inner_widget.h"
|
#include "info/polls/info_polls_results_inner_widget.h"
|
||||||
|
|
||||||
|
#include "info/polls/info_polls_results_widget.h"
|
||||||
#include "info/info_controller.h"
|
#include "info/info_controller.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "data/data_poll.h"
|
#include "data/data_poll.h"
|
||||||
|
@ -51,44 +52,6 @@ public:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ListController final : public PeerListController {
|
|
||||||
public:
|
|
||||||
ListController(
|
|
||||||
not_null<Main::Session*> session,
|
|
||||||
not_null<PollData*> poll,
|
|
||||||
FullMsgId context,
|
|
||||||
QByteArray option);
|
|
||||||
|
|
||||||
Main::Session &session() const override;
|
|
||||||
void prepare() override;
|
|
||||||
void rowClicked(not_null<PeerListRow*> row) override;
|
|
||||||
void loadMoreRows() override;
|
|
||||||
|
|
||||||
void allowLoadAll();
|
|
||||||
|
|
||||||
rpl::producer<not_null<PeerData*>> showPeerInfoRequests() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool appendRow(not_null<UserData*> user);
|
|
||||||
std::unique_ptr<PeerListRow> createRow(not_null<UserData*> user) const;
|
|
||||||
|
|
||||||
const not_null<Main::Session*> _session;
|
|
||||||
const not_null<PollData*> _poll;
|
|
||||||
const FullMsgId _context;
|
|
||||||
const QByteArray _option;
|
|
||||||
|
|
||||||
MTP::Sender _api;
|
|
||||||
|
|
||||||
QString _offset;
|
|
||||||
mtpRequestId _loadRequestId = 0;
|
|
||||||
int _fullCount = 0;
|
|
||||||
bool _allLoaded = false;
|
|
||||||
bool _loadingAll = false;
|
|
||||||
|
|
||||||
rpl::event_stream<not_null<PeerData*>> _showPeerInfoRequests;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
void ListDelegate::peerListSetTitle(rpl::producer<QString> title) {
|
void ListDelegate::peerListSetTitle(rpl::producer<QString> title) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,6 +86,59 @@ void ListDelegate::peerListSetDescription(
|
||||||
description.destroy();
|
description.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
class ListController final : public PeerListController {
|
||||||
|
public:
|
||||||
|
ListController(
|
||||||
|
not_null<Main::Session*> session,
|
||||||
|
not_null<PollData*> poll,
|
||||||
|
FullMsgId context,
|
||||||
|
QByteArray option);
|
||||||
|
|
||||||
|
Main::Session &session() const override;
|
||||||
|
void prepare() override;
|
||||||
|
void rowClicked(not_null<PeerListRow*> row) override;
|
||||||
|
void loadMoreRows() override;
|
||||||
|
|
||||||
|
void allowLoadAll();
|
||||||
|
|
||||||
|
rpl::producer<not_null<PeerData*>> showPeerInfoRequests() const;
|
||||||
|
|
||||||
|
std::unique_ptr<PeerListState> saveState() const override;
|
||||||
|
void restoreState(std::unique_ptr<PeerListState> state) override;
|
||||||
|
|
||||||
|
std::unique_ptr<PeerListRow> createRestoredRow(
|
||||||
|
not_null<PeerData*> peer) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct SavedState : SavedStateBase {
|
||||||
|
QString offset;
|
||||||
|
bool allLoaded = false;
|
||||||
|
bool wasLoading = false;
|
||||||
|
bool loadingAll = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool appendRow(not_null<UserData*> user);
|
||||||
|
std::unique_ptr<PeerListRow> createRow(not_null<UserData*> user) const;
|
||||||
|
|
||||||
|
const not_null<Main::Session*> _session;
|
||||||
|
const not_null<PollData*> _poll;
|
||||||
|
const FullMsgId _context;
|
||||||
|
const QByteArray _option;
|
||||||
|
|
||||||
|
MTP::Sender _api;
|
||||||
|
|
||||||
|
QString _offset;
|
||||||
|
mtpRequestId _loadRequestId = 0;
|
||||||
|
int _fullCount = 0;
|
||||||
|
bool _allLoaded = false;
|
||||||
|
bool _loadingAll = false;
|
||||||
|
|
||||||
|
rpl::event_stream<not_null<PeerData*>> _showPeerInfoRequests;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
ListController::ListController(
|
ListController::ListController(
|
||||||
not_null<Main::Session*> session,
|
not_null<Main::Session*> session,
|
||||||
not_null<PollData*> poll,
|
not_null<PollData*> poll,
|
||||||
|
@ -198,6 +214,46 @@ auto ListController::showPeerInfoRequests() const
|
||||||
return _showPeerInfoRequests.events();
|
return _showPeerInfoRequests.events();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto ListController::saveState() const -> std::unique_ptr<PeerListState> {
|
||||||
|
auto result = PeerListController::saveState();
|
||||||
|
|
||||||
|
auto my = std::make_unique<SavedState>();
|
||||||
|
my->offset = _offset;
|
||||||
|
my->allLoaded = _allLoaded;
|
||||||
|
my->wasLoading = (_loadRequestId != 0);
|
||||||
|
my->loadingAll = _loadingAll;
|
||||||
|
result->controllerState = std::move(my);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListController::restoreState(std::unique_ptr<PeerListState> state) {
|
||||||
|
auto typeErasedState = state
|
||||||
|
? state->controllerState.get()
|
||||||
|
: nullptr;
|
||||||
|
if (const auto my = dynamic_cast<SavedState*>(typeErasedState)) {
|
||||||
|
if (const auto requestId = base::take(_loadRequestId)) {
|
||||||
|
_api.request(requestId).cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
_offset = my->offset;
|
||||||
|
_allLoaded = my->allLoaded;
|
||||||
|
_loadingAll = my->loadingAll;
|
||||||
|
if (my->wasLoading) {
|
||||||
|
loadMoreRows();
|
||||||
|
}
|
||||||
|
PeerListController::restoreState(std::move(state));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<PeerListRow> ListController::createRestoredRow(
|
||||||
|
not_null<PeerData*> peer) {
|
||||||
|
if (const auto user = peer->asUser()) {
|
||||||
|
return createRow(user);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void ListController::rowClicked(not_null<PeerListRow*> row) {
|
void ListController::rowClicked(not_null<PeerListRow*> row) {
|
||||||
_showPeerInfoRequests.fire(row->peer());
|
_showPeerInfoRequests.fire(row->peer());
|
||||||
}
|
}
|
||||||
|
@ -303,8 +359,6 @@ ListController *CreateAnswerRows(
|
||||||
return controller;
|
return controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
InnerWidget::InnerWidget(
|
InnerWidget::InnerWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Controller*> controller,
|
not_null<Controller*> controller,
|
||||||
|
@ -314,7 +368,8 @@ InnerWidget::InnerWidget(
|
||||||
, _controller(controller)
|
, _controller(controller)
|
||||||
, _poll(poll)
|
, _poll(poll)
|
||||||
, _contextId(contextId)
|
, _contextId(contextId)
|
||||||
, _content(setupContent(this)) {
|
, _content(this) {
|
||||||
|
setupContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerWidget::visibleTopBottomUpdated(
|
void InnerWidget::visibleTopBottomUpdated(
|
||||||
|
@ -324,11 +379,23 @@ void InnerWidget::visibleTopBottomUpdated(
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerWidget::saveState(not_null<Memento*> memento) {
|
void InnerWidget::saveState(not_null<Memento*> memento) {
|
||||||
//memento->setListState(_listController->saveState());
|
auto states = base::flat_map<
|
||||||
|
QByteArray,
|
||||||
|
std::unique_ptr<PeerListState>>();
|
||||||
|
for (const auto &[option, controller] : _sections) {
|
||||||
|
states[option] = controller->saveState();
|
||||||
|
}
|
||||||
|
memento->setListStates(std::move(states));
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerWidget::restoreState(not_null<Memento*> memento) {
|
void InnerWidget::restoreState(not_null<Memento*> memento) {
|
||||||
//_listController->restoreState(memento->listState());
|
auto states = memento->listStates();
|
||||||
|
for (const auto &[option, controller] : _sections) {
|
||||||
|
const auto i = states.find(option);
|
||||||
|
if (i != end(states)) {
|
||||||
|
controller->restoreState(std::move(i->second));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int InnerWidget::desiredHeight() const {
|
int InnerWidget::desiredHeight() const {
|
||||||
|
@ -339,14 +406,11 @@ int InnerWidget::desiredHeight() const {
|
||||||
return qMax(height(), desired);
|
return qMax(height(), desired);
|
||||||
}
|
}
|
||||||
|
|
||||||
object_ptr<Ui::VerticalLayout> InnerWidget::setupContent(
|
void InnerWidget::setupContent() {
|
||||||
RpWidget *parent) {
|
|
||||||
auto result = object_ptr<Ui::VerticalLayout>(parent);
|
|
||||||
|
|
||||||
const auto quiz = _poll->quiz();
|
const auto quiz = _poll->quiz();
|
||||||
result->add(
|
_content->add(
|
||||||
object_ptr<Ui::FlatLabel>(
|
object_ptr<Ui::FlatLabel>(
|
||||||
result,
|
_content,
|
||||||
_poll->question,
|
_poll->question,
|
||||||
st::pollResultsQuestion),
|
st::pollResultsQuestion),
|
||||||
style::margins{
|
style::margins{
|
||||||
|
@ -357,27 +421,30 @@ object_ptr<Ui::VerticalLayout> InnerWidget::setupContent(
|
||||||
for (const auto &answer : _poll->answers) {
|
for (const auto &answer : _poll->answers) {
|
||||||
const auto session = &_controller->parentController()->session();
|
const auto session = &_controller->parentController()->session();
|
||||||
const auto controller = CreateAnswerRows(
|
const auto controller = CreateAnswerRows(
|
||||||
result,
|
_content,
|
||||||
session,
|
session,
|
||||||
_poll,
|
_poll,
|
||||||
_contextId,
|
_contextId,
|
||||||
answer);
|
answer);
|
||||||
if (controller) {
|
if (!controller) {
|
||||||
controller->showPeerInfoRequests(
|
continue;
|
||||||
) | rpl::start_to_stream(
|
|
||||||
_showPeerInfoRequests,
|
|
||||||
lifetime());
|
|
||||||
}
|
}
|
||||||
|
controller->showPeerInfoRequests(
|
||||||
|
) | rpl::start_to_stream(
|
||||||
|
_showPeerInfoRequests,
|
||||||
|
lifetime());
|
||||||
|
_sections.emplace(answer.option, controller);
|
||||||
}
|
}
|
||||||
parent->widthValue(
|
|
||||||
) | rpl::start_with_next([content = result.data()](int newWidth) {
|
widthValue(
|
||||||
content->resizeToWidth(newWidth);
|
) | rpl::start_with_next([=](int newWidth) {
|
||||||
}, result->lifetime());
|
_content->resizeToWidth(newWidth);
|
||||||
result->heightValue(
|
}, _content->lifetime());
|
||||||
|
|
||||||
|
_content->heightValue(
|
||||||
) | rpl::start_with_next([=](int height) {
|
) | rpl::start_with_next([=](int height) {
|
||||||
parent->resize(parent->width(), height);
|
resize(width(), height);
|
||||||
}, result->lifetime());
|
}, _content->lifetime());
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto InnerWidget::showPeerInfoRequests() const
|
auto InnerWidget::showPeerInfoRequests() const
|
||||||
|
|
|
@ -21,6 +21,7 @@ class Controller;
|
||||||
namespace Polls {
|
namespace Polls {
|
||||||
|
|
||||||
class Memento;
|
class Memento;
|
||||||
|
class ListController;
|
||||||
|
|
||||||
class InnerWidget final : public Ui::RpWidget {
|
class InnerWidget final : public Ui::RpWidget {
|
||||||
public:
|
public:
|
||||||
|
@ -51,13 +52,14 @@ protected:
|
||||||
int visibleBottom) override;
|
int visibleBottom) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
object_ptr<Ui::VerticalLayout> setupContent(RpWidget *parent);
|
void setupContent();
|
||||||
|
|
||||||
not_null<Controller*> _controller;
|
not_null<Controller*> _controller;
|
||||||
not_null<PollData*> _poll;
|
not_null<PollData*> _poll;
|
||||||
FullMsgId _contextId;
|
FullMsgId _contextId;
|
||||||
object_ptr<Ui::VerticalLayout> _content;
|
object_ptr<Ui::VerticalLayout> _content;
|
||||||
rpl::event_stream<not_null<PeerData*>> _showPeerInfoRequests;
|
rpl::event_stream<not_null<PeerData*>> _showPeerInfoRequests;
|
||||||
|
base::flat_map<QByteArray, not_null<ListController*>> _sections;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "info/polls/info_polls_results_widget.h"
|
#include "info/polls/info_polls_results_widget.h"
|
||||||
|
|
||||||
#include "info/polls/info_polls_results_inner_widget.h"
|
#include "info/polls/info_polls_results_inner_widget.h"
|
||||||
|
#include "boxes/peer_list_box.h"
|
||||||
|
|
||||||
namespace Info {
|
namespace Info {
|
||||||
namespace Polls {
|
namespace Polls {
|
||||||
|
@ -20,6 +21,17 @@ Section Memento::section() const {
|
||||||
return Section(Section::Type::PollResults);
|
return Section(Section::Type::PollResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Memento::setListStates(base::flat_map<
|
||||||
|
QByteArray,
|
||||||
|
std::unique_ptr<PeerListState>> states) {
|
||||||
|
_listStates = std::move(states);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Memento::listStates()
|
||||||
|
-> base::flat_map<QByteArray, std::unique_ptr<PeerListState>> {
|
||||||
|
return std::move(_listStates);
|
||||||
|
}
|
||||||
|
|
||||||
object_ptr<ContentWidget> Memento::createWidget(
|
object_ptr<ContentWidget> Memento::createWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Controller*> controller,
|
not_null<Controller*> controller,
|
||||||
|
@ -82,10 +94,12 @@ std::unique_ptr<ContentMemento> Widget::doCreateMemento() {
|
||||||
|
|
||||||
void Widget::saveState(not_null<Memento*> memento) {
|
void Widget::saveState(not_null<Memento*> memento) {
|
||||||
memento->setScrollTop(scrollTopSave());
|
memento->setScrollTop(scrollTopSave());
|
||||||
|
_inner->saveState(memento);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::restoreState(not_null<Memento*> memento) {
|
void Widget::restoreState(not_null<Memento*> memento) {
|
||||||
const auto scrollTop = memento->scrollTop();
|
_inner->restoreState(memento);
|
||||||
|
auto scrollTop = memento->scrollTop();
|
||||||
scrollTopRestore(memento->scrollTop());
|
scrollTopRestore(memento->scrollTop());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "info/info_content_widget.h"
|
#include "info/info_content_widget.h"
|
||||||
#include "info/info_controller.h"
|
#include "info/info_controller.h"
|
||||||
|
|
||||||
|
struct PeerListState;
|
||||||
|
|
||||||
namespace Info {
|
namespace Info {
|
||||||
namespace Polls {
|
namespace Polls {
|
||||||
|
|
||||||
|
@ -18,6 +20,7 @@ class InnerWidget;
|
||||||
class Memento final : public ContentMemento {
|
class Memento final : public ContentMemento {
|
||||||
public:
|
public:
|
||||||
Memento(not_null<PollData*> poll, FullMsgId contextId);
|
Memento(not_null<PollData*> poll, FullMsgId contextId);
|
||||||
|
~Memento();
|
||||||
|
|
||||||
object_ptr<ContentWidget> createWidget(
|
object_ptr<ContentWidget> createWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
|
@ -26,7 +29,16 @@ public:
|
||||||
|
|
||||||
Section section() const override;
|
Section section() const override;
|
||||||
|
|
||||||
~Memento();
|
void setListStates(base::flat_map<
|
||||||
|
QByteArray,
|
||||||
|
std::unique_ptr<PeerListState>> states);
|
||||||
|
auto listStates()
|
||||||
|
-> base::flat_map<QByteArray, std::unique_ptr<PeerListState>>;
|
||||||
|
|
||||||
|
private:
|
||||||
|
base::flat_map<
|
||||||
|
QByteArray,
|
||||||
|
std::unique_ptr<PeerListState>> _listStates;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue