Channels list in feed info with leave channel.

This commit is contained in:
John Preston 2018-02-08 12:20:14 +03:00
parent f23c23f696
commit 906cb95e67
17 changed files with 259 additions and 89 deletions

View File

@ -273,7 +273,7 @@ messageActionCustomAction#fae69f56 message:string = MessageAction;
messageActionBotAllowed#abe9affe domain:string = MessageAction;
dialog#e4def5db flags:# pinned:flags.2?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage = Dialog;
dialogFeed#907750e4 flags:# pinned:flags.2?true peer:Peer top_message:int feed_id:int feed_other_channels:Vector<int> read_max_position:flags.3?FeedPosition unread_count:int unread_muted_count:int sources_hash:int = Dialog;
dialogFeed#36086d42 flags:# pinned:flags.2?true peer:Peer top_message:int feed_id:int feed_other_channels:Vector<int> read_max_position:flags.3?FeedPosition unread_count:int unread_muted_count:int = Dialog;
photoEmpty#2331b22d id:long = Photo;
photo#9288dd29 flags:# has_stickers:flags.0?true id:long access_hash:long date:int sizes:Vector<PhotoSize> = Photo;
@ -1199,11 +1199,11 @@ channels.setStickers#ea8ca4f9 channel:InputChannel stickerset:InputStickerSet =
channels.readMessageContents#eab5dc38 channel:InputChannel id:Vector<int> = Bool;
channels.deleteHistory#af369d42 channel:InputChannel max_id:int = Bool;
channels.togglePreHistoryHidden#eabbb94c channel:InputChannel enabled:Bool = Updates;
channels.getFeed#18117df2 flags:# offset_to_max_read:flags.3?true feed_id:int offset_position:flags.0?FeedPosition add_offset:int limit:int max_position:flags.1?FeedPosition min_position:flags.2?FeedPosition sources_hash:int hash:int = messages.FeedMessages;
channels.getFeed#b90f450 flags:# offset_to_max_read:flags.3?true feed_id:int offset_position:flags.0?FeedPosition add_offset:int limit:int max_position:flags.1?FeedPosition min_position:flags.2?FeedPosition hash:int = messages.FeedMessages;
channels.searchFeed#88325369 feed_id:int q:string offset_date:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
channels.getFeedSources#d8ce236e flags:# feed_id:flags.0?int hash:int = channels.FeedSources;
channels.changeFeedBroadcast#2528871e flags:# channel:InputChannel feed_id:flags.0?int = Bool;
channels.setFeedBroadcasts#7e91b8f2 feed_id:int channels:Vector<InputChannel> also_newly_joined:Bool = Bool;
channels.changeFeedBroadcast#ffb37511 flags:# channel:InputChannel feed_id:flags.0?int = Updates;
channels.setFeedBroadcasts#ea80bfae flags:# feed_id:int channels:flags.0?Vector<InputChannel> also_newly_joined:flags.1?Bool = Updates;
channels.readFeed#9c3011d feed_id:int max_position:FeedPosition = Updates;
bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON;

View File

@ -187,7 +187,8 @@ void ApiWrap::toggleChannelGrouping(
MTP_flags(flags),
channel->inputChannel,
MTP_int(feedId)
)).done([=](const MTPBool &result) {
)).done([=](const MTPUpdates &result) {
applyUpdates(result);
if (group) {
channel->setFeed(Auth().data().feed(feedId));
} else {
@ -2993,6 +2994,11 @@ void ApiWrap::requestFeedChannels(not_null<Data::Feed*> feed) {
App::feedUsers(data.vusers);
App::feedChats(data.vchats);
if (data.has_newly_joined_feed()) {
_session->data().setDefaultFeedId(
data.vnewly_joined_feed.v);
}
if (feed->channelsLoaded()) {
feedChannelsDone(feed);
} else {
@ -3044,7 +3050,6 @@ void ApiWrap::requestFeedMessages(
}
Unexpected("Direction in PrepareSearchRequest");
}();
const auto sourcesHash = feed->channelsHash();
const auto hash = int32(0);
const auto flags = (messageId && messageId.fullId.channel)
? MTPchannels_GetFeed::Flag::f_offset_position
@ -3060,7 +3065,6 @@ void ApiWrap::requestFeedMessages(
MTP_int(limit),
MTPFeedPosition(),
MTPFeedPosition(),
MTP_int(sourcesHash),
MTP_int(hash)
)).done([=](const MTPmessages_FeedMessages &result) {
const auto key = std::make_tuple(feed, messageId, slice);
@ -3172,6 +3176,18 @@ void ApiWrap::feedMessagesDone(
}
}
void ApiWrap::saveDefaultFeedId(FeedId id, bool isDefaultFeedId) {
if (const auto already = base::take(_saveDefaultFeedIdRequest)) {
request(already).cancel();
}
_saveDefaultFeedIdRequest = request(MTPchannels_SetFeedBroadcasts(
MTP_flags(MTPchannels_SetFeedBroadcasts::Flag::f_also_newly_joined),
MTP_int(id),
MTPVector<MTPInputChannel>(),
MTP_bool(isDefaultFeedId)
)).send();
}
void ApiWrap::sendAction(const SendOptions &options) {
readServerHistory(options.history);
options.history->getReadyFor(ShowAtTheEndMsgId);

View File

@ -177,6 +177,7 @@ public:
not_null<Data::Feed*> feed,
Data::MessagePosition messageId,
SliceType slice);
void saveDefaultFeedId(FeedId id, bool isDefaultFeedId);
void stickerSetInstalled(uint64 setId) {
_stickerSetInstalled.fire_copy(setId);
@ -507,6 +508,7 @@ private:
not_null<Data::Feed*>,
Data::MessagePosition,
SliceType>> _feedMessagesRequestsPending;
mtpRequestId _saveDefaultFeedIdRequest = 0;
rpl::event_stream<SendOptions> _sendActions;

View File

@ -575,10 +575,14 @@ namespace {
cdata->setPhoto(d.vphoto);
if (wasInChannel != cdata->amIn()) update.flags |= UpdateFlag::ChannelAmIn;
if (wasInChannel != cdata->amIn()) {
update.flags |= UpdateFlag::ChannelAmIn;
}
if (canViewAdmins != cdata->canViewAdmins()
|| canViewMembers != cdata->canViewMembers()
|| canAddMembers != cdata->canAddMembers()) update.flags |= UpdateFlag::ChannelRightsChanged;
|| canAddMembers != cdata->canAddMembers()) {
update.flags |= UpdateFlag::ChannelRightsChanged;
}
} break;
case mtpc_channelForbidden: {
auto &d(chat.c_channelForbidden());
@ -612,10 +616,14 @@ namespace {
cdata->date = 0;
cdata->setMembersCount(0);
if (wasInChannel != cdata->amIn()) update.flags |= UpdateFlag::ChannelAmIn;
if (wasInChannel != cdata->amIn()) {
update.flags |= UpdateFlag::ChannelAmIn;
}
if (canViewAdmins != cdata->canViewAdmins()
|| canViewMembers != cdata->canViewMembers()
|| canAddMembers != cdata->canAddMembers()) update.flags |= UpdateFlag::ChannelRightsChanged;
|| canAddMembers != cdata->canAddMembers()) {
update.flags |= UpdateFlag::ChannelRightsChanged;
}
} break;
}
if (!data) {

View File

@ -84,6 +84,19 @@ void Feed::registerOne(not_null<ChannelData*> channel) {
} else if (lastMessageKnown()) {
_parent->session().api().requestDialogEntry(history);
}
if (unreadCountKnown()) {
if (history->unreadCountKnown()) {
// If history unreadCount is known that means that we've
// already had the channel information and if it was in the
// feed already (not yet known) it wouldn't get here.
// That means here we get if we add a new channel to feed.
if (const auto count = history->unreadCount()) {
unreadCountChanged(count, history->mute() ? count : 0);
}
} else if (!_settingChannels) {
_parent->session().api().requestDialogEntry(this);
}
}
if (invisible && _channels.size() > 1) {
updateChatListExistence();
for (const auto history : _channels) {
@ -105,9 +118,20 @@ void Feed::unregisterOne(not_null<ChannelData*> channel) {
_parent->session().storage().remove(
Storage::FeedMessagesRemoveAll(_id, channel->bareId()));
if (const auto last = lastMessage()) {
if (last->history() == history) {
recountLastMessage();
if (lastMessageKnown()) {
if (const auto last = lastMessage()) {
if (last->history() == history) {
recountLastMessage();
}
}
}
if (unreadCountKnown()) {
if (history->unreadCountKnown()) {
if (const auto delta = -history->unreadCount()) {
unreadCountChanged(delta, history->mute() ? delta : 0);
}
} else {
_parent->session().api().requestDialogEntry(this);
}
}
if (visible && _channels.size() < 2) {
@ -188,7 +212,7 @@ void Feed::setChannels(std::vector<not_null<ChannelData*>> channels) {
const auto remove = ranges::view::all(
_channels
) | ranges::view::transform([](not_null<History*> history) {
return history->peer->asChannel();
return not_null<ChannelData*>(history->peer->asChannel());
}) | ranges::view::filter([&](not_null<ChannelData*> channel) {
return !base::contains(channels, channel);
}) | ranges::to_vector;
@ -201,8 +225,21 @@ void Feed::setChannels(std::vector<not_null<ChannelData*>> channels) {
channel.get(),
[](auto history) { return history->peer->asChannel(); }
) == end(_channels);
}) | ranges::view::transform([](ChannelData *channel) {
return not_null<ChannelData*>(channel);
}) | ranges::to_vector;
changeChannelsList(add, remove);
setChannelsLoaded(true);
}
void Feed::changeChannelsList(
const std::vector<not_null<ChannelData*>> &add,
const std::vector<not_null<ChannelData*>> &remove) {
_settingChannels = true;
const auto restore = gsl::finally([&] { _settingChannels = false; });
for (const auto channel : remove) {
channel->clearFeed();
}
@ -216,14 +253,6 @@ void Feed::setChannels(std::vector<not_null<ChannelData*>> channels) {
channel->setFeed(this);
}
_lastMessage = oldLastMessage;
_channels.clear();
for (const auto channel : channels) {
Assert(channel->feed() == this);
_channels.push_back(App::history(channel));
}
setChannelsLoaded(true);
}
bool Feed::justUpdateLastMessage(not_null<HistoryItem*> item) {
@ -328,10 +357,6 @@ void Feed::applyDialog(const MTPDdialogFeed &data) {
if (data.has_read_max_position()) {
setUnreadPosition(FeedPositionFromMTP(data.vread_max_position));
}
if (channelsHash() != data.vsources_hash.v) {
setChannelsLoaded(false);
}
}
void Feed::setUnreadCounts(int unreadNonMutedCount, int unreadMutedCount) {

View File

@ -87,10 +87,14 @@ private:
void setLastMessageFromChannels();
bool justUpdateLastMessage(not_null<HistoryItem*> item);
void updateChatsListDate();
void changeChannelsList(
const std::vector<not_null<ChannelData*>> &add,
const std::vector<not_null<ChannelData*>> &remove);
FeedId _id = 0;
not_null<Data::Session*> _parent;
std::vector<not_null<History*>> _channels;
bool _settingChannels = false;
bool _channelsLoaded = false;
QString _name;

View File

@ -60,6 +60,11 @@ void UpdateImage(ImagePtr &old, ImagePtr now) {
Session::Session(not_null<AuthSession*> session)
: _session(session)
, _groups(this) {
setupContactViewsViewer();
setupChannelLeavingViewer();
}
void Session::setupContactViewsViewer() {
Notify::PeerUpdateViewer(
Notify::PeerUpdate::Flag::UserIsContact
) | rpl::map([](const Notify::PeerUpdate &update) {
@ -71,6 +76,20 @@ Session::Session(not_null<AuthSession*> session)
}, _lifetime);
}
void Session::setupChannelLeavingViewer() {
Notify::PeerUpdateViewer(
Notify::PeerUpdate::Flag::ChannelAmIn
) | rpl::map([](const Notify::PeerUpdate &update) {
return update.peer->asChannel();
}) | rpl::filter([](ChannelData *channel) {
return (channel != nullptr)
&& !(channel->amIn())
&& (channel->feed() != nullptr);
}) | rpl::start_with_next([=](not_null<ChannelData*> channel) {
channel->clearFeed();
}, _lifetime);
}
Session::~Session() = default;
template <typename Method>
@ -1447,6 +1466,18 @@ Feed *Session::feedLoaded(FeedId id) {
return (it == end(_feeds)) ? nullptr : it->second.get();
}
void Session::setDefaultFeedId(FeedId id) {
_defaultFeedId = id;
}
FeedId Session::defaultFeedId() const {
return _defaultFeedId.current();
}
rpl::producer<FeedId> Session::defaultFeedIdValue() const {
return _defaultFeedId.value();
}
void Session::forgetMedia() {
for (const auto &[id, photo] : _photos) {
photo->forget();

View File

@ -347,6 +347,9 @@ public:
not_null<Feed*> feed(FeedId id);
Feed *feedLoaded(FeedId id);
void setDefaultFeedId(FeedId id);
FeedId defaultFeedId() const;
rpl::producer<FeedId> defaultFeedIdValue() const;
void forgetMedia();
@ -361,6 +364,8 @@ public:
}
private:
void setupContactViewsViewer();
void setupChannelLeavingViewer();
void photoApplyFields(
not_null<PhotoData*> photo,
const MTPPhoto &data);
@ -517,6 +522,7 @@ private:
std::deque<Dialogs::Key> _pinnedDialogs;
base::flat_map<FeedId, std::unique_ptr<Feed>> _feeds;
rpl::variable<FeedId> _defaultFeedId = FeedId();
Groups _groups;
std::map<
not_null<const HistoryItem*>,

View File

@ -110,6 +110,7 @@ Widget::Widget(
_showNext->setClickedCallback([this] {
// #TODO feeds show next
});
_showNext->hide();
_feed->unreadPositionChanges(
) | rpl::filter([=](const Data::MessagePosition &position) {
@ -463,8 +464,8 @@ void Widget::updateControlsGeometry() {
const auto bottom = height();
const auto scrollHeight = bottom
- _topBar->height()
- _showNext->height();
- _topBar->height();
// - _showNext->height();
const auto scrollSize = QSize(contentWidth, scrollHeight);
if (_scroll->size() != scrollSize) {
_skipScrollEvent = true;
@ -480,12 +481,12 @@ void Widget::updateControlsGeometry() {
}
updateScrollDownPosition();
const auto fullWidthButtonRect = myrtlrect(
0,
bottom - _showNext->height(),
contentWidth,
_showNext->height());
_showNext->setGeometry(fullWidthButtonRect);
//const auto fullWidthButtonRect = myrtlrect(
// 0,
// bottom - _showNext->height(),
// contentWidth,
// _showNext->height());
//_showNext->setGeometry(fullWidthButtonRect);
if (_emptyTextView) {
_emptyTextView->resizeGetHeight(width());
@ -515,7 +516,7 @@ void Widget::paintEvent(QPaintEvent *e) {
const auto clip = e->rect();
const auto left = 0;
const auto top = (height()
- _showNext->height()
// - _showNext->height()
- _emptyTextView->height()) / 2;
p.translate(left, top);
_emptyTextView->draw(

View File

@ -18,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 "data/data_feed.h"
#include "lang/lang_keys.h"
#include "styles/style_boxes.h"
#include "styles/style_info.h"
@ -57,16 +58,8 @@ Channels::Channels(
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;
desired += st::infoMembersList.item.height
* std::max(int(_feed->channels().size()), _list->fullRowsCount());
return qMax(height(), desired);
}
@ -171,7 +164,7 @@ void Channels::setupList() {
_list = object_ptr<ListWidget>(
this,
_listController.get(),
st::infoMembersList);
st::infoCommonGroupsList);
_list->scrollToRequests(
) | rpl::start_with_next([this](Ui::ScrollToRequest request) {
auto addmin = (request.ymin < 0 || !_header)

View File

@ -11,12 +11,73 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_session.h"
#include "info/info_controller.h"
#include "lang/lang_keys.h"
#include "auth_session.h"
#include "history/history.h"
#include "window/window_peer_menu.h"
#include "auth_session.h"
#include "styles/style_widgets.h"
#include "styles/style_info.h"
#include "styles/style_boxes.h"
namespace Info {
namespace FeedProfile {
class ChannelsController::Row final : public PeerListRow {
public:
Row(not_null<ChannelData*> channel);
QSize actionSize() const override;
QMargins actionMargins() const override;
void paintAction(
Painter &p,
TimeMs ms,
int x,
int y,
int outerWidth,
bool selected,
bool actionSelected) override;
not_null<ChannelData*> channel() const {
return peer()->asChannel();
}
};
ChannelsController::Row::Row(not_null<ChannelData*> channel)
: PeerListRow(channel) {
}
QSize ChannelsController::Row::actionSize() const {
return QRect(
QPoint(),
st::smallCloseIcon.size()).marginsAdded(
st::infoFeedLeaveIconMargins).size();
}
QMargins ChannelsController::Row::actionMargins() const {
return QMargins(
0,
(st::infoCommonGroupsList.item.height - actionSize().height()) / 2,
0,
0);
}
void ChannelsController::Row::paintAction(
Painter &p,
TimeMs ms,
int x,
int y,
int outerWidth,
bool selected,
bool actionSelected) {
if (selected) {
x += st::infoFeedLeaveIconMargins.left();
y += st::infoFeedLeaveIconMargins.top();
(actionSelected
? st::smallCloseIconOver
: st::smallCloseIcon).paint(p, x, y, outerWidth);
}
}
ChannelsController::ChannelsController(not_null<Controller*> controller)
: PeerListController()
, _controller(controller)
@ -24,16 +85,16 @@ ChannelsController::ChannelsController(not_null<Controller*> controller)
_controller->setSearchEnabledByContent(false);
}
std::unique_ptr<PeerListRow> ChannelsController::createRow(
not_null<PeerData*> peer) {
auto result = std::make_unique<PeerListRow>(peer);
auto ChannelsController::createRow(not_null<ChannelData*> channel)
-> std::unique_ptr<Row> {
auto result = std::make_unique<Row>(channel);
result->setCustomStatus(QString());
return result;
}
std::unique_ptr<PeerListRow> ChannelsController::createRestoredRow(
not_null<PeerData*> peer) {
return createRow(peer);
return createRow(peer->asChannel());
}
void ChannelsController::prepare() {
@ -43,10 +104,7 @@ void ChannelsController::prepare() {
rebuildRows();
using Flag = Data::FeedUpdateFlag;
rpl::single(
Data::FeedUpdate{ _feed, Flag::Channels }
) | rpl::then(
Auth().data().feedUpdated()
Auth().data().feedUpdated(
) | rpl::filter([=](const Data::FeedUpdate &update) {
return (update.feed == _feed) && (update.flag == Flag::Channels);
}) | rpl::filter([=] {
@ -75,10 +133,11 @@ void ChannelsController::rebuildRows() {
}
}
for (const auto history : channels) {
if (auto row = createRow(history->peer)) {
if (auto row = createRow(history->peer->asChannel())) {
delegate()->peerListAppendRow(std::move(row));
}
}
delegate()->peerListRefreshRows();
}
std::unique_ptr<PeerListState> ChannelsController::saveState() const {
@ -106,5 +165,9 @@ void ChannelsController::rowClicked(not_null<PeerListRow*> row) {
Window::SectionShow::Way::Forward);
}
void ChannelsController::rowActionClicked(not_null<PeerListRow*> row) {
Window::DeleteAndLeaveHandler(row->peer())();
}
} // namespace FeedProfile
} // namespace Info

View File

@ -27,6 +27,7 @@ public:
void prepare() override;
void rowClicked(not_null<PeerListRow*> row) override;
void rowActionClicked(not_null<PeerListRow*> row) override;
std::unique_ptr<PeerListRow> createRestoredRow(
not_null<PeerData*> peer) override;
@ -35,12 +36,13 @@ public:
void restoreState(std::unique_ptr<PeerListState> state) override;
private:
class Row;
struct SavedState : SavedStateBase {
rpl::lifetime lifetime;
};
void rebuildRows();
std::unique_ptr<PeerListRow> createRow(not_null<PeerData*> peer);
std::unique_ptr<Row> createRow(not_null<ChannelData*> channel);
const not_null<Controller*> _controller;
not_null<Data::Feed*> _feed;

View File

@ -0,0 +1,9 @@
/*
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_widget.h"

View File

@ -0,0 +1,9 @@
/*
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

View File

@ -40,26 +40,26 @@ object_ptr<Ui::RpWidget> InnerWidget::setupContent(
_cover = result->add(object_ptr<Cover>(
result,
_controller));
//auto details = Profile::SetupFeedDetails(_controller, parent, _feed);
//result->add(std::move(details));
//result->add(object_ptr<BoxContentDivider>(result));
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);
}

View File

@ -691,3 +691,5 @@ topBarFeedInfoButton: FeedUserpicButton(defaultFeedUserpicButton) {
photoSize: 20px;
}
}
infoFeedLeaveIconMargins: margins(10px, 12px, 20px, 10px);

View File

@ -10,6 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <rpl/flatten_latest.h>
#include <rpl/combine.h>
#include "data/data_peer_values.h"
#include "data/data_session.h"
#include "data/data_feed.h"
#include "ui/wrap/vertical_layout.h"
#include "ui/wrap/padding_wrap.h"
#include "ui/wrap/slide_wrap.h"
@ -580,19 +582,11 @@ void ActionsFiller::addBlockAction(not_null<UserData*> user) {
void ActionsFiller::addLeaveChannelAction(
not_null<ChannelData*> channel) {
auto callback = [=] {
auto text = lang(channel->isMegagroup()
? lng_sure_leave_group
: lng_sure_leave_channel);
Ui::show(Box<ConfirmBox>(text, lang(lng_box_leave), [=] {
Auth().api().leaveChannel(channel);
}), LayerOption::KeepOther);
};
AddActionButton(
_wrap,
Lang::Viewer(lng_profile_leave_channel),
AmInChannelValue(channel),
std::move(callback));
Window::DeleteAndLeaveHandler(channel));
}
void ActionsFiller::addJoinChannelAction(
@ -700,15 +694,20 @@ object_ptr<Ui::RpWidget> FeedDetailsFiller::fill() {
}
object_ptr<Ui::RpWidget> FeedDetailsFiller::setupDefaultToggle() {
const auto feed = _feed;
using namespace rpl::mappers;
const auto feedId = _feed->id();
auto result = object_ptr<Button>(
_wrap,
Lang::Viewer(lng_info_feed_is_default),
st::infoNotificationsButton);
result->toggleOn(
rpl::single(false)// #TODO default
Auth().data().defaultFeedIdValue(
) | rpl::map(_1 == feedId)
)->addClickHandler([=] {
const auto makeDefault = (Auth().data().defaultFeedId() != feedId);
const auto defaultFeedId = makeDefault ? feedId : 0;
Auth().data().setDefaultFeedId(defaultFeedId);
Auth().api().saveDefaultFeedId(feedId, makeDefault);
});
object_ptr<FloatingIcon>(
result,