#pragma once #include "controllers/completion/TabCompletionModel.hpp" #include "messages/LimitedQueue.hpp" #include "messages/MessageFlag.hpp" #include #include #include #include #include #include #include namespace chatterino { struct Message; using MessagePtr = std::shared_ptr; enum class TimeoutStackStyle : int { StackHard = 0, DontStackBeyondUserMessage = 1, DontStack = 2, Default = DontStackBeyondUserMessage, }; /// Context of the message being added to a channel enum class MessageContext { /// This message is the original Original, /// This message is a repost of a message that has already been added in a channel Repost, }; class Channel : public std::enable_shared_from_this { public: // This is for Lua. See scripts/make_luals_meta.py /** * @exposeenum c2.ChannelType */ enum class Type { None, Direct, Twitch, TwitchWhispers, TwitchWatching, TwitchMentions, TwitchLive, TwitchAutomod, TwitchEnd, Misc, }; explicit Channel(const QString &name, Type type); virtual ~Channel(); // SIGNALS pajlada::Signals::Signal sendMessageSignal; pajlada::Signals::Signal sendReplySignal; pajlada::Signals::Signal> messageAppended; pajlada::Signals::Signal &> messagesAddedAtStart; pajlada::Signals::Signal messageReplaced; /// Invoked when some number of messages were filled in using time received pajlada::Signals::Signal &> filledInMessages; pajlada::Signals::NoArgSignal destroyed; pajlada::Signals::NoArgSignal displayNameChanged; pajlada::Signals::NoArgSignal messagesCleared; Type getType() const; const QString &getName() const; virtual const QString &getDisplayName() const; virtual const QString &getLocalizedName() const; bool isTwitchChannel() const; virtual bool isEmpty() const; LimitedQueueSnapshot getMessageSnapshot(); // MESSAGES // overridingFlags can be filled in with flags that should be used instead // of the message's flags. This is useful in case a flag is specific to a // type of split void addMessage(MessagePtr message, MessageContext context, std::optional overridingFlags = std::nullopt); void addMessagesAtStart(const std::vector &messages_); void addSystemMessage(const QString &contents); /// Inserts the given messages in order by Message::serverReceivedTime. void fillInMissingMessages(const std::vector &messages); void addOrReplaceTimeout(MessagePtr message); void disableAllMessages(); void replaceMessage(MessagePtr message, MessagePtr replacement); void replaceMessage(size_t index, MessagePtr replacement); void deleteMessage(QString messageID); /// Removes all messages from this channel and invokes #messagesCleared void clearMessages(); MessagePtr findMessage(QString messageID); bool hasMessages() const; // CHANNEL INFO virtual bool canSendMessage() const; virtual bool isWritable() const; // whether split input will be usable virtual void sendMessage(const QString &message); virtual bool isMod() const; virtual bool isBroadcaster() const; virtual bool hasModRights() const; virtual bool hasHighRateLimit() const; virtual bool isLive() const; virtual bool isRerun() const; virtual bool shouldIgnoreHighlights() const; virtual bool canReconnect() const; virtual void reconnect(); virtual QString getCurrentStreamID() const; static std::shared_ptr getEmpty(); TabCompletionModel *completionModel; QDate lastDate_; protected: virtual void onConnected(); virtual void messageRemovedFromStart(const MessagePtr &msg); QString platform_{"other"}; private: const QString name_; LimitedQueue messages_; Type type_; QTimer clearCompletionModelTimer_; }; using ChannelPtr = std::shared_ptr; class IndirectChannel { struct Data { ChannelPtr channel; Channel::Type type; pajlada::Signals::NoArgSignal changed; Data(ChannelPtr channel, Channel::Type type); }; public: IndirectChannel(ChannelPtr channel, Channel::Type type = Channel::Type::Direct); ChannelPtr get() const; void reset(ChannelPtr channel); pajlada::Signals::NoArgSignal &getChannelChanged(); Channel::Type getType(); private: std::shared_ptr data_; }; } // namespace chatterino template <> constexpr magic_enum::customize::customize_t magic_enum::customize::enum_name( chatterino::Channel::Type value) noexcept { using Type = chatterino::Channel::Type; switch (value) { case Type::Twitch: return "twitch"; case Type::TwitchWhispers: return "whispers"; case Type::TwitchWatching: return "watching"; case Type::TwitchMentions: return "mentions"; case Type::TwitchLive: return "live"; case Type::TwitchAutomod: return "automod"; case Type::Misc: return "misc"; default: return default_tag; } }