mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
Add feature to select channels to log (#4302)
* Add checkbox for custom logging and table with channels to log on Logs page * Add checkbox to enable and disable logging per channel * Return from addMessage before logging if custom logging enabled and channel does not have logging enabled * Use clang-format to fix formatting * Add CHANGELOG.md entry * Resolve PR comments * Remove toggle for channels so any channel listed will be logged * Move Only log channels listed below checkbox to just above table * Fix formatting * Re-order changelog * ChannelLog constructor: Copy & move instead of const ref & copy * ChannelLog::createEmpty: Curly brace initialize instead of repeating name * ChannelLog toString & createEmpty: nodiscard * Use COUNT paradigm in model column * Remove ChanneLoggingModel source file comments * Use Column::Channel in getRowFromItem * Rename `getItemFromRow` parameter and mark it as unused * Curly brace initialize ChannelLog * private & friend class the model * Filter out channels to log using a set instead of iterating over a vector every time a message comes in * Rename `ChannelLog::channel` member to `ChannelLog::channelName` Also made it private * mini comment on ChannelLog Co-authored-by: Felanbird <41973452+Felanbird@users.noreply.github.com> Co-authored-by: Rasmus Karlsson <rasmus.karlsson@pajlada.com>
This commit is contained in:
parent
a567cc5ae7
commit
4c782ce90c
|
@ -8,6 +8,7 @@
|
|||
- Minor: Tables in settings window will now scroll to newly added rows. (#4216)
|
||||
- Minor: Added link to streamlink docs for easier user setup. (#4217)
|
||||
- Minor: Added setting to turn off rendering of reply context. (#4224)
|
||||
- Minor: Added setting to select which channels to log. (#4302)
|
||||
- Bugfix: Fixed crash that would occur when performing certain actions after removing all tabs. (#4271)
|
||||
- Bugfix: Fixed highlight sounds not reloading on change properly. (#4194)
|
||||
- Bugfix: Fixed CTRL + C not working in reply thread popups. (#4209)
|
||||
|
|
|
@ -119,6 +119,11 @@ set(SOURCE_FILES
|
|||
controllers/moderationactions/ModerationActionModel.cpp
|
||||
controllers/moderationactions/ModerationActionModel.hpp
|
||||
|
||||
controllers/logging/ChannelLog.cpp
|
||||
controllers/logging/ChannelLog.hpp
|
||||
controllers/logging/ChannelLoggingModel.cpp
|
||||
controllers/logging/ChannelLoggingModel.hpp
|
||||
|
||||
controllers/nicknames/NicknamesModel.cpp
|
||||
controllers/nicknames/NicknamesModel.hpp
|
||||
controllers/nicknames/Nickname.hpp
|
||||
|
|
25
src/controllers/logging/ChannelLog.cpp
Normal file
25
src/controllers/logging/ChannelLog.cpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
#include "controllers/logging/ChannelLog.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
ChannelLog::ChannelLog(QString channelName)
|
||||
: channelName_(std::move(channelName))
|
||||
{
|
||||
}
|
||||
|
||||
QString ChannelLog::channelName() const
|
||||
{
|
||||
return this->channelName_;
|
||||
}
|
||||
|
||||
QString ChannelLog::toString() const
|
||||
{
|
||||
return this->channelName_;
|
||||
}
|
||||
|
||||
ChannelLog ChannelLog::createEmpty()
|
||||
{
|
||||
return {""};
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
69
src/controllers/logging/ChannelLog.hpp
Normal file
69
src/controllers/logging/ChannelLog.hpp
Normal file
|
@ -0,0 +1,69 @@
|
|||
#pragma once
|
||||
|
||||
#include "util/RapidjsonHelpers.hpp"
|
||||
|
||||
#include <pajlada/serialize.hpp>
|
||||
#include <QString>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
/**
|
||||
* @brief Contains the description of a channel that will be logged
|
||||
**/
|
||||
class ChannelLog
|
||||
{
|
||||
QString channelName_;
|
||||
|
||||
public:
|
||||
ChannelLog(QString channelName);
|
||||
|
||||
bool operator==(const ChannelLog &other) const;
|
||||
|
||||
[[nodiscard]] QString channelName() const;
|
||||
|
||||
[[nodiscard]] QString toString() const;
|
||||
|
||||
[[nodiscard]] static ChannelLog createEmpty();
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
namespace pajlada {
|
||||
|
||||
template <>
|
||||
struct Serialize<chatterino::ChannelLog> {
|
||||
static rapidjson::Value get(const chatterino::ChannelLog &value,
|
||||
rapidjson::Document::AllocatorType &a)
|
||||
{
|
||||
rapidjson::Value ret(rapidjson::kObjectType);
|
||||
|
||||
chatterino::rj::set(ret, "channelName", value.channelName(), a);
|
||||
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Deserialize<chatterino::ChannelLog> {
|
||||
static chatterino::ChannelLog get(const rapidjson::Value &value,
|
||||
bool *error = nullptr)
|
||||
{
|
||||
if (!value.IsObject())
|
||||
{
|
||||
PAJLADA_REPORT_ERROR(error);
|
||||
return chatterino::ChannelLog::createEmpty();
|
||||
}
|
||||
|
||||
QString channelName;
|
||||
|
||||
if (!chatterino::rj::getSafe(value, "channelName", channelName))
|
||||
{
|
||||
PAJLADA_REPORT_ERROR(error);
|
||||
return chatterino::ChannelLog::createEmpty();
|
||||
}
|
||||
|
||||
return {channelName};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace pajlada
|
25
src/controllers/logging/ChannelLoggingModel.cpp
Normal file
25
src/controllers/logging/ChannelLoggingModel.cpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
#include "controllers/logging/ChannelLoggingModel.hpp"
|
||||
|
||||
#include "util/StandardItemHelper.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
ChannelLoggingModel ::ChannelLoggingModel(QObject *parent)
|
||||
: SignalVectorModel<ChannelLog>(Column::COUNT, parent)
|
||||
{
|
||||
}
|
||||
|
||||
ChannelLog ChannelLoggingModel::getItemFromRow(
|
||||
std::vector<QStandardItem *> &row, const ChannelLog & /*original*/)
|
||||
{
|
||||
auto channelName = row[Column::Channel]->data(Qt::DisplayRole).toString();
|
||||
return {channelName};
|
||||
}
|
||||
|
||||
void ChannelLoggingModel::getRowFromItem(const ChannelLog &item,
|
||||
std::vector<QStandardItem *> &row)
|
||||
{
|
||||
setStringItem(row[Column::Channel], item.channelName());
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
31
src/controllers/logging/ChannelLoggingModel.hpp
Normal file
31
src/controllers/logging/ChannelLoggingModel.hpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
|
||||
#include "common/SignalVectorModel.hpp"
|
||||
#include "controllers/logging/ChannelLog.hpp"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class ChannelLoggingModel : public SignalVectorModel<ChannelLog>
|
||||
{
|
||||
explicit ChannelLoggingModel(QObject *parent);
|
||||
|
||||
enum Column {
|
||||
Channel,
|
||||
COUNT,
|
||||
};
|
||||
|
||||
protected:
|
||||
// turn a vector item into a model row
|
||||
ChannelLog getItemFromRow(std::vector<QStandardItem *> &row,
|
||||
const ChannelLog &original) override;
|
||||
|
||||
// turns a row in the model into a vector item
|
||||
void getRowFromItem(const ChannelLog &item,
|
||||
std::vector<QStandardItem *> &row) override;
|
||||
|
||||
friend class ModerationPage;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
|
@ -1,6 +1,5 @@
|
|||
#include "singletons/Logging.hpp"
|
||||
|
||||
#include "Application.hpp"
|
||||
#include "singletons/helper/LoggingChannel.hpp"
|
||||
#include "singletons/Paths.hpp"
|
||||
#include "singletons/Settings.hpp"
|
||||
|
@ -9,23 +8,42 @@
|
|||
#include <QStandardPaths>
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
void Logging::initialize(Settings &settings, Paths &paths)
|
||||
void Logging::initialize(Settings &settings, Paths & /*paths*/)
|
||||
{
|
||||
settings.loggedChannels.delayedItemsChanged.connect([this, &settings]() {
|
||||
this->threadGuard.guard();
|
||||
|
||||
this->onlyLogListedChannels.clear();
|
||||
|
||||
for (const auto &loggedChannel : *settings.loggedChannels.readOnly())
|
||||
{
|
||||
this->onlyLogListedChannels.insert(loggedChannel.channelName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Logging::addMessage(const QString &channelName, MessagePtr message,
|
||||
const QString &platformName)
|
||||
{
|
||||
this->threadGuard.guard();
|
||||
|
||||
if (!getSettings()->enableLogging)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (getSettings()->onlyLogListedChannels)
|
||||
{
|
||||
if (!this->onlyLogListedChannels.contains(channelName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto platIt = this->loggingChannels_.find(platformName);
|
||||
if (platIt == this->loggingChannels_.end())
|
||||
{
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
#include "common/Singleton.hpp"
|
||||
#include "util/QStringHash.hpp"
|
||||
#include "util/ThreadGuard.hpp"
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
|
@ -32,6 +35,10 @@ private:
|
|||
std::map<PlatformName,
|
||||
std::map<ChannelName, std::unique_ptr<LoggingChannel>>>
|
||||
loggingChannels_;
|
||||
|
||||
// Keeps the value of the `loggedChannels` settings
|
||||
std::unordered_set<ChannelName> onlyLogListedChannels;
|
||||
ThreadGuard threadGuard;
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
|
|
|
@ -25,6 +25,7 @@ ConcurrentSettings::ConcurrentSettings()
|
|||
, filterRecords(*new SignalVector<FilterRecordPtr>())
|
||||
, nicknames(*new SignalVector<Nickname>())
|
||||
, moderationActions(*new SignalVector<ModerationAction>)
|
||||
, loggedChannels(*new SignalVector<ChannelLog>)
|
||||
{
|
||||
persist(this->highlightedMessages, "/highlighting/highlights");
|
||||
persist(this->blacklistedUsers, "/highlighting/blacklist");
|
||||
|
@ -36,6 +37,7 @@ ConcurrentSettings::ConcurrentSettings()
|
|||
persist(this->nicknames, "/nicknames");
|
||||
// tagged users?
|
||||
persist(this->moderationActions, "/moderation/actions");
|
||||
persist(this->loggedChannels, "/logging/channels");
|
||||
}
|
||||
|
||||
bool ConcurrentSettings::isHighlightedUser(const QString &username)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "BaseSettings.hpp"
|
||||
#include "common/Channel.hpp"
|
||||
#include "common/SignalVector.hpp"
|
||||
#include "controllers/logging/ChannelLog.hpp"
|
||||
#include "singletons/Toasts.hpp"
|
||||
#include "util/RapidJsonSerializeQString.hpp"
|
||||
#include "util/StreamerMode.hpp"
|
||||
|
@ -40,6 +41,7 @@ public:
|
|||
SignalVector<FilterRecordPtr> &filterRecords;
|
||||
SignalVector<Nickname> &nicknames;
|
||||
SignalVector<ModerationAction> &moderationActions;
|
||||
SignalVector<ChannelLog> &loggedChannels;
|
||||
|
||||
bool isHighlightedUser(const QString &username);
|
||||
bool isBlacklistedUser(const QString &username);
|
||||
|
@ -364,6 +366,8 @@ public:
|
|||
|
||||
/// Logging
|
||||
BoolSetting enableLogging = {"/logging/enabled", false};
|
||||
BoolSetting onlyLogListedChannels = {"/logging/onlyLogListedChannels",
|
||||
false};
|
||||
|
||||
QStringSetting logPath = {"/logging/path", ""};
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "ModerationPage.hpp"
|
||||
|
||||
#include "Application.hpp"
|
||||
#include "controllers/logging/ChannelLoggingModel.hpp"
|
||||
#include "controllers/moderationactions/ModerationAction.hpp"
|
||||
#include "controllers/moderationactions/ModerationActionModel.hpp"
|
||||
#include "singletons/Logging.hpp"
|
||||
|
@ -69,8 +70,10 @@ ModerationPage::ModerationPage()
|
|||
|
||||
auto logs = tabs.appendTab(new QVBoxLayout, "Logs");
|
||||
{
|
||||
logs.append(this->createCheckBox("Enable logging",
|
||||
getSettings()->enableLogging));
|
||||
QCheckBox *enableLogging = this->createCheckBox(
|
||||
"Enable logging", getSettings()->enableLogging);
|
||||
logs.append(enableLogging);
|
||||
|
||||
auto logsPathLabel = logs.emplace<QLabel>();
|
||||
|
||||
// Logs (copied from LoggingMananger)
|
||||
|
@ -105,7 +108,6 @@ ModerationPage::ModerationPage()
|
|||
});
|
||||
|
||||
buttons->addStretch();
|
||||
logs->addStretch(1);
|
||||
|
||||
// Show how big (size-wise) the logs are
|
||||
auto logsPathSizeLabel = logs.emplace<QLabel>();
|
||||
|
@ -140,6 +142,36 @@ ModerationPage::ModerationPage()
|
|||
}));
|
||||
});
|
||||
|
||||
QCheckBox *onlyLogListedChannels =
|
||||
this->createCheckBox("Only log channels listed below",
|
||||
getSettings()->onlyLogListedChannels);
|
||||
|
||||
onlyLogListedChannels->setEnabled(getSettings()->enableLogging);
|
||||
logs.append(onlyLogListedChannels);
|
||||
|
||||
// Select event
|
||||
QObject::connect(
|
||||
enableLogging, &QCheckBox::stateChanged, this,
|
||||
[enableLogging, onlyLogListedChannels]() mutable {
|
||||
onlyLogListedChannels->setEnabled(enableLogging->isChecked());
|
||||
});
|
||||
|
||||
EditableModelView *view =
|
||||
logs.emplace<EditableModelView>(
|
||||
(new ChannelLoggingModel(nullptr))
|
||||
->initialized(&getSettings()->loggedChannels))
|
||||
.getElement();
|
||||
|
||||
view->setTitles({"Twitch channels"});
|
||||
view->getTableView()->horizontalHeader()->setSectionResizeMode(
|
||||
QHeaderView::Fixed);
|
||||
view->getTableView()->horizontalHeader()->setSectionResizeMode(
|
||||
0, QHeaderView::Stretch);
|
||||
|
||||
view->addButtonPressed.connect([] {
|
||||
getSettings()->loggedChannels.append(ChannelLog("channel"));
|
||||
});
|
||||
|
||||
} // logs end
|
||||
|
||||
auto modMode = tabs.appendTab(new QVBoxLayout, "Moderation buttons");
|
||||
|
|
Loading…
Reference in a new issue