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 "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<SplitNotebook *>(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;
}
}

View file

@ -2,6 +2,7 @@
#include "common/Common.hpp"
#include "widgets/helper/Button.hpp"
#include "widgets/helper/ChannelView.hpp"
#include "widgets/Notebook.hpp"
#include <pajlada/settings/setting.hpp>
@ -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<ChannelPtr> newMessageSource;
std::unordered_set<ChannelPtr> 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<ChannelViewProxy, ChannelViewProxyHash,
ChannelViewProxyEqual>
newMessageSource;
std::unordered_set<ChannelViewProxy, ChannelViewProxyHash,
ChannelViewProxyEqual>
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_;

View file

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