From 021a5881c2d13b7a62e3469b0fa7b68b782ef92e Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Sat, 23 Nov 2024 14:10:04 +0300 Subject: [PATCH 001/294] Improved display of history begin for channels with enabled auto-delete. --- Telegram/SourceFiles/data/data_types.cpp | 4 ++-- Telegram/SourceFiles/history/history.cpp | 9 ++++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Telegram/SourceFiles/data/data_types.cpp b/Telegram/SourceFiles/data/data_types.cpp index ab792cd30..8fed3ecd3 100644 --- a/Telegram/SourceFiles/data/data_types.cpp +++ b/Telegram/SourceFiles/data/data_types.cpp @@ -114,8 +114,8 @@ void MessageCursor::applyTo(not_null field) { } PeerId PeerFromMessage(const MTPmessage &message) { - return message.match([](const MTPDmessageEmpty &) { - return PeerId(0); + return message.match([](const MTPDmessageEmpty &data) { + return data.vpeer_id() ? peerFromMTP(*data.vpeer_id()) : PeerId(0); }, [](const auto &data) { return peerFromMTP(data.vpeer_id()); }); diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index 250fcb831..56ca12032 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -459,8 +459,15 @@ std::vector> History::createItems( const auto detachExistingItem = true; for (auto i = data.cend(), e = data.cbegin(); i != e;) { const auto &data = *--i; + const auto id = IdFromMessage(data); + if ((id.bare == 1) && (data.type() == mtpc_messageEmpty)) { + // The first message of channels should be a service message + // about its creation. But if channel auto-cleaning is enabled, + // the first message comes empty and is displayed incorrectly. + continue; + } result.emplace_back(createItem( - IdFromMessage(data), + id, data, localFlags, detachExistingItem)); From f888008dc156562248d68f012f23169dee345e1e Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Mon, 25 Nov 2024 17:44:49 +0300 Subject: [PATCH 002/294] Removed counting of unread topics from unread state in filters. --- Telegram/SourceFiles/data/data_forum_topic.cpp | 1 + Telegram/SourceFiles/dialogs/dialogs_entry.h | 3 +++ Telegram/SourceFiles/ui/widgets/chat_filters_tabs_strip.cpp | 5 ++++- Telegram/SourceFiles/window/window_filters_menu.cpp | 5 ++++- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Telegram/SourceFiles/data/data_forum_topic.cpp b/Telegram/SourceFiles/data/data_forum_topic.cpp index 7e7998897..d7ad7565a 100644 --- a/Telegram/SourceFiles/data/data_forum_topic.cpp +++ b/Telegram/SourceFiles/data/data_forum_topic.cpp @@ -897,6 +897,7 @@ Dialogs::UnreadState ForumTopic::unreadStateFor( const auto muted = this->muted(); result.messages = count; result.chats = count ? 1 : 0; + result.chatsTopic = count ? 1 : 0; result.mentions = unreadMentions().has() ? 1 : 0; result.reactions = unreadReactions().has() ? 1 : 0; result.messagesMuted = muted ? result.messages : 0; diff --git a/Telegram/SourceFiles/dialogs/dialogs_entry.h b/Telegram/SourceFiles/dialogs/dialogs_entry.h index 3a19eec68..ec61c0378 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_entry.h +++ b/Telegram/SourceFiles/dialogs/dialogs_entry.h @@ -65,6 +65,7 @@ struct UnreadState { int messagesMuted = 0; int chats = 0; int chatsMuted = 0; + int chatsTopic = 0; int marks = 0; int marksMuted = 0; int reactions = 0; @@ -77,6 +78,7 @@ struct UnreadState { messagesMuted += other.messagesMuted; chats += other.chats; chatsMuted += other.chatsMuted; + chatsTopic += other.chatsTopic; marks += other.marks; marksMuted += other.marksMuted; reactions += other.reactions; @@ -89,6 +91,7 @@ struct UnreadState { messagesMuted -= other.messagesMuted; chats -= other.chats; chatsMuted -= other.chatsMuted; + chatsTopic -= other.chatsTopic; marks -= other.marks; marksMuted -= other.marksMuted; reactions -= other.reactions; diff --git a/Telegram/SourceFiles/ui/widgets/chat_filters_tabs_strip.cpp b/Telegram/SourceFiles/ui/widgets/chat_filters_tabs_strip.cpp index 2c4472e79..65e9a9de8 100644 --- a/Telegram/SourceFiles/ui/widgets/chat_filters_tabs_strip.cpp +++ b/Telegram/SourceFiles/ui/widgets/chat_filters_tabs_strip.cpp @@ -337,8 +337,11 @@ not_null AddChatFiltersTabsStrip( ) | rpl::start_with_next([=]( const Dialogs::UnreadState &state, bool includeMuted) { + const auto chats = state.chatsTopic + ? (state.chats - state.chatsTopic + 1) + : state.chats; const auto muted = (state.chatsMuted + state.marksMuted); - const auto count = (state.chats + state.marks) + const auto count = (chats + state.marks) - (includeMuted ? 0 : muted); const auto isMuted = includeMuted && (count == muted); slider->setUnreadCount(i, count, isMuted); diff --git a/Telegram/SourceFiles/window/window_filters_menu.cpp b/Telegram/SourceFiles/window/window_filters_menu.cpp index f3e07eea9..d5d2fdd99 100644 --- a/Telegram/SourceFiles/window/window_filters_menu.cpp +++ b/Telegram/SourceFiles/window/window_filters_menu.cpp @@ -270,8 +270,11 @@ base::unique_qptr FiltersMenu::prepareButton( ) | rpl::start_with_next([=]( const Dialogs::UnreadState &state, bool includeMuted) { + const auto chats = state.chatsTopic + ? (state.chats - state.chatsTopic + 1) + : state.chats; const auto muted = (state.chatsMuted + state.marksMuted); - const auto count = (state.chats + state.marks) + const auto count = (chats + state.marks) - (includeMuted ? 0 : muted); const auto string = !count ? QString() From d5dbde0a246e072ed896ba25e8c73bf7ba02ab0d Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 20 Nov 2024 07:49:32 +0300 Subject: [PATCH 003/294] Added ability to cache filter colors in dialog entries. --- .../SourceFiles/dialogs/dialogs_entry.cpp | 28 +++++++++++++++++++ Telegram/SourceFiles/dialogs/dialogs_entry.h | 2 ++ 2 files changed, 30 insertions(+) diff --git a/Telegram/SourceFiles/dialogs/dialogs_entry.cpp b/Telegram/SourceFiles/dialogs/dialogs_entry.cpp index 6d227c69a..957e7f4f5 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_entry.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_entry.cpp @@ -338,6 +338,17 @@ not_null Entry::addToChatList( if (const auto main = maybeMainChatListLink(filterId)) { return main; } + if (filterId) { + const auto &list = owner().chatsFilters().list(); + const auto it = ranges::find(list, filterId, &Data::ChatFilter::id); + if (it != end(list) && it->colorIndex()) { + _tagColors[filterId] = *(it->colorIndex()); + } else { + if (it != end(list)) { + } + _tagColors.remove(filterId); + } + } return _chatListLinks.emplace( filterId, list->addEntry(this) @@ -350,6 +361,12 @@ void Entry::removeFromChatList( if (isPinnedDialog(filterId)) { owner().setChatPinned(this, filterId, false); } + if (filterId) { + const auto it = _tagColors.find(filterId); + if (it != end(_tagColors)) { + _tagColors.erase(it); + } + } const auto i = _chatListLinks.find(filterId); if (i == end(_chatListLinks)) { @@ -397,4 +414,15 @@ void Entry::updateChatListEntryHeight() { session().changes().entryUpdated(this, Data::EntryUpdate::Flag::Height); } +[[nodiscard]] bool Entry::hasChatsFilterTags(FilterId exclude) const { + if (exclude) { + if (_tagColors.size() == 1) { + if (_tagColors.begin()->first == exclude) { + return false; + } + } + } + return !_tagColors.empty(); +} + } // namespace Dialogs diff --git a/Telegram/SourceFiles/dialogs/dialogs_entry.h b/Telegram/SourceFiles/dialogs/dialogs_entry.h index ec61c0378..cb6ac728f 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_entry.h +++ b/Telegram/SourceFiles/dialogs/dialogs_entry.h @@ -254,6 +254,7 @@ public: return _chatListPeerBadge; } + [[nodiscard]] bool hasChatsFilterTags(FilterId exclude) const; protected: void notifyUnreadStateChange(const UnreadState &wasState); inline auto unreadStateChangeNotifier(bool required); @@ -284,6 +285,7 @@ private: uint64 _sortKeyInChatList = 0; uint64 _sortKeyByDate = 0; base::flat_map _pinnedIndex; + base::flat_map _tagColors; mutable Ui::PeerBadge _chatListPeerBadge; mutable Ui::Text::String _chatListNameText; mutable int _chatListNameVersion = 0; From aea2d340800c6b11f507492166c97de8119b35d2 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 20 Nov 2024 07:53:50 +0300 Subject: [PATCH 004/294] Added styles for dialog rows with tags. --- Telegram/SourceFiles/dialogs/dialogs.style | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Telegram/SourceFiles/dialogs/dialogs.style b/Telegram/SourceFiles/dialogs/dialogs.style index 8eb562d52..a0b8c4c76 100644 --- a/Telegram/SourceFiles/dialogs/dialogs.style +++ b/Telegram/SourceFiles/dialogs/dialogs.style @@ -22,6 +22,7 @@ DialogRow { topicsSkipBig: pixels; topicsHeight: pixels; unreadMarkDiameter: pixels; + tagTop: pixels; } ThreeStateIcon { @@ -89,6 +90,11 @@ defaultDialogRow: DialogRow { textLeft: 68px; textTop: 34px; } +taggedDialogRow: DialogRow(defaultDialogRow) { + height: 72px; + textTop: 30px; + tagTop: 52px; +} forumDialogRow: DialogRow(defaultDialogRow) { height: 80px; textTop: 32px; @@ -96,6 +102,12 @@ forumDialogRow: DialogRow(defaultDialogRow) { topicsSkipBig: 14px; topicsHeight: 21px; } +taggedForumDialogRow: DialogRow(forumDialogRow) { + height: 96px; + tagTop: 77px; +} +dialogRowFilterTagSkip : 4px; +dialogRowFilterTagFont : font(10px); forumDialogJumpArrow: icon{{ "dialogs/dialogs_topic_arrow", dialogsTextFg }}; forumDialogJumpArrowOver: icon{{ "dialogs/dialogs_topic_arrow", dialogsTextFgOver }}; From 0d58b32914f1af557f0021cb082ca403318583f3 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 20 Nov 2024 02:32:23 +0300 Subject: [PATCH 005/294] Added ability to recount height of dialog rows by chats filter id. --- .../SourceFiles/dialogs/dialogs_inner_widget.cpp | 6 +++--- Telegram/SourceFiles/dialogs/dialogs_list.cpp | 6 +++--- Telegram/SourceFiles/dialogs/dialogs_row.cpp | 12 ++++++++++-- Telegram/SourceFiles/dialogs/dialogs_row.h | 2 +- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index f587dab2b..585f72aa8 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -408,7 +408,7 @@ bool InnerWidget::updateEntryHeight(not_null entry) { result.top = top; } if (result.row->key().entry() == entry) { - result.row->recountHeight(_narrowRatio); + result.row->recountHeight(_narrowRatio, _filterId); changing = true; top = result.top; } @@ -2812,7 +2812,7 @@ void InnerWidget::applySearchState(SearchState state) { end(results)); for (const auto e = end(_filterResults); i != e; ++i) { i->top = top; - i->row->recountHeight(_narrowRatio); + i->row->recountHeight(_narrowRatio, _filterId); top += i->row->height(); } }; @@ -2885,7 +2885,7 @@ void InnerWidget::appendToFiltered(Key key) { } } auto row = std::make_unique(key, 0, 0); - row->recountHeight(_narrowRatio); + row->recountHeight(_narrowRatio, _filterId); const auto &[i, ok] = _filterResultsGlobal.emplace(key, std::move(row)); const auto height = filteredHeight(); _filterResults.emplace_back(i->second.get()); diff --git a/Telegram/SourceFiles/dialogs/dialogs_list.cpp b/Telegram/SourceFiles/dialogs/dialogs_list.cpp index 362f8b857..ce6a72462 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_list.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_list.cpp @@ -32,7 +32,7 @@ not_null List::addToEnd(Key key) { key, std::make_unique(key, _rows.size(), height()) ).first->second.get(); - result->recountHeight(_narrowRatio); + result->recountHeight(_narrowRatio, _filterId); _rows.emplace_back(result); if (_sortMode == SortMode::Date) { adjustByDate(result); @@ -112,7 +112,7 @@ bool List::updateHeight(Key key, float64 narrowRatio) { const auto index = row->index(); auto top = row->top(); const auto was = row->height(); - row->recountHeight(narrowRatio); + row->recountHeight(narrowRatio, _filterId); if (row->height() == was) { return false; } @@ -129,7 +129,7 @@ bool List::updateHeights(float64 narrowRatio) { auto top = 0; for (const auto &row : _rows) { row->_top = top; - row->recountHeight(narrowRatio); + row->recountHeight(narrowRatio, _filterId); top += row->height(); } return (height() != was); diff --git a/Telegram/SourceFiles/dialogs/dialogs_row.cpp b/Telegram/SourceFiles/dialogs/dialogs_row.cpp index 5a0730f86..8f974aa09 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_row.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_row.cpp @@ -316,11 +316,19 @@ Row::~Row() { clearTopicJumpRipple(); } -void Row::recountHeight(float64 narrowRatio) { +void Row::recountHeight(float64 narrowRatio, FilterId filterId) { if (const auto history = _id.history()) { + const auto hasTags = _id.entry()->hasChatsFilterTags(filterId); _height = history->isForum() ? anim::interpolate( - st::forumDialogRow.height, + hasTags + ? st::taggedForumDialogRow.height + : st::forumDialogRow.height, + st::defaultDialogRow.height, + narrowRatio) + : hasTags + ? anim::interpolate( + st::taggedDialogRow.height, st::defaultDialogRow.height, narrowRatio) : st::defaultDialogRow.height; diff --git a/Telegram/SourceFiles/dialogs/dialogs_row.h b/Telegram/SourceFiles/dialogs/dialogs_row.h index a4ddde404..b5181ba66 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_row.h +++ b/Telegram/SourceFiles/dialogs/dialogs_row.h @@ -94,7 +94,7 @@ public: return _height; } - void recountHeight(float64 narrowRatio); + void recountHeight(float64 narrowRatio, FilterId filterId); void updateCornerBadgeShown( not_null peer, From f4523b2dbaf2ae72e3f78cc4c87f0d9edb83be57 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Tue, 19 Nov 2024 12:15:05 +0300 Subject: [PATCH 006/294] Added initial implementation of filter tags to dialog rows. --- .../dialogs/dialogs_inner_widget.cpp | 113 ++++++++++++++++++ .../dialogs/dialogs_inner_widget.h | 3 + .../SourceFiles/dialogs/ui/dialogs_layout.cpp | 11 +- .../SourceFiles/dialogs/ui/dialogs_layout.h | 1 + 4 files changed, 127 insertions(+), 1 deletion(-) diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index 585f72aa8..6012f9d73 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -73,6 +73,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "styles/style_dialogs.h" #include "styles/style_chat.h" // popupMenuExpandedSeparator #include "styles/style_chat_helpers.h" +#include "styles/style_color_indices.h" #include "styles/style_window.h" #include "styles/style_menu_icons.h" @@ -702,6 +703,62 @@ void InnerWidget::paintEvent(QPaintEvent *e) { && (key.history()->peer->id == childListShown.peerId); context.st = (forum ? &st::forumDialogRow : _st.get()); + + auto chatsFilterTags = std::vector(); + if (context.narrow) { + context.chatsFilterTags = nullptr; + } else if (row->entry()->hasChatsFilterTags(context.filter)) { + context.st = forum + ? &st::taggedForumDialogRow + : &st::taggedDialogRow; + auto availableWidth = context.width + - context.st->padding.right() + - st::dialogsUnreadPadding + - context.st->nameLeft; + auto more = ushort(0); + const auto &list = session().data().chatsFilters().list(); + for (const auto &filter : list) { + if (!row->entry()->inChatList(filter.id()) + || (filter.id() == context.filter)) { + continue; + } + if (const auto tag = cacheChatsFilterTag(filter.id(), 0)) { + if (more) { + more++; + continue; + } + const auto tagWidth = tag->width() + / style::DevicePixelRatio(); + if (availableWidth < tagWidth) { + more++; + } else { + chatsFilterTags.push_back(tag); + availableWidth -= tagWidth + + st::dialogRowFilterTagSkip; + } + } + } + if (more) { + if (const auto tag = cacheChatsFilterTag(0, more)) { + const auto tagWidth = tag->width() + / style::DevicePixelRatio(); + if (availableWidth < tagWidth) { + more++; + if (const auto tag = cacheChatsFilterTag(0, more)) { + if (!chatsFilterTags.empty()) { + chatsFilterTags.back() = tag; + } + } + } else { + chatsFilterTags.push_back(tag); + } + } + } + context.chatsFilterTags = &chatsFilterTags; + } else { + context.chatsFilterTags = nullptr; + } + context.topicsExpanded = (expanding && !active) ? childListShown.shown : 0.; @@ -3943,6 +4000,62 @@ void InnerWidget::restoreChatsFilterScrollState(FilterId filterId) { } } +QImage *InnerWidget::cacheChatsFilterTag(FilterId filterId, ushort more) { + if (!filterId && !more) { + return nullptr; + } + const auto key = filterId ? filterId : -more; + { + const auto it = _chatsFilterTags.find(key); + if (it != end(_chatsFilterTags)) { + return &it->second; + } + } + auto roundedText = QString(); + auto colorIndex = -1; + if (filterId) { + const auto &list = session().data().chatsFilters().list(); + const auto it = ranges::find(list, filterId, &Data::ChatFilter::id); + if (it != end(list)) { + roundedText = it->title().toUpper(); + if (it->colorIndex()) { + colorIndex = *it->colorIndex(); + } + } + } else if (more > 0) { + roundedText = QChar('+') + QString::number(more); + colorIndex = st::colorIndexBlue; + } + if (roundedText.isEmpty() || colorIndex < 0) { + return nullptr; + } + const auto &roundedFont = st::dialogRowFilterTagFont; + const auto roundedWidth = roundedFont->width(roundedText) + + roundedFont->spacew * 3; + const auto rect = QRect(0, 0, roundedWidth, roundedFont->height); + auto cache = QImage( + rect.size() * style::DevicePixelRatio(), + QImage::Format_ARGB32_Premultiplied); + cache.setDevicePixelRatio(style::DevicePixelRatio()); + cache.fill(Qt::transparent); + { + auto p = QPainter(&cache); + const auto pen = QPen( + Ui::EmptyUserpic::UserpicColor(colorIndex).color2); + p.setPen(Qt::NoPen); + p.setBrush(anim::with_alpha(pen.color(), .15)); + { + auto hq = PainterHighQualityEnabler(p); + const auto radius = roundedFont->height / 3.; + p.drawRoundedRect(rect, radius, radius); + } + p.setPen(pen); + p.setFont(roundedFont); + p.drawText(rect, roundedText, style::al_center); + } + return &_chatsFilterTags.emplace(key, std::move(cache)).first->second; +} + bool InnerWidget::chooseHashtag() { if (_state != WidgetState::Filtered) { return false; diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h index a284cca11..dc316c2c1 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h @@ -448,6 +448,8 @@ private: void saveChatsFilterScrollState(FilterId filterId); void restoreChatsFilterScrollState(FilterId filterId); + [[nodiscard]] QImage *cacheChatsFilterTag(FilterId filterId, ushort more); + const not_null _controller; not_null _shownList; @@ -554,6 +556,7 @@ private: base::flat_map _chatsFilterScrollStates; + std::unordered_map _chatsFilterTags; Fn _loadMoreCallback; Fn _loadMoreFilteredCallback; rpl::event_stream<> _listBottomReached; diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp index 74ef86948..1a7b5a1ac 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp @@ -344,7 +344,7 @@ void PaintRow( row->paintUserpic(p, entry, from, videoUserpic, context); } - auto nameleft = context.st->nameLeft; + const auto nameleft = context.st->nameLeft; if (context.topicsExpanded > 0.) { PaintExpandedTopicsBar(p, context.topicsExpanded); } @@ -712,6 +712,15 @@ void PaintRow( .elisionLines = 1, }); } + + if (const auto tags = context.chatsFilterTags) { + auto left = nameleft; + for (const auto &tag : *tags) { + p.drawImage(left, context.st->tagTop, *tag); + left += st::dialogRowFilterTagSkip + + (tag->width() / style::DevicePixelRatio()); + } + } } } // namespace diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.h b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.h index cc67307d5..5e51c8e73 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.h +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.h @@ -53,6 +53,7 @@ struct TopicJumpCache { }; struct PaintContext { + std::vector *chatsFilterTags = nullptr; not_null st; TopicJumpCache *topicJumpCache = nullptr; Data::Folder *folder = nullptr; From e3465da979a52bf32d7be7d26c6ae3f09a02180c Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 20 Nov 2024 06:14:57 +0300 Subject: [PATCH 007/294] Switched order of data filter applying of changes from api. --- Telegram/SourceFiles/data/data_chat_filters.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Telegram/SourceFiles/data/data_chat_filters.cpp b/Telegram/SourceFiles/data/data_chat_filters.cpp index 7a6f63a74..36b88a740 100644 --- a/Telegram/SourceFiles/data/data_chat_filters.cpp +++ b/Telegram/SourceFiles/data/data_chat_filters.cpp @@ -393,7 +393,8 @@ void ChatFilters::received(const QVector &list) { auto changed = false; for (const auto &filter : list) { auto parsed = ChatFilter::FromTL(filter, _owner); - const auto b = begin(_list) + position, e = end(_list); + const auto b = begin(_list) + position; + const auto e = end(_list); const auto i = ranges::find(b, e, parsed.id(), &ChatFilter::id); if (i == e) { applyInsert(std::move(parsed), position); @@ -621,11 +622,13 @@ bool ChatFilters::applyChange(ChatFilter &filter, ChatFilter &&updated) { if (!listUpdated && !chatlistChanged) { return false; } + const auto wasFilter = std::move(filter); + filter = std::move(updated); if (rulesChanged) { const auto filterList = _owner->chatsFilters().chatsList(id); const auto feedHistory = [&](not_null history) { - const auto now = updated.contains(history); - const auto was = filter.contains(history); + const auto now = filter.contains(history); + const auto was = wasFilter.contains(history); if (now != was) { if (now) { history->addToChatList(id, filterList); @@ -645,17 +648,16 @@ bool ChatFilters::applyChange(ChatFilter &filter, ChatFilter &&updated) { if (const auto folder = _owner->folderLoaded(Data::Folder::kId)) { feedList(folder->chatsList()); } - if (exceptionsChanged && !updated.always().empty()) { + if (exceptionsChanged && !filter.always().empty()) { _exceptionsToLoad.push_back(id); Ui::PostponeCall(&_owner->session(), [=] { _owner->session().api().requestMoreDialogsIfNeeded(); }); } } - filter = std::move(updated); if (pinnedChanged) { const auto filterList = _owner->chatsFilters().chatsList(id); - filterList->pinned()->applyList(filter.pinned()); + filterList->pinned()->applyList(wasFilter.pinned()); } if (chatlistChanged) { _isChatlistChanged.fire_copy(id); From 632abd22256ef2120d586511bedc431894080cc8 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 20 Nov 2024 06:15:35 +0300 Subject: [PATCH 008/294] Optimized height refresh of main list on receiving chats filters. --- Telegram/SourceFiles/data/data_chat_filters.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Telegram/SourceFiles/data/data_chat_filters.cpp b/Telegram/SourceFiles/data/data_chat_filters.cpp index 36b88a740..141cf2a5d 100644 --- a/Telegram/SourceFiles/data/data_chat_filters.cpp +++ b/Telegram/SourceFiles/data/data_chat_filters.cpp @@ -624,8 +624,14 @@ bool ChatFilters::applyChange(ChatFilter &filter, ChatFilter &&updated) { } const auto wasFilter = std::move(filter); filter = std::move(updated); + auto entryToRefreshHeight = (Dialogs::Entry*)(nullptr); if (rulesChanged) { const auto filterList = _owner->chatsFilters().chatsList(id); + const auto tagsExistence = [&](not_null row) { + return entryToRefreshHeight + ? false + : row->entry()->hasChatsFilterTags(0); + }; const auto feedHistory = [&](not_null history) { const auto now = filter.contains(history); const auto was = wasFilter.contains(history); @@ -640,7 +646,11 @@ bool ChatFilters::applyChange(ChatFilter &filter, ChatFilter &&updated) { const auto feedList = [&](not_null list) { for (const auto &entry : *list->indexed()) { if (const auto history = entry->history()) { + const auto wasTags = tagsExistence(entry); feedHistory(history); + if (wasTags != tagsExistence(entry)) { + entryToRefreshHeight = entry->entry(); + } } } }; @@ -662,6 +672,10 @@ bool ChatFilters::applyChange(ChatFilter &filter, ChatFilter &&updated) { if (chatlistChanged) { _isChatlistChanged.fire_copy(id); } + if (entryToRefreshHeight) { + // Trigger a full refresh of height for the main list. + entryToRefreshHeight->updateChatListEntryHeight(); + } return listUpdated; } From 889fcb3939a82b14a259505841e0c712fa3385b1 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 20 Nov 2024 07:51:40 +0300 Subject: [PATCH 009/294] Optimized height refresh of non-main list on receiving chats filters. --- Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index 6012f9d73..47ed14dfc 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -287,9 +287,13 @@ InnerWidget::InnerWidget( }, lifetime()); rpl::merge( - session().settings().archiveCollapsedChanges() | rpl::to_empty, - session().data().chatsFilters().changed() - ) | rpl::start_with_next([=] { + session().settings().archiveCollapsedChanges() | rpl::map_to(false), + session().data().chatsFilters().changed() | rpl::map_to(true) + ) | rpl::start_with_next([=](bool refreshHeight) { + if (refreshHeight && _filterId) { + // Height of the main list will be refreshed in other way. + _shownList->updateHeights(_narrowRatio); + } refreshWithCollapsedRows(); }, lifetime()); From e314c68a561adb20c131ea8b67249b946ed9218d Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 20 Nov 2024 07:51:03 +0300 Subject: [PATCH 010/294] Optimized height refresh of chats list for chat filters with rules. --- .../dialogs/dialogs_inner_widget.cpp | 21 +++++++++++++++++++ .../dialogs/dialogs_inner_widget.h | 2 ++ 2 files changed, 23 insertions(+) diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index 47ed14dfc..2fb445fa1 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -2260,6 +2260,27 @@ void InnerWidget::handleChatListEntryRefreshes() { std::abs(from - to) + event.moved.height); } }, lifetime()); + + session().data().chatListEntryRefreshes( + ) | rpl::filter([=](const Event &event) { + if (_waitingAllChatListEntryRefreshesForTags) { + return false; + } + if (event.existenceChanged) { + if (event.key.entry()->inChatList(_filterId)) { + _waitingAllChatListEntryRefreshesForTags = true; + return true; + } + } + return false; + }) | rpl::start_with_next([=](const Event &event) { + Ui::PostponeCall(crl::guard(this, [=] { + _waitingAllChatListEntryRefreshesForTags = false; + if (_shownList->updateHeights(_narrowRatio)) { + refresh(); + } + })); + }, lifetime()); } void InnerWidget::repaintCollapsedFolderRow(not_null folder) { diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h index dc316c2c1..7af57126e 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h @@ -557,6 +557,8 @@ private: base::flat_map _chatsFilterScrollStates; std::unordered_map _chatsFilterTags; + bool _waitingAllChatListEntryRefreshesForTags = false; + Fn _loadMoreCallback; Fn _loadMoreFilteredCallback; rpl::event_stream<> _listBottomReached; From ba082081b3789ebb17fba7ae88db08dd7a0b21e2 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 20 Nov 2024 10:49:57 +0300 Subject: [PATCH 011/294] Added api support for enabled tags of chats filters. --- .../SourceFiles/data/data_chat_filters.cpp | 22 ++++++- Telegram/SourceFiles/data/data_chat_filters.h | 7 +++ .../SourceFiles/dialogs/dialogs_entry.cpp | 3 + .../dialogs/dialogs_inner_widget.cpp | 62 ++++++++++++------- .../dialogs/dialogs_inner_widget.h | 1 + 5 files changed, 72 insertions(+), 23 deletions(-) diff --git a/Telegram/SourceFiles/data/data_chat_filters.cpp b/Telegram/SourceFiles/data/data_chat_filters.cpp index 141cf2a5d..535acc205 100644 --- a/Telegram/SourceFiles/data/data_chat_filters.cpp +++ b/Telegram/SourceFiles/data/data_chat_filters.cpp @@ -377,6 +377,7 @@ void ChatFilters::load(bool force) { api.request(_loadRequestId).cancel(); _loadRequestId = api.request(MTPmessages_GetDialogFilters( )).done([=](const MTPmessages_DialogFilters &result) { + _tagsEnabled = result.data().is_tags_enabled(); received(result.data().vfilters().v); _loadRequestId = 0; }).fail([=] { @@ -388,6 +389,14 @@ void ChatFilters::load(bool force) { }).send(); } +bool ChatFilters::tagsEnabled() const { + return _tagsEnabled.current(); +} + +rpl::producer ChatFilters::tagsEnabledValue() const { + return _tagsEnabled.value(); +} + void ChatFilters::received(const QVector &list) { auto position = 0; auto changed = false; @@ -619,7 +628,8 @@ bool ChatFilters::applyChange(ChatFilter &filter, ChatFilter &&updated) { || pinnedChanged || (filter.title() != updated.title()) || (filter.iconEmoji() != updated.iconEmoji()); - if (!listUpdated && !chatlistChanged) { + const auto colorChanged = filter.colorIndex() != updated.colorIndex(); + if (!listUpdated && !chatlistChanged && !colorChanged) { return false; } const auto wasFilter = std::move(filter); @@ -627,8 +637,9 @@ bool ChatFilters::applyChange(ChatFilter &filter, ChatFilter &&updated) { auto entryToRefreshHeight = (Dialogs::Entry*)(nullptr); if (rulesChanged) { const auto filterList = _owner->chatsFilters().chatsList(id); + const auto areTagsEnabled = tagsEnabled(); const auto tagsExistence = [&](not_null row) { - return entryToRefreshHeight + return (!areTagsEnabled || entryToRefreshHeight) ? false : row->entry()->hasChatsFilterTags(0); }; @@ -672,6 +683,9 @@ bool ChatFilters::applyChange(ChatFilter &filter, ChatFilter &&updated) { if (chatlistChanged) { _isChatlistChanged.fire_copy(id); } + if (colorChanged) { + _tagColorChanged.fire_copy(id); + } if (entryToRefreshHeight) { // Trigger a full refresh of height for the main list. entryToRefreshHeight->updateChatListEntryHeight(); @@ -818,6 +832,10 @@ rpl::producer ChatFilters::isChatlistChanged() const { return _isChatlistChanged.events(); } +rpl::producer ChatFilters::tagColorChanged() const { + return _tagColorChanged.events(); +} + bool ChatFilters::loadNextExceptions(bool chatsListLoaded) { if (_exceptionsLoadRequestId) { return true; diff --git a/Telegram/SourceFiles/data/data_chat_filters.h b/Telegram/SourceFiles/data/data_chat_filters.h index e123ab2c1..42a635809 100644 --- a/Telegram/SourceFiles/data/data_chat_filters.h +++ b/Telegram/SourceFiles/data/data_chat_filters.h @@ -139,6 +139,7 @@ public: [[nodiscard]] const std::vector &list() const; [[nodiscard]] rpl::producer<> changed() const; [[nodiscard]] rpl::producer isChatlistChanged() const; + [[nodiscard]] rpl::producer tagColorChanged() const; [[nodiscard]] bool loaded() const; [[nodiscard]] bool has() const; @@ -185,6 +186,9 @@ public: FilterId id) const; void moreChatsHide(FilterId id, bool localOnly = false); + [[nodiscard]] bool tagsEnabled() const; + [[nodiscard]] rpl::producer tagsEnabledValue() const; + private: struct MoreChatsData { std::vector> missing; @@ -209,6 +213,7 @@ private: base::flat_map> _chatsLists; rpl::event_stream<> _listChanged; rpl::event_stream _isChatlistChanged; + rpl::event_stream _tagColorChanged; mtpRequestId _loadRequestId = 0; mtpRequestId _saveOrderRequestId = 0; mtpRequestId _saveOrderAfterId = 0; @@ -220,6 +225,8 @@ private: rpl::event_stream<> _suggestedUpdated; crl::time _suggestedLastReceived = 0; + rpl::variable _tagsEnabled = false; + std::deque _exceptionsToLoad; mtpRequestId _exceptionsLoadRequestId = 0; diff --git a/Telegram/SourceFiles/dialogs/dialogs_entry.cpp b/Telegram/SourceFiles/dialogs/dialogs_entry.cpp index 957e7f4f5..76d5ebe84 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_entry.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_entry.cpp @@ -415,6 +415,9 @@ void Entry::updateChatListEntryHeight() { } [[nodiscard]] bool Entry::hasChatsFilterTags(FilterId exclude) const { + if (!owner().chatsFilters().tagsEnabled()) { + return false; + } if (exclude) { if (_tagColors.size() == 1) { if (_tagColors.begin()->first == exclude) { diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index 2fb445fa1..44f672bec 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -297,6 +297,47 @@ InnerWidget::InnerWidget( refreshWithCollapsedRows(); }, lifetime()); + session().data().chatsFilters().tagsEnabledValue( + ) | rpl::distinct_until_changed() | rpl::start_with_next([=](bool tags) { + _handleChatListEntryTagRefreshesLifetime.destroy(); + if (_shownList->updateHeights(_narrowRatio)) { + refresh(); + } + if (!tags) { + return; + } + using Event = Data::Session::ChatListEntryRefresh; + session().data().chatListEntryRefreshes( + ) | rpl::filter([=](const Event &event) { + if (_waitingAllChatListEntryRefreshesForTags) { + return false; + } + if (event.existenceChanged) { + if (event.key.entry()->inChatList(_filterId)) { + _waitingAllChatListEntryRefreshesForTags = true; + return true; + } + } + return false; + }) | rpl::start_with_next([=](const Event &event) { + Ui::PostponeCall(crl::guard(this, [=] { + _waitingAllChatListEntryRefreshesForTags = false; + if (_shownList->updateHeights(_narrowRatio)) { + refresh(); + } + })); + }, _handleChatListEntryTagRefreshesLifetime); + + session().data().chatsFilters().tagColorChanged( + ) | rpl::start_with_next([=](FilterId filterId) { + const auto it = _chatsFilterTags.find(filterId); + if (it != _chatsFilterTags.end()) { + _chatsFilterTags.erase(it); + update(); + } + }, _handleChatListEntryTagRefreshesLifetime); + }, lifetime()); + session().settings().archiveInMainMenuChanges( ) | rpl::start_with_next([=] { refresh(); @@ -2260,27 +2301,6 @@ void InnerWidget::handleChatListEntryRefreshes() { std::abs(from - to) + event.moved.height); } }, lifetime()); - - session().data().chatListEntryRefreshes( - ) | rpl::filter([=](const Event &event) { - if (_waitingAllChatListEntryRefreshesForTags) { - return false; - } - if (event.existenceChanged) { - if (event.key.entry()->inChatList(_filterId)) { - _waitingAllChatListEntryRefreshesForTags = true; - return true; - } - } - return false; - }) | rpl::start_with_next([=](const Event &event) { - Ui::PostponeCall(crl::guard(this, [=] { - _waitingAllChatListEntryRefreshesForTags = false; - if (_shownList->updateHeights(_narrowRatio)) { - refresh(); - } - })); - }, lifetime()); } void InnerWidget::repaintCollapsedFolderRow(not_null folder) { diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h index 7af57126e..4819d0646 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h @@ -558,6 +558,7 @@ private: std::unordered_map _chatsFilterTags; bool _waitingAllChatListEntryRefreshesForTags = false; + rpl::lifetime _handleChatListEntryTagRefreshesLifetime; Fn _loadMoreCallback; Fn _loadMoreFilteredCallback; From 6baba5a7b2c6ae16dcdb3a1bca7189258981c415 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 20 Nov 2024 13:21:56 +0300 Subject: [PATCH 012/294] Added ability to disable chats filters tags from settings. --- Telegram/Resources/langs/lang.strings | 5 + .../SourceFiles/boxes/premium_preview_box.cpp | 5 + .../SourceFiles/boxes/premium_preview_box.h | 1 + .../SourceFiles/data/data_chat_filters.cpp | 17 ++ Telegram/SourceFiles/data/data_chat_filters.h | 2 + .../SourceFiles/settings/settings_folders.cpp | 172 ++++++++++++++++-- 6 files changed, 190 insertions(+), 12 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index b9c61205a..20b1b7c6a 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -2300,6 +2300,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_premium_summary_about_business" = "Upgrade your account with business features such as location, opening hours and quick replies."; "lng_premium_summary_subtitle_effects" = "Message Effects"; "lng_premium_summary_about_effects" = "Add over 500 animated effects to private messages."; +"lng_premium_summary_subtitle_filter_tags" = "Tag Your Chats"; +"lng_premium_summary_about_filter_tags" = "Display folder names for each chat in the chat list."; "lng_premium_summary_bottom_subtitle" = "About Telegram Premium"; "lng_premium_summary_bottom_about" = "While the free version of Telegram already gives its users more than any other messaging application, **Telegram Premium** pushes its capabilities even further.\n\n**Telegram Premium** is a paid option, because most Premium Features require additional expenses from Telegram to third parties such as data center providers and server manufacturers. Contributions from **Telegram Premium** users allow us to cover such costs and also help Telegram stay free for everyone."; "lng_premium_summary_button" = "Subscribe for {cost} per month"; @@ -5155,6 +5157,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_filters_view_subtitle" = "Tabs view"; "lng_filters_vertical" = "Tabs on the left"; "lng_filters_horizontal" = "Tabs at the top"; +"lng_filters_enable_tags" = "Show Folder Tags"; +"lng_filters_enable_tags_about" = "Display folder names for each chat in the chat list."; +"lng_filters_enable_tags_about_premium" = "Subscribe to **{link}** to display folder names for each chat in the chat list."; "lng_filters_delete_sure" = "Are you sure you want to delete this folder? This will also deactivate all the invite links created to share this folder."; "lng_filters_link" = "Share Folder"; diff --git a/Telegram/SourceFiles/boxes/premium_preview_box.cpp b/Telegram/SourceFiles/boxes/premium_preview_box.cpp index 89e0edfed..0e2bf6801 100644 --- a/Telegram/SourceFiles/boxes/premium_preview_box.cpp +++ b/Telegram/SourceFiles/boxes/premium_preview_box.cpp @@ -133,6 +133,8 @@ void PreloadSticker(const std::shared_ptr &media) { return tr::lng_premium_summary_subtitle_business(); case PremiumFeature::Effects: return tr::lng_premium_summary_subtitle_effects(); + case PremiumFeature::FilterTags: + return tr::lng_premium_summary_subtitle_filter_tags(); case PremiumFeature::BusinessLocation: return tr::lng_business_subtitle_location(); @@ -196,6 +198,8 @@ void PreloadSticker(const std::shared_ptr &media) { return tr::lng_premium_summary_about_business(); case PremiumFeature::Effects: return tr::lng_premium_summary_about_effects(); + case PremiumFeature::FilterTags: + return tr::lng_premium_summary_about_filter_tags(); case PremiumFeature::BusinessLocation: return tr::lng_business_about_location(); @@ -534,6 +538,7 @@ struct VideoPreviewDocument { case PremiumFeature::LastSeen: return "last_seen"; case PremiumFeature::MessagePrivacy: return "message_privacy"; case PremiumFeature::Effects: return "effects"; + case PremiumFeature::FilterTags: return "folder_tags"; case PremiumFeature::BusinessLocation: return "business_location"; case PremiumFeature::BusinessHours: return "business_hours"; diff --git a/Telegram/SourceFiles/boxes/premium_preview_box.h b/Telegram/SourceFiles/boxes/premium_preview_box.h index 4dae5c30d..e631c9789 100644 --- a/Telegram/SourceFiles/boxes/premium_preview_box.h +++ b/Telegram/SourceFiles/boxes/premium_preview_box.h @@ -71,6 +71,7 @@ enum class PremiumFeature { MessagePrivacy, Business, Effects, + FilterTags, // Business features. BusinessLocation, diff --git a/Telegram/SourceFiles/data/data_chat_filters.cpp b/Telegram/SourceFiles/data/data_chat_filters.cpp index 535acc205..ba3c0758d 100644 --- a/Telegram/SourceFiles/data/data_chat_filters.cpp +++ b/Telegram/SourceFiles/data/data_chat_filters.cpp @@ -397,6 +397,23 @@ rpl::producer ChatFilters::tagsEnabledValue() const { return _tagsEnabled.value(); } +void ChatFilters::requestToggleTags(bool value, Fn fail) { + if (_toggleTagsRequestId) { + return; + } + _toggleTagsRequestId = _owner->session().api().request( + MTPmessages_ToggleDialogFilterTags(MTP_bool(value)) + ).done([=](const MTPBool &result) { + _tagsEnabled = value; + _toggleTagsRequestId = 0; + }).fail([=](const MTP::Error &error) { + const auto message = error.type(); + _toggleTagsRequestId = 0; + LOG(("API Error: Toggle Tags - %1").arg(message)); + fail(); + }).send(); +} + void ChatFilters::received(const QVector &list) { auto position = 0; auto changed = false; diff --git a/Telegram/SourceFiles/data/data_chat_filters.h b/Telegram/SourceFiles/data/data_chat_filters.h index 42a635809..18630b391 100644 --- a/Telegram/SourceFiles/data/data_chat_filters.h +++ b/Telegram/SourceFiles/data/data_chat_filters.h @@ -188,6 +188,7 @@ public: [[nodiscard]] bool tagsEnabled() const; [[nodiscard]] rpl::producer tagsEnabledValue() const; + void requestToggleTags(bool value, Fn fail); private: struct MoreChatsData { @@ -217,6 +218,7 @@ private: mtpRequestId _loadRequestId = 0; mtpRequestId _saveOrderRequestId = 0; mtpRequestId _saveOrderAfterId = 0; + mtpRequestId _toggleTagsRequestId = 0; bool _loaded = false; bool _reloading = false; diff --git a/Telegram/SourceFiles/settings/settings_folders.cpp b/Telegram/SourceFiles/settings/settings_folders.cpp index 552215041..c0d595dd9 100644 --- a/Telegram/SourceFiles/settings/settings_folders.cpp +++ b/Telegram/SourceFiles/settings/settings_folders.cpp @@ -7,34 +7,38 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "settings/settings_folders.h" -#include "apiwrap.h" #include "api/api_chat_filters.h" // ProcessFilterRemove. -#include "boxes/premium_limits_box.h" +#include "apiwrap.h" #include "boxes/filters/edit_filter_box.h" +#include "boxes/premium_limits_box.h" +#include "boxes/premium_preview_box.h" #include "core/application.h" #include "data/data_chat_filters.h" #include "data/data_folder.h" #include "data/data_peer.h" #include "data/data_peer_values.h" // Data::AmPremiumValue. -#include "data/data_session.h" #include "data/data_premium_limits.h" +#include "data/data_session.h" #include "history/history.h" #include "lang/lang_keys.h" #include "lottie/lottie_icon.h" #include "main/main_session.h" +#include "settings/settings_premium.h" #include "ui/boxes/confirm_box.h" +#include "ui/empty_userpic.h" #include "ui/filter_icons.h" #include "ui/layers/generic_box.h" #include "ui/painter.h" -#include "ui/vertical_list.h" +#include "ui/rect.h" #include "ui/text/text_utilities.h" +#include "ui/ui_utility.h" +#include "ui/vertical_list.h" #include "ui/widgets/box_content_divider.h" #include "ui/widgets/buttons.h" #include "ui/widgets/checkbox.h" #include "ui/widgets/fields/input_field.h" #include "ui/widgets/labels.h" #include "ui/wrap/slide_wrap.h" -#include "ui/ui_utility.h" #include "window/window_controller.h" #include "window/window_session_controller.h" #include "styles/style_settings.h" @@ -67,6 +71,8 @@ public: [[nodiscard]] rpl::producer<> restoreRequests() const; [[nodiscard]] rpl::producer<> addRequests() const; + void setColorIndexProgress(float64 progress); + private: enum class State { Suggested, @@ -96,6 +102,8 @@ private: Ui::Text::String _title; QString _status; Ui::FilterIcon _icon = Ui::FilterIcon(); + std::optional _colorIndex; + float64 _colorIndexProgress = 1.; State _state = State::Normal; @@ -238,11 +246,11 @@ void FilterRowButton::setup( _title.setText(st::contactsNameStyle, filter.title()); _status = status; _icon = Ui::ComputeFilterIcon(filter); + _colorIndex = filter.colorIndex(); setState(_state, true); - sizeValue( - ) | rpl::start_with_next([=](QSize size) { + sizeValue() | rpl::start_with_next([=](QSize size) { const auto right = st::contactsPadding.right() + st::contactsCheckPosition.x(); const auto width = size.width(); @@ -272,6 +280,13 @@ rpl::producer<> FilterRowButton::addRequests() const { return _add.clicks() | rpl::to_empty; } +void FilterRowButton::setColorIndexProgress(float64 progress) { + _colorIndexProgress = progress; + if (_colorIndex) { + update(); + } +} + void FilterRowButton::paintEvent(QPaintEvent *e) { auto p = Painter(this); @@ -281,6 +296,19 @@ void FilterRowButton::paintEvent(QPaintEvent *e) { p.fillRect(e->rect(), st::windowBgOver); } RippleButton::paintRipple(p, 0, 0); + + if (_colorIndex) { + p.setPen(Qt::NoPen); + p.setBrush(Ui::EmptyUserpic::UserpicColor(*_colorIndex).color2); + const auto w = height() / 3; + const auto rect = QRect( + _remove.x() - w - st::contactsCheckPosition.x(), + (height() - w) / 2, + w, + w); + auto hq = PainterHighQualityEnabler(p); + p.drawEllipse(rect - Margins((1. - _colorIndexProgress) * w / 2)); + } } else if (_state == State::Removed) { p.setOpacity(st::stickersRowDisabledOpacity); } @@ -335,7 +363,8 @@ void FilterRowButton::paintEvent(QPaintEvent *e) { [[nodiscard]] Fn SetupFoldersContent( not_null controller, - not_null container) { + not_null container, + not_null*> tagsButtonEnabled) { auto &lifetime = container->lifetime(); const auto weak = Ui::MakeWeak(container); @@ -351,6 +380,7 @@ void FilterRowButton::paintEvent(QPaintEvent *e) { rpl::variable count; rpl::variable suggested; Fn)> save; + Ui::Animations::Simple tagsEnabledAnimation; }; const auto state = lifetime.make_state(); @@ -583,6 +613,22 @@ void FilterRowButton::paintEvent(QPaintEvent *e) { Ui::AddSkip(aboutRows); Ui::AddSubsectionTitle(aboutRows, tr::lng_filters_recommended()); + const auto setTagsProgress = [=](float64 value) { + for (const auto &row : state->rows) { + row.button->setColorIndexProgress(value); + } + }; + tagsButtonEnabled->events() | rpl::distinct_until_changed( + ) | rpl::start_with_next([=](bool value) { + state->tagsEnabledAnimation.stop(); + state->tagsEnabledAnimation.start( + setTagsProgress, + value ? .0 : 1., + value ? 1. : .0, + st::universalDuration); + }, lifetime); + setTagsProgress(session->data().chatsFilters().tagsEnabled()); + rpl::single(rpl::empty) | rpl::then( session->data().chatsFilters().suggestedUpdated() ) | rpl::map([=] { @@ -844,9 +890,101 @@ void SetupTopContent( } +void SetupTagContent( + not_null controller, + not_null content, + not_null*> tagsButtonEnabled) { + Ui::AddDivider(content); + Ui::AddSkip(content); + + const auto session = &controller->session(); + + struct State final { + rpl::event_stream tagsTurnOff; + base::Timer requestTimer; + Fn sendCallback; + }; + + auto premium = Data::AmPremiumValue(session); + const auto tagsButton = content->add( + object_ptr( + content, + tr::lng_filters_enable_tags(), + st::settingsButtonNoIconLocked)); + const auto state = tagsButton->lifetime().make_state(); + tagsButton->toggleOn(rpl::merge( + rpl::combine( + session->data().chatsFilters().tagsEnabledValue(), + rpl::duplicate(premium), + rpl::mappers::_1 && rpl::mappers::_2), + state->tagsTurnOff.events())); + rpl::duplicate(premium) | rpl::start_with_next([=](bool value) { + tagsButton->setToggleLocked(!value); + }, tagsButton->lifetime()); + + const auto send = [=, weak = Ui::MakeWeak(tagsButton)](bool checked) { + session->data().chatsFilters().requestToggleTags(checked, [=] { + if (const auto strong = weak.data()) { + state->tagsTurnOff.fire(!checked); + } + }); + }; + + tagsButton->toggledValue( + ) | rpl::filter([=](bool checked) { + const auto premium = session->premium(); + if (checked && !premium) { + ShowPremiumPreviewToBuy(controller, PremiumFeature::FilterTags); + state->tagsTurnOff.fire(false); + } + if (!premium) { + tagsButtonEnabled->fire(false); + } else { + tagsButtonEnabled->fire_copy(checked); + } + const auto proceed = premium + && (checked != session->data().chatsFilters().tagsEnabled()); + if (!proceed) { + state->requestTimer.cancel(); + } + return proceed; + }) | rpl::start_with_next([=](bool v) { + state->sendCallback = [=] { send(v); }; + state->requestTimer.cancel(); + state->requestTimer.setCallback([=] { send(v); }); + state->requestTimer.callOnce(500); + }, tagsButton->lifetime()); + + tagsButton->lifetime().add([=] { + if (state->requestTimer.isActive()) { + if (state->sendCallback) { + state->sendCallback(); + } + } + }); + + Ui::AddSkip(content); + const auto about = Ui::AddDividerText( + content, + rpl::conditional( + rpl::duplicate(premium), + tr::lng_filters_enable_tags_about(Ui::Text::RichLangValue), + tr::lng_filters_enable_tags_about_premium( + lt_link, + tr::lng_effect_premium_link() | rpl::map([](QString t) { + return Ui::Text::Link(std::move(t), u"internal:"_q); + }), + Ui::Text::RichLangValue))); + about->setClickHandlerFilter([=](const auto &...) { + Settings::ShowPremium(controller, u"folder_tags"_q); + return true; + }); +} + void SetupView( not_null controller, - not_null content) { + not_null content, + bool dividerNeeded) { const auto wrap = content->add( object_ptr>( content, @@ -854,7 +992,9 @@ void SetupView( wrap->toggleOn(controller->enoughSpaceForFiltersValue()); content = wrap->entity(); - Ui::AddDivider(content); + if (dividerNeeded) { + Ui::AddDivider(content); + } Ui::AddSkip(content); Ui::AddSubsectionTitle(content, tr::lng_filters_view_subtitle()); @@ -904,12 +1044,20 @@ void Folders::setupContent(not_null controller) { controller->session().data().chatsFilters().requestSuggested(); const auto content = Ui::CreateChild(this); + const auto tagsButtonEnabled + = content->lifetime().make_state>(); SetupTopContent(content, _showFinished.events()); - _save = SetupFoldersContent(controller, content); + _save = SetupFoldersContent(controller, content, tagsButtonEnabled); - SetupView(controller, content); + auto dividerNeeded = true; + if (controller->session().premiumPossible()) { + SetupTagContent(controller, content, tagsButtonEnabled); + dividerNeeded = false; + } + + SetupView(controller, content, dividerNeeded); Ui::ResizeFitChild(this, content); } From cfc40ee966dd046d53c4f67293b7ba2718b14a5f Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 20 Nov 2024 14:56:58 +0300 Subject: [PATCH 013/294] Added ability to set color for chats filter from settings. --- Telegram/Resources/langs/lang.strings | 3 + .../boxes/filters/edit_filter_box.cpp | 142 +++++++++++++++--- .../boxes/filters/edit_filter_box.h | 6 +- .../SourceFiles/data/data_chat_filters.cpp | 6 + Telegram/SourceFiles/data/data_chat_filters.h | 1 + .../SourceFiles/settings/settings_folders.cpp | 1 + 6 files changed, 137 insertions(+), 22 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 20b1b7c6a..5919b2593 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -5160,6 +5160,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_filters_enable_tags" = "Show Folder Tags"; "lng_filters_enable_tags_about" = "Display folder names for each chat in the chat list."; "lng_filters_enable_tags_about_premium" = "Subscribe to **{link}** to display folder names for each chat in the chat list."; +"lng_filters_tag_color_subtitle" = "Folder color in chat list"; +"lng_filters_tag_color_about" = "Choose a color for the tag of this folder."; +"lng_filters_tag_color_no" = "No Tag"; "lng_filters_delete_sure" = "Are you sure you want to delete this folder? This will also deactivate all the invite links created to share this folder."; "lng_filters_link" = "Share Folder"; diff --git a/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp b/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp index df85e6254..d36a33f2c 100644 --- a/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp +++ b/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp @@ -7,22 +7,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "boxes/filters/edit_filter_box.h" +#include "apiwrap.h" +#include "base/event_filter.h" #include "boxes/filters/edit_filter_chats_list.h" #include "boxes/filters/edit_filter_chats_preview.h" #include "boxes/filters/edit_filter_links.h" #include "boxes/premium_limits_box.h" +#include "boxes/premium_preview_box.h" #include "chat_helpers/emoji_suggestions_widget.h" -#include "ui/layers/generic_box.h" -#include "ui/text/text_utilities.h" -#include "ui/text/text_options.h" -#include "ui/widgets/buttons.h" -#include "ui/widgets/fields/input_field.h" -#include "ui/wrap/slide_wrap.h" -#include "ui/effects/panel_animation.h" -#include "ui/filter_icons.h" -#include "ui/filter_icon_panel.h" -#include "ui/painter.h" -#include "ui/vertical_list.h" +#include "core/application.h" +#include "core/core_settings.h" #include "data/data_channel.h" #include "data/data_chat_filters.h" #include "data/data_peer.h" @@ -30,22 +24,30 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_premium_limits.h" #include "data/data_session.h" #include "data/data_user.h" -#include "core/application.h" -#include "core/core_settings.h" -#include "settings/settings_common.h" -#include "base/event_filter.h" -#include "lang/lang_keys.h" #include "history/history.h" +#include "info/userpic/info_userpic_color_circle_button.h" +#include "lang/lang_keys.h" #include "main/main_session.h" -#include "window/window_session_controller.h" +#include "settings/settings_common.h" +#include "ui/effects/animations.h" +#include "ui/effects/panel_animation.h" +#include "ui/empty_userpic.h" +#include "ui/filter_icon_panel.h" +#include "ui/filter_icons.h" +#include "ui/layers/generic_box.h" +#include "ui/painter.h" +#include "ui/vertical_list.h" +#include "ui/widgets/buttons.h" +#include "ui/widgets/fields/input_field.h" +#include "ui/wrap/slide_wrap.h" #include "window/window_controller.h" -#include "apiwrap.h" +#include "window/window_session_controller.h" #include "styles/style_settings.h" #include "styles/style_boxes.h" #include "styles/style_layers.h" #include "styles/style_window.h" #include "styles/style_chat.h" -#include "styles/style_menu_icons.h" +#include "styles/style_info_userpic_builder.h" namespace { @@ -336,6 +338,7 @@ void EditFilterBox( const Data::ChatFilter &data, Fn next)> saveAnd) { using namespace rpl::mappers; + constexpr auto kColorsCount = 8; struct State { rpl::variable rules; @@ -343,6 +346,7 @@ void EditFilterBox( rpl::variable hasLinks; rpl::variable chatlist; rpl::variable creating; + rpl::variable colorIndex; }; const auto owner = &window->session().data(); const auto state = box->lifetime().make_state(State{ @@ -350,6 +354,7 @@ void EditFilterBox( .chatlist = filter.chatlist(), .creating = filter.title().isEmpty(), }); + state->colorIndex = filter.colorIndex().value_or(kColorsCount - 1); state->links = owner->chatsFilters().chatlistLinks(filter.id()), state->hasLinks = state->links.value() | rpl::map([=](const auto &v) { return !v.empty(); @@ -504,6 +509,99 @@ void EditFilterBox( Ui::AddDividerText(excludeInner, tr::lng_filters_exclude_about()); Ui::AddSkip(excludeInner); + { + const auto wrap = content->add( + object_ptr>( + content, + object_ptr(content))); + const auto colors = wrap->entity(); + const auto session = &window->session(); + + wrap->toggleOn( + rpl::combine( + session->premiumPossibleValue(), + session->data().chatsFilters().tagsEnabledValue(), + Data::AmPremiumValue(session) + ) | rpl::map([=] (bool possible, bool tagsEnabled, bool premium) { + return possible && (tagsEnabled || !premium); + }), + anim::type::instant); + + const auto isPremium = session->premium(); + Ui::AddSubsectionTitle(colors, tr::lng_filters_tag_color_subtitle()); + const auto side = st::userpicBuilderEmojiAccentColorSize; + const auto line = colors->add( + Ui::CreateSkipWidget(colors, side), + st::boxRowPadding); + auto buttons = std::vector>(); + const auto animation + = line->lifetime().make_state(); + for (auto i = 0; i < kColorsCount; ++i) { + const auto button = Ui::CreateChild( + line); + button->resize(side, side); + button->setIndex(i); + button->setSelectedProgress(isPremium + ? (state->colorIndex.current() == i) + : (i == (kColorsCount - 1))); + button->setBrush(Ui::EmptyUserpic::UserpicColor(i).color2); + buttons.push_back(button); + } + for (auto i = 0; i < kColorsCount; ++i) { + const auto &button = buttons[i]; + button->setClickedCallback([=] { + const auto was = state->colorIndex.current(); + const auto now = i; + if (was != now) { + animation->stop(); + animation->start([=](float64 progress) { + if (was >= 0) { + buttons[was]->setSelectedProgress(1. - progress); + } + buttons[now]->setSelectedProgress(progress); + }, 0., 1., st::universalDuration); + } + state->colorIndex = now; + }); + if (!session->premium()) { + button->setClickedCallback([w = window] { + ShowPremiumPreviewToBuy(w, PremiumFeature::FilterTags); + }); + } + } + line->sizeValue() | rpl::start_with_next([=](const QSize &size) { + const auto totalWidth = buttons.size() * side; + const auto spacing = (size.width() - totalWidth) + / (buttons.size() - 1); + for (auto i = 0; i < kColorsCount; ++i) { + const auto &button = buttons[i]; + button->moveToLeft(i * (side + spacing), 0); + } + }, line->lifetime()); + + { + const auto last = buttons.back(); + const auto icon = Ui::CreateChild(last); + icon->resize(side, side); + icon->paintRequest() | rpl::start_with_next([=] { + auto p = QPainter(icon); + (session->premium() + ? st::windowFilterSmallRemove.icon + : st::historySendDisabledIcon).paintInCenter( + p, + QRectF(icon->rect()), + st::historyPeerUserpicFg->c); + }, icon->lifetime()); + icon->setAttribute(Qt::WA_TransparentForMouseEvents); + last->setBrush(st::historyPeerArchiveUserpicBg); + } + + Ui::AddSkip(colors); + Ui::AddSkip(colors); + Ui::AddDividerText(colors, tr::lng_filters_tag_color_about()); + Ui::AddSkip(colors); + } + const auto collect = [=]() -> std::optional { const auto title = name->getLastText().trimmed(); const auto rules = data->current(); @@ -520,7 +618,11 @@ void EditFilterBox( window->window().showToast(tr::lng_filters_default(tr::now)); return {}; } - return rules.withTitle(title); + const auto rawColorIndex = state->colorIndex.current(); + const auto colorIndex = (rawColorIndex >= (kColorsCount - 1) + ? std::nullopt + : std::make_optional(rawColorIndex)); + return rules.withTitle(title).withColorIndex(colorIndex); }; Ui::AddSubsectionTitle( diff --git a/Telegram/SourceFiles/boxes/filters/edit_filter_box.h b/Telegram/SourceFiles/boxes/filters/edit_filter_box.h index 695dbbe92..cfff92907 100644 --- a/Telegram/SourceFiles/boxes/filters/edit_filter_box.h +++ b/Telegram/SourceFiles/boxes/filters/edit_filter_box.h @@ -7,12 +7,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once -#include "ui/layers/generic_box.h" - namespace Window { class SessionController; } // namespace Window +namespace Ui { +class GenericBox; +} // namespace Ui + namespace Data { class ChatFilter; } // namespace Data diff --git a/Telegram/SourceFiles/data/data_chat_filters.cpp b/Telegram/SourceFiles/data/data_chat_filters.cpp index ba3c0758d..224ee2797 100644 --- a/Telegram/SourceFiles/data/data_chat_filters.cpp +++ b/Telegram/SourceFiles/data/data_chat_filters.cpp @@ -168,6 +168,12 @@ ChatFilter ChatFilter::withTitle(const QString &title) const { return result; } +ChatFilter ChatFilter::withColorIndex(std::optional c) const { + auto result = *this; + result._colorIndex = c; + return result; +} + ChatFilter ChatFilter::withChatlist(bool chatlist, bool hasMyLinks) const { auto result = *this; result._flags &= Flag::RulesMask; diff --git a/Telegram/SourceFiles/data/data_chat_filters.h b/Telegram/SourceFiles/data/data_chat_filters.h index 18630b391..82f050af0 100644 --- a/Telegram/SourceFiles/data/data_chat_filters.h +++ b/Telegram/SourceFiles/data/data_chat_filters.h @@ -60,6 +60,7 @@ public: [[nodiscard]] ChatFilter withId(FilterId id) const; [[nodiscard]] ChatFilter withTitle(const QString &title) const; + [[nodiscard]] ChatFilter withColorIndex(std::optional) const; [[nodiscard]] ChatFilter withChatlist( bool chatlist, bool hasMyLinks) const; diff --git a/Telegram/SourceFiles/settings/settings_folders.cpp b/Telegram/SourceFiles/settings/settings_folders.cpp index c0d595dd9..f91427005 100644 --- a/Telegram/SourceFiles/settings/settings_folders.cpp +++ b/Telegram/SourceFiles/settings/settings_folders.cpp @@ -219,6 +219,7 @@ void FilterRowButton::updateData(const Data::ChatFilter &filter) { _title.setText(st::contactsNameStyle, filter.title()); _icon = Ui::ComputeFilterIcon(filter); + _colorIndex = filter.colorIndex(); updateCount(filter); } From 4a19f193ceb1ffe60f1bf10f01e7addfed6ad26d Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 20 Nov 2024 15:46:42 +0300 Subject: [PATCH 014/294] Added float preview of color for chats filter to settings. --- .../boxes/filters/edit_filter_box.cpp | 86 +++++++++++++++++-- 1 file changed, 79 insertions(+), 7 deletions(-) diff --git a/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp b/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp index d36a33f2c..0edbba1e9 100644 --- a/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp +++ b/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp @@ -29,6 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "lang/lang_keys.h" #include "main/main_session.h" #include "settings/settings_common.h" +#include "ui/effects/animation_value_f.h" #include "ui/effects/animations.h" #include "ui/effects/panel_animation.h" #include "ui/empty_userpic.h" @@ -44,6 +45,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/window_session_controller.h" #include "styles/style_settings.h" #include "styles/style_boxes.h" +#include "styles/style_dialogs.h" #include "styles/style_layers.h" #include "styles/style_window.h" #include "styles/style_chat.h" @@ -339,6 +341,7 @@ void EditFilterBox( Fn next)> saveAnd) { using namespace rpl::mappers; constexpr auto kColorsCount = 8; + constexpr auto kNoTag = kColorsCount - 1; struct State { rpl::variable rules; @@ -354,7 +357,7 @@ void EditFilterBox( .chatlist = filter.chatlist(), .creating = filter.title().isEmpty(), }); - state->colorIndex = filter.colorIndex().value_or(kColorsCount - 1); + state->colorIndex = filter.colorIndex().value_or(kNoTag); state->links = owner->chatsFilters().chatlistLinks(filter.id()), state->hasLinks = state->links.value() | rpl::map([=](const auto &v) { return !v.empty(); @@ -528,7 +531,59 @@ void EditFilterBox( anim::type::instant); const auto isPremium = session->premium(); - Ui::AddSubsectionTitle(colors, tr::lng_filters_tag_color_subtitle()); + const auto title = Ui::AddSubsectionTitle( + colors, + tr::lng_filters_tag_color_subtitle()); + const auto preview = Ui::CreateChild(colors); + title->geometryValue( + ) | rpl::start_with_next([=](const QRect &r) { + const auto h = st::normalFont->height; + preview->setGeometry( + colors->x(), + r.y() + (r.height() - h) / 2 + st::lineWidth, + colors->width(), + h); + }, preview->lifetime()); + const auto previewColor = preview->lifetime().make_state(); + const auto previewAlpha = preview->lifetime().make_state(1); + preview->paintRequest() | rpl::start_with_next([=] { + auto p = QPainter(preview); + p.fillRect(preview->rect(), Qt::transparent); + const auto &font = st::dialogRowFilterTagFont; + const auto text = name->getLastText().toUpper(); + p.setFont(font); + p.setOpacity(*previewAlpha); + const auto roundedWidth = font->width(text) + font->spacew * 3; + const auto rect = QRect( + preview->width() - roundedWidth - st::boxRowPadding.right(), + (st::normalFont->height - font->height) / 2, + roundedWidth, + font->height); + const auto pen = QPen(*previewColor); + p.setPen(Qt::NoPen); + p.setBrush(anim::with_alpha(pen.color(), .15)); + { + auto hq = PainterHighQualityEnabler(p); + const auto radius = font->height / 3.; + p.drawRoundedRect(rect, radius, radius); + } + p.setPen(pen); + p.drawText(rect, text, style::al_center); + if (p.opacity() < 1) { + p.setOpacity(1. - p.opacity()); + p.setFont(st::normalFont); + p.setPen(st::windowSubTextFg); + p.drawText( + preview->rect() - st::boxRowPadding, + tr::lng_filters_tag_color_no(tr::now), + style::al_right); + } + }, preview->lifetime()); + + name->changes() | rpl::start_with_next([=] { + preview->update(); + }, preview->lifetime()); + const auto side = st::userpicBuilderEmojiAccentColorSize; const auto line = colors->add( Ui::CreateSkipWidget(colors, side), @@ -536,15 +591,25 @@ void EditFilterBox( auto buttons = std::vector>(); const auto animation = line->lifetime().make_state(); + const auto palette = [](int i) { + return Ui::EmptyUserpic::UserpicColor(i).color2; + }; for (auto i = 0; i < kColorsCount; ++i) { const auto button = Ui::CreateChild( line); button->resize(side, side); - button->setIndex(i); - button->setSelectedProgress(isPremium + const auto progress = isPremium ? (state->colorIndex.current() == i) - : (i == (kColorsCount - 1))); - button->setBrush(Ui::EmptyUserpic::UserpicColor(i).color2); + : (i == kNoTag); + button->setSelectedProgress(progress); + const auto color = palette(i); + button->setBrush(color); + if (progress == 1) { + *previewColor = color->c; + if (i == kNoTag) { + *previewAlpha = 0.; + } + } buttons.push_back(button); } for (auto i = 0; i < kColorsCount; ++i) { @@ -553,12 +618,19 @@ void EditFilterBox( const auto was = state->colorIndex.current(); const auto now = i; if (was != now) { + const auto c1 = palette(was); + const auto c2 = palette(now); + const auto a1 = (was == kNoTag) ? 0. : 1.; + const auto a2 = (now == kNoTag) ? 0. : 1.; animation->stop(); animation->start([=](float64 progress) { if (was >= 0) { buttons[was]->setSelectedProgress(1. - progress); } buttons[now]->setSelectedProgress(progress); + *previewColor = anim::color(c1, c2, progress); + *previewAlpha = anim::interpolateF(a1, a2, progress); + preview->update(); }, 0., 1., st::universalDuration); } state->colorIndex = now; @@ -619,7 +691,7 @@ void EditFilterBox( return {}; } const auto rawColorIndex = state->colorIndex.current(); - const auto colorIndex = (rawColorIndex >= (kColorsCount - 1) + const auto colorIndex = (rawColorIndex >= kNoTag ? std::nullopt : std::make_optional(rawColorIndex)); return rules.withTitle(title).withColorIndex(colorIndex); From 1f162aa2a0b4c1c50448d77b02bc66a650f49e5d Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 20 Nov 2024 17:40:22 +0300 Subject: [PATCH 015/294] Fixed tags display when color of chats filter tag is toggled. --- .../SourceFiles/data/data_chat_filters.cpp | 9 +++++-- Telegram/SourceFiles/data/data_chat_filters.h | 9 +++++-- .../SourceFiles/dialogs/dialogs_entry.cpp | 27 ++++++++++++------- Telegram/SourceFiles/dialogs/dialogs_entry.h | 1 + .../dialogs/dialogs_inner_widget.cpp | 20 +++++++++++++- 5 files changed, 52 insertions(+), 14 deletions(-) diff --git a/Telegram/SourceFiles/data/data_chat_filters.cpp b/Telegram/SourceFiles/data/data_chat_filters.cpp index 224ee2797..acc36d10e 100644 --- a/Telegram/SourceFiles/data/data_chat_filters.cpp +++ b/Telegram/SourceFiles/data/data_chat_filters.cpp @@ -652,6 +652,8 @@ bool ChatFilters::applyChange(ChatFilter &filter, ChatFilter &&updated) { || (filter.title() != updated.title()) || (filter.iconEmoji() != updated.iconEmoji()); const auto colorChanged = filter.colorIndex() != updated.colorIndex(); + const auto colorExistenceChanged = (!filter.colorIndex()) + != (!updated.colorIndex()); if (!listUpdated && !chatlistChanged && !colorChanged) { return false; } @@ -707,7 +709,10 @@ bool ChatFilters::applyChange(ChatFilter &filter, ChatFilter &&updated) { _isChatlistChanged.fire_copy(id); } if (colorChanged) { - _tagColorChanged.fire_copy(id); + _tagColorChanged.fire_copy(TagColorChanged{ + .filterId = id, + .colorExistenceChanged = colorExistenceChanged, + }); } if (entryToRefreshHeight) { // Trigger a full refresh of height for the main list. @@ -855,7 +860,7 @@ rpl::producer ChatFilters::isChatlistChanged() const { return _isChatlistChanged.events(); } -rpl::producer ChatFilters::tagColorChanged() const { +rpl::producer ChatFilters::tagColorChanged() const { return _tagColorChanged.events(); } diff --git a/Telegram/SourceFiles/data/data_chat_filters.h b/Telegram/SourceFiles/data/data_chat_filters.h index 82f050af0..b18cda973 100644 --- a/Telegram/SourceFiles/data/data_chat_filters.h +++ b/Telegram/SourceFiles/data/data_chat_filters.h @@ -124,6 +124,11 @@ struct SuggestedFilter { QString description; }; +struct TagColorChanged final { + FilterId filterId = 0; + bool colorExistenceChanged = false; +}; + class ChatFilters final { public: explicit ChatFilters(not_null owner); @@ -140,7 +145,7 @@ public: [[nodiscard]] const std::vector &list() const; [[nodiscard]] rpl::producer<> changed() const; [[nodiscard]] rpl::producer isChatlistChanged() const; - [[nodiscard]] rpl::producer tagColorChanged() const; + [[nodiscard]] rpl::producer tagColorChanged() const; [[nodiscard]] bool loaded() const; [[nodiscard]] bool has() const; @@ -215,7 +220,7 @@ private: base::flat_map> _chatsLists; rpl::event_stream<> _listChanged; rpl::event_stream _isChatlistChanged; - rpl::event_stream _tagColorChanged; + rpl::event_stream _tagColorChanged; mtpRequestId _loadRequestId = 0; mtpRequestId _saveOrderRequestId = 0; mtpRequestId _saveOrderAfterId = 0; diff --git a/Telegram/SourceFiles/dialogs/dialogs_entry.cpp b/Telegram/SourceFiles/dialogs/dialogs_entry.cpp index 76d5ebe84..81b42c14d 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_entry.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_entry.cpp @@ -332,23 +332,32 @@ int Entry::posInChatList(FilterId filterId) const { return mainChatListLink(filterId)->index(); } +void Entry::setColorIndexForFilterId( + FilterId filterId, + std::optional colorIndex) { + if (!filterId) { + return; + } + if (colorIndex) { + _tagColors[filterId] = *colorIndex; + } else { + _tagColors.remove(filterId); + } +} + not_null Entry::addToChatList( FilterId filterId, not_null list) { - if (const auto main = maybeMainChatListLink(filterId)) { - return main; - } if (filterId) { const auto &list = owner().chatsFilters().list(); const auto it = ranges::find(list, filterId, &Data::ChatFilter::id); - if (it != end(list) && it->colorIndex()) { - _tagColors[filterId] = *(it->colorIndex()); - } else { - if (it != end(list)) { - } - _tagColors.remove(filterId); + if (it != end(list)) { + setColorIndexForFilterId(filterId, it->colorIndex()); } } + if (const auto main = maybeMainChatListLink(filterId)) { + return main; + } return _chatListLinks.emplace( filterId, list->addEntry(this) diff --git a/Telegram/SourceFiles/dialogs/dialogs_entry.h b/Telegram/SourceFiles/dialogs/dialogs_entry.h index cb6ac728f..e1909f7a6 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_entry.h +++ b/Telegram/SourceFiles/dialogs/dialogs_entry.h @@ -189,6 +189,7 @@ public: not_null addToChatList( FilterId filterId, not_null list); + void setColorIndexForFilterId(FilterId, std::optional); void removeFromChatList( FilterId filterId, not_null list); diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index 44f672bec..955f48a1c 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -329,10 +329,28 @@ InnerWidget::InnerWidget( }, _handleChatListEntryTagRefreshesLifetime); session().data().chatsFilters().tagColorChanged( - ) | rpl::start_with_next([=](FilterId filterId) { + ) | rpl::start_with_next([=](Data::TagColorChanged data) { + const auto filterId = data.filterId; const auto it = _chatsFilterTags.find(filterId); if (it != _chatsFilterTags.end()) { _chatsFilterTags.erase(it); + } + if (data.colorExistenceChanged) { + for (const auto &f : session().data().chatsFilters().list()) { + if (f.id() != filterId) { + continue; + } + const auto color = f.colorIndex(); + const auto list = session().data().chatsFilters().chatsList( + filterId); + for (const auto &row : list->indexed()->all()) { + row->entry()->setColorIndexForFilterId(filterId, color); + } + } + if (_shownList->updateHeights(_narrowRatio)) { + refresh(); + } + } else { update(); } }, _handleChatListEntryTagRefreshesLifetime); From 5362d54ab6d398d3a402f98caaac6475ace90a04 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 20 Nov 2024 18:36:38 +0300 Subject: [PATCH 016/294] Fixed display of chats filter tag for active dialog rows. --- .../dialogs/dialogs_inner_widget.cpp | 63 +++++++++++++------ .../dialogs/dialogs_inner_widget.h | 6 +- 2 files changed, 48 insertions(+), 21 deletions(-) diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index 955f48a1c..b9735045a 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -87,6 +87,15 @@ constexpr auto kStartReorderThreshold = 30; constexpr auto kQueryPreviewLimit = 32; constexpr auto kPreviewPostsLimit = 3; +[[nodiscard]] InnerWidget::ChatsFilterTagsKey SerializeFilterTagsKey( + FilterId filterId, + uint8 more, + bool active) { + return (filterId & 0xFFFFFFFF) + | (static_cast(more) << 32) + | (static_cast(active) << 40); +} + [[nodiscard]] int FixedOnTopDialogsCount(not_null list) { auto result = 0; for (const auto &row : *list) { @@ -221,6 +230,7 @@ InnerWidget::InnerWidget( style::PaletteChanged( ) | rpl::start_with_next([=] { _topicJumpCache = nullptr; + _chatsFilterTags.clear(); }, lifetime()); session().downloaderTaskFinished( @@ -331,20 +341,27 @@ InnerWidget::InnerWidget( session().data().chatsFilters().tagColorChanged( ) | rpl::start_with_next([=](Data::TagColorChanged data) { const auto filterId = data.filterId; - const auto it = _chatsFilterTags.find(filterId); - if (it != _chatsFilterTags.end()) { - _chatsFilterTags.erase(it); + const auto key = SerializeFilterTagsKey(filterId, 0, false); + const auto activeKey = SerializeFilterTagsKey(filterId, 0, true); + { + auto &tags = _chatsFilterTags; + if (const auto it = tags.find(key); it != tags.end()) { + tags.erase(it); + } + if (const auto it = tags.find(activeKey); it != tags.end()) { + tags.erase(it); + } } if (data.colorExistenceChanged) { - for (const auto &f : session().data().chatsFilters().list()) { - if (f.id() != filterId) { + auto &filters = session().data().chatsFilters(); + for (const auto &filter : filters.list()) { + if (filter.id() != filterId) { continue; } - const auto color = f.colorIndex(); - const auto list = session().data().chatsFilters().chatsList( - filterId); + const auto c = filter.colorIndex(); + const auto list = filters.chatsList(filterId); for (const auto &row : list->indexed()->all()) { - row->entry()->setColorIndexForFilterId(filterId, color); + row->entry()->setColorIndexForFilterId(filterId, c); } } if (_shownList->updateHeights(_narrowRatio)) { @@ -771,6 +788,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) { if (context.narrow) { context.chatsFilterTags = nullptr; } else if (row->entry()->hasChatsFilterTags(context.filter)) { + const auto a = active; context.st = forum ? &st::taggedForumDialogRow : &st::taggedDialogRow; @@ -778,14 +796,14 @@ void InnerWidget::paintEvent(QPaintEvent *e) { - context.st->padding.right() - st::dialogsUnreadPadding - context.st->nameLeft; - auto more = ushort(0); + auto more = uint8(0); const auto &list = session().data().chatsFilters().list(); for (const auto &filter : list) { if (!row->entry()->inChatList(filter.id()) || (filter.id() == context.filter)) { continue; } - if (const auto tag = cacheChatsFilterTag(filter.id(), 0)) { + if (const auto tag = cacheChatsFilterTag(filter.id(), 0, a)) { if (more) { more++; continue; @@ -802,13 +820,14 @@ void InnerWidget::paintEvent(QPaintEvent *e) { } } if (more) { - if (const auto tag = cacheChatsFilterTag(0, more)) { + if (const auto tag = cacheChatsFilterTag(0, more, a)) { const auto tagWidth = tag->width() / style::DevicePixelRatio(); if (availableWidth < tagWidth) { more++; - if (const auto tag = cacheChatsFilterTag(0, more)) { - if (!chatsFilterTags.empty()) { + if (!chatsFilterTags.empty()) { + const auto tag = cacheChatsFilterTag(0, more, a); + if (tag) { chatsFilterTags.back() = tag; } } @@ -4063,11 +4082,14 @@ void InnerWidget::restoreChatsFilterScrollState(FilterId filterId) { } } -QImage *InnerWidget::cacheChatsFilterTag(FilterId filterId, ushort more) { +QImage *InnerWidget::cacheChatsFilterTag( + FilterId filterId, + uint8 more, + bool active) { if (!filterId && !more) { return nullptr; } - const auto key = filterId ? filterId : -more; + const auto key = SerializeFilterTagsKey(filterId, more, active); { const auto it = _chatsFilterTags.find(key); if (it != end(_chatsFilterTags)) { @@ -4103,10 +4125,13 @@ QImage *InnerWidget::cacheChatsFilterTag(FilterId filterId, ushort more) { cache.fill(Qt::transparent); { auto p = QPainter(&cache); - const auto pen = QPen( - Ui::EmptyUserpic::UserpicColor(colorIndex).color2); + const auto pen = QPen(active + ? st::dialogsBgActive + : Ui::EmptyUserpic::UserpicColor(colorIndex).color2); p.setPen(Qt::NoPen); - p.setBrush(anim::with_alpha(pen.color(), .15)); + p.setBrush(active + ? st::dialogsTextFgActive->c + : anim::with_alpha(pen.color(), .15)); { auto hq = PainterHighQualityEnabler(p); const auto radius = roundedFont->height / 3.; diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h index 4819d0646..9249e5c56 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h @@ -99,6 +99,8 @@ enum class WidgetState { class InnerWidget final : public Ui::RpWidget { public: + using ChatsFilterTagsKey = int64; + struct ChildListShown { PeerId peerId = 0; float64 shown = 0.; @@ -448,7 +450,7 @@ private: void saveChatsFilterScrollState(FilterId filterId); void restoreChatsFilterScrollState(FilterId filterId); - [[nodiscard]] QImage *cacheChatsFilterTag(FilterId filterId, ushort more); + [[nodiscard]] QImage *cacheChatsFilterTag(FilterId, uint8, bool); const not_null _controller; @@ -556,7 +558,7 @@ private: base::flat_map _chatsFilterScrollStates; - std::unordered_map _chatsFilterTags; + std::unordered_map _chatsFilterTags; bool _waitingAllChatListEntryRefreshesForTags = false; rpl::lifetime _handleChatListEntryTagRefreshesLifetime; From d5dbbd566f342e27d42fecef892364fc35a814d3 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Thu, 21 Nov 2024 04:46:13 +0300 Subject: [PATCH 017/294] Fixed display tags with NoRead flag while history has fake unread state. --- .../SourceFiles/data/data_chat_filters.cpp | 6 +++-- Telegram/SourceFiles/data/data_chat_filters.h | 4 +++- .../SourceFiles/dialogs/dialogs_entry.cpp | 24 +++++++++++++++++++ .../dialogs/dialogs_inner_widget.cpp | 6 +++++ 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/Telegram/SourceFiles/data/data_chat_filters.cpp b/Telegram/SourceFiles/data/data_chat_filters.cpp index acc36d10e..e8c5db062 100644 --- a/Telegram/SourceFiles/data/data_chat_filters.cpp +++ b/Telegram/SourceFiles/data/data_chat_filters.cpp @@ -283,7 +283,9 @@ const base::flat_set> &ChatFilter::never() const { return _never; } -bool ChatFilter::contains(not_null history) const { +bool ChatFilter::contains( + not_null history, + bool ignoreFakeUnread) const { const auto flag = [&] { const auto peer = history->peer; if (const auto user = peer->asUser()) { @@ -320,7 +322,7 @@ bool ChatFilter::contains(not_null history) const { && (!(_flags & Flag::NoRead) || state.unread || state.mention - || history->fakeUnreadWhileOpened()) + || (!ignoreFakeUnread && history->fakeUnreadWhileOpened())) && (!(_flags & Flag::NoArchived) || (history->folderKnown() && !history->folder()))) || _always.contains(history); diff --git a/Telegram/SourceFiles/data/data_chat_filters.h b/Telegram/SourceFiles/data/data_chat_filters.h index b18cda973..5f876de24 100644 --- a/Telegram/SourceFiles/data/data_chat_filters.h +++ b/Telegram/SourceFiles/data/data_chat_filters.h @@ -81,7 +81,9 @@ public: [[nodiscard]] const std::vector> &pinned() const; [[nodiscard]] const base::flat_set> &never() const; - [[nodiscard]] bool contains(not_null history) const; + [[nodiscard]] bool contains( + not_null history, + bool ignoreFakeUnread = false) const; private: FilterId _id = 0; diff --git a/Telegram/SourceFiles/dialogs/dialogs_entry.cpp b/Telegram/SourceFiles/dialogs/dialogs_entry.cpp index 81b42c14d..501883a41 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_entry.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_entry.cpp @@ -254,7 +254,31 @@ void Entry::notifyUnreadStateChange(const UnreadState &wasState) { return state.messages || state.marks || state.mentions; }; if (isForFilters(wasState) != isForFilters(nowState)) { + const auto wasTags = _tagColors.size(); owner().chatsFilters().refreshHistory(history); + + // Hack for History::fakeUnreadWhileOpened(). + if (!isForFilters(nowState) + && (wasTags > 0) + && (wasTags == _tagColors.size())) { + auto updateRequested = false; + for (const auto &filter : filters.list()) { + if (!(filter.flags() & Data::ChatFilter::Flag::NoRead) + || !_chatListLinks.contains(filter.id()) + || filter.contains(history, true)) { + continue; + } + const auto wasTagsCount = _tagColors.size(); + setColorIndexForFilterId(filter.id(), std::nullopt); + updateRequested |= (wasTagsCount != _tagColors.size()); + } + if (updateRequested) { + updateChatListEntryHeight(); + session().changes().peerUpdated( + history->peer, + Data::PeerUpdate::Flag::Name); + } + } } } updateChatListEntryPostponed(); diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index b9735045a..f3490d7f9 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -803,6 +803,12 @@ void InnerWidget::paintEvent(QPaintEvent *e) { || (filter.id() == context.filter)) { continue; } + if (active + && (filter.flags() & Data::ChatFilter::Flag::NoRead) + && !filter.contains(key.history(), true)) { + // Hack for History::fakeUnreadWhileOpened(). + continue; + } if (const auto tag = cacheChatsFilterTag(filter.id(), 0, a)) { if (more) { more++; From 9d5ca1252a1d001a3a10e22dc8eadfb8d08719a2 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Thu, 21 Nov 2024 09:14:08 +0300 Subject: [PATCH 018/294] Added ability to pass preloaded chats filter tags toggle on logging in. --- Telegram/SourceFiles/data/data_chat_filters.cpp | 5 ++++- Telegram/SourceFiles/data/data_chat_filters.h | 4 +++- Telegram/SourceFiles/intro/intro_step.cpp | 10 ++++++---- Telegram/SourceFiles/intro/intro_step.h | 3 ++- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/Telegram/SourceFiles/data/data_chat_filters.cpp b/Telegram/SourceFiles/data/data_chat_filters.cpp index e8c5db062..dab96d40d 100644 --- a/Telegram/SourceFiles/data/data_chat_filters.cpp +++ b/Telegram/SourceFiles/data/data_chat_filters.cpp @@ -358,8 +358,11 @@ void ChatFilters::clear() { _list.clear(); } -void ChatFilters::setPreloaded(const QVector &result) { +void ChatFilters::setPreloaded( + const QVector &result, + bool tagsEnabled) { _loadRequestId = -1; + _tagsEnabled = tagsEnabled; received(result); crl::on_main(&_owner->session(), [=] { if (_loadRequestId == -1) { diff --git a/Telegram/SourceFiles/data/data_chat_filters.h b/Telegram/SourceFiles/data/data_chat_filters.h index 5f876de24..c33862aec 100644 --- a/Telegram/SourceFiles/data/data_chat_filters.h +++ b/Telegram/SourceFiles/data/data_chat_filters.h @@ -136,7 +136,9 @@ public: explicit ChatFilters(not_null owner); ~ChatFilters(); - void setPreloaded(const QVector &result); + void setPreloaded( + const QVector &result, + bool tagsEnabled); void load(); void reload(); diff --git a/Telegram/SourceFiles/intro/intro_step.cpp b/Telegram/SourceFiles/intro/intro_step.cpp index 9e9a266f6..e019da124 100644 --- a/Telegram/SourceFiles/intro/intro_step.cpp +++ b/Telegram/SourceFiles/intro/intro_step.cpp @@ -194,16 +194,18 @@ void Step::finish(const MTPUser &user, QImage &&photo) { api().request(MTPmessages_GetDialogFilters( )).done([=](const MTPmessages_DialogFilters &result) { - createSession(user, photo, result.data().vfilters().v); + const auto &d = result.data(); + createSession(user, photo, d.vfilters().v, d.is_tags_enabled()); }).fail([=] { - createSession(user, photo, QVector()); + createSession(user, photo, QVector(), false); }).send(); } void Step::createSession( const MTPUser &user, QImage photo, - const QVector &filters) { + const QVector &filters, + bool tagsEnabled) { // Save the default language if we've suggested some other and user ignored it. const auto currentId = Lang::Id(); const auto defaultId = Lang::DefaultLanguageId(); @@ -227,7 +229,7 @@ void Step::createSession( account->local().enforceModernStorageIdBots(); account->local().writeMtpData(); auto &session = account->session(); - session.data().chatsFilters().setPreloaded(filters); + session.data().chatsFilters().setPreloaded(filters, tagsEnabled); if (hasFilters) { session.saveSettingsDelayed(); } diff --git a/Telegram/SourceFiles/intro/intro_step.h b/Telegram/SourceFiles/intro/intro_step.h index 660e2c367..f265a4a98 100644 --- a/Telegram/SourceFiles/intro/intro_step.h +++ b/Telegram/SourceFiles/intro/intro_step.h @@ -116,7 +116,8 @@ protected: void createSession( const MTPUser &user, QImage photo, - const QVector &filters); + const QVector &filters, + bool tagsEnabled); void goBack(); From b3359816219322e6af63815e515a50a42e3be31b Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Thu, 21 Nov 2024 13:56:13 +0300 Subject: [PATCH 019/294] Removed duplicated search of correspond chat filter for tags in dialogs. --- .../dialogs/dialogs_inner_widget.cpp | 24 ++++++++----------- .../dialogs/dialogs_inner_widget.h | 6 ++++- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index f3490d7f9..9bcbb39d8 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -809,7 +809,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) { // Hack for History::fakeUnreadWhileOpened(). continue; } - if (const auto tag = cacheChatsFilterTag(filter.id(), 0, a)) { + if (const auto tag = cacheChatsFilterTag(filter, 0, a)) { if (more) { more++; continue; @@ -826,13 +826,13 @@ void InnerWidget::paintEvent(QPaintEvent *e) { } } if (more) { - if (const auto tag = cacheChatsFilterTag(0, more, a)) { + if (const auto tag = cacheChatsFilterTag({}, more, a)) { const auto tagWidth = tag->width() / style::DevicePixelRatio(); if (availableWidth < tagWidth) { more++; if (!chatsFilterTags.empty()) { - const auto tag = cacheChatsFilterTag(0, more, a); + const auto tag = cacheChatsFilterTag({}, more, a); if (tag) { chatsFilterTags.back() = tag; } @@ -4089,13 +4089,13 @@ void InnerWidget::restoreChatsFilterScrollState(FilterId filterId) { } QImage *InnerWidget::cacheChatsFilterTag( - FilterId filterId, + const Data::ChatFilter &filter, uint8 more, bool active) { - if (!filterId && !more) { + if (!filter.id() && !more) { return nullptr; } - const auto key = SerializeFilterTagsKey(filterId, more, active); + const auto key = SerializeFilterTagsKey(filter.id(), more, active); { const auto it = _chatsFilterTags.find(key); if (it != end(_chatsFilterTags)) { @@ -4104,14 +4104,10 @@ QImage *InnerWidget::cacheChatsFilterTag( } auto roundedText = QString(); auto colorIndex = -1; - if (filterId) { - const auto &list = session().data().chatsFilters().list(); - const auto it = ranges::find(list, filterId, &Data::ChatFilter::id); - if (it != end(list)) { - roundedText = it->title().toUpper(); - if (it->colorIndex()) { - colorIndex = *it->colorIndex(); - } + if (filter.id()) { + roundedText = filter.title().toUpper(); + if (filter.colorIndex()) { + colorIndex = *(filter.colorIndex()); } } else if (more > 0) { roundedText = QChar('+') + QString::number(more); diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h index 9249e5c56..43fb5bc92 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h @@ -41,6 +41,7 @@ class SessionController; } // namespace Window namespace Data { +class ChatFilter; class Thread; class Folder; class Forum; @@ -450,7 +451,10 @@ private: void saveChatsFilterScrollState(FilterId filterId); void restoreChatsFilterScrollState(FilterId filterId); - [[nodiscard]] QImage *cacheChatsFilterTag(FilterId, uint8, bool); + [[nodiscard]] QImage *cacheChatsFilterTag( + const Data::ChatFilter &filter, + uint8 more, + bool active); const not_null _controller; From aa8d543ed87650fbf661913f7cf99adefbcac941 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Sun, 24 Nov 2024 10:13:47 +0300 Subject: [PATCH 020/294] Fixed ability to remove peer from chats filter to make it empty. --- Telegram/SourceFiles/boxes/choose_filter_box.cpp | 4 +--- Telegram/SourceFiles/data/data_chat_filters.cpp | 10 ++++++++++ Telegram/SourceFiles/data/data_chat_filters.h | 4 ++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Telegram/SourceFiles/boxes/choose_filter_box.cpp b/Telegram/SourceFiles/boxes/choose_filter_box.cpp index 252403af8..80ff008bc 100644 --- a/Telegram/SourceFiles/boxes/choose_filter_box.cpp +++ b/Telegram/SourceFiles/boxes/choose_filter_box.cpp @@ -126,9 +126,7 @@ bool ChooseFilterValidator::canRemove(FilterId filterId) const { const auto list = _history->owner().chatsFilters().list(); const auto i = ranges::find(list, filterId, &Data::ChatFilter::id); if (i != end(list)) { - const auto &filter = *i; - return filter.contains(_history) - && ((filter.always().size() > 1) || filter.flags()); + return Data::CanRemoveFromChatFilter(*i, _history); } return false; } diff --git a/Telegram/SourceFiles/data/data_chat_filters.cpp b/Telegram/SourceFiles/data/data_chat_filters.cpp index dab96d40d..3dd176d94 100644 --- a/Telegram/SourceFiles/data/data_chat_filters.cpp +++ b/Telegram/SourceFiles/data/data_chat_filters.cpp @@ -1086,4 +1086,14 @@ void ChatFilters::checkLoadMoreChatsLists() { } } +bool CanRemoveFromChatFilter( + const ChatFilter &filter, + not_null history) { + using Flag = ChatFilter::Flag; + const auto flagsWithoutNoReadNoArchivedNoMuted = filter.flags() + & ~(Flag::NoRead | Flag::NoArchived | Flag::NoMuted); + return (filter.always().size() > 1 || flagsWithoutNoReadNoArchivedNoMuted) + && filter.contains(history); +} + } // namespace Data diff --git a/Telegram/SourceFiles/data/data_chat_filters.h b/Telegram/SourceFiles/data/data_chat_filters.h index c33862aec..2e34cc713 100644 --- a/Telegram/SourceFiles/data/data_chat_filters.h +++ b/Telegram/SourceFiles/data/data_chat_filters.h @@ -252,4 +252,8 @@ private: }; +[[nodiscard]] bool CanRemoveFromChatFilter( + const ChatFilter &filter, + not_null history); + } // namespace Data From 728d9a0993e7c5c4e72ad1b1a548c3b75e305de4 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Sun, 24 Nov 2024 10:27:54 +0300 Subject: [PATCH 021/294] Added ability to remove peer from chats filters when leave it. --- Telegram/Resources/langs/lang.strings | 4 ++ .../boxes/moderate_messages_box.cpp | 63 ++++++++++++++++++- .../SourceFiles/data/data_chat_filters.cpp | 8 +++ Telegram/SourceFiles/data/data_chat_filters.h | 1 + 4 files changed, 75 insertions(+), 1 deletion(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 5919b2593..2288910cb 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -5168,6 +5168,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_filters_link" = "Share Folder"; "lng_filters_link_has" = "Invite links"; +"lng_filters_checkbox_remove_bot" = "Remove bot from all folders"; +"lng_filters_checkbox_remove_group" = "Remove group from all folders"; +"lng_filters_checkbox_remove_channel" = "Remove channel from all folders"; + "lng_filters_link_create" = "Create an Invite Link"; "lng_filters_link_cant" = "You can’t share folders which include or exclude specific chat types like 'Groups', 'Contacts', etc."; "lng_filters_link_about" = "Share access to some of this folder's groups and channels with others."; diff --git a/Telegram/SourceFiles/boxes/moderate_messages_box.cpp b/Telegram/SourceFiles/boxes/moderate_messages_box.cpp index 9c68881a1..c7e696e9e 100644 --- a/Telegram/SourceFiles/boxes/moderate_messages_box.cpp +++ b/Telegram/SourceFiles/boxes/moderate_messages_box.cpp @@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/ui_integration.h" #include "data/data_channel.h" #include "data/data_chat.h" +#include "data/data_chat_filters.h" #include "data/data_chat_participant_status.h" #include "data/data_histories.h" #include "data/data_peer.h" @@ -512,6 +513,7 @@ void DeleteChatBox(not_null box, not_null peer) { const auto container = box->verticalLayout(); const auto maybeUser = peer->asUser(); + const auto isBot = maybeUser && maybeUser->isBot(); Ui::AddSkip(container); Ui::AddSkip(container); @@ -595,7 +597,7 @@ void DeleteChatBox(not_null box, not_null peer) { }(); const auto maybeBotCheckbox = [&]() -> Ui::Checkbox* { - if (!maybeUser || !maybeUser->isBot()) { + if (!isBot) { return nullptr; } Ui::AddSkip(container); @@ -608,6 +610,40 @@ void DeleteChatBox(not_null box, not_null peer) { st::defaultBoxCheckbox)); }(); + const auto removeFromChatsFilters = [=]( + not_null history) -> std::vector { + auto result = std::vector(); + for (const auto &filter : peer->owner().chatsFilters().list()) { + if (filter.withoutAlways(history) != filter) { + result.push_back(filter.id()); + } + } + return result; + }; + + const auto maybeChatsFiltersCheckbox = [&]() -> Ui::Checkbox* { + const auto history = (isBot || !maybeUser) + ? peer->owner().history(peer).get() + : nullptr; + if (!history || removeFromChatsFilters(history).empty()) { + return nullptr; + } + Ui::AddSkip(container); + Ui::AddSkip(container); + return box->addRow( + object_ptr( + container, + (maybeBotCheckbox + ? tr::lng_filters_checkbox_remove_bot + : (peer->isChannel() && !peer->isMegagroup()) + ? tr::lng_filters_checkbox_remove_channel + : tr::lng_filters_checkbox_remove_group)( + tr::now, + Ui::Text::WithEntities), + false, + st::defaultBoxCheckbox)); + }(); + Ui::AddSkip(container); auto buttonText = maybeUser @@ -622,10 +658,35 @@ void DeleteChatBox(not_null box, not_null peer) { box->addButton(std::move(buttonText), [=] { const auto revoke = maybeCheckbox && maybeCheckbox->checked(); const auto stopBot = maybeBotCheckbox && maybeBotCheckbox->checked(); + const auto removeFromChats = maybeChatsFiltersCheckbox + && maybeChatsFiltersCheckbox->checked(); Core::App().closeChatFromWindows(peer); if (stopBot) { peer->session().api().blockedPeers().block(peer); } + if (removeFromChats) { + const auto history = peer->owner().history(peer).get(); + const auto removeFrom = removeFromChatsFilters(history); + for (const auto &filter : peer->owner().chatsFilters().list()) { + if (!ranges::contains(removeFrom, filter.id())) { + continue; + } + const auto result = filter.withoutAlways(history); + if (result == filter) { + continue; + } + const auto tl = result.tl(); + peer->owner().chatsFilters().apply(MTP_updateDialogFilter( + MTP_flags(MTPDupdateDialogFilter::Flag::f_filter), + MTP_int(filter.id()), + tl)); + peer->session().api().request(MTPmessages_UpdateDialogFilter( + MTP_flags(MTPmessages_UpdateDialogFilter::Flag::f_filter), + MTP_int(filter.id()), + tl + )).send(); + } + } // Don't delete old history by default, // because Android app doesn't. // diff --git a/Telegram/SourceFiles/data/data_chat_filters.cpp b/Telegram/SourceFiles/data/data_chat_filters.cpp index 3dd176d94..354d95bf3 100644 --- a/Telegram/SourceFiles/data/data_chat_filters.cpp +++ b/Telegram/SourceFiles/data/data_chat_filters.cpp @@ -188,6 +188,14 @@ ChatFilter ChatFilter::withChatlist(bool chatlist, bool hasMyLinks) const { return result; } +ChatFilter ChatFilter::withoutAlways(not_null history) const { + auto result = *this; + if (CanRemoveFromChatFilter(result, history)) { + result._always.remove(history); + } + return result; +} + MTPDialogFilter ChatFilter::tl(FilterId replaceId) const { auto always = _always; auto pinned = QVector(); diff --git a/Telegram/SourceFiles/data/data_chat_filters.h b/Telegram/SourceFiles/data/data_chat_filters.h index 2e34cc713..0136919f5 100644 --- a/Telegram/SourceFiles/data/data_chat_filters.h +++ b/Telegram/SourceFiles/data/data_chat_filters.h @@ -64,6 +64,7 @@ public: [[nodiscard]] ChatFilter withChatlist( bool chatlist, bool hasMyLinks) const; + [[nodiscard]] ChatFilter withoutAlways(not_null) const; [[nodiscard]] static ChatFilter FromTL( const MTPDialogFilter &data, From 14cc7789d9999a00898e57fa0838354cf2e523c3 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Sun, 24 Nov 2024 10:49:24 +0300 Subject: [PATCH 022/294] Allowed to choose filters from any profile of peers in chats list. --- .../SourceFiles/window/window_peer_menu.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index 25e2ebbc0..cbe0dd813 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -276,7 +276,7 @@ private: void addInfo(); void addStoryArchive(); void addNewWindow(); - void addToggleFolder(bool onlyForChannels); + void addToggleFolder(); void addToggleUnreadMark(); void addToggleArchive(); void addClearHistory(); @@ -615,14 +615,13 @@ void Filler::addStoryArchive() { }, &st::menuIconStoriesArchiveSection); } -void Filler::addToggleFolder(bool onlyForChannels) { +void Filler::addToggleFolder() { const auto controller = _controller; const auto history = _request.key.history(); - if (_topic || !history || !history->owner().chatsFilters().has()) { - return; - } - if (onlyForChannels - && (!history->peer->isChannel() || !history->inChatList())) { + if (_topic + || !history + || !history->owner().chatsFilters().has() + || !history->inChatList()) { return; } _addAction(PeerMenuCallback::Args{ @@ -1408,7 +1407,7 @@ void Filler::fillContextMenuActions() { addToggleMuteSubmenu(false); addToggleUnreadMark(); addToggleTopicClosed(); - addToggleFolder(false); + addToggleFolder(); if (const auto user = _peer->asUser()) { if (!user->isContact()) { addBlockUser(); @@ -1456,7 +1455,7 @@ void Filler::fillProfileActions() { addToggleTopicClosed(); addViewDiscussion(); addExportChat(); - addToggleFolder(true); + addToggleFolder(); addBlockUser(); addReport(); addLeaveChat(); From 8a3aa660cb517b35e762fbc782c71de8b8b57ee7 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Sun, 24 Nov 2024 16:53:28 +0300 Subject: [PATCH 023/294] Added initial implementation of right button for bots in dialogs list. --- Telegram/Resources/langs/lang.strings | 1 + Telegram/SourceFiles/boxes/stickers_box.cpp | 2 +- Telegram/SourceFiles/dialogs/dialogs.style | 4 + Telegram/SourceFiles/dialogs/dialogs_entry.h | 9 + .../dialogs/dialogs_inner_widget.cpp | 155 ++++++++++++++++-- .../dialogs/dialogs_inner_widget.h | 17 +- .../SourceFiles/dialogs/dialogs_widget.cpp | 6 + .../SourceFiles/dialogs/ui/dialogs_layout.cpp | 102 +++++++++--- .../SourceFiles/dialogs/ui/dialogs_layout.h | 2 + 9 files changed, 259 insertions(+), 39 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 2288910cb..54ecda43a 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1475,6 +1475,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_profile_enable_notifications" = "Notifications"; "lng_profile_send_message" = "Send Message"; "lng_profile_open_app" = "Open App"; +"lng_profile_open_app_short" = "Open"; "lng_profile_open_app_about" = "By launching this mini app, you agree to the {terms}."; "lng_profile_open_app_terms" = "Terms of Service for Mini Apps"; "lng_profile_bot_permissions_title" = "Allow access to"; diff --git a/Telegram/SourceFiles/boxes/stickers_box.cpp b/Telegram/SourceFiles/boxes/stickers_box.cpp index 7509b898c..778db60af 100644 --- a/Telegram/SourceFiles/boxes/stickers_box.cpp +++ b/Telegram/SourceFiles/boxes/stickers_box.cpp @@ -1826,8 +1826,8 @@ void StickersBox::Inner::setPressed(SelectedRow pressed) { if (_megagroupSet && pressedIndex >= 0 && pressedIndex < _rows.size()) { update(0, _itemsTop + pressedIndex * _rowHeight, width(), _rowHeight); auto &set = _rows[pressedIndex]; - auto rippleMask = Ui::RippleAnimation::RectMask(QSize(width(), _rowHeight)); if (!set->ripple) { + auto rippleMask = Ui::RippleAnimation::RectMask(QSize(width(), _rowHeight)); set->ripple = std::make_unique(st::defaultRippleAnimation, std::move(rippleMask), [this, pressedIndex] { update(0, _itemsTop + pressedIndex * _rowHeight, width(), _rowHeight); }); diff --git a/Telegram/SourceFiles/dialogs/dialogs.style b/Telegram/SourceFiles/dialogs/dialogs.style index a0b8c4c76..2cc193d59 100644 --- a/Telegram/SourceFiles/dialogs/dialogs.style +++ b/Telegram/SourceFiles/dialogs/dialogs.style @@ -108,6 +108,10 @@ taggedForumDialogRow: DialogRow(forumDialogRow) { } dialogRowFilterTagSkip : 4px; dialogRowFilterTagFont : font(10px); +dialogRowOpenBotTextStyle: semiboldTextStyle; +dialogRowOpenBotHeight: 20px; +dialogRowOpenBotRight: 10px; +dialogRowOpenBotTop: 32px; forumDialogJumpArrow: icon{{ "dialogs/dialogs_topic_arrow", dialogsTextFg }}; forumDialogJumpArrowOver: icon{{ "dialogs/dialogs_topic_arrow", dialogsTextFgOver }}; diff --git a/Telegram/SourceFiles/dialogs/dialogs_entry.h b/Telegram/SourceFiles/dialogs/dialogs_entry.h index e1909f7a6..b97044241 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_entry.h +++ b/Telegram/SourceFiles/dialogs/dialogs_entry.h @@ -29,6 +29,7 @@ class SavedSublist; } // namespace Data namespace Ui { +class RippleAnimation; struct PeerUserpicView; } // namespace Ui @@ -43,6 +44,14 @@ class Row; class IndexedList; class MainList; +struct RightButton final { + QImage bg; + QImage selectedBg; + QImage activeBg; + Ui::Text::String text; + std::unique_ptr ripple; +}; + struct RowsByLetter { not_null main; base::flat_map> letters; diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index 9bcbb39d8..363b0dfd6 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -29,6 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/text/text_options.h" #include "ui/dynamic_thumbnails.h" #include "ui/painter.h" +#include "ui/rect.h" #include "ui/ui_utility.h" #include "data/data_drafts.h" #include "data/data_folder.h" @@ -62,6 +63,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/window_controller.h" #include "window/window_session_controller.h" #include "window/window_peer_menu.h" +#include "ui/effects/ripple_animation.h" #include "ui/effects/loading_element.h" #include "ui/widgets/multi_select.h" #include "ui/widgets/menu/menu_add_action_callback_factory.h" @@ -122,6 +124,19 @@ constexpr auto kPreviewPostsLimit = 3; return result; } +[[nodiscard]] UserData *MaybeBotWithApp(Row *row) { + if (row) { + if (const auto history = row->key().history()) { + if (const auto user = history->peer->asUser()) { + if (user->botInfo && user->botInfo->hasMainApp) { + return user; + } + } + } + } + return nullptr; +} + [[nodiscard]] object_ptr MakeSearchEmpty( QWidget *parent, SearchState state) { @@ -773,7 +788,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) { not_null row, bool selected, bool mayBeActive) { - const auto key = row->key(); + const auto &key = row->key(); const auto active = mayBeActive && isRowActive(row, activeEntry); const auto forum = key.history() && key.history()->isForum(); if (forum && !_topicJumpCache) { @@ -781,6 +796,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) { } const auto expanding = forum && (key.history()->peer->id == childListShown.peerId); + context.rightButton = maybeCacheRightButton(row); context.st = (forum ? &st::forumDialogRow : _st.get()); @@ -1195,6 +1211,47 @@ void InnerWidget::paintEvent(QPaintEvent *e) { } } +[[nodiscard]] RightButton *InnerWidget::maybeCacheRightButton(Row *row) { + if (const auto user = MaybeBotWithApp(row)) { + const auto it = _rightButtons.find(user->id); + if (it == _rightButtons.end()) { + auto rightButton = RightButton(); + const auto text + = tr::lng_profile_open_app_short(tr::now).toUpper(); + rightButton.text.setText(st::dialogRowOpenBotTextStyle, text); + const auto size = QSize( + rightButton.text.maxWidth() + + rightButton.text.minHeight(), + st::dialogRowOpenBotHeight); + const auto generateBg = [&](const style::color &c) { + auto bg = QImage( + style::DevicePixelRatio() * size, + QImage::Format_ARGB32_Premultiplied); + bg.setDevicePixelRatio(style::DevicePixelRatio()); + bg.fill(Qt::transparent); + { + auto p = QPainter(&bg); + auto hq = PainterHighQualityEnabler(p); + p.setPen(Qt::NoPen); + p.setBrush(c); + const auto r = size.height() / 2; + p.drawRoundedRect(Rect(size), r, r); + } + return bg; + }; + rightButton.bg = generateBg(st::activeButtonBg); + rightButton.selectedBg = generateBg(st::activeButtonBgOver); + rightButton.activeBg = generateBg(st::activeButtonFg); + return &(_rightButtons.emplace( + user->id, + std::move(rightButton)).first->second); + } else { + return &(it->second); + } + } + return nullptr; +} + Ui::VideoUserpic *InnerWidget::validateVideoUserpic(not_null row) { const auto history = row->history(); return history ? validateVideoUserpic(history) : nullptr; @@ -1554,6 +1611,26 @@ void InnerWidget::clearIrrelevantState() { } } +bool InnerWidget::lookupIsInBotAppButton( + Row *row, + QPoint localPosition) { + if (const auto user = MaybeBotWithApp(row)) { + const auto it = _rightButtons.find(user->id); + if (it != _rightButtons.end()) { + const auto s = it->second.bg.size() / style::DevicePixelRatio(); + const auto r = QRect( + width() - s.width() - st::dialogRowOpenBotRight, + st::dialogRowOpenBotTop, + s.width(), + s.height()); + if (r.contains(localPosition)) { + return true; + } + } + } + return false; +} + void InnerWidget::selectByMouse(QPoint globalPosition) { const auto local = mapFromGlobal(globalPosition); if (updateReorderPinned(local)) { @@ -1594,16 +1671,19 @@ void InnerWidget::selectByMouse(QPoint globalPosition) { : (mouseY >= offset) ? _shownList->rowAtY(mouseY - offset) : nullptr; + const auto mappedY = selected ? mouseY - offset - selected->top() : 0; const auto selectedTopicJump = selected - && selected->lookupIsInTopicJump( - local.x(), - mouseY - offset - selected->top()); + && selected->lookupIsInTopicJump(local.x(), mappedY); + const auto selectedBotApp = selected + && lookupIsInBotAppButton(selected, QPoint(local.x(), mappedY)); if (_collapsedSelected != collapsedSelected || _selected != selected - || _selectedTopicJump != selectedTopicJump) { + || _selectedTopicJump != selectedTopicJump + || _selectedBotApp != selectedBotApp) { updateSelectedRow(); _selected = selected; _selectedTopicJump = selectedTopicJump; + _selectedBotApp = selectedBotApp; _collapsedSelected = collapsedSelected; updateSelectedRow(); setCursor((_selected || _collapsedSelected >= 0) @@ -1729,7 +1809,7 @@ void InnerWidget::mousePressEvent(QMouseEvent *e) { selectByMouse(e->globalPos()); _pressButton = e->button(); - setPressed(_selected, _selectedTopicJump); + setPressed(_selected, _selectedTopicJump, _selectedBotApp); setCollapsedPressed(_collapsedSelected); setHashtagPressed(_hashtagSelected); _hashtagDeletePressed = _hashtagDeleteSelected; @@ -1762,7 +1842,22 @@ void InnerWidget::mousePressEvent(QMouseEvent *e) { }; const auto origin = e->pos() - QPoint(0, dialogsOffset() + _pressed->top()); - if (_pressedTopicJump) { + if (_pressedBotApp && _pressedBotAppData) { + const auto size = _pressedBotAppData->bg.size() + / style::DevicePixelRatio(); + if (!_pressedBotAppData->ripple) { + const auto r = size.height() / 2; + _pressedBotAppData->ripple + = std::make_unique( + st::defaultRippleAnimation, + Ui::RippleAnimation::RoundRectMask(size, r), + updateCallback); + } + const auto shift = QPoint( + width() - size.width() - st::dialogRowOpenBotRight, + st::dialogRowOpenBotTop); + _pressedBotAppData->ripple->add(origin - shift); + } else if (_pressedTopicJump) { row->addTopicJumpRipple( origin, _topicJumpCache.get(), @@ -2094,6 +2189,7 @@ void InnerWidget::mousePressReleased( setCollapsedPressed(-1); const auto pressedTopicRootId = _pressedTopicJumpRootId; const auto pressedTopicJump = _pressedTopicJump; + const auto pressedBotApp = _pressedBotApp; auto pressed = _pressed; clearPressed(); auto hashtagPressed = _hashtagPressed; @@ -2113,12 +2209,16 @@ void InnerWidget::mousePressReleased( if (wasDragging) { selectByMouse(globalPosition); } + if (_pressedBotAppData && _pressedBotAppData->ripple) { + _pressedBotAppData->ripple->lastStop(); + } updateSelectedRow(); if (!wasDragging && button == Qt::LeftButton) { if ((collapsedPressed >= 0 && collapsedPressed == _collapsedSelected) || (pressed && pressed == _selected - && pressedTopicJump == _selectedTopicJump) + && pressedTopicJump == _selectedTopicJump + && pressedBotApp == _selectedBotApp) || (hashtagPressed >= 0 && hashtagPressed == _hashtagSelected && hashtagDeletePressed == _hashtagDeleteSelected) @@ -2131,7 +2231,13 @@ void InnerWidget::mousePressReleased( && searchedPressed == _searchedSelected) || (pressedMorePosts && pressedMorePosts == _selectedMorePosts)) { - chooseRow(modifiers, pressedTopicRootId); + if (pressedBotApp) { + if (const auto user = MaybeBotWithApp(pressed)) { + _openBotMainAppRequests.fire(peerToUser(user->id)); + } + } else { + chooseRow(modifiers, pressedTopicRootId); + } } } if (auto activated = ClickHandler::unpressed()) { @@ -2152,14 +2258,31 @@ void InnerWidget::setCollapsedPressed(int pressed) { } } -void InnerWidget::setPressed(Row *pressed, bool pressedTopicJump) { - if (_pressed != pressed || (pressed && _pressedTopicJump != pressedTopicJump)) { +void InnerWidget::setPressed( + Row *pressed, + bool pressedTopicJump, + bool pressedBotApp) { + if ((_pressed != pressed) + || (pressed && _pressedTopicJump != pressedTopicJump) + || (pressed && _pressedBotApp != pressedBotApp)) { if (_pressed) { _pressed->stopLastRipple(); } + if (_pressedBotAppData && _pressedBotAppData->ripple) { + _pressedBotAppData->ripple->lastStop(); + } _pressed = pressed; - if (pressed || !pressedTopicJump) { + if (pressed || !pressedTopicJump || !pressedBotApp) { _pressedTopicJump = pressedTopicJump; + _pressedBotApp = pressedBotApp; + if (pressedBotApp) { + if (const auto user = MaybeBotWithApp(pressed)) { + const auto it = _rightButtons.find(user->id); + if (it != _rightButtons.end()) { + _pressedBotAppData = &(it->second); + } + } + } const auto history = pressedTopicJump ? pressed->history() : nullptr; @@ -2170,7 +2293,7 @@ void InnerWidget::setPressed(Row *pressed, bool pressedTopicJump) { } void InnerWidget::clearPressed() { - setPressed(nullptr, false); + setPressed(nullptr, false, false); } void InnerWidget::setHashtagPressed(int pressed) { @@ -2265,7 +2388,7 @@ void InnerWidget::dialogRowReplaced( _selected = newRow; } if (_pressed == oldRow) { - setPressed(newRow, _pressedTopicJump); + setPressed(newRow, _pressedTopicJump, _pressedBotApp); } if (_dragging == oldRow) { if (newRow) { @@ -4822,4 +4945,8 @@ bool InnerWidget::jumpToDialogRow(RowDescriptor to) { return _controller->jumpToChatListEntry(to); } +rpl::producer InnerWidget::openBotMainAppRequests() const { + return _openBotMainAppRequests.events(); +} + } // namespace Dialogs diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h index 43fb5bc92..a9c9a84b7 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h @@ -64,6 +64,7 @@ class SearchTags; class SearchEmpty; class ChatSearchIn; enum class HashOrCashtag : uchar; +struct RightButton; struct ChosenRow { Key key; @@ -200,6 +201,8 @@ public: return _touchCancelRequests.events(); } + [[nodiscard]] rpl::producer openBotMainAppRequests() const; + protected: void visibleTopBottomUpdated( int visibleTop, @@ -286,7 +289,7 @@ private: void scrollToItem(int top, int height); void scrollToDefaultSelected(); void setCollapsedPressed(int pressed); - void setPressed(Row *pressed, bool pressedTopicJump); + void setPressed(Row *pressed, bool pressedTopicJump, bool pressedBotApp); void clearPressed(); void setHashtagPressed(int pressed); void setFilteredPressed(int pressed, bool pressedTopicJump); @@ -451,6 +454,11 @@ private: void saveChatsFilterScrollState(FilterId filterId); void restoreChatsFilterScrollState(FilterId filterId); + [[nodiscard]] bool lookupIsInBotAppButton( + Row *row, + QPoint localPosition); + [[nodiscard]] RightButton *maybeCacheRightButton(Row *row); + [[nodiscard]] QImage *cacheChatsFilterTag( const Data::ChatFilter &filter, uint8 more, @@ -483,6 +491,10 @@ private: bool _selectedTopicJump = false; bool _pressedTopicJump = false; + RightButton *_pressedBotAppData = nullptr; + bool _selectedBotApp = false; + bool _pressedBotApp = false; + Row *_dragging = nullptr; int _draggingIndex = -1; int _aboveIndex = -1; @@ -566,6 +578,8 @@ private: bool _waitingAllChatListEntryRefreshesForTags = false; rpl::lifetime _handleChatListEntryTagRefreshesLifetime; + std::unordered_map _rightButtons; + Fn _loadMoreCallback; Fn _loadMoreFilteredCallback; rpl::event_stream<> _listBottomReached; @@ -577,6 +591,7 @@ private: rpl::event_stream _searchRequests; rpl::event_stream _completeHashtagRequests; rpl::event_stream<> _refreshHashtagsRequests; + rpl::event_stream _openBotMainAppRequests; RowDescriptor _chatPreviewRow; bool _chatPreviewScheduled = false; diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp index 7c737d4b5..bc5841380 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp @@ -478,6 +478,12 @@ Widget::Widget( ) | rpl::start_with_next([=](const ChosenRow &row) { chosenRow(row); }, lifetime()); + _inner->openBotMainAppRequests( + ) | rpl::start_with_next([=](UserId userId) { + if (const auto user = session().data().user(userId)) { + openBotMainApp(user); + } + }, lifetime()); _scroll->geometryChanged( ) | rpl::start_with_next(crl::guard(_inner, [=] { diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp index 1a7b5a1ac..f78d9dc09 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp @@ -7,41 +7,42 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "dialogs/ui/dialogs_layout.h" +#include "base/unixtime.h" +#include "core/ui_integration.h" +#include "data/data_channel.h" #include "data/data_drafts.h" +#include "data/data_folder.h" #include "data/data_forum_topic.h" +#include "data/data_peer_values.h" #include "data/data_saved_sublist.h" #include "data/data_session.h" +#include "data/data_user.h" #include "data/stickers/data_custom_emoji.h" #include "dialogs/dialogs_list.h" #include "dialogs/dialogs_three_state_icon.h" #include "dialogs/ui/dialogs_video_userpic.h" -#include "styles/style_dialogs.h" -#include "styles/style_window.h" +#include "history/history.h" +#include "history/history_item.h" +#include "history/history_item_components.h" +#include "history/history_item_helpers.h" +#include "history/history_unread_things.h" +#include "history/view/history_view_item_preview.h" +#include "history/view/history_view_send_action.h" +#include "lang/lang_keys.h" +#include "main/main_session.h" #include "storage/localstorage.h" +#include "support/support_helper.h" #include "ui/empty_userpic.h" +#include "ui/painter.h" +#include "ui/power_saving.h" #include "ui/text/format_values.h" #include "ui/text/text_options.h" #include "ui/text/text_utilities.h" #include "ui/unread_badge.h" #include "ui/unread_badge_paint.h" -#include "ui/painter.h" -#include "ui/power_saving.h" -#include "core/ui_integration.h" -#include "lang/lang_keys.h" -#include "support/support_helper.h" -#include "main/main_session.h" -#include "history/view/history_view_send_action.h" -#include "history/view/history_view_item_preview.h" -#include "history/history_unread_things.h" -#include "history/history_item.h" -#include "history/history_item_components.h" -#include "history/history_item_helpers.h" -#include "history/history.h" -#include "base/unixtime.h" -#include "data/data_channel.h" -#include "data/data_user.h" -#include "data/data_folder.h" -#include "data/data_peer_values.h" +#include "styles/style_dialogs.h" +#include "styles/style_widgets.h" +#include "styles/style_window.h" namespace Dialogs::Ui { namespace { @@ -84,6 +85,55 @@ void PaintRowTopRight( text); } +int PaintRightButton(QPainter &p, const PaintContext &context) { + if (context.width < st::columnMinimalWidthLeft) { + return 0; + } + if (const auto rightButton = context.rightButton) { + const auto size = rightButton->bg.size() / style::DevicePixelRatio(); + const auto left = context.width + - size.width() + - st::dialogRowOpenBotRight; + const auto top = st::dialogRowOpenBotTop; + p.drawImage( + left, + top, + context.active + ? rightButton->activeBg + : context.selected + ? rightButton->selectedBg + : rightButton->bg); + if (rightButton->ripple) { + rightButton->ripple->paint( + p, + left, + top, + size.width() - size.height() / 2, + context.active + ? &st::universalRippleAnimation.color->c + : &st::activeButtonBgRipple->c); + if (rightButton->ripple->empty()) { + rightButton->ripple.reset(); + } + } + p.setPen(context.active + ? st::activeButtonBg + : context.selected + ? st::activeButtonFgOver + : st::activeButtonFg); + rightButton->text.draw(p, { + .position = QPoint( + left + size.height() / 2, + top + (st::dialogRowOpenBotHeight - rightButton->text.minHeight()) / 2), + .availableWidth = size.width() - size.height() / 2, + .outerWidth = size.width() - size.height() / 2, + .elisionLines = 1, + }); + return size.width() + st::dialogsUnreadPadding; + } + return 0; +} + int PaintBadges( QPainter &p, const PaintContext &context, @@ -93,7 +143,9 @@ int PaintBadges( bool displayPinnedIcon = false, int pinnedIconTop = 0) { auto initial = right; - if (badgesState.unread + if (const auto used = PaintRightButton(p, context)) { + return used - st::dialogsUnreadPadding; + } else if (badgesState.unread && !badgesState.unreadCounter && context.st->unreadMarkDiameter > 0) { const auto d = context.st->unreadMarkDiameter; @@ -430,7 +482,9 @@ void PaintRow( } auto availableWidth = namewidth; - if (entry->isPinnedDialog(context.filter) + if (const auto used = PaintRightButton(p, context)) { + availableWidth -= used; + } else if (entry->isPinnedDialog(context.filter) && (context.filter || !entry->fixedOnTopIndex())) { auto &icon = ThreeStateIcon( st::dialogsPinnedIcon, @@ -528,7 +582,9 @@ void PaintRow( } } else if (!item) { auto availableWidth = namewidth; - if (entry->isPinnedDialog(context.filter) + if (const auto used = PaintRightButton(p, context)) { + availableWidth -= used; + } else if (entry->isPinnedDialog(context.filter) && (context.filter || !entry->fixedOnTopIndex())) { auto &icon = ThreeStateIcon( st::dialogsPinnedIcon, diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.h b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.h index 5e51c8e73..914052447 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.h +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.h @@ -29,6 +29,7 @@ namespace Dialogs { class Row; class FakeRow; class BasicRow; +struct RightButton; } // namespace Dialogs namespace Dialogs::Ui { @@ -53,6 +54,7 @@ struct TopicJumpCache { }; struct PaintContext { + RightButton *rightButton = nullptr; std::vector *chatsFilterTags = nullptr; not_null st; TopicJumpCache *topicJumpCache = nullptr; From 6c62bbe6fb88eb58cbfc14919191bca0f350799b Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Mon, 25 Nov 2024 11:25:43 +0300 Subject: [PATCH 024/294] Added right button for bots in dialogs list in filtered mode. --- .../dialogs/dialogs_inner_widget.cpp | 87 +++++++++++++------ .../dialogs/dialogs_inner_widget.h | 7 +- 2 files changed, 67 insertions(+), 27 deletions(-) diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index 363b0dfd6..d5572a026 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -1596,7 +1596,7 @@ void InnerWidget::clearIrrelevantState() { setHashtagPressed(-1); _hashtagDeleteSelected = _hashtagDeletePressed = false; _filteredSelected = -1; - setFilteredPressed(-1, false); + setFilteredPressed(-1, false, false); _peerSearchSelected = -1; setPeerSearchPressed(-1); _previewSelected = -1; @@ -1716,15 +1716,24 @@ void InnerWidget::selectByMouse(QPoint globalPosition) { if (filteredSelected < 0 || filteredSelected >= _filterResults.size()) { filteredSelected = -1; } + const auto mappedY = (filteredSelected >= 0) + ? mouseY - skip - _filterResults[filteredSelected].top + : 0; const auto selectedTopicJump = (filteredSelected >= 0) && _filterResults[filteredSelected].row->lookupIsInTopicJump( local.x(), - mouseY - skip - _filterResults[filteredSelected].top); + mappedY); + const auto selectedBotApp = (filteredSelected >= 0) + && lookupIsInBotAppButton( + _filterResults[filteredSelected].row, + QPoint(local.x(), mappedY)); if (_filteredSelected != filteredSelected - || _selectedTopicJump != selectedTopicJump) { + || _selectedTopicJump != selectedTopicJump + || _selectedBotApp != selectedBotApp) { updateSelectedRow(); _filteredSelected = filteredSelected; _selectedTopicJump = selectedTopicJump; + _selectedBotApp = selectedBotApp; updateSelectedRow(); } } @@ -1813,7 +1822,7 @@ void InnerWidget::mousePressEvent(QMouseEvent *e) { setCollapsedPressed(_collapsedSelected); setHashtagPressed(_hashtagSelected); _hashtagDeletePressed = _hashtagDeleteSelected; - setFilteredPressed(_filteredSelected, _selectedTopicJump); + setFilteredPressed(_filteredSelected, _selectedTopicJump, _selectedBotApp); setPeerSearchPressed(_peerSearchSelected); setPreviewPressed(_previewSelected); setSearchedPressed(_searchedSelected); @@ -1842,21 +1851,7 @@ void InnerWidget::mousePressEvent(QMouseEvent *e) { }; const auto origin = e->pos() - QPoint(0, dialogsOffset() + _pressed->top()); - if (_pressedBotApp && _pressedBotAppData) { - const auto size = _pressedBotAppData->bg.size() - / style::DevicePixelRatio(); - if (!_pressedBotAppData->ripple) { - const auto r = size.height() / 2; - _pressedBotAppData->ripple - = std::make_unique( - st::defaultRippleAnimation, - Ui::RippleAnimation::RoundRectMask(size, r), - updateCallback); - } - const auto shift = QPoint( - width() - size.width() - st::dialogRowOpenBotRight, - st::dialogRowOpenBotTop); - _pressedBotAppData->ripple->add(origin - shift); + if (addBotAppRipple(origin, updateCallback)) { } else if (_pressedTopicJump) { row->addTopicJumpRipple( origin, @@ -1883,7 +1878,8 @@ void InnerWidget::mousePressEvent(QMouseEvent *e) { const auto origin = e->pos() - QPoint(0, filteredOffset() + result.top); const auto updateCallback = [=] { repaintDialogRow(filterId, row); }; - if (_pressedTopicJump) { + if (addBotAppRipple(origin, updateCallback)) { + } else if (_pressedTopicJump) { row->addTopicJumpRipple( origin, _topicJumpCache.get(), @@ -1917,6 +1913,25 @@ void InnerWidget::mousePressEvent(QMouseEvent *e) { } } +bool InnerWidget::addBotAppRipple(QPoint origin, Fn updateCallback) { + if (!(_pressedBotApp && _pressedBotAppData)) { + return false; + } + const auto size = _pressedBotAppData->bg.size() + / style::DevicePixelRatio(); + if (!_pressedBotAppData->ripple) { + _pressedBotAppData->ripple = std::make_unique( + st::defaultRippleAnimation, + Ui::RippleAnimation::RoundRectMask(size, size.height() / 2), + updateCallback); + } + const auto shift = QPoint( + width() - size.width() - st::dialogRowOpenBotRight, + st::dialogRowOpenBotTop); + _pressedBotAppData->ripple->add(origin - shift); + return true; +} + const std::vector &InnerWidget::pinnedChatsOrder() const { const auto owner = &session().data(); return _savedSublists @@ -2197,7 +2212,7 @@ void InnerWidget::mousePressReleased( auto hashtagDeletePressed = _hashtagDeletePressed; _hashtagDeletePressed = false; auto filteredPressed = _filteredPressed; - setFilteredPressed(-1, false); + setFilteredPressed(-1, false, false); auto peerSearchPressed = _peerSearchPressed; setPeerSearchPressed(-1); auto previewPressed = _previewPressed; @@ -2231,8 +2246,11 @@ void InnerWidget::mousePressReleased( && searchedPressed == _searchedSelected) || (pressedMorePosts && pressedMorePosts == _selectedMorePosts)) { - if (pressedBotApp) { - if (const auto user = MaybeBotWithApp(pressed)) { + if (pressedBotApp && (pressed || filteredPressed >= 0)) { + const auto &row = pressed + ? pressed + : _filterResults[filteredPressed].row.get(); + if (const auto user = MaybeBotWithApp(row)) { _openBotMainAppRequests.fire(peerToUser(user->id)); } } else { @@ -2303,15 +2321,32 @@ void InnerWidget::setHashtagPressed(int pressed) { _hashtagPressed = pressed; } -void InnerWidget::setFilteredPressed(int pressed, bool pressedTopicJump) { +void InnerWidget::setFilteredPressed( + int pressed, + bool pressedTopicJump, + bool pressedBotApp) { if (_filteredPressed != pressed - || (pressed >= 0 && _pressedTopicJump != pressedTopicJump)) { + || (pressed >= 0 && _pressedTopicJump != pressedTopicJump) + || (pressed >= 0 && _pressedBotApp != pressedBotApp)) { if (base::in_range(_filteredPressed, 0, _filterResults.size())) { _filterResults[_filteredPressed].row->stopLastRipple(); } + if (_pressedBotAppData && _pressedBotAppData->ripple) { + _pressedBotAppData->ripple->lastStop(); + } _filteredPressed = pressed; - if (pressed >= 0 || !pressedTopicJump) { + if (pressed >= 0 || !pressedTopicJump || !pressedBotApp) { _pressedTopicJump = pressedTopicJump; + _pressedBotApp = pressedBotApp; + if (pressed >= 0 && pressedBotApp) { + const auto &row = _filterResults[pressed].row; + if (const auto history = row->history()) { + const auto it = _rightButtons.find(history->peer->id); + if (it != _rightButtons.end()) { + _pressedBotAppData = &(it->second); + } + } + } const auto history = pressedTopicJump ? _filterResults[pressed].row->history() : nullptr; diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h index a9c9a84b7..56defd4dd 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h @@ -292,7 +292,10 @@ private: void setPressed(Row *pressed, bool pressedTopicJump, bool pressedBotApp); void clearPressed(); void setHashtagPressed(int pressed); - void setFilteredPressed(int pressed, bool pressedTopicJump); + void setFilteredPressed( + int pressed, + bool pressedTopicJump, + bool pressedBotApp); void setPeerSearchPressed(int pressed); void setPreviewPressed(int pressed); void setSearchedPressed(int pressed); @@ -326,6 +329,8 @@ private: void updateRowCornerStatusShown(not_null history); void repaintDialogRowCornerStatus(not_null history); + bool addBotAppRipple(QPoint origin, Fn updateCallback); + void setupShortcuts(); RowDescriptor computeJump( const RowDescriptor &to, From a9824fde91a2eeee155e82bd936ec08ab95e6f2b Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Mon, 25 Nov 2024 12:25:36 +0300 Subject: [PATCH 025/294] Added right button for bots in list from recent dialogs. --- Telegram/SourceFiles/dialogs/dialogs.style | 1 + .../SourceFiles/dialogs/dialogs_widget.cpp | 4 +- .../dialogs/ui/dialogs_suggestions.cpp | 108 +++++++++++++++++- .../dialogs/ui/dialogs_suggestions.h | 5 + .../settings/business/settings_chatbots.cpp | 10 +- 5 files changed, 114 insertions(+), 14 deletions(-) diff --git a/Telegram/SourceFiles/dialogs/dialogs.style b/Telegram/SourceFiles/dialogs/dialogs.style index 2cc193d59..4b6c382da 100644 --- a/Telegram/SourceFiles/dialogs/dialogs.style +++ b/Telegram/SourceFiles/dialogs/dialogs.style @@ -112,6 +112,7 @@ dialogRowOpenBotTextStyle: semiboldTextStyle; dialogRowOpenBotHeight: 20px; dialogRowOpenBotRight: 10px; dialogRowOpenBotTop: 32px; +dialogRowOpenBotRecentTop: 28px; forumDialogJumpArrow: icon{{ "dialogs/dialogs_topic_arrow", dialogsTextFg }}; forumDialogJumpArrowOver: icon{{ "dialogs/dialogs_topic_arrow", dialogsTextFgOver }}; diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp index bc5841380..9c9b16234 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp @@ -1443,7 +1443,9 @@ void Widget::updateSuggestions(anim::type animated) { } }, _suggestions->lifetime()); - _suggestions->recentAppChosen( + rpl::merge( + _suggestions->openBotMainAppRequests(), + _suggestions->recentAppChosen() ) | rpl::start_with_next([=](not_null peer) { if (const auto user = peer->asUser()) { if (const auto info = user->botInfo.get()) { diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp index 43b5c5882..0951bf756 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp @@ -28,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "main/main_session.h" #include "settings/settings_common.h" #include "ui/boxes/confirm_box.h" +#include "ui/effects/ripple_animation.h" #include "ui/text/text_utilities.h" #include "ui/widgets/menu/menu_add_action_callback_factory.h" #include "ui/widgets/buttons.h" @@ -76,12 +77,18 @@ public: bool selected, bool actionSelected) override; bool rightActionDisabled() const override; + void rightActionAddRipple( + QPoint point, + Fn updateCallback) override; + void rightActionStopLastRipple() override; const style::PeerListItem &computeSt( const style::PeerListItem &st) const override; private: const not_null _history; + std::unique_ptr _mainAppText; + std::unique_ptr _actionRipple; QString _badgeString; QSize _badgeSize; uint32 _counter : 30 = 0; @@ -181,7 +188,17 @@ void FillEntryMenu( RecentRow::RecentRow(not_null peer) : PeerListRow(peer) -, _history(peer->owner().history(peer)) { +, _history(peer->owner().history(peer)) +, _mainAppText([&]() -> std::unique_ptr { + if (const auto user = peer->asUser()) { + if (user->botInfo && user->botInfo->hasMainApp) { + return std::make_unique( + st::dialogRowOpenBotTextStyle, + tr::lng_profile_open_app_short(tr::now).toUpper()); + } + } + return nullptr; +}()) { if (peer->isSelf() || peer->isRepliesChat() || peer->isVerifyCodes()) { setCustomStatus(u" "_q); } else if (const auto chat = peer->asChat()) { @@ -244,10 +261,23 @@ bool RecentRow::refreshBadge() { } QSize RecentRow::rightActionSize() const { + if (_mainAppText) { + const auto &font = st::dialogRowOpenBotTextStyle.font; + return QSize( + _mainAppText->maxWidth() + _mainAppText->minHeight(), + st::dialogRowOpenBotHeight); + } return _badgeSize; } QMargins RecentRow::rightActionMargins() const { + if (_mainAppText) { + return QMargins( + 0, + st::dialogRowOpenBotRecentTop, + st::dialogRowOpenBotRight, + 0); + } if (_badgeSize.isEmpty()) { return {}; } @@ -263,6 +293,32 @@ void RecentRow::rightActionPaint( int outerWidth, bool selected, bool actionSelected) { + if (_mainAppText) { + const auto size = RecentRow::rightActionSize(); + p.setPen(Qt::NoPen); + p.setBrush(actionSelected + ? st::activeButtonBgOver + : st::activeButtonBg); + const auto radius = size.height() / 2; + p.drawRoundedRect(QRect(QPoint(x, y), size), radius, radius); + if (_actionRipple) { + _actionRipple->paint(p, x, y, outerWidth); + if (_actionRipple->empty()) { + _actionRipple.reset(); + } + } + p.setPen(actionSelected + ? st::activeButtonFgOver + : st::activeButtonFg); + const auto top = 0 + + (st::dialogRowOpenBotHeight - _mainAppText->minHeight()) / 2; + _mainAppText->draw(p, { + .position = QPoint(x + size.height() / 2, y + top), + .availableWidth = outerWidth, + .outerWidth = outerWidth, + .elisionLines = 1, + }); + } if (!_counter && !_unread) { return; } else if (_badgeString.isEmpty()) { @@ -280,7 +336,31 @@ void RecentRow::rightActionPaint( } bool RecentRow::rightActionDisabled() const { - return true; + return !_mainAppText; +} + +void RecentRow::rightActionAddRipple( + QPoint point, + Fn updateCallback) { + if (!_mainAppText) { + return; + } + if (!_actionRipple) { + const auto size = rightActionSize(); + const auto radius = size.height() / 2; + auto mask = Ui::RippleAnimation::RoundRectMask(size, radius); + _actionRipple = std::make_unique( + st::defaultActiveButton.ripple, + std::move(mask), + std::move(updateCallback)); + } + _actionRipple->add(point); +} + +void RecentRow::rightActionStopLastRipple() { + if (_actionRipple) { + _actionRipple->lastStop(); + } } const style::PeerListItem &RecentRow::computeSt( @@ -357,14 +437,18 @@ private: class RecentsController final : public Suggestions::ObjectListController { public: + using RightActionCallback = Fn)>; + RecentsController( not_null window, - RecentPeersList list); + RecentPeersList list, + RightActionCallback rightActionCallback); void prepare() override; base::unique_qptr rowContextMenu( QWidget *parent, not_null row) override; + void rowRightActionClicked(not_null row) override; QString savedMessagesChatStatus() const override; @@ -374,6 +458,7 @@ private: [[nodiscard]] Fn removeAllCallback(); RecentPeersList _recent; + RightActionCallback _rightActionCallback; rpl::lifetime _lifetime; }; @@ -671,9 +756,11 @@ void Suggestions::ObjectListController::setupExpandDivider( RecentsController::RecentsController( not_null window, - RecentPeersList list) + RecentPeersList list, + RightActionCallback rightActionCallback) : ObjectListController(window) -, _recent(std::move(list)) { +, _recent(std::move(list)) +, _rightActionCallback(std::move(rightActionCallback)) { } void RecentsController::prepare() { @@ -735,6 +822,14 @@ base::unique_qptr RecentsController::rowContextMenu( return result; } +void RecentsController::rowRightActionClicked(not_null row) { + if (_rightActionCallback) { + if (const auto peer = row->peer()) { + _rightActionCallback(peer); + } + } +} + QString RecentsController::savedMessagesChatStatus() const { return tr::lng_saved_forward_here(tr::now); } @@ -1785,7 +1880,8 @@ auto Suggestions::setupRecentPeers(RecentPeersList recentPeers) -> std::unique_ptr { const auto controller = lifetime().make_state( _controller, - std::move(recentPeers)); + std::move(recentPeers), + [=](not_null p) { _openBotMainAppRequests.fire_copy(p); }); const auto addToScroll = [=] { return _topPeersWrap->toggled() ? _topPeers->height() : 0; diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.h b/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.h index 32998519f..973f65c7d 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.h +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.h @@ -88,6 +88,10 @@ public: -> rpl::producer> { return _popularApps->chosen.events(); } + [[nodiscard]] auto openBotMainAppRequests() const + -> rpl::producer> { + return _openBotMainAppRequests.events(); + } class ObjectListController; @@ -174,6 +178,7 @@ private: const not_null*> _topPeersWrap; const not_null _topPeers; rpl::event_stream> _topPeerChosen; + rpl::event_stream> _openBotMainAppRequests; const std::unique_ptr _recent; diff --git a/Telegram/SourceFiles/settings/business/settings_chatbots.cpp b/Telegram/SourceFiles/settings/business/settings_chatbots.cpp index cd439e139..c5006bf78 100644 --- a/Telegram/SourceFiles/settings/business/settings_chatbots.cpp +++ b/Telegram/SourceFiles/settings/business/settings_chatbots.cpp @@ -134,11 +134,7 @@ void PreviewRow::rightActionPaint( bool selected, bool actionSelected) { if (_actionRipple) { - _actionRipple->paint( - p, - x, - y, - outerWidth); + _actionRipple->paint(p, x, y, outerWidth); if (_actionRipple->empty()) { _actionRipple.reset(); } @@ -150,8 +146,8 @@ void PreviewRow::rightActionPaint( } void PreviewRow::rightActionAddRipple( - QPoint point, - Fn updateCallback) { + QPoint point, + Fn updateCallback) { if (!_actionRipple) { auto mask = Ui::RippleAnimation::EllipseMask(rightActionSize()); _actionRipple = std::make_unique( From 489c86dad873587a7ea646b5a8f4c605a625034c Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Mon, 25 Nov 2024 17:59:44 +0300 Subject: [PATCH 026/294] Added ability to disable debug logs even for debug builds. --- Telegram/SourceFiles/core/launcher.cpp | 4 ++++ Telegram/SourceFiles/logs.cpp | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Telegram/SourceFiles/core/launcher.cpp b/Telegram/SourceFiles/core/launcher.cpp index 0b6afb7aa..312ce9667 100644 --- a/Telegram/SourceFiles/core/launcher.cpp +++ b/Telegram/SourceFiles/core/launcher.cpp @@ -106,6 +106,10 @@ void ComputeDebugMode() { auto file = QFile(debugModeSettingPath); if (file.exists() && file.open(QIODevice::ReadOnly)) { Logs::SetDebugEnabled(file.read(1) != "0"); +#if defined _DEBUG + } else { + Logs::SetDebugEnabled(true); +#endif } if (cDebugMode()) { Logs::SetDebugEnabled(true); diff --git a/Telegram/SourceFiles/logs.cpp b/Telegram/SourceFiles/logs.cpp index 9a04542ef..382d65aaf 100644 --- a/Telegram/SourceFiles/logs.cpp +++ b/Telegram/SourceFiles/logs.cpp @@ -335,11 +335,7 @@ void SetDebugEnabled(bool enabled) { } bool DebugEnabled() { -#if defined _DEBUG - return true; -#else return DebugModeEnabled; -#endif } bool WritingEntry() { From 743c3c54a7820f9ae718aa016d0bccc18c3ecfd3 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Tue, 26 Nov 2024 06:08:17 +0300 Subject: [PATCH 027/294] Added message counter to each peer in moderate box. --- .../boxes/moderate_messages_box.cpp | 87 ++++++++++++++----- .../ui/widgets/expandable_peer_list.cpp | 39 ++++++--- .../ui/widgets/expandable_peer_list.h | 1 + 3 files changed, 96 insertions(+), 31 deletions(-) diff --git a/Telegram/SourceFiles/boxes/moderate_messages_box.cpp b/Telegram/SourceFiles/boxes/moderate_messages_box.cpp index c7e696e9e..49df5b0ea 100644 --- a/Telegram/SourceFiles/boxes/moderate_messages_box.cpp +++ b/Telegram/SourceFiles/boxes/moderate_messages_box.cpp @@ -87,19 +87,35 @@ ModerateOptions CalculateModerateOptions(const HistoryItemsList &items) { return result; } -[[nodiscard]] rpl::producer MessagesCountValue( +[[nodiscard]] rpl::producer> MessagesCountValue( not_null history, - not_null from) { + std::vector> from) { return [=](auto consumer) { auto lifetime = rpl::lifetime(); - auto search = lifetime.make_state(history); - consumer.put_next(0); - - search->messagesFounds( - ) | rpl::start_with_next([=](const Api::FoundMessages &found) { - consumer.put_next_copy(found.total); - }, lifetime); - search->searchMessages({ .from = from }); + struct State final { + base::flat_map messagesCounts; + int index = 0; + rpl::lifetime apiLifetime; + }; + const auto search = lifetime.make_state(history); + const auto state = lifetime.make_state(); + const auto send = [=](auto repeat) -> void { + if (state->index >= from.size()) { + consumer.put_next_copy(state->messagesCounts); + return; + } + const auto peer = from[state->index]; + const auto peerId = peer->id; + state->apiLifetime = search->messagesFounds( + ) | rpl::start_with_next([=](const Api::FoundMessages &found) { + state->messagesCounts[peerId] = found.total; + state->index++; + repeat(repeat); + }); + search->searchMessages({ .from = peer }); + }; + consumer.put_next({}); + send(send); return lifetime; }; @@ -274,15 +290,50 @@ void CreateModerateMessagesBox( false, st::defaultBoxCheckbox), st::boxRowPadding + buttonPadding); - if (isSingle) { - const auto history = items.front()->history(); + const auto history = items.front()->history(); + auto messagesCounts = MessagesCountValue(history, participants); + + const auto controller = box->lifetime().make_state( + Controller::Data{ + .messagesCounts = rpl::duplicate(messagesCounts), + .participants = participants, + }); + Ui::AddExpandablePeerList(deleteAll, controller, inner); + { tr::lng_selected_delete_sure( lt_count, rpl::combine( - MessagesCountValue(history, participants.front()), - deleteAll->checkedValue() - ) | rpl::map([s = items.size()](int all, bool checked) { - return float64((checked && all) ? all : s); + std::move(messagesCounts), + isSingle + ? deleteAll->checkedValue() + : rpl::merge( + controller->toggleRequestsFromInner.events(), + controller->checkAllRequests.events()) + ) | rpl::map([=, s = items.size()](const auto &map, bool c) { + const auto checked = (isSingle && !c) + ? Participants() + : controller->collectRequests + ? controller->collectRequests() + : Participants(); + auto result = 0; + for (const auto &[peerId, count] : map) { + for (const auto &peer : checked) { + if (peer->id == peerId) { + result += count; + break; + } + } + } + for (const auto &item : items) { + for (const auto &peer : checked) { + if (peer->id == item->from()->id) { + result--; + break; + } + } + result++; + } + return float64(result); }) ) | rpl::start_with_next([=](const QString &text) { title->setText(text); @@ -290,10 +341,6 @@ void CreateModerateMessagesBox( - rect::m::sum::h(st::boxRowPadding)); }, title->lifetime()); } - - const auto controller = box->lifetime().make_state( - Controller::Data{ .participants = participants }); - Ui::AddExpandablePeerList(deleteAll, controller, inner); handleSubmition(deleteAll); handleConfirmation(deleteAll, controller, [=]( diff --git a/Telegram/SourceFiles/ui/widgets/expandable_peer_list.cpp b/Telegram/SourceFiles/ui/widgets/expandable_peer_list.cpp index db09645b6..343d623aa 100644 --- a/Telegram/SourceFiles/ui/widgets/expandable_peer_list.cpp +++ b/Telegram/SourceFiles/ui/widgets/expandable_peer_list.cpp @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/widgets/expandable_peer_list.h" #include "data/data_peer.h" +#include "info/profile/info_profile_values.h" #include "ui/controls/userpic_button.h" #include "ui/rect.h" #include "ui/text/text_utilities.h" @@ -148,19 +149,35 @@ void AddExpandablePeerList( const auto &st = st::moderateBoxUserpic; line->resize(line->width(), st.size.height()); - const auto userpic = Ui::CreateChild( - line, - peer, - st); + using namespace Info::Profile; + auto name = controller->data.bold + ? NameValue(peer) | rpl::map(Ui::Text::Bold) + : NameValue(peer) | rpl::map(Ui::Text::WithEntities); + const auto userpic + = Ui::CreateChild(line, peer, st); const auto checkbox = Ui::CreateChild( line, - controller->data.bold - ? Ui::Text::Bold(peer->name()) - : TextWithEntities{ .text = peer->name() }, - ranges::contains(controller->data.checked, peer->id), - st::defaultBoxCheckbox); - line->widthValue( - ) | rpl::start_with_next([=](int width) { + controller->data.messagesCounts + ? rpl::combine( + std::move(name), + rpl::duplicate(controller->data.messagesCounts) + ) | rpl::map([=](const auto &richName, const auto &map) { + const auto it = map.find(peer->id); + return (it == map.end() || !it->second) + ? richName + : TextWithEntities( + (u"(%1) "_q).arg(it->second)).append(richName); + }) + : std::move(name), + st::defaultBoxCheckbox, + std::make_unique( + st::defaultCheck, + ranges::contains(controller->data.checked, peer->id))); + checkbox->setCheckAlignment(style::al_left); + rpl::combine( + line->widthValue(), + checkbox->widthValue() + ) | rpl::start_with_next([=](int width, int) { userpic->moveToLeft( st::boxRowPadding.left() + checkbox->checkRect().width() diff --git a/Telegram/SourceFiles/ui/widgets/expandable_peer_list.h b/Telegram/SourceFiles/ui/widgets/expandable_peer_list.h index 3ff7e4ee1..983701f53 100644 --- a/Telegram/SourceFiles/ui/widgets/expandable_peer_list.h +++ b/Telegram/SourceFiles/ui/widgets/expandable_peer_list.h @@ -18,6 +18,7 @@ class VerticalLayout; struct ExpandablePeerListController final { struct Data final { + rpl::producer> messagesCounts = nullptr; Participants participants; std::vector checked; bool skipSingle = false; From 10b026dfe0dce7bd21ec2a05502522bf6d927fe9 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Tue, 26 Nov 2024 09:28:11 +0300 Subject: [PATCH 028/294] Added ability to open peer in new window from short info box. --- .../boxes/peers/peer_short_info_box.cpp | 51 ++++++++++++++----- .../boxes/peers/peer_short_info_box.h | 12 +++++ .../boxes/peers/prepare_short_info_box.cpp | 47 ++++++++++++----- .../boxes/peers/prepare_short_info_box.h | 5 ++ .../stories/media_stories_controller.cpp | 1 + 5 files changed, 92 insertions(+), 24 deletions(-) diff --git a/Telegram/SourceFiles/boxes/peers/peer_short_info_box.cpp b/Telegram/SourceFiles/boxes/peers/peer_short_info_box.cpp index dc7524e76..0275358f0 100644 --- a/Telegram/SourceFiles/boxes/peers/peer_short_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/peer_short_info_box.cpp @@ -7,27 +7,36 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "boxes/peers/peer_short_info_box.h" -#include "ui/effects/radial_animation.h" -#include "ui/widgets/labels.h" -#include "ui/widgets/scroll_area.h" -#include "ui/wrap/vertical_layout.h" -#include "ui/wrap/slide_wrap.h" -#include "ui/wrap/wrap.h" -#include "ui/image/image_prepare.h" -#include "ui/text/text_utilities.h" -#include "ui/painter.h" +#include "base/event_filter.h" +#include "core/application.h" #include "info/profile/info_profile_text.h" #include "info/profile/info_profile_values.h" +#include "lang/lang_keys.h" #include "media/streaming/media_streaming_instance.h" #include "media/streaming/media_streaming_player.h" -#include "base/event_filter.h" -#include "lang/lang_keys.h" +#include "ui/effects/radial_animation.h" +#include "ui/image/image_prepare.h" +#include "ui/painter.h" +#include "ui/text/text_utilities.h" +#include "ui/widgets/labels.h" +#include "ui/widgets/menu/menu_add_action_callback.h" +#include "ui/widgets/menu/menu_add_action_callback_factory.h" +#include "ui/widgets/popup_menu.h" +#include "ui/widgets/scroll_area.h" +#include "ui/wrap/slide_wrap.h" +#include "ui/wrap/vertical_layout.h" +#include "ui/wrap/wrap.h" +#include "window/window_controller.h" +#include "window/window_session_controller.h" #include "styles/style_boxes.h" -#include "styles/style_layers.h" #include "styles/style_info.h" +#include "styles/style_layers.h" +#include "styles/style_menu_icons.h" namespace { +using MenuCallback = Ui::Menu::MenuCallback; + constexpr auto kShadowMaxAlpha = 80; constexpr auto kInactiveBarOpacity = 0.5; @@ -833,6 +842,24 @@ void PeerShortInfoBox::refreshRoundedTopImage(const QColor &color) { RectPart::TopLeft | RectPart::TopRight); } +rpl::producer PeerShortInfoBox::fillMenuRequests() const { + return _fillMenuRequests.events(); +} + +void PeerShortInfoBox::contextMenuEvent(QContextMenuEvent *e) { + _menuHolder = nullptr; + const auto menu = Ui::CreateChild( + this, + st::popupMenuWithIcons); + _fillMenuRequests.fire(Ui::Menu::CreateAddActionCallback(menu)); + _menuHolder.reset(menu); + if (menu->empty()) { + _menuHolder = nullptr; + return; + } + menu->popup(e->globalPos()); +} + rpl::producer PeerShortInfoBox::nameValue() const { return _fields.value( ) | rpl::map([](const PeerShortInfoFields &fields) { diff --git a/Telegram/SourceFiles/boxes/peers/peer_short_info_box.h b/Telegram/SourceFiles/boxes/peers/peer_short_info_box.h index b51ac3e2d..271e1826c 100644 --- a/Telegram/SourceFiles/boxes/peers/peer_short_info_box.h +++ b/Telegram/SourceFiles/boxes/peers/peer_short_info_box.h @@ -15,6 +15,10 @@ struct ShortInfoCover; struct ShortInfoBox; } // namespace style +namespace Ui::Menu { +struct MenuCallback; +} // namespace Ui::Menu + namespace Media::Streaming { class Document; class Instance; @@ -160,6 +164,11 @@ public: [[nodiscard]] rpl::producer<> openRequests() const; [[nodiscard]] rpl::producer moveRequests() const; + [[nodiscard]] auto fillMenuRequests() const + -> rpl::producer; + +protected: + void contextMenuEvent(QContextMenuEvent *e) override; private: void prepare() override; @@ -192,6 +201,9 @@ private: not_null _rows; PeerShortInfoCover _cover; + base::unique_qptr _menuHolder; + rpl::event_stream _fillMenuRequests; + rpl::event_stream<> _openRequests; }; diff --git a/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.cpp b/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.cpp index 72482cffd..760a821c7 100644 --- a/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.cpp @@ -7,26 +7,30 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "boxes/peers/prepare_short_info_box.h" +#include "base/unixtime.h" #include "boxes/peers/peer_short_info_box.h" +#include "core/application.h" +#include "data/data_changes.h" +#include "data/data_channel.h" +#include "data/data_chat.h" +#include "data/data_file_origin.h" #include "data/data_peer.h" +#include "data/data_peer_values.h" #include "data/data_photo.h" #include "data/data_photo_media.h" -#include "data/data_streaming.h" -#include "data/data_file_origin.h" -#include "data/data_user.h" -#include "data/data_chat.h" -#include "data/data_channel.h" -#include "data/data_peer_values.h" -#include "data/data_user_photos.h" -#include "data/data_changes.h" #include "data/data_session.h" -#include "main/main_session.h" -#include "window/window_session_controller.h" +#include "data/data_streaming.h" +#include "data/data_user.h" +#include "data/data_user_photos.h" #include "info/profile/info_profile_values.h" -#include "ui/text/format_values.h" -#include "base/unixtime.h" #include "lang/lang_keys.h" +#include "main/main_session.h" +#include "ui/delayed_activation.h" // PreventDelayedActivation +#include "ui/text/format_values.h" +#include "ui/widgets/menu/menu_add_action_callback.h" +#include "window/window_session_controller.h" #include "styles/style_info.h" +#include "styles/style_menu_icons.h" namespace { @@ -446,6 +450,7 @@ object_ptr PrepareShortInfoBox( not_null peer, Fn open, Fn videoPaused, + Fn menuFiller, const style::ShortInfoBox *stOverride) { const auto type = peer->isSelf() ? PeerShortInfoType::Self @@ -463,6 +468,13 @@ object_ptr PrepareShortInfoBox( std::move(videoPaused), stOverride); + if (menuFiller) { + result->fillMenuRequests( + ) | rpl::start_with_next([=](Ui::Menu::MenuCallback callback) { + menuFiller(std::move(callback)); + }, result->lifetime()); + } + result->openRequests( ) | rpl::start_with_next(open, result->lifetime()); @@ -481,10 +493,21 @@ object_ptr PrepareShortInfoBox( return navigation->parentController()->isGifPausedAtLeastFor( Window::GifPauseReason::Layer); }; + auto menuFiller = [=](Ui::Menu::MenuCallback addAction) { + const auto controller = navigation->parentController(); + const auto peerSeparateId = Window::SeparateId(peer); + if (controller->windowId() != peerSeparateId) { + addAction(tr::lng_context_new_window(tr::now), [=] { + Ui::PreventDelayedActivation(); + controller->showInNewWindow(peer); + }, &st::menuIconNewWindow); + } + }; return PrepareShortInfoBox( peer, open, videoIsPaused, + std::move(menuFiller), stOverride); } diff --git a/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.h b/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.h index 327ce373b..2edd5cd92 100644 --- a/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.h +++ b/Telegram/SourceFiles/boxes/peers/prepare_short_info_box.h @@ -16,6 +16,10 @@ struct ShortInfoCover; struct ShortInfoBox; } // namespace style +namespace Ui::Menu { +struct MenuCallback; +} // namespace Ui::Menu + namespace Ui { class BoxContent; } // namespace Ui @@ -35,6 +39,7 @@ struct PreparedShortInfoUserpic { not_null peer, Fn open, Fn videoPaused, + Fn menuFiller, const style::ShortInfoBox *stOverride = nullptr); [[nodiscard]] object_ptr PrepareShortInfoBox( diff --git a/Telegram/SourceFiles/media/stories/media_stories_controller.cpp b/Telegram/SourceFiles/media/stories/media_stories_controller.cpp index 1405eaae5..c0ca0eb43 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_controller.cpp +++ b/Telegram/SourceFiles/media/stories/media_stories_controller.cpp @@ -1921,6 +1921,7 @@ object_ptr PrepareShortInfoBox(not_null peer) { peer, open, [] { return false; }, + nullptr, &st::storiesShortInfoBox); } From 0e35107e17c7a2d232b62ef0bce05b085853ccf7 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Tue, 26 Nov 2024 12:05:41 +0300 Subject: [PATCH 029/294] Added ability to create new filter with selected dialog from menu. --- .../SourceFiles/boxes/choose_filter_box.cpp | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/Telegram/SourceFiles/boxes/choose_filter_box.cpp b/Telegram/SourceFiles/boxes/choose_filter_box.cpp index 80ff008bc..60d4c537d 100644 --- a/Telegram/SourceFiles/boxes/choose_filter_box.cpp +++ b/Telegram/SourceFiles/boxes/choose_filter_box.cpp @@ -8,9 +8,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/choose_filter_box.h" #include "apiwrap.h" +#include "boxes/filters/edit_filter_box.h" #include "boxes/premium_limits_box.h" #include "core/application.h" // primaryWindow #include "data/data_chat_filters.h" +#include "data/data_premium_limits.h" #include "data/data_session.h" #include "history/history.h" #include "lang/lang_keys.h" @@ -21,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/window_controller.h" #include "window/window_session_controller.h" #include "styles/style_media_player.h" // mediaPlayerMenuCheck +#include "styles/style_menu_icons.h" namespace { @@ -162,7 +165,8 @@ void FillChooseFilterMenu( not_null history) { const auto weak = base::make_weak(controller); const auto validator = ChooseFilterValidator(history); - for (const auto &filter : history->owner().chatsFilters().list()) { + const auto &list = history->owner().chatsFilters().list(); + for (const auto &filter : list) { const auto id = filter.id(); if (!id) { continue; @@ -191,6 +195,37 @@ void FillChooseFilterMenu( ? validator.canRemove(id) : validator.canAdd()); } + + const auto limit = [session = &controller->session()] { + return Data::PremiumLimits(session).dialogFiltersCurrent(); + }; + if ((list.size() - 1) < limit()) { + menu->addAction(tr::lng_filters_create(tr::now), [=] { + const auto strong = weak.get(); + if (!strong) { + return; + } + const auto session = &strong->session(); + const auto count = session->data().chatsFilters().list().size(); + if ((count - 1) >= limit()) { + return; + } + auto filter = + Data::ChatFilter({}, {}, {}, {}, {}, { history }, {}, {}); + const auto send = [=](const Data::ChatFilter &filter) { + session->api().request(MTPmessages_UpdateDialogFilter( + MTP_flags(MTPmessages_UpdateDialogFilter::Flag::f_filter), + MTP_int(count), + filter.tl() + )).done([=] { + session->data().chatsFilters().reload(); + }).send(); + }; + strong->uiShow()->show( + Box(EditFilterBox, strong, std::move(filter), send, nullptr)); + }, &st::menuIconShowInFolder); + } + history->owner().chatsFilters().changed( ) | rpl::start_with_next([=] { menu->hideMenu(); From cd5a1980c94d3b43e84714f34f3218d775d8180f Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Tue, 26 Nov 2024 13:35:14 +0300 Subject: [PATCH 030/294] Fixed display of button for earn out when withdrawal is locked. --- Telegram/SourceFiles/settings/settings_credits_graphics.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp index 4a190dc3a..889b7a921 100644 --- a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp +++ b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp @@ -2021,7 +2021,7 @@ void AddWithdrawalWidget( lockedLabel->paintRequest() | rpl::start_with_next([=] { auto p = QPainter(lockedLabel); p.setPen(state->locked ? QPen(lockedColor) : stButton.textFg->p); - if (state->dateIsNull) { + if (state->dateIsNull && state->locked) { p.setFont(st::channelEarnSemiboldLabel.style.font); p.drawText( lockedLabel->rect(), From cb2972b14594a67af4354cd6a2f4d37ed1c19f5f Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Tue, 26 Nov 2024 15:23:26 +0300 Subject: [PATCH 031/294] Moved out fixing of ampersand from text in actions to single place. --- .../SourceFiles/dialogs/ui/dialogs_suggestions.cpp | 3 ++- .../SourceFiles/history/history_inner_widget.cpp | 12 +++++++----- .../history/view/history_view_context_menu.cpp | 12 ++++++------ Telegram/SourceFiles/platform/mac/main_window_mac.mm | 7 +++++-- Telegram/lib_ui | 2 +- 5 files changed, 21 insertions(+), 15 deletions(-) diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp index 0951bf756..849a0c85c 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp @@ -1402,7 +1402,8 @@ void Suggestions::setupChats() { .removeOneText = tr::lng_recent_remove(tr::now), .removeOne = removeOne, .removeAllText = tr::lng_recent_hide_top( - tr::now).replace('&', u"&&"_q), + tr::now, + Ui::Text::FixAmpersandInAction), .removeAllConfirm = tr::lng_recent_hide_sure(tr::now), .removeAll = removeAll, }); diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index a6b9f2669..f239ff276 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -38,6 +38,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/effects/message_sending_animation_controller.h" #include "ui/effects/reaction_fly_animation.h" #include "ui/text/text_isolated_emoji.h" +#include "ui/text/text_utilities.h" #include "ui/boxes/edit_factcheck_box.h" #include "ui/boxes/report_box_graphics.h" #include "ui/controls/delete_message_context_action.h" @@ -2549,15 +2550,16 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { const auto canReply = canSendReply || item->allowsForward(); if (canReply) { const auto selected = selectedQuote(item); - auto text = selected - ? tr::lng_context_quote_and_reply(tr::now) - : tr::lng_context_reply_msg(tr::now); + auto text = (selected + ? tr::lng_context_quote_and_reply + : tr::lng_context_reply_msg)( + tr::now, + Ui::Text::FixAmpersandInAction); const auto replyToItem = selected.item ? selected.item : item; const auto itemId = replyToItem->fullId(); const auto quote = selected.text; const auto quoteOffset = selected.offset; - text.replace('&', u"&&"_q); - _menu->addAction(text, [=] { + _menu->addAction(std::move(text), [=] { _widget->replyToMessage({ .messageId = itemId, .quote = quote, diff --git a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp index 0fb338a88..50ffc31b3 100644 --- a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp +++ b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp @@ -635,12 +635,12 @@ bool AddReplyToMessageAction( } const auto "e = request.quote; - auto text = quote.text.empty() - ? tr::lng_context_reply_msg(tr::now) - : tr::lng_context_quote_and_reply(tr::now); - text.replace('&', u"&&"_q); - const auto itemId = item->fullId(); - menu->addAction(text, [=] { + auto text = (quote.text.empty() + ? tr::lng_context_reply_msg + : tr::lng_context_quote_and_reply)( + tr::now, + Ui::Text::FixAmpersandInAction); + menu->addAction(std::move(text), [=, itemId = item->fullId()] { list->replyToMessageRequestNotify({ .messageId = itemId, .quote = quote.text, diff --git a/Telegram/SourceFiles/platform/mac/main_window_mac.mm b/Telegram/SourceFiles/platform/mac/main_window_mac.mm index 6d3514d34..22ecff8ef 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.mm +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.mm @@ -18,8 +18,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "media/player/media_player_instance.h" #include "media/audio/media_audio.h" #include "storage/localstorage.h" -#include "window/window_session_controller.h" +#include "ui/text/text_utilities.h" #include "window/window_controller.h" +#include "window/window_session_controller.h" #include "platform/mac/touchbar/mac_touchbar_manager.h" #include "platform/platform_specific.h" #include "platform/platform_notifications_manager.h" @@ -519,7 +520,9 @@ void MainWindow::createGlobalMenu() { edit->addSeparator(); edit->addAction( - tr::lng_mac_menu_emoji_and_symbols(tr::now).replace('&', "&&"), + tr::lng_mac_menu_emoji_and_symbols( + tr::now, + Ui::Text::FixAmpersandInAction), this, [] { [NSApp orderFrontCharacterPalette:nil]; }, QKeySequence(Qt::MetaModifier | Qt::ControlModifier | Qt::Key_Space) diff --git a/Telegram/lib_ui b/Telegram/lib_ui index 64f99667a..3254aebf5 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit 64f99667a6f45e9a896624c2d1c71fa143804aab +Subproject commit 3254aebf55133066e0a8775cabdfcef568b79625 From 96b5c1d3d3b1f97310a82e4084fe4ac6b6259bd9 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Tue, 26 Nov 2024 15:16:20 +0300 Subject: [PATCH 032/294] Added icons and color indices to dialogs menu to choose chats filters. --- .../SourceFiles/boxes/choose_filter_box.cpp | 103 +++++++++++++++++- 1 file changed, 100 insertions(+), 3 deletions(-) diff --git a/Telegram/SourceFiles/boxes/choose_filter_box.cpp b/Telegram/SourceFiles/boxes/choose_filter_box.cpp index 60d4c537d..43a4d2ea4 100644 --- a/Telegram/SourceFiles/boxes/choose_filter_box.cpp +++ b/Telegram/SourceFiles/boxes/choose_filter_box.cpp @@ -17,16 +17,97 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/history.h" #include "lang/lang_keys.h" #include "main/main_session.h" +#include "ui/empty_userpic.h" +#include "ui/filter_icons.h" +#include "ui/painter.h" +#include "ui/rect.h" #include "ui/text/text_utilities.h" // Ui::Text::Bold #include "ui/widgets/buttons.h" +#include "ui/widgets/menu/menu_action.h" #include "ui/widgets/popup_menu.h" #include "window/window_controller.h" #include "window/window_session_controller.h" +#include "styles/style_dialogs.h" #include "styles/style_media_player.h" // mediaPlayerMenuCheck #include "styles/style_menu_icons.h" +#include "styles/style_settings.h" namespace { +[[nodiscard]] QImage Icon(const Data::ChatFilter &f) { + constexpr auto kScale = 0.75; + const auto icon = Ui::LookupFilterIcon(Ui::ComputeFilterIcon(f)).normal; + const auto originalWidth = icon->width(); + const auto originalHeight = icon->height(); + + const auto scaledWidth = int(originalWidth * kScale); + const auto scaledHeight = int(originalHeight * kScale); + + auto image = QImage( + scaledWidth * style::DevicePixelRatio(), + scaledHeight * style::DevicePixelRatio(), + QImage::Format_ARGB32_Premultiplied); + image.setDevicePixelRatio(style::DevicePixelRatio()); + image.fill(Qt::transparent); + + { + auto p = QPainter(&image); + auto hq = PainterHighQualityEnabler(p); + + const auto x = int((scaledWidth - originalWidth * kScale) / 2); + const auto y = int((scaledHeight - originalHeight * kScale) / 2); + + p.scale(kScale, kScale); + icon->paint(p, x, y, scaledWidth, st::dialogsUnreadBgMuted->c); + if (const auto color = f.colorIndex()) { + p.resetTransform(); + const auto circleSize = scaledWidth / 3.; + const auto r = QRectF( + x + scaledWidth - circleSize, + y + scaledHeight - circleSize - circleSize / 3., + circleSize, + circleSize); + p.setPen(Qt::NoPen); + p.setCompositionMode(QPainter::CompositionMode_Clear); + p.setBrush(Qt::transparent); + p.drawEllipse(r + Margins(st::lineWidth * 1.5)); + p.setCompositionMode(QPainter::CompositionMode_SourceOver); + p.setBrush(Ui::EmptyUserpic::UserpicColor(*color).color2); + p.drawEllipse(r); + } + } + + return image; +} + +class FilterAction : public Ui::Menu::Action { +public: + using Ui::Menu::Action::Action; + + void setIcon(QImage &&image) { + _icon = std::move(image); + } + +protected: + void paintEvent(QPaintEvent *event) override { + Ui::Menu::Action::paintEvent(event); + if (!_icon.isNull()) { + const auto size = _icon.size() / style::DevicePixelRatio(); + auto p = QPainter(this); + p.drawImage( + width() + - size.width() + - st::menuWithIcons.itemPadding.right(), + (height() - size.height()) / 2, + _icon); + } + } + +private: + QImage _icon; + +}; + Data::ChatFilter ChangedFilter( const Data::ChatFilter &filter, not_null history, @@ -166,14 +247,14 @@ void FillChooseFilterMenu( const auto weak = base::make_weak(controller); const auto validator = ChooseFilterValidator(history); const auto &list = history->owner().chatsFilters().list(); + const auto showColors = history->owner().chatsFilters().tagsEnabled(); for (const auto &filter : list) { const auto id = filter.id(); if (!id) { continue; } - const auto contains = filter.contains(history); - const auto action = menu->addAction(filter.title(), [=] { + auto callback = [=] { const auto toAdd = !filter.contains(history); const auto r = validator.limitReached(id, toAdd); if (r.reached) { @@ -190,7 +271,23 @@ void FillChooseFilterMenu( validator.remove(id); } } - }, contains ? &st::mediaPlayerMenuCheck : nullptr); + }; + + const auto contains = filter.contains(history); + auto item = base::make_unique_q( + menu.get(), + menu->st().menu, + Ui::Menu::CreateAction( + menu.get(), + Ui::Text::FixAmpersandInAction(filter.title()), + std::move(callback)), + contains ? &st::mediaPlayerMenuCheck : nullptr, + contains ? &st::mediaPlayerMenuCheck : nullptr); + + item->setIcon(Icon(showColors ? filter : filter.withColorIndex({}))); + const auto &p = st::menuWithIcons.itemPadding; + item->setMinWidth(item->minWidth() + p.left() - p.right() - p.top()); + const auto action = menu->addAction(std::move(item)); action->setEnabled(contains ? validator.canRemove(id) : validator.canAdd()); From 5934614edb7b1983d004c5d6ddfdba07142e6f4d Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 27 Nov 2024 08:47:39 +0300 Subject: [PATCH 033/294] Fixed counting of unread topics from unread state in filters. --- .../SourceFiles/data/data_forum_topic.cpp | 1 + Telegram/SourceFiles/dialogs/dialogs_entry.h | 9 +++++++++ Telegram/SourceFiles/history/history.cpp | 20 +++++++++++++++---- .../ui/widgets/chat_filters_tabs_strip.cpp | 9 +++++++-- .../window/window_filters_menu.cpp | 9 +++++++-- 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/Telegram/SourceFiles/data/data_forum_topic.cpp b/Telegram/SourceFiles/data/data_forum_topic.cpp index d7ad7565a..d8ebb396c 100644 --- a/Telegram/SourceFiles/data/data_forum_topic.cpp +++ b/Telegram/SourceFiles/data/data_forum_topic.cpp @@ -902,6 +902,7 @@ Dialogs::UnreadState ForumTopic::unreadStateFor( result.reactions = unreadReactions().has() ? 1 : 0; result.messagesMuted = muted ? result.messages : 0; result.chatsMuted = muted ? result.chats : 0; + result.chatsTopicMuted = muted ? result.chats : 0; result.reactionsMuted = muted ? result.reactions : 0; result.known = known; return result; diff --git a/Telegram/SourceFiles/dialogs/dialogs_entry.h b/Telegram/SourceFiles/dialogs/dialogs_entry.h index b97044241..83935c5ba 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_entry.h +++ b/Telegram/SourceFiles/dialogs/dialogs_entry.h @@ -75,10 +75,13 @@ struct UnreadState { int chats = 0; int chatsMuted = 0; int chatsTopic = 0; + int chatsTopicMuted = 0; int marks = 0; int marksMuted = 0; int reactions = 0; int reactionsMuted = 0; + int forums = 0; + int forumsMuted = 0; int mentions = 0; bool known = false; @@ -88,10 +91,13 @@ struct UnreadState { chats += other.chats; chatsMuted += other.chatsMuted; chatsTopic += other.chatsTopic; + chatsTopicMuted += other.chatsTopicMuted; marks += other.marks; marksMuted += other.marksMuted; reactions += other.reactions; reactionsMuted += other.reactionsMuted; + forums += other.forums; + forumsMuted += other.forumsMuted; mentions += other.mentions; return *this; } @@ -101,10 +107,13 @@ struct UnreadState { chats -= other.chats; chatsMuted -= other.chatsMuted; chatsTopic -= other.chatsTopic; + chatsTopicMuted -= other.chatsTopicMuted; marks -= other.marks; marksMuted -= other.marksMuted; reactions -= other.reactions; reactionsMuted -= other.reactionsMuted; + forums -= other.forums; + forumsMuted -= other.forumsMuted; mentions -= other.mentions; return *this; } diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index 56ca12032..8c9be9ce7 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -81,6 +81,17 @@ using UpdateFlag = Data::HistoryUpdate::Flag; return fields; } +[[nodiscard]] Dialogs::UnreadState AdjustedForumUnreadState( + Dialogs::UnreadState state) { + if (state.chatsTopic) { + state.forums = 1; + if (state.chatsTopic == state.chatsTopicMuted) { + state.forumsMuted = 1; + } + } + return state; +} + } // namespace History::History(not_null owner, PeerId peerId) @@ -2195,7 +2206,7 @@ History *History::migrateSibling() const { Dialogs::UnreadState History::chatListUnreadState() const { if (const auto forum = peer->forum()) { - return forum->topicsList()->unreadState(); + return AdjustedForumUnreadState(forum->topicsList()->unreadState()); } return computeUnreadState(); } @@ -2204,7 +2215,7 @@ Dialogs::BadgesState History::chatListBadgesState() const { if (const auto forum = peer->forum()) { return adjustBadgesStateByFolder( Dialogs::BadgesForUnread( - forum->topicsList()->unreadState(), + AdjustedForumUnreadState(forum->topicsList()->unreadState()), Dialogs::CountInBadge::Chats, Dialogs::IncludeInBadge::UnmutedOrAll)); } @@ -3068,7 +3079,7 @@ const Data::Thread *History::threadFor(MsgId topicRootId) const { void History::forumChanged(Data::Forum *old) { if (inChatList()) { notifyUnreadStateChange(old - ? old->topicsList()->unreadState() + ? AdjustedForumUnreadState(old->topicsList()->unreadState()) : computeUnreadState()); } @@ -3078,7 +3089,8 @@ void History::forumChanged(Data::Forum *old) { forum->topicsList()->unreadStateChanges( ) | rpl::filter([=] { return (_flags & Flag::IsForum) && inChatList(); - }) | rpl::start_with_next([=](const Dialogs::UnreadState &old) { + }) | rpl::map(AdjustedForumUnreadState + ) | rpl::start_with_next([=](const Dialogs::UnreadState &old) { notifyUnreadStateChange(old); }, forum->lifetime()); diff --git a/Telegram/SourceFiles/ui/widgets/chat_filters_tabs_strip.cpp b/Telegram/SourceFiles/ui/widgets/chat_filters_tabs_strip.cpp index 65e9a9de8..5bb72e1d6 100644 --- a/Telegram/SourceFiles/ui/widgets/chat_filters_tabs_strip.cpp +++ b/Telegram/SourceFiles/ui/widgets/chat_filters_tabs_strip.cpp @@ -338,9 +338,14 @@ not_null AddChatFiltersTabsStrip( const Dialogs::UnreadState &state, bool includeMuted) { const auto chats = state.chatsTopic - ? (state.chats - state.chatsTopic + 1) + ? (state.chats - state.chatsTopic + state.forums) : state.chats; - const auto muted = (state.chatsMuted + state.marksMuted); + const auto chatsMuted = state.chatsTopicMuted + ? (state.chatsMuted + - state.chatsTopicMuted + + state.forumsMuted) + : state.chatsMuted; + const auto muted = (chatsMuted + state.marksMuted); const auto count = (chats + state.marks) - (includeMuted ? 0 : muted); const auto isMuted = includeMuted && (count == muted); diff --git a/Telegram/SourceFiles/window/window_filters_menu.cpp b/Telegram/SourceFiles/window/window_filters_menu.cpp index d5d2fdd99..db1f15b35 100644 --- a/Telegram/SourceFiles/window/window_filters_menu.cpp +++ b/Telegram/SourceFiles/window/window_filters_menu.cpp @@ -271,9 +271,14 @@ base::unique_qptr FiltersMenu::prepareButton( const Dialogs::UnreadState &state, bool includeMuted) { const auto chats = state.chatsTopic - ? (state.chats - state.chatsTopic + 1) + ? (state.chats - state.chatsTopic + state.forums) : state.chats; - const auto muted = (state.chatsMuted + state.marksMuted); + const auto chatsMuted = state.chatsTopicMuted + ? (state.chatsMuted + - state.chatsTopicMuted + + state.forumsMuted) + : state.chatsMuted; + const auto muted = (chatsMuted + state.marksMuted); const auto count = (chats + state.marks) - (includeMuted ? 0 : muted); const auto string = !count From bf07b832f0d448fb19930bc0b47ae431a06ac7c1 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 27 Nov 2024 09:42:00 +0300 Subject: [PATCH 034/294] Replaced header in credits settings for credits history with subtitle. --- Telegram/SourceFiles/settings/settings_credits.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/Telegram/SourceFiles/settings/settings_credits.cpp b/Telegram/SourceFiles/settings/settings_credits.cpp index f22b94a7c..a407e7ad1 100644 --- a/Telegram/SourceFiles/settings/settings_credits.cpp +++ b/Telegram/SourceFiles/settings/settings_credits.cpp @@ -235,14 +235,10 @@ void Credits::setupHistory(not_null container) { const auto outTabText = tr::lng_credits_summary_history_tab_out( tr::now); if (hasOneTab) { - Ui::AddSkip(inner); - const auto header = inner->add( - object_ptr(inner), - st::statisticsLayerMargins - + st::boostsChartHeaderPadding); - header->resizeToWidth(header->width()); - header->setTitle(fullTabText); - header->setSubTitle({}); + Ui::AddSubsectionTitle( + inner, + tr::lng_credits_summary_history_tab_full(), + { 0, 0, 0, -st::defaultSubsectionTitlePadding.bottom() }); } const auto slider = inner->add( From eb821c1f360d622a503e0f459b400b8d62ef6631 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 27 Nov 2024 11:58:34 +0300 Subject: [PATCH 035/294] Improved display of unread badges in dialogs list with narrowed mode. --- .../SourceFiles/dialogs/ui/dialogs_layout.cpp | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp index f78d9dc09..d0324d3f2 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp @@ -140,8 +140,9 @@ int PaintBadges( BadgesState badgesState, int right, int top, - bool displayPinnedIcon = false, - int pinnedIconTop = 0) { + bool displayPinnedIcon, + int pinnedIconTop, + bool narrow) { auto initial = right; if (const auto used = PaintRightButton(p, context)) { return used - st::dialogsUnreadPadding; @@ -175,9 +176,16 @@ int PaintBadges( st.active = context.active; st.selected = context.selected; st.muted = badgesState.unreadMuted; - const auto counter = (badgesState.unreadCounter > 0) + const auto counter = (badgesState.unreadCounter <= 0) + ? QString() + : !narrow ? QString::number(badgesState.unreadCounter) - : QString(); + : ((badgesState.mention || badgesState.reaction) + && (badgesState.unreadCounter > 999)) + ? (u"99+"_q) + : (badgesState.unreadCounter > 999999) + ? (u"99999+"_q) + : QString::number(badgesState.unreadCounter); const auto badge = PaintUnreadBadge(p, counter, right, top, st); right -= badge.width() + st.padding; } else if (displayPinnedIcon) { @@ -241,7 +249,10 @@ void PaintNarrowCounter( context, badgesState, context.st->padding.left() + context.st->photoSize, - top); + top, + false, + 0, + true); } int PaintWideCounter( @@ -262,7 +273,8 @@ int PaintWideCounter( context.width - context.st->padding.right(), top, displayPinnedIcon, - texttop); + texttop, + false); return availableWidth - used; } From 4e8e096fdb6581c2b2051c65632c72ae41e1fee3 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 27 Nov 2024 12:16:37 +0300 Subject: [PATCH 036/294] Removed display of corner badges in narrowed mode when entry has unread. --- Telegram/SourceFiles/dialogs/dialogs_row.cpp | 17 +++++++++++------ Telegram/SourceFiles/dialogs/dialogs_row.h | 9 ++++++--- .../SourceFiles/dialogs/ui/dialogs_layout.cpp | 12 +++++++++++- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/Telegram/SourceFiles/dialogs/dialogs_row.cpp b/Telegram/SourceFiles/dialogs/dialogs_row.cpp index 8f974aa09..a9dae4d96 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_row.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_row.cpp @@ -302,7 +302,8 @@ void BasicRow::paintUserpic( not_null entry, PeerData *peer, Ui::VideoUserpic *videoUserpic, - const Ui::PaintContext &context) const { + const Ui::PaintContext &context, + bool hasUnreadBadgesAbove) const { PaintUserpic(p, entry, peer, videoUserpic, _userpic, context); } @@ -371,12 +372,15 @@ void Row::setCornerBadgeShown( void Row::updateCornerBadgeShown( not_null peer, - Fn updateCallback) const { + Fn updateCallback, + bool hasUnreadBadgesAbove) const { const auto user = peer->asUser(); const auto now = user ? base::unixtime::now() : TimeId(); const auto channel = user ? nullptr : peer->asChannel(); const auto nextLayer = [&] { - if (user && Data::IsUserOnline(user, now)) { + if (hasUnreadBadgesAbove) { + return kNoneLayer; + } else if (user && Data::IsUserOnline(user, now)) { return kTopLayer; } else if (channel && (Data::ChannelHasActiveCall(channel) @@ -533,9 +537,10 @@ void Row::paintUserpic( not_null entry, PeerData *peer, Ui::VideoUserpic *videoUserpic, - const Ui::PaintContext &context) const { + const Ui::PaintContext &context, + bool hasUnreadBadgesAbove) const { if (peer) { - updateCornerBadgeShown(peer); + updateCornerBadgeShown(peer, nullptr, hasUnreadBadgesAbove); } const auto cornerBadgeShown = !_cornerBadgeUserpic @@ -551,7 +556,7 @@ void Row::paintUserpic( ? storiesFolder->storiesCount() : false; if (!cornerBadgeShown && !storiesHas) { - BasicRow::paintUserpic(p, entry, peer, videoUserpic, context); + BasicRow::paintUserpic(p, entry, peer, videoUserpic, context, false); if (!peer || !_cornerBadgeShown) { _cornerBadgeUserpic = nullptr; } diff --git a/Telegram/SourceFiles/dialogs/dialogs_row.h b/Telegram/SourceFiles/dialogs/dialogs_row.h index b5181ba66..3850b880e 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_row.h +++ b/Telegram/SourceFiles/dialogs/dialogs_row.h @@ -51,7 +51,8 @@ public: not_null entry, PeerData *peer, Ui::VideoUserpic *videoUserpic, - const Ui::PaintContext &context) const; + const Ui::PaintContext &context, + bool hasUnreadBadgesAbove) const; void addRipple(QPoint origin, QSize size, Fn updateCallback); virtual void stopLastRipple(); @@ -98,13 +99,15 @@ public: void updateCornerBadgeShown( not_null peer, - Fn updateCallback = nullptr) const; + Fn updateCallback = nullptr, + bool hasUnreadBadgesAbove = false) const; void paintUserpic( Painter &p, not_null entry, PeerData *peer, Ui::VideoUserpic *videoUserpic, - const Ui::PaintContext &context) const final override; + const Ui::PaintContext &context, + bool hasUnreadBadgesAbove) const final override; [[nodiscard]] bool lookupIsInTopicJump(int x, int y) const; void stopLastRipple() override; diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp index d0324d3f2..fc911b90f 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp @@ -405,7 +405,17 @@ void PaintRow( row->userpicView(), context); } else { - row->paintUserpic(p, entry, from, videoUserpic, context); + row->paintUserpic( + p, + entry, + from, + videoUserpic, + context, + context.narrow + && !badgesState.empty() + && !draft + && item + && !item->isEmpty()); } const auto nameleft = context.st->nameLeft; From a405794a03eceb50429fdd4ca370b47455862274 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 27 Nov 2024 12:25:18 +0300 Subject: [PATCH 037/294] Allowed to display of hundreds digit in unread badge of filters. --- Telegram/SourceFiles/ui/widgets/chat_filters_tabs_slider.cpp | 2 +- Telegram/SourceFiles/window/window_filters_menu.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Telegram/SourceFiles/ui/widgets/chat_filters_tabs_slider.cpp b/Telegram/SourceFiles/ui/widgets/chat_filters_tabs_slider.cpp index b2286be5f..a6e9bf284 100644 --- a/Telegram/SourceFiles/ui/widgets/chat_filters_tabs_slider.cpp +++ b/Telegram/SourceFiles/ui/widgets/chat_filters_tabs_slider.cpp @@ -174,7 +174,7 @@ QImage ChatsFiltersTabs::cacheUnreadCount(int count, bool muted) const { QImage::Format_ARGB32_Premultiplied); image.setDevicePixelRatio(style::DevicePixelRatio()); image.fill(Qt::transparent); - const auto string = (count > 99) + const auto string = (count > 999) ? _unreadMaxString : QString::number(count); { diff --git a/Telegram/SourceFiles/window/window_filters_menu.cpp b/Telegram/SourceFiles/window/window_filters_menu.cpp index db1f15b35..3a2feb240 100644 --- a/Telegram/SourceFiles/window/window_filters_menu.cpp +++ b/Telegram/SourceFiles/window/window_filters_menu.cpp @@ -283,7 +283,7 @@ base::unique_qptr FiltersMenu::prepareButton( - (includeMuted ? 0 : muted); const auto string = !count ? QString() - : (count > 99) + : (count > 999) ? "99+" : QString::number(count); raw->setBadge(string, includeMuted && (count == muted)); From 7f85494b1d1c357260860437bf386a77722040a1 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 27 Nov 2024 14:27:31 +0300 Subject: [PATCH 038/294] Moved out UnreadState to td_ui. --- Telegram/SourceFiles/dialogs/dialogs_common.h | 136 ++++++++++++++++++ Telegram/SourceFiles/dialogs/dialogs_entry.h | 124 +--------------- .../dialogs/dialogs_indexed_list.h | 4 +- .../SourceFiles/dialogs/dialogs_main_list.h | 1 + .../dialogs/ui/dialogs_video_userpic.cpp | 1 + Telegram/cmake/td_ui.cmake | 1 + 6 files changed, 146 insertions(+), 121 deletions(-) create mode 100644 Telegram/SourceFiles/dialogs/dialogs_common.h diff --git a/Telegram/SourceFiles/dialogs/dialogs_common.h b/Telegram/SourceFiles/dialogs/dialogs_common.h new file mode 100644 index 000000000..d3e16f898 --- /dev/null +++ b/Telegram/SourceFiles/dialogs/dialogs_common.h @@ -0,0 +1,136 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +namespace Ui { +class RippleAnimation; +} // namespace Ui + +namespace Dialogs { + +class Row; + +enum class SortMode { + Date = 0x00, + Name = 0x01, + Add = 0x02, +}; + +struct PositionChange { + int from = -1; + int to = -1; + int height = 0; +}; + +struct UnreadState { + int messages = 0; + int messagesMuted = 0; + int chats = 0; + int chatsMuted = 0; + int chatsTopic = 0; + int chatsTopicMuted = 0; + int marks = 0; + int marksMuted = 0; + int reactions = 0; + int reactionsMuted = 0; + int forums = 0; + int forumsMuted = 0; + int mentions = 0; + bool known = false; + + UnreadState &operator+=(const UnreadState &other) { + messages += other.messages; + messagesMuted += other.messagesMuted; + chats += other.chats; + chatsMuted += other.chatsMuted; + chatsTopic += other.chatsTopic; + chatsTopicMuted += other.chatsTopicMuted; + marks += other.marks; + marksMuted += other.marksMuted; + reactions += other.reactions; + reactionsMuted += other.reactionsMuted; + forums += other.forums; + forumsMuted += other.forumsMuted; + mentions += other.mentions; + return *this; + } + UnreadState &operator-=(const UnreadState &other) { + messages -= other.messages; + messagesMuted -= other.messagesMuted; + chats -= other.chats; + chatsMuted -= other.chatsMuted; + chatsTopic -= other.chatsTopic; + chatsTopicMuted -= other.chatsTopicMuted; + marks -= other.marks; + marksMuted -= other.marksMuted; + reactions -= other.reactions; + reactionsMuted -= other.reactionsMuted; + forums -= other.forums; + forumsMuted -= other.forumsMuted; + mentions -= other.mentions; + return *this; + } +}; + +inline UnreadState operator+(const UnreadState &a, const UnreadState &b) { + auto result = a; + result += b; + return result; +} + +inline UnreadState operator-(const UnreadState &a, const UnreadState &b) { + auto result = a; + result -= b; + return result; +} + +struct BadgesState { + int unreadCounter = 0; + bool unread : 1 = false; + bool unreadMuted : 1 = false; + bool mention : 1 = false; + bool mentionMuted : 1 = false; + bool reaction : 1 = false; + bool reactionMuted : 1 = false; + + friend inline constexpr auto operator<=>( + BadgesState, + BadgesState) = default; + + [[nodiscard]] bool empty() const { + return !unread && !mention && !reaction; + } +}; + +enum class CountInBadge : uchar { + Default, + Chats, + Messages, +}; + +enum class IncludeInBadge : uchar { + Default, + Unmuted, + All, + UnmutedOrAll, +}; + +struct RowsByLetter { + not_null main; + base::flat_map> letters; +}; + +struct RightButton final { + QImage bg; + QImage selectedBg; + QImage activeBg; + Ui::Text::String text; + std::unique_ptr ripple; +}; + +} // namespace Dialogs diff --git a/Telegram/SourceFiles/dialogs/dialogs_entry.h b/Telegram/SourceFiles/dialogs/dialogs_entry.h index 83935c5ba..e52b45048 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_entry.h +++ b/Telegram/SourceFiles/dialogs/dialogs_entry.h @@ -10,10 +10,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/flat_map.h" #include "base/weak_ptr.h" #include "base/flags.h" -#include "dialogs/dialogs_key.h" +#include "dialogs/dialogs_common.h" #include "ui/unread_badge.h" class HistoryItem; +class History; class UserData; namespace Main { @@ -26,10 +27,10 @@ class Forum; class Folder; class ForumTopic; class SavedSublist; +class Thread; } // namespace Data namespace Ui { -class RippleAnimation; struct PeerUserpicView; } // namespace Ui @@ -40,128 +41,11 @@ struct PaintContext; namespace Dialogs { +struct UnreadState; class Row; class IndexedList; class MainList; -struct RightButton final { - QImage bg; - QImage selectedBg; - QImage activeBg; - Ui::Text::String text; - std::unique_ptr ripple; -}; - -struct RowsByLetter { - not_null main; - base::flat_map> letters; -}; - -enum class SortMode { - Date = 0x00, - Name = 0x01, - Add = 0x02, -}; - -struct PositionChange { - int from = -1; - int to = -1; - int height = 0; -}; - -struct UnreadState { - int messages = 0; - int messagesMuted = 0; - int chats = 0; - int chatsMuted = 0; - int chatsTopic = 0; - int chatsTopicMuted = 0; - int marks = 0; - int marksMuted = 0; - int reactions = 0; - int reactionsMuted = 0; - int forums = 0; - int forumsMuted = 0; - int mentions = 0; - bool known = false; - - UnreadState &operator+=(const UnreadState &other) { - messages += other.messages; - messagesMuted += other.messagesMuted; - chats += other.chats; - chatsMuted += other.chatsMuted; - chatsTopic += other.chatsTopic; - chatsTopicMuted += other.chatsTopicMuted; - marks += other.marks; - marksMuted += other.marksMuted; - reactions += other.reactions; - reactionsMuted += other.reactionsMuted; - forums += other.forums; - forumsMuted += other.forumsMuted; - mentions += other.mentions; - return *this; - } - UnreadState &operator-=(const UnreadState &other) { - messages -= other.messages; - messagesMuted -= other.messagesMuted; - chats -= other.chats; - chatsMuted -= other.chatsMuted; - chatsTopic -= other.chatsTopic; - chatsTopicMuted -= other.chatsTopicMuted; - marks -= other.marks; - marksMuted -= other.marksMuted; - reactions -= other.reactions; - reactionsMuted -= other.reactionsMuted; - forums -= other.forums; - forumsMuted -= other.forumsMuted; - mentions -= other.mentions; - return *this; - } -}; - -inline UnreadState operator+(const UnreadState &a, const UnreadState &b) { - auto result = a; - result += b; - return result; -} - -inline UnreadState operator-(const UnreadState &a, const UnreadState &b) { - auto result = a; - result -= b; - return result; -} - -struct BadgesState { - int unreadCounter = 0; - bool unread : 1 = false; - bool unreadMuted : 1 = false; - bool mention : 1 = false; - bool mentionMuted : 1 = false; - bool reaction : 1 = false; - bool reactionMuted : 1 = false; - - friend inline constexpr auto operator<=>( - BadgesState, - BadgesState) = default; - - [[nodiscard]] bool empty() const { - return !unread && !mention && !reaction; - } -}; - -enum class CountInBadge : uchar { - Default, - Chats, - Messages, -}; - -enum class IncludeInBadge : uchar { - Default, - Unmuted, - All, - UnmutedOrAll, -}; - [[nodiscard]] BadgesState BadgesForUnread( const UnreadState &state, CountInBadge count = CountInBadge::Default, diff --git a/Telegram/SourceFiles/dialogs/dialogs_indexed_list.h b/Telegram/SourceFiles/dialogs/dialogs_indexed_list.h index 62128d92e..dfdf3b1de 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_indexed_list.h +++ b/Telegram/SourceFiles/dialogs/dialogs_indexed_list.h @@ -7,13 +7,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once -#include "dialogs/dialogs_entry.h" #include "dialogs/dialogs_list.h" class History; namespace Dialogs { +struct RowsByLetter; +class Row; + class IndexedList { public: IndexedList(SortMode sortMode, FilterId filterId = 0); diff --git a/Telegram/SourceFiles/dialogs/dialogs_main_list.h b/Telegram/SourceFiles/dialogs/dialogs_main_list.h index 157e48e31..1a5f86c3a 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_main_list.h +++ b/Telegram/SourceFiles/dialogs/dialogs_main_list.h @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once +#include "dialogs/dialogs_common.h" #include "dialogs/dialogs_indexed_list.h" #include "dialogs/dialogs_pinned_list.h" diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_video_userpic.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_video_userpic.cpp index 188d512e8..9f970a30d 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_video_userpic.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_video_userpic.cpp @@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_photo_media.h" #include "data/data_file_origin.h" #include "data/data_session.h" +#include "dialogs/dialogs_entry.h" #include "dialogs/ui/dialogs_layout.h" #include "ui/painter.h" #include "styles/style_dialogs.h" diff --git a/Telegram/cmake/td_ui.cmake b/Telegram/cmake/td_ui.cmake index 54d8bc92b..fa35b57d9 100644 --- a/Telegram/cmake/td_ui.cmake +++ b/Telegram/cmake/td_ui.cmake @@ -95,6 +95,7 @@ PRIVATE data/data_statistics_chart.h data/data_subscriptions.h + dialogs/dialogs_common.h dialogs/dialogs_three_state_icon.h dialogs/ui/chat_search_empty.cpp dialogs/ui/chat_search_empty.h From 339d7be9c1aa488780ef85352c8c5803c068ffd5 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 27 Nov 2024 14:38:06 +0300 Subject: [PATCH 039/294] Removed unused include directives from Application. --- Telegram/SourceFiles/core/application.cpp | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp index c12747322..44dd9df17 100644 --- a/Telegram/SourceFiles/core/application.cpp +++ b/Telegram/SourceFiles/core/application.cpp @@ -9,13 +9,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_abstract_structure.h" #include "data/data_forum.h" -#include "data/data_photo.h" -#include "data/data_document.h" #include "data/data_message_reactions.h" #include "data/data_session.h" -#include "data/data_stories.h" -#include "data/data_user.h" -#include "data/data_channel.h" #include "data/data_download_manager.h" #include "base/battery_saving.h" #include "base/event_filter.h" @@ -33,15 +28,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/ui_integration.h" #include "chat_helpers/emoji_keywords.h" #include "chat_helpers/stickers_emoji_image_loader.h" -#include "base/qt/qt_common_adapters.h" #include "base/platform/base_platform_global_shortcuts.h" #include "base/platform/base_platform_url_scheme.h" #include "base/platform/base_platform_last_input.h" #include "base/platform/base_platform_info.h" #include "platform/platform_specific.h" #include "platform/platform_integration.h" -#include "mainwindow.h" -#include "dialogs/dialogs_entry.h" #include "history/history.h" #include "apiwrap.h" #include "api/api_updates.h" @@ -50,7 +42,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "iv/iv_delegate_impl.h" #include "iv/iv_instance.h" #include "iv/iv_data.h" -#include "lang/lang_file_parser.h" #include "lang/lang_translator.h" #include "lang/lang_cloud_manager.h" #include "lang/lang_hardcoded.h" @@ -58,7 +49,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "inline_bots/bot_attach_web_view.h" #include "mainwidget.h" #include "tray.h" -#include "core/file_utilities.h" #include "core/click_handler_types.h" // ClickHandlerContext. #include "core/crash_reports.h" #include "main/main_account.h" @@ -68,8 +58,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "media/view/media_view_open_common.h" #include "mtproto/mtproto_dc_options.h" #include "mtproto/mtproto_config.h" -#include "mtproto/mtp_instance.h" -#include "media/audio/media_audio.h" #include "media/audio/media_audio_track.h" #include "media/player/media_player_instance.h" #include "media/player/media_player_float.h" @@ -77,18 +65,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "media/system_media_controls_manager.h" #include "window/notifications_manager.h" #include "window/themes/window_theme.h" -#include "window/window_lock_widgets.h" -#include "history/history_location_manager.h" #include "ui/widgets/tooltip.h" #include "ui/gl/gl_detection.h" -#include "ui/image/image.h" #include "ui/text/text_options.h" -#include "ui/emoji_config.h" -#include "ui/effects/animations.h" #include "ui/effects/spoiler_mess.h" #include "ui/cached_round_corners.h" #include "ui/power_saving.h" -#include "storage/serialize_common.h" #include "storage/storage_domain.h" #include "storage/storage_databases.h" #include "storage/localstorage.h" @@ -101,7 +83,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/abstract_box.h" #include "base/qthelp_regex.h" #include "base/qthelp_url.h" -#include "boxes/connection_box.h" #include "boxes/premium_limits_box.h" #include "ui/boxes/confirm_box.h" #include "styles/style_window.h" From 5d71286000f6ae6aad6e0aaa5808baa8a6c29380 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 27 Nov 2024 15:01:46 +0300 Subject: [PATCH 040/294] Fixed display of title in sponsored messages with shorter description. --- .../SourceFiles/history/view/media/history_view_web_page.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp b/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp index 90aa91503..9437fa3b0 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp @@ -1077,7 +1077,7 @@ void WebPage::draw(Painter &p, const PaintContext &context) const { ? _parent->skipBlockWidth() : 0; const auto titleWidth = sponsored - ? (paintw - _pixh - st::webPagePhotoDelta) + ? (paintw - (_pixh ? (_pixh - st::webPagePhotoDelta) : 0)) : paintw; _title.drawLeftElided( p, From 3071daa6f38c7aa2e335678857e7c61f25e6970e Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 27 Nov 2024 15:45:25 +0300 Subject: [PATCH 041/294] Replaced header style in statistics sections with classic subsections. --- Telegram/SourceFiles/info/bot/earn/info_bot_earn_list.cpp | 2 -- .../SourceFiles/info/channel_statistics/earn/channel_earn.style | 1 + .../info/channel_statistics/earn/info_channel_earn_list.cpp | 1 - Telegram/SourceFiles/statistics/statistics.style | 2 +- Telegram/SourceFiles/statistics/widgets/chart_header_widget.cpp | 2 +- 5 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Telegram/SourceFiles/info/bot/earn/info_bot_earn_list.cpp b/Telegram/SourceFiles/info/bot/earn/info_bot_earn_list.cpp index 7b2072cda..b96427bca 100644 --- a/Telegram/SourceFiles/info/bot/earn/info_bot_earn_list.cpp +++ b/Telegram/SourceFiles/info/bot/earn/info_bot_earn_list.cpp @@ -143,7 +143,6 @@ void InnerWidget::fill() { Ui::AddSkip(container); Ui::AddDivider(container); Ui::AddSkip(container); - Ui::AddSkip(container); } { AddHeader(container, tr::lng_bot_earn_overview_title); @@ -279,7 +278,6 @@ void InnerWidget::fillHistory() { const auto outTabText = tr::lng_credits_summary_history_tab_out( tr::now); if (hasOneTab) { - Ui::AddSkip(inner); const auto header = inner->add( object_ptr(inner), st::statisticsLayerMargins diff --git a/Telegram/SourceFiles/info/channel_statistics/earn/channel_earn.style b/Telegram/SourceFiles/info/channel_statistics/earn/channel_earn.style index 15df2c282..5d68e501b 100644 --- a/Telegram/SourceFiles/info/channel_statistics/earn/channel_earn.style +++ b/Telegram/SourceFiles/info/channel_statistics/earn/channel_earn.style @@ -37,6 +37,7 @@ channelEarnSemiboldLabel: FlatLabel(channelEarnOverviewMajorLabel) { channelEarnHeaderLabel: FlatLabel(channelEarnOverviewMajorLabel) { style: TextStyle(statisticsHeaderTitleTextStyle) { } + textFg: windowActiveTextFg; } channelEarnHistorySubLabel: FlatLabel(channelEarnOverviewSubMinorLabel) { style: TextStyle(defaultTextStyle) { diff --git a/Telegram/SourceFiles/info/channel_statistics/earn/info_channel_earn_list.cpp b/Telegram/SourceFiles/info/channel_statistics/earn/info_channel_earn_list.cpp index 3a2250f39..08687b9c0 100644 --- a/Telegram/SourceFiles/info/channel_statistics/earn/info_channel_earn_list.cpp +++ b/Telegram/SourceFiles/info/channel_statistics/earn/info_channel_earn_list.cpp @@ -1014,7 +1014,6 @@ void InnerWidget::fill() { listsContainer, tr::lng_channel_earn_credits_history); slider->entity()->setActiveSectionFast(1); - AddSkip(listsContainer); } } else { slider->entity()->setActiveSectionFast(*sectionIndex); diff --git a/Telegram/SourceFiles/statistics/statistics.style b/Telegram/SourceFiles/statistics/statistics.style index 882623394..8cc22a9b9 100644 --- a/Telegram/SourceFiles/statistics/statistics.style +++ b/Telegram/SourceFiles/statistics/statistics.style @@ -59,7 +59,7 @@ statisticsPieChartPartOffset: 8px; statisticsChartHeaderHeight: 36px; statisticsChartHeaderPadding: margins(2px, 0px, 0px, 10px); statisticsHeaderTitleTextStyle: TextStyle(defaultTextStyle) { - font: font(13px); + font: font(boxFontSize semibold); } statisticsHeaderDatesTextStyle: TextStyle(defaultTextStyle) { font: font(11px); diff --git a/Telegram/SourceFiles/statistics/widgets/chart_header_widget.cpp b/Telegram/SourceFiles/statistics/widgets/chart_header_widget.cpp index f22cffcee..b8754ceb6 100644 --- a/Telegram/SourceFiles/statistics/widgets/chart_header_widget.cpp +++ b/Telegram/SourceFiles/statistics/widgets/chart_header_widget.cpp @@ -43,7 +43,7 @@ void Header::paintEvent(QPaintEvent *e) { p.fillRect(rect(), st::boxBg); - p.setPen(st::boxTextFg); + p.setPen(st::windowActiveTextFg); _title.drawLeftElided(p, 0, 0, width(), width()); p.setPen(st::windowSubTextFg); From e82506e0c48a5551b72861e1f355c42efdbca9a8 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Thu, 28 Nov 2024 12:27:59 +0300 Subject: [PATCH 042/294] Added ministars to button in service messages for premium requirements. --- .../SourceFiles/history/view/history_view_about_view.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Telegram/SourceFiles/history/view/history_view_about_view.cpp b/Telegram/SourceFiles/history/view/history_view_about_view.cpp index 3e6a46bc8..12a98949a 100644 --- a/Telegram/SourceFiles/history/view/history_view_about_view.cpp +++ b/Telegram/SourceFiles/history/view/history_view_about_view.cpp @@ -53,6 +53,7 @@ public: TextWithEntities subtitle() override; int buttonSkip() override; rpl::producer button() override; + bool buttonMinistars() override; void draw( Painter &p, const PaintContext &context, @@ -168,6 +169,10 @@ rpl::producer PremiumRequiredBox::button() { return tr::lng_send_non_premium_go(); } +bool PremiumRequiredBox::buttonMinistars() { + return true; +} + TextWithEntities PremiumRequiredBox::subtitle() { return _parent->data()->notificationText(); } From f2ed64969499ae60d8f658d53e209d2e6c2100b1 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Thu, 28 Nov 2024 14:28:21 +0300 Subject: [PATCH 043/294] Fixed focus capture from compose search widget. --- .../view/controls/history_view_compose_search.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Telegram/SourceFiles/history/view/controls/history_view_compose_search.cpp b/Telegram/SourceFiles/history/view/controls/history_view_compose_search.cpp index cc4463594..9e98ae7c7 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_compose_search.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_search.cpp @@ -31,6 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/widgets/shadow.h" #include "ui/widgets/scroll_area.h" #include "ui/painter.h" +#include "ui/ui_utility.h" #include "window/window_session_controller.h" #include "styles/style_boxes.h" #include "styles/style_chat.h" @@ -389,7 +390,9 @@ rpl::producer> TopBar::keyEvents() const { } void TopBar::setInnerFocus() { - _select->setInnerFocus(); + if (Ui::InFocusChain(_select)) { + _select->setInnerFocus(); + } } void TopBar::updateSize() { @@ -1032,7 +1035,9 @@ ComposeSearch::Inner::Inner( } void ComposeSearch::Inner::setInnerFocus() { - _topBar->setInnerFocus(); + if (Ui::InFocusChain(_topBar)) { + _topBar->setInnerFocus(); + } } void ComposeSearch::Inner::setQuery(const QString &query) { From 475dec30149189c36b66bbdc596d2dfaa479746d Mon Sep 17 00:00:00 2001 From: John Preston Date: Sun, 24 Nov 2024 17:49:15 +0400 Subject: [PATCH 044/294] Allow adding media to text with a link preview. --- .../SourceFiles/boxes/edit_caption_box.cpp | 2 +- Telegram/SourceFiles/history/history_item.cpp | 2 +- .../SourceFiles/history/history_widget.cpp | 2 +- .../history_view_compose_controls.cpp | 2 +- .../info/channels/info_channels_widget.cpp | 97 ------------------- .../info/channels/info_channels_widget.h | 74 -------------- 6 files changed, 4 insertions(+), 175 deletions(-) delete mode 100644 Telegram/SourceFiles/info/channels/info_channels_widget.cpp delete mode 100644 Telegram/SourceFiles/info/channels/info_channels_widget.h diff --git a/Telegram/SourceFiles/boxes/edit_caption_box.cpp b/Telegram/SourceFiles/boxes/edit_caption_box.cpp index f6e48b221..ae2cbc3d7 100644 --- a/Telegram/SourceFiles/boxes/edit_caption_box.cpp +++ b/Telegram/SourceFiles/boxes/edit_caption_box.cpp @@ -254,7 +254,7 @@ EditCaptionBox::EditCaptionBox( , _initialList(std::move(list)) , _saved(std::move(saved)) { Expects(!_initialList.files.empty()); - Expects(!item->media() || item->media()->allowsEditCaption()); + Expects(item->allowsEditMedia()); _mediaEditManager.start(item, spoilered, invertCaption); diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index 2c566ab1a..a63b7b6c3 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -2244,7 +2244,7 @@ bool HistoryItem::allowsEdit(TimeId now) const { bool HistoryItem::allowsEditMedia() const { return !awaitingVideoProcessing() - && (!_media || _media->allowsEditMedia()); + && (!_media || _media->allowsEditMedia() || _media->webpage()); } bool HistoryItem::canBeEdited() const { diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index f9f3445de..49fea20a1 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -8555,7 +8555,7 @@ void HistoryWidget::updateReplyEditTexts(bool force) { _mediaEditManager.start(_replyEditMsg); } _canReplaceMedia = _editMsgId && _replyEditMsg->allowsEditMedia(); - if (editMedia) { + if (editMedia && editMedia->allowsEditMedia()) { _canAddMedia = false; } else { _canAddMedia = base::take(_canReplaceMedia); diff --git a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp index a2eefd668..0196405c9 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp @@ -1960,7 +1960,7 @@ void ComposeControls::applyDraft(FieldHistoryAction fieldHistoryAction) { if (const auto item = _history->owner().message(editingId)) { const auto media = item->media(); _canReplaceMedia = item->allowsEditMedia(); - if (media) { + if (media && media->allowsEditMedia()) { _canAddMedia = false; } else { _canAddMedia = base::take(_canReplaceMedia); diff --git a/Telegram/SourceFiles/info/channels/info_channels_widget.cpp b/Telegram/SourceFiles/info/channels/info_channels_widget.cpp deleted file mode 100644 index 3b6c115a1..000000000 --- a/Telegram/SourceFiles/info/channels/info_channels_widget.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* -This file is part of Telegram Desktop, -the official desktop application for the Telegram messaging service. - -For license and copyright information please follow this link: -https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL -*/ -#include "info/channels/info_channels_widget.h" - -#include "info/feed/info_feed_channels.h" -#include "info/info_controller.h" -#include "ui/widgets/scroll_area.h" -#include "styles/style_info.h" - -namespace Info { -namespace Channels { - -Memento::Memento(not_null controller) -: Memento(controller->feed()) { -} - -Memento::Memento(not_null feed) -: ContentMemento(feed) { -} - -Section Memento::section() const { - return Section(Section::Type::Channels); -} - -object_ptr Memento::createWidget( - QWidget *parent, - not_null controller, - const QRect &geometry) { - auto result = object_ptr( - parent, - controller); - result->setInternalState(geometry, this); - return result; -} - -void Memento::setState(std::unique_ptr state) { - _state = std::move(state); -} - -std::unique_ptr Memento::state() { - return std::move(_state); -} - -Memento::~Memento() = default; - -Widget::Widget( - QWidget *parent, - not_null controller) -: ContentWidget(parent, controller) { - _inner = setInnerWidget(object_ptr( - this, - controller)); -} - -bool Widget::showInternal(not_null memento) { - if (!controller()->validateMementoPeer(memento)) { - return false; - } - if (auto membersMemento = dynamic_cast(memento.get())) { - restoreState(membersMemento); - return true; - } - return false; -} - -void Widget::setInternalState( - const QRect &geometry, - not_null memento) { - setGeometry(geometry); - Ui::SendPendingMoveResizeEvents(this); - restoreState(memento); -} - -std::unique_ptr Widget::doCreateMemento() { - auto result = std::make_unique(controller()); - saveState(result.get()); - return result; -} - -void Widget::saveState(not_null memento) { - memento->setScrollTop(scrollTopSave()); - memento->setState(_inner->saveState()); -} - -void Widget::restoreState(not_null memento) { - _inner->restoreState(memento->state()); - auto scrollTop = memento->scrollTop(); - scrollTopRestore(memento->scrollTop()); -} - -} // namespace Channels -} // namespace Info diff --git a/Telegram/SourceFiles/info/channels/info_channels_widget.h b/Telegram/SourceFiles/info/channels/info_channels_widget.h deleted file mode 100644 index 431f94ec1..000000000 --- a/Telegram/SourceFiles/info/channels/info_channels_widget.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -This file is part of Telegram Desktop, -the official desktop application for the Telegram messaging service. - -For license and copyright information please follow this link: -https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL -*/ -#pragma once - -#include "info/info_content_widget.h" - -struct PeerListState; - -namespace Data { -class Feed; -} // namespace Data - -namespace Info { -namespace FeedProfile { -class Channels; -struct ChannelsState; -} // namespace FeedProfile - -namespace Channels { - -using SavedState = FeedProfile::ChannelsState; - -class Memento final : public ContentMemento { -public: - explicit Memento(not_null controller); - explicit Memento(not_null feed); - - object_ptr createWidget( - QWidget *parent, - not_null controller, - const QRect &geometry) override; - - Section section() const override; - - void setState(std::unique_ptr state); - std::unique_ptr state(); - - ~Memento(); - -private: - std::unique_ptr _state; - -}; - -class Widget final : public ContentWidget { -public: - Widget( - QWidget *parent, - not_null controller); - - bool showInternal( - not_null memento) override; - - void setInternalState( - const QRect &geometry, - not_null memento); - -private: - void saveState(not_null memento); - void restoreState(not_null memento); - - std::unique_ptr doCreateMemento() override; - - FeedProfile::Channels *_inner = nullptr; - -}; - -} // namespace Channels -} // namespace Info From e52baf555fb348ba70036ba56a2bf6d7a377a110 Mon Sep 17 00:00:00 2001 From: John Preston Date: Sun, 24 Nov 2024 17:51:12 +0400 Subject: [PATCH 045/294] Update video qualities list. --- Telegram/SourceFiles/history/history.cpp | 3 ++ Telegram/SourceFiles/history/history_item.cpp | 32 +++++++++++++++++++ Telegram/SourceFiles/history/history_item.h | 2 ++ 3 files changed, 37 insertions(+) diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index 8c9be9ce7..7f47ffe06 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -451,6 +451,9 @@ not_null History::createItem( if (detachExistingItem) { result->removeMainView(); } + if (result->needsUpdateForVideoQualities(message)) { + owner().updateEditedMessage(message); + } return result; } const auto result = message.match([&](const auto &data) { diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index a63b7b6c3..cc757bcd9 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -1303,6 +1303,38 @@ void HistoryItem::customEmojiRepaint() { } } +bool HistoryItem::needsUpdateForVideoQualities(const MTPMessage &data) { + // When video gets the converted alt-videos lists, we need to update + // the message data even without edit-message update. + return data.match([&](const MTPDmessage &data) { + const auto media = data.vmedia(); + if (!media) { + return false; + } + return media->match([&](const MTPDmessageMediaDocument &data) { + const auto document = data.vdocument(); + const auto alts = data.valt_documents(); + if (!document || !alts || alts->v.isEmpty()) { + return false; + } + const auto id = document->match([](const auto &data) { + return DocumentId(data.vid().v); + }); + const auto existingMedia = this->media(); + const auto existingDocument = existingMedia + ? existingMedia->document() + : nullptr; + return !existingDocument + || (existingDocument->id != id) + || existingDocument->resolveQualities(this).empty(); + }, [](const auto &) { + return false; + }); + }, [](const auto &) { + return false; + }); +} + void HistoryItem::finishEditionToEmpty() { finishEdition(-1); _history->itemVanished(this); diff --git a/Telegram/SourceFiles/history/history_item.h b/Telegram/SourceFiles/history/history_item.h index 9a17be15f..ac24b011a 100644 --- a/Telegram/SourceFiles/history/history_item.h +++ b/Telegram/SourceFiles/history/history_item.h @@ -553,6 +553,8 @@ public: [[nodiscard]] bool canUpdateDate() const; void customEmojiRepaint(); + [[nodiscard]] bool needsUpdateForVideoQualities(const MTPMessage &data); + [[nodiscard]] TimeId ttlDestroyAt() const { return _ttlDestroyAt; } From bddac79b401f329cd344a1cca3e9e8b0d10c8b7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Novomesk=C3=BD?= Date: Sun, 24 Nov 2024 13:16:51 +0100 Subject: [PATCH 046/294] Update kimageformats submodule --- Telegram/ThirdParty/kimageformats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Telegram/ThirdParty/kimageformats b/Telegram/ThirdParty/kimageformats index 106279d32..1e47a751d 160000 --- a/Telegram/ThirdParty/kimageformats +++ b/Telegram/ThirdParty/kimageformats @@ -1 +1 @@ -Subproject commit 106279d32ec4b93ccf5e29a92616e0f0cc8d2382 +Subproject commit 1e47a751df4468f1e0b4447b3bb3601c5eadb40c From f13740cb7f30787f492a187ee9a817c30740310e Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 28 Nov 2024 20:27:35 +0400 Subject: [PATCH 047/294] Update lib_webview. --- Telegram/lib_webview | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Telegram/lib_webview b/Telegram/lib_webview index 3dc2f15cd..93af01974 160000 --- a/Telegram/lib_webview +++ b/Telegram/lib_webview @@ -1 +1 @@ -Subproject commit 3dc2f15cd449305536bd3ed0d0f3152701ce36c5 +Subproject commit 93af01974107d3037b5194b635473201164c112e From 18aaf3cc9364257a5f7dd785455c2f6d05058001 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 28 Nov 2024 20:33:13 +0400 Subject: [PATCH 048/294] Fix build for MSVC. --- Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp | 2 +- Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp index fc911b90f..131c10399 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp @@ -125,8 +125,8 @@ int PaintRightButton(QPainter &p, const PaintContext &context) { .position = QPoint( left + size.height() / 2, top + (st::dialogRowOpenBotHeight - rightButton->text.minHeight()) / 2), - .availableWidth = size.width() - size.height() / 2, .outerWidth = size.width() - size.height() / 2, + .availableWidth = size.width() - size.height() / 2, .elisionLines = 1, }); return size.width() + st::dialogsUnreadPadding; diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp index 849a0c85c..88a5faea4 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp @@ -262,7 +262,6 @@ bool RecentRow::refreshBadge() { QSize RecentRow::rightActionSize() const { if (_mainAppText) { - const auto &font = st::dialogRowOpenBotTextStyle.font; return QSize( _mainAppText->maxWidth() + _mainAppText->minHeight(), st::dialogRowOpenBotHeight); @@ -314,8 +313,8 @@ void RecentRow::rightActionPaint( + (st::dialogRowOpenBotHeight - _mainAppText->minHeight()) / 2; _mainAppText->draw(p, { .position = QPoint(x + size.height() / 2, y + top), - .availableWidth = outerWidth, .outerWidth = outerWidth, + .availableWidth = outerWidth, .elisionLines = 1, }); } From cef43e7f0690ec2a2ab1d36f2fb00c027ee8583d Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 28 Nov 2024 21:08:47 +0400 Subject: [PATCH 049/294] Fix build with Xcode. --- Telegram/SourceFiles/ui/widgets/expandable_peer_list.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Telegram/SourceFiles/ui/widgets/expandable_peer_list.cpp b/Telegram/SourceFiles/ui/widgets/expandable_peer_list.cpp index 343d623aa..fa43f4b92 100644 --- a/Telegram/SourceFiles/ui/widgets/expandable_peer_list.cpp +++ b/Telegram/SourceFiles/ui/widgets/expandable_peer_list.cpp @@ -165,10 +165,11 @@ void AddExpandablePeerList( const auto it = map.find(peer->id); return (it == map.end() || !it->second) ? richName - : TextWithEntities( - (u"(%1) "_q).arg(it->second)).append(richName); + : TextWithEntities{ + (u"(%1) "_q).arg(it->second) + }.append(richName); }) - : std::move(name), + : std::move(name) | rpl::type_erased(), st::defaultBoxCheckbox, std::make_unique( st::defaultCheck, From 8502b90c255bb03b8ac3e23c0b102e567dd9cf4e Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 28 Nov 2024 20:33:46 +0400 Subject: [PATCH 050/294] Beta version 5.8.4. - Add option to show folder tags in chats list. - Count group with topics as one chat in folder unread counter. --- Telegram/Resources/uwp/AppX/AppxManifest.xml | 2 +- Telegram/Resources/winrc/Telegram.rc | 8 ++++---- Telegram/Resources/winrc/Updater.rc | 8 ++++---- Telegram/SourceFiles/core/version.h | 6 +++--- Telegram/build/version | 10 +++++----- changelog.txt | 5 +++++ 6 files changed, 22 insertions(+), 17 deletions(-) diff --git a/Telegram/Resources/uwp/AppX/AppxManifest.xml b/Telegram/Resources/uwp/AppX/AppxManifest.xml index 1f5ac3f65..a4f31f0a0 100644 --- a/Telegram/Resources/uwp/AppX/AppxManifest.xml +++ b/Telegram/Resources/uwp/AppX/AppxManifest.xml @@ -10,7 +10,7 @@ + Version="5.8.4.0" /> Telegram Desktop Telegram Messenger LLP diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc index 9ae851b64..cf8860b86 100644 --- a/Telegram/Resources/winrc/Telegram.rc +++ b/Telegram/Resources/winrc/Telegram.rc @@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,8,3,0 - PRODUCTVERSION 5,8,3,0 + FILEVERSION 5,8,4,0 + PRODUCTVERSION 5,8,4,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -62,10 +62,10 @@ BEGIN BEGIN VALUE "CompanyName", "Telegram FZ-LLC" VALUE "FileDescription", "Telegram Desktop" - VALUE "FileVersion", "5.8.3.0" + VALUE "FileVersion", "5.8.4.0" VALUE "LegalCopyright", "Copyright (C) 2014-2024" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "5.8.3.0" + VALUE "ProductVersion", "5.8.4.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/Resources/winrc/Updater.rc b/Telegram/Resources/winrc/Updater.rc index 93a1d4d8d..4900b9ac7 100644 --- a/Telegram/Resources/winrc/Updater.rc +++ b/Telegram/Resources/winrc/Updater.rc @@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,8,3,0 - PRODUCTVERSION 5,8,3,0 + FILEVERSION 5,8,4,0 + PRODUCTVERSION 5,8,4,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -53,10 +53,10 @@ BEGIN BEGIN VALUE "CompanyName", "Telegram FZ-LLC" VALUE "FileDescription", "Telegram Desktop Updater" - VALUE "FileVersion", "5.8.3.0" + VALUE "FileVersion", "5.8.4.0" VALUE "LegalCopyright", "Copyright (C) 2014-2024" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "5.8.3.0" + VALUE "ProductVersion", "5.8.4.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h index e631de674..f117c4e1f 100644 --- a/Telegram/SourceFiles/core/version.h +++ b/Telegram/SourceFiles/core/version.h @@ -22,7 +22,7 @@ constexpr auto AppId = "{53F49750-6209-4FBF-9CA8-7A333C87D1ED}"_cs; constexpr auto AppNameOld = "Telegram Win (Unofficial)"_cs; constexpr auto AppName = "Telegram Desktop"_cs; constexpr auto AppFile = "Telegram"_cs; -constexpr auto AppVersion = 5008003; -constexpr auto AppVersionStr = "5.8.3"; -constexpr auto AppBetaVersion = false; +constexpr auto AppVersion = 5008004; +constexpr auto AppVersionStr = "5.8.4"; +constexpr auto AppBetaVersion = true; constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION; diff --git a/Telegram/build/version b/Telegram/build/version index 66fe3884c..591675ea8 100644 --- a/Telegram/build/version +++ b/Telegram/build/version @@ -1,7 +1,7 @@ -AppVersion 5008003 +AppVersion 5008004 AppVersionStrMajor 5.8 -AppVersionStrSmall 5.8.3 -AppVersionStr 5.8.3 -BetaChannel 0 +AppVersionStrSmall 5.8.4 +AppVersionStr 5.8.4 +BetaChannel 1 AlphaVersion 0 -AppVersionOriginal 5.8.3 +AppVersionOriginal 5.8.4.beta diff --git a/changelog.txt b/changelog.txt index 22c02f612..1f57a0ab2 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,8 @@ +5.8.4 beta (28.11.24) + +- Add option to show folder tags in chats list. +- Count group with topics as one chat in folder unread counter. + 5.8.3 (23.11.24) - Ctrl+Click on Reply in groups to reply in another chat. From ca0adba6cf818beead046736c51ecbfa200021ef Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Thu, 28 Nov 2024 22:08:22 +0300 Subject: [PATCH 051/294] Fixed pinned chats in chats filters. Regression was introduced in e3465da979. --- Telegram/SourceFiles/data/data_chat_filters.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Telegram/SourceFiles/data/data_chat_filters.cpp b/Telegram/SourceFiles/data/data_chat_filters.cpp index 354d95bf3..81eb2f536 100644 --- a/Telegram/SourceFiles/data/data_chat_filters.cpp +++ b/Telegram/SourceFiles/data/data_chat_filters.cpp @@ -716,7 +716,7 @@ bool ChatFilters::applyChange(ChatFilter &filter, ChatFilter &&updated) { } if (pinnedChanged) { const auto filterList = _owner->chatsFilters().chatsList(id); - filterList->pinned()->applyList(wasFilter.pinned()); + filterList->pinned()->applyList(filter.pinned()); } if (chatlistChanged) { _isChatlistChanged.fire_copy(id); From cffce47eb1e2b29ecce8e7e80f3d2d2addf551a0 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Fri, 29 Nov 2024 08:31:49 +0300 Subject: [PATCH 052/294] Fixed emoji in chats filter tags. --- .../boxes/filters/edit_filter_box.cpp | 49 +++++----- .../dialogs/dialogs_inner_widget.cpp | 38 ++------ .../SourceFiles/ui/chat/chats_filter_tag.cpp | 91 +++++++++++++++++++ .../SourceFiles/ui/chat/chats_filter_tag.h | 14 +++ Telegram/cmake/td_ui.cmake | 2 + 5 files changed, 140 insertions(+), 54 deletions(-) create mode 100644 Telegram/SourceFiles/ui/chat/chats_filter_tag.cpp create mode 100644 Telegram/SourceFiles/ui/chat/chats_filter_tag.h diff --git a/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp b/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp index 0edbba1e9..3ada6e408 100644 --- a/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp +++ b/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp @@ -29,6 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "lang/lang_keys.h" #include "main/main_session.h" #include "settings/settings_common.h" +#include "ui/chat/chats_filter_tag.h" #include "ui/effects/animation_value_f.h" #include "ui/effects/animations.h" #include "ui/effects/panel_animation.h" @@ -544,31 +545,18 @@ void EditFilterBox( colors->width(), h); }, preview->lifetime()); - const auto previewColor = preview->lifetime().make_state(); + const auto previewTag = preview->lifetime().make_state(); const auto previewAlpha = preview->lifetime().make_state(1); preview->paintRequest() | rpl::start_with_next([=] { auto p = QPainter(preview); - p.fillRect(preview->rect(), Qt::transparent); - const auto &font = st::dialogRowFilterTagFont; - const auto text = name->getLastText().toUpper(); - p.setFont(font); p.setOpacity(*previewAlpha); - const auto roundedWidth = font->width(text) + font->spacew * 3; + const auto size = previewTag->size() / style::DevicePixelRatio(); const auto rect = QRect( - preview->width() - roundedWidth - st::boxRowPadding.right(), - (st::normalFont->height - font->height) / 2, - roundedWidth, - font->height); - const auto pen = QPen(*previewColor); - p.setPen(Qt::NoPen); - p.setBrush(anim::with_alpha(pen.color(), .15)); - { - auto hq = PainterHighQualityEnabler(p); - const auto radius = font->height / 3.; - p.drawRoundedRect(rect, radius, radius); - } - p.setPen(pen); - p.drawText(rect, text, style::al_center); + preview->width() - size.width() - st::boxRowPadding.right(), + (st::normalFont->height - size.height()) / 2, + size.width(), + size.height()); + p.drawImage(rect.topLeft(), *previewTag); if (p.opacity() < 1) { p.setOpacity(1. - p.opacity()); p.setFont(st::normalFont); @@ -580,10 +568,6 @@ void EditFilterBox( } }, preview->lifetime()); - name->changes() | rpl::start_with_next([=] { - preview->update(); - }, preview->lifetime()); - const auto side = st::userpicBuilderEmojiAccentColorSize; const auto line = colors->add( Ui::CreateSkipWidget(colors, side), @@ -594,6 +578,13 @@ void EditFilterBox( const auto palette = [](int i) { return Ui::EmptyUserpic::UserpicColor(i).color2; }; + name->changes() | rpl::start_with_next([=] { + *previewTag = Ui::ChatsFilterTag( + name->getLastText().toUpper(), + palette(state->colorIndex.current())->c, + false); + preview->update(); + }, preview->lifetime()); for (auto i = 0; i < kColorsCount; ++i) { const auto button = Ui::CreateChild( line); @@ -605,7 +596,10 @@ void EditFilterBox( const auto color = palette(i); button->setBrush(color); if (progress == 1) { - *previewColor = color->c; + *previewTag = Ui::ChatsFilterTag( + name->getLastText().toUpper(), + color->c, + false); if (i == kNoTag) { *previewAlpha = 0.; } @@ -628,7 +622,10 @@ void EditFilterBox( buttons[was]->setSelectedProgress(1. - progress); } buttons[now]->setSelectedProgress(progress); - *previewColor = anim::color(c1, c2, progress); + *previewTag = Ui::ChatsFilterTag( + name->getLastText().toUpper(), + anim::color(c1, c2, progress), + false); *previewAlpha = anim::interpolateF(a1, a2, progress); preview->update(); }, 0., 1., st::universalDuration); diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index d5572a026..6fa18f356 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -63,6 +63,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/window_controller.h" #include "window/window_session_controller.h" #include "window/window_peer_menu.h" +#include "ui/chat/chats_filter_tag.h" #include "ui/effects/ripple_animation.h" #include "ui/effects/loading_element.h" #include "ui/widgets/multi_select.h" @@ -315,6 +316,9 @@ InnerWidget::InnerWidget( session().settings().archiveCollapsedChanges() | rpl::map_to(false), session().data().chatsFilters().changed() | rpl::map_to(true) ) | rpl::start_with_next([=](bool refreshHeight) { + if (refreshHeight) { + _chatsFilterTags.clear(); + } if (refreshHeight && _filterId) { // Height of the main list will be refreshed in other way. _shownList->updateHeights(_narrowRatio); @@ -4274,34 +4278,12 @@ QImage *InnerWidget::cacheChatsFilterTag( if (roundedText.isEmpty() || colorIndex < 0) { return nullptr; } - const auto &roundedFont = st::dialogRowFilterTagFont; - const auto roundedWidth = roundedFont->width(roundedText) - + roundedFont->spacew * 3; - const auto rect = QRect(0, 0, roundedWidth, roundedFont->height); - auto cache = QImage( - rect.size() * style::DevicePixelRatio(), - QImage::Format_ARGB32_Premultiplied); - cache.setDevicePixelRatio(style::DevicePixelRatio()); - cache.fill(Qt::transparent); - { - auto p = QPainter(&cache); - const auto pen = QPen(active - ? st::dialogsBgActive - : Ui::EmptyUserpic::UserpicColor(colorIndex).color2); - p.setPen(Qt::NoPen); - p.setBrush(active - ? st::dialogsTextFgActive->c - : anim::with_alpha(pen.color(), .15)); - { - auto hq = PainterHighQualityEnabler(p); - const auto radius = roundedFont->height / 3.; - p.drawRoundedRect(rect, radius, radius); - } - p.setPen(pen); - p.setFont(roundedFont); - p.drawText(rect, roundedText, style::al_center); - } - return &_chatsFilterTags.emplace(key, std::move(cache)).first->second; + return &_chatsFilterTags.emplace( + key, + Ui::ChatsFilterTag( + std::move(roundedText), + Ui::EmptyUserpic::UserpicColor(colorIndex).color2->c, + active)).first->second; } bool InnerWidget::chooseHashtag() { diff --git a/Telegram/SourceFiles/ui/chat/chats_filter_tag.cpp b/Telegram/SourceFiles/ui/chat/chats_filter_tag.cpp new file mode 100644 index 000000000..3e799aa02 --- /dev/null +++ b/Telegram/SourceFiles/ui/chat/chats_filter_tag.cpp @@ -0,0 +1,91 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "ui/chat/chats_filter_tag.h" + +#include "ui/emoji_config.h" +#include "ui/painter.h" +#include "styles/style_dialogs.h" + +namespace Ui { + +QImage ChatsFilterTag(QString roundedText, QColor color, bool active) { + const auto &roundedFont = st::dialogRowFilterTagFont; + const auto additionalWidth = roundedFont->spacew * 3; + struct EmojiReplacement final { + QPixmap pixmap; + int from = -1; + int length = 0; + float64 x = -1; + }; + auto emojiReplacements = std::vector(); + auto ch = roundedText.constData(); + const auto end = ch + roundedText.size(); + while (ch != end) { + auto emojiLength = 0; + if (const auto emoji = Ui::Emoji::Find(ch, end, &emojiLength)) { + const auto factor = style::DevicePixelRatio(); + emojiReplacements.emplace_back( + Ui::Emoji::SinglePixmap( + emoji, + st::normalFont->height * factor).scaledToHeight( + roundedFont->ascent * factor, + Qt::SmoothTransformation), + ch - roundedText.constData(), + emojiLength); + ch += emojiLength; + } else { + ch++; + } + } + if (!emojiReplacements.empty()) { + auto addedChars = 0; + for (auto &e : emojiReplacements) { + const auto pixmapWidth = e.pixmap.width() + / style::DevicePixelRatio(); + const auto spaces = 1 + pixmapWidth / roundedFont->spacew; + const auto placeholder = QString(spaces, ' '); + const auto from = e.from + addedChars; + e.x = roundedFont->width(roundedText.mid(0, from)) + + additionalWidth / 2. + + (roundedFont->width(placeholder) - pixmapWidth) / 2.; + roundedText.replace(from, e.length, placeholder); + addedChars += spaces - e.length; + } + } + const auto roundedWidth = roundedFont->width(roundedText) + + additionalWidth; + const auto rect = QRect(0, 0, roundedWidth, roundedFont->height); + auto cache = QImage( + rect.size() * style::DevicePixelRatio(), + QImage::Format_ARGB32_Premultiplied); + cache.setDevicePixelRatio(style::DevicePixelRatio()); + cache.fill(Qt::transparent); + { + auto p = QPainter(&cache); + const auto pen = QPen(active ? st::dialogsBgActive->c : color); + p.setPen(Qt::NoPen); + p.setBrush(active + ? st::dialogsTextFgActive->c + : anim::with_alpha(pen.color(), .15)); + { + auto hq = PainterHighQualityEnabler(p); + const auto radius = roundedFont->height / 3.; + p.drawRoundedRect(rect, radius, radius); + } + p.setPen(pen); + p.setFont(roundedFont); + p.drawText(rect, roundedText, style::al_center); + for (const auto &e : emojiReplacements) { + const auto h = e.pixmap.height() / style::DevicePixelRatio(); + p.drawPixmap(QPointF(e.x, (rect.height() - h) / 2), e.pixmap); + } + } + return cache; +} + +} // namespace Ui diff --git a/Telegram/SourceFiles/ui/chat/chats_filter_tag.h b/Telegram/SourceFiles/ui/chat/chats_filter_tag.h new file mode 100644 index 000000000..aa07bf4c5 --- /dev/null +++ b/Telegram/SourceFiles/ui/chat/chats_filter_tag.h @@ -0,0 +1,14 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +namespace Ui { + +[[nodiscard]] QImage ChatsFilterTag(QString text, QColor color, bool active); + +} // namespace Ui diff --git a/Telegram/cmake/td_ui.cmake b/Telegram/cmake/td_ui.cmake index fa35b57d9..5b281f1cf 100644 --- a/Telegram/cmake/td_ui.cmake +++ b/Telegram/cmake/td_ui.cmake @@ -334,6 +334,8 @@ PRIVATE ui/chat/chat_style_radius.h ui/chat/chat_theme.cpp ui/chat/chat_theme.h + ui/chat/chats_filter_tag.cpp + ui/chat/chats_filter_tag.h ui/chat/continuous_scroll.cpp ui/chat/continuous_scroll.h ui/chat/forward_options_box.cpp From e5bb5b75fec098ef448fbac165567f20eadf7525 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 29 Nov 2024 10:06:50 +0400 Subject: [PATCH 053/294] Fix crash in webview teardown on Windows. --- Telegram/lib_webview | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Telegram/lib_webview b/Telegram/lib_webview index 93af01974..46c8bd206 160000 --- a/Telegram/lib_webview +++ b/Telegram/lib_webview @@ -1 +1 @@ -Subproject commit 93af01974107d3037b5194b635473201164c112e +Subproject commit 46c8bd206efb11ccc28e2edaaffff360cec74ff0 From cf2dbe50a1c7bd4f2445d5b01664ebaecf6692e6 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 29 Nov 2024 10:07:07 +0400 Subject: [PATCH 054/294] Fix crash in narrow column reactions view. --- Telegram/SourceFiles/info/info_wrap_widget.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Telegram/SourceFiles/info/info_wrap_widget.cpp b/Telegram/SourceFiles/info/info_wrap_widget.cpp index 363558e59..5ede192e5 100644 --- a/Telegram/SourceFiles/info/info_wrap_widget.cpp +++ b/Telegram/SourceFiles/info/info_wrap_widget.cpp @@ -289,6 +289,7 @@ Dialogs::RowDescriptor WrapWidget::activeChat() const { : Dialogs::RowDescriptor(); } else if (key().settingsSelf() || key().isDownloads() + || key().reactionsContextId() || key().poll() || key().statisticsTag().peer) { return Dialogs::RowDescriptor(); From 03e4592082df59ddc6921c5e2216319f7e48a046 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 29 Nov 2024 10:17:42 +0400 Subject: [PATCH 055/294] Fix search in group/channel requests list. --- .../common_groups/info_common_groups_widget.cpp | 1 - Telegram/SourceFiles/info/info_top_bar.cpp | 1 + Telegram/SourceFiles/info/info_wrap_widget.cpp | 14 +++++++------- .../reactions_list/info_reactions_list_widget.cpp | 1 - 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Telegram/SourceFiles/info/common_groups/info_common_groups_widget.cpp b/Telegram/SourceFiles/info/common_groups/info_common_groups_widget.cpp index 392bee43c..f81019bb7 100644 --- a/Telegram/SourceFiles/info/common_groups/info_common_groups_widget.cpp +++ b/Telegram/SourceFiles/info/common_groups/info_common_groups_widget.cpp @@ -9,7 +9,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "info/common_groups/info_common_groups_inner_widget.h" #include "info/info_controller.h" -#include "ui/search_field_controller.h" #include "ui/widgets/scroll_area.h" #include "ui/ui_utility.h" #include "lang/lang_keys.h" diff --git a/Telegram/SourceFiles/info/info_top_bar.cpp b/Telegram/SourceFiles/info/info_top_bar.cpp index 0a59d52f2..c08303b3b 100644 --- a/Telegram/SourceFiles/info/info_top_bar.cpp +++ b/Telegram/SourceFiles/info/info_top_bar.cpp @@ -208,6 +208,7 @@ void TopBar::setSearchField( rpl::producer &&shown, bool startsFocused) { Expects(field != nullptr); + createSearchView(field.release(), std::move(shown), startsFocused); } diff --git a/Telegram/SourceFiles/info/info_wrap_widget.cpp b/Telegram/SourceFiles/info/info_wrap_widget.cpp index 5ede192e5..a638537b1 100644 --- a/Telegram/SourceFiles/info/info_wrap_widget.cpp +++ b/Telegram/SourceFiles/info/info_wrap_widget.cpp @@ -527,14 +527,14 @@ void WrapWidget::showTopBarMenu(bool check) { } bool WrapWidget::requireTopBarSearch() const { - if (!_topBar || !_controller->searchFieldController()) { + if (!_topBar + || !_controller->searchFieldController() + || (_controller->wrap() == Wrap::Layer) + || (_controller->section().type() == Section::Type::Profile) + || key().isDownloads()) { return false; - } else if (_controller->wrap() == Wrap::Layer - || _controller->section().type() == Section::Type::Profile) { - return false; - } else if (key().isDownloads()) { - return false; - } else if (hasStackHistory()) { + } else if (hasStackHistory() + || _controller->section().type() == Section::Type::RequestsList) { return true; } return false; diff --git a/Telegram/SourceFiles/info/reactions_list/info_reactions_list_widget.cpp b/Telegram/SourceFiles/info/reactions_list/info_reactions_list_widget.cpp index a94f2f2a7..9b0f4ad0e 100644 --- a/Telegram/SourceFiles/info/reactions_list/info_reactions_list_widget.cpp +++ b/Telegram/SourceFiles/info/reactions_list/info_reactions_list_widget.cpp @@ -15,7 +15,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "info/info_controller.h" #include "ui/controls/who_reacted_context_action.h" #include "ui/widgets/scroll_area.h" -#include "ui/search_field_controller.h" #include "ui/ui_utility.h" #include "lang/lang_keys.h" #include "styles/style_info.h" From b4f173cdb3cc8c84db66bdf02bf926a4fbfdbe3a Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 29 Nov 2024 10:25:21 +0400 Subject: [PATCH 056/294] Fix possible crash in ads preloading. --- .../SourceFiles/history/history_widget.cpp | 23 ++++++++----------- Telegram/SourceFiles/history/history_widget.h | 2 ++ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 49fea20a1..b8f8fb0fa 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -321,30 +321,26 @@ HistoryWidget::HistoryWidget( _list->onParentGeometryChanged(); }), lifetime()); - const auto weak = Ui::MakeWeak(this); _scroll->addContentRequests( ) | rpl::start_with_next([=] { if (_history && _history->loadedAtBottom()) { using Result = Data::SponsoredMessages::AppendResult; const auto tryToAppend = [=] { - const auto r = session().sponsoredMessages().append(_history); - if (r == Result::Appended) { + const auto sponsored = &session().sponsoredMessages(); + const auto result = sponsored->append(_history); + if (result == Result::Appended) { _scroll->contentAdded(); } - return r; + return result; }; - if (tryToAppend() == Result::MediaLoading) { - const auto sharedLifetime = std::make_shared(); + if (tryToAppend() == Result::MediaLoading + && !_historySponsoredPreloading) { session().downloaderTaskFinished( ) | rpl::start_with_next([=] { - if (const auto strong = weak.data()) { - if (tryToAppend() != Result::MediaLoading) { - sharedLifetime->destroy(); - } - } else { - sharedLifetime->destroy(); + if (tryToAppend() != Result::MediaLoading) { + _historySponsoredPreloading.destroy(); } - }, *sharedLifetime); + }, _historySponsoredPreloading); } } }, lifetime()); @@ -2625,6 +2621,7 @@ void HistoryWidget::setHistory(History *history) { unregisterDraftSources(); clearAllLoadRequests(); clearSupportPreloadRequest(); + _historySponsoredPreloading.destroy(); const auto wasHistory = base::take(_history); const auto wasMigrated = base::take(_migrated); unloadHeavyViewParts(wasHistory); diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index 73a8ff1c8..6c4c9cdbb 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -744,6 +744,8 @@ private: QPointer _list; History *_migrated = nullptr; History *_history = nullptr; + rpl::lifetime _historySponsoredPreloading; + // Initial updateHistoryGeometry() was called. bool _historyInited = false; // If updateListSize() was called without updateHistoryGeometry(). From 61ceb6641537221b7653cbb2caf89b49d2aee4bc Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 29 Nov 2024 10:52:14 +0400 Subject: [PATCH 057/294] Beta version 5.8.5. - Fix pinned chats in folders. - Fix emoji in folder tags. - Fix several crashes. --- Telegram/Resources/uwp/AppX/AppxManifest.xml | 2 +- Telegram/Resources/winrc/Telegram.rc | 8 ++++---- Telegram/Resources/winrc/Updater.rc | 8 ++++---- Telegram/SourceFiles/core/version.h | 4 ++-- Telegram/build/version | 8 ++++---- changelog.txt | 6 ++++++ 6 files changed, 21 insertions(+), 15 deletions(-) diff --git a/Telegram/Resources/uwp/AppX/AppxManifest.xml b/Telegram/Resources/uwp/AppX/AppxManifest.xml index a4f31f0a0..dd507d147 100644 --- a/Telegram/Resources/uwp/AppX/AppxManifest.xml +++ b/Telegram/Resources/uwp/AppX/AppxManifest.xml @@ -10,7 +10,7 @@ + Version="5.8.5.0" /> Telegram Desktop Telegram Messenger LLP diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc index cf8860b86..f769ce290 100644 --- a/Telegram/Resources/winrc/Telegram.rc +++ b/Telegram/Resources/winrc/Telegram.rc @@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,8,4,0 - PRODUCTVERSION 5,8,4,0 + FILEVERSION 5,8,5,0 + PRODUCTVERSION 5,8,5,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -62,10 +62,10 @@ BEGIN BEGIN VALUE "CompanyName", "Telegram FZ-LLC" VALUE "FileDescription", "Telegram Desktop" - VALUE "FileVersion", "5.8.4.0" + VALUE "FileVersion", "5.8.5.0" VALUE "LegalCopyright", "Copyright (C) 2014-2024" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "5.8.4.0" + VALUE "ProductVersion", "5.8.5.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/Resources/winrc/Updater.rc b/Telegram/Resources/winrc/Updater.rc index 4900b9ac7..21e050ef3 100644 --- a/Telegram/Resources/winrc/Updater.rc +++ b/Telegram/Resources/winrc/Updater.rc @@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,8,4,0 - PRODUCTVERSION 5,8,4,0 + FILEVERSION 5,8,5,0 + PRODUCTVERSION 5,8,5,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -53,10 +53,10 @@ BEGIN BEGIN VALUE "CompanyName", "Telegram FZ-LLC" VALUE "FileDescription", "Telegram Desktop Updater" - VALUE "FileVersion", "5.8.4.0" + VALUE "FileVersion", "5.8.5.0" VALUE "LegalCopyright", "Copyright (C) 2014-2024" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "5.8.4.0" + VALUE "ProductVersion", "5.8.5.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h index f117c4e1f..1e76d2b09 100644 --- a/Telegram/SourceFiles/core/version.h +++ b/Telegram/SourceFiles/core/version.h @@ -22,7 +22,7 @@ constexpr auto AppId = "{53F49750-6209-4FBF-9CA8-7A333C87D1ED}"_cs; constexpr auto AppNameOld = "Telegram Win (Unofficial)"_cs; constexpr auto AppName = "Telegram Desktop"_cs; constexpr auto AppFile = "Telegram"_cs; -constexpr auto AppVersion = 5008004; -constexpr auto AppVersionStr = "5.8.4"; +constexpr auto AppVersion = 5008005; +constexpr auto AppVersionStr = "5.8.5"; constexpr auto AppBetaVersion = true; constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION; diff --git a/Telegram/build/version b/Telegram/build/version index 591675ea8..a50056c62 100644 --- a/Telegram/build/version +++ b/Telegram/build/version @@ -1,7 +1,7 @@ -AppVersion 5008004 +AppVersion 5008005 AppVersionStrMajor 5.8 -AppVersionStrSmall 5.8.4 -AppVersionStr 5.8.4 +AppVersionStrSmall 5.8.5 +AppVersionStr 5.8.5 BetaChannel 1 AlphaVersion 0 -AppVersionOriginal 5.8.4.beta +AppVersionOriginal 5.8.5.beta diff --git a/changelog.txt b/changelog.txt index 1f57a0ab2..74493ce50 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,9 @@ +5.8.5 beta (29.11.24) + +- Fix pinned chats in folders. +- Fix emoji in folder tags. +- Fix several crashes. + 5.8.4 beta (28.11.24) - Add option to show folder tags in chats list. From 96398daa783da04d57aadfb16a5a7f2f0f3423f2 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 29 Nov 2024 11:25:29 +0400 Subject: [PATCH 058/294] Beta version 5.8.5: Fix build with Xcode. --- Telegram/SourceFiles/ui/chat/chats_filter_tag.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Telegram/SourceFiles/ui/chat/chats_filter_tag.cpp b/Telegram/SourceFiles/ui/chat/chats_filter_tag.cpp index 3e799aa02..aa1b4bff2 100644 --- a/Telegram/SourceFiles/ui/chat/chats_filter_tag.cpp +++ b/Telegram/SourceFiles/ui/chat/chats_filter_tag.cpp @@ -29,14 +29,15 @@ QImage ChatsFilterTag(QString roundedText, QColor color, bool active) { auto emojiLength = 0; if (const auto emoji = Ui::Emoji::Find(ch, end, &emojiLength)) { const auto factor = style::DevicePixelRatio(); - emojiReplacements.emplace_back( - Ui::Emoji::SinglePixmap( + emojiReplacements.push_back({ + .pixmap = Ui::Emoji::SinglePixmap( emoji, st::normalFont->height * factor).scaledToHeight( roundedFont->ascent * factor, Qt::SmoothTransformation), - ch - roundedText.constData(), - emojiLength); + .from = int(ch - roundedText.constData()), + .length = emojiLength, + }); ch += emojiLength; } else { ch++; From 5aba2f25cccdee0a45c51211d11d26d5a94dc298 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Fri, 29 Nov 2024 15:06:58 +0300 Subject: [PATCH 059/294] Fixed drawing of currency icon with non-default scale in profile. --- .../info/channel_statistics/earn/earn_icons.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/Telegram/SourceFiles/info/channel_statistics/earn/earn_icons.cpp b/Telegram/SourceFiles/info/channel_statistics/earn/earn_icons.cpp index 0a57f9288..b6c3ad85e 100644 --- a/Telegram/SourceFiles/info/channel_statistics/earn/earn_icons.cpp +++ b/Telegram/SourceFiles/info/channel_statistics/earn/earn_icons.cpp @@ -84,13 +84,16 @@ QImage MenuIconCurrency(const QSize &size) { w * 2), Qt::white); p.setCompositionMode(QPainter::CompositionMode_SourceOver); - const auto i = IconCurrencyColored( - st::inviteLinkSubscribeBoxTerms.style.font, - st::infoIconFg->c); - p.drawImage( - (size.width() - i.width() / style::DevicePixelRatio()) / 2, - (size.height() - i.height() / style::DevicePixelRatio()) / 2, - i); + + const auto s = Size(st::inviteLinkSubscribeBoxTerms.style.font->ascent); + auto svg = QSvgRenderer(CurrencySvg(st::infoIconFg->c)); + svg.render( + &p, + QRectF( + (size.width() - s.width()) / 2., + (size.height() - s.height()) / 2., + s.width(), + s.height())); return image; } From cdd7ff5c6d211bffddfdce7b779192735dcf5090 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Fri, 29 Nov 2024 15:55:08 +0300 Subject: [PATCH 060/294] Fixed count of current size for non-thumbed media with long bottom info. --- .../view/media/history_view_document.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/Telegram/SourceFiles/history/view/media/history_view_document.cpp b/Telegram/SourceFiles/history/view/media/history_view_document.cpp index 4f43cc9fd..b163321b2 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_document.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_document.cpp @@ -543,12 +543,21 @@ QSize Document::countCurrentSize(int newWidth) { if (!captioned && !hasTranscribe) { auto result = File::countCurrentSize(newWidth); if (isBubbleBottom()) { - if (const auto link = thumbedLinkMaxWidth()) { + const auto thumbedWidth = thumbedLinkMaxWidth(); + const auto statusWidth = thumbedWidth + ? 0 + : st::normalFont->width(_statusText); + if (thumbedWidth || statusWidth) { const auto needed = st.padding.left() - + st.thumbSize - + st.thumbSkip - + link + + (thumbedWidth + ? st.thumbSize + st.thumbSkip + : st::msgFileLayout.thumbSize + + st::mediaUnreadSkip) + + (thumbedWidth + statusWidth) + st.thumbSkip + + (_realParent->hasUnreadMediaFlag() + ? st::mediaUnreadSkip + st::mediaUnreadSize + : 0) + _parent->bottomInfoFirstLineWidth() + st.padding.right(); if (result.width() < needed) { From 9822c56f1a04311dd91c0ee4e387cd73ea9685bb Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Fri, 29 Nov 2024 16:03:42 +0300 Subject: [PATCH 061/294] Removed display of right button for bots when there is unread badge. --- Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp | 6 +++--- .../SourceFiles/dialogs/ui/dialogs_suggestions.cpp | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp index 131c10399..4de06e9f6 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp @@ -144,9 +144,7 @@ int PaintBadges( int pinnedIconTop, bool narrow) { auto initial = right; - if (const auto used = PaintRightButton(p, context)) { - return used - st::dialogsUnreadPadding; - } else if (badgesState.unread + if (badgesState.unread && !badgesState.unreadCounter && context.st->unreadMarkDiameter > 0) { const auto d = context.st->unreadMarkDiameter; @@ -188,6 +186,8 @@ int PaintBadges( : QString::number(badgesState.unreadCounter); const auto badge = PaintUnreadBadge(p, counter, right, top, st); right -= badge.width() + st.padding; + } else if (const auto used = PaintRightButton(p, context)) { + return used - st::dialogsUnreadPadding; } else if (displayPinnedIcon) { const auto &icon = ThreeStateIcon( st::dialogsPinnedIcon, diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp index 88a5faea4..e6b166802 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp @@ -261,7 +261,7 @@ bool RecentRow::refreshBadge() { } QSize RecentRow::rightActionSize() const { - if (_mainAppText) { + if (_mainAppText && _badgeSize.isEmpty()) { return QSize( _mainAppText->maxWidth() + _mainAppText->minHeight(), st::dialogRowOpenBotHeight); @@ -270,7 +270,7 @@ QSize RecentRow::rightActionSize() const { } QMargins RecentRow::rightActionMargins() const { - if (_mainAppText) { + if (_mainAppText && _badgeSize.isEmpty()) { return QMargins( 0, st::dialogRowOpenBotRecentTop, @@ -292,7 +292,7 @@ void RecentRow::rightActionPaint( int outerWidth, bool selected, bool actionSelected) { - if (_mainAppText) { + if (_mainAppText && _badgeSize.isEmpty()) { const auto size = RecentRow::rightActionSize(); p.setPen(Qt::NoPen); p.setBrush(actionSelected @@ -335,13 +335,13 @@ void RecentRow::rightActionPaint( } bool RecentRow::rightActionDisabled() const { - return !_mainAppText; + return !_mainAppText || !_badgeSize.isEmpty(); } void RecentRow::rightActionAddRipple( QPoint point, Fn updateCallback) { - if (!_mainAppText) { + if (!_mainAppText || !_badgeSize.isEmpty()) { return; } if (!_actionRipple) { From b3c8a79946a30921c3855f3fc80e9030fc301be0 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 29 Nov 2024 11:44:26 +0400 Subject: [PATCH 062/294] Use langpack-ed about for Verification Codes. --- Telegram/Resources/langs/lang.strings | 1 + .../history/view/history_view_about_view.cpp | 35 +++++++++++++++---- .../history/view/history_view_about_view.h | 5 +++ 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 54ecda43a..7190ff902 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -3376,6 +3376,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_replies_no_comments" = "No comments here yet..."; "lng_verification_codes" = "Verification Codes"; +"lng_verification_codes_about" = "Third-party services, like websites and stores, can send verification codes to your phone number via Telegram instead of SMS. Such codes will appear in this chat.\n\nIf you didn't request any codes — don't worry! Most likely, someone made a mistake when entering their number."; "lng_archived_name" = "Archived chats"; "lng_archived_add" = "Archive"; diff --git a/Telegram/SourceFiles/history/view/history_view_about_view.cpp b/Telegram/SourceFiles/history/view/history_view_about_view.cpp index 12a98949a..0c87a6489 100644 --- a/Telegram/SourceFiles/history/view/history_view_about_view.cpp +++ b/Telegram/SourceFiles/history/view/history_view_about_view.cpp @@ -241,6 +241,13 @@ HistoryItem *AboutView::item() const { } bool AboutView::refresh() { + if (_history->peer->isVerifyCodes()) { + if (_item) { + return false; + } + setItem(makeAboutVerifyCodes(), nullptr); + return true; + } const auto user = _history->peer->asUser(); const auto info = user ? user->botInfo.get() : nullptr; if (!info) { @@ -359,10 +366,24 @@ void AboutView::setItem(AdminLog::OwnedItem item, DocumentData *sticker) { toggleStickerRegistered(true); } +AdminLog::OwnedItem AboutView::makeAboutVerifyCodes() { + return makeAboutSimple( + tr::lng_verification_codes_about(tr::now, Ui::Text::RichLangValue)); +} + AdminLog::OwnedItem AboutView::makeAboutBot(not_null info) { - const auto textWithEntities = TextUtilities::ParseEntities( - info->description, - Ui::ItemTextBotNoMonoOptions().flags); + return makeAboutSimple( + TextUtilities::ParseEntities( + info->description, + Ui::ItemTextBotNoMonoOptions().flags), + info->document, + info->photo); +} + +AdminLog::OwnedItem AboutView::makeAboutSimple( + TextWithEntities textWithEntities, + DocumentData *document, + PhotoData *photo) { const auto make = [&](auto &&...args) { return _history->makeMessage({ .id = _history->nextNonHistoryEntryId(), @@ -372,10 +393,10 @@ AdminLog::OwnedItem AboutView::makeAboutBot(not_null info) { .from = _history->peer->id, }, std::forward(args)...); }; - const auto item = info->document - ? make(info->document, textWithEntities) - : info->photo - ? make(info->photo, textWithEntities) + const auto item = document + ? make(document, textWithEntities) + : photo + ? make(photo, textWithEntities) : make(textWithEntities, MTP_messageMediaEmpty()); return AdminLog::OwnedItem(_delegate, item); } diff --git a/Telegram/SourceFiles/history/view/history_view_about_view.h b/Telegram/SourceFiles/history/view/history_view_about_view.h index 0f4d90491..3e78c5c62 100644 --- a/Telegram/SourceFiles/history/view/history_view_about_view.h +++ b/Telegram/SourceFiles/history/view/history_view_about_view.h @@ -34,7 +34,12 @@ public: int height = 0; private: + [[nodiscard]] AdminLog::OwnedItem makeAboutVerifyCodes(); [[nodiscard]] AdminLog::OwnedItem makeAboutBot(not_null info); + [[nodiscard]] AdminLog::OwnedItem makeAboutSimple( + TextWithEntities textWithEntities, + DocumentData *document = nullptr, + PhotoData *photo = nullptr); [[nodiscard]] AdminLog::OwnedItem makePremiumRequired(); [[nodiscard]] AdminLog::OwnedItem makeBlocked(); void makeIntro(not_null user); From b3473081376f867793a36cd3ca4754a4b2a9a210 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 29 Nov 2024 14:27:13 +0400 Subject: [PATCH 063/294] Show bot app name in title. --- Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp | 6 +++++- Telegram/SourceFiles/inline_bots/bot_attach_web_view.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp index c5bf5ce1c..7481a0bf5 100644 --- a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp +++ b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp @@ -1253,6 +1253,7 @@ void WebViewInstance::requestApp(bool allowWrite) { using Flag = MTPmessages_RequestAppWebView::Flag; const auto app = _app; + const auto title = app->title; const auto flags = Flag::f_theme_params | (_context.fullscreen ? Flag::f_fullscreen : Flag(0)) | (_appStartParam.isEmpty() ? Flag(0) : Flag::f_start_param) @@ -1269,6 +1270,7 @@ void WebViewInstance::requestApp(bool allowWrite) { const auto &data = result.data(); show({ .url = qs(data.vurl()), + .title = title, .fullscreen = data.is_fullscreen(), }); }).fail([=](const MTP::Error &error) { @@ -1350,7 +1352,9 @@ void WebViewInstance::maybeChooseAndRequestButton(PeerTypes supported) { } void WebViewInstance::show(ShowArgs &&args) { - auto title = Info::Profile::NameValue(_bot); + auto title = args.title.isEmpty() + ? Info::Profile::NameValue(_bot) + : rpl::single(args.title); auto titleBadge = _bot->isVerified() ? object_ptr(_parentShow->toastParent()) : nullptr; diff --git a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.h b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.h index f0cb146a7..43dc76689 100644 --- a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.h +++ b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.h @@ -247,6 +247,7 @@ private: struct ShowArgs { QString url; + QString title; uint64 queryId = 0; bool fullscreen = false; }; From b1e2a4243e6d90b1a68e3cfb6cd92b571f2a7c2c Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 29 Nov 2024 20:17:10 +0400 Subject: [PATCH 064/294] Fix join requests list for legacy groups. --- Telegram/SourceFiles/info/info_memento.cpp | 2 +- .../info_requests_list_widget.cpp | 40 ++++++++----------- .../requests_list/info_requests_list_widget.h | 10 ++--- 3 files changed, 21 insertions(+), 31 deletions(-) diff --git a/Telegram/SourceFiles/info/info_memento.cpp b/Telegram/SourceFiles/info/info_memento.cpp index 7e38fb5d1..ce2b89d5d 100644 --- a/Telegram/SourceFiles/info/info_memento.cpp +++ b/Telegram/SourceFiles/info/info_memento.cpp @@ -171,7 +171,7 @@ std::shared_ptr Memento::DefaultContent( return std::make_shared( peer->asChannel()); case Section::Type::RequestsList: - return std::make_shared(peer->asChannel()); + return std::make_shared(peer); case Section::Type::PeerGifts: return std::make_shared(peer->asUser()); case Section::Type::SavedSublists: diff --git a/Telegram/SourceFiles/info/requests_list/info_requests_list_widget.cpp b/Telegram/SourceFiles/info/requests_list/info_requests_list_widget.cpp index 70f638e1c..2fae27d58 100644 --- a/Telegram/SourceFiles/info/requests_list/info_requests_list_widget.cpp +++ b/Telegram/SourceFiles/info/requests_list/info_requests_list_widget.cpp @@ -8,7 +8,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "info/requests_list/info_requests_list_widget.h" #include "boxes/peers/edit_peer_requests_box.h" -#include "data/data_channel.h" #include "info/info_controller.h" #include "ui/widgets/scroll_area.h" #include "ui/search_field_controller.h" @@ -28,10 +27,10 @@ public: InnerWidget( QWidget *parent, not_null controller, - not_null channel); + not_null peer); - [[nodiscard]] not_null channel() const { - return _channel; + [[nodiscard]] not_null peer() const { + return _peer; } rpl::producer scrollToRequests() const; @@ -67,7 +66,7 @@ private: const std::shared_ptr _show; not_null _controller; - const not_null _channel; + const not_null _peer; std::unique_ptr _listController; object_ptr _list; @@ -77,14 +76,14 @@ private: InnerWidget::InnerWidget( QWidget *parent, not_null controller, - not_null channel) + not_null peer) : RpWidget(parent) , _show(controller->uiShow()) , _controller(controller) -, _channel(channel) +, _peer(peer) , _listController(std::make_unique( controller, - _channel)) + _peer)) , _list(setupList(this, _listController.get())) { setContent(_list.data()); _listController->setDelegate(static_cast(this)); @@ -188,23 +187,19 @@ std::shared_ptr InnerWidget::peerListUiShow() { return _show; } -Memento::Memento(not_null channel) -: ContentMemento(channel, nullptr, PeerId()) { +Memento::Memento(not_null peer) +: ContentMemento(peer, nullptr, PeerId()) { } Section Memento::section() const { return Section(Section::Type::RequestsList); } -not_null Memento::channel() const { - return peer()->asChannel(); -} - object_ptr Memento::createWidget( QWidget *parent, not_null controller, const QRect &geometry) { - auto result = object_ptr(parent, controller, channel()); + auto result = object_ptr(parent, controller, peer()); result->setInternalState(geometry, this); return result; } @@ -222,21 +217,18 @@ Memento::~Memento() = default; Widget::Widget( QWidget *parent, not_null controller, - not_null channel) + not_null peer) : ContentWidget(parent, controller) { controller->setSearchEnabledByContent(true); - _inner = setInnerWidget(object_ptr( - this, - controller, - channel)); + _inner = setInnerWidget(object_ptr(this, controller, peer)); } rpl::producer Widget::title() { return tr::lng_manage_peer_requests(); } -not_null Widget::channel() const { - return _inner->channel(); +not_null Widget::peer() const { + return _inner->peer(); } bool Widget::showInternal(not_null memento) { @@ -244,7 +236,7 @@ bool Widget::showInternal(not_null memento) { return false; } if (auto requestsMemento = dynamic_cast(memento.get())) { - if (requestsMemento->channel() == channel()) { + if (requestsMemento->peer() == peer()) { restoreState(requestsMemento); return true; } @@ -261,7 +253,7 @@ void Widget::setInternalState( } std::shared_ptr Widget::doCreateMemento() { - auto result = std::make_shared(channel()); + auto result = std::make_shared(peer()); saveState(result.get()); return result; } diff --git a/Telegram/SourceFiles/info/requests_list/info_requests_list_widget.h b/Telegram/SourceFiles/info/requests_list/info_requests_list_widget.h index 32e04ac5d..a6bbb37d6 100644 --- a/Telegram/SourceFiles/info/requests_list/info_requests_list_widget.h +++ b/Telegram/SourceFiles/info/requests_list/info_requests_list_widget.h @@ -9,7 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "info/info_content_widget.h" -class ChannelData; +class PeerData; struct PeerListState; namespace Info::RequestsList { @@ -18,7 +18,7 @@ class InnerWidget; class Memento final : public ContentMemento { public: - explicit Memento(not_null channel); + explicit Memento(not_null peer); object_ptr createWidget( QWidget *parent, @@ -27,8 +27,6 @@ public: Section section() const override; - [[nodiscard]] not_null channel() const; - void setListState(std::unique_ptr state); std::unique_ptr listState(); @@ -44,9 +42,9 @@ public: Widget( QWidget *parent, not_null controller, - not_null channel); + not_null peer); - [[nodiscard]] not_null channel() const; + [[nodiscard]] not_null peer() const; bool showInternal( not_null memento) override; From 783570fe9ff09481b59f7598cd947ac200e86a73 Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Tue, 3 Dec 2024 02:22:43 +0400 Subject: [PATCH 065/294] Update Qt 6.8.0 -> 6.8.1 --- Telegram/build/docker/centos_env/Dockerfile | 5 +++-- Telegram/build/prepare/prepare.py | 3 ++- Telegram/build/qt_version.py | 2 +- snap/snapcraft.yaml | 5 +++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Telegram/build/docker/centos_env/Dockerfile b/Telegram/build/docker/centos_env/Dockerfile index 1be687618..255d38fa5 100644 --- a/Telegram/build/docker/centos_env/Dockerfile +++ b/Telegram/build/docker/centos_env/Dockerfile @@ -1,7 +1,7 @@ {%- set GIT = "https://github.com" -%} {%- set GIT_FREEDESKTOP = GIT ~ "/gitlab-freedesktop-mirrors" -%} {%- set GIT_UPDATE_M4 = "git submodule set-url m4 https://gitlab.freedesktop.org/xorg/util/xcb-util-m4 && git config -f .gitmodules submodule.m4.shallow true && git submodule init && git submodule update" -%} -{%- set QT = "6.8.0" -%} +{%- set QT = "6.8.1" -%} {%- set QT_TAG = "v" ~ QT -%} {%- set CFLAGS_DEBUG = "$CFLAGS -O0 -fno-lto -U_FORTIFY_SOURCE" -%} {%- set LibrariesPath = "/usr/src/Libraries" -%} @@ -42,7 +42,7 @@ FROM builder AS patches RUN git init patches \ && cd patches \ && git remote add origin {{ GIT }}/desktop-app/patches.git \ - && git fetch --depth=1 origin 643b18c2be6424fc6f35a52891ed5a6a42502ac2 \ + && git fetch --depth=1 origin cf3b896e00c288143fce51862dbd9b1c86df1960 \ && git reset --hard FETCH_HEAD \ && rm -rf .git @@ -734,6 +734,7 @@ RUN git clone -b {{ QT_TAG }} --depth=1 {{ GIT }}/qt/qt5.git \ && cmake -GNinja -B build . \ -DCMAKE_BUILD_TYPE=None \ -DBUILD_SHARED_LIBS=OFF \ + -DQT_GENERATE_SBOM=OFF \ -DINPUT_libpng=qt \ -DINPUT_harfbuzz=qt \ -DINPUT_pcre=qt \ diff --git a/Telegram/build/prepare/prepare.py b/Telegram/build/prepare/prepare.py index d9067f99f..142d48f20 100644 --- a/Telegram/build/prepare/prepare.py +++ b/Telegram/build/prepare/prepare.py @@ -457,7 +457,7 @@ if customRunCommand: stage('patches', """ git clone https://github.com/desktop-app/patches.git cd patches - git checkout 412f65c296 + git checkout cf3b896e00 """) stage('msys64', """ @@ -1692,6 +1692,7 @@ win: -static ^ -static-runtime ^ -feature-c++20 ^ + -no-sbom ^ -openssl linked ^ -system-webp ^ -system-zlib ^ diff --git a/Telegram/build/qt_version.py b/Telegram/build/qt_version.py index 42f729049..812288db3 100644 --- a/Telegram/build/qt_version.py +++ b/Telegram/build/qt_version.py @@ -6,7 +6,7 @@ def resolve(arch): elif sys.platform == 'win32': if arch == 'arm' or 'qt6' in sys.argv: print('Choosing Qt 6.') - os.environ['QT'] = '6.8.0' + os.environ['QT'] = '6.8.1' elif os.environ.get('QT') is None: print('Choosing Qt 5.') os.environ['QT'] = '5.15.15' diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 42e5c541a..b9ecad3bd 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -164,7 +164,7 @@ parts: patches: source: https://github.com/desktop-app/patches.git source-depth: 1 - source-commit: 643b18c2be6424fc6f35a52891ed5a6a42502ac2 + source-commit: cf3b896e00c288143fce51862dbd9b1c86df1960 plugin: dump override-pull: | craftctl default @@ -377,7 +377,7 @@ parts: - mesa-vulkan-drivers - xkb-data override-pull: | - QT=6.8.0 + QT=6.8.1 git clone -b v${QT} --depth=1 https://github.com/qt/qt5.git . git submodule update --init --recursive --depth=1 qtbase qtdeclarative qtwayland qtimageformats qtsvg qtshadertools @@ -393,6 +393,7 @@ parts: -DCMAKE_INSTALL_PREFIX=/usr \ -DCMAKE_PREFIX_PATH=$CRAFT_STAGE/usr \ -DINSTALL_LIBDIR=/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR \ + -DQT_GENERATE_SBOM=OFF \ -DINPUT_openssl=linked cmake --build . -j$CRAFT_PARALLEL_BUILD_COUNT From 794818953dcd355e6c413e4d9ee66d1567daf398 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Sun, 1 Dec 2024 00:37:25 +0000 Subject: [PATCH 066/294] Update User-Agent for DNS to Chrome 131.0.0.0. --- .../SourceFiles/mtproto/details/mtproto_domain_resolver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Telegram/SourceFiles/mtproto/details/mtproto_domain_resolver.cpp b/Telegram/SourceFiles/mtproto/details/mtproto_domain_resolver.cpp index 0206faf32..e18220968 100644 --- a/Telegram/SourceFiles/mtproto/details/mtproto_domain_resolver.cpp +++ b/Telegram/SourceFiles/mtproto/details/mtproto_domain_resolver.cpp @@ -65,7 +65,7 @@ QByteArray DnsUserAgent() { static const auto kResult = QByteArray( "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " "AppleWebKit/537.36 (KHTML, like Gecko) " - "Chrome/130.0.0.0 Safari/537.36"); + "Chrome/131.0.0.0 Safari/537.36"); return kResult; } From 043d97cfdf5ca194b9a153a498d6d8b47d3cf115 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Fri, 29 Nov 2024 19:25:14 +0300 Subject: [PATCH 067/294] Moved out SearchFieldController to td_ui. --- Telegram/CMakeLists.txt | 2 -- Telegram/cmake/td_ui.cmake | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index f631e837b..cf2055b31 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -1566,8 +1566,6 @@ PRIVATE ui/item_text_options.cpp ui/item_text_options.h ui/resize_area.h - ui/search_field_controller.cpp - ui/search_field_controller.h ui/unread_badge.cpp ui/unread_badge.h window/main_window.cpp diff --git a/Telegram/cmake/td_ui.cmake b/Telegram/cmake/td_ui.cmake index 5b281f1cf..e9e683250 100644 --- a/Telegram/cmake/td_ui.cmake +++ b/Telegram/cmake/td_ui.cmake @@ -415,6 +415,8 @@ PRIVATE ui/effects/snowflakes.h ui/effects/toggle_arrow.cpp ui/effects/toggle_arrow.h + ui/search_field_controller.cpp + ui/search_field_controller.h ui/text/format_song_name.cpp ui/text/format_song_name.h ui/text/format_values.cpp From 2b122087c4c52d21dcf36683f74ac42cbdd7cd93 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Sat, 30 Nov 2024 09:14:08 +0300 Subject: [PATCH 068/294] Re-fixed focus capture from compose search widget. --- .../history/view/controls/history_view_compose_search.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Telegram/SourceFiles/history/view/controls/history_view_compose_search.cpp b/Telegram/SourceFiles/history/view/controls/history_view_compose_search.cpp index 9e98ae7c7..19bf4bb95 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_compose_search.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_search.cpp @@ -390,7 +390,7 @@ rpl::producer> TopBar::keyEvents() const { } void TopBar::setInnerFocus() { - if (Ui::InFocusChain(_select)) { + if (Ui::AppInFocus() && Ui::InFocusChain(_select->window())) { _select->setInnerFocus(); } } @@ -1035,7 +1035,7 @@ ComposeSearch::Inner::Inner( } void ComposeSearch::Inner::setInnerFocus() { - if (Ui::InFocusChain(_topBar)) { + if (Ui::AppInFocus() && Ui::InFocusChain(_topBar->window())) { _topBar->setInnerFocus(); } } From 168162c17462b832cd12b4a98f91ba561b37dbfd Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Sat, 30 Nov 2024 09:22:30 +0300 Subject: [PATCH 069/294] Fixed color of float button from sponsored message bar in new window. --- .../ui/chat/sponsored_message_bar.cpp | 39 +++++++++++++++---- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/Telegram/SourceFiles/ui/chat/sponsored_message_bar.cpp b/Telegram/SourceFiles/ui/chat/sponsored_message_bar.cpp index 89a71b14c..adce1fcd7 100644 --- a/Telegram/SourceFiles/ui/chat/sponsored_message_bar.cpp +++ b/Telegram/SourceFiles/ui/chat/sponsored_message_bar.cpp @@ -89,15 +89,10 @@ public: } [[nodiscard]] ColorFactory GenerateReplyColorCallback( + not_null controller, not_null widget, FullMsgId fullId, int colorIndex) { - const auto controller = FindSessionController(widget); - if (!controller) { - return []() -> Colors { - return { st::windowBgActive->c, st::windowActiveTextFg->c }; - }; - } const auto peer = controller->session().data().peer(fullId.peer); struct State final { std::shared_ptr theme; @@ -112,7 +107,10 @@ public: return [=]() -> Colors { if (!state->theme) { - return { st::windowBgActive->c, st::windowActiveTextFg->c }; + return { + anim::with_alpha(st::windowBgActive->c, .15), + st::windowActiveTextFg->c, + }; } const auto context = controller->preparePaintContext({ .theme = state->theme.get(), @@ -125,6 +123,33 @@ public: }; } +[[nodiscard]] ColorFactory GenerateReplyColorCallback( + not_null widget, + FullMsgId fullId, + int colorIndex) { + if (const auto window = FindSessionController(widget)) { + return GenerateReplyColorCallback(window, widget, fullId, colorIndex); + } + const auto window + = widget->lifetime().make_state(); + const auto callback = widget->lifetime().make_state(); + return [=, color = colorIndex]() -> Colors { + if (*callback) { + return (*callback)(); + } + *window = FindSessionController(widget); + if (const auto w = (*window)) { + *callback = GenerateReplyColorCallback(w, widget, fullId, color); + return (*callback)(); + } else { + return { + anim::with_alpha(st::windowBgActive->c, .15), + st::windowActiveTextFg->c, + }; + } + }; +} + } // namespace void FillSponsoredMessageBar( From afab863f11770a28c5fe20501ac38e9f761247ad Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Sat, 30 Nov 2024 10:01:48 +0300 Subject: [PATCH 070/294] Fixed non-closed last tag for inline buttons in HTML export. --- Telegram/SourceFiles/export/output/export_output_html.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Telegram/SourceFiles/export/output/export_output_html.cpp b/Telegram/SourceFiles/export/output/export_output_html.cpp index 4bdb71eb3..eda916d0a 100644 --- a/Telegram/SourceFiles/export/output/export_output_html.cpp +++ b/Telegram/SourceFiles/export/output/export_output_html.cpp @@ -1549,6 +1549,7 @@ auto HtmlWriter::Wrap::pushMessage( block.append(popTag()); } block.append(popTag()); + block.append(popTag()); } if (!message.signature.isEmpty()) { block.append(pushDiv("signature details")); From 979973745b58ba1e582ad60e170b1231e5865cbe Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Sun, 1 Dec 2024 14:48:32 +0300 Subject: [PATCH 071/294] Fixed build of notifications type included with another Session declare. --- .../SourceFiles/settings/settings_notifications_type.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Telegram/SourceFiles/settings/settings_notifications_type.h b/Telegram/SourceFiles/settings/settings_notifications_type.h index bf4af8222..0416c929b 100644 --- a/Telegram/SourceFiles/settings/settings_notifications_type.h +++ b/Telegram/SourceFiles/settings/settings_notifications_type.h @@ -10,10 +10,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "settings/settings_common_session.h" #include "data/notify/data_notify_settings.h" -namespace Data { -enum class DefaultNotify; -} // namespace Data - namespace Settings { class NotificationsType : public AbstractSection { @@ -39,11 +35,11 @@ private: }; [[nodiscard]] bool NotificationsEnabledForType( - not_null session, + not_null<::Main::Session*> session, Data::DefaultNotify type); [[nodiscard]] rpl::producer NotificationsEnabledForTypeValue( - not_null session, + not_null<::Main::Session*> session, Data::DefaultNotify type); } // namespace Settings From 927d7a3aebb2dc415bef6bdb96cdcaae3fd8b31d Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Sun, 1 Dec 2024 17:26:29 +0300 Subject: [PATCH 072/294] Renamed sessions_box to settings_active_sessions. --- Telegram/CMakeLists.txt | 4 ++-- Telegram/SourceFiles/core/local_url_handlers.cpp | 2 +- .../settings_active_sessions.cpp} | 2 +- .../sessions_box.h => settings/settings_active_sessions.h} | 0 Telegram/SourceFiles/settings/settings_privacy_security.cpp | 2 +- Telegram/SourceFiles/settings/settings_websites.cpp | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) rename Telegram/SourceFiles/{boxes/sessions_box.cpp => settings/settings_active_sessions.cpp} (99%) rename Telegram/SourceFiles/{boxes/sessions_box.h => settings/settings_active_sessions.h} (100%) diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index cf2055b31..42e5c7ba1 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -322,8 +322,6 @@ PRIVATE boxes/send_gif_with_caption_box.h boxes/send_files_box.cpp boxes/send_files_box.h - boxes/sessions_box.cpp - boxes/sessions_box.h boxes/share_box.cpp boxes/share_box.h boxes/star_gift_box.cpp @@ -1405,6 +1403,8 @@ PRIVATE settings/cloud_password/settings_cloud_password_manage.h settings/cloud_password/settings_cloud_password_start.cpp settings/cloud_password/settings_cloud_password_start.h + settings/settings_active_sessions.cpp + settings/settings_active_sessions.h settings/settings_advanced.cpp settings/settings_advanced.h settings/settings_blocked_peers.cpp diff --git a/Telegram/SourceFiles/core/local_url_handlers.cpp b/Telegram/SourceFiles/core/local_url_handlers.cpp index adcc40385..48705366b 100644 --- a/Telegram/SourceFiles/core/local_url_handlers.cpp +++ b/Telegram/SourceFiles/core/local_url_handlers.cpp @@ -31,7 +31,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/edit_privacy_box.h" #include "boxes/premium_preview_box.h" #include "boxes/sticker_set_box.h" -#include "boxes/sessions_box.h" #include "boxes/star_gift_box.h" #include "boxes/language_box.h" #include "passport/passport_form_controller.h" @@ -51,6 +50,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/window_peer_menu.h" #include "window/themes/window_theme_editor_box.h" // GenerateSlug. #include "payments/payments_checkout_process.h" +#include "settings/settings_active_sessions.h" #include "settings/settings_credits.h" #include "settings/settings_credits_graphics.h" #include "settings/settings_information.h" diff --git a/Telegram/SourceFiles/boxes/sessions_box.cpp b/Telegram/SourceFiles/settings/settings_active_sessions.cpp similarity index 99% rename from Telegram/SourceFiles/boxes/sessions_box.cpp rename to Telegram/SourceFiles/settings/settings_active_sessions.cpp index 4328fc443..2b8368b4d 100644 --- a/Telegram/SourceFiles/boxes/sessions_box.cpp +++ b/Telegram/SourceFiles/settings/settings_active_sessions.cpp @@ -5,7 +5,7 @@ the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ -#include "boxes/sessions_box.h" +#include "settings/settings_active_sessions.h" #include "apiwrap.h" #include "api/api_authorizations.h" diff --git a/Telegram/SourceFiles/boxes/sessions_box.h b/Telegram/SourceFiles/settings/settings_active_sessions.h similarity index 100% rename from Telegram/SourceFiles/boxes/sessions_box.h rename to Telegram/SourceFiles/settings/settings_active_sessions.h diff --git a/Telegram/SourceFiles/settings/settings_privacy_security.cpp b/Telegram/SourceFiles/settings/settings_privacy_security.cpp index 3222bc248..05fe9a236 100644 --- a/Telegram/SourceFiles/settings/settings_privacy_security.cpp +++ b/Telegram/SourceFiles/settings/settings_privacy_security.cpp @@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "settings/cloud_password/settings_cloud_password_email_confirm.h" #include "settings/cloud_password/settings_cloud_password_input.h" #include "settings/cloud_password/settings_cloud_password_start.h" +#include "settings/settings_active_sessions.h" #include "settings/settings_blocked_peers.h" #include "settings/settings_global_ttl.h" #include "settings/settings_local_passcode.h" @@ -25,7 +26,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/system_unlock.h" #include "base/timer_rpl.h" #include "boxes/passcode_box.h" -#include "boxes/sessions_box.h" #include "ui/boxes/confirm_box.h" #include "boxes/self_destruction_box.h" #include "core/application.h" diff --git a/Telegram/SourceFiles/settings/settings_websites.cpp b/Telegram/SourceFiles/settings/settings_websites.cpp index 55bf911da..836f20ab4 100644 --- a/Telegram/SourceFiles/settings/settings_websites.cpp +++ b/Telegram/SourceFiles/settings/settings_websites.cpp @@ -10,11 +10,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "api/api_websites.h" #include "apiwrap.h" #include "boxes/peer_list_box.h" -#include "boxes/sessions_box.h" #include "data/data_user.h" #include "ui/boxes/confirm_box.h" #include "lang/lang_keys.h" #include "main/main_session.h" +#include "settings/settings_active_sessions.h" #include "ui/controls/userpic_button.h" #include "ui/widgets/checkbox.h" #include "ui/wrap/slide_wrap.h" From b6fb3bbf1df6ee347cea5f9fcffe97eeb2340d93 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Sun, 1 Dec 2024 17:28:08 +0300 Subject: [PATCH 073/294] Fixed build of shortcuts settings included with another Session declare. --- .../business/settings_recipients_helper.h | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Telegram/SourceFiles/settings/business/settings_recipients_helper.h b/Telegram/SourceFiles/settings/business/settings_recipients_helper.h index 8be1d42dc..bda2026f2 100644 --- a/Telegram/SourceFiles/settings/business/settings_recipients_helper.h +++ b/Telegram/SourceFiles/settings/business/settings_recipients_helper.h @@ -74,30 +74,30 @@ void AddBusinessRecipientsSelector( not_null container, BusinessRecipientsSelectorDescriptor &&descriptor); -[[nodiscard]] int ShortcutsCount(not_null session); +[[nodiscard]] int ShortcutsCount(not_null<::Main::Session*> session); [[nodiscard]] rpl::producer ShortcutsCountValue( - not_null session); + not_null<::Main::Session*> session); [[nodiscard]] int ShortcutMessagesCount( - not_null session, + not_null<::Main::Session*> session, const QString &name); [[nodiscard]] rpl::producer ShortcutMessagesCountValue( - not_null session, + not_null<::Main::Session*> session, const QString &name); [[nodiscard]] bool ShortcutExists( - not_null session, + not_null<::Main::Session*> session, const QString &name); [[nodiscard]] rpl::producer ShortcutExistsValue( - not_null session, + not_null<::Main::Session*> session, const QString &name); -[[nodiscard]] int ShortcutsLimit(not_null session); +[[nodiscard]] int ShortcutsLimit(not_null<::Main::Session*> session); [[nodiscard]] rpl::producer ShortcutsLimitValue( - not_null session); -[[nodiscard]] int ShortcutMessagesLimit(not_null session); + not_null<::Main::Session*> session); +[[nodiscard]] int ShortcutMessagesLimit(not_null<::Main::Session*> session); [[nodiscard]] rpl::producer ShortcutMessagesLimitValue( - not_null session); + not_null<::Main::Session*> session); [[nodiscard]] BusinessShortcutId LookupShortcutId( - not_null session, + not_null<::Main::Session*> session, const QString &name); } // namespace Settings From fe7c06bc84024244b897c5e1d60bf4f3bb2a8b71 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Tue, 3 Dec 2024 00:49:54 +0300 Subject: [PATCH 074/294] Added Enter shortcut to box for adding or removing of shared filter. --- Telegram/SourceFiles/api/api_chat_filters.cpp | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Telegram/SourceFiles/api/api_chat_filters.cpp b/Telegram/SourceFiles/api/api_chat_filters.cpp index 2c8410b80..a686f44d2 100644 --- a/Telegram/SourceFiles/api/api_chat_filters.cpp +++ b/Telegram/SourceFiles/api/api_chat_filters.cpp @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "api/api_chat_filters.h" #include "apiwrap.h" +#include "base/event_filter.h" #include "boxes/peer_list_box.h" #include "boxes/premium_limits_box.h" #include "boxes/filters/edit_filter_links.h" // FilterChatStatusText @@ -548,6 +549,26 @@ void ShowImportToast( strong->showToast(std::move(text)); } +void HandleEnterInBox(not_null box) { + const auto isEnter = [=](not_null event) { + if (event->type() == QEvent::KeyPress) { + if (const auto k = static_cast(event.get())) { + return (k->key() == Qt::Key_Enter) + || (k->key() == Qt::Key_Return); + } + } + return false; + }; + + base::install_event_filter(box, [=](not_null event) { + if (isEnter(event)) { + box->triggerButton(0); + return base::EventFilterResult::Cancel; + } + return base::EventFilterResult::Continue; + }); +} + void ProcessFilterInvite( base::weak_ptr weak, const QString &slug, @@ -610,6 +631,8 @@ void ProcessFilterInvite( box->addButton(std::move(owned)); + HandleEnterInBox(box); + struct State { bool importing = false; }; @@ -829,6 +852,8 @@ void ProcessFilterRemove( box->addButton(std::move(owned)); + HandleEnterInBox(box); + raw->selectedValue( ) | rpl::start_with_next([=]( base::flat_set> &&peers) { From 18d9484ab1f207067a28f34163e6a896eb265292 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Tue, 3 Dec 2024 06:57:58 +0300 Subject: [PATCH 075/294] Removed Ui::show from LocalStorageBox. --- Telegram/SourceFiles/boxes/local_storage_box.cpp | 13 ++++++------- Telegram/SourceFiles/boxes/local_storage_box.h | 6 +++++- Telegram/SourceFiles/settings/settings_chat.cpp | 4 +--- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/Telegram/SourceFiles/boxes/local_storage_box.cpp b/Telegram/SourceFiles/boxes/local_storage_box.cpp index 647d6e0e9..ade6a4ee1 100644 --- a/Telegram/SourceFiles/boxes/local_storage_box.cpp +++ b/Telegram/SourceFiles/boxes/local_storage_box.cpp @@ -7,7 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "boxes/local_storage_box.h" -#include "boxes/abstract_box.h" #include "ui/wrap/vertical_layout.h" #include "ui/wrap/slide_wrap.h" #include "ui/widgets/labels.h" @@ -21,8 +20,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/cache/storage_cache_database.h" #include "data/data_session.h" #include "lang/lang_keys.h" -#include "mainwindow.h" #include "main/main_session.h" +#include "window/window_session_controller.h" #include "styles/style_layers.h" #include "styles/style_boxes.h" @@ -282,19 +281,19 @@ LocalStorageBox::LocalStorageBox( _timeLimit = settings.totalTimeLimit; } -void LocalStorageBox::Show(not_null<::Main::Session*> session) { +void LocalStorageBox::Show(not_null controller) { auto shared = std::make_shared>( - Box(session, CreateTag())); + Box(&controller->session(), CreateTag())); const auto weak = shared->data(); rpl::combine( - session->data().cache().statsOnMain(), - session->data().cacheBigFile().statsOnMain() + controller->session().data().cache().statsOnMain(), + controller->session().data().cacheBigFile().statsOnMain() ) | rpl::start_with_next([=]( Database::Stats &&stats, Database::Stats &&statsBig) { weak->update(std::move(stats), std::move(statsBig)); if (auto &strong = *shared) { - Ui::show(std::move(strong)); + controller->uiShow()->show(std::move(strong)); } }, weak->lifetime()); } diff --git a/Telegram/SourceFiles/boxes/local_storage_box.h b/Telegram/SourceFiles/boxes/local_storage_box.h index e78f10738..cc9e01b57 100644 --- a/Telegram/SourceFiles/boxes/local_storage_box.h +++ b/Telegram/SourceFiles/boxes/local_storage_box.h @@ -14,6 +14,10 @@ namespace Main { class Session; } // namespace Main +namespace Window { +class SessionController; +} // namespace Window + namespace Storage { namespace Cache { class Database; @@ -40,7 +44,7 @@ public: not_null session, CreateTag); - static void Show(not_null session); + static void Show(not_null controller); protected: void prepare() override; diff --git a/Telegram/SourceFiles/settings/settings_chat.cpp b/Telegram/SourceFiles/settings/settings_chat.cpp index a83b75b45..1dfda764c 100644 --- a/Telegram/SourceFiles/settings/settings_chat.cpp +++ b/Telegram/SourceFiles/settings/settings_chat.cpp @@ -1058,9 +1058,7 @@ void SetupLocalStorage( tr::lng_settings_manage_local_storage(), st::settingsButton, { &st::menuIconStorage } - )->addClickHandler([=] { - LocalStorageBox::Show(&controller->session()); - }); + )->addClickHandler([=] { LocalStorageBox::Show(controller); }); } void SetupDataStorage( From 0bccb35cb0e6f62d54fde046b53a021f6732b07c Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 29 Nov 2024 22:27:53 +0400 Subject: [PATCH 076/294] Use "Open" non-upper-case. --- Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp | 3 +-- Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index 6fa18f356..5d476d854 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -1220,8 +1220,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) { const auto it = _rightButtons.find(user->id); if (it == _rightButtons.end()) { auto rightButton = RightButton(); - const auto text - = tr::lng_profile_open_app_short(tr::now).toUpper(); + const auto text = tr::lng_profile_open_app_short(tr::now); rightButton.text.setText(st::dialogRowOpenBotTextStyle, text); const auto size = QSize( rightButton.text.maxWidth() diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp index e6b166802..27b17ad1d 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_suggestions.cpp @@ -194,7 +194,7 @@ RecentRow::RecentRow(not_null peer) if (user->botInfo && user->botInfo->hasMainApp) { return std::make_unique( st::dialogRowOpenBotTextStyle, - tr::lng_profile_open_app_short(tr::now).toUpper()); + tr::lng_profile_open_app_short(tr::now)); } } return nullptr; From ac13ac7a2cff51d335b9cf452c045eb394537654 Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Wed, 4 Dec 2024 10:00:59 +0400 Subject: [PATCH 077/294] Remove "Desktop" from application name on Linux --- lib/xdg/org.telegram.desktop.desktop | 2 +- lib/xdg/org.telegram.desktop.metainfo.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/xdg/org.telegram.desktop.desktop b/lib/xdg/org.telegram.desktop.desktop index 68a689159..e3d3581ce 100644 --- a/lib/xdg/org.telegram.desktop.desktop +++ b/lib/xdg/org.telegram.desktop.desktop @@ -1,5 +1,5 @@ [Desktop Entry] -Name=Telegram Desktop +Name=Telegram Comment=Official desktop version of Telegram messaging app TryExec=telegram-desktop Exec=telegram-desktop -- %u diff --git a/lib/xdg/org.telegram.desktop.metainfo.xml b/lib/xdg/org.telegram.desktop.metainfo.xml index 01a155762..488f56919 100644 --- a/lib/xdg/org.telegram.desktop.metainfo.xml +++ b/lib/xdg/org.telegram.desktop.metainfo.xml @@ -3,7 +3,7 @@ org.telegram.desktop CC0-1.0 GPL-3.0 - Telegram Desktop + Telegram Fast. Secure. Powerful.

Pure instant messaging — simple, fast, secure, and synced across all your devices. One of the world's top 10 most downloaded apps with over 500 million active users.

From ac5cf3bd80993c6291ec75072ad56583c83fa98f Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Wed, 4 Dec 2024 09:38:10 +0400 Subject: [PATCH 078/294] Update summary in metainfo and comment in desktop file --- lib/xdg/org.telegram.desktop.desktop | 2 +- lib/xdg/org.telegram.desktop.metainfo.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/xdg/org.telegram.desktop.desktop b/lib/xdg/org.telegram.desktop.desktop index e3d3581ce..100752f00 100644 --- a/lib/xdg/org.telegram.desktop.desktop +++ b/lib/xdg/org.telegram.desktop.desktop @@ -1,6 +1,6 @@ [Desktop Entry] Name=Telegram -Comment=Official desktop version of Telegram messaging app +Comment=New era of messaging TryExec=telegram-desktop Exec=telegram-desktop -- %u Icon=telegram diff --git a/lib/xdg/org.telegram.desktop.metainfo.xml b/lib/xdg/org.telegram.desktop.metainfo.xml index 488f56919..a74be9893 100644 --- a/lib/xdg/org.telegram.desktop.metainfo.xml +++ b/lib/xdg/org.telegram.desktop.metainfo.xml @@ -4,7 +4,7 @@ CC0-1.0 GPL-3.0 Telegram - Fast. Secure. Powerful. + New era of messaging

Pure instant messaging — simple, fast, secure, and synced across all your devices. One of the world's top 10 most downloaded apps with over 500 million active users.

FAST: Telegram is the fastest messaging app on the market, connecting people via a unique, distributed network of data centers around the globe.

From f232d329c58bda86dcfef30ff205467120f1ec5f Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Wed, 4 Dec 2024 07:59:37 +0400 Subject: [PATCH 079/294] Add transparency to the preview image --- docs/assets/preview.png | Bin 1087694 -> 1241708 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/assets/preview.png b/docs/assets/preview.png index 20a6e91a28d9a07c64caf72d36d4e8b04b67f33c..808d016f34fe2d4156a2bd26e8cdbe384f888b65 100644 GIT binary patch literal 1241708 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 z zfp$D3TgS8Ihbv9|{=W$WrJUfGvgjw$Z&v=iFvSe)raE*vJblXJj5}hMBX{&tgOtWb zmQ{M(TFr%-l+1hphel@SgJ1I|~@Hiwjd-aL$$1K!#X zDP#WdVeih0E7hj68Y%9ZO7CwH`4P6#M2;vzA-ZpJFw8+~q=3%*nZkQ9!n42l>xD!8 zERge>sKB!8HK|XF(0l(I^!aYH3c+#x-COdMxx0f-Ykd8cdRzeFkb@EnnXEKu>5|}N z;WaVWavgqt+>qRMtI&RdO@?6(%ZMtaW= zmR`c8#A41WF?6C2|JEBi|NE7_h~ZW|O~tUUmtjZ%7{W&j)7oybjq|J_%0DYtnDez2 z1?$ciBlHyod{imfeJ>eSwXtG@8AR`e#MRzZZyFE@yVqp(EZ}K9y4OU4cx~7kA#VmQ zY9w-BlgP%7awa_)w-m)o{n{r?bkd@rkJL1phe@4l^-cP^0KY# zkNX8S509$jvO(Nxm9^WqsQI z>7ePC)lRQ2nXHyNx?qh>P_BJrAA@u$Pc1~}25i42sv1{BN z#zc6nH#<@|gMuH6a@p$5*;hV8HTSF03HX#eG(wNtLN(Plwee*_$RA0}G}^aj^mn%! zN`AQmu3vTE1!G-*lHUtyW>8a0_6ZFVzx_KX|mg04pH<7rk9noDP%<4MN zcLdd_ab%!PNKCb+IzQf1aza*n)-(;$eI5uu1P;crr-rTko!RVPv9^}VF34>HZm#_c zvTk(EC3k(Txtc_7pt;w7(|vhosRC`G?*Bv>-UX?lQ}OxOU7DL9+@P(7=PkP^no^m* ztebZ#PJGfD`n)wRDP5=j-750J_aUqXb#`>QX1q_4x2KL^-b&Y#*BSL(w19I)a-nb=xZSQzbE-%an)ePfj6 zG$VI8%)RwLDsYA3o`BcfJI$Z5|5G$mj;NN!S)-zr@Fc#3t?jVO!aTi%Svfc=pmOM~ z0+5h|gamfrxLuHIWaGw+HgFfON=^z3G3Oh_z5ycZ;v-@QsO|TpbeLO7%rT%dMueNpy&= z>#Dcl#5(66m!2qd>B3UshrCsML`eWg?(OOG_iWUuMS)^1&LojC(EWatMVL}G2`SeN zfh2B3gLm`~;;suLo+yVB_3lE&(Elzzah5G_7zv|i#GcK5MPTh@S?l$YrkOPv-*#IE z1@ITczW}1I(vjuolh(>t-RGST;FuxNPsv05NM$sim(7mln-F7G#9ATPHQ=tkS78j0 zD|A2a3X2acmc-7-+^}sah{+plf^hX>7g-62w-G(OYN_{ z?L+!;lDbfylto_ZTojnp+UL22+*E5F=u9u@YF0>KG0cuF>}p1=9}tFqayOh09S&?e zO_P$RVTagtby5k#&!OE+9*h8D3p65m>pK`gXfbon6Aq~^BPrT4x~s6n+YZoI=pwed z9AED*MxPp#PIt^*?n3UQBa4xmBL6a(HZdZ`2*0v<@^;G-DRZvT1Y7Oy@) zr6(IexB;*5j5EfdeYd79+47t`B2_|H%*$o12o_Pt#{my$MMQh;0R8gQp&r*!Knqr1 z&ebBVz&;6%nBYlN&tO{gOGR5peZ5Q@^1x1bAK->omX1-~4%d&If7c8mk$9CfXqU zdGZ%b0_*6vi=DiaU{p#Z%ZtT6!T@32kGiXCkAj6x|A4bs=8^}$uiQ(eR#${OK|qeq zoRE6uj?$i-$r*`J1FEIIlX!=UF}QD`eRKMED_o%(MVzWAvCk}W8XmJAPNOJy(lD4x zJuhbfbeBg8^gEqtq;1$kYLv}{aAjao35Qo?7=3LPdSlZfY%AnW^CO4_>nl!`Uf9b+ z#UJG#z83GW{x$g>_&p@g;X|^Cx67F3%QhVz=~^CH>Ip}JCR#~GDw$G`*sk!BYYqZ) zwJtS@GFB1mz)@Bodefx7%Rj?@V)}hAE(qv3yX{UU@;TK(1N|nw(>T#g1-Qc1j}kdf zGu#tH8L8$X1>qQ>{xsg6mJ@v*r28m9B;~~`Ra>L|(_z)q9r)Wpc{pCH9ZSGRl;CJ^ zU^+6J+o83?Ll0%E%ZtyJHp0?g&&0@^@vhhG5RA>-raN7zX7WPQxR!(S>OBnLXm9-S zcf)CkBxay&>DBs*CMnT(iw@K4npZ6?-q^2raXo&>4HEW<=PgQ)=j1kK&{7nqq|Ygv z$}h0on$n5WTQ(!VVXfm;?gy=2-0fR*hKa{YCsdi=9{{T;Q9Tecl^>DcL6rCdmbIL! z%6_9W!gXF9+p9^o2KP@S_ofWbsOH*)cgje|)>e;7Z4!Mx*M0G%U{A(U z4ELYh=(jT*|K!iGkq}|8m_^Q7N%EE)PY$85&5~!)DaIZUDctmmW5lM0phc|$x7sS` zUO707Xs|SJBbfC542C{~Df3`0bD%aK|55-ND&6o^L{DxD?{1p`T+medI9^ozfrH)S z8F5wA5RME8N$uGR!`i%Aw5C)+ZBh2S;^{Mx4s%f@ufF93GTkYkLFK1{C*O+GkUDyF z9RB(S=3rroVdy?ke-ywYMUIxJ-gNI5y6!))vo9v{mC7|d?87ePtdNiGppOufJDRfD zmvuv;B5y}tKH+`k4g82La61*HO)(sgPic7~{xs3Nm5xtmQn1JAbA* z)bnBFJ0KiBS=F$WHa3+oRE$<(?|P+j0j1vC}MP(Pt4QnKqbWnja2_IyA^>05xOmDjxH)(>gQO;mhijI&H1xywbN`6z3 zsH?uixJH(|OT9w@D5MUZXv}&w1D_C8C8PQAc!o|G{N`XwS$?V)9TqmX}r9s`RjZg_|C2TEyy_=ZAG>n zUn(cd>kmo}@Yfy*<3xnHm89(XJ!0dCixv}wMH}VtdEsWP0$2B$mtoWg-5BGd-y%&E zQY@tSW7vP~=V^ZT6B?E14_sekoA_jTZne{w{!}7fs(D^sSs#V9+FxUk6LqAn@j<0& zAL9(u#S*Tp>b&sv>|Rt-npI+H#**Z&<`gf-QJZe)Xcipg)kx8JC(-*g!h0khohtFH z47f|mm@gJ#$5r_8t=iideh*+HS@OxTIC4R$8w5Yv0F?MnwZo0NL%PTP;Nv!IVS4c6 z5W_Z)^{T+BhY|>k0n5ochdEUw81h>jhbU}IhK|W6X-Z(Pc(m%XGzH?Nk;9ms%2&JJ zcH-i;o|k&R%9sAIe7g{dagge?kO{@*ZtiP&!t$rs7>X1EQ zX0(3NVG!Wzjx{HY{1y^#C$qskJTqxE2<(ez4mR9re#W~=w7%AP&i-uQg(N2N8zE(> zZVkT~3q9OC`9eLUZsdl_8*dIj3TNw!Mz4}0^D$f&zwfCVlm%U+u6gH+SyLpi1u(Mh)ODVH z2X7r~s@zjsc=h7DM~ZpS;O1WjJDhF@k3j3YZ_R>EU9CHH-k7Gukup3P=BF-GKzDiX z3=*qZyAgUQQ0vf7b<^}Hu0K_++0W%NH=#=fl7DVORUMo&x~UMQ|}zW$b(@kgzz!mpx$+x5)&lcj~2bVw4t<-CWXHL1U%>F z3mIH~6vg9#{Pz=VMjQeg!pWYA*;vNRS9D1t;bm*}kbC?vI31}?DhiQ9x(WPgd(5pB zF^}EkHKf0}0{gpN#n2Cv;CvyJxq(||?z^>3&MO?? z?U;4!m>Ak-5=Pgga52+Nfsd?a^ExEX1_$U{Al2?-h*BROC^zt6D*oVg*78)Jg^S|2 zbKy@ebcSzyBAnN_S{jU88dq_@Z1yN$wEWQ<%*TrU5Gl)|D2uShdHrbB3F{+aoTRx6!a15x}*ny8vX~g_b|d`tU9jQmvwaN1r>{AJ_X+No;Jw z^su|d`@&VfQ126Ui{RLiGk+AzE_n+&u)3*xA#C13Ys4Nz<+cGLZzaE0Xg~Az0os+$6X%p@vmZ@S&i!aj zjsn}gi@dIdGpLW)I&%I@NW>K@8Wx@>V19|)riT+mp?$f~1XaB~8ohVcJ4zypFItB4 zgp_>es0ldw(2{pG$TMY7{F8T*&-m(QR`^-ksjK??g?8uUd}<2znh!aBPa5)I2}_UP zps4cXW%79NZ9w;+yfmJG?H`S#uuOaKevt6d!L6~y0~bE&w)E-G(B;QP)UFQWtOqEZ zTAReXw6eH%C|7Cdt#GkI1>ruAKTf=N##}ST>kARnVH$BYsu_z^?7Zj+ z#24Ko*k;CKPvvHWP z3cs1ZhB++jKSnHdy3kj&rgb#xnOdEl-fP}N)XB7JqfiwLq8%1%pRPn-2S$hBC{T~T z&bZvo*7tA)|7CJ6&a}^D2cRyzCZreNnqOQE=M99PX|sl3|8p-(jdBaCHEkx)Q+c@d zhF=YHr@tW@4zMGg8pbi?k>E9eCSER>_-klt#oxG@znb}nt8j10^_ku9YuNYJYT}C@ zk<;HD=04m`2^-myH@|Pur^uzR7nDBJ)9JO#t&elJe)G0nx7$;sL`o;P60hTv{|g0+ zbEc`)fWe_Rw;fymwvM*sb-nw!`_F&bhpL?(#*ZVE?v}^_*v8#CYVU!>lh)z0DQuI$ z{b(9oLF2x%E&yeO6BFBAw9wVh7=Yd(0o|5{=+|se+nW%fJ2jwTYU~{%11axHe$PM zOUF9G8|&`Kz;);Pw*Pv7G6ErP5pwCfvH@wlxLAWtn1UBNsk`+Pd^aLYZ$rcsQ9G_% zF@VR2Dp-Xdy6Ef~+g9S$yK4e_40*njsSX+GXz?&a(`+C(RRu)M&Ww_h`v$ZS2jVUm zS#ub^c{=8Mbs`?rW>~bJ_-VGntEZfyT}S^>Wc3i#a(%HiQkIwmQ|(a? z%+4YxKB)xWKFON)NQ`oSwV7-3&FE^o?ea}+kga7iWhGLbaM_V1lBO{9mq1iZ6X3H+ zL7ur2Bat_fLA*fi!~B_{P()+YAiY$fTOH=|3UL9wM+E;N5tK0~n0@7^Cy%i5dh^?< zoLGyzo>~-M@pe{PjOLSiA^|qZ&(-}S9La;vQEpt2DH*K6Bn!`jV-rys%E3YVJkusB zhx}Y;t4=VU*5u@UXR8<6_Qfxf`^x75?kKIiWCB?b4H2j@?pBwtiFc@{Q68W2KU%djWL0O$X~g&ZY-Lo zb8RpWdyBU3N;yJr5BZLnL5ZW>j)qQ)cFYXBl5^PiGvhyzp_Cz(fg2yV3f*UtWpq321G+p#!?b`X-od`L_XS$`i0F&*8 z&|V%@T8^%hZgLfUm-&yE7dcoC=0$Bit<~uM^}mL+AQiHki6%HoelAaR*|jL~efAKm z?|2P64MU8qqxEJ)qRq0TNr&H|=;`rQ8Kw)v6t!1f*FmyB=|6wxV?{L0mHjw^bJCX~ zPv?so%9YXj3KbDWr?*Xfxc7c+nEhmLKUkG}{`~pbYcGkC;xew4!&@h~u zUw&jLOlh$1RwOP(WM(GyCDxz=HSf?$6RASnt@&_pd}7LbkBirFin?KORI$8bLNU1$ z{wBbW-g)Og9(|9EJ~||}*7ud|1^ofz>r?!i$Mq|;b6?0$C;zj#i3nA8SJ>o*B}{dp z$~I3w;3l)zQOKCJkl4JOL4R=6%2#ATbFRV)70S6UD8-bTHy7ohOkU_!?7I6m$W~AJ zW4Qtk#a0U*e>{(ebjscf&wFrtV0{S06n*DQzk8LU@-TjLzMx;yO-hVl*_@~sm~`Zb zDvNMxDg(2zZxr_t3sqp4{xQ3#)mB_F{lsP2{N>`hb9USRW0F5~L-yOotkjwR{p})v zWEF#wN7$Bb;9??{r}|-2icA#8C8w@RZ2xc{GcdusnZlNaqm-DbI_iVK~OHsBA{zB?zuQ>LcjUp`2n z!^ZIh*5`gqzcDyCJd1B%?oNMSHep2brtf`%Ahp?3iE6w&E>o>N2f2UT^G%CYH>HV* z_D!GKv}>O>=&;>Yb=TC4J9m>+l<||s=u(?gg+Dc)3*x&ll@tibYC$zeb`kAo;Q4MB z=qzYNv{Q?|tvay7Zm*DGPl2y1ijE#)RkxndkdD3!*6v756 zDL=>VbreJO7xMAX+yhu#$IRwnT33ctdO0jh~;VZ zdRekEeE&^7>Ay7TwcPFo;Xpa05<+*^r@DvXq}9I0GF-4LX(6U!DH!YzqnOdW8T9 zW{R&x9#VNaV(Kd!8e_sMJN0Sk5OzbG$|?ru9q*}Stcq$xT24Z4#=qb`qJPDc*kKDL z&CL=%1Cs){&3GP#J!!cwNnAx#`9@p-=|_Fi`fArZxEbu19^{R(wKppJKS8)}-Atpc zIB&U-W{U2q)b$?g3+Z}-Wt2>mmTa^vKXQj-1CkC1_9seoT;U1{1eKKD5FYYc)_%zA z6w@Nykkv1Z1ITYBQ7{r{UvB6$t(6_5ilVk7f^-_`Kza*i9otH{eFp}Mc(C4MtnUK_zs1Opm9Y7ENivI*qND48do zd(GK!*Y>|=T>I@H=O@++8CWO;`2tNo#er>$l2-;lBFFwgsZ`Z7XaIxoq*WVC&W-!p zWE<$Fc24i49?0?Um;p)OmOHfxyNl?WaJX+jX};@&pQA=sKD#F&iQ0PIlcA>Sk41?n zh2pvDrSt&9eX#yuIW0^U0Y_a;mF3`xH(5~s`D;A>F_$0Lp7)tuwjQuyL%Lb==Tg9l z3NhZrC=PEr?>W=D02NR}LtNxc6Is$I|N6r>vpitl+eQyfHV-a~++< z3>n@a8E+gm4$trQc_Xxe*D52fBAP18GoSYEnupnYVCUSAZ0koX;h|%4#fs*@X%g{U zQ}r&t-&Y*jt~8+sCOBQQzm;Zp1{7|9{yQc&=f(SX6YBJ+Sytgc$cOn*Z5%x=Q1{e95?UH1=o4Q>qt2T&FV-InFKk$SCY%~Jk#Tj?S< z(bbXW{90c9Hzrc&|4BAgk2#X zYxwXES;Ba-u>OEXZ=DSm_7lcACcU$^9i?8k*KlqL`@tFPL59!5EC&G>L1 zOWWJB$xs$dI_Kgo-igk)DlyPT52%3Y&|D!J7MBypoAW{yp6JV{*$v`F725lcW3^=o z#$Zv=6d;zKf``iQ?@1Rid!{2}(-WG|o9hfVEv2Gr83Wm&C!AVI)K6}M|K=L@limXmV~9)>G2XJu1Un?6>N&x6{2zR~E=IS=-nnrMsk?$Lw|%j%1{ zQ<>MyuvuukoeDVJ!Gk=PP?Nnk(8NZ=uki zA2z8OurlBRl{kzLC%#1yF`+hY{?BS}iiDaz&w7kkXf`9RdV2KC>Us5TyznJNtSI@l z*@~Xiw*CdoZd;l&mL>Ajdts+M^P)$=h(n7y+=JFkXj)cVmBdV9znm1aHjK5)=qwK* zjsG>`)9OA6v>t1gCWyWAnWyRsB2{NHnv_*2d&n0{aAxnLjP&;fzcctLLm6O!dH3uI|Ewa! zbUjMce@yz;|IScn0G0S%&+{A$pzEc2w%4IdO$wkJ_m6ef))O3jpZDX*=Zurlo6+I7 ztkbKo9S#f-^MHh4ltpeCcJjd}$1^yMzM{mBKi2o})4B~)9^t=8jG7I{pp@)Zu^C-%&uR9S`*8|3;n-P$Qv%r4;MaxBR zmP2P$sHw`9d`cUJGU7bu{PC%b%7_vD06g%8g?DB>uuN}e>3`Mo$P99OV0SD@!W0oC ztgY7i5XAXO0?+1e4|Mj!cbXo7C{;e~Cp!{et9G4d-Lk@W0fB*2|EX--O}<8V@&~8P zj5EU5eDyUCcadkEQ<#+1H|lyJ#$2UK6(>&(>K9kDW)h$M1B#6DY$-c{iJZP-rn)wQ z#bp-0F1Mg8l?_Do^Yp(u_K6@FJQru&Nwb43#5pO=?R_`2iI{hSxolEKo@)KG-Mg5k zs%f{^UD%L#K_P0E_$wpYvZy-Y??}L#1N=A7+8wN7zx%4UD_B-c-NHQsbD=UN@8j-m--|LRr0XEg%Zqr=f8ataX8v3Ze`+|eUrWCX-Iq&Q(t@M>yjMmOe3R@o3jqT& z+~B>gm@S?2U#>X(i1xr@wR#;DzZb&Hs|1v5z6xQ8LXLJ7_8Y)vOZ|&9lYBx&T+^&? zQ(|HJSDSqKrMO5(0P55cK#5UO3*E1^pz|)oR(`m*-Kr_d$C*bZ|1M06K zG-10c9tn$p>+7^t0P;aB3Iv#12`z|9Xm%~&NUq*Gtq-02krvt`TxxHgQX4bX4GUjh z2Boirp;ss4c5a)+^K{cAkk-qM<*q@K9Li;NvMC$n7@rFU6jBy&RDOO14iPDCd5)az zH*Qf9LL+Ekv3zI|jC;HNP>eWc7Z6#EL7!OK`~eV8zCh`Ct&EAqsw;TJxJCpSpVe!2 zW3pPEb?6NLObmEQe5v?K%mjX+we{^A^+yNamxb>e^93ay7=!TXu;l9B^ler>wP_gK zuNlghD))W;4&v6OJKCtwUHHuLyCWbp4vi4}136itFp^;zNv^?6VCI)=K z65dnQaQH57tekm6J~L1mUHqXr4NJ7dK9L^UE=(z$if8N3Oc3u{8Z|F&-|Lw(h4tWX z-@-mcyKvLPX}@2bKlWi%M?T?!Hd%UAO%Wct4ObfnzjiY;(aTe*c#4y3N|G!6iyNYC zb-+iJ_cQkAD=Oe7D1b9DP4z&I&&I_X2CWJcwV{J2JNud1`Np{9!{*7HUI@$s`3)to zKI(M6e5K5f%fE+u>FdFxj(>4uL}p=Ni^Gs%mKSQ+7$AUaw$(iTZ1F^viOqV@=aV|g zvV=a37d}rqEoUU$*JtV&{tvII zLAqJNFhEz+H4X7O($=`O=mj)ZNu$5`1UBZXD$*EgLP|e% z@zq7xA1xIGX}S`A=Oqhc_RyKMH)SHCGDON_Ase-Wf^AP|*6PKl)t{`t*uyH>n=k0J zV_zS)BC1;K=-`|fbQ{guAI8xok8$2!AGKjV%^vzm`>a#uuxBIPVbd~11p1xJsFlT4 zqX+X_T*D`X7hX*(w}kTTNBCC!T^n>4;n1$Dzd5i+vD&Sc*SOc_UBIx#f3r#aIYjW| zFPN!X26oCFe$wIeVn|JYCZOOK=(){OOJ&rKWpOY*0Fp10#W^MR_m6FJ^OKJA55o^0%he1$xC2}1xengS z)IXR>7e zo$MMxlo=lJ!^^P*<>$Prw<4awI%mKGn$Ts({8P!_3YJkrnhj40taq;dsxGjEunw+n zwr|SoYVMN3g{2xaGE;7Rf^c#3!Fr3KG`=BoX;Yw zWLjec-?$|k7-Rc6zKdEKF`a1_R?z={00%+%zI<=p6KkDBQ3Tpf2Iv*3GXzm%iLGMQ zcc(DX!UBS?0y^Wrm@sl}9vY^X$}K|aun;jt$>k1b<>iq&oinA#iL8oYLfvwU zT9oKHZ!2SFUp5#ewSKdyV#rQ+V4oVBQ}~{l+-j2BJ@*}-f_J_1J8dkz<}U6J^^D6z zfR`M5Dx3k3lODa~oD<6dn*)9iE?fmUCLX-=OgMPfv)wb`iW{$li_a|2x8@vqAw2$r zEwJ*;cSrBu1fRTYd?DWhUh=2#SMX2p5&zB__}5S7A-`i!KNjwaz^L5ySaJq@Z*mc%_gVbtnyX62*@xlVA3nYM5~*V1nU}D!a7a^u zUyJ7O!@~~Xly!Zw`(&1CQ0+9H)kFXu&P&C|Pdn*ILrhmgI0v%)j1A1n6ddqrAk0S* zP%t7xtn=QQ$S@=SK$&QJuToqecOJL`){3QHB9fZGOgkIESY*Z~vRclCjlkQ9+%axj zBSxh1jLWIWEjnN%@^%z3lX8p{Gz57_Iad$z6jX15G;&_vHTGJRCzhnOIX}jP z@)7OTbR_pNDq``9Os^{Li#-&vzxg^kKozLp9kyixUQ{R^4FDoU?O_jNRaV4lb8^N- z7N@BD#09U4S>dXr@5IwL{2V|ym6Mv*ZjP!Pa4r6vc%6-Ah3|r@w3jX|xdzJS`%+*q zBROZ}MVywhY*okW-O27|D$j~sTjjnqHkZE^!CC*Df%Y7=$Z+%^I^CaK!eGKV6EhU= z)0TzqZVSD-4)c@l?7K68IoSh6wX*BkRbzQyg*%S#VIlSI^}YXxL^YZ5lXAqY~+>9Ma|St2^Sb(`{?;*yrqwx=)R5CB7$$MVHtK{ z68wr}47Bco2wq^sWL@9p?l7+AFK<-m=TVVAWATTn6|@41O! zx$(s#H7+C)-h1}lsZldU(RZZv?0COK5@X^yK-Nz1TrT@Qv3B>q@7wn2Wyb?3n}0w} ze-ggWN*3F(25kT8H+JtT{O-*%sn4+Q_O?J7*;sbBOu`rCei7J{K(MXIq(WdZ4g~Vz zc+rbq1eafaImu#v{p(*RFb_dp1OelHBj`7tWMon{U3Ez|~?PSbOK4cf!X$_A$8Oh8uF{Pbv7CH4`2O`x5t$$LYjq#lK-+cI(o)wuZ4qMvmVOLEQrH2?8|77R73x%qU*VAiLP?`+NZapp($H_Mld z!^lkzhrhk$;4_z=+i{!IUjHum@@HQbd6GUI z{%+?z@aeaeeOH|UpZw0laOX`oz+d@;%r9Jz8l3Zw8{xk`^oJ#%UkyuoT~F1!qwBt+ zyA&ud_D5eYZ#8cfeERy&!@FL8YUh(b?LxTXTfc$fyFU!8+b;WL+PHiDFq!l7_rQ_) z+~|^QJavkH`T3o2!^d7*@|QQj*M7YjK6>6Eh4;H)dHh><+>)6;$IjRAD0ttMm%%Gm zb)2!m2d=mQ)((Fho+)U0vI17WK9?E8aR)Ng7goUCTA*L@Lwd*?N9 zVacEW=!0K}O?Uh?9KO$M!c{RFK?Qj{?;UG42|SfGG+dOe=^8O7Ysf8CHE`TOx8h9T zD6zE^d2D(qSqAc)uV%zFGu8uC^jY*MHTgNPfVh@HS$rA(mp&tsjK(q5=zV0tvAi*Y zwjMOl;2D*|T+LD#XmI;{-|E z@d{KGbe8cg`z-ae0M&ecHO`4rK7WXFKg9r!NbbhR6UtE*+VcT$G{Y*}QmH-nwlY43Cadd$5??1OKTj$-%xzc;E6& z3okAruw`v4kGahRmJHWnztK7@7*#N@0W>zXb+p)K*2iNt3nMl5D38}g^2*hqa)lIA zTRWI;FxHI~_ERRaZ+`g^HZv8``|R{|;CtVP*7j}H%yFs{&8*J`zWY5`aNarlWc!hM z8Z$hR-4wHAzxvg$=C(iUto*_Z%G;L79OL`NeGd%{O}bqO79-$TlnciF;R`{*_q^vl z1PFJM*qzRJ?|a{yV~QbQ95Z+^KJt-|__matKLQ=&1p>NpU!wFdvTb8YXguebC5+o6 zh$<}CB3riz0$+5|ML9`hY$t-VaX;f{#$zHQpd0UFPf1BvQAHJ<1DUB)Wv3$885eb& zaKZ^4*}TY#MW&+wu*g95>-`HC(lcaNn80!D+_}@sC*#lfy6djHa#F?5de*bX-3J27 z!sf*SlH-p*KId`!@WT)1ww>rXJsm-dLD_$}^n`td{WLHzK~qVO_WGp$@3IHR-*r6bGI-_R z{s%PQ{V7ZY`yTIyuBA_hRfjF1y^Qmyt2~{XZRdDU&F=llDB`5UL%9sVf(h7-UqnW)0Z88 zQOWuA!5gm{fK%RkKkR69!OEjo!O~jjLu=nM#T#ydzR7**jKM+2o)2HLP5AiZ>!6vn z5k_`Geer>?w6{WHtC(7NrWjjaxOtxqQpNEKvUT%9qpWAG2|>_Af=Ju^^V0lU; z48%y0qGjn~lJ$)X`Ah)$z%c6#9H=Wm9)Y=T((2s#7{mnjJxw5hA_RJn1he*y)>0g) z6$3SHp`H37aezgNd$B>**n!Q3nQxA9#pemiOMRq~w5a0wYmqfr1h_2svJqw|v)~+W ztn>9O%EcDv+HIg4dLwECq*#Vj@)`zKEElB`EXF{CSMU^|#j+GIgmbWQhj1R0=){jX z&5~L1YxP4ExEbUcQOI~RP2zw(-;D?{&DEa{=UhK!8V2do(cKP zig$1=x<_g(N}dYy6=Esgd_M`hH7_|1?A;25{5Ke&$~9^UOBf5Cu|LSOmYF-F5^3I|p?*JjNCs5Dji`#h*m#dnEjMmgB_dTP($mK@zGEsni)}3@Y^Sj=}h;Rg)Z`sRs;rPQIR}nQ<73v zr1n7LmF0_(;VSo|QxPs_l9#b$X`MvXpxdINSc>|@^gO`6MSooS9`ejpk@i=zGy(ZK z{s^7rYcmxqtm%q;aeOC@H$NJt{rLOjEVZ?H3k?3~C)JE`7h~||pTfM8PlDRgCHq|4 zQF1sA1lt4@M5biCIFAeLoxnHTcGIR!((4nSJAw&iz(^+_-&lH7Kn-LV7yB|dp2qw@%vrgodk!g#-=xhM8NmBRK)(8?TU9tqmM#o^l^m{Ni_5@KN zazO1eLSPn?`=mr-t5aeCke4jRZScDdpZoY7kNssL2`&y{ZRh|1 zAOJ~3K~(YNQc-0+M6yxxFUm)+T)C3Q&bDpaLM1eNtzZQzv0@8SYB?6KDkP{K5&)kN zsd&L4-mdL~yfEb0u(4C7QXJ(sJ>sbT`t`r{ZqDg(GXVFqvxo9_z*_(ZSrad)lJ+NqL4=kF&Htude zOeT5{JRFXnlsiDPt=-enwAnbvj>qm@M6bz39~`#o_&s=Y*I;S(y*+(BU&ZfQ5Zexd zT8jV`Qe0?7b{6rb)G>^NJ?f^ynk0=|kb0R-niHdagcL6Vd(+7RKLe;LW&%d@UlU0q z$6l!d*5*t3+=8)TKU$e%BHOhlY_V8P#x=wh6(*WxN^OuRj!+8(e!OICN%dhU9JD#s znV--yO^S*NJ+sgWHH#gJ^XTo&2kMyNt(hS#z>;{orpC=tg()lkxgfY~p@27^C#tqe?0b55WusRJ!=fJm9zIphoRQ8Fpy1dN4quDvp;mD?s1XA9 zp{)aUJs2x;xnBO8iw2@|WoKm`gL!~W3p-sq(AWdL$`!7JeJlSwun=TzA$nejb&;=w zuGW$nv*u<#3W??lyIg*`5w(ZWv3i%^n) zWNl5Hua2v@)qpBPD2?YALHxf?rWj-qEt|$0UxAO4dTy%@zFe~%Yx~pc0X0MM#6Z=z zyBkAmu7sx@|DH*2|NKwh3P1Vt=Tse6MHN+4@e~i8V-LDHn$d1ST)Zn~iYM$xHwiOd z+S048@Zz)<9ZVasYdi?Xi~KV8H39(J97tdze?~vWH0+xx?|a`<2H%3|BGg#^HD(|o z6RQSMvkWseweqSjR;M2P_3flpcn89%Y)+dhH!l&7RR`D!P+&Y0O-n|gLaqSpJ4m0= zE-xTS(SkyZvEo>3Dce9V+yp@YTs$`^0VqygI&q9;P;Kk`4k+TH#i;O+fMz-d&&$Cv zKCNf(syw(Y>OPDk;D-|(04(O}5tC7Ij-;df$U_t+k_l!>Y|XxmnxPHx_soOZkyJA? z1~m^c*I&*vQVCldg10a>6WPs8<@z+154Kz^s|lF*8m}HeHH?;PW;2Tqs>`K6B!u3C%6+ZpVSfXmCMJ99=%-fAU>+%kt_Yh z*I6+mQZ9p>3*9Rgy)#qlbNqe&f`xF{VMmay&2R6!7n+UDbUlqpqr5g^2iv@qbj&vQ zg%?&>m*UrqZF23U@j`6;8a)ffvKxBL(S@Ood8AF8q&5S(sS?Ru=_8gnH`W8H?)o^{ z*7z>UvAh{rO(PjB&;DkhRogIJ6UY~uxbX>IE?4eLc}Aqf?ld_ztX1-)P@%@bhWuE` zzih1p3^;rFab1S($^D!}sH_8THSf==;5~~)EhzzZ3BA(nIhZyZbPi5h81Ijir01!a zK^abl%HPzW%rSb)uT&o5V~t+{wau?{%i%gE$!iC3(!&Xo-y zwF>6Dnwi5fC=YRQ4R<{G3}gS&L#GaDtHD0$X`~jQ{PKkfU$AbqC<6Rtzu}%0&t324 z>z<`N9_b8KO4rOir`>Z>SuT1)h}c&WjVCi43VC9s3Z-p+AuAU%Q{=wS0kW-i>tXoz zHPwu9Hv{{y_eJZW>%ar{xwfBq=9xM9-5>w>#{`5TTQ&}q2aW@MVq<^OnG9?XO6$Jr zRj;D9#_dIRC<3-qVQx<3lNtwt4YLtbWz<$tMHN*{M-;)>@jz4rU1Km7eZ>VBMW7Rz zrpTVf{b405exH=d+D|4>Az(UuU9n9l4U8Z$GJuhxiRUK;D|j9gdC^Yq0u?9Y*$;!m zgD^5SLJ4S;Eqh-YnY@oD8zxzXiYNH_4coUb+XsYd^OjW7W`Ezhbt}mgqpyloZl{s} zM+^nYLtH}6X#p=fY}>vAwr<;=C0Z?7WJ2krwAJ#-gK0U5WGo3aUVd4HY)UbMK#s@B z1g;p_BwjFZdnDO71bKBW+n@6CNXFQLb4f@zsTS2LPJZH~gOeCFdvZT4N(O53mO>#91fiYlt8;&&i4F9Rpc@}dQ51_Wj9>eLmj2NwN23q2S4^CUM6 zjKk7g5j-n0FlVg?yJ!#WBO6b?t!kIgbe@gwU!#h^mh~X8Vip^)2cwBWMO?5ZhAhh; zTi002#gzmIFq)!8rq)=`9(HUx2jHaIFf%Tm&NEvpLY0l>d8sq$4gR;*fqbb6V1k{7Hu%{$Ilw^>k3{2(C0&1L2tblzc5)1UtEIVZ!fSYI!@?cx3uQ@N$+}4Em zov0+s=Pb#L3L}!nE2{tz1d=$0qw5|W##U~;NnZu#qq2E+Unn>5s9hwBTb|!(&Z~Ss zd#0$0#<*fqo%MgRTr6Ak!i|W9;a`=<-w1#-w$0W?epUpQLj*Vi1F^1$@mYamu+dE2 zn8yNRx{jI(bJ1JWd73H)XH6ImHu5=E&PxHIy$wZi00D>-)?qgbS! zAu2{NDq?VBjdCoZtRisEF@cki>Vg*^_SfF}v8s9Okn%yP%9ay4&$-Y_kvaDZJ?ps` z+p$SC+wR z*}9b_x-}Q8SS~xUp#Vcg%y6*5lQ;ry33OM$r6|VVa5_9JL5kCf<87mH%6{coCZHL* zcRsLCcmPCqb_u?kBB-v~nbb2G`y3!U@ckQi&%w6}|0O<{_2u5glAUaz94|7CM7s8K zpZgrKqhi)8O4Y`)zzAp-!C3S=z2Jfih{1&5C`#j^tnhROGI~Gofe+BadMwjB6@OX` zlwSN@jLR>-d_v$Cz5c4GqKe;*mD2=H4TDC*L75!m#txgLSE!9%RbQS*Wi<|QjQtVq5mbiFPAzuZm)JzHM zOdLC#rg~6SeY@AjoFgyF?$3*=j;NxFr%F`n#8pgFkS}K>?JFRgiWb#rJ70*Gm){ho zATI^eqA>zs=%J`Ivq+0OXL2};Wg-oT71^!md# zdp}D7V{MQpCdt!m-f2_EMa_Auf|C#>PgU-hltE`(bD*=e6Bhw0K8KW9$T^!2k>}L9 zO?EaRpI$}tVh1R@KCuMe(M59rnAOY>jYy@uP;Wq(dCWxB$}<#e37%&?4|p<*%oR(5 zw=J;*yaTgGZ4O8xcqjrf3`F2>&MJjLTLvc`jAK0u+l>teQaNxsFI#M5lv+6!cfuaO z1njZTs2iukTxN!xagbGwJLzqZ_OI`W8xXk^R9vW31Z8z13V?GoFGv+Z^)+`^c1zSx{j zL+r;ISnNrOH+1>G>fjYbnTZr%t_Zg?_#&NqEQ z02OmvmOqX`L7VRb%?w@>=kH3l-4oWvlI`ts+2S=$GU$;kalBn_>@s+2bIUh2caH@& zcfQ~oV_{z(9C7Gjkks($bw6y{vWW^0+;co$bBUgj43;~!FSk1<$se_q3TqM&XjsYr zu@VDt5k&BdF4{&Zuhd|TDiVG7%Gjp>+19r0Fnq_I)ogK^0{e3Q)@@MRZ}C3Y_KPmM z$OEhh%%X2=97XTaBA|(2Y*99NAo~)XsVI7@ju&N~fU(!@Q#p$Lgp$XTk+QC$iYlJ^ zF;y_O_+0PnD`!R_xQT^1;?IhV)QP-aXF5>gSO8gM#;)|fXaGkZdE~6N#rvyvNSs9$ zXyP<`1{cw!nwsT`iwPhUJcL5Np?u}3_?(DjQ;XTL-d71LkTv)O7ky-L++cF{$fJ)C zP>uU1-y6&wuo{{wVS06}v`XpTs5V2*%d4pXc_>f#z7lRZ_bi&MoHT z{cfaURD6|GyCKdj#!#~=nymV^iYk5wB74-YjeZ?bRhP_GG#ZbFU+!|SUU zykZdyNv%j>GJDU12f*w#Q}81NKLaMV8v>*T45RVog9; z_H!x#Y*79s8&8O&KHY>k$SdRAQWoBEZfax|oTm~snO9=rVas|3pkn#jqOy(iMhzeb zwUa$x(==j1bd47cB470UrXE`CNkAMJ!P)q70hOTolQ^u@UQ47;Uz|x+=JsxcB&)iHZ%W?g;2l zq*oJIn<5d+KsAlI0zj1zh^LA1#dqC9S;x=waTNowPQ}#H zb-=DkBj$Dte)uu0ay0{O+xpHBg`Wn0CL9rDD%M8DtOO& z&14HXrfr%3Z2S2_t}sK9Ol^&FLVSPI=8d^RW(SD6b9dWEUeL^LlriYOlJquOL2pAKIN^<>k}ZlB(dN1wE!EQ4F-aGfE1zli(Se{Z66m!z*iD6lz4CG7ho)Kg}p6KY=ZrT7~ts$^m`B@qWyJ6(SfV(TM z$zPLLxS!a#9-CHq58+4(dG=SNrXKqgAUpKapRwC}71OkWNqxHDymR)sroZ&1FU>Jt zV-WAz&we(sXvYf#{^A%O9ww&kt^~4g(W4OeiHz8?DEixu7bu?@w;$V9lw*FXMiB%- zzh7jv#cby)s;J_rxVY9JAhhf`fUzrJEJk;CxBnSgrk#M+{{DXd^HjaBXCkl-C`*hW zF*0LCb{PS{>GHUp^a7Ps_KJKim2%orFjjKzVp2P^Q<+e4ED7xxvWaW82%PO8k7e_| zPbR9CR@x=Inq{KMg9j50ti)#~0gfrnj0esALe=JpTTHU#pVR_vQC=!_sU=q7V?Df1 zXdlR&sOcc-)i<{XmMvWZLxY2`HM=KlsefpWUH8#uq>sC z7>`(C)KpmbP9o%~|%Ut6y*GY+jCJB`Q3&hR{`5Pu|nJPM_@omKrXx|YGDk~b>+L4rF7{zpq0N5owAdT z}(TxauPttfUbk=d$SucbKtX*iyv%6*Z1S!Ms2o1J;2%^=WI2!jY&5iY++R+mh=|+ zX(w$jUfw!)u0c+|%?hgEU7jDCLET|spdTK1=m8qjs08ZN)0CGHF5cTJ@-2>;w@%pr zKgX131Y(idYNVK<<%?=U8(0~^va7OX;5@qrEm!N<2(a!Ha&F%9dJn1a?lXWaPH2XH z@vCa4INb|pzx*}KKl^2%SY~fe#gBgUqmC?4T$p~r3to_W4}nj7@5UQ%Y}@_~Z+OFm z$NTulKTeX6$iDo=FMa`E_`(;w1oBh^*|#EfjBPsm?6YanAKSfQ!v^@?_r8|{j8Sg+ zkV6jfzZWHWv27Tqopu_19zn@ij`^t^2t>!%70>(9OD}~tzxmA`q(=G9JMOpxuDk9! zShQ$S8`HUpDyrD`;`-~aC%IsZq8IC~g0UD&mMrmL=54p#2K()|U)yJK|2Ub%K=0PQ z0g%Nw^w2{+Yggj1!w%acZAqmHSQce?p-Lpt#!Fo7cyhth6j+&@vRpC#T+3dP08?@p zCy;TzsUTNXNq$&Vo$nR{oV=VnPf9ej@*ZKhZ}d$;7KK!(i<~p{1NIs9TMAuuSMl92 z#)I0;)Vg&6<^EO7iZJ5or6DZLDVKnd4J|Jn7;y4*Zm}kpOLD@$XLO5)E1T1qo3mFm zuqvw9i=qZg4_sMw!=C8*-ledzx9W!~rhBfN(mXe{Zl;&8KcwJ#F_0)=rTktKmK(j7 zGVsAn)>>hb2EaauF_4vKI{CS(_&y5g;U#U|yi~>D4Kr|cQgiaOBz4Okl&n^p2;))- zjfxk$m1Fao2;3CF80|U|oq$c7&`Q~37Ci`!V=|$7j8U@CZrbvJlpANQDfpnee>8)V zVLtBu=)oNZV`}xp0S&?~Oc)69>^We`;;3kp8Jvj<(x^(iwz%tw9<1E&PR53rwbERwlF~yHX{!x<(ak#9S4<03Gi*SsOVt+f(6ji)eR#J^u!z@cCgOIMoWP&Zncnx zl+T9TCBB&9`UWrA9GIj4puh%H;-L!;6iFiRPK&26gz=Fwh+>4D%QD}BOPP`!G%v{- zWrM<$jaYp}R&2iglJ{CJj?h_7ob^+yK|d$iy@z9~MY*Aqt_2!vfqChl6JE+VW{QI^ zS`ZLY>jG2KFwn=(7^5OdYvZ)etqlNp8c8MV$bS?+o0b$%D+S)uIPRmOEVTDc)}ctm z_jg$WT390pa=7Jk*Vxrm;LM<+WshbmP7q5`X1d$xnd<&t^buC$tVQHqgJV#a3OAH1 z3&6}92?QujyoUu)HNU)mT5XNh{--mC&E zG&~z(R<~tEgR&wC$Voc8eu+VO9rZw(`#y?`7?cOQMG_u8b2o1pqxaIZ$exNn4gn#{0_BB^fGoyqUh|q#K(@$!#XtZw_MOFl z&pYqDX+IBaPg$Gdxa_jaa*R&|g^|@8gRa;g(?q09hRpp1=v`TIuz2A-IP&lnP|p(cdmnrVHf#K)L6;)JGMHN+4 zQN;uyzM^hkC_s^QAXdudcnm70G04S|q0ZBi=ZFvr`w;0A_GdKl^uDytbCBRDR3>ec zlq_2)_Mj^NEK;oGd21Y73+KkfUS&WFfk!GJBtKR+_Y`)W2M`T2j5K?Xio~jo=Fnd1 zn899x>ad@(eR6>!dHxmkdke`$3_Qzu%}S&p(9?tb8YXpAP1B612$qnJ$2;DYFX`ZifMuJ%)mBE2Fq7k`MPFmI~uL?pqm=d3j?88e;BA z&j@S%eiKj(mb-Kfi-q0oWkOoY<4)dlp1+C;LnPeaoOHC4a%F}&7ib^|l|WQ165XTD zqq_YblxLB)E=`PcWsy=Ym?L{F_c;G8-Zwe_UuNm!xx}njRTu{X4(GsFaEwtBtTplT zPW+y2Bqa{as0T0U-uamlu6c1l(s(K`WHFM&<=uF1Il$4twryMKIn>)bp9;YT2K%Xi zA>n66%6{D_^)1Zc_+AkIT^kkn$XAbv0aSm@VrFuXx|hZ)2vW#Wgb|LFe+K0C9ec%s zQ-dh7%H6nf<6JzrQ(KfIX32N3zIY(?W3&zfiEk_9AYm!gQ2x4V2E(0Pc`N_*VI%3~ z><`UW%EQ&MlM^h`r|$_vG#-=F>LXG_6l1YgHHHh!k;b5F%M_~3&{q8UNzDypdB zcQ0a@;oS}Nhebv$GG8T-F^e+t=+PR3v1god27#b^OJLiNIN}KZ`>Iu|=)GBApo%8I zvf$(={O#*2ezKdd(41PtpP$S=Oq3LqO{}#vZW8-daS~TJLt8efm!#J^SubDlubq_L z;suN0q!Ukq(@r@Ro_^3u&q~0Y<$(PUfD=wQ0hTRa2F+%ZR!DGBYj9{7#u`nj?WcXB z#26-f_3U4iQ10Rd83)L^YJ05`h}NI-iTEtV+*MKFMAEwe*0U9HJ5i7!zz$i6HSOomidkveC&h6@R0ZYkS|6liWP4q*{F z2Crn%Kh4_FY&4+NY!DEs$Z(a_TKV62;U3w�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

a5LgPNZT8I_YqQiS=vAJDX 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


7{W_K0lqn zcZc&Mmv%EIjh|xHUr6~88nIZn=^oxzrBnm)SuLvFQ_tWM%t6&wFI6dKlXJZJFAQZK zw2;CZw$4d1JP%{cUsD-rWqmlw6g3bOG*}BcDzy}uvSgiINHQBB0!Qj%XBIXNo9CL@ z9})CLSgFdvuV%~NzJ0U%ydHY&XPhB0-K1rqOD@I$8UYPzDsjRo^aHfDk{%p=fgxXb zQyJXG`b-;f=dsyZlDS6j1rVsff?n22M7&-!4ImpbQ*O1G*$iRiz2y!lkt$;iu7qLv zQlZlJkeW=(2NInD42xy|-L96lODDvP{NYCFiVEz9iacGMHh=>X5)+-wc|}}G#Qj-W zcbh7~5QbB>AFL__^-c$h_hf3c_-;Z`PdN-G^m=srK|90)+k^(YDeQ_?gc6ii!&a%+ z+0V8(+^+DG*lr@nGspGaQ%++yt6}$tHdMqW+xmj)1IyLX^gWhpWkd2p25eo=Rgt|% z^OMT64^RM3om|`}zk{rny0{6SgD2xL{^WdEz-WXIpAHt8#Bpw7c$RIPXz^MUoDK6S z-`DzqhZBF%HgHTsrzR*>>Gk%N%4;l7g#2ys5 zid%x`a{Qcl>Xga3X%Xf1fQ6t5T)wAYH^yqyVoCkLBC%qB?dL%4t#mvBiw*z6dj23V zpIGq9gspQFZI$Xw@6g#v2j6W_j+nEWF_*(wQZj_8Np0~YdQ)X?oXt6w#z_`1<|bDE z5Te=^JLre56n}hjP0gj(hL}JAlG7#wzO5~bE>&|Sbx=>dw|qt%-~r*mw}UEBc!%)C zO|>%LNJMnyH)~3q zVAWha4Ul}7Y6tT`1>q-%^g0?Bgm9~s+f)@&rwgjKl@;8;uXTS|sTb*`6(hO@+ekM^ zKejdCRXoplOq{Q8E`x0jeQTv*D{IDg=Vfo|6@kK*MiKm$PX_Zlf(45%M(vl#8AIxq zs3=HuL>Pp-$>jGJt(QH+!?2G(lrJ{5jeQ`^)Bay`Q7!dGosoK5sw0XgHg@Z<;|Axc zr1M(->S!A4>EN+54V5J)#6I5?b}L8G1Eps=KNUYtj3CHWWm~+1l#$-kez_FbS$rds zpZc}W0K(J}!jp{IItaML)lz}RbuSdAQ|Dn6>ShahCrnAK9N}(TLh1h) z$;L3s5oAA&1wYZLCU%Wy@-%;7oK9F9 z4=gcKjz;qNko;OV*d9w2_T<8k%2-w+Sb=7P1SA;#+eX_6%0DGYb|2xS+~h$-cb<}^ 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