mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
Merge branch 'master' of https://github.com/fourtf/chatterino2
This commit is contained in:
commit
a44758ad23
23 changed files with 255 additions and 104 deletions
|
@ -17,6 +17,11 @@ DEFINES += QT_DEPRECATED_WARNINGS
|
||||||
PRECOMPILED_HEADER = src/precompiled_header.hpp
|
PRECOMPILED_HEADER = src/precompiled_header.hpp
|
||||||
CONFIG += precompile_header
|
CONFIG += precompile_header
|
||||||
|
|
||||||
|
# https://bugreports.qt.io/browse/QTBUG-27018
|
||||||
|
equals(QMAKE_CXX, "clang++") {
|
||||||
|
TARGET = bin/chatterino
|
||||||
|
}
|
||||||
|
|
||||||
# Icons
|
# Icons
|
||||||
macx:ICON = resources/images/chatterino2.icns
|
macx:ICON = resources/images/chatterino2.icns
|
||||||
win32:RC_FILE = resources/windows.rc
|
win32:RC_FILE = resources/windows.rc
|
||||||
|
@ -167,7 +172,6 @@ SOURCES += \
|
||||||
src/widgets/splitcontainer.cpp \
|
src/widgets/splitcontainer.cpp \
|
||||||
src/widgets/streamview.cpp \
|
src/widgets/streamview.cpp \
|
||||||
src/widgets/textinputdialog.cpp \
|
src/widgets/textinputdialog.cpp \
|
||||||
src/widgets/titlebar.cpp \
|
|
||||||
src/widgets/tooltipwidget.cpp \
|
src/widgets/tooltipwidget.cpp \
|
||||||
src/widgets/window.cpp \
|
src/widgets/window.cpp \
|
||||||
src/providers/irc/_ircaccount.cpp \
|
src/providers/irc/_ircaccount.cpp \
|
||||||
|
@ -280,7 +284,6 @@ HEADERS += \
|
||||||
src/widgets/splitcontainer.hpp \
|
src/widgets/splitcontainer.hpp \
|
||||||
src/widgets/streamview.hpp \
|
src/widgets/streamview.hpp \
|
||||||
src/widgets/textinputdialog.hpp \
|
src/widgets/textinputdialog.hpp \
|
||||||
src/widgets/titlebar.hpp \
|
|
||||||
src/widgets/tooltipwidget.hpp \
|
src/widgets/tooltipwidget.hpp \
|
||||||
src/widgets/window.hpp \
|
src/widgets/window.hpp \
|
||||||
src/common.hpp \
|
src/common.hpp \
|
||||||
|
|
|
@ -97,20 +97,16 @@ void AbstractIrcServer::writeConnectionMessageReceived(Communi::IrcMessage *mess
|
||||||
|
|
||||||
std::shared_ptr<Channel> AbstractIrcServer::addChannel(const QString &channelName)
|
std::shared_ptr<Channel> AbstractIrcServer::addChannel(const QString &channelName)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(this->channelMutex);
|
// try get channel
|
||||||
|
ChannelPtr chan = this->getChannel(channelName);
|
||||||
// value exists
|
if (chan != Channel::getEmpty()) {
|
||||||
auto it = this->channels.find(channelName);
|
return chan;
|
||||||
if (it != this->channels.end()) {
|
|
||||||
std::shared_ptr<Channel> chan = it.value().lock();
|
|
||||||
|
|
||||||
if (chan) {
|
|
||||||
return chan;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(this->channelMutex);
|
||||||
|
|
||||||
// value doesn't exist
|
// value doesn't exist
|
||||||
std::shared_ptr<Channel> chan = this->createChannel(channelName);
|
chan = this->createChannel(channelName);
|
||||||
if (!chan) {
|
if (!chan) {
|
||||||
return Channel::getEmpty();
|
return Channel::getEmpty();
|
||||||
}
|
}
|
||||||
|
@ -119,7 +115,7 @@ std::shared_ptr<Channel> AbstractIrcServer::addChannel(const QString &channelNam
|
||||||
|
|
||||||
this->channels.insert(channelName, chan);
|
this->channels.insert(channelName, chan);
|
||||||
chan->destroyed.connect([this, clojuresInCppAreShit] {
|
chan->destroyed.connect([this, clojuresInCppAreShit] {
|
||||||
// fourtf: issues when the server itself in destroyed
|
// fourtf: issues when the server itself is destroyed
|
||||||
|
|
||||||
debug::Log("[AbstractIrcServer::addChannel] {} was destroyed", clojuresInCppAreShit);
|
debug::Log("[AbstractIrcServer::addChannel] {} was destroyed", clojuresInCppAreShit);
|
||||||
this->channels.remove(clojuresInCppAreShit);
|
this->channels.remove(clojuresInCppAreShit);
|
||||||
|
@ -128,6 +124,7 @@ std::shared_ptr<Channel> AbstractIrcServer::addChannel(const QString &channelNam
|
||||||
// join irc channel
|
// join irc channel
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock2(this->connectionMutex);
|
std::lock_guard<std::mutex> lock2(this->connectionMutex);
|
||||||
|
|
||||||
if (this->readConnection) {
|
if (this->readConnection) {
|
||||||
this->readConnection->sendRaw("JOIN #" + channelName);
|
this->readConnection->sendRaw("JOIN #" + channelName);
|
||||||
}
|
}
|
||||||
|
@ -144,10 +141,16 @@ std::shared_ptr<Channel> AbstractIrcServer::getChannel(const QString &channelNam
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(this->channelMutex);
|
std::lock_guard<std::mutex> lock(this->channelMutex);
|
||||||
|
|
||||||
|
// try get special channel
|
||||||
|
ChannelPtr chan = this->getCustomChannel(channelName);
|
||||||
|
if (chan) {
|
||||||
|
return chan;
|
||||||
|
}
|
||||||
|
|
||||||
// value exists
|
// value exists
|
||||||
auto it = this->channels.find(channelName);
|
auto it = this->channels.find(channelName);
|
||||||
if (it != this->channels.end()) {
|
if (it != this->channels.end()) {
|
||||||
std::shared_ptr<Channel> chan = it.value().lock();
|
chan = it.value().lock();
|
||||||
|
|
||||||
if (chan) {
|
if (chan) {
|
||||||
return chan;
|
return chan;
|
||||||
|
@ -221,6 +224,20 @@ void AbstractIrcServer::privateMessageReceived(Communi::IrcPrivateMessage *messa
|
||||||
void AbstractIrcServer::messageReceived(Communi::IrcMessage *message)
|
void AbstractIrcServer::messageReceived(Communi::IrcMessage *message)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AbstractIrcServer::forEachChannel(std::function<void(ChannelPtr)> func)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(this->channelMutex);
|
||||||
|
|
||||||
|
for (std::weak_ptr<Channel> &weak : this->channels.values()) {
|
||||||
|
std::shared_ptr<Channel> chan = weak.lock();
|
||||||
|
if (!chan) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
func(chan);
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace irc
|
} // namespace irc
|
||||||
} // namespace providers
|
} // namespace providers
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <IrcMessage>
|
#include <IrcMessage>
|
||||||
|
#include <functional>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <pajlada/signals/signal.hpp>
|
#include <pajlada/signals/signal.hpp>
|
||||||
|
|
||||||
|
@ -31,6 +32,9 @@ public:
|
||||||
|
|
||||||
void addFakeMessage(const QString &data);
|
void addFakeMessage(const QString &data);
|
||||||
|
|
||||||
|
// iteration
|
||||||
|
void forEachChannel(std::function<void(ChannelPtr)> func);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
AbstractIrcServer();
|
AbstractIrcServer();
|
||||||
|
|
||||||
|
@ -47,16 +51,16 @@ protected:
|
||||||
|
|
||||||
virtual std::shared_ptr<Channel> getCustomChannel(const QString &channelName);
|
virtual std::shared_ptr<Channel> getCustomChannel(const QString &channelName);
|
||||||
|
|
||||||
|
QMap<QString, std::weak_ptr<Channel>> channels;
|
||||||
|
std::mutex channelMutex;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initConnection();
|
void initConnection();
|
||||||
|
|
||||||
QMap<QString, std::weak_ptr<Channel>> channels;
|
|
||||||
|
|
||||||
std::unique_ptr<Communi::IrcConnection> writeConnection = nullptr;
|
std::unique_ptr<Communi::IrcConnection> writeConnection = nullptr;
|
||||||
std::unique_ptr<Communi::IrcConnection> readConnection = nullptr;
|
std::unique_ptr<Communi::IrcConnection> readConnection = nullptr;
|
||||||
|
|
||||||
std::mutex connectionMutex;
|
std::mutex connectionMutex;
|
||||||
std::mutex channelMutex;
|
|
||||||
};
|
};
|
||||||
} // namespace irc
|
} // namespace irc
|
||||||
} // namespace providers
|
} // namespace providers
|
||||||
|
|
|
@ -6,10 +6,10 @@
|
||||||
#include "messages/limitedqueue.hpp"
|
#include "messages/limitedqueue.hpp"
|
||||||
#include "messages/message.hpp"
|
#include "messages/message.hpp"
|
||||||
#include "providers/twitch/twitchchannel.hpp"
|
#include "providers/twitch/twitchchannel.hpp"
|
||||||
//#include "singletons/channelmanager.hpp"
|
#include "providers/twitch/twitchmessagebuilder.hpp"
|
||||||
|
#include "providers/twitch/twitchserver.hpp"
|
||||||
#include "singletons/resourcemanager.hpp"
|
#include "singletons/resourcemanager.hpp"
|
||||||
#include "singletons/windowmanager.hpp"
|
#include "singletons/windowmanager.hpp"
|
||||||
#include "twitchserver.hpp"
|
|
||||||
|
|
||||||
using namespace chatterino::singletons;
|
using namespace chatterino::singletons;
|
||||||
using namespace chatterino::messages;
|
using namespace chatterino::messages;
|
||||||
|
@ -149,7 +149,29 @@ void IrcMessageHandler::handleUserStateMessage(Communi::IrcMessage *message)
|
||||||
|
|
||||||
void IrcMessageHandler::handleWhisperMessage(Communi::IrcMessage *message)
|
void IrcMessageHandler::handleWhisperMessage(Communi::IrcMessage *message)
|
||||||
{
|
{
|
||||||
// TODO: Implement
|
debug::Log("Received whisper!");
|
||||||
|
messages::MessageParseArgs args;
|
||||||
|
|
||||||
|
args.isReceivedWhisper = true;
|
||||||
|
|
||||||
|
auto c = TwitchServer::getInstance().whispersChannel.get();
|
||||||
|
|
||||||
|
twitch::TwitchMessageBuilder builder(c, message, message->parameter(1), args);
|
||||||
|
|
||||||
|
if (!builder.isIgnored()) {
|
||||||
|
messages::MessagePtr _message = builder.build();
|
||||||
|
if (_message->flags & messages::Message::Highlighted) {
|
||||||
|
TwitchServer::getInstance().mentionsChannel->addMessage(_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
c->addMessage(_message);
|
||||||
|
|
||||||
|
if (SettingManager::getInstance().inlineWhispers) {
|
||||||
|
TwitchServer::getInstance().forEachChannel([_message](ChannelPtr channel) {
|
||||||
|
channel->addMessage(_message); //
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IrcMessageHandler::handleUserNoticeMessage(Communi::IrcMessage *message)
|
void IrcMessageHandler::handleUserNoticeMessage(Communi::IrcMessage *message)
|
||||||
|
@ -177,9 +199,9 @@ void IrcMessageHandler::handleNoticeMessage(Communi::IrcNoticeMessage *message)
|
||||||
|
|
||||||
if (broadcast) {
|
if (broadcast) {
|
||||||
// fourtf: send to all twitch channels
|
// fourtf: send to all twitch channels
|
||||||
// this->channelManager.doOnAll([msg](const auto &c) {
|
TwitchServer::getInstance().forEachChannelAndSpecialChannels([msg](const auto &c) {
|
||||||
// c->addMessage(msg); //
|
c->addMessage(msg); //
|
||||||
// });
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <QColor>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
@ -27,6 +28,8 @@ public:
|
||||||
|
|
||||||
bool isAnon() const;
|
bool isAnon() const;
|
||||||
|
|
||||||
|
QColor color;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString oauthClient;
|
QString oauthClient;
|
||||||
QString oauthToken;
|
QString oauthToken;
|
||||||
|
|
|
@ -249,6 +249,7 @@ void TwitchChannel::fetchRecentMessages()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace twitch
|
} // namespace twitch
|
||||||
} // namespace providers
|
} // namespace providers
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "providers/twitch/twitchmessagebuilder.hpp"
|
#include "providers/twitch/twitchmessagebuilder.hpp"
|
||||||
#include "debug/log.hpp"
|
#include "debug/log.hpp"
|
||||||
#include "providers/twitch/twitchchannel.hpp"
|
#include "providers/twitch/twitchchannel.hpp"
|
||||||
|
#include "singletons/accountmanager.hpp"
|
||||||
#include "singletons/emotemanager.hpp"
|
#include "singletons/emotemanager.hpp"
|
||||||
#include "singletons/ircmanager.hpp"
|
#include "singletons/ircmanager.hpp"
|
||||||
#include "singletons/resourcemanager.hpp"
|
#include "singletons/resourcemanager.hpp"
|
||||||
|
@ -27,8 +28,22 @@ TwitchMessageBuilder::TwitchMessageBuilder(Channel *_channel,
|
||||||
, args(_args)
|
, args(_args)
|
||||||
, tags(this->ircMessage->tags())
|
, tags(this->ircMessage->tags())
|
||||||
, usernameColor(singletons::ThemeManager::getInstance().messages.textColors.system)
|
, usernameColor(singletons::ThemeManager::getInstance().messages.textColors.system)
|
||||||
|
, originalMessage(_ircMessage->content())
|
||||||
|
, action(_ircMessage->isAction())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TwitchMessageBuilder::TwitchMessageBuilder(Channel *_channel,
|
||||||
|
const Communi::IrcMessage *_ircMessage, QString content,
|
||||||
|
const messages::MessageParseArgs &_args)
|
||||||
|
: channel(_channel)
|
||||||
|
, twitchChannel(dynamic_cast<TwitchChannel *>(_channel))
|
||||||
|
, ircMessage(_ircMessage)
|
||||||
|
, args(_args)
|
||||||
|
, tags(this->ircMessage->tags())
|
||||||
|
, usernameColor(singletons::ThemeManager::getInstance().messages.textColors.system)
|
||||||
|
, originalMessage(content)
|
||||||
{
|
{
|
||||||
this->originalMessage = this->ircMessage->content();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TwitchMessageBuilder::isIgnored() const
|
bool TwitchMessageBuilder::isIgnored() const
|
||||||
|
@ -125,8 +140,8 @@ MessagePtr TwitchMessageBuilder::build()
|
||||||
long int i = 0;
|
long int i = 0;
|
||||||
|
|
||||||
for (QString split : splits) {
|
for (QString split : splits) {
|
||||||
MessageColor textColor = ircMessage->isAction() ? MessageColor(this->usernameColor)
|
MessageColor textColor =
|
||||||
: MessageColor(MessageColor::Text);
|
this->action ? MessageColor(this->usernameColor) : MessageColor(MessageColor::Text);
|
||||||
|
|
||||||
// twitch emote
|
// twitch emote
|
||||||
if (currentTwitchEmote != twitchEmotes.end() && currentTwitchEmote->first == i) {
|
if (currentTwitchEmote != twitchEmotes.end() && currentTwitchEmote->first == i) {
|
||||||
|
@ -244,7 +259,7 @@ void TwitchMessageBuilder::parseUsername()
|
||||||
}
|
}
|
||||||
|
|
||||||
// username
|
// username
|
||||||
this->userName = ircMessage->nick();
|
this->userName = this->ircMessage->nick();
|
||||||
|
|
||||||
if (this->userName.isEmpty()) {
|
if (this->userName.isEmpty()) {
|
||||||
this->userName = this->tags.value(QLatin1String("login")).toString();
|
this->userName = this->tags.value(QLatin1String("login")).toString();
|
||||||
|
@ -309,20 +324,36 @@ void TwitchMessageBuilder::appendUsername()
|
||||||
if (this->args.isSentWhisper) {
|
if (this->args.isSentWhisper) {
|
||||||
// TODO(pajlada): Re-implement
|
// TODO(pajlada): Re-implement
|
||||||
// userDisplayString += IrcManager::getInstance().getUser().getUserName();
|
// userDisplayString += IrcManager::getInstance().getUser().getUserName();
|
||||||
}
|
} else if (this->args.isReceivedWhisper) {
|
||||||
|
// Sender username
|
||||||
|
this->emplace<TextElement>(usernameText, MessageElement::Text, this->usernameColor,
|
||||||
|
FontStyle::MediumBold)
|
||||||
|
->setLink({Link::UserInfo, this->userName});
|
||||||
|
|
||||||
if (this->args.isReceivedWhisper) {
|
auto currentUser = singletons::AccountManager::getInstance().Twitch.getCurrent();
|
||||||
// TODO(pajlada): Re-implement
|
|
||||||
// userDisplayString += " -> " + IrcManager::getInstance().getUser().getUserName();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ircMessage->isAction()) {
|
// Separator
|
||||||
usernameText += ":";
|
this->emplace<TextElement>(
|
||||||
}
|
"->", MessageElement::Text,
|
||||||
|
singletons::ThemeManager::getInstance().messages.textColors.system, FontStyle::Medium);
|
||||||
|
|
||||||
this->emplace<TextElement>(usernameText, MessageElement::Text, this->usernameColor,
|
QColor selfColor = currentUser->color;
|
||||||
FontStyle::MediumBold)
|
if (!selfColor.isValid()) {
|
||||||
->setLink({Link::UserInfo, this->userName});
|
selfColor = singletons::ThemeManager::getInstance().messages.textColors.system;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Your own username
|
||||||
|
this->emplace<TextElement>(currentUser->getUserName() + ":", MessageElement::Text,
|
||||||
|
selfColor, FontStyle::MediumBold);
|
||||||
|
} else {
|
||||||
|
if (!this->action) {
|
||||||
|
usernameText += ":";
|
||||||
|
}
|
||||||
|
|
||||||
|
this->emplace<TextElement>(usernameText, MessageElement::Text, this->usernameColor,
|
||||||
|
FontStyle::MediumBold)
|
||||||
|
->setLink({Link::UserInfo, this->userName});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TwitchMessageBuilder::parseHighlights()
|
void TwitchMessageBuilder::parseHighlights()
|
||||||
|
@ -330,11 +361,12 @@ void TwitchMessageBuilder::parseHighlights()
|
||||||
static auto player = new QMediaPlayer;
|
static auto player = new QMediaPlayer;
|
||||||
static QUrl currentPlayerUrl;
|
static QUrl currentPlayerUrl;
|
||||||
singletons::SettingManager &settings = singletons::SettingManager::getInstance();
|
singletons::SettingManager &settings = singletons::SettingManager::getInstance();
|
||||||
static pajlada::Settings::Setting<std::string> currentUser("/accounts/current");
|
auto currentUser = singletons::AccountManager::getInstance().Twitch.getCurrent();
|
||||||
|
|
||||||
QString currentUsername = QString::fromStdString(currentUser.getValue());
|
QString currentUsername = currentUser->getUserName();
|
||||||
|
|
||||||
if (this->ircMessage->nick() == currentUsername) {
|
if (this->ircMessage->nick() == currentUsername) {
|
||||||
|
currentUser->color = this->usernameColor;
|
||||||
// Do nothing. Highlights cannot be triggered by yourself
|
// Do nothing. Highlights cannot be triggered by yourself
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -413,7 +445,7 @@ void TwitchMessageBuilder::parseHighlights()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TwitchMessageBuilder::appendTwitchEmote(const Communi::IrcPrivateMessage *ircMessage,
|
void TwitchMessageBuilder::appendTwitchEmote(const Communi::IrcMessage *ircMessage,
|
||||||
const QString &emote,
|
const QString &emote,
|
||||||
std::vector<std::pair<long int, util::EmoteData>> &vec)
|
std::vector<std::pair<long int, util::EmoteData>> &vec)
|
||||||
{
|
{
|
||||||
|
@ -442,11 +474,11 @@ void TwitchMessageBuilder::appendTwitchEmote(const Communi::IrcPrivateMessage *i
|
||||||
long int start = std::stol(coords.at(0).toStdString(), nullptr, 10);
|
long int start = std::stol(coords.at(0).toStdString(), nullptr, 10);
|
||||||
long int end = std::stol(coords.at(1).toStdString(), nullptr, 10);
|
long int end = std::stol(coords.at(1).toStdString(), nullptr, 10);
|
||||||
|
|
||||||
if (start >= end || start < 0 || end > ircMessage->content().length()) {
|
if (start >= end || start < 0 || end > this->originalMessage.length()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString name = ircMessage->content().mid(start, end - start + 1);
|
QString name = this->originalMessage.mid(start, end - start + 1);
|
||||||
|
|
||||||
vec.push_back(
|
vec.push_back(
|
||||||
std::pair<long int, util::EmoteData>(start, emoteManager.getTwitchEmoteById(id, name)));
|
std::pair<long int, util::EmoteData>(start, emoteManager.getTwitchEmoteById(id, name)));
|
||||||
|
|
|
@ -29,10 +29,12 @@ public:
|
||||||
|
|
||||||
explicit TwitchMessageBuilder(Channel *_channel, const Communi::IrcPrivateMessage *_ircMessage,
|
explicit TwitchMessageBuilder(Channel *_channel, const Communi::IrcPrivateMessage *_ircMessage,
|
||||||
const messages::MessageParseArgs &_args);
|
const messages::MessageParseArgs &_args);
|
||||||
|
explicit TwitchMessageBuilder(Channel *_channel, const Communi::IrcMessage *_ircMessage,
|
||||||
|
QString content, const messages::MessageParseArgs &_args);
|
||||||
|
|
||||||
Channel *channel;
|
Channel *channel;
|
||||||
TwitchChannel *twitchChannel;
|
TwitchChannel *twitchChannel;
|
||||||
const Communi::IrcPrivateMessage *ircMessage;
|
const Communi::IrcMessage *ircMessage;
|
||||||
messages::MessageParseArgs args;
|
messages::MessageParseArgs args;
|
||||||
const QVariantMap tags;
|
const QVariantMap tags;
|
||||||
|
|
||||||
|
@ -46,7 +48,9 @@ private:
|
||||||
QString roomID;
|
QString roomID;
|
||||||
|
|
||||||
QColor usernameColor;
|
QColor usernameColor;
|
||||||
QString originalMessage;
|
const QString originalMessage;
|
||||||
|
|
||||||
|
const bool action = false;
|
||||||
|
|
||||||
void parseMessageID();
|
void parseMessageID();
|
||||||
void parseRoomID();
|
void parseRoomID();
|
||||||
|
@ -55,7 +59,7 @@ private:
|
||||||
void appendUsername();
|
void appendUsername();
|
||||||
void parseHighlights();
|
void parseHighlights();
|
||||||
|
|
||||||
void appendTwitchEmote(const Communi::IrcPrivateMessage *ircMessage, const QString &emote,
|
void appendTwitchEmote(const Communi::IrcMessage *ircMessage, const QString &emote,
|
||||||
std::vector<std::pair<long, util::EmoteData>> &vec);
|
std::vector<std::pair<long, util::EmoteData>> &vec);
|
||||||
bool tryAppendEmote(QString &emoteString);
|
bool tryAppendEmote(QString &emoteString);
|
||||||
|
|
||||||
|
|
|
@ -143,6 +143,23 @@ std::shared_ptr<Channel> TwitchServer::getCustomChannel(const QString &channelNa
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TwitchServer::forEachChannelAndSpecialChannels(std::function<void(ChannelPtr)> func)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(this->channelMutex);
|
||||||
|
|
||||||
|
for (std::weak_ptr<Channel> &weak : this->channels) {
|
||||||
|
std::shared_ptr<Channel> chan = weak.lock();
|
||||||
|
if (!chan) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
func(chan);
|
||||||
|
}
|
||||||
|
|
||||||
|
func(this->whispersChannel);
|
||||||
|
func(this->mentionsChannel);
|
||||||
|
}
|
||||||
} // namespace twitch
|
} // namespace twitch
|
||||||
} // namespace providers
|
} // namespace providers
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
|
@ -16,6 +16,9 @@ class TwitchServer final : public irc::AbstractIrcServer
|
||||||
public:
|
public:
|
||||||
static TwitchServer &getInstance();
|
static TwitchServer &getInstance();
|
||||||
|
|
||||||
|
// fourtf: ugh
|
||||||
|
void forEachChannelAndSpecialChannels(std::function<void(ChannelPtr)> func);
|
||||||
|
|
||||||
const ChannelPtr whispersChannel;
|
const ChannelPtr whispersChannel;
|
||||||
const ChannelPtr mentionsChannel;
|
const ChannelPtr mentionsChannel;
|
||||||
|
|
||||||
|
|
|
@ -136,5 +136,14 @@
|
||||||
// func(this->mentionsChannel);
|
// func(this->mentionsChannel);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//} // namespace singletons
|
//}
|
||||||
|
|
||||||
|
// void ChannelManager::doOnAllNormalChannels(std::function<void(ChannelPtr)> func)
|
||||||
|
//{
|
||||||
|
// for (const auto &channel : this->twitchChannels) {
|
||||||
|
// func(std::get<0>(channel));
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
//} // namespace chatterino
|
//} // namespace chatterino
|
||||||
|
//}
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
// const ChannelPtr whispersChannel;
|
// const ChannelPtr whispersChannel;
|
||||||
// const ChannelPtr mentionsChannel;
|
// const ChannelPtr mentionsChannel;
|
||||||
// const ChannelPtr emptyChannel;
|
// const ChannelPtr emptyChannel;
|
||||||
|
// void doOnAll(std::function<void(ChannelPtr)> func);
|
||||||
|
// void doOnAllNormalChannels(std::function<void(ChannelPtr)> func);
|
||||||
|
|
||||||
// private:
|
// private:
|
||||||
// std::map<std::string, std::string> usernameToID;
|
// std::map<std::string, std::string> usernameToID;
|
||||||
|
|
|
@ -7,18 +7,18 @@
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
namespace singletons {
|
namespace singletons {
|
||||||
|
|
||||||
|
QByteArray endline("\n");
|
||||||
|
|
||||||
LoggingChannel::LoggingChannel(const QString &_channelName, const QString &_baseDirectory)
|
LoggingChannel::LoggingChannel(const QString &_channelName, const QString &_baseDirectory)
|
||||||
: channelName(_channelName)
|
: channelName(_channelName)
|
||||||
, baseDirectory(_baseDirectory)
|
, baseDirectory(_baseDirectory)
|
||||||
{
|
{
|
||||||
QDateTime now = QDateTime::currentDateTime();
|
QDateTime now = QDateTime::currentDateTime();
|
||||||
|
|
||||||
QString baseFileName = this->channelName + "-" + now.toString("yyyy-MM-dd") + ".log";
|
this->dateString = this->generateDateString(now);
|
||||||
|
|
||||||
// Open file handle to log file of current date
|
this->openLogFile();
|
||||||
this->fileHandle.setFileName(this->baseDirectory + QDir::separator() + baseFileName);
|
|
||||||
|
|
||||||
this->fileHandle.open(QIODevice::Append);
|
|
||||||
this->appendLine(this->generateOpeningString(now));
|
this->appendLine(this->generateOpeningString(now));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,24 +28,38 @@ LoggingChannel::~LoggingChannel()
|
||||||
this->fileHandle.close();
|
this->fileHandle.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LoggingChannel::openLogFile()
|
||||||
|
{
|
||||||
|
if (this->fileHandle.isOpen()) {
|
||||||
|
this->fileHandle.flush();
|
||||||
|
this->fileHandle.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString baseFileName = this->channelName + "-" + this->dateString + ".log";
|
||||||
|
|
||||||
|
// Open file handle to log file of current date
|
||||||
|
this->fileHandle.setFileName(this->baseDirectory + QDir::separator() + baseFileName);
|
||||||
|
|
||||||
|
this->fileHandle.open(QIODevice::Append);
|
||||||
|
}
|
||||||
|
|
||||||
void LoggingChannel::addMessage(std::shared_ptr<messages::Message> message)
|
void LoggingChannel::addMessage(std::shared_ptr<messages::Message> message)
|
||||||
{
|
{
|
||||||
QDateTime now = QDateTime::currentDateTime();
|
QDateTime now = QDateTime::currentDateTime();
|
||||||
|
|
||||||
|
QString messageDateString = this->generateDateString(now);
|
||||||
|
if (messageDateString != this->dateString) {
|
||||||
|
this->dateString = messageDateString;
|
||||||
|
this->openLogFile();
|
||||||
|
}
|
||||||
|
|
||||||
QString str;
|
QString str;
|
||||||
str.append('[');
|
str.append('[');
|
||||||
str.append(now.toString("HH:mm:ss"));
|
str.append(now.toString("HH:mm:ss"));
|
||||||
str.append("] ");
|
str.append("] ");
|
||||||
|
|
||||||
if ((message->flags & messages::Message::MessageFlags::System) != 0) {
|
str.append(message->searchText);
|
||||||
str.append(message->searchText);
|
str.append(endline);
|
||||||
str.append('\n');
|
|
||||||
} else {
|
|
||||||
str.append(message->loginName);
|
|
||||||
str.append(": ");
|
|
||||||
str.append(message->searchText);
|
|
||||||
str.append('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
this->appendLine(str);
|
this->appendLine(str);
|
||||||
}
|
}
|
||||||
|
@ -56,7 +70,7 @@ QString LoggingChannel::generateOpeningString(const QDateTime &now) const
|
||||||
|
|
||||||
ret.append(now.toString("yyyy-MM-dd HH:mm:ss "));
|
ret.append(now.toString("yyyy-MM-dd HH:mm:ss "));
|
||||||
ret.append(now.timeZoneAbbreviation());
|
ret.append(now.timeZoneAbbreviation());
|
||||||
ret.append('\n');
|
ret.append(endline);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -67,16 +81,31 @@ QString LoggingChannel::generateClosingString(const QDateTime &now) const
|
||||||
|
|
||||||
ret.append(now.toString("yyyy-MM-dd HH:mm:ss"));
|
ret.append(now.toString("yyyy-MM-dd HH:mm:ss"));
|
||||||
ret.append(now.timeZoneAbbreviation());
|
ret.append(now.timeZoneAbbreviation());
|
||||||
ret.append('\n');
|
ret.append(endline);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoggingChannel::appendLine(const QString &line)
|
void LoggingChannel::appendLine(const QString &line)
|
||||||
{
|
{
|
||||||
|
auto a1 = line.toUtf8();
|
||||||
|
auto a2 = line.toLatin1();
|
||||||
|
auto a3 = line.toLocal8Bit();
|
||||||
|
|
||||||
|
auto a4 = line.data();
|
||||||
|
|
||||||
|
auto a5 = line.toStdString();
|
||||||
|
|
||||||
|
// this->fileHandle.write(a5.c_str(), a5.length());
|
||||||
|
// this->fileHandle.write(a5.c_str(), a5.length());
|
||||||
this->fileHandle.write(line.toUtf8());
|
this->fileHandle.write(line.toUtf8());
|
||||||
this->fileHandle.flush();
|
this->fileHandle.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString LoggingChannel::generateDateString(const QDateTime &now)
|
||||||
|
{
|
||||||
|
return now.toString("yyyy-MM-dd");
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace singletons
|
} // namespace singletons
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
|
@ -21,17 +21,22 @@ public:
|
||||||
void addMessage(std::shared_ptr<messages::Message> message);
|
void addMessage(std::shared_ptr<messages::Message> message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void openLogFile();
|
||||||
|
|
||||||
QString generateOpeningString(const QDateTime &now = QDateTime::currentDateTime()) const;
|
QString generateOpeningString(const QDateTime &now = QDateTime::currentDateTime()) const;
|
||||||
QString generateClosingString(const QDateTime &now = QDateTime::currentDateTime()) const;
|
QString generateClosingString(const QDateTime &now = QDateTime::currentDateTime()) const;
|
||||||
|
|
||||||
void appendLine(const QString &line);
|
void appendLine(const QString &line);
|
||||||
|
|
||||||
private:
|
QString generateDateString(const QDateTime &now);
|
||||||
QString channelName;
|
|
||||||
const QString &baseDirectory;
|
const QString channelName;
|
||||||
QString fileName;
|
const QString baseDirectory;
|
||||||
|
|
||||||
QFile fileHandle;
|
QFile fileHandle;
|
||||||
|
|
||||||
|
QString dateString;
|
||||||
|
|
||||||
friend class LoggingManager;
|
friend class LoggingManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -85,12 +85,16 @@ void ResizingTextEdit::keyPressEvent(QKeyEvent *event)
|
||||||
|
|
||||||
if (doComplete) {
|
if (doComplete) {
|
||||||
// check if there is a completer
|
// check if there is a completer
|
||||||
return_if_not(this->completer);
|
if (!this->completer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QString currentCompletionPrefix = this->textUnderCursor();
|
QString currentCompletionPrefix = this->textUnderCursor();
|
||||||
|
|
||||||
// check if there is something to complete
|
// check if there is something to complete
|
||||||
return_if_not(currentCompletionPrefix.size());
|
if (!currentCompletionPrefix.size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto *completionModel =
|
auto *completionModel =
|
||||||
static_cast<chatterino::singletons::CompletionModel *>(this->completer->model());
|
static_cast<chatterino::singletons::CompletionModel *>(this->completer->model());
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
namespace widgets {
|
namespace widgets {
|
||||||
namespace settingspages {
|
namespace settingspages {
|
||||||
|
|
||||||
EmotesPage::EmotesPage()
|
EmotesPage::EmotesPage()
|
||||||
: SettingsPage("Emotes", ":/images/emote.svg")
|
: SettingsPage("Emotes", ":/images/emote.svg")
|
||||||
{
|
{
|
||||||
|
@ -22,6 +23,7 @@ EmotesPage::EmotesPage()
|
||||||
|
|
||||||
layout->addStretch(1);
|
layout->addStretch(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace settingspages
|
} // namespace settingspages
|
||||||
} // namespace widgets
|
} // namespace widgets
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "logspage.hpp"
|
#include "logspage.hpp"
|
||||||
|
#include "singletons/pathmanager.hpp"
|
||||||
|
|
||||||
#include <QFormLayout>
|
#include <QFormLayout>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
@ -9,6 +10,16 @@ namespace chatterino {
|
||||||
namespace widgets {
|
namespace widgets {
|
||||||
namespace settingspages {
|
namespace settingspages {
|
||||||
|
|
||||||
|
inline QString CreateLink(const QString &url, bool file = false)
|
||||||
|
{
|
||||||
|
if (file) {
|
||||||
|
return QString("<a href=\"file:///" + url + "\"><span style=\"color: white;\">" + url +
|
||||||
|
"</span></a>");
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString("<a href=\"" + url + "\"><span style=\"color: white;\">" + url + "</span></a>");
|
||||||
|
}
|
||||||
|
|
||||||
LogsPage::LogsPage()
|
LogsPage::LogsPage()
|
||||||
: SettingsPage("Logs", "")
|
: SettingsPage("Logs", "")
|
||||||
{
|
{
|
||||||
|
@ -16,13 +27,16 @@ LogsPage::LogsPage()
|
||||||
util::LayoutCreator<LogsPage> layoutCreator(this);
|
util::LayoutCreator<LogsPage> layoutCreator(this);
|
||||||
auto layout = layoutCreator.emplace<QVBoxLayout>().withoutMargin();
|
auto layout = layoutCreator.emplace<QVBoxLayout>().withoutMargin();
|
||||||
|
|
||||||
{
|
singletons::PathManager &pathManager = singletons::PathManager::getInstance();
|
||||||
auto form = layout.emplace<QFormLayout>();
|
auto logPath = pathManager.logsFolderPath;
|
||||||
|
|
||||||
// clang-format off
|
auto created = layout.emplace<QLabel>();
|
||||||
form->addRow("Enabled:", this->createCheckBox("Enable logging", settings.enableLogging));
|
created->setText("Logs are saved to " + CreateLink(logPath, true));
|
||||||
// clang-format on
|
created->setTextFormat(Qt::RichText);
|
||||||
}
|
created->setTextInteractionFlags(Qt::TextBrowserInteraction | Qt::LinksAccessibleByKeyboard |
|
||||||
|
Qt::LinksAccessibleByKeyboard);
|
||||||
|
created->setOpenExternalLinks(true);
|
||||||
|
layout.append(this->createCheckBox("Enable logging", settings.enableLogging));
|
||||||
|
|
||||||
layout->addStretch(1);
|
layout->addStretch(1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ namespace settingspages {
|
||||||
SpecialChannelsPage::SpecialChannelsPage()
|
SpecialChannelsPage::SpecialChannelsPage()
|
||||||
: SettingsPage("Special channels", "")
|
: SettingsPage("Special channels", "")
|
||||||
{
|
{
|
||||||
|
singletons::SettingManager &settings = singletons::SettingManager::getInstance();
|
||||||
util::LayoutCreator<SpecialChannelsPage> layoutCreator(this);
|
util::LayoutCreator<SpecialChannelsPage> layoutCreator(this);
|
||||||
auto layout = layoutCreator.setLayoutType<QVBoxLayout>();
|
auto layout = layoutCreator.setLayoutType<QVBoxLayout>();
|
||||||
|
|
||||||
|
@ -21,6 +22,12 @@ SpecialChannelsPage::SpecialChannelsPage()
|
||||||
mentions.emplace<QLabel>("Join /mentions to view your mentions.");
|
mentions.emplace<QLabel>("Join /mentions to view your mentions.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto whispers = layout.emplace<QGroupBox>("Whispers").setLayoutType<QVBoxLayout>();
|
||||||
|
{
|
||||||
|
whispers.emplace<QLabel>("Join /whispers to view your mentions.");
|
||||||
|
whispers.append(this->createCheckBox("Show whispers inline", settings.inlineWhispers));
|
||||||
|
}
|
||||||
|
|
||||||
layout->addStretch(1);
|
layout->addStretch(1);
|
||||||
}
|
}
|
||||||
} // namespace settingspages
|
} // namespace settingspages
|
||||||
|
|
|
@ -139,11 +139,6 @@ ChannelPtr Split::getChannel() const
|
||||||
return this->channel;
|
return this->channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChannelPtr &Split::getChannelRef()
|
|
||||||
{
|
|
||||||
return this->channel;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Split::setChannel(ChannelPtr _newChannel)
|
void Split::setChannel(ChannelPtr _newChannel)
|
||||||
{
|
{
|
||||||
this->view.setChannel(_newChannel);
|
this->view.setChannel(_newChannel);
|
||||||
|
|
|
@ -57,7 +57,6 @@ public:
|
||||||
|
|
||||||
const std::string &getUUID() const;
|
const std::string &getUUID() const;
|
||||||
ChannelPtr getChannel() const;
|
ChannelPtr getChannel() const;
|
||||||
ChannelPtr &getChannelRef();
|
|
||||||
void setFlexSizeX(double x);
|
void setFlexSizeX(double x);
|
||||||
double getFlexSizeX();
|
double getFlexSizeX();
|
||||||
void setFlexSizeY(double y);
|
void setFlexSizeY(double y);
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
#include "titlebar.hpp"
|
|
||||||
|
|
||||||
namespace chatterino {
|
|
||||||
namespace widgets {
|
|
||||||
|
|
||||||
TitleBar::TitleBar(QWidget *parent)
|
|
||||||
: QWidget(parent)
|
|
||||||
{
|
|
||||||
setFixedHeight(32);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace widgets
|
|
||||||
} // namespace chatterino
|
|
|
@ -46,11 +46,6 @@ Window::Window(const QString &windowName, singletons::ThemeManager &_themeManage
|
||||||
|
|
||||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||||
|
|
||||||
// add titlebar
|
|
||||||
// if (SettingsManager::getInstance().useCustomWindowFrame.get()) {
|
|
||||||
// layout->addWidget(&_titleBar);
|
|
||||||
// }
|
|
||||||
|
|
||||||
layout->addWidget(&this->notebook);
|
layout->addWidget(&this->notebook);
|
||||||
this->getLayoutContainer()->setLayout(layout);
|
this->getLayoutContainer()->setLayout(layout);
|
||||||
|
|
||||||
|
@ -63,9 +58,7 @@ Window::Window(const QString &windowName, singletons::ThemeManager &_themeManage
|
||||||
|
|
||||||
/// Initialize program-wide hotkeys
|
/// Initialize program-wide hotkeys
|
||||||
// CTRL+P: Open Settings Dialog
|
// CTRL+P: Open Settings Dialog
|
||||||
CreateWindowShortcut(this, "CTRL+P", [] {
|
CreateWindowShortcut(this, "CTRL+P", [] { SettingsDialog::showDialog(); });
|
||||||
SettingsDialog::showDialog(); //
|
|
||||||
});
|
|
||||||
|
|
||||||
// CTRL+Number: Switch to n'th tab
|
// CTRL+Number: Switch to n'th tab
|
||||||
CreateWindowShortcut(this, "CTRL+1", [this] { this->notebook.selectIndex(0); });
|
CreateWindowShortcut(this, "CTRL+1", [this] { this->notebook.selectIndex(0); });
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
#include "util/helpers.hpp"
|
#include "util/helpers.hpp"
|
||||||
#include "widgets/basewindow.hpp"
|
#include "widgets/basewindow.hpp"
|
||||||
#include "widgets/notebook.hpp"
|
#include "widgets/notebook.hpp"
|
||||||
#include "widgets/titlebar.hpp"
|
|
||||||
|
|
||||||
//#ifdef USEWINSDK
|
//#ifdef USEWINSDK
|
||||||
//#include <platform/borderless/qwinwidget.h>
|
//#include <platform/borderless/qwinwidget.h>
|
||||||
|
@ -65,7 +64,7 @@ private:
|
||||||
void loadGeometry();
|
void loadGeometry();
|
||||||
|
|
||||||
Notebook notebook;
|
Notebook notebook;
|
||||||
TitleBar titleBar;
|
// TitleBar titleBar;
|
||||||
|
|
||||||
friend class Notebook;
|
friend class Notebook;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue