feat: user notes (#6122)

Fixes #2413
This commit is contained in:
fourtf
2025-04-13 13:38:56 +02:00
committed by GitHub
parent 3ba25dd33d
commit 37061dd3bd
12 changed files with 312 additions and 73 deletions
+16 -1
View File
@@ -17,8 +17,12 @@ namespace chatterino {
// Replacement fields should be optional, where none denotes that the field should not be updated for the user
struct UserData {
std::optional<QColor> color{std::nullopt};
QString notes;
// TODO: User note?
bool isEmpty() const
{
return !color.has_value() && notes.isEmpty();
}
};
} // namespace chatterino
@@ -38,6 +42,11 @@ struct Serialize<chatterino::UserData> {
chatterino::rj::set(obj, "color",
color.name().toUtf8().toStdString(), a);
}
if (!value.notes.isEmpty())
{
chatterino::rj::set(obj, "notes",
value.notes.toUtf8().toStdString(), a);
}
return obj;
}
};
@@ -65,6 +74,12 @@ struct Deserialize<chatterino::UserData> {
}
}
QString notes;
if (chatterino::rj::getSafe(value, "notes", notes))
{
user.notes = notes;
}
return user;
}
};
@@ -39,6 +39,11 @@ UserDataController::UserDataController(const Paths &paths)
std::optional<UserData> UserDataController::getUser(const QString &userID) const
{
if (userID.isEmpty())
{
return std::nullopt;
}
std::shared_lock lock(this->usersMutex);
auto it = this->users.find(userID);
@@ -59,7 +64,14 @@ std::unordered_map<QString, UserData> UserDataController::getUsers() const
void UserDataController::setUserColor(const QString &userID,
const QString &colorString)
{
auto c = this->getUsers();
if (userID.isEmpty())
{
return;
}
std::unique_lock lock(this->usersMutex);
auto c = this->users;
auto it = c.find(userID);
std::optional<QColor> finalColor =
makeConditionedOptional(!colorString.isEmpty(), QColor(colorString));
@@ -80,15 +92,46 @@ void UserDataController::setUserColor(const QString &userID,
it->second.color = finalColor;
}
this->update(std::move(c));
this->update(std::move(c), std::move(lock));
}
void UserDataController::update(
std::unordered_map<QString, UserData> &&newUsers)
std::unordered_map<QString, UserData> &&newUsers,
std::unique_lock<std::shared_mutex> usersLock)
{
std::unique_lock lock(this->usersMutex);
// Remove empty user data items
std::erase_if(newUsers, [](const auto &pair) {
return pair.second.isEmpty();
});
this->users = std::move(newUsers);
this->setting.setValue(this->users);
// unlock before invoking updated signal
usersLock.unlock();
this->userDataUpdated_.invoke();
}
void UserDataController::setUserNotes(const QString &userID,
const QString &notes)
{
if (userID.isEmpty())
{
return;
}
std::unique_lock lock(this->usersMutex);
auto users = this->users;
users[userID].notes = notes;
this->update(std::move(users), std::move(lock));
}
pajlada::Signals::NoArgSignal &UserDataController::userDataUpdated()
{
return this->userDataUpdated_;
}
} // namespace chatterino
@@ -7,6 +7,7 @@
#include "util/serialize/Container.hpp"
#include <pajlada/settings.hpp>
#include <pajlada/signals/signal.hpp>
#include <QColor>
#include <QString>
@@ -27,6 +28,9 @@ public:
virtual void setUserColor(const QString &userID,
const QString &colorString) = 0;
virtual void setUserNotes(const QString &userID, const QString &notes) = 0;
virtual pajlada::Signals::NoArgSignal &userDataUpdated() = 0;
};
class UserDataController : public IUserDataController
@@ -42,8 +46,14 @@ public:
void setUserColor(const QString &userID,
const QString &colorString) override;
// Update or insert extra data for the notes about a user
void setUserNotes(const QString &userID, const QString &notes) override;
pajlada::Signals::NoArgSignal &userDataUpdated() override;
private:
void update(std::unordered_map<QString, UserData> &&newUsers);
void update(std::unordered_map<QString, UserData> &&newUsers,
std::unique_lock<std::shared_mutex> usersLock);
std::unordered_map<QString, UserData> getUsers() const;
@@ -53,6 +63,7 @@ private:
std::shared_ptr<pajlada::Settings::SettingManager> sm;
pajlada::Settings::Setting<std::unordered_map<QString, UserData>> setting;
pajlada::Signals::NoArgSignal userDataUpdated_;
};
} // namespace chatterino