#pragma once #include "messages/image.hpp" #include "messages/limitedqueue.hpp" #include "messages/message.hpp" #include "util/completionmodel.hpp" #include "util/concurrentmap.hpp" #include #include #include #include namespace chatterino { namespace messages { struct Message; } // namespace messages class Channel : public std::enable_shared_from_this { QTimer *clearCompletionModelTimer; public: enum Type { None, Direct, Twitch, TwitchWhispers, TwitchWatching, TwitchMentions, TwitchEnd, }; explicit Channel(const QString &_name, Type type); virtual ~Channel(); pajlada::Signals::Signal sendMessageSignal; pajlada::Signals::Signal messageRemovedFromStart; pajlada::Signals::Signal messageAppended; pajlada::Signals::Signal &> messagesAddedAtStart; pajlada::Signals::Signal messageReplaced; pajlada::Signals::NoArgSignal destroyed; Type getType() const; bool isTwitchChannel() const; virtual bool isEmpty() const; messages::LimitedQueueSnapshot getMessageSnapshot(); void addMessage(messages::MessagePtr message); void addMessagesAtStart(std::vector &messages); void addOrReplaceTimeout(messages::MessagePtr message); void replaceMessage(messages::MessagePtr message, messages::MessagePtr replacement); virtual void addRecentChatter(const std::shared_ptr &message); QString name; QStringList modList; virtual bool canSendMessage() const; virtual void sendMessage(const QString &message); virtual bool isMod() const; static std::shared_ptr getEmpty(); CompletionModel completionModel; protected: virtual void onConnected(); private: messages::LimitedQueue messages; Type type; }; using ChannelPtr = std::shared_ptr; class IndirectChannel { struct Data { ChannelPtr channel; Channel::Type type; pajlada::Signals::NoArgSignal changed; Data() = delete; Data(ChannelPtr _channel, Channel::Type _type) : channel(_channel) , type(_type) { } }; std::shared_ptr data; public: IndirectChannel(ChannelPtr channel, Channel::Type type = Channel::Direct) : data(new Data(channel, type)) { } ChannelPtr get() { return data->channel; } void update(ChannelPtr ptr) { assert(this->data->type != Channel::Direct); this->data->channel = ptr; this->data->changed.invoke(); } pajlada::Signals::NoArgSignal &getChannelChanged() { return this->data->changed; } Channel::Type getType() { if (this->data->type == Channel::Direct) { return this->get()->getType(); } else { return this->data->type; } } }; } // namespace chatterino