Show correct titles in sublists / sublist.

This commit is contained in:
John Preston 2023-12-30 19:04:43 +04:00
parent 634687881a
commit 9f0b42bbbd
9 changed files with 131 additions and 56 deletions

View File

@ -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 <QtCore/QMimeData>
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<Data::MessagesSlice> 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<Data::MessagesSlice> SublistWidget::listSource(
const auto useAfter = std::min(after, limitAfter);
const auto from = i - useAfter;
const auto till = i + useBefore;
auto nearestDistance = std::numeric_limits<int>::max();
auto nearestDistance = std::numeric_limits<int64>::max();
result.ids.reserve(useAfter + useBefore);
for (auto j = till; j != from;) {
const auto item = *--j;

View File

@ -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 {

View File

@ -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;

View File

@ -96,6 +96,9 @@ public:
}
[[nodiscard]] virtual rpl::producer<QString> title() = 0;
[[nodiscard]] virtual rpl::producer<QString> subtitle() {
return nullptr;
}
[[nodiscard]] virtual auto titleStories()
-> rpl::producer<Dialogs::Stories::Content>;

View File

@ -82,13 +82,36 @@ void TopBar::registerToggleControlCallback(
});
}
void TopBar::setTitle(rpl::producer<QString> &&title) {
void TopBar::setTitle(TitleDescriptor descriptor) {
if (_title) {
delete _title;
}
if (_subtitle) {
delete _subtitle;
}
const auto withSubtitle = !!descriptor.subtitle;
if (withSubtitle) {
_subtitle = Ui::CreateChild<Ui::FadeWrap<Ui::FlatLabel>>(
this,
object_ptr<Ui::FlatLabel>(
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<Ui::FadeWrap<Ui::FlatLabel>>(
this,
object_ptr<Ui::FlatLabel>(this, std::move(title), _st.title),
object_ptr<Ui::FlatLabel>(
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<QString> &&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);
}
}
}

View File

@ -41,6 +41,11 @@ namespace Info {
class Key;
class Section;
struct TitleDescriptor {
rpl::producer<QString> title;
rpl::producer<QString> subtitle;
};
class TopBar : public Ui::RpWidget {
public:
TopBar(
@ -56,7 +61,7 @@ public:
return _storyClicks.events();
}
void setTitle(rpl::producer<QString> &&title);
void setTitle(TitleDescriptor descriptor);
void setStories(rpl::producer<Dialogs::Stories::Content> content);
void setStoriesArchive(bool archive);
void enableBackButton();
@ -155,6 +160,7 @@ private:
QPointer<Ui::FadeWrap<Ui::IconButton>> _back;
std::vector<base::unique_qptr<Ui::RpWidget>> _buttons;
QPointer<Ui::FadeWrap<Ui::FlatLabel>> _title;
QPointer<Ui::FadeWrap<Ui::FlatLabel>> _subtitle;
bool _searchModeEnabled = false;
bool _searchModeAvailable = false;

View File

@ -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);

View File

@ -77,6 +77,16 @@ rpl::producer<QString> SublistsWidget::title() {
return tr::lng_saved_messages();
}
rpl::producer<QString> 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<ContentMemento*> memento) {
if (!controller()->validateMementoPeer(memento)) {
return false;

View File

@ -50,6 +50,7 @@ public:
not_null<SublistsMemento*> memento);
rpl::producer<QString> title() override;
rpl::producer<QString> subtitle() override;
private:
void saveState(not_null<SublistsMemento*> memento);