diff --git a/Telegram/Resources/icons/dialogs/dialogs_downloads.png b/Telegram/Resources/icons/dialogs/dialogs_downloads.png new file mode 100644 index 0000000000..fd23ff3c81 Binary files /dev/null and b/Telegram/Resources/icons/dialogs/dialogs_downloads.png differ diff --git a/Telegram/Resources/icons/dialogs/dialogs_downloads@2x.png b/Telegram/Resources/icons/dialogs/dialogs_downloads@2x.png new file mode 100644 index 0000000000..e52d981fcf Binary files /dev/null and b/Telegram/Resources/icons/dialogs/dialogs_downloads@2x.png differ diff --git a/Telegram/Resources/icons/dialogs/dialogs_downloads@3x.png b/Telegram/Resources/icons/dialogs/dialogs_downloads@3x.png new file mode 100644 index 0000000000..24b4d8af1d Binary files /dev/null and b/Telegram/Resources/icons/dialogs/dialogs_downloads@3x.png differ diff --git a/Telegram/SourceFiles/boxes/add_contact_box.cpp b/Telegram/SourceFiles/boxes/add_contact_box.cpp index c63d744200..73623d4f0a 100644 --- a/Telegram/SourceFiles/boxes/add_contact_box.cpp +++ b/Telegram/SourceFiles/boxes/add_contact_box.cpp @@ -878,14 +878,14 @@ SetupChannelBox::SetupChannelBox( (channel->isMegagroup() ? tr::lng_create_public_group_about : tr::lng_create_public_channel_about)(tr::now), - _defaultOptions, + kDefaultTextOptions, _aboutPublicWidth) , _aboutPrivate( st::defaultTextStyle, (channel->isMegagroup() ? tr::lng_create_private_group_about : tr::lng_create_private_channel_about)(tr::now), - _defaultOptions, + kDefaultTextOptions, _aboutPublicWidth) , _link( this, diff --git a/Telegram/SourceFiles/dialogs/dialogs.style b/Telegram/SourceFiles/dialogs/dialogs.style index 8de5ee935e..0b7b9d41a5 100644 --- a/Telegram/SourceFiles/dialogs/dialogs.style +++ b/Telegram/SourceFiles/dialogs/dialogs.style @@ -327,4 +327,6 @@ downloadLoadingLeft: 15px; downloadLoadingSize: 24px; downloadLoadingLine: 2px; downloadLoadedSize: 30px; -downloadIconDocument: icon {{ "history_file_document", windowFgActive }}; +downloadIconDocument: icon {{ "dialogs/dialogs_downloads", windowFgActive }}; +downloadIconSize: 16px; +downloadIconSizeDone: 20px; diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp index e375eb62bc..e310b74999 100644 --- a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp +++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp @@ -504,8 +504,6 @@ void InnerWidget::clearAndRequestLog() { } void InnerWidget::updateEmptyText() { - auto options = _defaultOptions; - options.flags |= TextParseMarkdown; auto hasSearch = !_searchQuery.isEmpty(); auto hasFilter = (_filter.flags != 0) || !_filter.allUsers; auto text = Ui::Text::Semibold((hasSearch || hasFilter) @@ -522,7 +520,7 @@ void InnerWidget::updateEmptyText() { ? tr::lng_admin_log_no_events_text(tr::now) : tr::lng_admin_log_no_events_text_channel(tr::now); text.text.append(qstr("\n\n") + description); - _emptyText.setMarkedText(st::defaultTextStyle, text, options); + _emptyText.setMarkedText(st::defaultTextStyle, text); } QString InnerWidget::tooltipText() const { diff --git a/Telegram/SourceFiles/history/history_item_components.cpp b/Telegram/SourceFiles/history/history_item_components.cpp index 67d8db9d67..e9ac1817c0 100644 --- a/Telegram/SourceFiles/history/history_item_components.cpp +++ b/Telegram/SourceFiles/history/history_item_components.cpp @@ -524,7 +524,7 @@ ReplyKeyboard::ReplyKeyboard( button.text.setText( _st->textStyle(), TextUtilities::SingleLine(text), - _textPlainOptions); + kPlainTextOptions); button.characters = text.isEmpty() ? 1 : text.size(); newRow.push_back(std::move(button)); } diff --git a/Telegram/SourceFiles/history/view/history_view_empty_list_bubble.cpp b/Telegram/SourceFiles/history/view/history_view_empty_list_bubble.cpp index b1668f5297..6cf4f05e9d 100644 --- a/Telegram/SourceFiles/history/view/history_view_empty_list_bubble.cpp +++ b/Telegram/SourceFiles/history/view/history_view_empty_list_bubble.cpp @@ -56,9 +56,7 @@ void EmptyListBubbleWidget::paintEvent(QPaintEvent *e) { void EmptyListBubbleWidget::setText( const TextWithEntities &textWithEntities) { - auto options = _defaultOptions; - options.flags |= TextParseMarkdown; - _text.setMarkedText(st::defaultTextStyle, textWithEntities, options); + _text.setMarkedText(st::defaultTextStyle, textWithEntities); updateGeometry(size()); } diff --git a/Telegram/SourceFiles/info/downloads/info_downloads_provider.cpp b/Telegram/SourceFiles/info/downloads/info_downloads_provider.cpp index 0177d83ff7..14180063fd 100644 --- a/Telegram/SourceFiles/info/downloads/info_downloads_provider.cpp +++ b/Telegram/SourceFiles/info/downloads/info_downloads_provider.cpp @@ -386,16 +386,49 @@ QString Provider::showInFolderPath( return (i != end(_elements)) ? i->path : QString(); } +int64 Provider::scrollTopStatePosition(not_null item) { + const auto i = ranges::find(_elements, item, &Element::item); + return (i != end(_elements)) ? i->started : 0; +} + +HistoryItem *Provider::scrollTopStateItem(ListScrollTopState state) { + if (!state.position) { + return _elements.empty() ? nullptr : _elements.back().item.get(); + } + const auto i = ranges::lower_bound( + _elements, + state.position, + ranges::less(), + &Element::started); + return (i != end(_elements)) + ? i->item.get() + : _elements.empty() + ? nullptr + : _elements.back().item.get(); +} + void Provider::saveState( not_null memento, ListScrollTopState scrollState) { - + if (!_elements.empty() && scrollState.item) { + memento->setAroundId({ PeerId(), 1 }); + memento->setScrollTopItem(scrollState.item->globalId()); + memento->setScrollTopItemPosition(scrollState.position); + memento->setScrollTopShift(scrollState.shift); + } } void Provider::restoreState( not_null memento, Fn restoreScrollState) { - + if (memento->aroundId() == FullMsgId(PeerId(), 1)) { + restoreScrollState({ + .position = memento->scrollTopItemPosition(), + .item = MessageByGlobalId(memento->scrollTopItem()), + .shift = memento->scrollTopShift(), + }); + refreshViewer(); + } } } // namespace Info::Downloads diff --git a/Telegram/SourceFiles/info/downloads/info_downloads_provider.h b/Telegram/SourceFiles/info/downloads/info_downloads_provider.h index f4296bdda5..1c17e46582 100644 --- a/Telegram/SourceFiles/info/downloads/info_downloads_provider.h +++ b/Telegram/SourceFiles/info/downloads/info_downloads_provider.h @@ -70,6 +70,10 @@ public: not_null item, not_null document) override; + + int64 scrollTopStatePosition(not_null item) override; + HistoryItem *scrollTopStateItem( + Media::ListScrollTopState state) override; void saveState( not_null memento, Media::ListScrollTopState scrollState) override; diff --git a/Telegram/SourceFiles/info/media/info_media_common.h b/Telegram/SourceFiles/info/media/info_media_common.h index 2418c1b49e..0bb2b55757 100644 --- a/Telegram/SourceFiles/info/media/info_media_common.h +++ b/Telegram/SourceFiles/info/media/info_media_common.h @@ -59,6 +59,7 @@ struct ListContext { }; struct ListScrollTopState { + int64 position = 0; // ListProvider-specific. HistoryItem *item = nullptr; int shift = 0; }; @@ -157,6 +158,10 @@ public: not_null item, not_null document) = 0; + [[nodiscard]] virtual int64 scrollTopStatePosition( + not_null item) = 0; + [[nodiscard]] virtual HistoryItem *scrollTopStateItem( + ListScrollTopState state) = 0; virtual void saveState( not_null memento, ListScrollTopState scrollState) = 0; diff --git a/Telegram/SourceFiles/info/media/info_media_list_widget.cpp b/Telegram/SourceFiles/info/media/info_media_list_widget.cpp index 8cf168f296..0c1da4beb7 100644 --- a/Telegram/SourceFiles/info/media/info_media_list_widget.cpp +++ b/Telegram/SourceFiles/info/media/info_media_list_widget.cpp @@ -163,7 +163,7 @@ void ListWidget::start() { if (_controller->isDownloads()) { _provider->refreshViewer(); } else { - subscribeToSession(&session(), lifetime()); + trackSession(&session()); _controller->mediaSourceQueryValue( ) | rpl::start_with_next([this] { @@ -482,6 +482,7 @@ bool ListWidget::preventAutoHide() const { void ListWidget::saveState(not_null memento) { _provider->saveState(memento, countScrollState()); + _trackedSessions.clear(); } void ListWidget::restoreState(not_null memento) { @@ -655,12 +656,14 @@ void ListWidget::clearHeavyItems() { } ListScrollTopState ListWidget::countScrollState() const { - if (_sections.empty()) { + if (_sections.empty() || _visibleTop <= 0) { return {}; } const auto topItem = findItemByPoint({ st::infoMediaSkip, _visibleTop }); + const auto item = topItem.layout->getItem(); return { - .item = topItem.layout->getItem(), + .position = _provider->scrollTopStatePosition(item), + .item = item, .shift = _visibleTop - topItem.geometry.y(), }; } @@ -672,16 +675,22 @@ void ListWidget::saveScrollState() { } void ListWidget::restoreScrollState() { - if (_sections.empty() || !_scrollTopState.item) { + if (_sections.empty() || !_scrollTopState.position) { + return; + } + _scrollTopState.item = _provider->scrollTopStateItem(_scrollTopState); + if (!_scrollTopState.item) { return; } auto sectionIt = findSectionByItem(_scrollTopState.item); if (sectionIt == _sections.end()) { --sectionIt; } - auto item = foundItemInSection( // #TODO downloads - sectionIt->findItemNearId(GetUniversalId(_scrollTopState.item)), - *sectionIt); + const auto found = sectionIt->findItemByItem(_scrollTopState.item); + if (!found) { + return; + } + auto item = foundItemInSection(*found, *sectionIt); auto newVisibleTop = item.geometry.y() + _scrollTopState.shift; if (_visibleTop != newVisibleTop) { _scrollToRequests.fire_copy(newVisibleTop); @@ -1080,7 +1089,9 @@ void ListWidget::deleteItems(SelectedItems &&items, Fn confirmed) { return item.globalId; }) | ranges::to_vector; Core::App().downloadManager().deleteFiles(ids); - confirmed(); + if (confirmed) { + confirmed(); + } }; setActionBoxWeak(window->show(Box( phrase, diff --git a/Telegram/SourceFiles/info/media/info_media_provider.cpp b/Telegram/SourceFiles/info/media/info_media_provider.cpp index ab567a9ed1..2d1896ae04 100644 --- a/Telegram/SourceFiles/info/media/info_media_provider.cpp +++ b/Telegram/SourceFiles/info/media/info_media_provider.cpp @@ -511,6 +511,21 @@ void Provider::applyDragSelection( } } +int64 Provider::scrollTopStatePosition(not_null item) { + return GetUniversalId(item).bare; +} + +HistoryItem *Provider::scrollTopStateItem(ListScrollTopState state) { + if (state.item && _slice.indexOf(state.item->fullId())) { + return state.item; + } else if (const auto id = _slice.nearest(state.position)) { + if (const auto item = _controller->session().data().message(*id)) { + return item; + } + } + return state.item; +} + void Provider::saveState( not_null memento, ListScrollTopState scrollState) { @@ -518,6 +533,7 @@ void Provider::saveState( memento->setAroundId(computeFullId(_universalAroundId)); memento->setIdsLimit(_idsLimit); memento->setScrollTopItem(scrollState.item->globalId()); + memento->setScrollTopItemPosition(scrollState.position); memento->setScrollTopShift(scrollState.shift); } } @@ -531,6 +547,7 @@ void Provider::restoreState( _idsLimit = limit; _universalAroundId = GetUniversalId(wasAroundId); restoreScrollState({ + .position = memento->scrollTopItemPosition(), .item = MessageByGlobalId(memento->scrollTopItem()), .shift = memento->scrollTopShift(), }); diff --git a/Telegram/SourceFiles/info/media/info_media_provider.h b/Telegram/SourceFiles/info/media/info_media_provider.h index 3320d09fcd..d89c74c700 100644 --- a/Telegram/SourceFiles/info/media/info_media_provider.h +++ b/Telegram/SourceFiles/info/media/info_media_provider.h @@ -63,6 +63,8 @@ public: not_null item, not_null document) override; + int64 scrollTopStatePosition(not_null item) override; + HistoryItem *scrollTopStateItem(ListScrollTopState state) override; void saveState( not_null memento, ListScrollTopState scrollState) override; diff --git a/Telegram/SourceFiles/info/media/info_media_widget.h b/Telegram/SourceFiles/info/media/info_media_widget.h index 6ac4d9e8ca..ca523b1f5f 100644 --- a/Telegram/SourceFiles/info/media/info_media_widget.h +++ b/Telegram/SourceFiles/info/media/info_media_widget.h @@ -34,9 +34,9 @@ public: not_null controller, const QRect &geometry) override; - Section section() const override; + [[nodiscard]] Section section() const override; - Type type() const { + [[nodiscard]] Type type() const { return _type; } @@ -44,32 +44,38 @@ public: void setAroundId(FullMsgId aroundId) { _aroundId = aroundId; } - FullMsgId aroundId() const { + [[nodiscard]] FullMsgId aroundId() const { return _aroundId; } void setIdsLimit(int limit) { _idsLimit = limit; } - int idsLimit() const { + [[nodiscard]] int idsLimit() const { return _idsLimit; } void setScrollTopItem(GlobalMsgId item) { _scrollTopItem = item; } - GlobalMsgId scrollTopItem() const { + [[nodiscard]] GlobalMsgId scrollTopItem() const { return _scrollTopItem; } + void setScrollTopItemPosition(int64 position) { + _scrollTopItemPosition = position; + } + [[nodiscard]] int64 scrollTopItemPosition() const { + return _scrollTopItemPosition; + } void setScrollTopShift(int shift) { _scrollTopShift = shift; } - int scrollTopShift() const { + [[nodiscard]] int scrollTopShift() const { return _scrollTopShift; } void setSearchState(SearchState &&state) { _searchState = std::move(state); } - SearchState searchState() { + [[nodiscard]] SearchState searchState() { return std::move(_searchState); } @@ -77,6 +83,7 @@ private: Type _type = Type::Photo; FullMsgId _aroundId; int _idsLimit = 0; + int64 _scrollTopItemPosition = 0; GlobalMsgId _scrollTopItem; int _scrollTopShift = 0; SearchState _searchState; diff --git a/Telegram/SourceFiles/ui/boxes/confirm_box.cpp b/Telegram/SourceFiles/ui/boxes/confirm_box.cpp index b285e8e7bf..e3d7b6a111 100644 --- a/Telegram/SourceFiles/ui/boxes/confirm_box.cpp +++ b/Telegram/SourceFiles/ui/boxes/confirm_box.cpp @@ -189,7 +189,7 @@ void ConfirmBox::init(const QString &text) { _text.setText( st::boxLabelStyle, text, - _informative ? kInformBoxTextOptions : _textPlainOptions); + _informative ? kInformBoxTextOptions : kPlainTextOptions); } void ConfirmBox::init(const TextWithEntities &text) { diff --git a/Telegram/SourceFiles/ui/controls/download_bar.cpp b/Telegram/SourceFiles/ui/controls/download_bar.cpp index 05a9361044..851862f713 100644 --- a/Telegram/SourceFiles/ui/controls/download_bar.cpp +++ b/Telegram/SourceFiles/ui/controls/download_bar.cpp @@ -39,6 +39,12 @@ DownloadBar::DownloadBar( paint(p, clip); }, lifetime()); + style::PaletteChanged( + ) | rpl::start_with_next([=] { + refreshIcon(); + }, lifetime()); + refreshIcon(); + _progress.value( ) | rpl::start_with_next([=](const DownloadBarProgress &progress) { refreshInfo(progress); @@ -56,7 +62,8 @@ void DownloadBar::show(DownloadBarContent &&content) { _radial.start(computeProgress()); } _content = content; - _title.setMarkedText(st::defaultTextStyle, + _title.setMarkedText( + st::defaultTextStyle, (content.count > 1 ? Ui::Text::Bold( tr::lng_profile_files(tr::now, lt_count, content.count)) @@ -64,8 +71,24 @@ void DownloadBar::show(DownloadBarContent &&content) { refreshInfo(_progress.current()); } +void DownloadBar::refreshIcon() { + _documentIconOriginal = st::downloadIconDocument.instance( + st::windowFgActive->c, + style::kScaleMax / style::DevicePixelRatio()); + const auto make = [&](int size) { + auto result = _documentIconOriginal.scaledToWidth( + size * style::DevicePixelRatio(), + Qt::SmoothTransformation); + result.setDevicePixelRatio(style::DevicePixelRatio()); + return result; + }; + _documentIcon = make(st::downloadIconSize); + _documentIconDone = make(st::downloadIconSizeDone); +} + void DownloadBar::refreshInfo(const DownloadBarProgress &progress) { - _info.setMarkedText(st::downloadInfoStyle, + _info.setMarkedText( + st::downloadInfoStyle, (progress.ready < progress.total ? Text::WithEntities( FormatDownloadText(progress.ready, progress.total)) @@ -146,12 +169,10 @@ void DownloadBar::paint(Painter &p, QRect clip) { p.setOpacity(1.); } } - p.save(); - p.translate(full.center()); - p.scale(0.6, 0.6); - p.translate(-full.center()); - st::downloadIconDocument.paintInCenter(p, full); - p.restore(); + p.drawImage( + full.x() + (full.width() - st::downloadIconSize) / 2, + full.y() + (full.height() - st::downloadIconSize) / 2, + _documentIcon); } const auto minleft = std::min( diff --git a/Telegram/SourceFiles/ui/controls/download_bar.h b/Telegram/SourceFiles/ui/controls/download_bar.h index fe69138884..3748511b4e 100644 --- a/Telegram/SourceFiles/ui/controls/download_bar.h +++ b/Telegram/SourceFiles/ui/controls/download_bar.h @@ -49,6 +49,7 @@ public: private: void paint(Painter &p, QRect clip); + void refreshIcon(); void refreshInfo(const DownloadBarProgress &progress); void radialAnimationCallback(crl::time now); [[nodiscard]] float64 computeProgress() const; @@ -57,6 +58,9 @@ private: PlainShadow _shadow; DownloadBarContent _content; rpl::variable _progress; + QImage _documentIconOriginal; + QImage _documentIcon; + QImage _documentIconDone; Text::String _title; Text::String _info; RadialAnimation _radial; diff --git a/Telegram/lib_ui b/Telegram/lib_ui index bd7c4ee06d..5214f96bba 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit bd7c4ee06d7292fddf5f4dbd2249efd4d7bc8e85 +Subproject commit 5214f96bbafa1d879fca39c3374cb182687084c8