mirror of https://github.com/procxx/kepka.git
Add feed notifications edit box.
This commit is contained in:
parent
22a5b7faf6
commit
cfd5c2a650
|
@ -1427,6 +1427,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_feed_no_messages" = "No messages in this feed yet";
|
"lng_feed_no_messages" = "No messages in this feed yet";
|
||||||
"lng_feed_channels#one" = "{count} channel";
|
"lng_feed_channels#one" = "{count} channel";
|
||||||
"lng_feed_channels#other" = "{count} channels";
|
"lng_feed_channels#other" = "{count} channels";
|
||||||
|
"lng_feed_notifications" = "Feed notifications";
|
||||||
|
|
||||||
"lng_info_feed_title" = "Feed Info";
|
"lng_info_feed_title" = "Feed Info";
|
||||||
"lng_info_feed_is_default" = "Group new channels";
|
"lng_info_feed_is_default" = "Group new channels";
|
||||||
|
|
|
@ -147,8 +147,7 @@ void TopBarWidget::onCall() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TopBarWidget::showMenu() {
|
void TopBarWidget::showMenu() {
|
||||||
// #TODO feeds menu
|
if (!_activeChat || _menu) {
|
||||||
if (!_activeChat || _menu || !_activeChat.peer()) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_menu.create(parentWidget());
|
_menu.create(parentWidget());
|
||||||
|
@ -170,13 +169,26 @@ void TopBarWidget::showMenu() {
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
_menuToggle->installEventFilter(_menu);
|
_menuToggle->installEventFilter(_menu);
|
||||||
Window::FillPeerMenu(
|
const auto addAction = [&](
|
||||||
_controller,
|
const QString &text,
|
||||||
_activeChat.peer(),
|
base::lambda<void()> callback) {
|
||||||
[this](const QString &text, base::lambda<void()> callback) {
|
return _menu->addAction(text, std::move(callback));
|
||||||
return _menu->addAction(text, std::move(callback));
|
};
|
||||||
},
|
if (const auto peer = _activeChat.peer()) {
|
||||||
Window::PeerMenuSource::History);
|
Window::FillPeerMenu(
|
||||||
|
_controller,
|
||||||
|
peer,
|
||||||
|
addAction,
|
||||||
|
Window::PeerMenuSource::History);
|
||||||
|
} else if (const auto feed = _activeChat.feed()) {
|
||||||
|
Window::FillFeedMenu(
|
||||||
|
_controller,
|
||||||
|
feed,
|
||||||
|
addAction,
|
||||||
|
Window::PeerMenuSource::History);
|
||||||
|
} else {
|
||||||
|
Unexpected("Empty active chat in TopBarWidget::showMenu.");
|
||||||
|
}
|
||||||
_menu->moveToRight((parentWidget()->width() - width()) + st::topBarMenuPosition.x(), st::topBarMenuPosition.y());
|
_menu->moveToRight((parentWidget()->width() - width()) + st::topBarMenuPosition.x(), st::topBarMenuPosition.y());
|
||||||
_menu->showAnimated(Ui::PanelAnimation::Origin::TopRight);
|
_menu->showAnimated(Ui::PanelAnimation::Origin::TopRight);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "window/window_peer_menu.h"
|
#include "window/window_peer_menu.h"
|
||||||
#include "ui/widgets/popup_menu.h"
|
#include "ui/widgets/popup_menu.h"
|
||||||
#include "auth_session.h"
|
#include "auth_session.h"
|
||||||
|
#include "mainwidget.h"
|
||||||
#include "styles/style_widgets.h"
|
#include "styles/style_widgets.h"
|
||||||
#include "styles/style_info.h"
|
#include "styles/style_info.h"
|
||||||
#include "styles/style_boxes.h"
|
#include "styles/style_boxes.h"
|
||||||
|
@ -196,5 +197,135 @@ base::unique_qptr<Ui::PopupMenu> ChannelsController::rowContextMenu(
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FeedNotificationsController::Start(not_null<Data::Feed*> feed) {
|
||||||
|
const auto initBox = [=](not_null<PeerListBox*> box) {
|
||||||
|
box->addButton(langFactory(lng_settings_save), [=] {
|
||||||
|
const auto main = App::main();
|
||||||
|
const auto count = box->peerListFullRowsCount();
|
||||||
|
for (auto i = 0; i != count; ++i) {
|
||||||
|
const auto row = box->peerListRowAt(i);
|
||||||
|
const auto peer = row->peer();
|
||||||
|
const auto muted = !row->checked();
|
||||||
|
if (muted != peer->isMuted()) {
|
||||||
|
main->updateNotifySettings(
|
||||||
|
peer,
|
||||||
|
(muted
|
||||||
|
? Data::NotifySettings::MuteChange::Mute
|
||||||
|
: Data::NotifySettings::MuteChange::Unmute));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
box->closeBox();
|
||||||
|
});
|
||||||
|
box->addButton(langFactory(lng_cancel), [box] { box->closeBox(); });
|
||||||
|
};
|
||||||
|
Ui::show(Box<PeerListBox>(
|
||||||
|
std::make_unique<FeedNotificationsController>(feed),
|
||||||
|
initBox));
|
||||||
|
}
|
||||||
|
|
||||||
|
FeedNotificationsController::FeedNotificationsController(
|
||||||
|
not_null<Data::Feed*> feed)
|
||||||
|
: _feed(feed) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void FeedNotificationsController::prepare() {
|
||||||
|
setSearchNoResultsText(lang(lng_blocked_list_not_found));
|
||||||
|
delegate()->peerListSetSearchMode(PeerListSearchMode::Enabled);
|
||||||
|
delegate()->peerListSetTitle(langFactory(lng_feed_notifications));
|
||||||
|
|
||||||
|
loadMoreRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FeedNotificationsController::loadMoreRows() {
|
||||||
|
if (_preloadRequestId || _allLoaded) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_preloadRequestId = request(MTPmessages_GetDialogs(
|
||||||
|
MTP_flags(MTPmessages_GetDialogs::Flag::f_feed_id),
|
||||||
|
MTP_int(_feed->id()),
|
||||||
|
MTP_int(_preloadOffsetDate),
|
||||||
|
MTP_int(_preloadOffsetId),
|
||||||
|
_preloadPeer ? _preloadPeer->input : MTP_inputPeerEmpty(),
|
||||||
|
MTP_int(Data::Feed::kChannelsLimit)
|
||||||
|
)).done([=](const MTPmessages_Dialogs &result) {
|
||||||
|
applyFeedDialogs(result);
|
||||||
|
_preloadRequestId = 0;
|
||||||
|
}).fail([=](const RPCError &error) {
|
||||||
|
_preloadRequestId = 0;
|
||||||
|
}).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FeedNotificationsController::applyFeedDialogs(
|
||||||
|
const MTPmessages_Dialogs &result) {
|
||||||
|
const auto [dialogsList, messagesList] = [&] {
|
||||||
|
const auto process = [&](const auto &data) {
|
||||||
|
App::feedUsers(data.vusers);
|
||||||
|
App::feedChats(data.vchats);
|
||||||
|
return std::make_tuple(&data.vdialogs.v, &data.vmessages.v);
|
||||||
|
};
|
||||||
|
switch (result.type()) {
|
||||||
|
case mtpc_messages_dialogs:
|
||||||
|
_allLoaded = true;
|
||||||
|
return process(result.c_messages_dialogs());
|
||||||
|
|
||||||
|
case mtpc_messages_dialogsSlice:
|
||||||
|
LOG(("API Error: "
|
||||||
|
"Unexpected dialogsSlice in feed dialogs list."));
|
||||||
|
return process(result.c_messages_dialogsSlice());
|
||||||
|
}
|
||||||
|
Unexpected("Type in FeedNotificationsController::applyFeedDialogs");
|
||||||
|
}();
|
||||||
|
|
||||||
|
App::feedMsgs(*messagesList, NewMessageLast);
|
||||||
|
|
||||||
|
if (dialogsList->empty()) {
|
||||||
|
_allLoaded = true;
|
||||||
|
}
|
||||||
|
auto channels = std::vector<not_null<ChannelData*>>();
|
||||||
|
channels.reserve(dialogsList->size());
|
||||||
|
for (const auto &dialog : *dialogsList) {
|
||||||
|
switch (dialog.type()) {
|
||||||
|
case mtpc_dialog: {
|
||||||
|
if (const auto peerId = peerFromMTP(dialog.c_dialog().vpeer)) {
|
||||||
|
if (peerIsChannel(peerId)) {
|
||||||
|
const auto history = App::history(peerId);
|
||||||
|
const auto channel = history->peer->asChannel();
|
||||||
|
history->applyDialog(dialog.c_dialog());
|
||||||
|
channels.push_back(channel);
|
||||||
|
} else {
|
||||||
|
LOG(("API Error: "
|
||||||
|
"Unexpected non-channel in feed dialogs list."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case mtpc_dialogFeed: {
|
||||||
|
LOG(("API Error: Unexpected dialogFeed in feed dialogs list."));
|
||||||
|
} break;
|
||||||
|
default: Unexpected("Type in DialogsInner::dialogsReceived");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!channels.empty()) {
|
||||||
|
auto notMutedChannels = ranges::view::all(
|
||||||
|
channels
|
||||||
|
) | ranges::view::filter([](not_null<ChannelData*> channel) {
|
||||||
|
return !channel->isMuted();
|
||||||
|
});
|
||||||
|
delegate()->peerListAddSelectedRows(notMutedChannels);
|
||||||
|
for (const auto channel : channels) {
|
||||||
|
delegate()->peerListAppendRow(createRow(channel));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delegate()->peerListRefreshRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FeedNotificationsController::rowClicked(not_null<PeerListRow*> row) {
|
||||||
|
delegate()->peerListSetRowChecked(row, !row->checked());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<PeerListRow> FeedNotificationsController::createRow(
|
||||||
|
not_null<ChannelData*> channel) {
|
||||||
|
return std::make_unique<PeerListRow>(channel);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace FeedProfile
|
} // namespace FeedProfile
|
||||||
} // namespace Info
|
} // namespace Info
|
||||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "boxes/peer_list_box.h"
|
#include "boxes/peer_list_box.h"
|
||||||
|
#include "mtproto/sender.h"
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
class Feed;
|
class Feed;
|
||||||
|
@ -51,5 +52,31 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FeedNotificationsController
|
||||||
|
: public PeerListController
|
||||||
|
, private MTP::Sender {
|
||||||
|
public:
|
||||||
|
static void Start(not_null<Data::Feed*> feed);
|
||||||
|
|
||||||
|
FeedNotificationsController(not_null<Data::Feed*> feed);
|
||||||
|
|
||||||
|
void prepare() override;
|
||||||
|
void rowClicked(not_null<PeerListRow*> row) override;
|
||||||
|
|
||||||
|
void loadMoreRows() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<PeerListRow> createRow(not_null<ChannelData*> channel);
|
||||||
|
void applyFeedDialogs(const MTPmessages_Dialogs &result);
|
||||||
|
|
||||||
|
not_null<Data::Feed*> _feed;
|
||||||
|
mtpRequestId _preloadRequestId = 0;
|
||||||
|
TimeId _preloadOffsetDate = TimeId(0);
|
||||||
|
MsgId _preloadOffsetId = MsgId(0);
|
||||||
|
PeerData *_preloadPeer = nullptr;
|
||||||
|
bool _allLoaded = false;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace FeedProfile
|
} // namespace FeedProfile
|
||||||
} // namespace Info
|
} // namespace Info
|
||||||
|
|
|
@ -25,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "styles/style_boxes.h"
|
#include "styles/style_boxes.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "window/window_controller.h"
|
#include "window/window_controller.h"
|
||||||
|
#include "info/feed/info_feed_channels_controllers.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_feed.h"
|
#include "data/data_feed.h"
|
||||||
#include "dialogs/dialogs_key.h"
|
#include "dialogs/dialogs_key.h"
|
||||||
|
@ -69,6 +70,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void addPinToggle();
|
void addPinToggle();
|
||||||
|
void addNotifications();
|
||||||
|
|
||||||
not_null<Controller*> _controller;
|
not_null<Controller*> _controller;
|
||||||
not_null<Data::Feed*> _feed;
|
not_null<Data::Feed*> _feed;
|
||||||
|
@ -385,11 +387,11 @@ void Filler::fill() {
|
||||||
addSearch();
|
addSearch();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto user = _peer->asUser()) {
|
if (const auto user = _peer->asUser()) {
|
||||||
addUserActions(user);
|
addUserActions(user);
|
||||||
} else if (auto chat = _peer->asChat()) {
|
} else if (const auto chat = _peer->asChat()) {
|
||||||
addChatActions(chat);
|
addChatActions(chat);
|
||||||
} else if (auto channel = _peer->asChannel()) {
|
} else if (const auto channel = _peer->asChannel()) {
|
||||||
addChannelActions(channel);
|
addChannelActions(channel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -409,20 +411,27 @@ void FeedFiller::fill() {
|
||||||
if (_source == PeerMenuSource::ChatsList) {
|
if (_source == PeerMenuSource::ChatsList) {
|
||||||
addPinToggle();
|
addPinToggle();
|
||||||
}
|
}
|
||||||
|
addNotifications();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedFiller::addPinToggle() {
|
void FeedFiller::addPinToggle() {
|
||||||
auto feed = _feed;
|
const auto feed = _feed;
|
||||||
auto isPinned = feed->isPinnedDialog();
|
const auto isPinned = feed->isPinnedDialog();
|
||||||
auto pinText = [](bool isPinned) {
|
const auto pinText = [](bool isPinned) {
|
||||||
return lang(isPinned
|
return lang(isPinned
|
||||||
? lng_context_unpin_from_top
|
? lng_context_unpin_from_top
|
||||||
: lng_context_pin_to_top);
|
: lng_context_pin_to_top);
|
||||||
};
|
};
|
||||||
auto pinToggle = [=] {
|
_addAction(pinText(isPinned), [=] {
|
||||||
TogglePinnedDialog(feed);
|
TogglePinnedDialog(feed);
|
||||||
};
|
});
|
||||||
_addAction(pinText(isPinned), pinToggle);
|
}
|
||||||
|
|
||||||
|
void FeedFiller::addNotifications() {
|
||||||
|
const auto feed = _feed;
|
||||||
|
_addAction(lang(lng_feed_notifications), [=] {
|
||||||
|
Info::FeedProfile::FeedNotificationsController::Start(feed);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -692,7 +701,6 @@ void FillFeedMenu(
|
||||||
not_null<Data::Feed*> feed,
|
not_null<Data::Feed*> feed,
|
||||||
const PeerMenuCallback &callback,
|
const PeerMenuCallback &callback,
|
||||||
PeerMenuSource source) {
|
PeerMenuSource source) {
|
||||||
// TODO feeds context menu
|
|
||||||
FeedFiller filler(controller, feed, callback, source);
|
FeedFiller filler(controller, feed, callback, source);
|
||||||
filler.fill();
|
filler.fill();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue