mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 06:07:06 +02:00
Handle forum-non_forum changes in realtime.
This commit is contained in:
parent
04d06e5b12
commit
6695eda1be
35 changed files with 286 additions and 499 deletions
|
@ -1032,11 +1032,15 @@ void Application::preventOrInvoke(Fn<void()> &&callback) {
|
|||
}
|
||||
|
||||
void Application::lockByPasscode() {
|
||||
enumerateWindows([&](not_null<Window::Controller*> w) {
|
||||
_passcodeLock = true;
|
||||
w->setupPasscodeLock();
|
||||
});
|
||||
}
|
||||
|
||||
void Application::maybeLockByPasscode() {
|
||||
preventOrInvoke([=] {
|
||||
enumerateWindows([&](not_null<Window::Controller*> w) {
|
||||
_passcodeLock = true;
|
||||
w->setupPasscodeLock();
|
||||
});
|
||||
lockByPasscode();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1427,7 +1431,7 @@ void Application::startShortcuts() {
|
|||
});
|
||||
request->check(Command::Lock) && request->handle([=] {
|
||||
if (!passcodeLocked() && _domain->local().hasLocalPasscode()) {
|
||||
lockByPasscode();
|
||||
maybeLockByPasscode();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -263,6 +263,7 @@ public:
|
|||
[[nodiscard]] bool downloadPreventsQuit();
|
||||
void checkLocalTime();
|
||||
void lockByPasscode();
|
||||
void maybeLockByPasscode();
|
||||
void unlockPasscode();
|
||||
[[nodiscard]] bool passcodeLocked() const;
|
||||
rpl::producer<bool> passcodeLockChanges() const;
|
||||
|
|
|
@ -67,6 +67,18 @@ not_null<Dialogs::MainList*> Forum::topicsList() {
|
|||
return &_topicsList;
|
||||
}
|
||||
|
||||
rpl::producer<> Forum::destroyed() const {
|
||||
return channel()->flagsValue(
|
||||
) | rpl::filter([=](const ChannelData::Flags::Change &update) {
|
||||
using Flag = ChannelData::Flag;
|
||||
return (update.diff & Flag::Forum) && !(update.value & Flag::Forum);
|
||||
}) | rpl::take(1) | rpl::to_empty;
|
||||
}
|
||||
|
||||
rpl::producer<not_null<ForumTopic*>> Forum::topicDestroyed() const {
|
||||
return _topicDestroyed.events();
|
||||
}
|
||||
|
||||
void Forum::requestTopics() {
|
||||
if (_allLoaded || _requestId) {
|
||||
return;
|
||||
|
|
|
@ -34,6 +34,9 @@ public:
|
|||
[[nodiscard]] not_null<History*> history() const;
|
||||
[[nodiscard]] not_null<ChannelData*> channel() const;
|
||||
[[nodiscard]] not_null<Dialogs::MainList*> topicsList();
|
||||
[[nodiscard]] rpl::producer<> destroyed() const;
|
||||
[[nodiscard]] auto topicDestroyed() const
|
||||
-> rpl::producer<not_null<ForumTopic*>>;
|
||||
|
||||
void requestTopics();
|
||||
[[nodiscard]] rpl::producer<> chatsListChanges() const;
|
||||
|
@ -75,6 +78,7 @@ private:
|
|||
const not_null<History*> _history;
|
||||
|
||||
base::flat_map<MsgId, std::unique_ptr<ForumTopic>> _topics;
|
||||
rpl::event_stream<not_null<ForumTopic*>> _topicDestroyed;
|
||||
Dialogs::MainList _topicsList;
|
||||
|
||||
base::flat_map<MsgId, TopicRequest> _topicRequests;
|
||||
|
|
|
@ -138,8 +138,8 @@ QImage ForumTopicIconFrame(
|
|||
|
||||
ForumTopic::ForumTopic(not_null<History*> history, MsgId rootId)
|
||||
: Entry(&history->owner(), Type::ForumTopic)
|
||||
, _history(history)
|
||||
, _list(forum()->topicsList())
|
||||
, _forum(history->peer->forum())
|
||||
, _list(_forum->topicsList())
|
||||
, _replies(std::make_shared<RepliesList>(history, rootId))
|
||||
, _rootId(rootId) {
|
||||
_replies->unreadCountValue(
|
||||
|
@ -165,15 +165,22 @@ std::shared_ptr<Data::RepliesList> ForumTopic::replies() const {
|
|||
}
|
||||
|
||||
not_null<ChannelData*> ForumTopic::channel() const {
|
||||
return _history->peer->asChannel();
|
||||
return _forum->channel();
|
||||
}
|
||||
|
||||
not_null<History*> ForumTopic::history() const {
|
||||
return _history;
|
||||
return _forum->history();
|
||||
}
|
||||
|
||||
not_null<Forum*> ForumTopic::forum() const {
|
||||
return channel()->forum();
|
||||
return _forum;
|
||||
}
|
||||
|
||||
rpl::producer<> ForumTopic::destroyed() const {
|
||||
using namespace rpl::mappers;
|
||||
return rpl::merge(
|
||||
_forum->destroyed(),
|
||||
_forum->topicDestroyed() | rpl::filter(_1 == this) | rpl::to_empty);
|
||||
}
|
||||
|
||||
MsgId ForumTopic::rootId() const {
|
||||
|
@ -183,7 +190,7 @@ MsgId ForumTopic::rootId() const {
|
|||
void ForumTopic::setRealRootId(MsgId realId) {
|
||||
if (_rootId != realId) {
|
||||
_rootId = realId;
|
||||
_replies = std::make_shared<RepliesList>(_history, _rootId);
|
||||
_replies = std::make_shared<RepliesList>(history(), _rootId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -252,7 +259,7 @@ int ForumTopic::chatListNameVersion() const {
|
|||
|
||||
void ForumTopic::applyTopicTopMessage(MsgId topMessageId) {
|
||||
if (topMessageId) {
|
||||
const auto itemId = FullMsgId(_history->peer->id, topMessageId);
|
||||
const auto itemId = FullMsgId(channel()->id, topMessageId);
|
||||
if (const auto item = owner().message(itemId)) {
|
||||
setLastServerMessage(item);
|
||||
|
||||
|
@ -428,7 +435,7 @@ void ForumTopic::applyIconId(DocumentId iconId) {
|
|||
if (_iconId != iconId) {
|
||||
_iconId = iconId;
|
||||
_icon = iconId
|
||||
? _history->owner().customEmojiManager().create(
|
||||
? owner().customEmojiManager().create(
|
||||
_iconId,
|
||||
[=] { updateChatListEntry(); },
|
||||
Data::CustomEmojiManager::SizeTag::Normal)
|
||||
|
@ -524,7 +531,7 @@ Dialogs::UnreadState ForumTopic::unreadStateFor(
|
|||
bool known) const {
|
||||
auto result = Dialogs::UnreadState();
|
||||
const auto mark = !count && unreadMark();
|
||||
const auto muted = _history->mute();
|
||||
const auto muted = history()->mute();
|
||||
result.messages = count;
|
||||
result.messagesMuted = muted ? count : 0;
|
||||
result.chats = count ? 1 : 0;
|
||||
|
|
|
@ -55,6 +55,7 @@ public:
|
|||
[[nodiscard]] not_null<ChannelData*> channel() const;
|
||||
[[nodiscard]] not_null<History*> history() const;
|
||||
[[nodiscard]] not_null<Forum*> forum() const;
|
||||
[[nodiscard]] rpl::producer<> destroyed() const;
|
||||
[[nodiscard]] MsgId rootId() const;
|
||||
[[nodiscard]] bool isGeneral() const {
|
||||
return (_rootId == kGeneralId);
|
||||
|
@ -131,7 +132,7 @@ private:
|
|||
int count,
|
||||
bool known) const;
|
||||
|
||||
const not_null<History*> _history;
|
||||
const not_null<Data::Forum*> _forum;
|
||||
const not_null<Dialogs::MainList*> _list;
|
||||
std::shared_ptr<RepliesList> _replies;
|
||||
MsgId _rootId = 0;
|
||||
|
|
|
@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_changes.h"
|
||||
#include "data/data_photo.h"
|
||||
#include "data/data_folder.h"
|
||||
#include "data/data_forum.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "data/data_histories.h"
|
||||
|
@ -889,6 +890,22 @@ Data::Forum *PeerData::forum() const {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
Data::ForumTopic *PeerData::forumTopicFor(
|
||||
not_null<const HistoryItem*> item) const {
|
||||
if (const auto forum = this->forum()) {
|
||||
return forum->topicFor(item);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Data::ForumTopic *PeerData::forumTopicFor(MsgId rootId) const {
|
||||
if (const auto forum = this->forum()) {
|
||||
return forum->topicFor(rootId);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
bool PeerData::canWrite() const {
|
||||
if (const auto user = asUser()) {
|
||||
return user->canWrite();
|
||||
|
|
|
@ -33,6 +33,7 @@ class Session;
|
|||
namespace Data {
|
||||
|
||||
class Forum;
|
||||
class ForumTopic;
|
||||
class Session;
|
||||
class GroupCall;
|
||||
class CloudImageView;
|
||||
|
@ -197,6 +198,9 @@ public:
|
|||
}
|
||||
|
||||
[[nodiscard]] Data::Forum *forum() const;
|
||||
[[nodiscard]] Data::ForumTopic *forumTopicFor(
|
||||
not_null<const HistoryItem*> item) const;
|
||||
[[nodiscard]] Data::ForumTopic *forumTopicFor(MsgId rootId) const;
|
||||
|
||||
[[nodiscard]] std::optional<TimeId> notifyMuteUntil() const {
|
||||
return _notify.muteUntil();
|
||||
|
|
|
@ -328,7 +328,7 @@ Widget::Widget(
|
|||
}, lifetime());
|
||||
_lockUnlock->setClickedCallback([this] {
|
||||
_lockUnlock->setIconOverride(&st::dialogsUnlockIcon, &st::dialogsUnlockIconOver);
|
||||
Core::App().lockByPasscode();
|
||||
Core::App().maybeLockByPasscode();
|
||||
_lockUnlock->setIconOverride(nullptr);
|
||||
});
|
||||
|
||||
|
|
|
@ -487,6 +487,13 @@ void RepliesWidget::subscribeToTopic() {
|
|||
_cornerButtons.updateUnreadThingsVisibility();
|
||||
}, _topicLifetime);
|
||||
|
||||
_topic->destroyed(
|
||||
) | rpl::start_with_next([=] {
|
||||
controller()->showBackFromStack(Window::SectionShow(
|
||||
anim::type::normal,
|
||||
anim::activation::background));
|
||||
}, _topicLifetime);
|
||||
|
||||
_cornerButtons.updateUnreadThingsVisibility();
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace Info {
|
|||
namespace CommonGroups {
|
||||
|
||||
Memento::Memento(not_null<UserData*> user)
|
||||
: ContentMemento(user, 0) {
|
||||
: ContentMemento(user, nullptr, PeerId()) {
|
||||
}
|
||||
|
||||
Section Memento::section() const {
|
||||
|
|
|
@ -337,16 +337,23 @@ Key ContentMemento::key() const {
|
|||
}
|
||||
}
|
||||
|
||||
ContentMemento::ContentMemento(not_null<Data::ForumTopic*> topic)
|
||||
: _peer(topic->channel())
|
||||
, _migratedPeerId(_peer->migrateFrom() ? _peer->migrateFrom()->id : 0)
|
||||
ContentMemento::ContentMemento(
|
||||
not_null<PeerData*> peer,
|
||||
Data::ForumTopic *topic,
|
||||
PeerId migratedPeerId)
|
||||
: _peer(peer)
|
||||
, _migratedPeerId((!topic && peer->migrateFrom())
|
||||
? peer->migrateFrom()->id
|
||||
: 0)
|
||||
, _topic(topic) {
|
||||
_peer->owner().itemIdChanged(
|
||||
) | rpl::start_with_next([=](const Data::Session::IdChange &change) {
|
||||
if (_topic->rootId() == change.oldId) {
|
||||
_topic = _topic->forum()->topicFor(change.newId.msg);
|
||||
}
|
||||
}, _lifetime);
|
||||
if (_topic) {
|
||||
_peer->owner().itemIdChanged(
|
||||
) | rpl::start_with_next([=](const Data::Session::IdChange &change) {
|
||||
if (_topic->rootId() == change.oldId) {
|
||||
_topic = _topic->forum()->topicFor(change.newId.msg);
|
||||
}
|
||||
}, _lifetime);
|
||||
}
|
||||
}
|
||||
|
||||
ContentMemento::ContentMemento(Settings::Tag settings)
|
||||
|
|
|
@ -144,11 +144,10 @@ private:
|
|||
|
||||
class ContentMemento {
|
||||
public:
|
||||
ContentMemento(not_null<PeerData*> peer, PeerId migratedPeerId)
|
||||
: _peer(peer)
|
||||
, _migratedPeerId(migratedPeerId) {
|
||||
}
|
||||
explicit ContentMemento(not_null<Data::ForumTopic*> topic);
|
||||
ContentMemento(
|
||||
not_null<PeerData*> peer,
|
||||
Data::ForumTopic *topic,
|
||||
PeerId migratedPeerId);
|
||||
explicit ContentMemento(Settings::Tag settings);
|
||||
explicit ContentMemento(Downloads::Tag downloads);
|
||||
ContentMemento(not_null<PollData*> poll, FullMsgId contextId)
|
||||
|
|
|
@ -192,7 +192,10 @@ Controller::Controller(
|
|||
|
||||
void Controller::setupMigrationViewer() {
|
||||
const auto peer = _key.peer();
|
||||
if (!peer || (!peer->isChat() && !peer->isChannel()) || _migrated) {
|
||||
if (_key.topic()
|
||||
|| !peer
|
||||
|| (!peer->isChat() && !peer->isChannel())
|
||||
|| _migrated) {
|
||||
return;
|
||||
}
|
||||
peer->session().changes().peerFlagsValue(
|
||||
|
@ -335,6 +338,7 @@ auto Controller::produceSearchQuery(
|
|||
auto result = SearchQuery();
|
||||
result.type = _section.mediaType();
|
||||
result.peerId = _key.peer()->id;
|
||||
result.topicRootId = _key.topic() ? _key.topic()->rootId() : 0;
|
||||
result.query = query;
|
||||
result.migratedPeerId = _migrated ? _migrated->id : PeerId(0);
|
||||
return result;
|
||||
|
|
|
@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "boxes/peer_list_box.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_chat.h"
|
||||
#include "data/data_forum_topic.h"
|
||||
#include "data/data_session.h"
|
||||
#include "main/main_session.h"
|
||||
|
||||
|
@ -51,6 +52,27 @@ Memento::Memento(not_null<PollData*> poll, FullMsgId contextId)
|
|||
|
||||
Memento::Memento(std::vector<std::shared_ptr<ContentMemento>> stack)
|
||||
: _stack(std::move(stack)) {
|
||||
auto topics = base::flat_set<not_null<Data::ForumTopic*>>();
|
||||
for (auto &entry : _stack) {
|
||||
if (const auto topic = entry->topic()) {
|
||||
topics.emplace(topic);
|
||||
}
|
||||
}
|
||||
for (const auto &topic : topics) {
|
||||
topic->destroyed(
|
||||
) | rpl::start_with_next([=] {
|
||||
for (auto i = begin(_stack); i != end(_stack);) {
|
||||
if (i->get()->topic() == topic) {
|
||||
i = _stack.erase(i);
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
if (_stack.empty()) {
|
||||
_removeRequests.fire({});
|
||||
}
|
||||
}, _lifetime);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<ContentMemento>> Memento::DefaultStack(
|
||||
|
|
|
@ -58,6 +58,10 @@ public:
|
|||
not_null<Window::SessionController*> controller,
|
||||
const QRect &geometry) override;
|
||||
|
||||
rpl::producer<> removeRequests() const override {
|
||||
return _removeRequests.events();
|
||||
}
|
||||
|
||||
int stackSize() const {
|
||||
return int(_stack.size());
|
||||
}
|
||||
|
@ -96,6 +100,8 @@ private:
|
|||
Section section);
|
||||
|
||||
std::vector<std::shared_ptr<ContentMemento>> _stack;
|
||||
rpl::event_stream<> _removeRequests;
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -124,6 +124,10 @@ object_ptr<Ui::LayerWidget> SectionWidget::moveContentToLayer(
|
|||
bodyGeometry);
|
||||
}
|
||||
|
||||
rpl::producer<> SectionWidget::removeRequests() const {
|
||||
return _content->removeRequests();
|
||||
}
|
||||
|
||||
bool SectionWidget::floatPlayerHandleWheelEvent(QEvent *e) {
|
||||
return _content->floatPlayerHandleWheelEvent(e);
|
||||
}
|
||||
|
|
|
@ -53,6 +53,8 @@ public:
|
|||
object_ptr<Ui::LayerWidget> moveContentToLayer(
|
||||
QRect bodyGeometry) override;
|
||||
|
||||
rpl::producer<> removeRequests() const override;
|
||||
|
||||
// Float player interface.
|
||||
bool floatPlayerHandleWheelEvent(QEvent *e) override;
|
||||
QRect floatPlayerAvailableRect() override;
|
||||
|
|
|
@ -40,6 +40,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_session.h"
|
||||
#include "data/data_changes.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_forum_topic.h"
|
||||
#include "mainwidget.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "styles/style_chat.h" // popupMenuExpandedSeparator
|
||||
|
@ -104,6 +105,22 @@ WrapWidget::WrapWidget(
|
|||
});
|
||||
}, lifetime());
|
||||
restoreHistoryStack(memento->takeStack());
|
||||
|
||||
if (const auto topic = _controller->topic()) {
|
||||
topic->destroyed(
|
||||
) | rpl::start_with_next([=] {
|
||||
if (_wrap.current() == Wrap::Layer) {
|
||||
_controller->parentController()->hideSpecialLayer();
|
||||
} else if (_wrap.current() == Wrap::Narrow) {
|
||||
_controller->parentController()->showBackFromStack(
|
||||
Window::SectionShow(
|
||||
anim::type::normal,
|
||||
anim::activation::background));
|
||||
} else {
|
||||
_removeRequests.fire({});
|
||||
}
|
||||
}, lifetime());
|
||||
}
|
||||
}
|
||||
|
||||
void WrapWidget::setupShortcuts() {
|
||||
|
@ -233,129 +250,16 @@ Dialogs::RowDescriptor WrapWidget::activeChat() const {
|
|||
Unexpected("Owner in WrapWidget::activeChat().");
|
||||
}
|
||||
|
||||
// This was done for tabs support.
|
||||
//
|
||||
//void WrapWidget::createTabs() {
|
||||
// _topTabs.create(this, st::infoTabs);
|
||||
// auto sections = QStringList();
|
||||
// sections.push_back(tr::lng_profile_info_section(tr::now).toUpper());
|
||||
// sections.push_back(tr::lng_info_tab_media(tr::now).toUpper());
|
||||
// _topTabs->setSections(sections);
|
||||
// _topTabs->setActiveSection(static_cast<int>(_tab));
|
||||
// _topTabs->finishAnimating();
|
||||
//
|
||||
// _topTabs->sectionActivated(
|
||||
// ) | rpl::map([](int index) {
|
||||
// return static_cast<Tab>(index);
|
||||
// }) | rpl::start_with_next(
|
||||
// [this](Tab tab) { showTab(tab); },
|
||||
// lifetime());
|
||||
//
|
||||
// _topTabs->move(0, 0);
|
||||
// _topTabs->resizeToWidth(width());
|
||||
// _topTabs->show();
|
||||
//
|
||||
// _topTabsBackground.create(this, st::profileBg);
|
||||
// _topTabsBackground->setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
//
|
||||
// _topTabsBackground->move(0, 0);
|
||||
// _topTabsBackground->resize(
|
||||
// width(),
|
||||
// _topTabs->height() - st::lineWidth);
|
||||
// _topTabsBackground->show();
|
||||
//}
|
||||
|
||||
void WrapWidget::forceContentRepaint() {
|
||||
// WA_OpaquePaintEvent on TopBar creates render glitches when
|
||||
// animating the LayerWidget's height :( Fixing by repainting.
|
||||
|
||||
// This was done for tabs support.
|
||||
//
|
||||
//if (_topTabs) {
|
||||
// _topTabsBackground->update();
|
||||
//}
|
||||
|
||||
if (_topBar) {
|
||||
_topBar->update();
|
||||
}
|
||||
_content->update();
|
||||
}
|
||||
|
||||
// This was done for tabs support.
|
||||
//
|
||||
//void WrapWidget::showTab(Tab tab) {
|
||||
// if (_tab == tab) {
|
||||
// return;
|
||||
// }
|
||||
// Expects(_content != nullptr);
|
||||
// auto direction = (tab > _tab)
|
||||
// ? SlideDirection::FromRight
|
||||
// : SlideDirection::FromLeft;
|
||||
// auto newAnotherMemento = _content->createMemento();
|
||||
// if (!_anotherTabMemento) {
|
||||
// _anotherTabMemento = createTabMemento(tab);
|
||||
// }
|
||||
// auto newController = createController(
|
||||
// _controller->parentController(),
|
||||
// _anotherTabMemento.get());
|
||||
// auto newContent = createContent(
|
||||
// _anotherTabMemento.get(),
|
||||
// newController.get());
|
||||
// auto animationParams = SectionSlideParams();
|
||||
//// animationParams.withFade = (wrap() == Wrap::Layer);
|
||||
// animationParams.withTabs = true;
|
||||
// animationParams.withTopBarShadow = hasTopBarShadow()
|
||||
// && newContent->hasTopBarShadow();
|
||||
// animationParams.oldContentCache = grabForShowAnimation(
|
||||
// animationParams);
|
||||
//
|
||||
// _controller = std::move(newController);
|
||||
// showContent(std::move(newContent));
|
||||
//
|
||||
// showAnimated(direction, animationParams);
|
||||
//
|
||||
// _anotherTabMemento = std::move(newAnotherMemento);
|
||||
// _tab = tab;
|
||||
//}
|
||||
//
|
||||
//void WrapWidget::setupTabbedTop() {
|
||||
// auto section = _controller->section();
|
||||
// switch (section.type()) {
|
||||
// case Section::Type::Profile:
|
||||
// setupTabs(Tab::Profile);
|
||||
// break;
|
||||
// case Section::Type::Media:
|
||||
// switch (section.mediaType()) {
|
||||
// case Section::MediaType::Photo:
|
||||
// case Section::MediaType::Video:
|
||||
// case Section::MediaType::File:
|
||||
// setupTabs(Tab::Media);
|
||||
// break;
|
||||
// default:
|
||||
// setupTabs(Tab::None);
|
||||
// break;
|
||||
// }
|
||||
// break;
|
||||
// case Section::Type::CommonGroups:
|
||||
// case Section::Type::Members:
|
||||
// setupTabs(Tab::None);
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
|
||||
void WrapWidget::setupTop() {
|
||||
// This was done for tabs support.
|
||||
//
|
||||
//if (wrap() == Wrap::Side && !hasStackHistory()) {
|
||||
// setupTabbedTop();
|
||||
//} else {
|
||||
// setupTabs(Tab::None);
|
||||
//}
|
||||
//if (_topTabs) {
|
||||
// _topBar.destroy();
|
||||
//} else {
|
||||
// createTopBar();
|
||||
//}
|
||||
if (HasCustomTopBar(_controller.get())) {
|
||||
_topBar.destroy();
|
||||
return;
|
||||
|
@ -602,11 +506,6 @@ bool WrapWidget::requireTopBarSearch() const {
|
|||
} else if (hasStackHistory()) {
|
||||
return true;
|
||||
}
|
||||
// This was for top-level tabs support.
|
||||
//
|
||||
//auto section = _controller->section();
|
||||
//return (section.type() != Section::Type::Media)
|
||||
// || !Media::TypeToTabIndex(section.mediaType()).has_value();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -618,7 +517,6 @@ bool WrapWidget::showBackFromStackInternal(
|
|||
showNewContent(
|
||||
last.section.get(),
|
||||
params.withWay(Window::SectionShow::Way::Backward));
|
||||
//_anotherTabMemento = std::move(last.anotherTab);
|
||||
return true;
|
||||
}
|
||||
return (wrap() == Wrap::Layer);
|
||||
|
@ -645,11 +543,6 @@ void WrapWidget::removeFromStack(const std::vector<Section> §ions) {
|
|||
}
|
||||
|
||||
not_null<Ui::RpWidget*> WrapWidget::topWidget() const {
|
||||
// This was done for tabs support.
|
||||
//
|
||||
//if (_topTabs) {
|
||||
// return _topTabsBackground;
|
||||
//}
|
||||
return _topBar;
|
||||
}
|
||||
|
||||
|
@ -670,7 +563,6 @@ void WrapWidget::showContent(object_ptr<ContentWidget> content) {
|
|||
}
|
||||
_additionalScroll = 0;
|
||||
_content->show();
|
||||
//_anotherTabMemento = nullptr;
|
||||
finishShowContent();
|
||||
}
|
||||
|
||||
|
@ -696,23 +588,9 @@ void WrapWidget::finishShowContent() {
|
|||
) | rpl::start_with_next([=] {
|
||||
updateContentGeometry();
|
||||
}, _content->lifetime());
|
||||
|
||||
// This was done for tabs support.
|
||||
//
|
||||
//if (_topTabs) {
|
||||
// _topTabs->raise();
|
||||
//}
|
||||
}
|
||||
|
||||
rpl::producer<bool> WrapWidget::topShadowToggledValue() const {
|
||||
// Allows always showing shadow for specific wrap value.
|
||||
// Was done for top level tabs support.
|
||||
//
|
||||
//using namespace rpl::mappers;
|
||||
//return rpl::combine(
|
||||
// _controller->wrapValue(),
|
||||
// _desiredShadowVisibilities.events() | rpl::flatten_latest(),
|
||||
// (_1 == Wrap::Side) || _2);
|
||||
return _desiredShadowVisibilities.events()
|
||||
| rpl::flatten_latest(
|
||||
) | rpl::map([=](bool v) { return v && (_topBar != nullptr); });
|
||||
|
@ -730,22 +608,6 @@ rpl::producer<SelectedItems> WrapWidget::selectedListValue() const {
|
|||
return _selectedLists.events() | rpl::flatten_latest();
|
||||
}
|
||||
|
||||
// Was done for top level tabs support.
|
||||
//
|
||||
//std::shared_ptr<ContentMemento> WrapWidget::createTabMemento(
|
||||
// Tab tab) {
|
||||
// switch (tab) {
|
||||
// case Tab::Profile: return std::make_shared<Profile::Memento>(
|
||||
// _controller->peerId(),
|
||||
// _controller->migratedPeerId());
|
||||
// case Tab::Media: return std::make_shared<Media::Memento>(
|
||||
// _controller->peerId(),
|
||||
// _controller->migratedPeerId(),
|
||||
// Media::Type::Photo);
|
||||
// }
|
||||
// Unexpected("Tab value in Info::WrapWidget::createInner()");
|
||||
//}
|
||||
|
||||
object_ptr<ContentWidget> WrapWidget::createContent(
|
||||
not_null<ContentMemento*> memento,
|
||||
not_null<Controller*> controller) {
|
||||
|
@ -755,43 +617,11 @@ object_ptr<ContentWidget> WrapWidget::createContent(
|
|||
contentGeometry());
|
||||
}
|
||||
|
||||
// Was done for top level tabs support.
|
||||
//
|
||||
//void WrapWidget::convertProfileFromStackToTab() {
|
||||
// if (!hasStackHistory()) {
|
||||
// return;
|
||||
// }
|
||||
// auto &entry = _historyStack[0];
|
||||
// if (entry.section->section().type() != Section::Type::Profile) {
|
||||
// return;
|
||||
// }
|
||||
// auto convertInsideStack = (_historyStack.size() > 1);
|
||||
// auto checkSection = convertInsideStack
|
||||
// ? _historyStack[1].section->section()
|
||||
// : _controller->section();
|
||||
// auto &anotherMemento = convertInsideStack
|
||||
// ? _historyStack[1].anotherTab
|
||||
// : _anotherTabMemento;
|
||||
// if (checkSection.type() != Section::Type::Media) {
|
||||
// return;
|
||||
// }
|
||||
// if (!Info::Media::TypeToTabIndex(checkSection.mediaType())) {
|
||||
// return;
|
||||
// }
|
||||
// anotherMemento = std::move(entry.section);
|
||||
// _historyStack.erase(_historyStack.begin());
|
||||
//}
|
||||
|
||||
rpl::producer<Wrap> WrapWidget::wrapValue() const {
|
||||
return _wrap.value();
|
||||
}
|
||||
|
||||
void WrapWidget::setWrap(Wrap wrap) {
|
||||
// Was done for top level tabs support.
|
||||
//
|
||||
//if (_wrap.current() != Wrap::Side && wrap == Wrap::Side) {
|
||||
// convertProfileFromStackToTab();
|
||||
//}
|
||||
_wrap = wrap;
|
||||
}
|
||||
|
||||
|
@ -810,9 +640,6 @@ QPixmap WrapWidget::grabForShowAnimation(
|
|||
} else {
|
||||
_topShadow->setVisible(_topShadow->toggled());
|
||||
}
|
||||
//if (params.withTabs && _topTabs) {
|
||||
// _topTabs->hide();
|
||||
//}
|
||||
const auto expanding = _expanding;
|
||||
if (expanding) {
|
||||
_grabbingForExpanding = true;
|
||||
|
@ -824,18 +651,11 @@ QPixmap WrapWidget::grabForShowAnimation(
|
|||
if (params.withTopBarShadow) {
|
||||
_topShadow->setVisible(true);
|
||||
}
|
||||
//if (params.withTabs && _topTabs) {
|
||||
// _topTabs->show();
|
||||
//}
|
||||
return result;
|
||||
}
|
||||
|
||||
void WrapWidget::showAnimatedHook(
|
||||
const Window::SectionSlideParams ¶ms) {
|
||||
//if (params.withTabs && _topTabs) {
|
||||
// _topTabs->show();
|
||||
// _topTabsBackground->show();
|
||||
//}
|
||||
if (params.withTopBarShadow) {
|
||||
_topShadow->setVisible(true);
|
||||
}
|
||||
|
@ -870,25 +690,6 @@ bool WrapWidget::showInternal(
|
|||
if (!skipInternal && _content->showInternal(content)) {
|
||||
highlightTopBar();
|
||||
return true;
|
||||
|
||||
// This was done for tabs support.
|
||||
//
|
||||
//} else if (_topTabs) {
|
||||
// // If we open the profile being in the media tab.
|
||||
// // Just switch back to the profile tab.
|
||||
// auto type = content->section().type();
|
||||
// if (type == Section::Type::Profile
|
||||
// && _tab != Tab::Profile) {
|
||||
// _anotherTabMemento = std::move(infoMemento->takeStack().back());
|
||||
// _topTabs->setActiveSection(static_cast<int>(Tab::Profile));
|
||||
// return true;
|
||||
// } else if (type == Section::Type::Media
|
||||
// && _tab != Tab::Media
|
||||
// && Media::TypeToTabIndex(content->section().mediaType()).has_value()) {
|
||||
// _anotherTabMemento = std::move(infoMemento->takeStack().back());
|
||||
// _topTabs->setActiveSection(static_cast<int>(Tab::Media));
|
||||
// return true;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -899,9 +700,7 @@ bool WrapWidget::showInternal(
|
|||
return true;
|
||||
}
|
||||
|
||||
showNewContent(
|
||||
content,
|
||||
params);
|
||||
showNewContent(content, params);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -997,9 +796,6 @@ void WrapWidget::showNewContent(
|
|||
if (saveToStack) {
|
||||
auto item = StackItem();
|
||||
item.section = _content->createMemento();
|
||||
//if (_anotherTabMemento) {
|
||||
// item.anotherTab = std::move(_anotherTabMemento);
|
||||
//}
|
||||
_historyStack.push_back(std::move(item));
|
||||
} else if (params.way == Window::SectionShow::Way::ClearStack) {
|
||||
_historyStack.clear();
|
||||
|
@ -1041,29 +837,7 @@ void WrapWidget::showNewContent(not_null<ContentMemento*> memento) {
|
|||
showContent(createContent(memento, _controller.get()));
|
||||
}
|
||||
|
||||
// This was done for tabs support.
|
||||
//
|
||||
//void WrapWidget::setupTabs(Tab tab) {
|
||||
// _tab = tab;
|
||||
// if (_tab == Tab::None) {
|
||||
// _topTabs.destroy();
|
||||
// _topTabsBackground.destroy();
|
||||
// } else if (!_topTabs) {
|
||||
// createTabs();
|
||||
// } else {
|
||||
// _topTabs->setActiveSection(static_cast<int>(tab));
|
||||
// }
|
||||
//}
|
||||
|
||||
void WrapWidget::resizeEvent(QResizeEvent *e) {
|
||||
// This was done for tabs support.
|
||||
//
|
||||
//if (_topTabs) {
|
||||
// _topTabs->resizeToWidth(width());
|
||||
// _topTabsBackground->resize(
|
||||
// width(),
|
||||
// _topTabs->height() - st::lineWidth);
|
||||
//}
|
||||
if (_topBar) {
|
||||
_topBar->resizeToWidth(width());
|
||||
}
|
||||
|
|
|
@ -132,6 +132,10 @@ public:
|
|||
[[nodiscard]] rpl::producer<bool> grabbingForExpanding() const;
|
||||
[[nodiscard]] const Ui::RoundRect *bottomSkipRounding() const;
|
||||
|
||||
[[nodiscard]] rpl::producer<> removeRequests() const {
|
||||
return _removeRequests.events();
|
||||
}
|
||||
|
||||
~WrapWidget();
|
||||
|
||||
protected:
|
||||
|
@ -147,11 +151,6 @@ protected:
|
|||
private:
|
||||
using SlideDirection = Window::SlideDirection;
|
||||
using SectionSlideParams = Window::SectionSlideParams;
|
||||
//enum class Tab {
|
||||
// Profile,
|
||||
// Media,
|
||||
// None,
|
||||
//};
|
||||
struct StackItem;
|
||||
|
||||
void startInjectingActivePeerProfiles();
|
||||
|
@ -173,9 +172,6 @@ private:
|
|||
not_null<ContentMemento*> memento,
|
||||
const Window::SectionShow ¶ms);
|
||||
void setupTop();
|
||||
//void setupTabbedTop();
|
||||
//void setupTabs(Tab tab);
|
||||
//void createTabs();
|
||||
void createTopBar();
|
||||
void highlightTopBar();
|
||||
void setupShortcuts();
|
||||
|
@ -190,16 +186,13 @@ private:
|
|||
rpl::producer<bool> topShadowToggledValue() const;
|
||||
void updateContentGeometry();
|
||||
|
||||
//void showTab(Tab tab);
|
||||
void showContent(object_ptr<ContentWidget> content);
|
||||
//std::shared_ptr<ContentMemento> createTabMemento(Tab tab);
|
||||
object_ptr<ContentWidget> createContent(
|
||||
not_null<ContentMemento*> memento,
|
||||
not_null<Controller*> controller);
|
||||
std::unique_ptr<Controller> createController(
|
||||
not_null<Window::SessionController*> window,
|
||||
not_null<ContentMemento*> memento);
|
||||
//void convertProfileFromStackToTab();
|
||||
|
||||
rpl::producer<SelectedItems> selectedListValue() const;
|
||||
bool requireTopBarSearch() const;
|
||||
|
@ -215,8 +208,6 @@ private:
|
|||
int _additionalScroll = 0;
|
||||
bool _expanding = false;
|
||||
rpl::variable<bool> _grabbingForExpanding = false;
|
||||
//object_ptr<Ui::PlainShadow> _topTabsBackground = { nullptr };
|
||||
//object_ptr<Ui::SettingsSlider> _topTabs = { nullptr };
|
||||
object_ptr<TopBar> _topBar = { nullptr };
|
||||
object_ptr<Ui::RpWidget> _topBarSurrogate = { nullptr };
|
||||
Ui::Animations::Simple _topBarOverrideAnimation;
|
||||
|
@ -227,9 +218,8 @@ private:
|
|||
base::unique_qptr<Ui::IconButton> _topBarMenuToggle;
|
||||
base::unique_qptr<Ui::PopupMenu> _topBarMenu;
|
||||
|
||||
// Tab _tab = Tab::Profile;
|
||||
// std::shared_ptr<ContentMemento> _anotherTabMemento;
|
||||
std::vector<StackItem> _historyStack;
|
||||
rpl::event_stream<> _removeRequests;
|
||||
|
||||
rpl::event_stream<rpl::producer<int>> _desiredHeights;
|
||||
rpl::event_stream<rpl::producer<bool>> _desiredShadowVisibilities;
|
||||
|
|
|
@ -93,8 +93,15 @@ inline auto AddButton(
|
|||
MediaText(type),
|
||||
tracker)->entity();
|
||||
result->addClickHandler([=] {
|
||||
navigation->showSection(
|
||||
std::make_shared<Info::Memento>(peer, Section(type)));
|
||||
const auto topic = topicRootId
|
||||
? peer->forumTopicFor(topicRootId)
|
||||
: nullptr;
|
||||
if (topicRootId && !topic) {
|
||||
return;
|
||||
}
|
||||
navigation->showSection(topicRootId
|
||||
? std::make_shared<Info::Memento>(topic, Section(type))
|
||||
: std::make_shared<Info::Memento>(peer, Section(type)));
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
|
|
@ -41,8 +41,7 @@ InnerWidget::InnerWidget(
|
|||
}
|
||||
|
||||
// Allows showing additional shared media links and tabs.
|
||||
// Was done for top level tabs support.
|
||||
// Now used for shared media in Saved Messages.
|
||||
// Used for shared media in Saved Messages.
|
||||
void InnerWidget::setupOtherTypes() {
|
||||
if (_controller->key().peer()->isSelf() && _isStackBottom) {
|
||||
createOtherTypes();
|
||||
|
@ -50,26 +49,14 @@ void InnerWidget::setupOtherTypes() {
|
|||
_otherTypes.destroy();
|
||||
refreshHeight();
|
||||
}
|
||||
//rpl::combine(
|
||||
// _controller->wrapValue(),
|
||||
// _controller->searchEnabledByContent()
|
||||
//) | rpl::start_with_next([this](Wrap wrap, bool enabled) {
|
||||
// _searchEnabled = enabled;
|
||||
// refreshSearchField();
|
||||
//}, lifetime());
|
||||
}
|
||||
|
||||
void InnerWidget::createOtherTypes() {
|
||||
//_otherTabsShadow.create(this);
|
||||
//_otherTabsShadow->show();
|
||||
|
||||
//_otherTabs = nullptr;
|
||||
_otherTypes.create(this);
|
||||
_otherTypes->show();
|
||||
|
||||
createTypeButtons();
|
||||
_otherTypes->add(object_ptr<Ui::BoxContentDivider>(_otherTypes));
|
||||
//createTabs();
|
||||
|
||||
_otherTypes->resizeToWidth(width());
|
||||
_otherTypes->heightValue(
|
||||
|
@ -111,19 +98,6 @@ void InnerWidget::createTypeButtons() {
|
|||
icon,
|
||||
st::infoSharedMediaButtonIconPosition)->show();
|
||||
};
|
||||
//auto addCommonGroupsButton = [&](
|
||||
// not_null<UserData*> user,
|
||||
// const style::icon &icon) {
|
||||
// auto result = AddCommonGroupsButton(
|
||||
// content,
|
||||
// _controller,
|
||||
// user,
|
||||
// tracker);
|
||||
// object_ptr<Profile::FloatingIcon>(
|
||||
// result,
|
||||
// icon,
|
||||
// st::infoSharedMediaButtonIconPosition)->show();
|
||||
//};
|
||||
|
||||
addMediaButton(Type::Photo, st::infoIconMediaPhoto);
|
||||
addMediaButton(Type::Video, st::infoIconMediaVideo);
|
||||
|
@ -132,9 +106,6 @@ void InnerWidget::createTypeButtons() {
|
|||
addMediaButton(Type::Link, st::infoIconMediaLink);
|
||||
addMediaButton(Type::RoundVoiceFile, st::infoIconMediaVoice);
|
||||
addMediaButton(Type::GIF, st::infoIconMediaGif);
|
||||
// if (auto user = _controller->key().peer()->asUser()) {
|
||||
// addCommonGroupsButton(user, st::infoIconMediaGroup);
|
||||
// }
|
||||
|
||||
content->add(object_ptr<Ui::FixedHeightWidget>(
|
||||
content,
|
||||
|
@ -143,33 +114,6 @@ void InnerWidget::createTypeButtons() {
|
|||
wrap->finishAnimating();
|
||||
}
|
||||
|
||||
//void InnerWidget::createTabs() {
|
||||
// _otherTabs = _otherTypes->add(object_ptr<Ui::SettingsSlider>(
|
||||
// this,
|
||||
// st::infoTabs));
|
||||
// auto sections = QStringList();
|
||||
// sections.push_back(tr::lng_media_type_photos(tr::now).toUpper());
|
||||
// sections.push_back(tr::lng_media_type_videos(tr::now).toUpper());
|
||||
// sections.push_back(tr::lng_media_type_files(tr::now).toUpper());
|
||||
// _otherTabs->setSections(sections);
|
||||
// _otherTabs->setActiveSection(*TypeToTabIndex(type()));
|
||||
// _otherTabs->finishAnimating();
|
||||
//
|
||||
// _otherTabs->sectionActivated(
|
||||
// ) | rpl::map([](int index) {
|
||||
// return TabIndexToType(index);
|
||||
// }) | rpl::start_with_next(
|
||||
// [this](Type newType) {
|
||||
// if (type() != newType) {
|
||||
// switchToTab(Memento(
|
||||
// _controller->peerId(),
|
||||
// _controller->migratedPeerId(),
|
||||
// newType));
|
||||
// }
|
||||
// },
|
||||
// _otherTabs->lifetime());
|
||||
//}
|
||||
|
||||
Type InnerWidget::type() const {
|
||||
return _controller->section().mediaType();
|
||||
}
|
||||
|
@ -188,63 +132,10 @@ bool InnerWidget::showInternal(not_null<Memento*> memento) {
|
|||
if (mementoType == type()) {
|
||||
restoreState(memento);
|
||||
return true;
|
||||
|
||||
// Allows showing additional shared media links and tabs.
|
||||
// Was done for top level tabs support.
|
||||
//
|
||||
//} else if (_otherTypes) {
|
||||
// if (TypeToTabIndex(mementoType)) {
|
||||
// switchToTab(std::move(*memento));
|
||||
// return true;
|
||||
// }
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Allows showing additional shared media links and tabs.
|
||||
// Was done for top level tabs support.
|
||||
//
|
||||
//void InnerWidget::switchToTab(Memento &&memento) {
|
||||
// // Save state of the tab before setSection() call.
|
||||
// _controller->setSection(&memento);
|
||||
// _list = setupList();
|
||||
// restoreState(&memento);
|
||||
// _list->show();
|
||||
// _list->resizeToWidth(width());
|
||||
// refreshHeight();
|
||||
// if (_otherTypes) {
|
||||
// _otherTabsShadow->raise();
|
||||
// _otherTypes->raise();
|
||||
// _otherTabs->setActiveSection(*TypeToTabIndex(type()));
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void InnerWidget::refreshSearchField() {
|
||||
// auto search = _controller->searchFieldController();
|
||||
// if (search && _otherTabs && _searchEnabled) {
|
||||
// _searchField = search->createRowView(
|
||||
// this,
|
||||
// st::infoMediaSearch);
|
||||
// _searchField->resizeToWidth(width());
|
||||
// _searchField->show();
|
||||
// search->queryChanges(
|
||||
// ) | rpl::start_with_next([this] {
|
||||
// scrollToSearchField();
|
||||
// }, _searchField->lifetime());
|
||||
// } else {
|
||||
// _searchField = nullptr;
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void InnerWidget::scrollToSearchField() {
|
||||
// Expects(_searchField != nullptr);
|
||||
//
|
||||
// auto top = _searchField->y();
|
||||
// auto bottom = top + _searchField->height();
|
||||
// _scrollToRequests.fire({ top, bottom });
|
||||
//}
|
||||
|
||||
object_ptr<ListWidget> InnerWidget::setupList() {
|
||||
auto result = object_ptr<ListWidget>(
|
||||
this,
|
||||
|
@ -299,11 +190,7 @@ int InnerWidget::resizeGetHeight(int newWidth) {
|
|||
|
||||
if (_otherTypes) {
|
||||
_otherTypes->resizeToWidth(newWidth);
|
||||
//_otherTabsShadow->resizeToWidth(newWidth);
|
||||
}
|
||||
//if (_searchField) {
|
||||
// _searchField->resizeToWidth(newWidth);
|
||||
//}
|
||||
_list->resizeToWidth(newWidth);
|
||||
_empty->resizeToWidth(newWidth);
|
||||
return recountHeight();
|
||||
|
@ -321,12 +208,7 @@ int InnerWidget::recountHeight() {
|
|||
if (_otherTypes) {
|
||||
_otherTypes->moveToLeft(0, top);
|
||||
top += _otherTypes->heightNoMargins() - st::lineWidth;
|
||||
// _otherTabsShadow->moveToLeft(0, top);
|
||||
}
|
||||
//if (_searchField) {
|
||||
// _searchField->moveToLeft(0, top);
|
||||
// top += _searchField->heightNoMargins() - st::lineWidth;
|
||||
//}
|
||||
auto listHeight = 0;
|
||||
if (_list) {
|
||||
_list->moveToLeft(0, top);
|
||||
|
|
|
@ -62,18 +62,10 @@ private:
|
|||
int recountHeight();
|
||||
void refreshHeight();
|
||||
// Allows showing additional shared media links and tabs.
|
||||
// Was done for top level tabs support.
|
||||
// Now used for shared media in Saved Messages.
|
||||
// Used for shared media in Saved Messages.
|
||||
void setupOtherTypes();
|
||||
void createOtherTypes();
|
||||
void createTypeButtons();
|
||||
// Allows showing additional shared media links and tabs.
|
||||
// Was done for top level tabs support.
|
||||
//
|
||||
//void createTabs();
|
||||
//void switchToTab(Memento &&memento);
|
||||
//void refreshSearchField();
|
||||
//void scrollToSearchField();
|
||||
|
||||
Type type() const;
|
||||
|
||||
|
@ -81,13 +73,9 @@ private:
|
|||
|
||||
const not_null<Controller*> _controller;
|
||||
|
||||
//Ui::SettingsSlider *_otherTabs = nullptr;
|
||||
object_ptr<Ui::VerticalLayout> _otherTypes = { nullptr };
|
||||
//object_ptr<Ui::PlainShadow> _otherTabsShadow = { nullptr };
|
||||
//base::unique_qptr<Ui::RpWidget> _searchField = nullptr;
|
||||
object_ptr<ListWidget> _list = { nullptr };
|
||||
object_ptr<EmptyWidget> _empty;
|
||||
//bool _searchEnabled = false;
|
||||
|
||||
bool _inResize = false;
|
||||
bool _isStackBottom = false;
|
||||
|
|
|
@ -15,6 +15,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/ui_utility.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_forum_topic.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "styles/style_info.h"
|
||||
|
||||
|
@ -43,6 +45,7 @@ Memento::Memento(not_null<Controller*> controller)
|
|||
(controller->peer()
|
||||
? controller->peer()
|
||||
: controller->parentController()->session().user()),
|
||||
controller->topic(),
|
||||
controller->migratedPeerId(),
|
||||
(controller->section().type() == Section::Type::Downloads
|
||||
? Type::File
|
||||
|
@ -50,23 +53,25 @@ Memento::Memento(not_null<Controller*> controller)
|
|||
}
|
||||
|
||||
Memento::Memento(not_null<PeerData*> peer, PeerId migratedPeerId, Type type)
|
||||
: ContentMemento(peer, migratedPeerId)
|
||||
, _type(type) {
|
||||
_searchState.query.type = type;
|
||||
_searchState.query.peerId = peer->id;
|
||||
_searchState.query.migratedPeerId = migratedPeerId;
|
||||
if (migratedPeerId) {
|
||||
_searchState.migratedList = Storage::SparseIdsList();
|
||||
}
|
||||
: Memento(peer, nullptr, migratedPeerId, type) {
|
||||
}
|
||||
|
||||
Memento::Memento(not_null<Data::ForumTopic*> topic, Type type)
|
||||
: ContentMemento(topic)
|
||||
: Memento(topic->channel(), topic, PeerId(), type) {
|
||||
}
|
||||
|
||||
Memento::Memento(
|
||||
not_null<PeerData*> peer,
|
||||
Data::ForumTopic *topic,
|
||||
PeerId migratedPeerId,
|
||||
Type type)
|
||||
: ContentMemento(peer, topic, migratedPeerId)
|
||||
, _type(type) {
|
||||
_searchState.query.type = type; // #TODO forum search
|
||||
_searchState.query.peerId = peer()->id;
|
||||
_searchState.query.migratedPeerId = migratedPeerId();
|
||||
if (migratedPeerId()) {
|
||||
_searchState.query.type = type;
|
||||
_searchState.query.peerId = peer->id;
|
||||
_searchState.query.topicRootId = topic ? topic->rootId() : 0;
|
||||
_searchState.query.migratedPeerId = migratedPeerId;
|
||||
if (migratedPeerId) {
|
||||
_searchState.migratedList = Storage::SparseIdsList();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,6 +83,12 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
Memento(
|
||||
not_null<PeerData*> peer,
|
||||
Data::ForumTopic *topic,
|
||||
PeerId migratedPeerId,
|
||||
Type type);
|
||||
|
||||
Type _type = Type::Photo;
|
||||
FullMsgId _aroundId;
|
||||
int _idsLimit = 0;
|
||||
|
|
|
@ -26,7 +26,7 @@ Memento::Memento(not_null<Controller*> controller)
|
|||
}
|
||||
|
||||
Memento::Memento(not_null<PeerData*> peer, PeerId migratedPeerId)
|
||||
: ContentMemento(peer, migratedPeerId) {
|
||||
: ContentMemento(peer, nullptr, migratedPeerId) {
|
||||
}
|
||||
|
||||
Section Memento::section() const {
|
||||
|
|
|
@ -73,8 +73,9 @@ object_ptr<Ui::RpWidget> InnerWidget::setupContent(
|
|||
_topic ? TitleValue(_topic) : NameValue(_peer)));
|
||||
_cover->showSection(
|
||||
) | rpl::start_with_next([=](Section section) {
|
||||
_controller->showSection(
|
||||
std::make_shared<Info::Memento>(_peer, section));
|
||||
_controller->showSection(_topic
|
||||
? std::make_shared<Info::Memento>(_topic, section)
|
||||
: std::make_shared<Info::Memento>(_peer, section));
|
||||
}, _cover->lifetime());
|
||||
_cover->setOnlineCount(rpl::single(0));
|
||||
if (_topic) {
|
||||
|
@ -166,34 +167,6 @@ object_ptr<Ui::RpWidget> InnerWidget::setupSharedMedia(
|
|||
object_ptr<Ui::VerticalLayout>(parent)
|
||||
);
|
||||
|
||||
// Allows removing shared media links in third column.
|
||||
// Was done for tabs support.
|
||||
//
|
||||
//using ToggledData = std::tuple<bool, Wrap, bool>;
|
||||
//rpl::combine(
|
||||
// tracker.atLeastOneShownValue(),
|
||||
// _controller->wrapValue(),
|
||||
// _isStackBottom.value()
|
||||
//) | rpl::combine_previous(
|
||||
// ToggledData()
|
||||
//) | rpl::start_with_next([wrap = result.data()](
|
||||
// const ToggledData &was,
|
||||
// const ToggledData &now) {
|
||||
// bool wasOneShown, wasStackBottom, nowOneShown, nowStackBottom;
|
||||
// Wrap wasWrap, nowWrap;
|
||||
// std::tie(wasOneShown, wasWrap, wasStackBottom) = was;
|
||||
// std::tie(nowOneShown, nowWrap, nowStackBottom) = now;
|
||||
// // MSVC Internal Compiler Error
|
||||
// //auto [wasOneShown, wasWrap, wasStackBottom] = was;
|
||||
// //auto [nowOneShown, nowWrap, nowStackBottom] = now;
|
||||
// wrap->toggle(
|
||||
// nowOneShown && (nowWrap != Wrap::Side || !nowStackBottom),
|
||||
// (wasStackBottom == nowStackBottom && wasWrap == nowWrap)
|
||||
// ? anim::type::normal
|
||||
// : anim::type::instant);
|
||||
//}, result->lifetime());
|
||||
//
|
||||
// Using that instead
|
||||
result->setDuration(
|
||||
st::infoSlideDuration
|
||||
)->toggleOn(
|
||||
|
|
|
@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/ui_utility.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_forum_topic.h"
|
||||
#include "data/data_user.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "info/info_controller.h"
|
||||
|
@ -22,15 +23,23 @@ namespace Info::Profile {
|
|||
Memento::Memento(not_null<Controller*> controller)
|
||||
: Memento(
|
||||
controller->peer(),
|
||||
controller->topic(),
|
||||
controller->migratedPeerId()) {
|
||||
}
|
||||
|
||||
Memento::Memento(not_null<PeerData*> peer, PeerId migratedPeerId)
|
||||
: ContentMemento(peer, migratedPeerId) {
|
||||
: Memento(peer, nullptr, migratedPeerId) {
|
||||
}
|
||||
|
||||
Memento::Memento(
|
||||
not_null<PeerData*> peer,
|
||||
Data::ForumTopic *topic,
|
||||
PeerId migratedPeerId)
|
||||
: ContentMemento(peer, topic, migratedPeerId) {
|
||||
}
|
||||
|
||||
Memento::Memento(not_null<Data::ForumTopic*> topic)
|
||||
: ContentMemento(topic) {
|
||||
: ContentMemento(topic->channel(), topic, 0) {
|
||||
}
|
||||
|
||||
Section Memento::section() const {
|
||||
|
|
|
@ -37,6 +37,11 @@ public:
|
|||
~Memento();
|
||||
|
||||
private:
|
||||
Memento(
|
||||
not_null<PeerData*> peer,
|
||||
Data::ForumTopic *topic,
|
||||
PeerId migratedPeerId);
|
||||
|
||||
std::unique_ptr<MembersState> _membersState;
|
||||
|
||||
};
|
||||
|
|
|
@ -123,27 +123,33 @@ enum StackItemType {
|
|||
|
||||
class StackItem {
|
||||
public:
|
||||
StackItem(PeerData *peer) : _peer(peer) {
|
||||
explicit StackItem(PeerData *peer) : _peer(peer) {
|
||||
}
|
||||
|
||||
PeerData *peer() const {
|
||||
[[nodiscard]] PeerData *peer() const {
|
||||
return _peer;
|
||||
}
|
||||
|
||||
void setThirdSectionMemento(
|
||||
std::shared_ptr<Window::SectionMemento> memento);
|
||||
std::shared_ptr<Window::SectionMemento> takeThirdSectionMemento() {
|
||||
[[nodiscard]] auto takeThirdSectionMemento()
|
||||
-> std::shared_ptr<Window::SectionMemento> {
|
||||
return std::move(_thirdSectionMemento);
|
||||
}
|
||||
|
||||
void setThirdSectionWeak(QPointer<Window::SectionWidget> section) {
|
||||
_thirdSectionWeak = section;
|
||||
}
|
||||
QPointer<Window::SectionWidget> thirdSectionWeak() const {
|
||||
[[nodiscard]] QPointer<Window::SectionWidget> thirdSectionWeak() const {
|
||||
return _thirdSectionWeak;
|
||||
}
|
||||
|
||||
virtual StackItemType type() const = 0;
|
||||
[[nodiscard]] rpl::lifetime &lifetime() {
|
||||
return _lifetime;
|
||||
}
|
||||
|
||||
[[nodiscard]] virtual StackItemType type() const = 0;
|
||||
[[nodiscard]] virtual rpl::producer<> removeRequests() const = 0;
|
||||
virtual ~StackItem() = default;
|
||||
|
||||
private:
|
||||
|
@ -151,9 +157,11 @@ private:
|
|||
QPointer<Window::SectionWidget> _thirdSectionWeak;
|
||||
std::shared_ptr<Window::SectionMemento> _thirdSectionMemento;
|
||||
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
};
|
||||
|
||||
class StackItemHistory : public StackItem {
|
||||
class StackItemHistory final : public StackItem {
|
||||
public:
|
||||
StackItemHistory(
|
||||
not_null<History*> history,
|
||||
|
@ -168,6 +176,9 @@ public:
|
|||
StackItemType type() const override {
|
||||
return HistoryStackItem;
|
||||
}
|
||||
rpl::producer<> removeRequests() const override {
|
||||
return rpl::never<>();
|
||||
}
|
||||
|
||||
not_null<History*> history;
|
||||
MsgId msgId;
|
||||
|
@ -183,6 +194,9 @@ public:
|
|||
StackItemType type() const override {
|
||||
return SectionStackItem;
|
||||
}
|
||||
rpl::producer<> removeRequests() const override {
|
||||
return _memento->removeRequests();
|
||||
}
|
||||
std::shared_ptr<Window::SectionMemento> takeMemento() {
|
||||
return std::move(_memento);
|
||||
}
|
||||
|
@ -1499,15 +1513,28 @@ void MainWidget::saveSectionInStack() {
|
|||
if (auto memento = _mainSection->createMemento()) {
|
||||
_stack.push_back(std::make_unique<StackItemSection>(
|
||||
std::move(memento)));
|
||||
_stack.back()->setThirdSectionWeak(_thirdSection.data());
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else if (const auto history = _history->history()) {
|
||||
_stack.push_back(std::make_unique<StackItemHistory>(
|
||||
history,
|
||||
_history->msgId(),
|
||||
_history->replyReturns()));
|
||||
_stack.back()->setThirdSectionWeak(_thirdSection.data());
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
const auto raw = _stack.back().get();
|
||||
raw->setThirdSectionWeak(_thirdSection.data());
|
||||
raw->removeRequests(
|
||||
) | rpl::start_with_next([=] {
|
||||
for (auto i = begin(_stack); i != end(_stack); ++i) {
|
||||
if (i->get() == raw) {
|
||||
_stack.erase(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}, raw->lifetime());
|
||||
}
|
||||
|
||||
void MainWidget::showSection(
|
||||
|
@ -1715,6 +1742,12 @@ void MainWidget::showNewSection(
|
|||
: _mainSection;
|
||||
if (newThirdSection) {
|
||||
_thirdSection = std::move(newThirdSection);
|
||||
_thirdSection->removeRequests(
|
||||
) | rpl::start_with_next([=] {
|
||||
_thirdSection.destroy();
|
||||
_thirdShadow.destroy();
|
||||
updateControlsGeometry();
|
||||
}, _thirdSection->lifetime());
|
||||
if (!_thirdShadow) {
|
||||
_thirdShadow.create(this);
|
||||
_thirdShadow->show();
|
||||
|
@ -1821,9 +1854,9 @@ bool MainWidget::preventsCloseSection(Fn<void()> callback) const {
|
|||
bool MainWidget::preventsCloseSection(
|
||||
Fn<void()> callback,
|
||||
const SectionShow ¶ms) const {
|
||||
return params.thirdColumn
|
||||
? false
|
||||
: preventsCloseSection(std::move(callback));
|
||||
return !params.thirdColumn
|
||||
&& (params.activation != anim::activation::background)
|
||||
&& preventsCloseSection(std::move(callback));
|
||||
}
|
||||
|
||||
void MainWidget::showBackFromStack(
|
||||
|
|
|
@ -1902,9 +1902,19 @@ void OverlayWidget::showMediaOverview() {
|
|||
close();
|
||||
if (SharedMediaOverviewType(*overviewType)) {
|
||||
if (const auto window = findWindow()) {
|
||||
window->showSection(std::make_shared<Info::Memento>(
|
||||
_history->peer,
|
||||
Info::Section(*overviewType)));
|
||||
const auto topic = _topicRootId
|
||||
? _history->peer->forumTopicFor(_topicRootId)
|
||||
: nullptr;
|
||||
if (_topicRootId && !topic) {
|
||||
return;
|
||||
}
|
||||
window->showSection(_topicRootId
|
||||
? std::make_shared<Info::Memento>(
|
||||
topic,
|
||||
Info::Section(*overviewType))
|
||||
: std::make_shared<Info::Memento>(
|
||||
_history->peer,
|
||||
Info::Section(*overviewType)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1225,11 +1225,11 @@ reactionPremiumLocked: icon{
|
|||
{ "chat/reactions_premium_star", historyPeerUserpicFg },
|
||||
};
|
||||
reactionExpandPanel: icon{
|
||||
{ "chat/reactions_round_big", windowSubTextFg },
|
||||
{ "chat/reactions_round_big", windowBgRipple },
|
||||
{ "chat/reactions_expand_panel", windowBg },
|
||||
};
|
||||
reactionsExpandDropdown: icon{
|
||||
{ "chat/reactions_round_small", windowSubTextFg },
|
||||
{ "chat/reactions_round_small", windowBgRipple },
|
||||
{ "chat/reactions_expand_panel", windowBg },
|
||||
};
|
||||
|
||||
|
|
|
@ -19,21 +19,25 @@ enum class Column;
|
|||
|
||||
class SectionMemento {
|
||||
public:
|
||||
virtual object_ptr<SectionWidget> createWidget(
|
||||
[[nodiscard]] virtual object_ptr<SectionWidget> createWidget(
|
||||
QWidget *parent,
|
||||
not_null<SessionController*> controller,
|
||||
Column column,
|
||||
const QRect &geometry) = 0;
|
||||
|
||||
virtual object_ptr<Ui::LayerWidget> createLayer(
|
||||
[[nodiscard]] virtual object_ptr<Ui::LayerWidget> createLayer(
|
||||
not_null<SessionController*> controller,
|
||||
const QRect &geometry) {
|
||||
return nullptr;
|
||||
}
|
||||
virtual bool instant() const {
|
||||
[[nodiscard]] virtual bool instant() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
[[nodiscard]] virtual rpl::producer<> removeRequests() const {
|
||||
return rpl::never<>();
|
||||
}
|
||||
|
||||
virtual ~SectionMemento() = default;
|
||||
|
||||
};
|
||||
|
|
|
@ -139,7 +139,8 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
virtual bool preventsClose(Fn<void()> &&continueCallback) const {
|
||||
[[nodiscard]] virtual bool preventsClose(
|
||||
Fn<void()> &&continueCallback) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -157,10 +158,13 @@ public:
|
|||
doSetInnerFocus();
|
||||
}
|
||||
|
||||
virtual rpl::producer<int> desiredHeight() const;
|
||||
[[nodiscard]] virtual rpl::producer<int> desiredHeight() const;
|
||||
[[nodiscard]] virtual rpl::producer<> removeRequests() const {
|
||||
return rpl::never<>();
|
||||
}
|
||||
|
||||
// Some sections convert to layers on some geometry sizes.
|
||||
virtual object_ptr<Ui::LayerWidget> moveContentToLayer(
|
||||
[[nodiscard]] virtual object_ptr<Ui::LayerWidget> moveContentToLayer(
|
||||
QRect bodyGeometry) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -893,12 +893,8 @@ void SessionController::openForum(
|
|||
closeFolder();
|
||||
_openedForum = forum.get();
|
||||
if (_openedForum.current() == forum) {
|
||||
forum->flagsValue(
|
||||
) | rpl::filter([=](const ChannelData::Flags::Change &update) {
|
||||
using Flag = ChannelData::Flag;
|
||||
return (update.diff & Flag::Forum)
|
||||
&& !(update.value & Flag::Forum);
|
||||
}) | rpl::start_with_next([=] {
|
||||
forum->forum()->destroyed(
|
||||
) | rpl::start_with_next([=] {
|
||||
closeForum();
|
||||
showPeerHistory(
|
||||
forum,
|
||||
|
|
Loading…
Add table
Reference in a new issue