Add ability to archive/unarchive the chats.

This commit is contained in:
John Preston 2019-04-18 12:28:43 +04:00
parent c58f097535
commit 854870683b
17 changed files with 210 additions and 129 deletions

View File

@ -1192,10 +1192,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_channel_mute" = "Mute"; "lng_channel_mute" = "Mute";
"lng_channel_unmute" = "Unmute"; "lng_channel_unmute" = "Unmute";
"lng_saved_messages" = "Saved Messages"; "lng_saved_messages" = "Saved Messages";
"lng_archived_chats" = "Archived chats";
"lng_saved_short" = "Save"; "lng_saved_short" = "Save";
"lng_saved_forward_here" = "Forward messages here for quick access"; "lng_saved_forward_here" = "Forward messages here for quick access";
"lng_archived_chats" = "Archived chats";
"lng_archived_add" = "Archive";
"lng_archived_remove" = "Unarchive";
"lng_chat_archived" = "Chat archived.\nMuted chats will stay archived after new messages arrive.";
"lng_chat_unarchived" = "Chat restored from your archive.";
"lng_dialogs_text_with_from" = "{from_part} {message}"; "lng_dialogs_text_with_from" = "{from_part} {message}";
"lng_dialogs_text_from_wrapped" = "{from}:"; "lng_dialogs_text_from_wrapped" = "{from}:";
"lng_dialogs_text_media" = "{media_part} {caption}"; "lng_dialogs_text_media" = "{media_part} {caption}";

View File

@ -460,29 +460,27 @@ void ApiWrap::toggleHistoryArchived(
if (const auto already = _historyArchivedRequests.take(history)) { if (const auto already = _historyArchivedRequests.take(history)) {
request(already->first).cancel(); request(already->first).cancel();
} }
// #TODO archive const auto archiveId = Data::Folder::kId;
const auto folderId = Data::Folder::kId; const auto requestId = request(MTPfolders_EditPeerFolders(
//const auto flags = group MTP_vector<MTPInputFolderPeer>(
// ? MTPchannels_ChangeFeedBroadcast::Flag::f_feed_id 1,
// : MTPchannels_ChangeFeedBroadcast::Flag(0); MTP_inputFolderPeer(
//const auto requestId = request(MTPchannels_ChangeFeedBroadcast( history->peer->input,
// MTP_flags(flags), MTP_int(archived ? archiveId : 0)))
// channel->inputChannel, )).done([=](const MTPUpdates &result) {
// MTP_int(feedId) applyUpdates(result);
//)).done([=](const MTPUpdates &result) { if (archived) {
// applyUpdates(result); history->setFolder(_session->data().folder(archiveId));
// if (group) { } else {
// channel->setFeed(_session->data().feed(feedId)); history->clearFolder();
// } else { }
// channel->clearFeed(); if (const auto data = _historyArchivedRequests.take(history)) {
// } data->second();
// if (const auto data = _channelGroupingRequests.take(channel)) { }
// data->second(); }).fail([=](const RPCError &error) {
// } _historyArchivedRequests.remove(history);
//}).fail([=](const RPCError &error) { }).send();
// _channelGroupingRequests.remove(channel); _historyArchivedRequests.emplace(history, requestId, callback);
//}).send();
//_channelGroupingRequests.emplace(channel, requestId, callback);
} }
// #feed // #feed
//void ApiWrap::ungroupAllFromFeed(not_null<Data::Feed*> feed) { //void ApiWrap::ungroupAllFromFeed(not_null<Data::Feed*> feed) {
@ -678,7 +676,7 @@ QString ApiWrap::exportDirectMessageLink(not_null<HistoryItem*> item) {
} }
void ApiWrap::requestContacts() { void ApiWrap::requestContacts() {
if (_session->data().contactsLoaded().value() || _contactsRequestId) { if (_session->data().contactsLoaded().current() || _contactsRequestId) {
return; return;
} }
_contactsRequestId = request(MTPcontacts_GetContacts( _contactsRequestId = request(MTPcontacts_GetContacts(
@ -700,7 +698,7 @@ void ApiWrap::requestContacts() {
UserData::ContactStatus::Contact); UserData::ContactStatus::Contact);
} }
} }
_session->data().contactsLoaded().set(true); _session->data().contactsLoaded() = true;
}).fail([=](const RPCError &error) { }).fail([=](const RPCError &error) {
_contactsRequestId = 0; _contactsRequestId = 0;
}).send(); }).send();
@ -767,17 +765,12 @@ void ApiWrap::requestMoreDialogs(FolderId folderId) {
if (!folderId) { if (!folderId) {
requestDialogs(); requestDialogs();
requestContacts();
if (!_dialogsLoadState || !_dialogsLoadState->requestId) { if (!_dialogsLoadState || !_dialogsLoadState->requestId) {
refreshDialogsLoadBlocked(); refreshDialogsLoadBlocked();
} }
} }
_session->data().moreChatsLoaded().notify(); _session->data().chatsListChanged(folderId);
if (!folderId) {
if (!_dialogsLoadState && _pinnedDialogsReceived) {
_session->data().allChatsLoaded().set(true);
}
requestContacts();
}
}).fail([=](const RPCError &error) { }).fail([=](const RPCError &error) {
dialogsLoadState(folderId)->requestId = 0; dialogsLoadState(folderId)->requestId = 0;
}).send(); }).send();
@ -852,11 +845,19 @@ auto ApiWrap::dialogsLoadState(FolderId folderId) -> DialogsLoadState* {
} }
void ApiWrap::dialogsLoadFinish(FolderId folderId) { void ApiWrap::dialogsLoadFinish(FolderId folderId) {
const auto notify = [&] {
Core::App().postponeCall(crl::guard(_session, [=] {
_session->data().chatsListDone(folderId);
}));
};
if (folderId) { if (folderId) {
_session->data().folder(folderId)->setChatsListLoaded(true);
_foldersLoadState.remove(folderId); _foldersLoadState.remove(folderId);
notify();
} else { } else {
_dialogsLoadState = nullptr; _dialogsLoadState = nullptr;
if (_pinnedDialogsReceived) {
notify();
}
} }
} }
@ -865,7 +866,6 @@ void ApiWrap::requestPinnedDialogs() {
return; return;
} }
_pinnedDialogsReceived = false;
const auto folderId = FolderId(0); const auto folderId = FolderId(0);
_pinnedDialogsRequestId = request(MTPmessages_GetPinnedDialogs( _pinnedDialogsRequestId = request(MTPmessages_GetPinnedDialogs(
MTP_int(folderId) MTP_int(folderId)
@ -884,9 +884,9 @@ void ApiWrap::requestPinnedDialogs() {
_pinnedDialogsRequestId = 0; _pinnedDialogsRequestId = 0;
_pinnedDialogsReceived = true; _pinnedDialogsReceived = true;
_session->data().moreChatsLoaded().notify(); _session->data().chatsListChanged(folderId);
if (!_dialogsLoadState) { if (!_dialogsLoadState) {
_session->data().allChatsLoaded().set(true); _session->data().chatsListDone(folderId);
} }
}); });
}).fail([=](const RPCError &error) { }).fail([=](const RPCError &error) {

View File

@ -225,18 +225,26 @@ void ChatsListBoxController::prepare() {
prepareViewHook(); prepareViewHook();
rebuildRows(); if (!Auth().data().chatsListLoaded()) {
Auth().data().chatsListLoadedEvents(
auto &sessionData = Auth().data(); ) | rpl::filter([=](Data::Folder *folder) {
subscribe(sessionData.contactsLoaded(), [this](bool loaded) { return !folder;
rebuildRows(); }) | rpl::start_with_next([=] {
});
subscribe(sessionData.moreChatsLoaded(), [this] {
rebuildRows();
});
subscribe(sessionData.allChatsLoaded(), [this](bool loaded) {
checkForEmptyRows(); checkForEmptyRows();
}); }, lifetime());
}
Auth().data().chatsListChanges(
) | rpl::filter([=](Data::Folder *folder) {
return !folder;
}) | rpl::start_with_next([=] {
rebuildRows();
}, lifetime());
Auth().data().contactsLoaded().value(
) | rpl::start_with_next([=] {
rebuildRows();
}, lifetime());
} }
void ChatsListBoxController::rebuildRows() { void ChatsListBoxController::rebuildRows() {
@ -280,8 +288,8 @@ void ChatsListBoxController::checkForEmptyRows() {
if (delegate()->peerListFullRowsCount()) { if (delegate()->peerListFullRowsCount()) {
setDescriptionText(QString()); setDescriptionText(QString());
} else { } else {
auto &sessionData = Auth().data(); const auto loaded = Auth().data().contactsLoaded().current()
auto loaded = sessionData.contactsLoaded().value() && sessionData.allChatsLoaded().value(); && Auth().data().chatsListLoaded();
setDescriptionText(loaded ? emptyBoxText() : lang(lng_contacts_loading)); setDescriptionText(loaded ? emptyBoxText() : lang(lng_contacts_loading));
} }
} }
@ -318,12 +326,10 @@ void ContactsBoxController::prepare() {
prepareViewHook(); prepareViewHook();
Auth().data().contactsLoaded().value(
) | rpl::start_with_next([=] {
rebuildRows(); rebuildRows();
}, lifetime());
auto &sessionData = Auth().data();
subscribe(sessionData.contactsLoaded(), [this](bool loaded) {
rebuildRows();
});
} }
void ContactsBoxController::rebuildRows() { void ContactsBoxController::rebuildRows() {
@ -349,8 +355,7 @@ void ContactsBoxController::checkForEmptyRows() {
if (delegate()->peerListFullRowsCount()) { if (delegate()->peerListFullRowsCount()) {
setDescriptionText(QString()); setDescriptionText(QString());
} else { } else {
auto &sessionData = Auth().data(); const auto loaded = Auth().data().contactsLoaded().current();
auto loaded = sessionData.contactsLoaded().value();
setDescriptionText(lang(loaded ? lng_contacts_not_found : lng_contacts_loading)); setDescriptionText(lang(loaded ? lng_contacts_not_found : lng_contacts_loading));
} }
} }
@ -473,13 +478,13 @@ bool AddBotToGroupBoxController::sharingBotGame() const {
} }
QString AddBotToGroupBoxController::emptyBoxText() const { QString AddBotToGroupBoxController::emptyBoxText() const {
return lang(Auth().data().allChatsLoaded().value() return lang(Auth().data().chatsListLoaded()
? (sharingBotGame() ? lng_bot_no_chats : lng_bot_no_groups) ? (sharingBotGame() ? lng_bot_no_chats : lng_bot_no_groups)
: lng_contacts_loading); : lng_contacts_loading);
} }
QString AddBotToGroupBoxController::noResultsText() const { QString AddBotToGroupBoxController::noResultsText() const {
return lang(Auth().data().allChatsLoaded().value() return lang(Auth().data().chatsListLoaded()
? (sharingBotGame() ? lng_bot_chats_not_found : lng_bot_groups_not_found) ? (sharingBotGame() ? lng_bot_chats_not_found : lng_bot_groups_not_found)
: lng_contacts_loading); : lng_contacts_loading);
} }
@ -493,7 +498,12 @@ void AddBotToGroupBoxController::prepareViewHook() {
? lng_bot_choose_chat ? lng_bot_choose_chat
: lng_bot_choose_group)); : lng_bot_choose_group));
updateLabels(); updateLabels();
subscribe(Auth().data().allChatsLoaded(), [this](bool) { updateLabels(); }); Auth().data().chatsListLoadedEvents(
) | rpl::filter([=](Data::Folder *folder) {
return !folder;
}) | rpl::start_with_next([=] {
updateLabels();
}, lifetime());
} }
ChooseRecipientBoxController::ChooseRecipientBoxController( ChooseRecipientBoxController::ChooseRecipientBoxController(

View File

@ -76,9 +76,7 @@ private:
}; };
class ChatsListBoxController class ChatsListBoxController : public PeerListController {
: public PeerListController
, protected base::Subscriber {
public: public:
ChatsListBoxController( ChatsListBoxController(
std::unique_ptr<PeerListSearchController> searchController std::unique_ptr<PeerListSearchController> searchController
@ -113,9 +111,7 @@ private:
}; };
class ContactsBoxController class ContactsBoxController : public PeerListController {
: public PeerListController
, protected base::Subscriber {
public: public:
ContactsBoxController( ContactsBoxController(
std::unique_ptr<PeerListSearchController> searchController std::unique_ptr<PeerListSearchController> searchController

View File

@ -103,9 +103,12 @@ QString FormatVersionPrecise(int version) {
Changelogs::Changelogs(not_null<AuthSession*> session, int oldVersion) Changelogs::Changelogs(not_null<AuthSession*> session, int oldVersion)
: _session(session) : _session(session)
, _oldVersion(oldVersion) { , _oldVersion(oldVersion) {
_chatsSubscription = subscribe( _session->data().chatsListChanges(
_session->data().moreChatsLoaded(), ) | rpl::filter([](Data::Folder *folder) {
[=] { requestCloudLogs(); }); return !folder;
}) | rpl::start_with_next([=] {
requestCloudLogs();
}, _chatsSubscription);
} }
std::unique_ptr<Changelogs> Changelogs::Create( std::unique_ptr<Changelogs> Changelogs::Create(
@ -117,7 +120,7 @@ std::unique_ptr<Changelogs> Changelogs::Create(
} }
void Changelogs::requestCloudLogs() { void Changelogs::requestCloudLogs() {
unsubscribe(base::take(_chatsSubscription)); _chatsSubscription.destroy();
const auto callback = [this](const MTPUpdates &result) { const auto callback = [this](const MTPUpdates &result) {
_session->api().applyUpdates(result); _session->api().applyUpdates(result);

View File

@ -29,7 +29,7 @@ private:
const not_null<AuthSession*> _session; const not_null<AuthSession*> _session;
const int _oldVersion = 0; const int _oldVersion = 0;
int _chatsSubscription = 0; rpl::lifetime _chatsSubscription;
bool _addedSomeLocal = false; bool _addedSomeLocal = false;
}; };

View File

@ -774,6 +774,28 @@ bool Session::sendActionsAnimationCallback(crl::time now) {
return !_sendActions.empty(); return !_sendActions.empty();
} }
bool Session::chatsListLoaded(Data::Folder *folder) {
return folder ? folder->chatsListLoaded() : _chatsListLoaded;
}
void Session::chatsListChanged(FolderId folderId) {
chatsListChanged(folderId ? folder(folderId).get() : nullptr);
}
void Session::chatsListChanged(Data::Folder *folder) {
_chatsListChanged.fire_copy(folder);
}
void Session::chatsListDone(FolderId folderId) {
const auto folder = folderId ? this->folder(folderId).get() : nullptr;
if (folder) {
folder->setChatsListLoaded(true);
} else {
_chatsListLoaded = true;
}
_chatsListLoadedEvents.fire_copy(folder);
}
Storage::Cache::Database &Session::cache() { Storage::Cache::Database &Session::cache() {
return *_cache; return *_cache;
} }

View File

@ -135,15 +135,19 @@ public:
const MTPSendMessageAction &action, const MTPSendMessageAction &action,
TimeId when); TimeId when);
[[nodiscard]] base::Variable<bool> &contactsLoaded() { [[nodiscard]] rpl::variable<bool> &contactsLoaded() {
return _contactsLoaded; return _contactsLoaded;
} }
[[nodiscard]] base::Variable<bool> &allChatsLoaded() { [[nodiscard]] rpl::producer<Data::Folder*> chatsListChanges() const {
return _allChatsLoaded; return _chatsListChanged.events();
} }
[[nodiscard]] base::Observable<void> &moreChatsLoaded() { [[nodiscard]] bool chatsListLoaded(Data::Folder *folder = nullptr);
return _moreChatsLoaded; [[nodiscard]] rpl::producer<Data::Folder*> chatsListLoadedEvents() const {
return _chatsListLoadedEvents.events();
} }
void chatsListChanged(FolderId folderId);
void chatsListChanged(Data::Folder *folder);
void chatsListDone(FolderId folderId);
struct ItemVisibilityQuery { struct ItemVisibilityQuery {
not_null<HistoryItem*> item; not_null<HistoryItem*> item;
@ -725,9 +729,10 @@ private:
TimeId _exportAvailableAt = 0; TimeId _exportAvailableAt = 0;
QPointer<BoxContent> _exportSuggestion; QPointer<BoxContent> _exportSuggestion;
base::Variable<bool> _contactsLoaded = { false }; rpl::variable<bool> _contactsLoaded = false;
base::Variable<bool> _allChatsLoaded = { false }; bool _chatsListLoaded = false;
base::Observable<void> _moreChatsLoaded; rpl::event_stream<Data::Folder*> _chatsListLoadedEvents;
rpl::event_stream<Data::Folder*> _chatsListChanged;
base::Observable<ItemVisibilityQuery> _queryItemVisibility; base::Observable<ItemVisibilityQuery> _queryItemVisibility;
rpl::event_stream<IdChange> _itemIdChanges; rpl::event_stream<IdChange> _itemIdChanges;
rpl::event_stream<not_null<const HistoryItem*>> _itemLayoutChanges; rpl::event_stream<not_null<const HistoryItem*>> _itemLayoutChanges;

View File

@ -89,8 +89,12 @@ DialogsInner::DialogsInner(QWidget *parent, not_null<Window::Controller*> contro
_cancelSearchFromUser->setClickedCallback([this] { searchFromUserChanged.notify(nullptr); }); _cancelSearchFromUser->setClickedCallback([this] { searchFromUserChanged.notify(nullptr); });
_cancelSearchFromUser->hide(); _cancelSearchFromUser->hide();
subscribe(session().downloaderTaskFinished(), [this] { update(); }); subscribe(session().downloaderTaskFinished(), [=] { update(); });
subscribe(session().data().contactsLoaded(), [this](bool) { refresh(); });
session().data().contactsLoaded().changes(
) | rpl::start_with_next([=] {
refresh();
}, lifetime());
session().data().itemRemoved( session().data().itemRemoved(
) | rpl::start_with_next([=](not_null<const HistoryItem*> item) { ) | rpl::start_with_next([=](not_null<const HistoryItem*> item) {
@ -362,7 +366,7 @@ void DialogsInner::paintEvent(QPaintEvent *e) {
p.fillRect(dialogsClip, st::dialogsBg); p.fillRect(dialogsClip, st::dialogsBg);
p.setFont(st::noContactsFont); p.setFont(st::noContactsFont);
p.setPen(st::noContactsColor); p.setPen(st::noContactsColor);
p.drawText(QRect(0, 0, fullWidth, st::noContactsHeight - (session().data().contactsLoaded().value() ? st::noContactsFont->height : 0)), lang(session().data().contactsLoaded().value() ? lng_no_chats : lng_contacts_loading), style::al_center); p.drawText(QRect(0, 0, fullWidth, st::noContactsHeight - (session().data().contactsLoaded().current() ? st::noContactsFont->height : 0)), lang(session().data().contactsLoaded().current() ? lng_no_chats : lng_contacts_loading), style::al_center);
} }
} else if (_state == State::Filtered) { } else if (_state == State::Filtered) {
if (!_hashtagResults.empty()) { if (!_hashtagResults.empty()) {
@ -1953,12 +1957,16 @@ void DialogsInner::notify_historyMuteUpdated(History *history) {
refreshDialog(history); refreshDialog(history);
} }
Data::Folder *DialogsInner::shownFolder() const {
return _openedFolder;
}
void DialogsInner::refresh(bool toTop) { void DialogsInner::refresh(bool toTop) {
int32 h = 0; int32 h = 0;
if (_state == State::Default) { if (_state == State::Default) {
if (shownDialogs()->empty()) { if (shownDialogs()->empty()) {
h = st::noContactsHeight; h = st::noContactsHeight;
if (session().data().contactsLoaded().value()) { if (session().data().contactsLoaded().current()) {
if (_addContactLnk->isHidden()) _addContactLnk->show(); if (_addContactLnk->isHidden()) _addContactLnk->show();
} else { } else {
if (!_addContactLnk->isHidden()) _addContactLnk->hide(); if (!_addContactLnk->isHidden()) _addContactLnk->hide();

View File

@ -68,6 +68,7 @@ public:
void scrollToEntry(const Dialogs::RowDescriptor &entry); void scrollToEntry(const Dialogs::RowDescriptor &entry);
Data::Folder *shownFolder() const;
int32 lastSearchDate() const; int32 lastSearchDate() const;
PeerData *lastSearchPeer() const; PeerData *lastSearchPeer() const;
MsgId lastSearchId() const; MsgId lastSearchId() const;

View File

@ -183,10 +183,13 @@ DialogsWidget::DialogsWidget(QWidget *parent, not_null<Window::Controller*> cont
}); });
connect(_scroll, SIGNAL(geometryChanged()), _inner, SLOT(onParentGeometryChanged())); connect(_scroll, SIGNAL(geometryChanged()), _inner, SLOT(onParentGeometryChanged()));
connect(_scroll, SIGNAL(scrolled()), this, SLOT(onListScroll())); connect(_scroll, SIGNAL(scrolled()), this, SLOT(onListScroll()));
subscribe(session().data().moreChatsLoaded(), [=] { session().data().chatsListChanges(
) | rpl::filter([=](Data::Folder *folder) {
return (folder == _inner->shownFolder());
}) | rpl::start_with_next([=] {
_inner->refresh(); _inner->refresh();
onListScroll(); onListScroll();
}); }, lifetime());
connect(_filter, &Ui::FlatInput::cancelled, [=] { connect(_filter, &Ui::FlatInput::cancelled, [=] {
onCancel(); onCancel();
}); });

View File

@ -1829,23 +1829,25 @@ void History::setFolderPointer(Data::Folder *folder) {
} }
using Mode = Dialogs::Mode; using Mode = Dialogs::Mode;
const auto wasAll = inChatList(Mode::All); const auto wasAll = inChatList(Mode::All);
const auto wasImportant = inChatList(Mode::Important); const auto wasImportant = wasAll && inChatList(Mode::Important);
if (wasAll) { if (wasAll) {
removeFromChatList(Mode::All); removeFromChatList(Mode::All);
}
if (wasImportant) { if (wasImportant) {
removeFromChatList(Mode::Important); removeFromChatList(Mode::Important);
} }
}
const auto was = std::exchange(_folder, folder); const auto was = std::exchange(_folder, folder);
if (was) { if (was) {
was->unregisterOne(this); was->unregisterOne(this);
} }
if (wasAll) { if (wasAll) {
addToChatList(Mode::All); addToChatList(Mode::All);
}
if (wasImportant) { if (wasImportant) {
addToChatList(Mode::Important); addToChatList(Mode::Important);
} }
owner().chatsListChanged(was);
owner().chatsListChanged(_folder);
}
if (_folder) { if (_folder) {
_folder->registerOne(this); _folder->registerOne(this);
} }

View File

@ -361,48 +361,55 @@ HistoryWidget::HistoryWidget(
confirmSendingFiles(data, CompressConfirm::No); confirmSendingFiles(data, CompressConfirm::No);
ActivateWindow(this->controller()); ActivateWindow(this->controller());
}); });
_attachDragPhoto->setDroppedCallback([this](const QMimeData *data) { _attachDragPhoto->setDroppedCallback([=](const QMimeData *data) {
confirmSendingFiles(data, CompressConfirm::Yes); confirmSendingFiles(data, CompressConfirm::Yes);
ActivateWindow(this->controller()); ActivateWindow(this->controller());
}); });
subscribe(Adaptive::Changed(), [this] { update(); }); subscribe(Adaptive::Changed(), [=] { update(); });
Auth().data().itemRemoved( Auth().data().itemRemoved(
) | rpl::start_with_next( ) | rpl::start_with_next([=](not_null<const HistoryItem*> item) {
[this](auto item) { itemRemoved(item); }, itemRemoved(item);
lifetime()); }, lifetime());
Auth().data().historyChanged( Auth().data().historyChanged(
) | rpl::start_with_next( ) | rpl::start_with_next([=](not_null<History*> history) {
[=](auto history) { handleHistoryChange(history); }, handleHistoryChange(history);
lifetime()); }, lifetime());
Auth().data().viewResizeRequest( Auth().data().viewResizeRequest(
) | rpl::start_with_next([this](auto view) { ) | rpl::start_with_next([=](not_null<HistoryView::Element*> view) {
if (view->data()->mainView() == view) { if (view->data()->mainView() == view) {
updateHistoryGeometry(); updateHistoryGeometry();
} }
}, lifetime()); }, lifetime());
Auth().data().itemViewRefreshRequest( Auth().data().itemViewRefreshRequest(
) | rpl::start_with_next([this](auto item) { ) | rpl::start_with_next([=](not_null<HistoryItem*> item) {
// While HistoryInner doesn't own item views we must refresh them // While HistoryInner doesn't own item views we must refresh them
// even if the list is not yet created / was destroyed. // even if the list is not yet created / was destroyed.
if (!_list) { if (!_list) {
item->refreshMainView(); item->refreshMainView();
} }
}, lifetime()); }, lifetime());
Auth().data().animationPlayInlineRequest( Auth().data().animationPlayInlineRequest(
) | rpl::start_with_next([=](auto item) { ) | rpl::start_with_next([=](not_null<HistoryItem*> item) {
if (const auto view = item->mainView()) { if (const auto view = item->mainView()) {
if (const auto media = view->media()) { if (const auto media = view->media()) {
media->playAnimation(); media->playAnimation();
} }
} }
}, lifetime()); }, lifetime());
subscribe(Auth().data().contactsLoaded(), [this](bool) {
Auth().data().contactsLoaded().changes(
) | rpl::start_with_next([=] {
if (_peer) { if (_peer) {
updateReportSpamStatus(); updateReportSpamStatus();
updateControlsVisibility(); updateControlsVisibility();
} }
}); }, lifetime());
subscribe(Media::Player::instance()->switchToNextNotifier(), [this](const Media::Player::Instance::Switch &pair) { subscribe(Media::Player::instance()->switchToNextNotifier(), [this](const Media::Player::Instance::Switch &pair) {
if (pair.from.type() == AudioMsgId::Type::Voice) { if (pair.from.type() == AudioMsgId::Type::Voice) {
scrollToCurrentVoiceMessage(pair.from.contextId(), pair.to); scrollToCurrentVoiceMessage(pair.from.contextId(), pair.to);
@ -1863,7 +1870,7 @@ void HistoryWidget::updateReportSpamStatus() {
} }
} }
auto status = dbiprsRequesting; auto status = dbiprsRequesting;
if (!Auth().data().contactsLoaded().value() || _firstLoadRequest) { if (!Auth().data().contactsLoaded().current() || _firstLoadRequest) {
status = dbiprsUnknown; status = dbiprsUnknown;
} else if (_peer->isUser() } else if (_peer->isUser()
&& _peer->asUser()->contactStatus() == UserData::ContactStatus::Contact) { && _peer->asUser()->contactStatus() == UserData::ContactStatus::Contact) {

View File

@ -39,7 +39,9 @@ namespace {
constexpr auto kBlockedPerPage = 40; constexpr auto kBlockedPerPage = 40;
class BlockUserBoxController : public ChatsListBoxController { class BlockUserBoxController
: public ChatsListBoxController
, private base::Subscriber {
public: public:
void rowClicked(not_null<PeerListRow*> row) override; void rowClicked(not_null<PeerListRow*> row) override;

View File

@ -620,6 +620,9 @@ void MainWindow::setInactivePress(bool inactive) {
} }
} }
MainWindow::~MainWindow() = default; MainWindow::~MainWindow() {
// We want to delete all widgets before the _controller.
_body.destroy();
}
} // namespace Window } // namespace Window

View File

@ -20,7 +20,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mainwidget.h" #include "mainwidget.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "observer_peer.h" #include "observer_peer.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 "support/support_helper.h" #include "support/support_helper.h"
@ -37,6 +36,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_user.h" #include "data/data_user.h"
#include "dialogs/dialogs_key.h" #include "dialogs/dialogs_key.h"
#include "boxes/peers/edit_peer_info_box.h" #include "boxes/peers/edit_peer_info_box.h"
#include "styles/style_boxes.h"
#include "styles/style_window.h" // st::windowMinWidth
namespace Window { namespace Window {
namespace { namespace {
@ -56,6 +57,7 @@ private:
void addInfo(); void addInfo();
void addSearch(); void addSearch();
void addToggleUnreadMark(); void addToggleUnreadMark();
void addToggleArchive();
void addUserActions(not_null<UserData*> user); void addUserActions(not_null<UserData*> user);
void addBlockUser(not_null<UserData*> user); void addBlockUser(not_null<UserData*> user);
void addChatActions(not_null<ChatData*> chat); void addChatActions(not_null<ChatData*> chat);
@ -94,7 +96,7 @@ private:
History *FindWastedPin() { History *FindWastedPin() {
const auto &order = Auth().data().pinnedDialogsOrder(); const auto &order = Auth().data().pinnedDialogsOrder();
for (const auto pinned : order) { for (const auto &pinned : order) {
if (const auto history = pinned.history()) { if (const auto history = pinned.history()) {
if (history->peer->isChat() if (history->peer->isChat()
&& history->peer->asChat()->isDeactivated() && history->peer->asChat()->isDeactivated()
@ -271,6 +273,22 @@ void Filler::addToggleUnreadMark() {
}, *lifetime); }, *lifetime);
} }
void Filler::addToggleArchive() {
const auto peer = _peer;
const auto archived = [&] {
const auto history = peer->owner().historyLoaded(peer);
return history && history->folder();
}();
const auto toggle = [=] {
ToggleHistoryArchived(
peer->owner().history(peer),
!archived);
};
_addAction(
lang(archived ? lng_archived_remove : lng_archived_add),
toggle);
}
void Filler::addBlockUser(not_null<UserData*> user) { void Filler::addBlockUser(not_null<UserData*> user) {
auto blockText = [](not_null<UserData*> user) { auto blockText = [](not_null<UserData*> user) {
return lang(user->isBlocked() return lang(user->isBlocked()
@ -477,6 +495,9 @@ void Filler::fill() {
} else if (const auto channel = _peer->asChannel()) { } else if (const auto channel = _peer->asChannel()) {
addChannelActions(channel); addChannelActions(channel);
} }
if (_source == PeerMenuSource::ChatsList) {
addToggleArchive();
}
} }
FolderFiller::FolderFiller( FolderFiller::FolderFiller(
@ -767,24 +788,17 @@ void PeerMenuAddMuteAction(
// [=] { Ui::hideLayer(); Auth().api().ungroupAllFromFeed(feed); })); // [=] { Ui::hideLayer(); Auth().api().ungroupAllFromFeed(feed); }));
//} //}
// //
//void ToggleChannelGrouping(not_null<ChannelData*> channel, bool group) { void ToggleHistoryArchived(not_null<History*> history, bool archived) {
// const auto callback = [=] { const auto callback = [=] {
// Ui::Toast::Show(lang(group Ui::Toast::Show(lang(archived
// ? lng_feed_channel_added ? lng_chat_archived
// : lng_feed_channel_removed)); : lng_chat_unarchived));
// }; };
// if (group) { history->session().api().toggleHistoryArchived(
// const auto feed = Auth().data().feed(Data::Feed::kId); history,
// if (feed->channels().size() < 2) { archived,
// Info::FeedProfile::EditController::Start(feed, channel); callback);
// return; }
// }
// }
// Auth().api().toggleChannelGrouping(
// channel,
// group,
// callback);
//}
Fn<void()> ClearHistoryHandler(not_null<PeerData*> peer) { Fn<void()> ClearHistoryHandler(not_null<PeerData*> peer) {
return [=] { return [=] {

View File

@ -52,7 +52,7 @@ void PeerMenuAddChannelMembers(not_null<ChannelData*> channel);
//void PeerMenuUngroupFeed(not_null<Data::Feed*> feed); // #feed //void PeerMenuUngroupFeed(not_null<Data::Feed*> feed); // #feed
void PeerMenuCreatePoll(not_null<PeerData*> peer); void PeerMenuCreatePoll(not_null<PeerData*> peer);
//void ToggleChannelGrouping(not_null<ChannelData*> channel, bool group); // #feed void ToggleHistoryArchived(not_null<History*> history, bool archived);
Fn<void()> ClearHistoryHandler(not_null<PeerData*> peer); Fn<void()> ClearHistoryHandler(not_null<PeerData*> peer);
Fn<void()> DeleteAndLeaveHandler(not_null<PeerData*> peer); Fn<void()> DeleteAndLeaveHandler(not_null<PeerData*> peer);