From 410de8226113c8f3a274d200f07602854d616f17 Mon Sep 17 00:00:00 2001 From: Mm2PL Date: Sat, 25 Jan 2020 12:59:31 +0100 Subject: [PATCH] Make a command that shows the Chatterino user card (/usercard) (#1375) * Make UserInfoPopup be able to show that fetching the information failed. --- .../commands/CommandController.cpp | 16 +++++++++++++++ src/providers/twitch/PartialTwitchUser.cpp | 13 +++++++++++- src/providers/twitch/PartialTwitchUser.hpp | 4 ++++ src/widgets/dialogs/UserInfoPopup.cpp | 20 ++++++++++++++++++- 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/controllers/commands/CommandController.cpp b/src/controllers/commands/CommandController.cpp index 0845f3288..a6150cfa9 100644 --- a/src/controllers/commands/CommandController.cpp +++ b/src/controllers/commands/CommandController.cpp @@ -17,6 +17,7 @@ #include "singletons/Theme.hpp" #include "util/CombinePath.hpp" #include "widgets/dialogs/LogsPopup.hpp" +#include "widgets/dialogs/UserInfoPopup.hpp" #include #include @@ -481,6 +482,21 @@ QString CommandController::execCommand(const QString &textNoEmoji, channelName + "/viewercard/" + words[1]); return ""; } + else if (commandName == "/usercard") + { + if (words.size() < 2) + { + channel->addMessage( + makeSystemMessage("Usage /usercard [user]")); + return ""; + } + auto *userPopup = new UserInfoPopup; + userPopup->setData(words[1], channel); + userPopup->setActionOnFocusLoss(BaseWindow::Delete); + userPopup->move(QCursor::pos()); + userPopup->show(); + return ""; + } } { diff --git a/src/providers/twitch/PartialTwitchUser.cpp b/src/providers/twitch/PartialTwitchUser.cpp index 631f41fc6..5407fbada 100644 --- a/src/providers/twitch/PartialTwitchUser.cpp +++ b/src/providers/twitch/PartialTwitchUser.cpp @@ -27,6 +27,13 @@ PartialTwitchUser PartialTwitchUser::byId(const QString &id) void PartialTwitchUser::getId(std::function successCallback, const QObject *caller) +{ + getId( + successCallback, [] {}, caller); +} +void PartialTwitchUser::getId(std::function successCallback, + std::function failureCallback, + const QObject *caller) { assert(!this->username_.isEmpty()); @@ -34,12 +41,13 @@ void PartialTwitchUser::getId(std::function successCallback, this->username_) .caller(caller) .authorizeTwitchV5(getDefaultClientID()) - .onSuccess([successCallback](auto result) -> Outcome { + .onSuccess([successCallback, failureCallback](auto result) -> Outcome { auto root = result.parseJson(); if (!root.value("users").isArray()) { qDebug() << "API Error while getting user id, users is not an array"; + failureCallback(); return Failure; } @@ -48,12 +56,14 @@ void PartialTwitchUser::getId(std::function successCallback, { qDebug() << "API Error while getting user id, users array size " "is not 1"; + failureCallback(); return Failure; } if (!users[0].isObject()) { qDebug() << "API Error while getting user id, first user is " "not an object"; + failureCallback(); return Failure; } auto firstUser = users[0].toObject(); @@ -62,6 +72,7 @@ void PartialTwitchUser::getId(std::function successCallback, { qDebug() << "API Error: while getting user id, first user " "object `_id` key is not a string"; + failureCallback(); return Failure; } successCallback(id.toString()); diff --git a/src/providers/twitch/PartialTwitchUser.hpp b/src/providers/twitch/PartialTwitchUser.hpp index 36876dc26..6537bb279 100644 --- a/src/providers/twitch/PartialTwitchUser.hpp +++ b/src/providers/twitch/PartialTwitchUser.hpp @@ -21,6 +21,10 @@ public: void getId(std::function successCallback, const QObject *caller = nullptr); + + void getId(std::function successCallback, + std::function failureCallback, + const QObject *caller = nullptr); }; } // namespace chatterino diff --git a/src/widgets/dialogs/UserInfoPopup.cpp b/src/widgets/dialogs/UserInfoPopup.cpp index b0fc0071a..e530a5bff 100644 --- a/src/widgets/dialogs/UserInfoPopup.cpp +++ b/src/widgets/dialogs/UserInfoPopup.cpp @@ -25,6 +25,7 @@ #define TEXT_VIEWS "Views: " #define TEXT_CREATED "Created: " #define TEXT_USER_ID "ID: " +#define TEXT_UNAVAILABLE "(not available)" namespace chatterino { namespace { @@ -382,6 +383,22 @@ void UserInfoPopup::updateUserData() { std::weak_ptr hack = this->hack_; + const auto onIdFetchFailed = [this]() { + // this can occur when the account doesn't exist. + this->ui_.followerCountLabel->setText(TEXT_FOLLOWERS + + QString(TEXT_UNAVAILABLE)); + this->ui_.viewCountLabel->setText(TEXT_VIEWS + + QString(TEXT_UNAVAILABLE)); + this->ui_.createdDateLabel->setText(TEXT_CREATED + + QString(TEXT_UNAVAILABLE)); + + this->ui_.nameLabel->setText(this->userName_); + + this->ui_.userIDLabel->setText(QString("ID") + + QString(TEXT_UNAVAILABLE)); + this->ui_.userIDLabel->setProperty("copy-text", + QString(TEXT_UNAVAILABLE)); + }; const auto onIdFetched = [this, hack](QString id) { auto currentUser = getApp()->accounts->twitch.getCurrent(); @@ -462,7 +479,8 @@ void UserInfoPopup::updateUserData() this->ui_.ignoreHighlights->setChecked(isIgnoringHighlights); }; - PartialTwitchUser::byName(this->userName_).getId(onIdFetched, this); + PartialTwitchUser::byName(this->userName_) + .getId(onIdFetched, onIdFetchFailed, this); this->ui_.follow->setEnabled(false); this->ui_.ignore->setEnabled(false);