From ad99ab8daaa2f497a5c871b3a027c8f302c6fb19 Mon Sep 17 00:00:00 2001 From: Nerixyz Date: Sun, 5 Jul 2026 16:09:18 +0200 Subject: [PATCH] refactor: Use magic_enum for encoding channels (#7079) Split from #6906. This changes the en-/decoding of channels in the window layout to use magic-enum for translating between enum and string. This way, the names are consistent when en-/deconding. And more importantly, when adding channel types, you should get compiler warnings in switch statements for uncovered cases. Tested-by: Mm2PL Reviewed-by: pajlada --- src/common/Channel.hpp | 36 +++++++++++++++++++++++ src/common/WindowDescriptors.cpp | 49 ++++++++++++++++---------------- src/singletons/WindowManager.cpp | 44 +++++++++------------------- 3 files changed, 75 insertions(+), 54 deletions(-) diff --git a/src/common/Channel.hpp b/src/common/Channel.hpp index 1ef92807a..51561f0c7 100644 --- a/src/common/Channel.hpp +++ b/src/common/Channel.hpp @@ -199,3 +199,39 @@ private: }; } // namespace chatterino + +// NOLINTBEGIN(readability-identifier-naming) +template <> +constexpr magic_enum::customize::customize_t + magic_enum::customize::enum_name( + chatterino::Channel::Type value) noexcept +{ + using Type = chatterino::Channel::Type; + + // These names are used for encoding channels in the window layout settings. + // They need to be stable across Chatterino versions. + switch (value) + { + case Type::Twitch: + return "twitch"; + case Type::TwitchAutomod: + return "automod"; + case Type::TwitchMentions: + return "mentions"; + case Type::TwitchWatching: + return "watching"; + case Type::TwitchWhispers: + return "whispers"; + case Type::TwitchLive: + return "live"; + case Type::Misc: + return "misc"; + + case Type::None: + case Type::Direct: + case Type::TwitchEnd: + return default_tag; // FIXME: Remove these (#5703) + } + return default_tag; +} +// NOLINTEND(readability-identifier-naming) diff --git a/src/common/WindowDescriptors.cpp b/src/common/WindowDescriptors.cpp index 2e9fc5def..577bca75a 100644 --- a/src/common/WindowDescriptors.cpp +++ b/src/common/WindowDescriptors.cpp @@ -8,6 +8,7 @@ #include "common/QLogging.hpp" #include "debug/AssertInGuiThread.hpp" #include "providers/twitch/TwitchIrcServer.hpp" +#include "util/QMagicEnum.hpp" #include "widgets/Window.hpp" #include @@ -78,33 +79,33 @@ IndirectChannel SplitDescriptor::decodeChannel() const { assertInGuiThread(); - if (this->type_ == "twitch") + auto type = qmagicenum::enumCast(this->type_); + if (!type) { - return getApp()->getTwitch()->getOrAddChannel(this->channelName_); + return Channel::getEmpty(); } - else if (this->type_ == "mentions") + + switch (*type) { - return getApp()->getTwitch()->getMentionsChannel(); - } - else if (this->type_ == "watching") - { - return getApp()->getTwitch()->getWatchingChannel(); - } - else if (this->type_ == "whispers") - { - return getApp()->getTwitch()->getWhispersChannel(); - } - else if (this->type_ == "live") - { - return getApp()->getTwitch()->getLiveChannel(); - } - else if (this->type_ == "automod") - { - return getApp()->getTwitch()->getAutomodChannel(); - } - else if (this->type_ == "misc") - { - return getApp()->getTwitch()->getChannelOrEmpty(this->channelName_); + case Channel::Type::Twitch: + return getApp()->getTwitch()->getOrAddChannel(this->channelName_); + case Channel::Type::TwitchMentions: + return getApp()->getTwitch()->getMentionsChannel(); + case Channel::Type::TwitchWatching: + return getApp()->getTwitch()->getWatchingChannel(); + case Channel::Type::TwitchWhispers: + return getApp()->getTwitch()->getWhispersChannel(); + case Channel::Type::TwitchLive: + return getApp()->getTwitch()->getLiveChannel(); + case Channel::Type::TwitchAutomod: + return getApp()->getTwitch()->getAutomodChannel(); + case Channel::Type::Misc: + return getApp()->getTwitch()->getChannelOrEmpty(this->channelName_); + + case Channel::Type::None: + case Channel::Type::Direct: + case Channel::Type::TwitchEnd: + break; // FIXME: Remove these (#5703) } return Channel::getEmpty(); diff --git a/src/singletons/WindowManager.cpp b/src/singletons/WindowManager.cpp index 84765efa4..e2d763fa2 100644 --- a/src/singletons/WindowManager.cpp +++ b/src/singletons/WindowManager.cpp @@ -733,40 +733,24 @@ void WindowManager::encodeChannel(IndirectChannel channel, QJsonObject &obj) { assertInGuiThread(); + obj.insert("type", qmagicenum::enumNameString(channel.getType())); switch (channel.getType()) { - case Channel::Type::Twitch: { - obj.insert("type", "twitch"); + case Channel::Type::Twitch: + case Channel::Type::Misc: obj.insert("name", channel.get()->getName()); - } - break; - case Channel::Type::TwitchAutomod: { - obj.insert("type", "automod"); - } - break; - case Channel::Type::TwitchMentions: { - obj.insert("type", "mentions"); - } - break; - case Channel::Type::TwitchWatching: { - obj.insert("type", "watching"); - } - break; - case Channel::Type::TwitchWhispers: { - obj.insert("type", "whispers"); - } - break; - case Channel::Type::TwitchLive: { - obj.insert("type", "live"); - } - break; - case Channel::Type::Misc: { - obj.insert("type", "misc"); - obj.insert("name", channel.get()->getName()); - } - break; + break; - default: + case Channel::Type::TwitchWhispers: + case Channel::Type::TwitchWatching: + case Channel::Type::TwitchMentions: + case Channel::Type::TwitchLive: + case Channel::Type::TwitchAutomod: + + // FIXME: Remove these (#5703) + case Channel::Type::None: + case Channel::Type::Direct: + case Channel::Type::TwitchEnd: break; } }