hash based matching based on ChannelView name and filters

This commit is contained in:
unknown 2024-10-20 17:46:22 +02:00
parent 2884c828b0
commit fe51ba85e7
3 changed files with 78 additions and 22 deletions

View file

@ -1,6 +1,7 @@
#include "widgets/helper/NotebookTab.hpp" #include "widgets/helper/NotebookTab.hpp"
#include "Application.hpp" #include "Application.hpp"
#include "common/Channel.hpp"
#include "common/Common.hpp" #include "common/Common.hpp"
#include "controllers/hotkeys/HotkeyCategory.hpp" #include "controllers/hotkeys/HotkeyCategory.hpp"
#include "controllers/hotkeys/HotkeyController.hpp" #include "controllers/hotkeys/HotkeyController.hpp"
@ -10,7 +11,6 @@
#include "singletons/WindowManager.hpp" #include "singletons/WindowManager.hpp"
#include "util/Helpers.hpp" #include "util/Helpers.hpp"
#include "widgets/dialogs/SettingsDialog.hpp" #include "widgets/dialogs/SettingsDialog.hpp"
#include "widgets/helper/ChannelView.hpp"
#include "widgets/Notebook.hpp" #include "widgets/Notebook.hpp"
#include "widgets/splits/DraggedSplit.hpp" #include "widgets/splits/DraggedSplit.hpp"
#include "widgets/splits/Split.hpp" #include "widgets/splits/Split.hpp"
@ -55,6 +55,27 @@ namespace {
} }
} // 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) NotebookTab::NotebookTab(Notebook *notebook)
: Button(notebook) : Button(notebook)
, positionChangedAnimation_(this, "pos") , positionChangedAnimation_(this, "pos")
@ -304,12 +325,14 @@ bool NotebookTab::isSelected() const
return this->selected_; return this->selected_;
} }
void NotebookTab::removeNewMessageSource(const ChannelPtr &source) void NotebookTab::removeNewMessageSource(
const HighlightSources::ChannelViewProxy &source)
{ {
this->highlightSources_.newMessageSource.erase(source); this->highlightSources_.newMessageSource.erase(source);
} }
void NotebookTab::removeHighlightedSource(const ChannelPtr &source) void NotebookTab::removeHighlightedSource(
const HighlightSources::ChannelViewProxy &source)
{ {
this->highlightSources_.highlightedSource.erase(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); auto channelViewProxy =
this->removeNewMessageSource(source); HighlightSources::ChannelViewProxy{&channelViewSource};
auto sourceChannel = channelViewSource.underlyingChannel();
this->removeHighlightedSource(channelViewProxy);
this->removeNewMessageSource(channelViewProxy);
this->updateHighlightStateDueSourcesChange(); this->updateHighlightStateDueSourcesChange();
auto *splitNotebook = dynamic_cast<SplitNotebook *>(this->notebook_); auto *splitNotebook = dynamic_cast<SplitNotebook *>(this->notebook_);
@ -346,8 +372,8 @@ void NotebookTab::newHighlightSourceAdded(const ChannelPtr &source)
auto *tab = splitContainer->getTab(); auto *tab = splitContainer->getTab();
if (tab && tab != this) if (tab && tab != this)
{ {
tab->removeHighlightedSource(source); tab->removeHighlightedSource(channelViewProxy);
tab->removeNewMessageSource(source); tab->removeNewMessageSource(channelViewProxy);
tab->updateHighlightStateDueSourcesChange(); tab->updateHighlightStateDueSourcesChange();
} }
} }
@ -541,25 +567,34 @@ void NotebookTab::updateHighlightState(HighlightState newHighlightStyle,
return; return;
} }
// message is highlighting unvisible tab
auto underlyingChannel = channelViewSource.underlyingChannel(); 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) switch (newHighlightStyle)
{ {
case HighlightState::Highlighted: { case HighlightState::Highlighted: {
if (!this->highlightSources_.highlightedSource.contains( if (!this->highlightSources_.highlightedSource.contains(
underlyingChannel)) channelViewProxy))
{ {
this->highlightSources_.highlightedSource.insert( this->highlightSources_.highlightedSource.insert(
underlyingChannel); channelViewProxy);
} }
break; break;
} }
case HighlightState::NewMessage: { case HighlightState::NewMessage: {
if (!this->highlightSources_.newMessageSource.contains( if (!this->highlightSources_.newMessageSource.contains(
underlyingChannel)) channelViewProxy))
{ {
this->highlightSources_.newMessageSource.insert( this->highlightSources_.newMessageSource.insert(
underlyingChannel); channelViewProxy);
} }
break; break;
} }
@ -608,6 +643,10 @@ bool NotebookTab::shouldMessageHighlight(const ChannelView &channelViewSource,
visibleSplit->getChannelView().shouldIncludeMessage(message) && visibleSplit->getChannelView().shouldIncludeMessage(message) &&
isSubset(filterIdsSource, filterIdsSplit)) 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; return false;
} }
} }

View file

@ -2,6 +2,7 @@
#include "common/Common.hpp" #include "common/Common.hpp"
#include "widgets/helper/Button.hpp" #include "widgets/helper/Button.hpp"
#include "widgets/helper/ChannelView.hpp"
#include "widgets/Notebook.hpp" #include "widgets/Notebook.hpp"
#include <pajlada/settings/setting.hpp> #include <pajlada/settings/setting.hpp>
@ -14,7 +15,6 @@ namespace chatterino {
inline constexpr int NOTEBOOK_TAB_HEIGHT = 28; inline constexpr int NOTEBOOK_TAB_HEIGHT = 28;
class SplitContainer; class SplitContainer;
class ChannelView;
class NotebookTab : public Button class NotebookTab : public Button
{ {
@ -76,7 +76,7 @@ public:
const MessagePtr &message); const MessagePtr &message);
void copyHighlightStateAndSourcesFrom(const NotebookTab *sourceTab); void copyHighlightStateAndSourcesFrom(const NotebookTab *sourceTab);
void setHighlightsEnabled(const bool &newVal); void setHighlightsEnabled(const bool &newVal);
void newHighlightSourceAdded(const ChannelPtr &source); void newHighlightSourceAdded(const ChannelView &channelViewSource);
bool hasHighlightsEnabled() const; bool hasHighlightsEnabled() const;
HighlightState highlightState() const; HighlightState highlightState() const;
@ -126,8 +126,26 @@ private:
const MessagePtr &message) const; const MessagePtr &message) const;
struct HighlightSources { struct HighlightSources {
std::unordered_set<ChannelPtr> newMessageSource; struct ChannelViewProxy {
std::unordered_set<ChannelPtr> highlightedSource; 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<ChannelViewProxy, ChannelViewProxyHash,
ChannelViewProxyEqual>
newMessageSource;
std::unordered_set<ChannelViewProxy, ChannelViewProxyHash,
ChannelViewProxyEqual>
highlightedSource;
void clear() void clear()
{ {
@ -138,8 +156,10 @@ private:
} highlightSources_; } highlightSources_;
void removeHighlightStateChangeSources(const HighlightSources &toRemove); void removeHighlightStateChangeSources(const HighlightSources &toRemove);
void removeNewMessageSource(const ChannelPtr &source); void removeNewMessageSource(
void removeHighlightedSource(const ChannelPtr &source); const HighlightSources::ChannelViewProxy &source);
void removeHighlightedSource(
const HighlightSources::ChannelViewProxy &source);
void updateHighlightStateDueSourcesChange(); void updateHighlightStateDueSourcesChange();
QPropertyAnimation positionChangedAnimation_; QPropertyAnimation positionChangedAnimation_;

View file

@ -224,12 +224,9 @@ void SplitContainer::addSplit(Split *split)
}); });
conns.managedConnect(split->channelChanged, [this, split] { conns.managedConnect(split->channelChanged, [this, split] {
qDebug() << "Changing Channel"
<< split->getChannelView().underlyingChannel()->getName();
if (this->tab_ != nullptr) if (this->tab_ != nullptr)
{ {
this->tab_->newHighlightSourceAdded( this->tab_->newHighlightSourceAdded(split->getChannelView());
split->getChannelView().underlyingChannel());
} }
}); });