From fe51ba85e772e2d8e8c85033e0311636cd5fdf72 Mon Sep 17 00:00:00 2001 From: unknown <1310440+hemirt@users.noreply.github.com> Date: Sun, 20 Oct 2024 17:46:22 +0200 Subject: [PATCH] hash based matching based on ChannelView name and filters --- src/widgets/helper/NotebookTab.cpp | 63 ++++++++++++++++++++++----- src/widgets/helper/NotebookTab.hpp | 32 +++++++++++--- src/widgets/splits/SplitContainer.cpp | 5 +-- 3 files changed, 78 insertions(+), 22 deletions(-) diff --git a/src/widgets/helper/NotebookTab.cpp b/src/widgets/helper/NotebookTab.cpp index a04725909..db444b237 100644 --- a/src/widgets/helper/NotebookTab.cpp +++ b/src/widgets/helper/NotebookTab.cpp @@ -1,6 +1,7 @@ #include "widgets/helper/NotebookTab.hpp" #include "Application.hpp" +#include "common/Channel.hpp" #include "common/Common.hpp" #include "controllers/hotkeys/HotkeyCategory.hpp" #include "controllers/hotkeys/HotkeyController.hpp" @@ -10,7 +11,6 @@ #include "singletons/WindowManager.hpp" #include "util/Helpers.hpp" #include "widgets/dialogs/SettingsDialog.hpp" -#include "widgets/helper/ChannelView.hpp" #include "widgets/Notebook.hpp" #include "widgets/splits/DraggedSplit.hpp" #include "widgets/splits/Split.hpp" @@ -55,6 +55,27 @@ namespace { } } // namespace +std::size_t NotebookTab::HighlightSources::ChannelViewProxyHash::operator()( + const ChannelViewProxy &cp) const noexcept +{ + std::size_t seed = 0; + auto first = qHash(cp.channelView->underlyingChannel()->getName()); + auto second = qHash(cp.channelView->getFilterIds()); + + boost::hash_combine(seed, first); + boost::hash_combine(seed, second); + + return seed; +} + +bool NotebookTab::HighlightSources::ChannelViewProxyEqual::operator()( + const ChannelViewProxy &lp, const ChannelViewProxy &rp) const +{ + return lp.channelView->underlyingChannel() == + rp.channelView->underlyingChannel() && + lp.channelView->getFilterIds() == rp.channelView->getFilterIds(); +} + NotebookTab::NotebookTab(Notebook *notebook) : Button(notebook) , positionChangedAnimation_(this, "pos") @@ -304,12 +325,14 @@ bool NotebookTab::isSelected() const return this->selected_; } -void NotebookTab::removeNewMessageSource(const ChannelPtr &source) +void NotebookTab::removeNewMessageSource( + const HighlightSources::ChannelViewProxy &source) { this->highlightSources_.newMessageSource.erase(source); } -void NotebookTab::removeHighlightedSource(const ChannelPtr &source) +void NotebookTab::removeHighlightedSource( + const HighlightSources::ChannelViewProxy &source) { this->highlightSources_.highlightedSource.erase(source); } @@ -328,10 +351,13 @@ void NotebookTab::removeHighlightStateChangeSources( } } -void NotebookTab::newHighlightSourceAdded(const ChannelPtr &source) +void NotebookTab::newHighlightSourceAdded(const ChannelView &channelViewSource) { - this->removeHighlightedSource(source); - this->removeNewMessageSource(source); + auto channelViewProxy = + HighlightSources::ChannelViewProxy{&channelViewSource}; + auto sourceChannel = channelViewSource.underlyingChannel(); + this->removeHighlightedSource(channelViewProxy); + this->removeNewMessageSource(channelViewProxy); this->updateHighlightStateDueSourcesChange(); auto *splitNotebook = dynamic_cast(this->notebook_); @@ -346,8 +372,8 @@ void NotebookTab::newHighlightSourceAdded(const ChannelPtr &source) auto *tab = splitContainer->getTab(); if (tab && tab != this) { - tab->removeHighlightedSource(source); - tab->removeNewMessageSource(source); + tab->removeHighlightedSource(channelViewProxy); + tab->removeNewMessageSource(channelViewProxy); tab->updateHighlightStateDueSourcesChange(); } } @@ -541,25 +567,34 @@ void NotebookTab::updateHighlightState(HighlightState newHighlightStyle, return; } + // message is highlighting unvisible tab + auto underlyingChannel = channelViewSource.underlyingChannel(); + auto newFilters = channelViewSource.getFilterIds(); + auto channelViewProxy = + HighlightSources::ChannelViewProxy{&channelViewSource}; + + // the unvisible tab should unhighlight other tabs iff + // the other tab's filters are more generic therefore + // the other tab's filter set is subset of the unvisible tab switch (newHighlightStyle) { case HighlightState::Highlighted: { if (!this->highlightSources_.highlightedSource.contains( - underlyingChannel)) + channelViewProxy)) { this->highlightSources_.highlightedSource.insert( - underlyingChannel); + channelViewProxy); } break; } case HighlightState::NewMessage: { if (!this->highlightSources_.newMessageSource.contains( - underlyingChannel)) + channelViewProxy)) { this->highlightSources_.newMessageSource.insert( - underlyingChannel); + channelViewProxy); } break; } @@ -608,6 +643,10 @@ bool NotebookTab::shouldMessageHighlight(const ChannelView &channelViewSource, visibleSplit->getChannelView().shouldIncludeMessage(message) && isSubset(filterIdsSource, filterIdsSplit)) { + // all filters in unvisible source are found in visible split + // therefore the unvisible split is more generic than the visible one + // and the visible one is showing current message + // so no highlight of unvisible tab needed return false; } } diff --git a/src/widgets/helper/NotebookTab.hpp b/src/widgets/helper/NotebookTab.hpp index cfd2e1d34..ec0ad0ad9 100644 --- a/src/widgets/helper/NotebookTab.hpp +++ b/src/widgets/helper/NotebookTab.hpp @@ -2,6 +2,7 @@ #include "common/Common.hpp" #include "widgets/helper/Button.hpp" +#include "widgets/helper/ChannelView.hpp" #include "widgets/Notebook.hpp" #include @@ -14,7 +15,6 @@ namespace chatterino { inline constexpr int NOTEBOOK_TAB_HEIGHT = 28; class SplitContainer; -class ChannelView; class NotebookTab : public Button { @@ -76,7 +76,7 @@ public: const MessagePtr &message); void copyHighlightStateAndSourcesFrom(const NotebookTab *sourceTab); void setHighlightsEnabled(const bool &newVal); - void newHighlightSourceAdded(const ChannelPtr &source); + void newHighlightSourceAdded(const ChannelView &channelViewSource); bool hasHighlightsEnabled() const; HighlightState highlightState() const; @@ -126,8 +126,26 @@ private: const MessagePtr &message) const; struct HighlightSources { - std::unordered_set newMessageSource; - std::unordered_set highlightedSource; + struct ChannelViewProxy { + const ChannelView *channelView; + }; + + struct ChannelViewProxyHash { + using is_transparent = void; + std::size_t operator()(const ChannelViewProxy &cp) const noexcept; + }; + + struct ChannelViewProxyEqual { + bool operator()(const ChannelViewProxy &l, + const ChannelViewProxy &r) const; + }; + + std::unordered_set + newMessageSource; + std::unordered_set + highlightedSource; void clear() { @@ -138,8 +156,10 @@ private: } highlightSources_; void removeHighlightStateChangeSources(const HighlightSources &toRemove); - void removeNewMessageSource(const ChannelPtr &source); - void removeHighlightedSource(const ChannelPtr &source); + void removeNewMessageSource( + const HighlightSources::ChannelViewProxy &source); + void removeHighlightedSource( + const HighlightSources::ChannelViewProxy &source); void updateHighlightStateDueSourcesChange(); QPropertyAnimation positionChangedAnimation_; diff --git a/src/widgets/splits/SplitContainer.cpp b/src/widgets/splits/SplitContainer.cpp index 4e430c6b0..c684d56ea 100644 --- a/src/widgets/splits/SplitContainer.cpp +++ b/src/widgets/splits/SplitContainer.cpp @@ -224,12 +224,9 @@ void SplitContainer::addSplit(Split *split) }); conns.managedConnect(split->channelChanged, [this, split] { - qDebug() << "Changing Channel" - << split->getChannelView().underlyingChannel()->getName(); if (this->tab_ != nullptr) { - this->tab_->newHighlightSourceAdded( - split->getChannelView().underlyingChannel()); + this->tab_->newHighlightSourceAdded(split->getChannelView()); } });