From 9f0b42bbbdd88a47f8946b39d08921f4e1ade906 Mon Sep 17 00:00:00 2001 From: John Preston Date: Sat, 30 Dec 2023 19:04:43 +0400 Subject: [PATCH] Show correct titles in sublists / sublist. --- .../view/history_view_sublist_section.cpp | 36 +++--------- .../view/history_view_top_bar_widget.cpp | 58 +++++++++++++------ Telegram/SourceFiles/info/info.style | 14 +++++ .../SourceFiles/info/info_content_widget.h | 3 + Telegram/SourceFiles/info/info_top_bar.cpp | 52 +++++++++++++++-- Telegram/SourceFiles/info/info_top_bar.h | 8 ++- .../SourceFiles/info/info_wrap_widget.cpp | 5 +- .../info/saved/info_saved_sublists_widget.cpp | 10 ++++ .../info/saved/info_saved_sublists_widget.h | 1 + 9 files changed, 131 insertions(+), 56 deletions(-) diff --git a/Telegram/SourceFiles/history/view/history_view_sublist_section.cpp b/Telegram/SourceFiles/history/view/history_view_sublist_section.cpp index b92711acfe..f40c76a517 100644 --- a/Telegram/SourceFiles/history/view/history_view_sublist_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_sublist_section.cpp @@ -7,53 +7,26 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "history/view/history_view_sublist_section.h" -//#include "base/timer_rpl.h" -//#include "apiwrap.h" -//#include "base/event_filter.h" -//#include "base/call_delayed.h" -//#include "base/qt/qt_key_modifiers.h" -//#include "core/file_utilities.h" #include "main/main_session.h" -//#include "data/data_chat.h" -//#include "data/data_channel.h" -//#include "data/data_changes.h" #include "data/data_saved_messages.h" #include "data/data_saved_sublist.h" #include "data/data_session.h" -//#include "data/data_sparse_ids.h" -//#include "data/data_shared_media.h" #include "data/data_peer_values.h" #include "data/data_user.h" #include "history/view/history_view_top_bar_widget.h" #include "history/view/history_view_translate_bar.h" #include "history/view/history_view_list_widget.h" #include "history/history.h" -//#include "history/history_item_components.h" #include "history/history_item.h" -//#include "storage/storage_account.h" -//#include "platform/platform_specific.h" #include "lang/lang_keys.h" -//#include "ui/boxes/confirm_box.h" -//#include "ui/layers/generic_box.h" -//#include "ui/item_text_options.h" #include "ui/chat/chat_style.h" -//#include "ui/toast/toast.h" -//#include "ui/text/format_values.h" -//#include "ui/text/text_utilities.h" #include "ui/widgets/buttons.h" #include "ui/widgets/scroll_area.h" #include "ui/widgets/shadow.h" -//#include "ui/ui_utility.h" -//#include "window/window_adaptive.h" #include "window/window_session_controller.h" -//#include "window/window_peer_menu.h" #include "styles/style_chat.h" #include "styles/style_chat_helpers.h" #include "styles/style_window.h" -//#include "styles/style_info.h" -//#include "styles/style_boxes.h" -// -//#include namespace HistoryView { namespace { @@ -134,7 +107,6 @@ SublistWidget::SublistWidget( _topBar->move(0, 0); _topBar->resizeToWidth(width()); _topBar->show(); - _topBar->setCustomTitle(tr::lng_contacts_loading(tr::now)); _topBar->deleteSelectionRequest( ) | rpl::start_with_next([=] { @@ -464,6 +436,12 @@ rpl::producer SublistWidget::listSource( const auto pushSlice = [=] { auto result = Data::MessagesSlice(); result.fullCount = _sublist->fullCount(); + _topBar->setCustomTitle(result.fullCount + ? tr::lng_forum_messages( + tr::now, + lt_count_decimal, + *result.fullCount) + : tr::lng_contacts_loading(tr::now)); const auto &messages = _sublist->messages(); const auto i = ranges::lower_bound( messages, @@ -476,7 +454,7 @@ rpl::producer SublistWidget::listSource( const auto useAfter = std::min(after, limitAfter); const auto from = i - useAfter; const auto till = i + useBefore; - auto nearestDistance = std::numeric_limits::max(); + auto nearestDistance = std::numeric_limits::max(); result.ids.reserve(useAfter + useBefore); for (auto j = till; j != from;) { const auto item = *--j; diff --git a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp index d357079a14..67a3b6c57a 100644 --- a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp @@ -44,6 +44,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_peer_values.h" #include "data/data_group_call.h" // GroupCall::input. #include "data/data_folder.h" +#include "data/data_saved_sublist.h" #include "data/data_session.h" #include "data/data_stories.h" #include "data/data_channel.h" @@ -467,10 +468,17 @@ void TopBarWidget::paintTopBar(Painter &p) { } const auto now = crl::now(); - const auto history = _activeChat.key.owningHistory(); + const auto peer = _activeChat.key.owningHistory() + ? _activeChat.key.owningHistory()->peer.get() + : nullptr; const auto folder = _activeChat.key.folder(); const auto sublist = _activeChat.key.sublist(); const auto topic = _activeChat.key.topic(); + const auto history = _activeChat.key.history(); + const auto namePeer = history + ? history->peer.get() + : sublist ? sublist->peer().get() + : nullptr; if (topic && _activeChat.section == Section::Replies) { p.setPen(st::dialogsNameFg); topic->chatListNameText().drawElided( @@ -492,24 +500,23 @@ void TopBarWidget::paintTopBar(Painter &p) { p.setPen(st::historyStatusFg); p.drawTextLeft(nameleft, statustop, width(), _customTitleText); } - } else if (sublist) { } else if (folder - || (history && history->peer->sharedMediaInfo()) + || (peer && peer->sharedMediaInfo()) || (_activeChat.section == Section::Scheduled) || (_activeChat.section == Section::Pinned)) { auto text = (_activeChat.section == Section::Scheduled) - ? ((history && history->peer->isSelf()) + ? ((peer && peer->isSelf()) ? tr::lng_reminder_messages(tr::now) : tr::lng_scheduled_messages(tr::now)) : (_activeChat.section == Section::Pinned) ? _customTitleText : folder ? folder->chatListName() - : history->peer->isSelf() + : peer->isSelf() ? tr::lng_saved_messages(tr::now) - : history->peer->isRepliesChat() + : peer->isRepliesChat() ? tr::lng_replies_messages(tr::now) - : history->peer->name(); + : peer->name(); const auto textWidth = st::historySavedFont->width(text); if (availableWidth < textWidth) { text = st::historySavedFont->elided(text, availableWidth); @@ -540,16 +547,14 @@ void TopBarWidget::paintTopBar(Painter &p) { width(), st::historyStatusFgTyping, now)) { - p.setPen(st::historyStatusFg); - p.drawTextLeft(nameleft, statustop, width(), _customTitleText); + paintStatus(p, nameleft, statustop, availableWidth, width()); } - } else if (const auto history = _activeChat.key.history()) { - const auto peer = history->peer; - if (_titleNameVersion < peer->nameVersion()) { - _titleNameVersion = peer->nameVersion(); + } else if (namePeer) { + if (_titleNameVersion < namePeer->nameVersion()) { + _titleNameVersion = namePeer->nameVersion(); _title.setText( st::msgNameStyle, - peer->topBarNameText(), + namePeer->topBarNameText(), Ui::NameTextOptions()); } const auto badgeWidth = _titleBadge.drawGetWidth( @@ -562,7 +567,7 @@ void TopBarWidget::paintTopBar(Painter &p) { _title.maxWidth(), width(), { - .peer = peer, + .peer = namePeer, .verified = &st::dialogsVerifiedIcon, .premium = &st::dialogsPremiumIcon.icon, .scam = &st::attentionButtonFg, @@ -604,6 +609,9 @@ bool TopBarWidget::paintSendAction( int outerWidth, style::color fg, crl::time now) { + if (!_sendAction) { + return false; + } const auto seen = _emojiInteractionSeen.get(); if (!seen || seen->till <= now) { return _sendAction->paint(p, x, y, availableWidth, outerWidth, fg, now); @@ -654,10 +662,22 @@ void TopBarWidget::paintStatus( int top, int availableWidth, int outerWidth) { - p.setPen(_titlePeerTextOnline - ? st::historyStatusFgActive - : st::historyStatusFg); - _titlePeerText.drawLeftElided(p, left, top, availableWidth, outerWidth); + using Section = Dialogs::EntryState::Section; + const auto section = _activeChat.section; + if (section == Section::Replies || section == Section::SavedSublist) { + p.setPen(st::historyStatusFg); + p.drawTextLeft(left, top, outerWidth, _customTitleText); + } else { + p.setPen(_titlePeerTextOnline + ? st::historyStatusFgActive + : st::historyStatusFg); + _titlePeerText.drawLeftElided( + p, + left, + top, + availableWidth, + outerWidth); + } } QRect TopBarWidget::getMembersShowAreaGeometry() const { diff --git a/Telegram/SourceFiles/info/info.style b/Telegram/SourceFiles/info/info.style index 549985aa34..c709a70141 100644 --- a/Telegram/SourceFiles/info/info.style +++ b/Telegram/SourceFiles/info/info.style @@ -33,6 +33,10 @@ InfoTopBar { back: IconButton; title: FlatLabel; titlePosition: point; + titleWithSubtitle: FlatLabel; + titleWithSubtitlePosition: point; + subtitle: FlatLabel; + subtitlePosition: point; bg: color; mediaCancel: IconButton; mediaActionsSkip: pixels; @@ -186,6 +190,14 @@ infoTopBar: InfoTopBar { back: infoTopBarBack; title: infoTopBarTitle; titlePosition: point(24px, 17px); + titleWithSubtitle: FlatLabel(infoTopBarTitle) { + style: semiboldTextStyle; + } + titleWithSubtitlePosition: point(16px, 8px); + subtitle: FlatLabel(defaultFlatLabel) { + textFg: windowSubTextFg; + } + subtitlePosition: point(16px, 28px); bg: windowBg; mediaCancel: infoTopBarMediaCancel; mediaActionsSkip: 4px; @@ -261,6 +273,8 @@ infoLayerTopBar: InfoTopBar(infoTopBar) { back: infoLayerTopBarBack; title: boxTitle; titlePosition: point(24px, 17px); + titleWithSubtitlePosition: point(16px, 9px); + subtitlePosition: point(16px, 30px); bg: boxBg; mediaCancel: infoLayerTopBarMediaCancel; mediaActionsSkip: 6px; diff --git a/Telegram/SourceFiles/info/info_content_widget.h b/Telegram/SourceFiles/info/info_content_widget.h index 5d53efee53..a7782d4f9a 100644 --- a/Telegram/SourceFiles/info/info_content_widget.h +++ b/Telegram/SourceFiles/info/info_content_widget.h @@ -96,6 +96,9 @@ public: } [[nodiscard]] virtual rpl::producer title() = 0; + [[nodiscard]] virtual rpl::producer subtitle() { + return nullptr; + } [[nodiscard]] virtual auto titleStories() -> rpl::producer; diff --git a/Telegram/SourceFiles/info/info_top_bar.cpp b/Telegram/SourceFiles/info/info_top_bar.cpp index 04985c6179..6c91d38ca2 100644 --- a/Telegram/SourceFiles/info/info_top_bar.cpp +++ b/Telegram/SourceFiles/info/info_top_bar.cpp @@ -82,13 +82,36 @@ void TopBar::registerToggleControlCallback( }); } -void TopBar::setTitle(rpl::producer &&title) { +void TopBar::setTitle(TitleDescriptor descriptor) { if (_title) { delete _title; } + if (_subtitle) { + delete _subtitle; + } + const auto withSubtitle = !!descriptor.subtitle; + if (withSubtitle) { + _subtitle = Ui::CreateChild>( + this, + object_ptr( + this, + std::move(descriptor.subtitle), + _st.subtitle), + st::infoTopBarScale); + _subtitle->setDuration(st::infoTopBarDuration); + _subtitle->toggle( + !selectionMode() && !storiesTitle(), + anim::type::instant); + registerToggleControlCallback(_subtitle.data(), [=] { + return !selectionMode() && !storiesTitle() && !searchMode(); + }); + } _title = Ui::CreateChild>( this, - object_ptr(this, std::move(title), _st.title), + object_ptr( + this, + std::move(descriptor.title), + withSubtitle ? _st.titleWithSubtitle : _st.title), st::infoTopBarScale); _title->setDuration(st::infoTopBarDuration); _title->toggle( @@ -100,6 +123,9 @@ void TopBar::setTitle(rpl::producer &&title) { if (_back) { _title->setAttribute(Qt::WA_TransparentForMouseEvents); + if (_subtitle) { + _subtitle->setAttribute(Qt::WA_TransparentForMouseEvents); + } } updateControlsGeometry(width()); } @@ -124,6 +150,9 @@ void TopBar::enableBackButton() { if (_title) { _title->setAttribute(Qt::WA_TransparentForMouseEvents); } + if (_subtitle) { + _subtitle->setAttribute(Qt::WA_TransparentForMouseEvents); + } if (_storiesWrap) { _storiesWrap->raise(); } @@ -339,10 +368,21 @@ void TopBar::updateDefaultControlsGeometry(int newWidth) { newWidth); } if (_title) { - _title->moveToLeft( - _back ? _st.back.width : _st.titlePosition.x(), - _st.titlePosition.y(), - newWidth); + const auto x = _back + ? _st.back.width + : _subtitle + ? _st.titleWithSubtitlePosition.x() + : _st.titlePosition.x(); + const auto y = _subtitle + ? _st.titleWithSubtitlePosition.y() + : _st.titlePosition.y(); + _title->moveToLeft(x, y, newWidth); + if (_subtitle) { + _subtitle->moveToLeft( + _back ? _st.back.width : _st.subtitlePosition.x(), + _st.subtitlePosition.y(), + newWidth); + } } } diff --git a/Telegram/SourceFiles/info/info_top_bar.h b/Telegram/SourceFiles/info/info_top_bar.h index 4961669549..9e6ad80a8f 100644 --- a/Telegram/SourceFiles/info/info_top_bar.h +++ b/Telegram/SourceFiles/info/info_top_bar.h @@ -41,6 +41,11 @@ namespace Info { class Key; class Section; +struct TitleDescriptor { + rpl::producer title; + rpl::producer subtitle; +}; + class TopBar : public Ui::RpWidget { public: TopBar( @@ -56,7 +61,7 @@ public: return _storyClicks.events(); } - void setTitle(rpl::producer &&title); + void setTitle(TitleDescriptor descriptor); void setStories(rpl::producer content); void setStoriesArchive(bool archive); void enableBackButton(); @@ -155,6 +160,7 @@ private: QPointer> _back; std::vector> _buttons; QPointer> _title; + QPointer> _subtitle; bool _searchModeEnabled = false; bool _searchModeAvailable = false; diff --git a/Telegram/SourceFiles/info/info_wrap_widget.cpp b/Telegram/SourceFiles/info/info_wrap_widget.cpp index bde368bd0c..32bd69c7a5 100644 --- a/Telegram/SourceFiles/info/info_wrap_widget.cpp +++ b/Telegram/SourceFiles/info/info_wrap_widget.cpp @@ -597,7 +597,10 @@ void WrapWidget::finishShowContent() { updateContentGeometry(); _content->setIsStackBottom(!hasStackHistory()); if (_topBar) { - _topBar->setTitle(_content->title()); + _topBar->setTitle({ + .title = _content->title(), + .subtitle = _content->subtitle(), + }); _topBar->setStories(_content->titleStories()); _topBar->setStoriesArchive( _controller->key().storiesTab() == Stories::Tab::Archive); diff --git a/Telegram/SourceFiles/info/saved/info_saved_sublists_widget.cpp b/Telegram/SourceFiles/info/saved/info_saved_sublists_widget.cpp index e846977802..af229100d7 100644 --- a/Telegram/SourceFiles/info/saved/info_saved_sublists_widget.cpp +++ b/Telegram/SourceFiles/info/saved/info_saved_sublists_widget.cpp @@ -77,6 +77,16 @@ rpl::producer SublistsWidget::title() { return tr::lng_saved_messages(); } +rpl::producer SublistsWidget::subtitle() { + const auto saved = &controller()->session().data().savedMessages(); + return saved->chatsList()->fullSize().value( + ) | rpl::map([=](int value) { + return (value || saved->chatsList()->loaded()) + ? tr::lng_filters_chats_count(tr::now, lt_count, value) + : tr::lng_contacts_loading(tr::now); + }); +} + bool SublistsWidget::showInternal(not_null memento) { if (!controller()->validateMementoPeer(memento)) { return false; diff --git a/Telegram/SourceFiles/info/saved/info_saved_sublists_widget.h b/Telegram/SourceFiles/info/saved/info_saved_sublists_widget.h index e7a875ba0d..b5d3cb0aaf 100644 --- a/Telegram/SourceFiles/info/saved/info_saved_sublists_widget.h +++ b/Telegram/SourceFiles/info/saved/info_saved_sublists_widget.h @@ -50,6 +50,7 @@ public: not_null memento); rpl::producer title() override; + rpl::producer subtitle() override; private: void saveState(not_null memento);