Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added the ability to add nicknames for users #2981

Merged
merged 17 commits into from
Jul 31, 2021
Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## Unversioned

- Major: Newly uploaded Twitch emotes are once again present in emote picker and can be autocompleted with Tab as well. (#2992)
- Major: Added the ability to add nicknames for users. (#137, #2981)
- Minor: Added autocompletion in /whispers for Twitch emotes, Global Bttv/Ffz emotes and emojis. (#2999, #3033)
- Minor: Received Twitch messages now use the exact same timestamp (obtained from Twitch's server) for every Chatterino user instead of assuming message timestamp on client's side. (#3021)
- Minor: Received IRC messages use `time` message tag for timestamp if it's available. (#3021)
Expand Down
4 changes: 4 additions & 0 deletions chatterino.pro
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ SOURCES += \
src/controllers/ignores/IgnoreModel.cpp \
src/controllers/moderationactions/ModerationAction.cpp \
src/controllers/moderationactions/ModerationActionModel.cpp \
src/controllers/nicknames/NicknamesModel.cpp \
src/controllers/notifications/NotificationController.cpp \
src/controllers/notifications/NotificationModel.cpp \
src/controllers/pings/MutedChannelModel.cpp \
Expand Down Expand Up @@ -315,6 +316,7 @@ SOURCES += \
src/widgets/settingspages/IgnoresPage.cpp \
src/widgets/settingspages/KeyboardSettingsPage.cpp \
src/widgets/settingspages/ModerationPage.cpp \
src/widgets/settingspages/NicknamesPage.cpp \
src/widgets/settingspages/NotificationPage.cpp \
src/widgets/settingspages/SettingsPage.cpp \
src/widgets/splits/ClosedSplits.cpp \
Expand Down Expand Up @@ -391,6 +393,8 @@ HEADERS += \
src/controllers/ignores/IgnorePhrase.hpp \
src/controllers/moderationactions/ModerationAction.hpp \
src/controllers/moderationactions/ModerationActionModel.hpp \
src/controllers/nicknames/Nickname.hpp \
src/controllers/nicknames/NicknamesModel.hpp \
src/controllers/notifications/NotificationController.hpp \
src/controllers/notifications/NotificationModel.hpp \
src/controllers/pings/MutedChannelModel.hpp \
Expand Down
6 changes: 6 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ set(SOURCE_FILES
controllers/moderationactions/ModerationActionModel.cpp
controllers/moderationactions/ModerationActionModel.hpp

controllers/nicknames/NicknamesModel.cpp
controllers/nicknames/NicknamesModel.hpp
controllers/nicknames/Nickname.hpp

controllers/notifications/NotificationController.cpp
controllers/notifications/NotificationController.hpp
controllers/notifications/NotificationModel.cpp
Expand Down Expand Up @@ -428,6 +432,8 @@ set(SOURCE_FILES
widgets/settingspages/KeyboardSettingsPage.hpp
widgets/settingspages/ModerationPage.cpp
widgets/settingspages/ModerationPage.hpp
widgets/settingspages/NicknamesPage.cpp
widgets/settingspages/NicknamesPage.hpp
widgets/settingspages/NotificationPage.cpp
widgets/settingspages/NotificationPage.hpp
widgets/settingspages/SettingsPage.cpp
Expand Down
77 changes: 77 additions & 0 deletions src/controllers/nicknames/Nickname.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#pragma once

#include "controllers/accounts/AccountController.hpp"

#include "util/RapidJsonSerializeQString.hpp"
#include "util/RapidjsonHelpers.hpp"

#include <QString>
#include <pajlada/serialize.hpp>

#include <memory>

namespace chatterino {

class Nickname
{
public:
Nickname(const QString &name, const QString &replace)
: name_(name)
, replace_(replace)
{
}

const QString &name() const
{
return this->name_;
}
const QString &replace() const
{
return this->replace_;
}

private:
QString name_;
QString replace_;
};

} // namespace chatterino

namespace pajlada {

template <>
struct Serialize<chatterino::Nickname> {
static rapidjson::Value get(const chatterino::Nickname &value,
rapidjson::Document::AllocatorType &a)
{
rapidjson::Value ret(rapidjson::kObjectType);

chatterino::rj::set(ret, "name", value.name(), a);
chatterino::rj::set(ret, "replace", value.replace(), a);

return ret;
}
};

template <>
struct Deserialize<chatterino::Nickname> {
static chatterino::Nickname get(const rapidjson::Value &value,
bool *error = nullptr)
{
if (!value.IsObject())
{
PAJLADA_REPORT_ERROR(error)
return chatterino::Nickname(QString(), QString());
}

QString _name;
QString _replace;

chatterino::rj::getSafe(value, "name", _name);
chatterino::rj::getSafe(value, "replace", _replace);

return chatterino::Nickname(_name, _replace);
}
};

} // namespace pajlada
31 changes: 31 additions & 0 deletions src/controllers/nicknames/NicknamesModel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include "NicknamesModel.hpp"

#include "Application.hpp"
#include "providers/twitch/api/Helix.hpp"
#include "singletons/Settings.hpp"
#include "util/StandardItemHelper.hpp"

namespace chatterino {

NicknamesModel::NicknamesModel(QObject *parent)
: SignalVectorModel<Nickname>(2, parent)
{
}

// turn a vector item into a model row
Nickname NicknamesModel::getItemFromRow(std::vector<QStandardItem *> &row,
const Nickname &original)
{
return Nickname{row[0]->data(Qt::DisplayRole).toString(),
row[1]->data(Qt::DisplayRole).toString()};
}

// turns a row in the model into a vector item
void NicknamesModel::getRowFromItem(const Nickname &item,
std::vector<QStandardItem *> &row)
{
setStringItem(row[0], item.name());
setStringItem(row[1], item.replace());
}

} // namespace chatterino
25 changes: 25 additions & 0 deletions src/controllers/nicknames/NicknamesModel.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include <QObject>

#include "common/SignalVectorModel.hpp"
#include "controllers/nicknames/Nickname.hpp"

namespace chatterino {

class NicknamesModel : public SignalVectorModel<Nickname>
{
public:
explicit NicknamesModel(QObject *parent);

protected:
// turn a vector item into a model row
virtual Nickname getItemFromRow(std::vector<QStandardItem *> &row,
const Nickname &original) override;

// turns a row in the model into a vector item
virtual void getRowFromItem(const Nickname &item,
std::vector<QStandardItem *> &row) override;
};

} // namespace chatterino
12 changes: 12 additions & 0 deletions src/providers/twitch/TwitchMessageBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,18 @@ void TwitchMessageBuilder::appendUsername()
break;
}

auto nicknames = getCSettings().nicknames.readOnly();
auto loginLower = this->message().loginName.toLower();

for (const auto &nickname : *nicknames)
{
if (nickname.name().toLower() == loginLower)
{
usernameText = nickname.replace();
break;
}
}

if (this->args.isSentWhisper)
{
// TODO(pajlada): Re-implement
Expand Down
2 changes: 2 additions & 0 deletions src/singletons/Settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ ConcurrentSettings::ConcurrentSettings()
, ignoredMessages(*new SignalVector<IgnorePhrase>())
, mutedChannels(*new SignalVector<QString>())
, filterRecords(*new SignalVector<FilterRecordPtr>())
, nicknames(*new SignalVector<Nickname>())
, moderationActions(*new SignalVector<ModerationAction>)
{
persist(this->highlightedMessages, "/highlighting/highlights");
Expand All @@ -32,6 +33,7 @@ ConcurrentSettings::ConcurrentSettings()
persist(this->ignoredMessages, "/ignore/phrases");
persist(this->mutedChannels, "/pings/muted");
persist(this->filterRecords, "/filtering/filters");
persist(this->nicknames, "/nicknames");
// tagged users?
persist(this->moderationActions, "/moderation/actions");
}
Expand Down
3 changes: 3 additions & 0 deletions src/singletons/Settings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "controllers/highlights/HighlightBadge.hpp"
#include "controllers/highlights/HighlightPhrase.hpp"
#include "controllers/moderationactions/ModerationAction.hpp"
#include "controllers/nicknames/Nickname.hpp"
#include "singletons/Toasts.hpp"
#include "util/StreamerMode.hpp"
#include "widgets/Notebook.hpp"
Expand All @@ -23,6 +24,7 @@ class HighlightBlacklistUser;
class IgnorePhrase;
class TaggedUser;
class FilterRecord;
class Nickname;

/// Settings which are availlable for reading on all threads.
class ConcurrentSettings
Expand All @@ -37,6 +39,7 @@ class ConcurrentSettings
SignalVector<IgnorePhrase> &ignoredMessages;
SignalVector<QString> &mutedChannels;
SignalVector<FilterRecordPtr> &filterRecords;
SignalVector<Nickname> &nicknames;
//SignalVector<TaggedUser> &taggedUsers;
SignalVector<ModerationAction> &moderationActions;

Expand Down
2 changes: 2 additions & 0 deletions src/widgets/dialogs/SettingsDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "widgets/settingspages/IgnoresPage.hpp"
#include "widgets/settingspages/KeyboardSettingsPage.hpp"
#include "widgets/settingspages/ModerationPage.hpp"
#include "widgets/settingspages/NicknamesPage.hpp"
#include "widgets/settingspages/NotificationPage.hpp"

#include <QDialogButtonBox>
Expand Down Expand Up @@ -164,6 +165,7 @@ void SettingsDialog::addTabs()
this->addTab([]{return new GeneralPage;}, "General", ":/settings/about.svg");
this->ui_.tabContainer->addSpacing(16);
this->addTab([]{return new AccountsPage;}, "Accounts", ":/settings/accounts.svg", SettingsTabId::Accounts);
this->addTab([]{return new NicknamesPage;}, "Nicknames", ":/settings/accounts.svg");
this->ui_.tabContainer->addSpacing(16);
this->addTab([]{return new CommandPage;}, "Commands", ":/settings/commands.svg");
this->addTab([]{return new HighlightingPage;}, "Highlights", ":/settings/notifications.svg");
Expand Down
48 changes: 48 additions & 0 deletions src/widgets/settingspages/NicknamesPage.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include "NicknamesPage.hpp"

#include "controllers/nicknames/NicknamesModel.hpp"
#include "singletons/Settings.hpp"
#include "singletons/WindowManager.hpp"
#include "util/LayoutCreator.hpp"
#include "widgets/Window.hpp"
#include "widgets/helper/EditableModelView.hpp"

#include <QTableView>

#include <QHeaderView>

namespace chatterino {

NicknamesPage::NicknamesPage()
{
LayoutCreator<NicknamesPage> layoutCreator(this);
auto layout = layoutCreator.setLayoutType<QVBoxLayout>();

layout.emplace<QLabel>(
"Nicknames do not work with features such as search or user highlights."
"\nWith those features you will still need to use the user's original "
"name.");
EditableModelView *view =
layout
.emplace<EditableModelView>(
(new NicknamesModel(nullptr))
->initialized(&getSettings()->nicknames))
.getElement();

view->setTitles({"Username", "Nickname"});
view->getTableView()->horizontalHeader()->setSectionResizeMode(
QHeaderView::Interactive);
view->getTableView()->horizontalHeader()->setSectionResizeMode(
1, QHeaderView::Stretch);

view->addButtonPressed.connect([] {
getSettings()->nicknames.append(Nickname{"Username", "Nickname"});
});

QTimer::singleShot(1, [view] {
view->getTableView()->resizeColumnsToContents();
view->getTableView()->setColumnWidth(0, 250);
});
}

} // namespace chatterino
18 changes: 18 additions & 0 deletions src/widgets/settingspages/NicknamesPage.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#pragma once

#include "widgets/helper/EditableModelView.hpp"
#include "widgets/settingspages/SettingsPage.hpp"

#include <QStringListModel>

class QVBoxLayout;

namespace chatterino {

class NicknamesPage : public SettingsPage
{
public:
NicknamesPage();
};

} // namespace chatterino