mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/telegramdesktop/tdesktop
synced 2026-09-20 08:03:45 +08:00
Added saving of profile tab state in section memento.
Related commits:76e26ebbb1,e01a603a80.
This commit is contained in:
@@ -507,7 +507,7 @@ void InnerWidget::saveState(not_null<Memento*> memento) {
|
||||
memento->setMembersState(_members->saveState());
|
||||
}
|
||||
if (_tabsHost) {
|
||||
memento->setActiveTab(_tabsHost->activeId());
|
||||
memento->setTabsState(_tabsHost->saveState());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -519,9 +519,7 @@ void InnerWidget::restoreState(not_null<Memento*> memento) {
|
||||
_sharedMediaWrap->finishAnimating();
|
||||
}
|
||||
if (_tabsHost) {
|
||||
if (const auto active = memento->activeTab(); !active.isEmpty()) {
|
||||
_tabsHost->restoreActiveTab(active);
|
||||
}
|
||||
_tabsHost->restoreState(memento->tabsState());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -94,6 +94,14 @@ std::unique_ptr<MembersState> Memento::membersState() {
|
||||
return std::move(_membersState);
|
||||
}
|
||||
|
||||
void Memento::setTabsState(std::unique_ptr<TabsState> state) {
|
||||
_tabsState = std::move(state);
|
||||
}
|
||||
|
||||
std::unique_ptr<TabsState> Memento::tabsState() {
|
||||
return std::move(_tabsState);
|
||||
}
|
||||
|
||||
Memento::~Memento() = default;
|
||||
|
||||
Widget::Widget(
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace Info::Profile {
|
||||
class InnerWidget;
|
||||
class TabsHost;
|
||||
struct MembersState;
|
||||
struct TabsState;
|
||||
|
||||
struct GroupReactionOrigin {
|
||||
not_null<PeerData*> group;
|
||||
@@ -55,12 +56,8 @@ public:
|
||||
void setMembersState(std::unique_ptr<MembersState> state);
|
||||
[[nodiscard]] std::unique_ptr<MembersState> membersState();
|
||||
|
||||
void setActiveTab(const QString &id) {
|
||||
_activeTab = id;
|
||||
}
|
||||
[[nodiscard]] QString activeTab() const {
|
||||
return _activeTab;
|
||||
}
|
||||
void setTabsState(std::unique_ptr<TabsState> state);
|
||||
[[nodiscard]] std::unique_ptr<TabsState> tabsState();
|
||||
|
||||
~Memento();
|
||||
|
||||
@@ -73,8 +70,8 @@ private:
|
||||
Origin origin);
|
||||
|
||||
std::unique_ptr<MembersState> _membersState;
|
||||
std::unique_ptr<TabsState> _tabsState;
|
||||
Origin _origin;
|
||||
QString _activeTab;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -20,6 +20,10 @@ namespace {
|
||||
|
||||
constexpr auto kEnableSearchMembersAfterCount = 20;
|
||||
|
||||
struct MembersTabState final : MediaTabState {
|
||||
std::unique_ptr<MembersState> list;
|
||||
};
|
||||
|
||||
class MembersTabAdapter final : public MediaTabContent {
|
||||
public:
|
||||
explicit MembersTabAdapter(MediaTabContext context)
|
||||
@@ -109,6 +113,18 @@ public:
|
||||
_members->setVisibleTopBottom(top, bottom);
|
||||
}
|
||||
|
||||
std::unique_ptr<MediaTabState> saveState() override {
|
||||
auto result = std::make_unique<MembersTabState>();
|
||||
result->list = _members->saveState();
|
||||
return result;
|
||||
}
|
||||
|
||||
void restoreState(std::unique_ptr<MediaTabState> state) override {
|
||||
if (const auto my = dynamic_cast<MembersTabState*>(state.get())) {
|
||||
_members->restoreState(std::move(my->list));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const not_null<PeerData*> _peer;
|
||||
object_ptr<Ui::RpWidget> _host;
|
||||
|
||||
@@ -40,6 +40,10 @@ struct MediaTabContext {
|
||||
Fn<void(int count)> onlineCountChanged;
|
||||
};
|
||||
|
||||
struct MediaTabState {
|
||||
virtual ~MediaTabState() = default;
|
||||
};
|
||||
|
||||
class MediaTabContent {
|
||||
public:
|
||||
virtual ~MediaTabContent() = default;
|
||||
@@ -62,9 +66,10 @@ public:
|
||||
virtual void paintOverflow(QPainter &p) {
|
||||
}
|
||||
|
||||
virtual void saveScrollState(QByteArray &out) {
|
||||
[[nodiscard]] virtual std::unique_ptr<MediaTabState> saveState() {
|
||||
return nullptr;
|
||||
}
|
||||
virtual void restoreScrollState(const QByteArray &in) {
|
||||
virtual void restoreState(std::unique_ptr<MediaTabState> state) {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -487,6 +487,35 @@ void TabsHost::ensureActiveVisible() {
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<TabsState> TabsHost::saveState() {
|
||||
auto result = std::make_unique<TabsState>();
|
||||
result->activeId = _activeId;
|
||||
result->scrollTops = _tabScrollTops;
|
||||
if (!_activeId.isEmpty() && _visibleTop >= 0) {
|
||||
result->scrollTops[_activeId] = _visibleTop;
|
||||
}
|
||||
for (auto &[id, content] : _contents) {
|
||||
if (auto state = content->saveState()) {
|
||||
result->contents.emplace(id, std::move(state));
|
||||
}
|
||||
}
|
||||
for (auto &[id, state] : base::take(_pendingStates)) {
|
||||
result->contents.emplace(id, std::move(state));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void TabsHost::restoreState(std::unique_ptr<TabsState> state) {
|
||||
if (!state) {
|
||||
return;
|
||||
}
|
||||
_tabScrollTops = std::move(state->scrollTops);
|
||||
_pendingStates = std::move(state->contents);
|
||||
if (!state->activeId.isEmpty()) {
|
||||
restoreActiveTab(state->activeId);
|
||||
}
|
||||
}
|
||||
|
||||
void TabsHost::restoreActiveTab(const QString &id) {
|
||||
const auto it = ranges::find(_tabs, id, &MediaTabDescriptor::id);
|
||||
if (it == end(_tabs)) {
|
||||
@@ -580,6 +609,12 @@ void TabsHost::activateTab(const QString &id, bool animated) {
|
||||
});
|
||||
};
|
||||
cached = it->factory(std::move(context));
|
||||
const auto pending = _pendingStates.find(id);
|
||||
if (pending != end(_pendingStates)) {
|
||||
auto state = std::move(pending->second);
|
||||
_pendingStates.erase(pending);
|
||||
cached->restoreState(std::move(state));
|
||||
}
|
||||
}
|
||||
const auto previousId = _activeId;
|
||||
const auto previousIndex = previousId.isEmpty()
|
||||
|
||||
@@ -28,6 +28,12 @@ extern const char kOptionProfileMediaTabs[];
|
||||
|
||||
class TabsStrip;
|
||||
|
||||
struct TabsState {
|
||||
QString activeId;
|
||||
base::flat_map<QString, int> scrollTops;
|
||||
base::flat_map<QString, std::unique_ptr<MediaTabState>> contents;
|
||||
};
|
||||
|
||||
class TabsHost final : public Ui::RpWidget {
|
||||
public:
|
||||
struct Descriptor {
|
||||
@@ -60,6 +66,9 @@ public:
|
||||
void activateTab(const QString &id, bool animated = true);
|
||||
void restoreActiveTab(const QString &id);
|
||||
|
||||
[[nodiscard]] std::unique_ptr<TabsState> saveState();
|
||||
void restoreState(std::unique_ptr<TabsState> state);
|
||||
|
||||
[[nodiscard]] QRect bodyGeometry() const;
|
||||
[[nodiscard]] Fn<void()> prepareSwitch(bool toNextTab);
|
||||
|
||||
@@ -121,6 +130,7 @@ private:
|
||||
QRect _slideRect;
|
||||
|
||||
base::flat_map<QString, std::unique_ptr<MediaTabContent>> _contents;
|
||||
base::flat_map<QString, std::unique_ptr<MediaTabState>> _pendingStates;
|
||||
base::flat_map<QString, int> _tabScrollTops;
|
||||
rpl::event_stream<Ui::ScrollToRequest> _scrollToRequests;
|
||||
QString _activeId;
|
||||
|
||||
Reference in New Issue
Block a user