diff --git a/src/accountmanager.cpp b/src/accountmanager.cpp index dc713f06..fbb5b7c4 100644 --- a/src/accountmanager.cpp +++ b/src/accountmanager.cpp @@ -59,20 +59,125 @@ bool TwitchAccountManager::userExists(const QString &username) const return this->findUserByUsername(username) != nullptr; } -bool TwitchAccountManager::addUser(std::shared_ptr user) +void TwitchAccountManager::reloadUsers() { - if (this->userExists(user->getNickName())) { - // User already exists in user list + auto keys = pajlada::Settings::SettingManager::getObjectKeys("/accounts"); + + UserData userData; + + bool listUpdated = false; + + for (const auto &uid : keys) { + if (uid == "current") { + continue; + } + + std::string username = + pajlada::Settings::Setting::get("/accounts/" + uid + "/username"); + std::string userID = + pajlada::Settings::Setting::get("/accounts/" + uid + "/userID"); + std::string clientID = + pajlada::Settings::Setting::get("/accounts/" + uid + "/clientID"); + std::string oauthToken = + pajlada::Settings::Setting::get("/accounts/" + uid + "/oauthToken"); + + if (username.empty() || userID.empty() || clientID.empty() || oauthToken.empty()) { + continue; + } + + userData.username = qS(username); + userData.userID = qS(userID); + userData.clientID = qS(clientID); + userData.oauthToken = qS(oauthToken); + + switch (this->addUser(userData)) { + case AddUserResponse::UserAlreadyExists: { + debug::Log("User {} already exists", userData.username); + // Do nothing + } break; + case AddUserResponse::UserValuesUpdated: { + debug::Log("User {} already exists, and values updated!", userData.username); + if (userData.username == this->getCurrent()->getNickName()) { + debug::Log("It was the current user, so we need to reconnect stuff!"); + this->userChanged.invoke(); + } + } break; + case AddUserResponse::UserAdded: { + debug::Log("Added user {}", userData.username); + listUpdated = true; + } break; + } + } + + if (listUpdated) { + this->userListUpdated.invoke(); + } +} + +bool TwitchAccountManager::removeUser(const QString &username) +{ + if (!this->userExists(username)) { return false; } - std::lock_guard lock(this->mutex); + this->mutex.lock(); + this->users.erase(std::remove_if(this->users.begin(), this->users.end(), [username](auto user) { + if (user->getNickName() == username) { + std::string userID(user->getUserId().toStdString()); + assert(!userID.empty()); + pajlada::Settings::SettingManager::removeSetting("/accounts/uid" + userID); + return true; + } + return false; + })); + this->mutex.unlock(); - this->users.push_back(user); + if (username == qS(this->currentUsername.getValue())) { + // The user that was removed is the current user, log into the anonymous user + this->currentUsername = ""; + } + + this->userListUpdated.invoke(); return true; } +TwitchAccountManager::AddUserResponse TwitchAccountManager::addUser( + const TwitchAccountManager::UserData &userData) +{ + auto previousUser = this->findUserByUsername(userData.username); + if (previousUser) { + bool userUpdated = false; + if (previousUser->getOAuthClient().compare(userData.clientID) != 0) { + previousUser->setOAuthClient(userData.clientID); + userUpdated = true; + } + + if (previousUser->getOAuthToken().compare(userData.oauthToken) != 0) { + previousUser->setOAuthToken(userData.oauthToken); + userUpdated = true; + } + + if (userUpdated) { + return AddUserResponse::UserValuesUpdated; + } else { + return AddUserResponse::UserAlreadyExists; + } + } + + auto newUser = std::make_shared(userData.username, userData.oauthToken, + userData.clientID); + + // Set users User ID without the uid prefix + newUser->setUserId(userData.userID.mid(3)); + + std::lock_guard lock(this->mutex); + + this->users.push_back(newUser); + + return AddUserResponse::UserAdded; +} + AccountManager::AccountManager() { this->Twitch.anonymousUser.reset(new twitch::TwitchUser("justinfan64537", "", "")); @@ -96,33 +201,7 @@ AccountManager::AccountManager() void AccountManager::load() { - auto keys = pajlada::Settings::SettingManager::getObjectKeys("/accounts"); - - for (const auto &uid : keys) { - if (uid == "current") { - continue; - } - - std::string username = - pajlada::Settings::Setting::get("/accounts/" + uid + "/username"); - std::string userID = - pajlada::Settings::Setting::get("/accounts/" + uid + "/userID"); - std::string clientID = - pajlada::Settings::Setting::get("/accounts/" + uid + "/clientID"); - std::string oauthToken = - pajlada::Settings::Setting::get("/accounts/" + uid + "/oauthToken"); - - if (username.empty() || userID.empty() || clientID.empty() || oauthToken.empty()) { - continue; - } - - auto user = - std::make_shared(qS(username), qS(oauthToken), qS(clientID)); - - this->Twitch.addUser(user); - - printf("Adding user %s(%s)\n", username.c_str(), userID.c_str()); - } + this->Twitch.reloadUsers(); auto currentUser = this->Twitch.findUserByUsername( QString::fromStdString(this->Twitch.currentUsername.getValue())); diff --git a/src/accountmanager.hpp b/src/accountmanager.hpp index f496c7ff..0e98d134 100644 --- a/src/accountmanager.hpp +++ b/src/accountmanager.hpp @@ -14,6 +14,13 @@ class AccountManager; class TwitchAccountManager { public: + struct UserData { + QString username; + QString userID; + QString clientID; + QString oauthToken; + }; + // Returns the current twitchUsers, or the anonymous user if we're not currently logged in std::shared_ptr getCurrent(); @@ -22,11 +29,21 @@ public: std::shared_ptr findUserByUsername(const QString &username) const; bool userExists(const QString &username) const; + void reloadUsers(); + + bool removeUser(const QString &username); + pajlada::Settings::Setting currentUsername = {"/accounts/current", ""}; pajlada::Signals::NoArgSignal userChanged; + pajlada::Signals::NoArgSignal userListUpdated; private: - bool addUser(std::shared_ptr user); + enum class AddUserResponse { + UserAlreadyExists, + UserValuesUpdated, + UserAdded, + }; + AddUserResponse addUser(const UserData &data); std::shared_ptr currentUser; diff --git a/src/widgets/accountswitchwidget.cpp b/src/widgets/accountswitchwidget.cpp index 6404d09a..d34793e8 100644 --- a/src/widgets/accountswitchwidget.cpp +++ b/src/widgets/accountswitchwidget.cpp @@ -15,6 +15,22 @@ AccountSwitchWidget::AccountSwitchWidget(QWidget *parent) this->addItem(userName); } + AccountManager::getInstance().Twitch.userListUpdated.connect([this]() { + this->blockSignals(true); + + this->clear(); + + this->addItem(anonUsername); + + for (const auto &userName : AccountManager::getInstance().Twitch.getUsernames()) { + this->addItem(userName); + } + + this->refreshSelection(); + + this->blockSignals(false); + }); + this->refreshSelection(); QObject::connect(this, &QListWidget::clicked, [this] { diff --git a/src/widgets/logindialog.cpp b/src/widgets/logindialog.cpp index c39b80cc..c28fb9f8 100644 --- a/src/widgets/logindialog.cpp +++ b/src/widgets/logindialog.cpp @@ -1,9 +1,11 @@ #include "widgets/logindialog.hpp" +#include "common.hpp" #include "util/urlfetch.hpp" #include #include #include +#include #include #include @@ -56,8 +58,16 @@ BasicLoginWidget::BasicLoginWidget() } if (oauthToken.empty() || clientID.empty() || username.empty() || userID.empty()) { - qDebug() << "Missing variables!!!!!!!!!"; + QMessageBox messageBox; + messageBox.setText("Bad values"); + messageBox.setInformativeText("Missing values from the clipboard.
Ensure you " + "copied all text and try again."); + messageBox.setStandardButtons(QMessageBox::Ok); + messageBox.exec(); } else { + QMessageBox messageBox; + messageBox.setText("Success!"); + messageBox.setInformativeText("Successfully added user " + qS(username) + "!"); qDebug() << "Success! mr"; pajlada::Settings::Setting::set("/accounts/uid" + userID + "/username", username); @@ -67,6 +77,10 @@ BasicLoginWidget::BasicLoginWidget() clientID); pajlada::Settings::Setting::set("/accounts/uid" + userID + "/oauthToken", oauthToken); + + AccountManager::getInstance().Twitch.reloadUsers(); + + messageBox.exec(); } }); } diff --git a/src/widgets/settingsdialog.cpp b/src/widgets/settingsdialog.cpp index 727afb8d..289d9527 100644 --- a/src/widgets/settingsdialog.cpp +++ b/src/widgets/settingsdialog.cpp @@ -120,10 +120,6 @@ QVBoxLayout *SettingsDialog::createAccountsTab() loginWidget->show(); }); - connect(removeButton, &QPushButton::clicked, []() { - qDebug() << "TODO: Implement"; // - }); - buttonBox->addButton(addButton, QDialogButtonBox::YesRole); buttonBox->addButton(removeButton, QDialogButtonBox::NoRole); @@ -131,6 +127,16 @@ QVBoxLayout *SettingsDialog::createAccountsTab() this->ui.accountSwitchWidget = new AccountSwitchWidget(this); + connect(removeButton, &QPushButton::clicked, [this]() { + qDebug() << "TODO: Implement"; // + auto selectedUser = this->ui.accountSwitchWidget->currentItem()->text(); + if (selectedUser == " - anonymous - ") { + // Do nothing + return; + } + AccountManager::getInstance().Twitch.removeUser(selectedUser); + }); + layout->addWidget(this->ui.accountSwitchWidget); return layout;