From 04c355f7e9552db8a0426b7c3e2267b53a548348 Mon Sep 17 00:00:00 2001 From: James Upjohn Date: Sat, 9 Apr 2022 23:27:21 +1200 Subject: [PATCH] feat: use message's original channel name when usercard popout is opened (#3623) Co-authored-by: Rasmus Karlsson --- CHANGELOG.md | 1 + src/widgets/dialogs/UserInfoPopup.cpp | 101 ++++++++++++++++---------- src/widgets/dialogs/UserInfoPopup.hpp | 5 ++ src/widgets/helper/ChannelView.cpp | 17 +++-- src/widgets/helper/ChannelView.hpp | 10 ++- 5 files changed, 87 insertions(+), 47 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca61bd2d6..35795a7c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Minor: Added quotation marks in the permitted/blocked Automod messages for clarity. (#3654) - Minor: Adjust large stream thumbnail to 16:9 (#3655) +- Minor: Fixed being unable to load Twitch Usercards from the `/mentions` tab. (#3623) - Bugfix: Fixed live notifications for usernames containing uppercase characters. (#3646) ## 2.3.5 diff --git a/src/widgets/dialogs/UserInfoPopup.cpp b/src/widgets/dialogs/UserInfoPopup.cpp index 730617b09..a70494b98 100644 --- a/src/widgets/dialogs/UserInfoPopup.cpp +++ b/src/widgets/dialogs/UserInfoPopup.cpp @@ -226,7 +226,7 @@ UserInfoPopup::UserInfoPopup(bool closeAutomatically, QWidget *parent) .arg(this->userName_) .arg(calculateTimeoutDuration(button)); } - this->channel_->sendMessage(msg); + this->underlyingChannel_->sendMessage(msg); return ""; }}, @@ -385,28 +385,28 @@ UserInfoPopup::UserInfoPopup(bool closeAutomatically, QWidget *parent) QObject::connect(usercard.getElement(), &Button::leftClicked, [this] { QDesktopServices::openUrl("https://www.twitch.tv/popout/" + - this->channel_->getName() + + this->underlyingChannel_->getName() + "/viewercard/" + this->userName_); }); QObject::connect(mod.getElement(), &Button::leftClicked, [this] { - this->channel_->sendMessage("/mod " + this->userName_); + this->underlyingChannel_->sendMessage("/mod " + this->userName_); }); QObject::connect(unmod.getElement(), &Button::leftClicked, [this] { - this->channel_->sendMessage("/unmod " + this->userName_); + this->underlyingChannel_->sendMessage("/unmod " + this->userName_); }); QObject::connect(vip.getElement(), &Button::leftClicked, [this] { - this->channel_->sendMessage("/vip " + this->userName_); + this->underlyingChannel_->sendMessage("/vip " + this->userName_); }); QObject::connect(unvip.getElement(), &Button::leftClicked, [this] { - this->channel_->sendMessage("/unvip " + this->userName_); + this->underlyingChannel_->sendMessage("/unvip " + this->userName_); }); // userstate this->userStateChanged_.connect([this, mod, unmod, vip, unvip]() mutable { TwitchChannel *twitchChannel = - dynamic_cast(this->channel_.get()); + dynamic_cast(this->underlyingChannel_.get()); bool visibilityModButtons = false; @@ -436,7 +436,7 @@ UserInfoPopup::UserInfoPopup(bool closeAutomatically, QWidget *parent) this->userStateChanged_.connect([this, lineMod, timeout]() mutable { TwitchChannel *twitchChannel = - dynamic_cast(this->channel_.get()); + dynamic_cast(this->underlyingChannel_.get()); bool hasModRights = twitchChannel ? twitchChannel->hasModRights() : false; @@ -452,26 +452,27 @@ UserInfoPopup::UserInfoPopup(bool closeAutomatically, QWidget *parent) switch (action) { case TimeoutWidget::Ban: { - if (this->channel_) + if (this->underlyingChannel_) { - this->channel_->sendMessage("/ban " + this->userName_); + this->underlyingChannel_->sendMessage("/ban " + + this->userName_); } } break; case TimeoutWidget::Unban: { - if (this->channel_) + if (this->underlyingChannel_) { - this->channel_->sendMessage("/unban " + - this->userName_); + this->underlyingChannel_->sendMessage("/unban " + + this->userName_); } } break; case TimeoutWidget::Timeout: { - if (this->channel_) + if (this->underlyingChannel_) { - this->channel_->sendMessage("/timeout " + - this->userName_ + " " + - QString::number(arg)); + this->underlyingChannel_->sendMessage( + "/timeout " + this->userName_ + " " + + QString::number(arg)); } } break; @@ -680,10 +681,28 @@ void UserInfoPopup::installEvents() } void UserInfoPopup::setData(const QString &name, const ChannelPtr &channel) +{ + this->setData(name, channel, channel); +} + +void UserInfoPopup::setData(const QString &name, + const ChannelPtr &contextChannel, + const ChannelPtr &openingChannel) { this->userName_ = name; - this->channel_ = channel; - this->setWindowTitle(TEXT_TITLE.arg(name, channel->getName())); + this->channel_ = openingChannel; + + if (!contextChannel->isEmpty()) + { + this->underlyingChannel_ = contextChannel; + } + else + { + this->underlyingChannel_ = openingChannel; + } + + this->setWindowTitle( + TEXT_TITLE.arg(name, this->underlyingChannel_->getName())); this->ui_.nameLabel->setText(name); this->ui_.nameLabel->setProperty("copy-text", name); @@ -700,9 +719,10 @@ void UserInfoPopup::setData(const QString &name, const ChannelPtr &channel) void UserInfoPopup::updateLatestMessages() { - auto filteredChannel = filterMessages(this->userName_, this->channel_); + auto filteredChannel = + filterMessages(this->userName_, this->underlyingChannel_); this->ui_.latestMessages->setChannel(filteredChannel); - this->ui_.latestMessages->setSourceChannel(this->channel_); + this->ui_.latestMessages->setSourceChannel(this->underlyingChannel_); const bool hasMessages = filteredChannel->hasMessages(); this->ui_.latestMessages->setVisible(hasMessages); @@ -713,23 +733,24 @@ void UserInfoPopup::updateLatestMessages() this->refreshConnection_ = std::make_unique( - this->channel_->messageAppended.connect([this, hasMessages]( - auto message, auto) { - if (!checkMessageUserName(this->userName_, message)) - return; + this->underlyingChannel_->messageAppended.connect( + [this, hasMessages](auto message, auto) { + if (!checkMessageUserName(this->userName_, message)) + return; - if (hasMessages) - { - // display message in ChannelView - this->ui_.latestMessages->channel()->addMessage(message); - } - else - { - // The ChannelView is currently hidden, so manually refresh - // and display the latest messages - this->updateLatestMessages(); - } - })); + if (hasMessages) + { + // display message in ChannelView + this->ui_.latestMessages->channel()->addMessage( + message); + } + else + { + // The ChannelView is currently hidden, so manually refresh + // and display the latest messages + this->updateLatestMessages(); + } + })); } void UserInfoPopup::updateUserData() @@ -781,8 +802,8 @@ void UserInfoPopup::updateUserData() this->ui_.nameLabel->setProperty("copy-text", user.displayName); } - this->setWindowTitle( - TEXT_TITLE.arg(user.displayName, this->channel_->getName())); + this->setWindowTitle(TEXT_TITLE.arg( + user.displayName, this->underlyingChannel_->getName())); this->ui_.viewCountLabel->setText( TEXT_VIEWS.arg(localizeNumbers(user.viewCount))); this->ui_.createdDateLabel->setText( @@ -849,7 +870,7 @@ void UserInfoPopup::updateUserData() // get followage and subage getIvr()->getSubage( - this->userName_, this->channel_->getName(), + this->userName_, this->underlyingChannel_->getName(), [this, hack](const IvrSubage &subageInfo) { if (!hack.lock()) { diff --git a/src/widgets/dialogs/UserInfoPopup.hpp b/src/widgets/dialogs/UserInfoPopup.hpp index 6aff6e19d..db710ae8c 100644 --- a/src/widgets/dialogs/UserInfoPopup.hpp +++ b/src/widgets/dialogs/UserInfoPopup.hpp @@ -24,6 +24,8 @@ public: UserInfoPopup(bool closeAutomatically, QWidget *parent); void setData(const QString &name, const ChannelPtr &channel); + void setData(const QString &name, const ChannelPtr &contextChannel, + const ChannelPtr &openingChannel); protected: virtual void themeChangedEvent() override; @@ -44,7 +46,10 @@ private: QString userName_; QString userId_; QString avatarUrl_; + // The channel the popup was opened from (e.g. /mentions or #forsen). Can be a special channel. ChannelPtr channel_; + // The channel the messages are rendered from (e.g. #forsen). Can be a special channel, but will try to not be where possible. + ChannelPtr underlyingChannel_; // isMoving_ is set to true if the user is holding the left mouse button down and has moved the mouse a small amount away from the original click point (startPosDrag_) bool isMoving_ = false; diff --git a/src/widgets/helper/ChannelView.cpp b/src/widgets/helper/ChannelView.cpp index c8c4e742b..769f1e298 100644 --- a/src/widgets/helper/ChannelView.cpp +++ b/src/widgets/helper/ChannelView.cpp @@ -2153,15 +2153,20 @@ void ChannelView::hideEvent(QHideEvent *) this->messagesOnScreen_.clear(); } -void ChannelView::showUserInfoPopup(const QString &userName) +void ChannelView::showUserInfoPopup(const QString &userName, + QString alternativePopoutChannel) { - QWidget *userCardParent = + auto *userCardParent = static_cast(&(getApp()->windows->getMainWindow())); auto *userPopup = new UserInfoPopup(getSettings()->autoCloseUserPopup, userCardParent); - userPopup->setData(userName, this->hasSourceChannel() - ? this->sourceChannel_ - : this->underlyingChannel_); + + auto contextChannel = + getApp()->twitch->getChannelOrEmpty(alternativePopoutChannel); + auto openingChannel = this->hasSourceChannel() ? this->sourceChannel_ + : this->underlyingChannel_; + userPopup->setData(userName, contextChannel, openingChannel); + QPoint offset(int(150 * this->scale()), int(70 * this->scale())); userPopup->move(QCursor::pos() - offset); userPopup->show(); @@ -2181,7 +2186,7 @@ void ChannelView::handleLinkClick(QMouseEvent *event, const Link &link, case Link::UserWhisper: case Link::UserInfo: { auto user = link.value; - this->showUserInfoPopup(user); + this->showUserInfoPopup(user, layout->getMessage()->channelName); } break; diff --git a/src/widgets/helper/ChannelView.hpp b/src/widgets/helper/ChannelView.hpp index 009b35b74..05f2becb0 100644 --- a/src/widgets/helper/ChannelView.hpp +++ b/src/widgets/helper/ChannelView.hpp @@ -96,7 +96,15 @@ public: void queueLayout(); void clearMessages(); - void showUserInfoPopup(const QString &userName); + + /** + * @brief Creates and shows a UserInfoPopup dialog + * + * @param userName The login name of the user + * @param alternativePopoutChannel Optional parameter containing the channel name to use for context + **/ + void showUserInfoPopup(const QString &userName, + QString alternativePopoutChannel = QString()); pajlada::Signals::Signal mouseDown; pajlada::Signals::NoArgSignal selectionChanged;