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);
}
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() {
const auto now = base::unixtime::now();
if (_lastStartedBase != now) {
@ -140,11 +159,15 @@ void DownloadManager::addLoading(DownloadObject object) {
return;
}
const auto shownExists = !data.downloading.empty()
&& !data.downloading.front().hiddenByView;
data.downloading.push_back({
.object = object,
.started = computeNextStartDate(),
.path = path,
.total = size,
.hiddenByView = (!shownExists
&& item->history()->owner().queryItemVisibility(item)),
});
_loading.emplace(item);
_loadingDocuments.emplace(object.document);
@ -908,6 +931,9 @@ rpl::producer<Ui::DownloadBarContent> MakeDownloadBarContent() {
auto content = Ui::DownloadBarContent();
auto single = (const Data::DownloadObject*) nullptr;
for (const auto id : manager.loadingList()) {
if (id->hiddenByView) {
break;
}
if (!single) {
single = &id->object;
}

View file

@ -71,6 +71,7 @@ struct DownloadingId {
QString path;
int ready = 0;
int total = 0;
bool hiddenByView = false;
bool done = false;
};
@ -80,6 +81,7 @@ public:
~DownloadManager();
void trackSession(not_null<Main::Session*> session);
void itemVisibilitiesUpdated(not_null<Main::Session*> session);
[[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_user.h"
#include "data/data_file_origin.h"
#include "data/data_download_manager.h"
#include "data/data_photo.h"
#include "data/data_document.h"
#include "data/data_web_page.h"
@ -1373,6 +1374,24 @@ void Session::changeMessageId(PeerId peerId, MsgId wasId, MsgId nowId) {
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) {
const auto item = event.item;
changeMessageId(item->history()->peer->id, event.oldId, item->id);

View file

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

View file

@ -300,20 +300,24 @@ InnerWidget::InnerWidget(
}
}
}, 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) {
if (_history != query.item->history()
|| !query.item->isAdminLogEntry()
|| !isVisible()) {
return;
}
if (const auto view = viewForItem(query.item)) {
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;
}
}
});
}, lifetime());
updateEmptyText();
requestAdmins();
@ -355,6 +359,7 @@ void InnerWidget::visibleTopBottomUpdated(
scrollDateHideByTimer();
}
_controller->floatPlayerAreaUpdated();
session().data().itemVisibilitiesUpdated();
}
void InnerWidget::updateVisibleTopItem() {

View file

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

View file

@ -331,7 +331,9 @@ ListWidget::ListWidget(
itemRemoved(item);
}, 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)) {
const auto top = itemTop(view);
if (top >= 0
@ -340,7 +342,7 @@ ListWidget::ListWidget(
*query.isVisible = true;
}
}
});
}, lifetime());
using ChosenReaction = Reactions::Manager::Chosen;
_reactionsManager->chosen(
@ -794,6 +796,7 @@ void ListWidget::visibleTopBottomUpdated(
scrollDateHideByTimer();
}
_controller->floatPlayerAreaUpdated();
session().data().itemVisibilitiesUpdated();
_applyUpdatedScrollState.call();
}

View file

@ -169,6 +169,23 @@ void ListWidget::start() {
) | rpl::start_with_next([this] {
restart();
}, 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();
@ -566,6 +583,8 @@ void ListWidget::visibleTopBottomUpdated(
_dateBadge->check.call();
}
}
session().data().itemVisibilitiesUpdated();
}
void ListWidget::updateDateBadgeFor(int top) {

View file

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