Start feeds support.

This commit is contained in:
John Preston 2018-01-04 12:40:58 +03:00
parent 46612ef128
commit 724fe65d72
15 changed files with 199 additions and 32 deletions

View File

@ -582,6 +582,11 @@ namespace {
cdata->setRestrictionReason(QString());
}
cdata->setFlags(d.vflags.v);
if (d.has_feed_id()) {
cdata->setFeed(Auth().data().feed(d.vfeed_id.v));
} else {
cdata->clearFeed();
}
}
QString uname = d.has_username() ? TextUtilities::SingleLine(qs(d.vusername)) : QString();

View File

@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/localstorage.h"
#include "storage/storage_facade.h"
#include "storage/serialize_common.h"
#include "data/data_feed.h"
#include "history/history_item_components.h"
#include "window/notifications_manager.h"
#include "window/themes/window_theme.h"
@ -408,6 +409,21 @@ MessageIdsList AuthSessionData::groupToIds(
return result;
}
not_null<Data::Feed*> AuthSessionData::feed(FeedId id) {
if (const auto result = feedLoaded(id)) {
return result;
}
const auto [it, ok] = _feeds.emplace(
id,
std::make_unique<Data::Feed>(id));
return it->second.get();
}
Data::Feed *AuthSessionData::feedLoaded(FeedId id) {
const auto it = _feeds.find(id);
return (it == _feeds.end()) ? nullptr : it->second.get();
}
AuthSession &Auth() {
auto result = Messenger::Instance().authSession();
Assert(result != nullptr);

View File

@ -16,6 +16,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
class ApiWrap;
enum class SendFilesWay;
namespace Data {
class Feed;
} // namespace Data
namespace Storage {
class Downloader;
class Uploader;
@ -266,6 +270,9 @@ public:
MessageIdsList itemsToIds(const HistoryItemsList &items) const;
MessageIdsList groupToIds(not_null<HistoryMessageGroup*> group) const;
not_null<Data::Feed*> feed(FeedId id);
Data::Feed *feedLoaded(FeedId id);
private:
struct Variables {
Variables();
@ -325,6 +332,8 @@ private:
Stickers::Order _archivedStickerSetsOrder;
Stickers::SavedGifs _savedGifs;
base::flat_map<FeedId, std::unique_ptr<Data::Feed>> _feeds;
rpl::event_stream<bool> _thirdSectionInfoEnabledValue;
bool _tabbedReplacedWithInfo = false;
rpl::event_stream<bool> _tabbedReplacedWithInfoValue;

View File

@ -273,16 +273,18 @@ ShareBox::Inner::Inner(QWidget *parent, ShareBox::FilterCallback &&filterCallbac
_rowHeight = st::shareRowHeight;
setAttribute(Qt::WA_OpaquePaintEvent);
auto dialogs = App::main()->dialogsList();
if (auto self = App::self()) {
const auto dialogs = App::main()->dialogsList();
if (const auto self = App::self()) {
if (_filterCallback(App::self())) {
_chatsIndexed->addToEnd(App::history(self));
}
}
for_const (auto row, dialogs->all()) {
auto history = row->history();
if (!history->peer->isSelf() && _filterCallback(history->peer)) {
_chatsIndexed->addToEnd(history);
for (const auto row : dialogs->all()) {
// #TODO dialogs
if (const auto history = row->history()) {
if (!history->peer->isSelf() && _filterCallback(history->peer)) {
_chatsIndexed->addToEnd(history);
}
}
}
@ -640,8 +642,9 @@ void ShareBox::Inner::changeCheckState(Chat *chat) {
if (!_filter.isEmpty()) {
auto row = _chatsIndexed->getRow(chat->peer->id);
if (!row) {
auto rowsByLetter = _chatsIndexed->addToEnd(App::history(chat->peer));
auto it = rowsByLetter.find(0);
const auto rowsByLetter = _chatsIndexed->addToEnd(
App::history(chat->peer));
const auto it = rowsByLetter.find(0);
Assert(it != rowsByLetter.cend());
row = it->second;
}

View File

@ -0,0 +1,28 @@
/*
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 "data/data_feed.h"
namespace Data {
Feed::Feed(FeedId id) : _id(id) {
}
void Feed::registerOne(not_null<ChannelData*> channel) {
_channels.emplace(channel);
}
void Feed::unregisterOne(not_null<ChannelData*> channel) {
_channels.remove(channel);
}
void Feed::setUnreadCounts(int unreadCount, int unreadMutedCount) {
_unreadCount = unreadCount;
_unreadMutedCount = unreadMutedCount;
}
} // namespace Data

View File

@ -0,0 +1,32 @@
/*
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
class ChannelData;
namespace Data {
class Feed {
public:
Feed(FeedId id);
void registerOne(not_null<ChannelData*> channel);
void unregisterOne(not_null<ChannelData*> channel);
void setUnreadCounts(int unreadCount, int unreadMutedCount);
private:
FeedId _id = 0;
base::flat_set<not_null<ChannelData*>> _channels;
int _unreadCount = 0;
int _unreadMutedCount = 0;
bool _complete = false;
};
} // namespace Data

View File

@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_peer_values.h"
#include "data/data_channel_admins.h"
#include "data/data_photo.h"
#include "data/data_feed.h"
#include "lang/lang_keys.h"
#include "observer_peer.h"
#include "mainwidget.h"
@ -849,6 +850,26 @@ void ChannelData::setPinnedMessageId(MsgId messageId) {
}
}
void ChannelData::setFeed(not_null<Data::Feed*> feed) {
setFeedPointer(feed);
}
void ChannelData::clearFeed() {
setFeedPointer(nullptr);
}
void ChannelData::setFeedPointer(Data::Feed *feed) {
if (_feed != feed) {
if (_feed) {
_feed->unregisterOne(this);
}
_feed = feed;
if (_feed) {
_feed->registerOne(this);
}
}
}
bool ChannelData::canBanMembers() const {
return (adminRights() & AdminRight::f_ban_users)
|| amCreator();

View File

@ -22,6 +22,8 @@ class ChannelData;
namespace Data {
class Feed;
int PeerColorIndex(PeerId peerId);
int PeerColorIndex(int32 bareId);
style::color PeerUserpicColor(PeerId peerId);
@ -103,6 +105,7 @@ public:
ChatData *migrateFrom() const;
ChannelData *migrateTo() const;
Data::Feed *feed() const;
void updateFull();
void updateFullForced();
@ -1009,11 +1012,19 @@ public:
setPinnedMessageId(0);
}
void setFeed(not_null<Data::Feed*> feed);
void clearFeed();
Data::Feed *feed() const {
return _feed;
}
private:
void flagsUpdated(MTPDchannel::Flags diff);
void fullFlagsUpdated(MTPDchannelFull::Flags diff);
bool canEditLastAdmin(not_null<UserData*> user) const;
void setFeedPointer(Data::Feed *feed);
Flags _flags = Flags(MTPDchannel_ClientFlag::f_forbidden | 0);
FullFlags _fullFlags;
@ -1035,6 +1046,7 @@ private:
QString _about;
QString _inviteLink;
Data::Feed *_feed = nullptr;
rpl::lifetime _lifetime;
@ -1105,16 +1117,26 @@ inline bool isMegagroup(const PeerData *peer) {
return peer ? peer->isMegagroup() : false;
}
inline ChatData *PeerData::migrateFrom() const {
return (isMegagroup() && asChannel()->amIn())
? asChannel()->mgInfo->migrateFromPtr
: nullptr;
if (const auto megagroup = asMegagroup()) {
return megagroup->amIn()
? megagroup->mgInfo->migrateFromPtr
: nullptr;
}
return nullptr;
}
inline ChannelData *PeerData::migrateTo() const {
return (isChat()
&& asChat()->migrateToPtr
&& asChat()->migrateToPtr->amIn())
? asChat()->migrateToPtr
: nullptr;
if (const auto chat = asChat()) {
if (const auto migrateTo = chat->migrateToPtr) {
return migrateTo->amIn() ? migrateTo : nullptr;
}
}
return nullptr;
}
inline Data::Feed *PeerData::feed() const {
if (const auto channel = asChannel()) {
return channel->feed();
}
return nullptr;
}
inline const Text &PeerData::dialogName() const {
return migrateTo()

View File

@ -27,6 +27,7 @@ class ChannelData;
using UserId = int32;
using ChatId = int32;
using ChannelId = int32;
using FeedId = int32;
constexpr auto NoChannel = ChannelId(0);

View File

@ -15,7 +15,7 @@ IndexedList::IndexedList(SortMode sortMode)
, _empty(sortMode) {
}
RowsByLetter IndexedList::addToEnd(History *history) {
RowsByLetter IndexedList::addToEnd(not_null<History*> history) {
RowsByLetter result;
if (!_list.contains(history->peer->id)) {
result.emplace(0, _list.addToEnd(history));
@ -32,8 +32,8 @@ RowsByLetter IndexedList::addToEnd(History *history) {
return result;
}
Row *IndexedList::addByName(History *history) {
if (auto row = _list.getRow(history->peer->id)) {
Row *IndexedList::addByName(not_null<History*> history) {
if (const auto row = _list.getRow(history->peer->id)) {
return row;
}
@ -105,11 +105,14 @@ void IndexedList::peerNameChanged(Mode list, not_null<PeerData*> peer, const Pee
adjustNames(list, peer, oldChars);
}
void IndexedList::adjustByName(not_null<PeerData*> peer, const PeerData::NameFirstChars &oldChars) {
Row *mainRow = _list.adjustByName(peer);
void IndexedList::adjustByName(
not_null<PeerData*> peer,
const PeerData::NameFirstChars &oldChars) {
const auto mainRow = _list.adjustByName(peer);
if (!mainRow) return;
History *history = mainRow->history();
// #TODO dialogs
const auto history = mainRow->history();
PeerData::NameFirstChars toRemove = oldChars, toAdd;
for (auto ch : peer->nameFirstChars()) {
@ -145,6 +148,7 @@ void IndexedList::adjustNames(Mode list, not_null<PeerData*> peer, const PeerDat
auto mainRow = _list.getRow(peer->id);
if (!mainRow) return;
// #TODO dialogs
auto history = mainRow->history();
PeerData::NameFirstChars toRemove = oldChars, toAdd;

View File

@ -18,8 +18,8 @@ class IndexedList {
public:
IndexedList(SortMode sortMode);
RowsByLetter addToEnd(History *history);
Row *addByName(History *history);
RowsByLetter addToEnd(not_null<History*> history);
Row *addByName(not_null<History*> history);
void adjustByPos(const RowsByLetter &links);
void moveToTop(not_null<PeerData*> peer);

View File

@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/popup_menu.h"
#include "ui/text_options.h"
#include "data/data_drafts.h"
#include "data/data_feed.h"
#include "lang/lang_keys.h"
#include "mainwindow.h"
#include "mainwidget.h"
@ -1561,7 +1562,27 @@ void DialogsInner::applyDialog(const MTPDdialog &dialog) {
}
void DialogsInner::applyFeedDialog(const MTPDdialogFeed &dialog) {
// #TODO feeds
const auto peerId = peerFromMTP(dialog.vpeer);
const auto feedId = dialog.vfeed_id.v;
const auto feed = Auth().data().feed(feedId);
const auto addChannel = [&](ChannelId channelId) {
if (const auto channel = App::channelLoaded(channelId)) {
channel->setFeed(feed);
}
};
if (peerId && peerIsChannel(peerId)) {
addChannel(peerToChannel(peerId));
}
for (const auto &channelId : dialog.vfeed_other_channels.v) {
addChannel(channelId.v);
}
feed->setUnreadCounts(
dialog.vunread_count.v,
dialog.vunread_muted_count.v);
if (dialog.has_read_max_position()) {
// #TODO feeds
// feed->set
}
}
void DialogsInner::addSavedPeersAfter(const QDateTime &date) {

View File

@ -33,8 +33,8 @@ void List::adjustCurrent(int32 y, int32 h) const {
}
}
Row *List::addToEnd(History *history) {
Row *result = new Row(history, _end->_prev, _end, _end->_pos);
Row *List::addToEnd(not_null<History*> history) {
const auto result = new Row(history, _end->_prev, _end, _end->_pos);
_end->_pos++;
if (_begin == _end) {
_begin = _current = result;
@ -121,10 +121,13 @@ Row *List::adjustByName(const PeerData *peer) {
return row;
}
Row *List::addByName(History *history) {
if (_sortMode != SortMode::Name) return nullptr;
Row *List::addByName(not_null<History*> history) {
if (_sortMode != SortMode::Name) {
return nullptr;
}
Row *row = addToEnd(history), *change = row;
const auto row = addToEnd(history);
auto change = row;
const QString &peerName(history->peer->name);
while (change->_prev && change->_prev->history()->peer->name.compare(peerName, Qt::CaseInsensitive) > 0) {
change = change->_prev;

View File

@ -38,9 +38,9 @@ public:
return *i;
}
Row *addToEnd(History *history);
Row *addToEnd(not_null<History*> history);
Row *adjustByName(const PeerData *peer);
Row *addByName(History *history);
Row *addByName(not_null<History*> history);
bool moveToTop(PeerId peerId);
void adjustByPos(Row *row);
bool del(PeerId peerId, Row *replacedBy = nullptr);

View File

@ -167,6 +167,8 @@
<(src_loc)/data/data_document.h
<(src_loc)/data/data_drafts.cpp
<(src_loc)/data/data_drafts.h
<(src_loc)/data/data_feed.cpp
<(src_loc)/data/data_feed.h
<(src_loc)/data/data_flags.h
<(src_loc)/data/data_game.h
<(src_loc)/data/data_notify_settings.cpp