added watching channel

This commit is contained in:
fourtf 2018-04-20 19:54:45 +02:00
parent e17a7cc222
commit a16a2b0579
14 changed files with 128 additions and 45 deletions

View file

@ -83,6 +83,6 @@ function selectChannel(channelName) {
let port = getPort();
if (port) {
port.postMessage({action: "select", channelName: channelName});
port.postMessage({action: "select", type: "twitch", name: channelName});
}
}

View file

@ -24,6 +24,7 @@ class Channel : public std::enable_shared_from_this<Channel>
public:
enum Type {
None,
Direct,
Twitch,
TwitchWhispers,
TwitchWatching,
@ -71,4 +72,55 @@ private:
using ChannelPtr = std::shared_ptr<Channel>;
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> data;
public:
IndirectChannel(ChannelPtr channel, Channel::Type type = Channel::None)
: 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

View file

@ -19,7 +19,7 @@ namespace twitch {
TwitchServer::TwitchServer()
: whispersChannel(new Channel("/whispers", Channel::TwitchWhispers))
, mentionsChannel(new Channel("/mentions", Channel::TwitchMentions))
, watchingChannel(new Channel("/watching", Channel::TwitchWatching))
, watchingChannel(Channel::getEmpty(), Channel::TwitchWatching)
{
AccountManager::getInstance().Twitch.userChanged.connect([this]() { //
util::postToThread([this] { this->connect(); });

View file

@ -22,7 +22,7 @@ public:
const ChannelPtr whispersChannel;
const ChannelPtr mentionsChannel;
const ChannelPtr watchingChannel;
IndirectChannel watchingChannel;
protected:
void initializeConnection(Communi::IrcConnection *connection, bool isRead,

View file

@ -1,6 +1,8 @@
#include "nativemessagingmanager.hpp"
#include "providers/twitch/twitchserver.hpp"
#include "singletons/pathmanager.hpp"
#include "util/posttothread.hpp"
#include <QCoreApplication>
#include <QFile>
@ -8,11 +10,9 @@
#include <QJsonObject>
#include <QJsonValue>
#ifdef BOOSTLIBS
#include <boost/interprocess/ipc/message_queue.hpp>
namespace ipc = boost::interprocess;
#endif
#ifdef Q_OS_WIN
#include <QProcess>
@ -81,7 +81,6 @@ void NativeMessagingManager::registerHost()
void NativeMessagingManager::openGuiMessageQueue()
{
#ifdef BOOSTLIBS
static ReceiverThread thread;
if (thread.isRunning()) {
@ -89,12 +88,10 @@ void NativeMessagingManager::openGuiMessageQueue()
}
thread.start();
#endif
}
void NativeMessagingManager::sendToGuiProcess(const QByteArray &array)
{
#ifdef BOOSTLIBS
ipc::message_queue messageQueue(ipc::open_or_create, "chatterino_gui", 100, MESSAGE_SIZE);
try {
@ -102,12 +99,10 @@ void NativeMessagingManager::sendToGuiProcess(const QByteArray &array)
} catch (ipc::interprocess_exception &ex) {
qDebug() << "send to gui process:" << ex.what();
}
#endif
}
void NativeMessagingManager::ReceiverThread::run()
{
#ifdef BOOSTLIBS
ipc::message_queue::remove("chatterino_gui");
ipc::message_queue messageQueue(ipc::open_or_create, "chatterino_gui", 100, MESSAGE_SIZE);
@ -120,19 +115,43 @@ void NativeMessagingManager::ReceiverThread::run()
messageQueue.receive(buf, MESSAGE_SIZE, retSize, priority);
QJsonDocument document = QJsonDocument::fromRawData(buf, retSize);
QJsonDocument document = QJsonDocument::fromJson(QByteArray(buf, retSize));
this->handleMessage(document.object());
} catch (ipc::interprocess_exception &ex) {
qDebug() << "received from gui process:" << ex.what();
}
}
#endif
}
void NativeMessagingManager::ReceiverThread::handleMessage(const QJsonObject &root)
{
// TODO: add code xD
QString action = root.value("action").toString();
if (action.isNull()) {
qDebug() << "NM action was null";
return;
}
if (action == "select") {
QString _type = root.value("type").toString();
QString name = root.value("name").toString();
if (_type.isNull() || name.isNull()) {
qDebug() << "NM type or name missing";
return;
}
if (_type == "twitch") {
util::postToThread([name] {
auto &ts = providers::twitch::TwitchServer::getInstance();
ts.watchingChannel.update(ts.addChannel(name));
});
} else {
qDebug() << "NM unknown channel type";
}
}
}
} // namespace singletons

View file

@ -270,7 +270,7 @@ void WindowManager::save()
for (widgets::Split *cell : cells) {
QJsonObject cell_obj;
cell_obj.insert("channelName", cell->getChannel()->name);
cell_obj.insert("channelName", cell->getChannel().get()->name);
cells_arr.append(cell_obj);
}

View file

@ -341,6 +341,7 @@ void ChannelView::setChannel(ChannelPtr newChannel)
if (this->channel) {
this->detachChannel();
}
this->messages.clear();
// on new message
@ -445,15 +446,10 @@ void ChannelView::setChannel(ChannelPtr newChannel)
void ChannelView::detachChannel()
{
// on message added
if (this->messageAppendedConnection.isConnected()) {
this->messageAppendedConnection.disconnect();
}
// on message removed
if (this->messageRemovedConnection.isConnected()) {
this->messageRemovedConnection.disconnect();
}
messageAppendedConnection.disconnect();
messageAddedAtStartConnection.disconnect();
messageRemovedConnection.disconnect();
messageReplacedConnection.disconnect();
}
void ChannelView::pause(int msecTimeout)

View file

@ -129,6 +129,7 @@ private:
pajlada::Signals::Connection layoutConnection;
std::vector<pajlada::Signals::ScopedConnection> managedConnections;
std::vector<pajlada::Signals::ScopedConnection> channelConnections;
std::unordered_set<std::shared_ptr<messages::MessageLayout>> messagesOnScreen;

View file

@ -154,14 +154,14 @@ void SplitHeader::scaleChangedEvent(float scale)
void SplitHeader::updateChannelText()
{
const QString channelName = this->split->getChannel()->name;
auto channel = this->split->getChannel();
const QString channelName = channel->name;
if (channelName.isEmpty()) {
this->titleLabel->setText("<no channel>");
return;
}
auto channel = this->split->getChannel();
TwitchChannel *twitchChannel = dynamic_cast<TwitchChannel *>(channel.get());
if (twitchChannel != nullptr) {

View file

@ -21,7 +21,7 @@ SplitInput::SplitInput(Split *_chatWidget)
{
this->initLayout();
auto completer = new QCompleter(&this->chatWidget->getChannel()->completionModel);
auto completer = new QCompleter(&this->chatWidget->getChannel().get()->completionModel);
this->ui.textEdit->setCompleter(completer);
this->chatWidget->channelChanged.connect([this] {

View file

@ -138,8 +138,10 @@ void SelectChannelDialog::ok()
this->close();
}
void SelectChannelDialog::setSelectedChannel(ChannelPtr channel)
void SelectChannelDialog::setSelectedChannel(IndirectChannel _channel)
{
auto channel = _channel.get();
assert(channel);
this->selectedChannel = channel;
@ -171,7 +173,7 @@ void SelectChannelDialog::setSelectedChannel(ChannelPtr channel)
this->_hasSelectedChannel = false;
}
ChannelPtr SelectChannelDialog::getSelectedChannel() const
IndirectChannel SelectChannelDialog::getSelectedChannel() const
{
if (!this->_hasSelectedChannel) {
return this->selectedChannel;

View file

@ -17,8 +17,8 @@ class SelectChannelDialog : public BaseWindow
public:
SelectChannelDialog();
void setSelectedChannel(ChannelPtr selectedChannel);
ChannelPtr getSelectedChannel() const;
void setSelectedChannel(IndirectChannel selectedChannel);
IndirectChannel getSelectedChannel() const;
bool hasSeletedChannel() const;
pajlada::Signals::NoArgSignal closed;

View file

@ -119,28 +119,39 @@ Split::~Split()
{
this->usermodeChangedConnection.disconnect();
this->channelIDChangedConnection.disconnect();
this->indirectChannelChangedConnection.disconnect();
}
ChannelPtr Split::getChannel() const
IndirectChannel Split::getIndirectChannel()
{
return this->channel;
}
void Split::setChannel(ChannelPtr _newChannel)
ChannelPtr Split::getChannel()
{
this->view.setChannel(_newChannel);
return this->channel.get();
}
void Split::setChannel(IndirectChannel newChannel)
{
this->view.setChannel(newChannel.get());
this->usermodeChangedConnection.disconnect();
this->indirectChannelChangedConnection.disconnect();
this->channel = _newChannel;
this->channel = newChannel;
TwitchChannel *tc = dynamic_cast<TwitchChannel *>(_newChannel.get());
TwitchChannel *tc = dynamic_cast<TwitchChannel *>(newChannel.get().get());
if (tc != nullptr) {
this->usermodeChangedConnection =
tc->userStateChanged.connect([this] { this->header.updateModerationModeIcon(); });
}
this->indirectChannelChangedConnection = newChannel.getChannelChanged().connect([this] { //
QTimer::singleShot(0, [this] { this->setChannel(this->channel); });
});
this->header.updateModerationModeIcon();
this->header.updateChannelText();
@ -316,7 +327,7 @@ void Split::doClearChat()
void Split::doOpenChannel()
{
ChannelPtr _channel = this->channel;
ChannelPtr _channel = this->getChannel();
TwitchChannel *tc = dynamic_cast<TwitchChannel *>(_channel.get());
if (tc != nullptr) {
@ -326,7 +337,7 @@ void Split::doOpenChannel()
void Split::doOpenPopupPlayer()
{
ChannelPtr _channel = this->channel;
ChannelPtr _channel = this->getChannel();
TwitchChannel *tc = dynamic_cast<TwitchChannel *>(_channel.get());
if (tc != nullptr) {
@ -337,7 +348,7 @@ void Split::doOpenPopupPlayer()
void Split::doOpenStreamlink()
{
try {
streamlink::Start(this->channel->name);
streamlink::Start(this->getChannel()->name);
} catch (const streamlink::Exception &ex) {
debug::Log("Error in doOpenStreamlink: {}", ex.what());
}
@ -353,7 +364,7 @@ void Split::doOpenViewerList()
this->height() - this->header.height() - this->input.height());
viewerDock->move(0, this->header.height());
auto accountPopup = new AccountPopupWidget(this->channel);
auto accountPopup = new AccountPopupWidget(this->getChannel());
accountPopup->setAttribute(Qt::WA_DeleteOnClose);
auto multiWidget = new QWidget(viewerDock);
auto dockVbox = new QVBoxLayout(viewerDock);
@ -372,8 +383,8 @@ void Split::doOpenViewerList()
}
auto loadingLabel = new QLabel("Loading...");
util::twitch::get("https://tmi.twitch.tv/group/user/" + channel->name + "/chatters", this,
[=](QJsonObject obj) {
util::twitch::get("https://tmi.twitch.tv/group/user/" + this->getChannel()->name + "/chatters",
this, [=](QJsonObject obj) {
QJsonObject chattersObj = obj.value("chatters").toObject();
loadingLabel->hide();

View file

@ -53,8 +53,9 @@ public:
return this->view;
}
ChannelPtr getChannel() const;
void setChannel(ChannelPtr newChannel);
IndirectChannel getIndirectChannel();
ChannelPtr getChannel();
void setChannel(IndirectChannel newChannel);
void setFlexSizeX(double x);
double getFlexSizeX();
@ -83,7 +84,7 @@ protected:
private:
SplitContainer &parentPage;
ChannelPtr channel;
IndirectChannel channel;
QVBoxLayout vbox;
SplitHeader header;
@ -96,6 +97,7 @@ private:
pajlada::Signals::Connection channelIDChangedConnection;
pajlada::Signals::Connection usermodeChangedConnection;
pajlada::Signals::Connection indirectChannelChangedConnection;
void doOpenAccountPopupWidget(AccountPopupWidget *widget, QString user);
void channelNameUpdated(const QString &newChannelName);
void handleModifiers(QEvent *event, Qt::KeyboardModifiers modifiers);