mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-01-20 22:41:11 +00:00
Display feed channels list in feed info.
This commit is contained in:
parent
a144e35f84
commit
99c686e3e1
@ -1429,6 +1429,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_feed_channels#other" = "{count} channels";
|
||||
|
||||
"lng_info_feed_title" = "Feed Info";
|
||||
"lng_info_feed_is_default" = "Group new channels";
|
||||
"lng_info_feed_channels" = "Channels";
|
||||
|
||||
// Wnd specific
|
||||
|
||||
|
@ -7,8 +7,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "info/feed/info_feed_channels.h"
|
||||
|
||||
#include "info/feed/info_feed_channels_controllers.h"
|
||||
#include "info/profile/info_profile_icon.h"
|
||||
#include "info/profile/info_profile_button.h"
|
||||
#include "info/profile/info_profile_values.h"
|
||||
#include "info/info_controller.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
@ -16,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/wrap/padding_wrap.h"
|
||||
#include "ui/search_field_controller.h"
|
||||
#include "boxes/peer_list_controllers.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_info.h"
|
||||
|
||||
@ -33,7 +36,7 @@ Channels::Channels(
|
||||
: RpWidget(parent)
|
||||
, _controller(controller)
|
||||
, _feed(_controller->key().feed())
|
||||
, _listController(std::make_unique<ContactsBoxController>()) {
|
||||
, _listController(std::make_unique<ChannelsController>(_controller)) {
|
||||
setupHeader();
|
||||
setupList();
|
||||
setContent(_list.data());
|
||||
@ -44,12 +47,12 @@ Channels::Channels(
|
||||
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());
|
||||
Profile::FeedChannelsCountValue(
|
||||
_feed
|
||||
) | rpl::start_with_next([this](int count) {
|
||||
const auto enabled = (count >= kEnableSearchChannelsAfterCount);
|
||||
_controller->setSearchEnabledByContent(enabled);
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
int Channels::desiredHeight() const {
|
||||
@ -122,12 +125,11 @@ void Channels::setupHeader() {
|
||||
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(),
|
||||
Profile::FeedChannelsCountValue(
|
||||
_feed
|
||||
) | rpl::map([](int count) {
|
||||
return lng_feed_channels(lt_count, count);
|
||||
}) | Profile::ToUpperValue(),
|
||||
st::infoBlockHeaderLabel);
|
||||
result->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
return result;
|
||||
|
@ -0,0 +1,110 @@
|
||||
/*
|
||||
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_controllers.h"
|
||||
|
||||
#include "data/data_feed.h"
|
||||
#include "data/data_session.h"
|
||||
#include "info/info_controller.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "auth_session.h"
|
||||
#include "history/history.h"
|
||||
|
||||
namespace Info {
|
||||
namespace FeedProfile {
|
||||
|
||||
ChannelsController::ChannelsController(not_null<Controller*> controller)
|
||||
: PeerListController()
|
||||
, _controller(controller)
|
||||
, _feed(_controller->key().feed()) {
|
||||
_controller->setSearchEnabledByContent(false);
|
||||
}
|
||||
|
||||
std::unique_ptr<PeerListRow> ChannelsController::createRow(
|
||||
not_null<PeerData*> peer) {
|
||||
auto result = std::make_unique<PeerListRow>(peer);
|
||||
result->setCustomStatus(QString());
|
||||
return result;
|
||||
}
|
||||
|
||||
std::unique_ptr<PeerListRow> ChannelsController::createRestoredRow(
|
||||
not_null<PeerData*> peer) {
|
||||
return createRow(peer);
|
||||
}
|
||||
|
||||
void ChannelsController::prepare() {
|
||||
setSearchNoResultsText(lang(lng_bot_groups_not_found));
|
||||
delegate()->peerListSetSearchMode(PeerListSearchMode::Enabled);
|
||||
delegate()->peerListSetTitle(langFactory(lng_info_feed_channels));
|
||||
|
||||
rebuildRows();
|
||||
using Flag = Data::FeedUpdateFlag;
|
||||
rpl::single(
|
||||
Data::FeedUpdate{ _feed, Flag::Channels }
|
||||
) | rpl::then(
|
||||
Auth().data().feedUpdated()
|
||||
) | rpl::filter([=](const Data::FeedUpdate &update) {
|
||||
return (update.feed == _feed) && (update.flag == Flag::Channels);
|
||||
}) | rpl::filter([=] {
|
||||
return _feed->channelsLoaded();
|
||||
}) | rpl::start_with_next([=] {
|
||||
rebuildRows();
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
void ChannelsController::rebuildRows() {
|
||||
if (!_feed->channelsLoaded()) {
|
||||
return;
|
||||
}
|
||||
const auto &channels = _feed->channels();
|
||||
auto count = delegate()->peerListFullRowsCount();
|
||||
for (auto i = 0; i != count;) {
|
||||
const auto row = delegate()->peerListRowAt(i);
|
||||
const auto peer = row->peer();
|
||||
if (ranges::find_if(channels, [=](not_null<History*> history) {
|
||||
return (history->peer == peer);
|
||||
}) != end(channels)) {
|
||||
++i;
|
||||
} else {
|
||||
delegate()->peerListRemoveRow(row);
|
||||
--count;
|
||||
}
|
||||
}
|
||||
for (const auto history : channels) {
|
||||
if (auto row = createRow(history->peer)) {
|
||||
delegate()->peerListAppendRow(std::move(row));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<PeerListState> ChannelsController::saveState() const {
|
||||
auto result = PeerListController::saveState();
|
||||
auto my = std::make_unique<SavedState>();
|
||||
using Flag = Data::FeedUpdateFlag;
|
||||
Auth().data().feedUpdated(
|
||||
) | rpl::filter([=](const Data::FeedUpdate &update) {
|
||||
return (update.feed == _feed) && (update.flag == Flag::Channels);
|
||||
}) | rpl::start_with_next([state = result.get()] {
|
||||
state->controllerState = nullptr;
|
||||
}, my->lifetime);
|
||||
result->controllerState = std::move(my);
|
||||
return result;
|
||||
}
|
||||
|
||||
void ChannelsController::restoreState(
|
||||
std::unique_ptr<PeerListState> state) {
|
||||
PeerListController::restoreState(std::move(state));
|
||||
}
|
||||
|
||||
void ChannelsController::rowClicked(not_null<PeerListRow*> row) {
|
||||
_controller->parentController()->showPeerHistory(
|
||||
row->peer(),
|
||||
Window::SectionShow::Way::Forward);
|
||||
}
|
||||
|
||||
} // namespace FeedProfile
|
||||
} // namespace Info
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
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 "boxes/peer_list_box.h"
|
||||
|
||||
namespace Data {
|
||||
class Feed;
|
||||
} // namespace Data
|
||||
|
||||
namespace Info {
|
||||
|
||||
class Controller;
|
||||
|
||||
namespace FeedProfile {
|
||||
|
||||
class ChannelsController
|
||||
: public PeerListController
|
||||
, private base::Subscriber {
|
||||
public:
|
||||
ChannelsController(not_null<Controller*> controller);
|
||||
|
||||
void prepare() override;
|
||||
void rowClicked(not_null<PeerListRow*> row) override;
|
||||
|
||||
std::unique_ptr<PeerListRow> createRestoredRow(
|
||||
not_null<PeerData*> peer) override;
|
||||
|
||||
std::unique_ptr<PeerListState> saveState() const override;
|
||||
void restoreState(std::unique_ptr<PeerListState> state) override;
|
||||
|
||||
private:
|
||||
struct SavedState : SavedStateBase {
|
||||
rpl::lifetime lifetime;
|
||||
};
|
||||
|
||||
void rebuildRows();
|
||||
std::unique_ptr<PeerListRow> createRow(not_null<PeerData*> peer);
|
||||
|
||||
const not_null<Controller*> _controller;
|
||||
not_null<Data::Feed*> _feed;
|
||||
|
||||
};
|
||||
|
||||
} // namespace FeedProfile
|
||||
} // namespace Info
|
@ -42,6 +42,7 @@ Cover::Cover(
|
||||
_name->setSelectable(true);
|
||||
_name->setContextCopyText(lang(lng_profile_copy_fullname));
|
||||
refreshNameText();
|
||||
refreshStatusText();
|
||||
|
||||
initViewers();
|
||||
setupChildGeometry();
|
||||
@ -62,7 +63,7 @@ void Cover::setupChildGeometry() {
|
||||
void Cover::initViewers() {
|
||||
Auth().data().feedUpdated(
|
||||
) | rpl::filter([](const Data::FeedUpdate &update) {
|
||||
return update.flag == Data::FeedUpdateFlag::Channels;
|
||||
return (update.flag == Data::FeedUpdateFlag::Channels);
|
||||
}) | rpl::start_with_next(
|
||||
[=] { refreshStatusText(); },
|
||||
lifetime());
|
||||
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "info/feed/info_feed_profile_widget.h"
|
||||
#include "info/feed/info_feed_cover.h"
|
||||
#include "info/feed/info_feed_channels.h"
|
||||
#include "info/profile/info_profile_actions.h"
|
||||
#include "ui/widgets/scroll_area.h"
|
||||
#include "ui/wrap/vertical_layout.h"
|
||||
|
||||
@ -39,32 +40,26 @@ object_ptr<Ui::RpWidget> InnerWidget::setupContent(
|
||||
_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));
|
||||
//}
|
||||
auto details = Profile::SetupFeedDetails(_controller, parent, _feed);
|
||||
result->add(std::move(details));
|
||||
result->add(object_ptr<BoxContentDivider>(result));
|
||||
|
||||
//_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());
|
||||
_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);
|
||||
}
|
||||
|
@ -164,6 +164,37 @@ private:
|
||||
|
||||
};
|
||||
|
||||
class FeedDetailsFiller {
|
||||
public:
|
||||
FeedDetailsFiller(
|
||||
not_null<Controller*> controller,
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
not_null<Data::Feed*> feed);
|
||||
|
||||
object_ptr<Ui::RpWidget> fill();
|
||||
|
||||
private:
|
||||
object_ptr<Ui::RpWidget> setupDefaultToggle();
|
||||
|
||||
template <
|
||||
typename Widget,
|
||||
typename = std::enable_if_t<
|
||||
std::is_base_of_v<Ui::RpWidget, Widget>>>
|
||||
Widget *add(
|
||||
object_ptr<Widget> &&child,
|
||||
const style::margins &margin = style::margins()) {
|
||||
return _wrap->add(
|
||||
std::move(child),
|
||||
margin);
|
||||
}
|
||||
|
||||
not_null<Controller*> _controller;
|
||||
not_null<Ui::RpWidget*> _parent;
|
||||
not_null<Data::Feed*> _feed;
|
||||
object_ptr<Ui::VerticalLayout> _wrap;
|
||||
|
||||
};
|
||||
|
||||
DetailsFiller::DetailsFiller(
|
||||
not_null<Controller*> controller,
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
@ -650,6 +681,42 @@ object_ptr<Ui::RpWidget> ActionsFiller::fill() {
|
||||
return { nullptr };
|
||||
}
|
||||
|
||||
FeedDetailsFiller::FeedDetailsFiller(
|
||||
not_null<Controller*> controller,
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
not_null<Data::Feed*> feed)
|
||||
: _controller(controller)
|
||||
, _parent(parent)
|
||||
, _feed(feed)
|
||||
, _wrap(_parent) {
|
||||
}
|
||||
|
||||
object_ptr<Ui::RpWidget> FeedDetailsFiller::fill() {
|
||||
add(object_ptr<BoxContentDivider>(_wrap));
|
||||
add(CreateSkipWidget(_wrap));
|
||||
add(setupDefaultToggle());
|
||||
add(CreateSkipWidget(_wrap));
|
||||
return std::move(_wrap);
|
||||
}
|
||||
|
||||
object_ptr<Ui::RpWidget> FeedDetailsFiller::setupDefaultToggle() {
|
||||
const auto feed = _feed;
|
||||
auto result = object_ptr<Button>(
|
||||
_wrap,
|
||||
Lang::Viewer(lng_info_feed_is_default),
|
||||
st::infoNotificationsButton);
|
||||
result->toggleOn(
|
||||
rpl::single(false)// #TODO default
|
||||
)->addClickHandler([=] {
|
||||
|
||||
});
|
||||
object_ptr<FloatingIcon>(
|
||||
result,
|
||||
st::infoIconNotifications,
|
||||
st::infoNotificationsIconPosition);
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
object_ptr<Ui::RpWidget> SetupDetails(
|
||||
@ -746,5 +813,13 @@ object_ptr<Ui::RpWidget> SetupChannelMembers(
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
object_ptr<Ui::RpWidget> SetupFeedDetails(
|
||||
not_null<Controller*> controller,
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
not_null<Data::Feed*> feed) {
|
||||
FeedDetailsFiller filler(controller, parent, feed);
|
||||
return filler.fill();
|
||||
}
|
||||
|
||||
} // namespace Profile
|
||||
} // namespace Info
|
||||
|
@ -7,9 +7,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace Data {
|
||||
class Feed;
|
||||
} // namespace Data
|
||||
|
||||
namespace Ui {
|
||||
class RpWidget;
|
||||
}
|
||||
} // namespace Ui
|
||||
|
||||
namespace Info {
|
||||
|
||||
@ -32,5 +36,10 @@ object_ptr<Ui::RpWidget> SetupChannelMembers(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
not_null<PeerData*> peer);
|
||||
|
||||
object_ptr<Ui::RpWidget> SetupFeedDetails(
|
||||
not_null<Controller*> controller,
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
not_null<Data::Feed*> feed);
|
||||
|
||||
} // namespace Profile
|
||||
} // namespace Info
|
||||
|
@ -13,9 +13,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include <rpl/combine.h>
|
||||
#include "observer_peer.h"
|
||||
#include "messenger.h"
|
||||
#include "auth_session.h"
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "data/data_peer_values.h"
|
||||
#include "data/data_shared_media.h"
|
||||
#include "data/data_feed.h"
|
||||
#include "data/data_session.h"
|
||||
|
||||
namespace Info {
|
||||
namespace Profile {
|
||||
@ -292,5 +295,22 @@ rpl::producer<bool> VerifiedValue(
|
||||
return rpl::single(false);
|
||||
}
|
||||
|
||||
rpl::producer<int> FeedChannelsCountValue(
|
||||
not_null<Data::Feed*> feed) {
|
||||
using Flag = Data::FeedUpdateFlag;
|
||||
return rpl::single(
|
||||
Data::FeedUpdate{ feed, Flag::Channels }
|
||||
) | rpl::then(
|
||||
Auth().data().feedUpdated()
|
||||
) | rpl::filter([=](const Data::FeedUpdate &update) {
|
||||
return (update.feed == feed) && (update.flag == Flag::Channels);
|
||||
}) | rpl::filter([=] {
|
||||
return feed->channelsLoaded();
|
||||
}) | rpl::map([=] {
|
||||
return int(feed->channels().size());
|
||||
}) | rpl::distinct_until_changed();
|
||||
}
|
||||
|
||||
|
||||
} // namespace Profile
|
||||
} // namespace Info
|
||||
|
@ -83,5 +83,8 @@ rpl::producer<bool> CanAddMemberValue(
|
||||
rpl::producer<bool> VerifiedValue(
|
||||
not_null<PeerData*> peer);
|
||||
|
||||
rpl::producer<int> FeedChannelsCountValue(
|
||||
not_null<Data::Feed*> feed);
|
||||
|
||||
} // namespace Profile
|
||||
} // namespace Info
|
||||
|
@ -292,6 +292,8 @@
|
||||
<(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_channels_controllers.cpp
|
||||
<(src_loc)/info/feed/info_feed_channels_controllers.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
|
||||
|
Loading…
Reference in New Issue
Block a user