mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 10:11:41 -05:00
Feed info profile placeholder.
This commit is contained in:
parent
b9ad8bb700
commit
a47981054f
37 changed files with 1336 additions and 104 deletions
|
@ -1418,6 +1418,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_feed_name" = "Feed";
|
||||
"lng_feed_show_next" = "Show Next";
|
||||
|
||||
"lng_info_feed_title" = "Feed Info";
|
||||
|
||||
// Wnd specific
|
||||
|
||||
"lng_wnd_choose_program_menu" = "Choose Default Program...";
|
||||
|
|
|
@ -3830,16 +3830,6 @@ void HistoryWidget::pushTabbedSelectorToThirdSection(
|
|||
destroyingPanel.destroy();
|
||||
}
|
||||
|
||||
void HistoryWidget::pushInfoToThirdSection(
|
||||
const Window::SectionShow ¶ms) {
|
||||
if (!_peer) {
|
||||
return;
|
||||
}
|
||||
controller()->showSection(
|
||||
Info::Memento::Default(_peer),
|
||||
params.withThirdColumn());
|
||||
}
|
||||
|
||||
void HistoryWidget::toggleTabbedSelectorMode() {
|
||||
if (_tabbedPanel) {
|
||||
if (controller()->canShowThirdSection()
|
||||
|
|
|
@ -208,8 +208,6 @@ public:
|
|||
QRect historyRect() const;
|
||||
void pushTabbedSelectorToThirdSection(
|
||||
const Window::SectionShow ¶ms);
|
||||
void pushInfoToThirdSection(
|
||||
const Window::SectionShow ¶ms);
|
||||
|
||||
void updateRecentStickers();
|
||||
|
||||
|
|
|
@ -198,21 +198,20 @@ void TopBarWidget::toggleInfoSection() {
|
|||
&& (Auth().settings().thirdSectionInfoEnabled()
|
||||
|| Auth().settings().tabbedReplacedWithInfo())) {
|
||||
_controller->closeThirdSection();
|
||||
} else if (_activeChat.peer()) {
|
||||
// #TODO feeds profile
|
||||
} else if (_activeChat) {
|
||||
if (_controller->canShowThirdSection()) {
|
||||
Auth().settings().setThirdSectionInfoEnabled(true);
|
||||
Auth().saveSettingsDelayed();
|
||||
if (Adaptive::ThreeColumn()) {
|
||||
_controller->showSection(
|
||||
Info::Memento::Default(_activeChat.peer()),
|
||||
Info::Memento::Default(_activeChat),
|
||||
Window::SectionShow().withThirdColumn());
|
||||
} else {
|
||||
_controller->resizeForThirdSection();
|
||||
_controller->updateColumnLayout();
|
||||
}
|
||||
} else {
|
||||
_controller->showSection(Info::Memento(_activeChat.peer()->id));
|
||||
infoClicked();
|
||||
}
|
||||
} else {
|
||||
updateControlsVisibility();
|
||||
|
@ -345,7 +344,9 @@ void TopBarWidget::infoClicked() {
|
|||
if (!_activeChat) {
|
||||
return;
|
||||
} else if (const auto feed = _activeChat.feed()) {
|
||||
// #TODO feeds profile
|
||||
_controller->showSection(Info::Memento(
|
||||
feed,
|
||||
Info::Section(Info::Section::Type::Profile)));
|
||||
} else if (_activeChat.peer()->isSelf()) {
|
||||
_controller->showSection(Info::Memento(
|
||||
_activeChat.peer()->id,
|
||||
|
|
352
Telegram/SourceFiles/info/feed/info_feed_channels.cpp
Normal file
352
Telegram/SourceFiles/info/feed/info_feed_channels.cpp
Normal file
|
@ -0,0 +1,352 @@
|
|||
/*
|
||||
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/feed/info_feed_channels.h"
|
||||
|
||||
#include "info/profile/info_profile_icon.h"
|
||||
#include "info/profile/info_profile_button.h"
|
||||
#include "info/info_controller.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/scroll_area.h"
|
||||
#include "ui/wrap/padding_wrap.h"
|
||||
#include "ui/search_field_controller.h"
|
||||
#include "boxes/peer_list_controllers.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_info.h"
|
||||
|
||||
namespace Info {
|
||||
namespace FeedProfile {
|
||||
namespace {
|
||||
|
||||
constexpr auto kEnableSearchChannelsAfterCount = 20;
|
||||
|
||||
} // namespace
|
||||
|
||||
Channels::Channels(
|
||||
QWidget *parent,
|
||||
not_null<Controller*> controller)
|
||||
: RpWidget(parent)
|
||||
, _controller(controller)
|
||||
, _feed(_controller->key().feed())
|
||||
, _listController(std::make_unique<ContactsBoxController>()) {
|
||||
setupHeader();
|
||||
setupList();
|
||||
setContent(_list.data());
|
||||
_listController->setDelegate(static_cast<PeerListDelegate*>(this));
|
||||
|
||||
_controller->searchFieldController()->queryValue(
|
||||
) | rpl::start_with_next([this](QString &&query) {
|
||||
peerListScrollToTop();
|
||||
content()->searchQueryChanged(std::move(query));
|
||||
}, lifetime());
|
||||
//MembersCountValue(
|
||||
// _peer
|
||||
//) | rpl::start_with_next([this](int count) {
|
||||
// const auto enabled = (count >= kEnableSearchChannelsAfterCount);
|
||||
// _controller->setSearchEnabledByContent(enabled);
|
||||
//}, lifetime());
|
||||
}
|
||||
|
||||
int Channels::desiredHeight() const {
|
||||
auto desired = _header ? _header->height() : 0;
|
||||
//auto count = [this] {
|
||||
// if (auto chat = _peer->asChat()) {
|
||||
// return chat->count;
|
||||
// } else if (auto channel = _peer->asChannel()) {
|
||||
// return channel->membersCount();
|
||||
// }
|
||||
// return 0;
|
||||
//}();
|
||||
//desired += qMax(count, _list->fullRowsCount())
|
||||
// * st::infoMembersList.item.height;
|
||||
return qMax(height(), desired);
|
||||
}
|
||||
|
||||
rpl::producer<Ui::ScrollToRequest> Channels::scrollToRequests() const {
|
||||
return _scrollToRequests.events();
|
||||
}
|
||||
|
||||
std::unique_ptr<ChannelsState> Channels::saveState() {
|
||||
auto result = std::make_unique<ChannelsState>();
|
||||
result->list = _listController->saveState();
|
||||
return result;
|
||||
}
|
||||
|
||||
void Channels::restoreState(std::unique_ptr<ChannelsState> state) {
|
||||
if (!state) {
|
||||
return;
|
||||
}
|
||||
_listController->restoreState(std::move(state->list));
|
||||
}
|
||||
|
||||
void Channels::setupHeader() {
|
||||
if (_controller->section().type() == Section::Type::Members) {
|
||||
return;
|
||||
}
|
||||
_header = object_ptr<Ui::FixedHeightWidget>(
|
||||
this,
|
||||
st::infoMembersHeader);
|
||||
auto parent = _header.data();
|
||||
|
||||
_openChannels = Ui::CreateChild<Profile::Button>(
|
||||
parent,
|
||||
rpl::single(QString()));
|
||||
|
||||
object_ptr<Profile::FloatingIcon>(
|
||||
parent,
|
||||
st::infoIconMembers,
|
||||
st::infoIconPosition);
|
||||
|
||||
_titleWrap = Ui::CreateChild<Ui::RpWidget>(parent);
|
||||
_title = setupTitle();
|
||||
_addChannel = Ui::CreateChild<Ui::IconButton>(
|
||||
_openChannels,
|
||||
st::infoMembersAddMember);
|
||||
_search = Ui::CreateChild<Ui::IconButton>(
|
||||
_openChannels,
|
||||
st::infoMembersSearch);
|
||||
|
||||
setupButtons();
|
||||
|
||||
widthValue(
|
||||
) | rpl::start_with_next([this](int width) {
|
||||
_header->resizeToWidth(width);
|
||||
}, _header->lifetime());
|
||||
}
|
||||
|
||||
object_ptr<Ui::FlatLabel> Channels::setupTitle() {
|
||||
auto result = object_ptr<Ui::FlatLabel>(
|
||||
_titleWrap,
|
||||
rpl::single(QString("Contacts")),
|
||||
//MembersCountValue(
|
||||
// _peer
|
||||
//) | rpl::map([](int count) {
|
||||
// return lng_chat_status_members(lt_count, count);
|
||||
//}) | ToUpperValue(),
|
||||
st::infoBlockHeaderLabel);
|
||||
result->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Channels::setupButtons() {
|
||||
using namespace rpl::mappers;
|
||||
|
||||
_openChannels->addClickHandler([this] {
|
||||
showChannelsWithSearch(false);
|
||||
});
|
||||
|
||||
//auto addMemberShown = CanAddMemberValue(_peer)
|
||||
// | rpl::start_spawning(lifetime());
|
||||
//_addChannel->showOn(rpl::duplicate(addMemberShown));
|
||||
//_addChannel->addClickHandler([this] { // TODO throttle(ripple duration)
|
||||
// this->addMember();
|
||||
//});
|
||||
|
||||
//auto searchShown = MembersCountValue(_peer)
|
||||
// | rpl::map(_1 >= kEnableSearchMembersAfterCount)
|
||||
// | rpl::distinct_until_changed()
|
||||
// | rpl::start_spawning(lifetime());
|
||||
//_search->showOn(rpl::duplicate(searchShown));
|
||||
//_search->addClickHandler([this] { // TODO throttle(ripple duration)
|
||||
// this->showMembersWithSearch(true);
|
||||
//});
|
||||
|
||||
//rpl::combine(
|
||||
// std::move(addMemberShown),
|
||||
// std::move(searchShown)
|
||||
//) | rpl::start_with_next([this] {
|
||||
// updateHeaderControlsGeometry(width());
|
||||
//}, lifetime());
|
||||
}
|
||||
|
||||
void Channels::setupList() {
|
||||
auto topSkip = _header ? _header->height() : 0;
|
||||
_list = object_ptr<ListWidget>(
|
||||
this,
|
||||
_listController.get(),
|
||||
st::infoMembersList);
|
||||
_list->scrollToRequests(
|
||||
) | rpl::start_with_next([this](Ui::ScrollToRequest request) {
|
||||
auto addmin = (request.ymin < 0 || !_header)
|
||||
? 0
|
||||
: _header->height();
|
||||
auto addmax = (request.ymax < 0 || !_header)
|
||||
? 0
|
||||
: _header->height();
|
||||
_scrollToRequests.fire({
|
||||
request.ymin + addmin,
|
||||
request.ymax + addmax });
|
||||
}, _list->lifetime());
|
||||
widthValue(
|
||||
) | rpl::start_with_next([this](int newWidth) {
|
||||
_list->resizeToWidth(newWidth);
|
||||
}, _list->lifetime());
|
||||
_list->heightValue(
|
||||
) | rpl::start_with_next([=](int listHeight) {
|
||||
auto newHeight = (listHeight > st::membersMarginBottom)
|
||||
? (topSkip
|
||||
+ listHeight
|
||||
+ st::membersMarginBottom)
|
||||
: 0;
|
||||
resize(width(), newHeight);
|
||||
}, _list->lifetime());
|
||||
_list->moveToLeft(0, topSkip);
|
||||
}
|
||||
|
||||
int Channels::resizeGetHeight(int newWidth) {
|
||||
if (_header) {
|
||||
updateHeaderControlsGeometry(newWidth);
|
||||
}
|
||||
return heightNoMargins();
|
||||
}
|
||||
|
||||
//void Channels::updateSearchEnabledByContent() {
|
||||
// _controller->setSearchEnabledByContent(
|
||||
// peerListFullRowsCount() >= kEnableSearchMembersAfterCount);
|
||||
//}
|
||||
|
||||
void Channels::updateHeaderControlsGeometry(int newWidth) {
|
||||
_openChannels->setGeometry(0, st::infoProfileSkip, newWidth, st::infoMembersHeader - st::infoProfileSkip - st::infoMembersHeaderPaddingBottom);
|
||||
|
||||
auto availableWidth = newWidth
|
||||
- st::infoMembersButtonPosition.x();
|
||||
|
||||
//auto cancelLeft = availableWidth - _cancelSearch->width();
|
||||
//_cancelSearch->moveToLeft(
|
||||
// cancelLeft,
|
||||
// st::infoMembersButtonPosition.y());
|
||||
|
||||
//auto searchShownLeft = st::infoIconPosition.x()
|
||||
// - st::infoMembersSearch.iconPosition.x();
|
||||
//auto searchHiddenLeft = availableWidth - _search->width();
|
||||
//auto searchShown = _searchShownAnimation.current(_searchShown ? 1. : 0.);
|
||||
//auto searchCurrentLeft = anim::interpolate(
|
||||
// searchHiddenLeft,
|
||||
// searchShownLeft,
|
||||
// searchShown);
|
||||
//_search->moveToLeft(
|
||||
// searchCurrentLeft,
|
||||
// st::infoMembersButtonPosition.y());
|
||||
|
||||
//if (!_search->isHidden()) {
|
||||
// availableWidth -= st::infoMembersSearch.width;
|
||||
//}
|
||||
_addChannel->moveToLeft(
|
||||
availableWidth - _addChannel->width(),
|
||||
st::infoMembersButtonPosition.y(),
|
||||
newWidth);
|
||||
if (!_addChannel->isHidden()) {
|
||||
availableWidth -= st::infoMembersSearch.width;
|
||||
}
|
||||
_search->moveToLeft(
|
||||
availableWidth - _search->width(),
|
||||
st::infoMembersButtonPosition.y(),
|
||||
newWidth);
|
||||
|
||||
//auto fieldLeft = anim::interpolate(
|
||||
// cancelLeft,
|
||||
// st::infoBlockHeaderPosition.x(),
|
||||
// searchShown);
|
||||
//_searchField->setGeometryToLeft(
|
||||
// fieldLeft,
|
||||
// st::infoMembersSearchTop,
|
||||
// cancelLeft - fieldLeft,
|
||||
// _searchField->height());
|
||||
|
||||
//_titleWrap->resize(
|
||||
// searchCurrentLeft - st::infoBlockHeaderPosition.x(),
|
||||
// _title->height());
|
||||
_titleWrap->resize(
|
||||
availableWidth - _addChannel->width() - st::infoBlockHeaderPosition.x(),
|
||||
_title->height());
|
||||
_titleWrap->moveToLeft(
|
||||
st::infoBlockHeaderPosition.x(),
|
||||
st::infoBlockHeaderPosition.y(),
|
||||
newWidth);
|
||||
_titleWrap->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
|
||||
//_title->resizeToWidth(searchHiddenLeft);
|
||||
_title->resizeToWidth(_titleWrap->width());
|
||||
_title->moveToLeft(0, 0);
|
||||
}
|
||||
|
||||
void Channels::addChannel() {
|
||||
//if (const auto chat = _peer->asChat()) {
|
||||
// if (chat->count >= Global::ChatSizeMax() && chat->amCreator()) {
|
||||
// Ui::show(Box<ConvertToSupergroupBox>(chat));
|
||||
// } else {
|
||||
// AddParticipantsBoxController::Start(chat);
|
||||
// }
|
||||
//} else if (const auto channel = _peer->asChannel()) {
|
||||
// const auto state = _listController->saveState();
|
||||
// const auto users = ranges::view::all(
|
||||
// state->list
|
||||
// ) | ranges::view::transform([](not_null<PeerData*> peer) {
|
||||
// return peer->asUser();
|
||||
// }) | ranges::to_vector;
|
||||
// AddParticipantsBoxController::Start(
|
||||
// channel,
|
||||
// { users.begin(), users.end() });
|
||||
//}
|
||||
}
|
||||
|
||||
void Channels::showChannelsWithSearch(bool withSearch) {
|
||||
//auto contentMemento = std::make_unique<Info::Members::Memento>(
|
||||
// _controller);
|
||||
//contentMemento->setState(saveState());
|
||||
//contentMemento->setSearchStartsFocused(withSearch);
|
||||
//auto mementoStack = std::vector<std::unique_ptr<ContentMemento>>();
|
||||
//mementoStack.push_back(std::move(contentMemento));
|
||||
//_controller->showSection(
|
||||
// Info::Memento(std::move(mementoStack)));
|
||||
}
|
||||
|
||||
void Channels::visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) {
|
||||
setChildVisibleTopBottom(_list, visibleTop, visibleBottom);
|
||||
}
|
||||
|
||||
void Channels::peerListSetTitle(base::lambda<QString()> title) {
|
||||
}
|
||||
|
||||
void Channels::peerListSetAdditionalTitle(
|
||||
base::lambda<QString()> title) {
|
||||
}
|
||||
|
||||
bool Channels::peerListIsRowSelected(not_null<PeerData*> peer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int Channels::peerListSelectedRowsCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<not_null<PeerData*>> Channels::peerListCollectSelectedRows() {
|
||||
return {};
|
||||
}
|
||||
|
||||
void Channels::peerListScrollToTop() {
|
||||
_scrollToRequests.fire({ -1, -1 });
|
||||
}
|
||||
|
||||
void Channels::peerListAddSelectedRowInBunch(not_null<PeerData*> peer) {
|
||||
Unexpected("Item selection in Info::Profile::Members.");
|
||||
}
|
||||
|
||||
void Channels::peerListFinishSelectedRowsBunch() {
|
||||
}
|
||||
|
||||
void Channels::peerListSetDescription(
|
||||
object_ptr<Ui::FlatLabel> description) {
|
||||
description.destroy();
|
||||
}
|
||||
|
||||
} // namespace FeedProfile
|
||||
} // namespace Info
|
||||
|
103
Telegram/SourceFiles/info/feed/info_feed_channels.h
Normal file
103
Telegram/SourceFiles/info/feed/info_feed_channels.h
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
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 "boxes/peer_list_box.h"
|
||||
|
||||
namespace Ui {
|
||||
class InputField;
|
||||
class CrossButton;
|
||||
class IconButton;
|
||||
class FlatLabel;
|
||||
struct ScrollToRequest;
|
||||
class AbstractButton;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Info {
|
||||
|
||||
class Controller;
|
||||
enum class Wrap;
|
||||
|
||||
namespace Profile {
|
||||
class Button;
|
||||
} // namespace Profile
|
||||
|
||||
namespace FeedProfile {
|
||||
|
||||
class Memento;
|
||||
struct ChannelsState {
|
||||
std::unique_ptr<PeerListState> list;
|
||||
base::optional<QString> search;
|
||||
};
|
||||
|
||||
class Channels
|
||||
: public Ui::RpWidget
|
||||
, private PeerListContentDelegate {
|
||||
public:
|
||||
Channels(
|
||||
QWidget *parent,
|
||||
not_null<Controller*> controller);
|
||||
|
||||
rpl::producer<Ui::ScrollToRequest> scrollToRequests() const;
|
||||
|
||||
std::unique_ptr<ChannelsState> saveState();
|
||||
void restoreState(std::unique_ptr<ChannelsState> state);
|
||||
|
||||
int desiredHeight() const;
|
||||
|
||||
protected:
|
||||
void visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) override;
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
|
||||
private:
|
||||
using ListWidget = PeerListContent;
|
||||
|
||||
// PeerListContentDelegate interface.
|
||||
void peerListSetTitle(base::lambda<QString()> title) override;
|
||||
void peerListSetAdditionalTitle(
|
||||
base::lambda<QString()> title) override;
|
||||
bool peerListIsRowSelected(not_null<PeerData*> peer) override;
|
||||
int peerListSelectedRowsCount() override;
|
||||
std::vector<not_null<PeerData*>> peerListCollectSelectedRows() override;
|
||||
void peerListScrollToTop() override;
|
||||
void peerListAddSelectedRowInBunch(
|
||||
not_null<PeerData*> peer) override;
|
||||
void peerListFinishSelectedRowsBunch() override;
|
||||
void peerListSetDescription(
|
||||
object_ptr<Ui::FlatLabel> description) override;
|
||||
|
||||
void setupHeader();
|
||||
object_ptr<Ui::FlatLabel> setupTitle();
|
||||
void setupList();
|
||||
|
||||
void setupButtons();
|
||||
void addChannel();
|
||||
void showChannelsWithSearch(bool withSearch);
|
||||
void updateHeaderControlsGeometry(int newWidth);
|
||||
|
||||
not_null<Controller*> _controller;
|
||||
not_null<Data::Feed*> _feed;
|
||||
std::unique_ptr<PeerListController> _listController;
|
||||
object_ptr<Ui::RpWidget> _header = { nullptr };
|
||||
object_ptr<ListWidget> _list = { nullptr };
|
||||
|
||||
Profile::Button *_openChannels = nullptr;
|
||||
Ui::RpWidget *_titleWrap = nullptr;
|
||||
Ui::FlatLabel *_title = nullptr;
|
||||
Ui::IconButton *_addChannel = nullptr;
|
||||
Ui::IconButton *_search = nullptr;
|
||||
|
||||
rpl::event_stream<Ui::ScrollToRequest> _scrollToRequests;
|
||||
|
||||
};
|
||||
|
||||
} // namespace FeedProfile
|
||||
} // namespace Info
|
191
Telegram/SourceFiles/info/feed/info_feed_cover.cpp
Normal file
191
Telegram/SourceFiles/info/feed/info_feed_cover.cpp
Normal file
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
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/feed/info_feed_cover.h"
|
||||
|
||||
#include "data/data_feed.h"
|
||||
#include "info/info_controller.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "styles/style_info.h"
|
||||
|
||||
namespace Info {
|
||||
namespace FeedProfile {
|
||||
|
||||
Cover::Cover(
|
||||
QWidget *parent,
|
||||
not_null<Controller*> controller)
|
||||
: FixedHeightWidget(
|
||||
parent,
|
||||
st::infoProfilePhotoTop
|
||||
+ st::infoProfilePhoto.size.height()
|
||||
+ st::infoProfilePhotoBottom)
|
||||
, _controller(controller)
|
||||
, _feed(_controller->key().feed())
|
||||
//, _userpic(
|
||||
// this,
|
||||
// controller->parentController(),
|
||||
// _peer,
|
||||
// Ui::UserpicButton::Role::OpenPhoto,
|
||||
// st::infoProfilePhoto)
|
||||
, _name(this, st::infoProfileNameLabel)
|
||||
, _status(
|
||||
this,
|
||||
st::infoProfileMegagroupStatusLabel) {
|
||||
_name->setSelectable(true);
|
||||
_name->setContextCopyText(lang(lng_profile_copy_fullname));
|
||||
|
||||
initViewers();
|
||||
setupChildGeometry();
|
||||
}
|
||||
|
||||
void Cover::setupChildGeometry() {
|
||||
using namespace rpl::mappers;
|
||||
//
|
||||
// Visual Studio 2017 15.5.1 internal compiler error here.
|
||||
// See https://developercommunity.visualstudio.com/content/problem/165155/ice-regression-in-1551-after-successfull-build-in.html
|
||||
//
|
||||
//rpl::combine(
|
||||
// toggleShownValue(),
|
||||
// widthValue(),
|
||||
// _2
|
||||
//) | rpl::map([](bool shown, int width) {
|
||||
|
||||
//rpl::combine(
|
||||
// toggleShownValue(),
|
||||
// widthValue()
|
||||
//) | rpl::map([](bool shown, int width) {
|
||||
// return width;
|
||||
//}) | rpl::start_with_next([this](int newWidth) {
|
||||
// _userpic->moveToLeft(
|
||||
// st::infoProfilePhotoLeft,
|
||||
// st::infoProfilePhotoTop,
|
||||
// newWidth);
|
||||
// refreshNameGeometry(newWidth);
|
||||
// refreshStatusGeometry(newWidth);
|
||||
//}, lifetime());
|
||||
}
|
||||
|
||||
void Cover::initViewers() {
|
||||
//using Flag = Notify::PeerUpdate::Flag;
|
||||
//Notify::PeerUpdateValue(
|
||||
// _peer,
|
||||
// Flag::NameChanged
|
||||
//) | rpl::start_with_next(
|
||||
// [this] { refreshNameText(); },
|
||||
// lifetime());
|
||||
//Notify::PeerUpdateValue(
|
||||
// _peer,
|
||||
// Flag::UserOnlineChanged | Flag::MembersChanged
|
||||
//) | rpl::start_with_next(
|
||||
// [this] { refreshStatusText(); },
|
||||
// lifetime());
|
||||
//if (!_peer->isUser()) {
|
||||
// Notify::PeerUpdateValue(
|
||||
// _peer,
|
||||
// Flag::ChannelRightsChanged | Flag::ChatCanEdit
|
||||
// ) | rpl::start_with_next(
|
||||
// [this] { refreshUploadPhotoOverlay(); },
|
||||
// lifetime());
|
||||
//}
|
||||
//VerifiedValue(
|
||||
// _peer
|
||||
//) | rpl::start_with_next(
|
||||
// [this](bool verified) { setVerified(verified); },
|
||||
// lifetime());
|
||||
}
|
||||
|
||||
void Cover::refreshUploadPhotoOverlay() {
|
||||
//_userpic->switchChangePhotoOverlay([&] {
|
||||
// if (auto chat = _peer->asChat()) {
|
||||
// return chat->canEdit();
|
||||
// } else if (auto channel = _peer->asChannel()) {
|
||||
// return channel->canEditInformation();
|
||||
// }
|
||||
// return false;
|
||||
//}());
|
||||
}
|
||||
|
||||
void Cover::refreshNameText() {
|
||||
_name->setText(_feed->chatsListName());
|
||||
refreshNameGeometry(width());
|
||||
}
|
||||
|
||||
void Cover::refreshStatusText() {
|
||||
//auto hasMembersLink = [&] {
|
||||
// if (auto megagroup = _peer->asMegagroup()) {
|
||||
// return megagroup->canViewMembers();
|
||||
// }
|
||||
// return false;
|
||||
//}();
|
||||
//auto statusText = [&] {
|
||||
// auto currentTime = unixtime();
|
||||
// if (auto user = _peer->asUser()) {
|
||||
// const auto result = Data::OnlineTextFull(user, currentTime);
|
||||
// const auto showOnline = Data::OnlineTextActive(user, currentTime);
|
||||
// const auto updateIn = Data::OnlineChangeTimeout(user, currentTime);
|
||||
// if (showOnline) {
|
||||
// _refreshStatusTimer.callOnce(updateIn);
|
||||
// }
|
||||
// return showOnline
|
||||
// ? textcmdLink(1, result)
|
||||
// : result;
|
||||
// } else if (auto chat = _peer->asChat()) {
|
||||
// if (!chat->amIn()) {
|
||||
// return lang(lng_chat_status_unaccessible);
|
||||
// }
|
||||
// auto fullCount = std::max(
|
||||
// chat->count,
|
||||
// int(chat->participants.size()));
|
||||
// return ChatStatusText(fullCount, _onlineCount, true);
|
||||
// } else if (auto channel = _peer->asChannel()) {
|
||||
// auto fullCount = qMax(channel->membersCount(), 1);
|
||||
// auto result = ChatStatusText(
|
||||
// fullCount,
|
||||
// _onlineCount,
|
||||
// channel->isMegagroup());
|
||||
// return hasMembersLink ? textcmdLink(1, result) : result;
|
||||
// }
|
||||
// return lang(lng_chat_status_unaccessible);
|
||||
//}();
|
||||
//_status->setRichText(statusText);
|
||||
//if (hasMembersLink) {
|
||||
// _status->setLink(1, std::make_shared<LambdaClickHandler>([=] {
|
||||
// _controller->showSection(Info::Memento(
|
||||
// _controller->peerId(),
|
||||
// Section::Type::Members));
|
||||
// }));
|
||||
//}
|
||||
refreshStatusGeometry(width());
|
||||
}
|
||||
|
||||
Cover::~Cover() {
|
||||
}
|
||||
|
||||
void Cover::refreshNameGeometry(int newWidth) {
|
||||
auto nameLeft = st::infoProfileNameLeft;
|
||||
auto nameTop = st::infoProfileNameTop;
|
||||
auto nameWidth = newWidth
|
||||
- nameLeft
|
||||
- st::infoProfileNameRight;
|
||||
_name->resizeToNaturalWidth(nameWidth);
|
||||
_name->moveToLeft(nameLeft, nameTop, newWidth);
|
||||
}
|
||||
|
||||
void Cover::refreshStatusGeometry(int newWidth) {
|
||||
auto statusWidth = newWidth
|
||||
- st::infoProfileStatusLeft
|
||||
- st::infoProfileStatusRight;
|
||||
_status->resizeToWidth(statusWidth);
|
||||
_status->moveToLeft(
|
||||
st::infoProfileStatusLeft,
|
||||
st::infoProfileStatusTop,
|
||||
newWidth);
|
||||
}
|
||||
|
||||
} // namespace FeedProfile
|
||||
} // namespace Info
|
64
Telegram/SourceFiles/info/feed/info_feed_cover.h
Normal file
64
Telegram/SourceFiles/info/feed/info_feed_cover.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
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/wrap/padding_wrap.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "base/timer.h"
|
||||
|
||||
namespace style {
|
||||
struct InfoToggle;
|
||||
} // namespace style
|
||||
|
||||
namespace Data {
|
||||
class Feed;
|
||||
} // namespace Data
|
||||
|
||||
namespace Ui {
|
||||
class UserpicButton;
|
||||
class FlatLabel;
|
||||
template <typename Widget>
|
||||
class SlideWrap;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Info {
|
||||
class Controller;
|
||||
} // namespace Info
|
||||
|
||||
namespace Info {
|
||||
namespace FeedProfile {
|
||||
|
||||
class Cover : public Ui::FixedHeightWidget {
|
||||
public:
|
||||
Cover(
|
||||
QWidget *parent,
|
||||
not_null<Controller*> controller);
|
||||
|
||||
~Cover();
|
||||
|
||||
private:
|
||||
void setupChildGeometry();
|
||||
void initViewers();
|
||||
void refreshNameText();
|
||||
void refreshStatusText();
|
||||
void refreshNameGeometry(int newWidth);
|
||||
void refreshStatusGeometry(int newWidth);
|
||||
void refreshUploadPhotoOverlay();
|
||||
|
||||
not_null<Controller*> _controller;
|
||||
not_null<Data::Feed*> _feed;
|
||||
|
||||
//object_ptr<Ui::UserpicButton> _userpic;
|
||||
object_ptr<Ui::FlatLabel> _name = { nullptr };
|
||||
object_ptr<Ui::FlatLabel> _status = { nullptr };
|
||||
//object_ptr<CoverDropArea> _dropArea = { nullptr };
|
||||
|
||||
};
|
||||
|
||||
} // namespace FeedProfile
|
||||
} // namespace Info
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
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/feed/info_feed_profile_inner_widget.h"
|
||||
|
||||
#include "info/info_controller.h"
|
||||
#include "info/feed/info_feed_profile_widget.h"
|
||||
#include "info/feed/info_feed_cover.h"
|
||||
#include "info/feed/info_feed_channels.h"
|
||||
#include "ui/widgets/scroll_area.h"
|
||||
#include "ui/wrap/vertical_layout.h"
|
||||
|
||||
namespace Info {
|
||||
namespace FeedProfile {
|
||||
|
||||
InnerWidget::InnerWidget(
|
||||
QWidget *parent,
|
||||
not_null<Controller*> controller)
|
||||
: RpWidget(parent)
|
||||
, _controller(controller)
|
||||
, _feed(_controller->key().feed())
|
||||
, _content(setupContent(this)) {
|
||||
_content->heightValue(
|
||||
) | rpl::start_with_next([this](int height) {
|
||||
if (!_inResize) {
|
||||
resizeToWidth(width());
|
||||
updateDesiredHeight();
|
||||
}
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
object_ptr<Ui::RpWidget> InnerWidget::setupContent(
|
||||
not_null<RpWidget*> parent) {
|
||||
auto result = object_ptr<Ui::VerticalLayout>(parent);
|
||||
_cover = result->add(object_ptr<Cover>(
|
||||
result,
|
||||
_controller));
|
||||
//auto details = SetupDetails(_controller, parent, _peer);
|
||||
//result->add(std::move(details));
|
||||
//if (auto members = SetupChannelMembers(_controller, result.data(), _peer)) {
|
||||
// result->add(std::move(members));
|
||||
//}
|
||||
//result->add(object_ptr<BoxContentDivider>(result));
|
||||
//if (auto actions = SetupActions(_controller, result.data(), _peer)) {
|
||||
// result->add(std::move(actions));
|
||||
//}
|
||||
|
||||
//_channels = result->add(object_ptr<Channels>(
|
||||
// result,
|
||||
// _controller)
|
||||
//);
|
||||
//_channels->scrollToRequests(
|
||||
//) | rpl::start_with_next([this](Ui::ScrollToRequest request) {
|
||||
// auto min = (request.ymin < 0)
|
||||
// ? request.ymin
|
||||
// : mapFromGlobal(_channels->mapToGlobal({ 0, request.ymin })).y();
|
||||
// auto max = (request.ymin < 0)
|
||||
// ? mapFromGlobal(_channels->mapToGlobal({ 0, 0 })).y()
|
||||
// : (request.ymax < 0)
|
||||
// ? request.ymax
|
||||
// : mapFromGlobal(_channels->mapToGlobal({ 0, request.ymax })).y();
|
||||
// _scrollToRequests.fire({ min, max });
|
||||
//}, _channels->lifetime());
|
||||
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
int InnerWidget::countDesiredHeight() const {
|
||||
return _content->height() + (_channels
|
||||
? (_channels->desiredHeight() - _channels->height())
|
||||
: 0);
|
||||
}
|
||||
|
||||
void InnerWidget::visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) {
|
||||
setChildVisibleTopBottom(_content, visibleTop, visibleBottom);
|
||||
}
|
||||
|
||||
void InnerWidget::saveState(not_null<Memento*> memento) {
|
||||
if (_channels) {
|
||||
memento->setChannelsState(_channels->saveState());
|
||||
}
|
||||
}
|
||||
|
||||
void InnerWidget::restoreState(not_null<Memento*> memento) {
|
||||
if (_channels) {
|
||||
_channels->restoreState(memento->channelsState());
|
||||
}
|
||||
}
|
||||
|
||||
rpl::producer<Ui::ScrollToRequest> InnerWidget::scrollToRequests() const {
|
||||
return _scrollToRequests.events();
|
||||
}
|
||||
|
||||
rpl::producer<int> InnerWidget::desiredHeightValue() const {
|
||||
return _desiredHeight.events_starting_with(countDesiredHeight());
|
||||
}
|
||||
|
||||
int InnerWidget::resizeGetHeight(int newWidth) {
|
||||
_inResize = true;
|
||||
auto guard = gsl::finally([&] { _inResize = false; });
|
||||
|
||||
_content->resizeToWidth(newWidth);
|
||||
_content->moveToLeft(0, 0);
|
||||
updateDesiredHeight();
|
||||
return _content->heightNoMargins();
|
||||
}
|
||||
|
||||
} // namespace FeedProfile
|
||||
} // namespace Info
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
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 <rpl/variable.h>
|
||||
#include "ui/rp_widget.h"
|
||||
|
||||
namespace Window {
|
||||
class Controller;
|
||||
} // namespace Window
|
||||
|
||||
namespace Ui {
|
||||
class VerticalLayout;
|
||||
template <typename Widget>
|
||||
class SlideWrap;
|
||||
struct ScrollToRequest;
|
||||
class MultiSlideTracker;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Info {
|
||||
|
||||
enum class Wrap;
|
||||
class Controller;
|
||||
|
||||
namespace FeedProfile {
|
||||
|
||||
class Memento;
|
||||
class Channels;
|
||||
class Cover;
|
||||
|
||||
class InnerWidget final : public Ui::RpWidget {
|
||||
public:
|
||||
InnerWidget(
|
||||
QWidget *parent,
|
||||
not_null<Controller*> controller);
|
||||
|
||||
void saveState(not_null<Memento*> memento);
|
||||
void restoreState(not_null<Memento*> memento);
|
||||
|
||||
void setIsStackBottom(bool isStackBottom) {
|
||||
_isStackBottom = isStackBottom;
|
||||
}
|
||||
rpl::producer<Ui::ScrollToRequest> scrollToRequests() const;
|
||||
rpl::producer<int> desiredHeightValue() const override;
|
||||
|
||||
protected:
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
void visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) override;
|
||||
|
||||
private:
|
||||
object_ptr<RpWidget> setupContent(not_null<RpWidget*> parent);
|
||||
|
||||
int countDesiredHeight() const;
|
||||
void updateDesiredHeight() {
|
||||
_desiredHeight.fire(countDesiredHeight());
|
||||
}
|
||||
|
||||
rpl::variable<bool> _isStackBottom = true;
|
||||
|
||||
const not_null<Controller*> _controller;
|
||||
const not_null<Data::Feed*> _feed;
|
||||
|
||||
Channels *_channels = nullptr;
|
||||
Cover *_cover = nullptr;
|
||||
object_ptr<RpWidget> _content;
|
||||
|
||||
bool _inResize = false;
|
||||
rpl::event_stream<Ui::ScrollToRequest> _scrollToRequests;
|
||||
rpl::event_stream<int> _desiredHeight;
|
||||
|
||||
};
|
||||
|
||||
} // namespace FeedProfile
|
||||
} // namespace Info
|
116
Telegram/SourceFiles/info/feed/info_feed_profile_widget.cpp
Normal file
116
Telegram/SourceFiles/info/feed/info_feed_profile_widget.cpp
Normal file
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
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/feed/info_feed_profile_widget.h"
|
||||
|
||||
#include "info/feed/info_feed_profile_inner_widget.h"
|
||||
#include "info/feed/info_feed_channels.h"
|
||||
#include "ui/widgets/scroll_area.h"
|
||||
#include "info/info_controller.h"
|
||||
|
||||
namespace Info {
|
||||
namespace FeedProfile {
|
||||
|
||||
Memento::Memento(not_null<Controller*> controller)
|
||||
: Memento(controller->feed()) {
|
||||
}
|
||||
|
||||
Memento::Memento(not_null<Data::Feed*> feed)
|
||||
: ContentMemento(feed) {
|
||||
}
|
||||
|
||||
Section Memento::section() const {
|
||||
return Section(Section::Type::Profile);
|
||||
}
|
||||
|
||||
object_ptr<ContentWidget> Memento::createWidget(
|
||||
QWidget *parent,
|
||||
not_null<Controller*> controller,
|
||||
const QRect &geometry) {
|
||||
auto result = object_ptr<Widget>(
|
||||
parent,
|
||||
controller);
|
||||
result->setInternalState(geometry, this);
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
void Memento::setChannelsState(std::unique_ptr<ChannelsState> state) {
|
||||
_channelsState = std::move(state);
|
||||
}
|
||||
|
||||
std::unique_ptr<ChannelsState> Memento::channelsState() {
|
||||
return std::move(_channelsState);
|
||||
}
|
||||
|
||||
Memento::~Memento() = default;
|
||||
|
||||
Widget::Widget(
|
||||
QWidget *parent,
|
||||
not_null<Controller*> controller)
|
||||
: ContentWidget(parent, controller) {
|
||||
controller->setSearchEnabledByContent(false);
|
||||
|
||||
_inner = setInnerWidget(object_ptr<InnerWidget>(
|
||||
this,
|
||||
controller));
|
||||
_inner->move(0, 0);
|
||||
_inner->scrollToRequests(
|
||||
) | rpl::start_with_next([this](Ui::ScrollToRequest request) {
|
||||
if (request.ymin < 0) {
|
||||
scrollTopRestore(
|
||||
qMin(scrollTopSave(), request.ymax));
|
||||
} else {
|
||||
scrollTo(request);
|
||||
}
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
void Widget::setIsStackBottom(bool isStackBottom) {
|
||||
_inner->setIsStackBottom(isStackBottom);
|
||||
}
|
||||
|
||||
void Widget::setInnerFocus() {
|
||||
_inner->setFocus();
|
||||
}
|
||||
|
||||
bool Widget::showInternal(not_null<ContentMemento*> memento) {
|
||||
if (!controller()->validateMementoPeer(memento)) {
|
||||
return false;
|
||||
}
|
||||
if (auto profileMemento = dynamic_cast<Memento*>(memento.get())) {
|
||||
restoreState(profileMemento);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Widget::setInternalState(
|
||||
const QRect &geometry,
|
||||
not_null<Memento*> memento) {
|
||||
setGeometry(geometry);
|
||||
Ui::SendPendingMoveResizeEvents(this);
|
||||
restoreState(memento);
|
||||
}
|
||||
|
||||
std::unique_ptr<ContentMemento> Widget::doCreateMemento() {
|
||||
auto result = std::make_unique<Memento>(controller());
|
||||
saveState(result.get());
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
void Widget::saveState(not_null<Memento*> memento) {
|
||||
memento->setScrollTop(scrollTopSave());
|
||||
_inner->saveState(memento);
|
||||
}
|
||||
|
||||
void Widget::restoreState(not_null<Memento*> memento) {
|
||||
_inner->restoreState(memento);
|
||||
scrollTopRestore(memento->scrollTop());
|
||||
}
|
||||
|
||||
} // namespace FeedProfile
|
||||
} // namespace Info
|
69
Telegram/SourceFiles/info/feed/info_feed_profile_widget.h
Normal file
69
Telegram/SourceFiles/info/feed/info_feed_profile_widget.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
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 <rpl/producer.h>
|
||||
#include "info/info_content_widget.h"
|
||||
|
||||
namespace Info {
|
||||
namespace FeedProfile {
|
||||
|
||||
class InnerWidget;
|
||||
struct ChannelsState;
|
||||
|
||||
class Memento final : public ContentMemento {
|
||||
public:
|
||||
Memento(not_null<Controller*> controller);
|
||||
Memento(not_null<Data::Feed*> feed);
|
||||
|
||||
object_ptr<ContentWidget> createWidget(
|
||||
QWidget *parent,
|
||||
not_null<Controller*> controller,
|
||||
const QRect &geometry) override;
|
||||
|
||||
Section section() const override;
|
||||
|
||||
void setChannelsState(std::unique_ptr<ChannelsState> state);
|
||||
std::unique_ptr<ChannelsState> channelsState();
|
||||
|
||||
~Memento();
|
||||
|
||||
private:
|
||||
std::unique_ptr<ChannelsState> _channelsState;
|
||||
|
||||
};
|
||||
|
||||
class Widget final : public ContentWidget {
|
||||
public:
|
||||
Widget(
|
||||
QWidget *parent,
|
||||
not_null<Controller*> controller);
|
||||
|
||||
void setIsStackBottom(bool isStackBottom) override;
|
||||
|
||||
bool showInternal(
|
||||
not_null<ContentMemento*> memento) override;
|
||||
|
||||
void setInternalState(
|
||||
const QRect &geometry,
|
||||
not_null<Memento*> memento);
|
||||
|
||||
void setInnerFocus() override;
|
||||
|
||||
private:
|
||||
void saveState(not_null<Memento*> memento);
|
||||
void restoreState(not_null<Memento*> memento);
|
||||
|
||||
std::unique_ptr<ContentMemento> doCreateMemento() override;
|
||||
|
||||
InnerWidget *_inner = nullptr;
|
||||
|
||||
};
|
||||
|
||||
} // namespace FeedProfile
|
||||
} // namespace Info
|
|
@ -17,7 +17,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/search_field_controller.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "info/profile/info_profile_widget.h"
|
||||
#include "info/profile/info_profile_members.h"
|
||||
#include "info/media/info_media_widget.h"
|
||||
#include "info/common_groups/info_common_groups_widget.h"
|
||||
#include "info/info_layer_widget.h"
|
||||
|
|
|
@ -23,6 +23,10 @@ template <typename Widget>
|
|||
class PaddingWrap;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Data {
|
||||
class Feed;
|
||||
} // namespace Data
|
||||
|
||||
namespace Info {
|
||||
|
||||
class ContentMemento;
|
||||
|
@ -115,6 +119,9 @@ public:
|
|||
: _peerId(peerId)
|
||||
, _migratedPeerId(migratedPeerId) {
|
||||
}
|
||||
ContentMemento(not_null<Data::Feed*> feed)
|
||||
: _feed(feed) {
|
||||
}
|
||||
|
||||
virtual object_ptr<ContentWidget> createWidget(
|
||||
QWidget *parent,
|
||||
|
@ -127,6 +134,9 @@ public:
|
|||
PeerId migratedPeerId() const {
|
||||
return _migratedPeerId;
|
||||
}
|
||||
Data::Feed *feed() const {
|
||||
return _feed;
|
||||
}
|
||||
|
||||
virtual Section section() const = 0;
|
||||
|
||||
|
@ -160,6 +170,7 @@ public:
|
|||
private:
|
||||
const PeerId _peerId = 0;
|
||||
const PeerId _migratedPeerId = 0;
|
||||
Data::Feed * const _feed = nullptr;
|
||||
int _scrollTop = 0;
|
||||
QString _searchFieldQuery;
|
||||
bool _searchEnabledByContent = false;
|
||||
|
|
|
@ -22,6 +22,7 @@ namespace {
|
|||
|
||||
not_null<PeerData*> CorrectPeer(PeerId peerId) {
|
||||
Expects(peerId != 0);
|
||||
|
||||
auto result = App::peer(peerId);
|
||||
if (auto to = result->migrateTo()) {
|
||||
return to;
|
||||
|
@ -31,6 +32,26 @@ not_null<PeerData*> CorrectPeer(PeerId peerId) {
|
|||
|
||||
} // namespace
|
||||
|
||||
Key::Key(not_null<PeerData*> peer) : _value(peer) {
|
||||
}
|
||||
|
||||
Key::Key(not_null<Data::Feed*> feed) : _value(feed) {
|
||||
}
|
||||
|
||||
PeerData *Key::peer() const {
|
||||
if (const auto peer = base::get_if<not_null<PeerData*>>(&_value)) {
|
||||
return *peer;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Data::Feed *Key::feed() const {
|
||||
if (const auto feed = base::get_if<not_null<Data::Feed*>>(&_value)) {
|
||||
return *feed;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
rpl::producer<SparseIdsMergedSlice> AbstractController::mediaSource(
|
||||
SparseIdsMergedSlice::UniversalMsgId aroundId,
|
||||
int limitBefore,
|
||||
|
@ -67,7 +88,9 @@ Controller::Controller(
|
|||
not_null<ContentMemento*> memento)
|
||||
: AbstractController(window)
|
||||
, _widget(widget)
|
||||
, _peer(App::peer(memento->peerId()))
|
||||
, _key(memento->peerId()
|
||||
? Key(App::peer(memento->peerId()))
|
||||
: Key(memento->feed()))
|
||||
, _migrated(memento->migratedPeerId()
|
||||
? App::peer(memento->migratedPeerId())
|
||||
: nullptr)
|
||||
|
@ -77,20 +100,20 @@ Controller::Controller(
|
|||
}
|
||||
|
||||
void Controller::setupMigrationViewer() {
|
||||
if (!_peer->isChat() && (!_peer->isChannel() || _migrated != nullptr)) {
|
||||
const auto peer = _key.peer();
|
||||
if (!peer || (!peer->isChat() && !peer->isChannel()) || _migrated) {
|
||||
return;
|
||||
}
|
||||
Notify::PeerUpdateValue(
|
||||
_peer,
|
||||
peer,
|
||||
Notify::PeerUpdate::Flag::MigrationChanged
|
||||
) | rpl::start_with_next([this] {
|
||||
if (_peer->migrateTo() || (_peer->migrateFrom() != _migrated)) {
|
||||
auto window = parentController();
|
||||
auto peerId = _peer->id;
|
||||
auto section = _section;
|
||||
) | rpl::start_with_next([=] {
|
||||
if (peer->migrateTo() || (peer->migrateFrom() != _migrated)) {
|
||||
const auto window = parentController();
|
||||
const auto section = _section;
|
||||
InvokeQueued(_widget, [=] {
|
||||
window->showSection(
|
||||
Memento(peerId, section),
|
||||
Memento(peer->id, section),
|
||||
Window::SectionShow(
|
||||
Window::SectionShow::Way::Backward,
|
||||
anim::type::instant,
|
||||
|
@ -111,7 +134,8 @@ rpl::producer<Wrap> Controller::wrapValue() const {
|
|||
bool Controller::validateMementoPeer(
|
||||
not_null<ContentMemento*> memento) const {
|
||||
return memento->peerId() == peerId()
|
||||
&& memento->migratedPeerId() == migratedPeerId();
|
||||
&& memento->migratedPeerId() == migratedPeerId()
|
||||
&& memento->feed() == feed();
|
||||
}
|
||||
|
||||
void Controller::setSection(not_null<ContentMemento*> memento) {
|
||||
|
@ -193,9 +217,11 @@ void Controller::showBackFromStack(const Window::SectionShow ¶ms) {
|
|||
|
||||
auto Controller::produceSearchQuery(
|
||||
const QString &query) const -> SearchQuery {
|
||||
Expects(_key.peer() != nullptr);
|
||||
|
||||
auto result = SearchQuery();
|
||||
result.type = _section.mediaType();
|
||||
result.peerId = _peer->id;
|
||||
result.peerId = _key.peer()->id;
|
||||
result.query = query;
|
||||
result.migratedPeerId = _migrated ? _migrated->id : PeerId(0);
|
||||
return result;
|
||||
|
|
|
@ -17,6 +17,19 @@ class SearchFieldController;
|
|||
|
||||
namespace Info {
|
||||
|
||||
class Key {
|
||||
public:
|
||||
Key(not_null<PeerData*> peer);
|
||||
Key(not_null<Data::Feed*> feed);
|
||||
|
||||
PeerData *peer() const;
|
||||
Data::Feed *feed() const;
|
||||
|
||||
private:
|
||||
base::variant<not_null<PeerData*>, not_null<Data::Feed*>> _value;
|
||||
|
||||
};
|
||||
|
||||
enum class Wrap;
|
||||
class WrapWidget;
|
||||
class Memento;
|
||||
|
@ -60,12 +73,15 @@ public:
|
|||
: _parent(parent) {
|
||||
}
|
||||
|
||||
virtual not_null<PeerData*> peer() const = 0;
|
||||
virtual Key key() const = 0;
|
||||
virtual PeerData *migrated() const = 0;
|
||||
virtual Section section() const = 0;
|
||||
|
||||
PeerId peerId() const {
|
||||
return peer()->id;
|
||||
if (const auto peer = key().peer()) {
|
||||
return peer->id;
|
||||
}
|
||||
return PeerId(0);
|
||||
}
|
||||
PeerId migratedPeerId() const {
|
||||
if (auto peer = migrated()) {
|
||||
|
@ -73,6 +89,9 @@ public:
|
|||
}
|
||||
return PeerId(0);
|
||||
}
|
||||
Data::Feed *feed() const {
|
||||
return key().feed();
|
||||
}
|
||||
|
||||
virtual void setSearchEnabledByContent(bool enabled) {
|
||||
}
|
||||
|
@ -103,8 +122,8 @@ public:
|
|||
not_null<Window::Controller*> window,
|
||||
not_null<ContentMemento*> memento);
|
||||
|
||||
not_null<PeerData*> peer() const override {
|
||||
return _peer;
|
||||
Key key() const override {
|
||||
return _key;
|
||||
}
|
||||
PeerData *migrated() const override {
|
||||
return _migrated;
|
||||
|
@ -158,7 +177,7 @@ private:
|
|||
void setupMigrationViewer();
|
||||
|
||||
not_null<WrapWidget*> _widget;
|
||||
not_null<PeerData*> _peer;
|
||||
Key _key;
|
||||
PeerData *_migrated = nullptr;
|
||||
rpl::variable<Wrap> _wrap;
|
||||
Section _section;
|
||||
|
|
|
@ -8,10 +8,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "info/info_memento.h"
|
||||
|
||||
#include "info/profile/info_profile_widget.h"
|
||||
#include "info/profile/info_profile_members.h"
|
||||
#include "info/media/info_media_widget.h"
|
||||
#include "info/members/info_members_widget.h"
|
||||
#include "info/common_groups/info_common_groups_widget.h"
|
||||
#include "info/feed/info_feed_profile_widget.h"
|
||||
#include "info/info_section_widget.h"
|
||||
#include "info/info_layer_widget.h"
|
||||
#include "info/info_controller.h"
|
||||
|
@ -27,6 +27,10 @@ Memento::Memento(PeerId peerId, Section section)
|
|||
: Memento(DefaultStack(peerId, section)) {
|
||||
}
|
||||
|
||||
Memento::Memento(not_null<Data::Feed*> feed, Section section)
|
||||
: Memento(DefaultStack(feed, section)) {
|
||||
}
|
||||
|
||||
Memento::Memento(std::vector<std::unique_ptr<ContentMemento>> stack)
|
||||
: _stack(std::move(stack)) {
|
||||
}
|
||||
|
@ -39,14 +43,28 @@ std::vector<std::unique_ptr<ContentMemento>> Memento::DefaultStack(
|
|||
return result;
|
||||
}
|
||||
|
||||
Section Memento::DefaultSection(not_null<PeerData*> peer) {
|
||||
return peer->isSelf()
|
||||
? Section(Section::MediaType::Photo)
|
||||
: Section(Section::Type::Profile);
|
||||
std::vector<std::unique_ptr<ContentMemento>> Memento::DefaultStack(
|
||||
not_null<Data::Feed*> feed,
|
||||
Section section) {
|
||||
auto result = std::vector<std::unique_ptr<ContentMemento>>();
|
||||
result.push_back(DefaultContent(feed, section));
|
||||
return result;
|
||||
}
|
||||
|
||||
Memento Memento::Default(not_null<PeerData*> peer) {
|
||||
return Memento(peer->id, DefaultSection(peer));
|
||||
Section Memento::DefaultSection(Dialogs::Key key) {
|
||||
if (const auto peer = key.peer()) {
|
||||
if (peer->isSelf()) {
|
||||
return Section(Section::MediaType::Photo);
|
||||
}
|
||||
}
|
||||
return Section(Section::Type::Profile);
|
||||
}
|
||||
|
||||
Memento Memento::Default(Dialogs::Key key) {
|
||||
if (const auto peer = key.peer()) {
|
||||
return Memento(peer->id, DefaultSection(key));
|
||||
}
|
||||
return Memento(key.feed(), DefaultSection(key));
|
||||
}
|
||||
|
||||
std::unique_ptr<ContentMemento> Memento::DefaultContent(
|
||||
|
@ -84,6 +102,16 @@ std::unique_ptr<ContentMemento> Memento::DefaultContent(
|
|||
Unexpected("Wrong section type in Info::Memento::DefaultContent()");
|
||||
}
|
||||
|
||||
std::unique_ptr<ContentMemento> Memento::DefaultContent(
|
||||
not_null<Data::Feed*> feed,
|
||||
Section section) {
|
||||
switch (section.type()) {
|
||||
case Section::Type::Profile:
|
||||
return std::make_unique<FeedProfile::Memento>(feed);
|
||||
}
|
||||
Unexpected("Wrong feed section in Info::Memento::DefaultContent()");
|
||||
}
|
||||
|
||||
object_ptr<Window::SectionWidget> Memento::createWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::Controller*> controller,
|
||||
|
|
|
@ -9,12 +9,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
#include "ui/rp_widget.h"
|
||||
#include "info/info_wrap_widget.h"
|
||||
#include "dialogs/dialogs_key.h"
|
||||
#include "window/section_memento.h"
|
||||
|
||||
namespace Storage {
|
||||
enum class SharedMediaType : char;
|
||||
} // namespace Storage
|
||||
|
||||
namespace Data {
|
||||
class Feed;
|
||||
} // namespace Data
|
||||
|
||||
namespace Ui {
|
||||
class ScrollArea;
|
||||
struct ScrollToRequest;
|
||||
|
@ -29,6 +34,7 @@ class Memento final : public Window::SectionMemento {
|
|||
public:
|
||||
Memento(PeerId peerId);
|
||||
Memento(PeerId peerId, Section section);
|
||||
Memento(not_null<Data::Feed*> feed, Section section);
|
||||
Memento(std::vector<std::unique_ptr<ContentMemento>> stack);
|
||||
|
||||
object_ptr<Window::SectionWidget> createWidget(
|
||||
|
@ -51,8 +57,8 @@ public:
|
|||
return _stack.back().get();
|
||||
}
|
||||
|
||||
static Section DefaultSection(not_null<PeerData*> peer);
|
||||
static Memento Default(not_null<PeerData*> peer);
|
||||
static Section DefaultSection(Dialogs::Key key);
|
||||
static Memento Default(Dialogs::Key key);
|
||||
|
||||
~Memento();
|
||||
|
||||
|
@ -60,6 +66,13 @@ private:
|
|||
static std::vector<std::unique_ptr<ContentMemento>> DefaultStack(
|
||||
PeerId peerId,
|
||||
Section section);
|
||||
static std::vector<std::unique_ptr<ContentMemento>> DefaultStack(
|
||||
not_null<Data::Feed*> feed,
|
||||
Section section);
|
||||
static std::unique_ptr<ContentMemento> DefaultContent(
|
||||
not_null<Data::Feed*> feed,
|
||||
Section section);
|
||||
|
||||
static std::unique_ptr<ContentMemento> DefaultContent(
|
||||
PeerId peerId,
|
||||
Section section);
|
||||
|
|
|
@ -527,12 +527,16 @@ void TopBar::performDelete() {
|
|||
|
||||
rpl::producer<QString> TitleValue(
|
||||
const Section §ion,
|
||||
not_null<PeerData*> peer,
|
||||
Key key,
|
||||
bool isStackBottom) {
|
||||
return Lang::Viewer([&] {
|
||||
const auto peer = key.peer();
|
||||
|
||||
switch (section.type()) {
|
||||
case Section::Type::Profile:
|
||||
if (auto user = peer->asUser()) {
|
||||
if (const auto feed = key.feed()) {
|
||||
return lng_info_feed_title;
|
||||
} else if (auto user = peer->asUser()) {
|
||||
return user->botInfo
|
||||
? lng_info_bot_title
|
||||
: lng_info_user_title;
|
||||
|
|
|
@ -26,11 +26,12 @@ class LabelWithNumbers;
|
|||
|
||||
namespace Info {
|
||||
|
||||
class Key;
|
||||
class Section;
|
||||
|
||||
rpl::producer<QString> TitleValue(
|
||||
const Section §ion,
|
||||
not_null<PeerData*> peer,
|
||||
Key key,
|
||||
bool isStackBottom);
|
||||
|
||||
class TopBar : public Ui::RpWidget {
|
||||
|
|
|
@ -11,7 +11,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include <rpl/take.h>
|
||||
#include <rpl/combine.h>
|
||||
#include "info/profile/info_profile_widget.h"
|
||||
#include "info/profile/info_profile_members.h"
|
||||
#include "info/profile/info_profile_values.h"
|
||||
#include "info/media/info_media_widget.h"
|
||||
#include "info/info_content_widget.h"
|
||||
|
@ -119,7 +118,7 @@ void WrapWidget::injectActiveProfile(Dialogs::Key key) {
|
|||
if (const auto peer = key.peer()) {
|
||||
injectActivePeerProfile(peer);
|
||||
} else if (const auto feed = key.feed()) {
|
||||
// #TODO feed profile
|
||||
injectActiveFeedProfile(feed);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -147,12 +146,34 @@ void WrapWidget::injectActivePeerProfile(not_null<PeerData*> peer) {
|
|||
if (firstSectionType != expectedType
|
||||
|| firstSectionMediaType != expectedMediaType
|
||||
|| firstPeerId != peer->id) {
|
||||
auto injected = StackItem();
|
||||
auto section = peer->isSelf()
|
||||
? Section(Section::MediaType::Photo)
|
||||
: Section(Section::Type::Profile);
|
||||
injected.section = std::move(
|
||||
Memento(peer->id, section).takeStack().front());
|
||||
injectActiveProfileMemento(std::move(
|
||||
Memento(peer->id, section).takeStack().front()));
|
||||
}
|
||||
}
|
||||
|
||||
void WrapWidget::injectActiveFeedProfile(not_null<Data::Feed*> feed) {
|
||||
const auto firstFeed = hasStackHistory()
|
||||
? _historyStack.front().section->feed()
|
||||
: _controller->feed();
|
||||
const auto firstSectionType = hasStackHistory()
|
||||
? _historyStack.front().section->section().type()
|
||||
: _controller->section().type();
|
||||
const auto expectedType = Section::Type::Profile;
|
||||
if (firstSectionType != expectedType
|
||||
|| firstFeed != feed) {
|
||||
auto section = Section(Section::Type::Profile);
|
||||
injectActiveProfileMemento(std::move(
|
||||
Memento(feed, section).takeStack().front()));
|
||||
}
|
||||
}
|
||||
|
||||
void WrapWidget::injectActiveProfileMemento(
|
||||
std::unique_ptr<ContentMemento> memento) {
|
||||
auto injected = StackItem();
|
||||
injected.section = std::move(memento);
|
||||
_historyStack.insert(
|
||||
_historyStack.begin(),
|
||||
std::move(injected));
|
||||
|
@ -160,7 +181,6 @@ void WrapWidget::injectActivePeerProfile(not_null<PeerData*> peer) {
|
|||
setupTop();
|
||||
finishShowContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Controller> WrapWidget::createController(
|
||||
|
@ -173,12 +193,17 @@ std::unique_ptr<Controller> WrapWidget::createController(
|
|||
return result;
|
||||
}
|
||||
|
||||
not_null<PeerData*> WrapWidget::peer() const {
|
||||
return _controller->peer();
|
||||
Key WrapWidget::key() const {
|
||||
return _controller->key();
|
||||
}
|
||||
|
||||
Dialogs::RowDescriptor WrapWidget::activeChat() const {
|
||||
return Dialogs::RowDescriptor(App::history(peer()), MsgId(0));
|
||||
if (const auto peer = key().peer()) {
|
||||
return Dialogs::RowDescriptor(App::history(peer), MsgId(0));
|
||||
} else if (const auto feed = key().feed()) {
|
||||
return Dialogs::RowDescriptor(feed, MsgId(0));
|
||||
}
|
||||
Unexpected("Owner in WrapWidget::activeChat().");
|
||||
}
|
||||
|
||||
// This was done for tabs support.
|
||||
|
@ -320,7 +345,7 @@ void WrapWidget::createTopBar() {
|
|||
|
||||
_topBar->setTitle(TitleValue(
|
||||
_controller->section(),
|
||||
_controller->peer(),
|
||||
_controller->key(),
|
||||
!hasStackHistory()));
|
||||
if (wrapValue == Wrap::Narrow || hasStackHistory()) {
|
||||
_topBar->enableBackButton();
|
||||
|
@ -383,7 +408,8 @@ void WrapWidget::addProfileMenuButton() {
|
|||
void WrapWidget::addProfileCallsButton() {
|
||||
Expects(_topBar != nullptr);
|
||||
|
||||
const auto user = _controller->peer()->asUser();
|
||||
const auto peer = key().peer();
|
||||
const auto user = peer ? peer->asUser() : nullptr;
|
||||
if (!user || user->isSelf() || !Global::PhoneCallsEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
@ -415,7 +441,10 @@ void WrapWidget::addProfileCallsButton() {
|
|||
void WrapWidget::addProfileNotificationsButton() {
|
||||
Expects(_topBar != nullptr);
|
||||
|
||||
const auto peer = _controller->peer();
|
||||
const auto peer = key().peer();
|
||||
if (!peer) {
|
||||
return;
|
||||
}
|
||||
auto notifications = _topBar->addButton(
|
||||
base::make_unique_q<Ui::IconButton>(
|
||||
_topBar,
|
||||
|
@ -468,9 +497,14 @@ void WrapWidget::showProfileMenu() {
|
|||
});
|
||||
_topBarMenuToggle->installEventFilter(_topBarMenu.get());
|
||||
|
||||
// #TODO feeds menu
|
||||
const auto peer = key().peer();
|
||||
if (!peer) {
|
||||
return;
|
||||
}
|
||||
Window::FillPeerMenu(
|
||||
_controller->parentController(),
|
||||
_controller->peer(),
|
||||
peer,
|
||||
[this](const QString &text, base::lambda<void()> callback) {
|
||||
return _topBarMenu->addAction(text, std::move(callback));
|
||||
},
|
||||
|
|
|
@ -15,6 +15,10 @@ namespace Storage {
|
|||
enum class SharedMediaType : char;
|
||||
} // namespace Storage
|
||||
|
||||
namespace Data {
|
||||
class Feed;
|
||||
} // namespace Data
|
||||
|
||||
namespace Ui {
|
||||
class SettingsSlider;
|
||||
class FadeShadow;
|
||||
|
@ -36,6 +40,7 @@ namespace Media {
|
|||
class Widget;
|
||||
} // namespace Media
|
||||
|
||||
class Key;
|
||||
class Controller;
|
||||
class Section;
|
||||
class Memento;
|
||||
|
@ -77,7 +82,7 @@ public:
|
|||
Wrap wrap,
|
||||
not_null<Memento*> memento);
|
||||
|
||||
not_null<PeerData*> peer() const;
|
||||
Key key() const;
|
||||
Dialogs::RowDescriptor activeChat() const override;
|
||||
Wrap wrap() const {
|
||||
return _wrap.current();
|
||||
|
@ -140,6 +145,9 @@ private:
|
|||
void startInjectingActivePeerProfiles();
|
||||
void injectActiveProfile(Dialogs::Key key);
|
||||
void injectActivePeerProfile(not_null<PeerData*> peer);
|
||||
void injectActiveFeedProfile(not_null<Data::Feed*> feed);
|
||||
void injectActiveProfileMemento(
|
||||
std::unique_ptr<ContentMemento> memento);
|
||||
void restoreHistoryStack(
|
||||
std::vector<std::unique_ptr<ContentMemento>> stack);
|
||||
bool hasStackHistory() const {
|
||||
|
|
|
@ -42,7 +42,7 @@ InnerWidget::InnerWidget(
|
|||
// Was done for top level tabs support.
|
||||
// Now used for shared media in Saved Messages.
|
||||
void InnerWidget::setupOtherTypes() {
|
||||
if (_controller->peer()->isSelf() && _isStackBottom) {
|
||||
if (_controller->key().peer()->isSelf() && _isStackBottom) {
|
||||
createOtherTypes();
|
||||
} else {
|
||||
_otherTypes.destroy();
|
||||
|
@ -95,7 +95,7 @@ void InnerWidget::createTypeButtons() {
|
|||
auto result = AddButton(
|
||||
content,
|
||||
_controller,
|
||||
_controller->peer(),
|
||||
_controller->key().peer(),
|
||||
_controller->migrated(),
|
||||
buttonType,
|
||||
tracker);
|
||||
|
@ -123,7 +123,7 @@ void InnerWidget::createTypeButtons() {
|
|||
addMediaButton(Type::File, st::infoIconMediaFile);
|
||||
addMediaButton(Type::MusicFile, st::infoIconMediaAudio);
|
||||
addMediaButton(Type::Link, st::infoIconMediaLink);
|
||||
if (auto user = _controller->peer()->asUser()) {
|
||||
if (auto user = _controller->key().peer()->asUser()) {
|
||||
// addCommonGroupsButton(user, st::infoIconMediaGroup);
|
||||
}
|
||||
addMediaButton(Type::VoiceFile, st::infoIconMediaVoice);
|
||||
|
|
|
@ -541,7 +541,7 @@ ListWidget::ListWidget(
|
|||
not_null<AbstractController*> controller)
|
||||
: RpWidget(parent)
|
||||
, _controller(controller)
|
||||
, _peer(_controller->peer())
|
||||
, _peer(_controller->key().peer())
|
||||
, _migrated(_controller->migrated())
|
||||
, _type(_controller->section().mediaType())
|
||||
, _slice(sliceKey(_universalAroundId)) {
|
||||
|
|
|
@ -21,6 +21,10 @@ Memento::Memento(not_null<Controller*> controller)
|
|||
controller->migratedPeerId()) {
|
||||
}
|
||||
|
||||
Memento::Memento(PeerId peerId, PeerId migratedPeerId)
|
||||
: ContentMemento(peerId, migratedPeerId) {
|
||||
}
|
||||
|
||||
Section Memento::section() const {
|
||||
return Section(Section::Type::Members);
|
||||
}
|
||||
|
@ -52,8 +56,7 @@ Widget::Widget(
|
|||
: ContentWidget(parent, controller) {
|
||||
_inner = setInnerWidget(object_ptr<Profile::Members>(
|
||||
this,
|
||||
controller,
|
||||
controller->peer()));
|
||||
controller));
|
||||
}
|
||||
|
||||
bool Widget::showInternal(not_null<ContentMemento*> memento) {
|
||||
|
|
|
@ -25,9 +25,7 @@ using SavedState = Profile::MembersState;
|
|||
class Memento final : public ContentMemento {
|
||||
public:
|
||||
Memento(not_null<Controller*> controller);
|
||||
Memento(PeerId peerId, PeerId migratedPeerId)
|
||||
: ContentMemento(peerId, migratedPeerId) {
|
||||
}
|
||||
Memento(PeerId peerId, PeerId migratedPeerId);
|
||||
|
||||
object_ptr<ContentWidget> createWidget(
|
||||
QWidget *parent,
|
||||
|
|
|
@ -212,15 +212,14 @@ int SectionWithToggle::toggleSkip() const {
|
|||
|
||||
Cover::Cover(
|
||||
QWidget *parent,
|
||||
not_null<Controller*> controller,
|
||||
not_null<PeerData*> peer)
|
||||
not_null<Controller*> controller)
|
||||
: SectionWithToggle(
|
||||
parent,
|
||||
st::infoProfilePhotoTop
|
||||
+ st::infoProfilePhoto.size.height()
|
||||
+ st::infoProfilePhotoBottom)
|
||||
, _controller(controller)
|
||||
, _peer(peer)
|
||||
, _peer(_controller->key().peer())
|
||||
, _userpic(
|
||||
this,
|
||||
controller->parentController(),
|
||||
|
|
|
@ -52,8 +52,7 @@ class Cover : public SectionWithToggle {
|
|||
public:
|
||||
Cover(
|
||||
QWidget *parent,
|
||||
not_null<Controller*> controller,
|
||||
not_null<PeerData*> peer);
|
||||
not_null<Controller*> controller);
|
||||
|
||||
Cover *setOnlineCount(rpl::producer<int> &&count);
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ InnerWidget::InnerWidget(
|
|||
not_null<Controller*> controller)
|
||||
: RpWidget(parent)
|
||||
, _controller(controller)
|
||||
, _peer(_controller->peer())
|
||||
, _peer(_controller->key().peer())
|
||||
, _migrated(_controller->migrated())
|
||||
, _content(setupContent(this)) {
|
||||
_content->heightValue(
|
||||
|
@ -77,8 +77,7 @@ object_ptr<Ui::RpWidget> InnerWidget::setupContent(
|
|||
auto result = object_ptr<Ui::VerticalLayout>(parent);
|
||||
_cover = result->add(object_ptr<Cover>(
|
||||
result,
|
||||
_controller,
|
||||
_peer));
|
||||
_controller));
|
||||
_cover->setOnlineCount(rpl::single(0));
|
||||
auto details = SetupDetails(_controller, parent, _peer);
|
||||
if (canHideDetailsEver()) {
|
||||
|
@ -106,9 +105,7 @@ object_ptr<Ui::RpWidget> InnerWidget::setupContent(
|
|||
if (_peer->isChat() || _peer->isMegagroup()) {
|
||||
_members = result->add(object_ptr<Members>(
|
||||
result,
|
||||
_controller,
|
||||
_peer)
|
||||
);
|
||||
_controller));
|
||||
_members->scrollToRequests(
|
||||
) | rpl::start_with_next([this](Ui::ScrollToRequest request) {
|
||||
auto min = (request.ymin < 0)
|
||||
|
|
|
@ -41,11 +41,10 @@ constexpr auto kEnableSearchMembersAfterCount = 20;
|
|||
|
||||
Members::Members(
|
||||
QWidget *parent,
|
||||
not_null<Controller*> controller,
|
||||
not_null<PeerData*> peer)
|
||||
not_null<Controller*> controller)
|
||||
: RpWidget(parent)
|
||||
, _controller(controller)
|
||||
, _peer(peer)
|
||||
, _peer(_controller->key().peer())
|
||||
, _listController(CreateMembersController(controller, _peer)) {
|
||||
setupHeader();
|
||||
setupList();
|
||||
|
|
|
@ -20,7 +20,6 @@ class AbstractButton;
|
|||
} // namespace Ui
|
||||
|
||||
namespace Profile {
|
||||
class GroupMembersWidget;
|
||||
class ParticipantsBoxController;
|
||||
} // namespace Profile
|
||||
|
||||
|
@ -44,8 +43,7 @@ class Members
|
|||
public:
|
||||
Members(
|
||||
QWidget *parent,
|
||||
not_null<Controller*> controller,
|
||||
not_null<PeerData*> peer);
|
||||
not_null<Controller*> controller);
|
||||
|
||||
rpl::producer<Ui::ScrollToRequest> scrollToRequests() const;
|
||||
|
||||
|
|
|
@ -21,6 +21,10 @@ Memento::Memento(not_null<Controller*> controller)
|
|||
controller->migratedPeerId()) {
|
||||
}
|
||||
|
||||
Memento::Memento(PeerId peerId, PeerId migratedPeerId)
|
||||
: ContentMemento(peerId, migratedPeerId) {
|
||||
}
|
||||
|
||||
Section Memento::section() const {
|
||||
return Section(Section::Type::Profile);
|
||||
}
|
||||
|
|
|
@ -19,9 +19,7 @@ struct MembersState;
|
|||
class Memento final : public ContentMemento {
|
||||
public:
|
||||
Memento(not_null<Controller*> controller);
|
||||
Memento(PeerId peerId, PeerId migratedPeerId)
|
||||
: ContentMemento(peerId, migratedPeerId) {
|
||||
}
|
||||
Memento(PeerId peerId, PeerId migratedPeerId);
|
||||
|
||||
object_ptr<ContentWidget> createWidget(
|
||||
QWidget *parent,
|
||||
|
@ -43,7 +41,6 @@ public:
|
|||
|
||||
private:
|
||||
bool _infoExpanded = true;
|
||||
base::optional<QString> _membersSearch;
|
||||
std::unique_ptr<MembersState> _membersState;
|
||||
|
||||
};
|
||||
|
|
|
@ -3009,7 +3009,11 @@ void MainWidget::updateControlsGeometry() {
|
|||
if (Auth().settings().tabbedSelectorSectionEnabled()) {
|
||||
_history->pushTabbedSelectorToThirdSection(params);
|
||||
} else if (Auth().settings().thirdSectionInfoEnabled()) {
|
||||
_history->pushInfoToThirdSection(params);
|
||||
if (const auto key = _controller->activeChatCurrent()) {
|
||||
_controller->showSection(
|
||||
Info::Memento::Default(key),
|
||||
params.withThirdColumn());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -3206,12 +3210,13 @@ auto MainWidget::thirdSectionForCurrentMainSection(
|
|||
} else if (const auto peer = key.peer()) {
|
||||
return std::make_unique<Info::Memento>(
|
||||
peer->id,
|
||||
Info::Memento::DefaultSection(peer));
|
||||
} else {
|
||||
Info::Memento::DefaultSection(key));
|
||||
} else if (const auto feed = key.feed()) {
|
||||
return std::make_unique<Info::Memento>(
|
||||
App::self()->id,
|
||||
Info::Memento::DefaultSection(App::self()));
|
||||
feed,
|
||||
Info::Memento::DefaultSection(key));
|
||||
}
|
||||
Unexpected("Key in MainWidget::thirdSectionForCurrentMainSection().");
|
||||
}
|
||||
|
||||
void MainWidget::updateThirdColumnToCurrentChat(
|
||||
|
|
|
@ -355,8 +355,8 @@ void Panel::setCloseCallback(ButtonCallback &&callback) {
|
|||
}
|
||||
}
|
||||
|
||||
not_null<PeerData*> Panel::peer() const {
|
||||
return _listPeer;
|
||||
Info::Key Panel::key() const {
|
||||
return Info::Key(_listPeer);
|
||||
}
|
||||
|
||||
PeerData *Panel::migrated() const {
|
||||
|
|
|
@ -57,7 +57,7 @@ protected:
|
|||
|
||||
private:
|
||||
// Info::AbstractController implementation.
|
||||
not_null<PeerData*> peer() const override;
|
||||
Info::Key key() const override;
|
||||
PeerData *migrated() const override;
|
||||
Info::Section section() const override;
|
||||
|
||||
|
|
|
@ -284,6 +284,14 @@
|
|||
<(src_loc)/info/common_groups/info_common_groups_inner_widget.h
|
||||
<(src_loc)/info/common_groups/info_common_groups_widget.cpp
|
||||
<(src_loc)/info/common_groups/info_common_groups_widget.h
|
||||
<(src_loc)/info/feed/info_feed_channels.cpp
|
||||
<(src_loc)/info/feed/info_feed_channels.h
|
||||
<(src_loc)/info/feed/info_feed_cover.cpp
|
||||
<(src_loc)/info/feed/info_feed_cover.h
|
||||
<(src_loc)/info/feed/info_feed_profile_inner_widget.cpp
|
||||
<(src_loc)/info/feed/info_feed_profile_inner_widget.h
|
||||
<(src_loc)/info/feed/info_feed_profile_widget.cpp
|
||||
<(src_loc)/info/feed/info_feed_profile_widget.h
|
||||
<(src_loc)/info/media/info_media_buttons.h
|
||||
<(src_loc)/info/media/info_media_empty_widget.cpp
|
||||
<(src_loc)/info/media/info_media_empty_widget.h
|
||||
|
|
Loading…
Add table
Reference in a new issue