Don't show downloads bar while message is visible.

This commit is contained in:
John Preston 2022-03-09 14:52:44 +04:00
parent f1064e2d2f
commit 6dd720b76e
9 changed files with 102 additions and 24 deletions

View file

@ -105,6 +105,25 @@ void DownloadManager::trackSession(not_null<Main::Session*> session) {
}, data.lifetime); }, data.lifetime);
} }
void DownloadManager::itemVisibilitiesUpdated(
not_null<Main::Session*> session) {
const auto i = _sessions.find(session);
if (i == end(_sessions)
|| i->second.downloading.empty()
|| !i->second.downloading.front().hiddenByView) {
return;
}
for (const auto &id : i->second.downloading) {
if (!session->data().queryItemVisibility(id.object.item)) {
for (auto &id : i->second.downloading) {
id.hiddenByView = false;
}
_loadingListChanges.fire({});
return;
}
}
}
int64 DownloadManager::computeNextStartDate() { int64 DownloadManager::computeNextStartDate() {
const auto now = base::unixtime::now(); const auto now = base::unixtime::now();
if (_lastStartedBase != now) { if (_lastStartedBase != now) {
@ -140,11 +159,15 @@ void DownloadManager::addLoading(DownloadObject object) {
return; return;
} }
const auto shownExists = !data.downloading.empty()
&& !data.downloading.front().hiddenByView;
data.downloading.push_back({ data.downloading.push_back({
.object = object, .object = object,
.started = computeNextStartDate(), .started = computeNextStartDate(),
.path = path, .path = path,
.total = size, .total = size,
.hiddenByView = (!shownExists
&& item->history()->owner().queryItemVisibility(item)),
}); });
_loading.emplace(item); _loading.emplace(item);
_loadingDocuments.emplace(object.document); _loadingDocuments.emplace(object.document);
@ -908,6 +931,9 @@ rpl::producer<Ui::DownloadBarContent> MakeDownloadBarContent() {
auto content = Ui::DownloadBarContent(); auto content = Ui::DownloadBarContent();
auto single = (const Data::DownloadObject*) nullptr; auto single = (const Data::DownloadObject*) nullptr;
for (const auto id : manager.loadingList()) { for (const auto id : manager.loadingList()) {
if (id->hiddenByView) {
break;
}
if (!single) { if (!single) {
single = &id->object; single = &id->object;
} }

View file

@ -71,6 +71,7 @@ struct DownloadingId {
QString path; QString path;
int ready = 0; int ready = 0;
int total = 0; int total = 0;
bool hiddenByView = false;
bool done = false; bool done = false;
}; };
@ -80,6 +81,7 @@ public:
~DownloadManager(); ~DownloadManager();
void trackSession(not_null<Main::Session*> session); void trackSession(not_null<Main::Session*> session);
void itemVisibilitiesUpdated(not_null<Main::Session*> session);
[[nodiscard]] DownloadDate computeNextStartDate(); [[nodiscard]] DownloadDate computeNextStartDate();

View file

@ -44,6 +44,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_chat.h" #include "data/data_chat.h"
#include "data/data_user.h" #include "data/data_user.h"
#include "data/data_file_origin.h" #include "data/data_file_origin.h"
#include "data/data_download_manager.h"
#include "data/data_photo.h" #include "data/data_photo.h"
#include "data/data_document.h" #include "data/data_document.h"
#include "data/data_web_page.h" #include "data/data_web_page.h"
@ -1373,6 +1374,24 @@ void Session::changeMessageId(PeerId peerId, MsgId wasId, MsgId nowId) {
Ensures(ok); Ensures(ok);
} }
bool Session::queryItemVisibility(not_null<HistoryItem*> item) const {
auto result = false;
_itemVisibilityQueries.fire({ item, &result });
return result;
}
[[nodiscard]] auto Session::itemVisibilityQueries() const
-> rpl::producer<Session::ItemVisibilityQuery> {
return _itemVisibilityQueries.events();
}
void Session::itemVisibilitiesUpdated() {
// This could be rewritten in a more generic form, like:
// rpl::producer<> itemVisibilitiesUpdates()
// if someone else requires those methods, using fast for now.
Core::App().downloadManager().itemVisibilitiesUpdated(_session);
}
void Session::notifyItemIdChange(IdChange event) { void Session::notifyItemIdChange(IdChange event) {
const auto item = event.item; const auto item = event.item;
changeMessageId(item->history()->peer->id, event.oldId, item->id); changeMessageId(item->history()->peer->id, event.oldId, item->id);

View file

@ -227,9 +227,10 @@ public:
not_null<HistoryItem*> item; not_null<HistoryItem*> item;
not_null<bool*> isVisible; not_null<bool*> isVisible;
}; };
[[nodiscard]] base::Observable<ItemVisibilityQuery> &queryItemVisibility() { [[nodiscard]] bool queryItemVisibility(not_null<HistoryItem*> item) const;
return _queryItemVisibility; [[nodiscard]] rpl::producer<ItemVisibilityQuery> itemVisibilityQueries() const;
} void itemVisibilitiesUpdated();
struct IdChange { struct IdChange {
not_null<HistoryItem*> item; not_null<HistoryItem*> item;
MsgId oldId = 0; MsgId oldId = 0;
@ -839,7 +840,7 @@ private:
rpl::event_stream<Data::Folder*> _chatsListChanged; rpl::event_stream<Data::Folder*> _chatsListChanged;
rpl::event_stream<not_null<UserData*>> _userIsBotChanges; rpl::event_stream<not_null<UserData*>> _userIsBotChanges;
rpl::event_stream<not_null<PeerData*>> _botCommandsChanges; rpl::event_stream<not_null<PeerData*>> _botCommandsChanges;
base::Observable<ItemVisibilityQuery> _queryItemVisibility; rpl::event_stream<ItemVisibilityQuery> _itemVisibilityQueries;
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;
rpl::event_stream<not_null<const ViewElement*>> _viewLayoutChanges; rpl::event_stream<not_null<const ViewElement*>> _viewLayoutChanges;

View file

@ -300,20 +300,24 @@ InnerWidget::InnerWidget(
} }
} }
}, lifetime()); }, lifetime());
subscribe(session().data().queryItemVisibility(), [=]( session().data().itemVisibilityQueries(
) | rpl::filter([=](
const Data::Session::ItemVisibilityQuery &query) {
return (_history == query.item->history())
&& query.item->isAdminLogEntry()
&& isVisible();
}) | rpl::start_with_next([=](
const Data::Session::ItemVisibilityQuery &query) { const Data::Session::ItemVisibilityQuery &query) {
if (_history != query.item->history()
|| !query.item->isAdminLogEntry()
|| !isVisible()) {
return;
}
if (const auto view = viewForItem(query.item)) { if (const auto view = viewForItem(query.item)) {
auto top = itemTop(view); auto top = itemTop(view);
if (top >= 0 && top + view->height() > _visibleTop && top < _visibleBottom) { if (top >= 0
&& top + view->height() > _visibleTop
&& top < _visibleBottom) {
*query.isVisible = true; *query.isVisible = true;
} }
} }
}); }, lifetime());
updateEmptyText(); updateEmptyText();
requestAdmins(); requestAdmins();
@ -355,6 +359,7 @@ void InnerWidget::visibleTopBottomUpdated(
scrollDateHideByTimer(); scrollDateHideByTimer();
} }
_controller->floatPlayerAreaUpdated(); _controller->floatPlayerAreaUpdated();
session().data().itemVisibilitiesUpdated();
} }
void InnerWidget::updateVisibleTopItem() { void InnerWidget::updateVisibleTopItem() {

View file

@ -760,13 +760,15 @@ HistoryWidget::HistoryWidget(
updateNotifyControls(); updateNotifyControls();
}, lifetime()); }, lifetime());
subscribe(session().data().queryItemVisibility(), [=]( session().data().itemVisibilityQueries(
) | rpl::filter([=](
const Data::Session::ItemVisibilityQuery &query) {
return !_a_show.animating()
&& (_history == query.item->history())
&& (query.item->mainView() != nullptr)
&& isVisible();
}) | rpl::start_with_next([=](
const Data::Session::ItemVisibilityQuery &query) { const Data::Session::ItemVisibilityQuery &query) {
if (_a_show.animating()
|| _history != query.item->history()
|| !query.item->mainView() || !isVisible()) {
return;
}
if (const auto view = query.item->mainView()) { if (const auto view = query.item->mainView()) {
auto top = _list->itemTop(view); auto top = _list->itemTop(view);
if (top >= 0) { if (top >= 0) {
@ -777,7 +779,8 @@ HistoryWidget::HistoryWidget(
} }
} }
} }
}); }, lifetime());
_topBar->membersShowAreaActive( _topBar->membersShowAreaActive(
) | rpl::start_with_next([=](bool active) { ) | rpl::start_with_next([=](bool active) {
setMembersShowAreaActive(active); setMembersShowAreaActive(active);
@ -2301,6 +2304,7 @@ void HistoryWidget::showHistory(
} }
update(); update();
controller()->floatPlayerAreaUpdated(); controller()->floatPlayerAreaUpdated();
session().data().itemVisibilitiesUpdated();
crl::on_main(this, [=] { controller()->widget()->setInnerFocus(); }); crl::on_main(this, [=] { controller()->widget()->setInnerFocus(); });
} }
@ -3332,6 +3336,7 @@ void HistoryWidget::visibleAreaUpdated() {
const auto scrollBottom = scrollTop + _scroll->height(); const auto scrollBottom = scrollTop + _scroll->height();
_list->visibleAreaUpdated(scrollTop, scrollBottom); _list->visibleAreaUpdated(scrollTop, scrollBottom);
controller()->floatPlayerAreaUpdated(); controller()->floatPlayerAreaUpdated();
session().data().itemVisibilitiesUpdated();
} }
} }

View file

@ -331,7 +331,9 @@ ListWidget::ListWidget(
itemRemoved(item); itemRemoved(item);
}, lifetime()); }, lifetime());
subscribe(session().data().queryItemVisibility(), [this](const Data::Session::ItemVisibilityQuery &query) { session().data().itemVisibilityQueries(
) | rpl::start_with_next([=](
const Data::Session::ItemVisibilityQuery &query) {
if (const auto view = viewForItem(query.item)) { if (const auto view = viewForItem(query.item)) {
const auto top = itemTop(view); const auto top = itemTop(view);
if (top >= 0 if (top >= 0
@ -340,7 +342,7 @@ ListWidget::ListWidget(
*query.isVisible = true; *query.isVisible = true;
} }
} }
}); }, lifetime());
using ChosenReaction = Reactions::Manager::Chosen; using ChosenReaction = Reactions::Manager::Chosen;
_reactionsManager->chosen( _reactionsManager->chosen(
@ -794,6 +796,7 @@ void ListWidget::visibleTopBottomUpdated(
scrollDateHideByTimer(); scrollDateHideByTimer();
} }
_controller->floatPlayerAreaUpdated(); _controller->floatPlayerAreaUpdated();
session().data().itemVisibilitiesUpdated();
_applyUpdatedScrollState.call(); _applyUpdatedScrollState.call();
} }

View file

@ -169,6 +169,23 @@ void ListWidget::start() {
) | rpl::start_with_next([this] { ) | rpl::start_with_next([this] {
restart(); restart();
}, lifetime()); }, lifetime());
if (_provider->type() == Type::File) {
// For downloads manager.
session().data().itemVisibilityQueries(
) | rpl::filter([=](
const Data::Session::ItemVisibilityQuery &query) {
return _provider->isPossiblyMyItem(query.item)
&& isVisible();
}) | rpl::start_with_next([=](
const Data::Session::ItemVisibilityQuery &query) {
if (const auto found = findItemByItem(query.item)) {
if (itemVisible(found->layout)) {
*query.isVisible = true;
}
}
}, lifetime());
}
} }
setupSelectRestriction(); setupSelectRestriction();
@ -566,6 +583,8 @@ void ListWidget::visibleTopBottomUpdated(
_dateBadge->check.call(); _dateBadge->check.call();
} }
} }
session().data().itemVisibilitiesUpdated();
} }
void ListWidget::updateDateBadgeFor(int top) { void ListWidget::updateDateBadgeFor(int top) {

View file

@ -479,9 +479,7 @@ void MainWidget::floatPlayerEnumerateSections(Fn<void(
} }
bool MainWidget::floatPlayerIsVisible(not_null<HistoryItem*> item) { bool MainWidget::floatPlayerIsVisible(not_null<HistoryItem*> item) {
auto isVisible = false; return session().data().queryItemVisibility(item);
session().data().queryItemVisibility().notify({ item, &isVisible }, true);
return isVisible;
} }
void MainWidget::floatPlayerClosed(FullMsgId itemId) { void MainWidget::floatPlayerClosed(FullMsgId itemId) {