Add option to subscribe to and pin reply threads (#4680)

Co-authored-by: Rasmus Karlsson <rasmus.karlsson@pajlada.com>
This commit is contained in:
nerix
2023-06-17 17:41:52 +02:00
committed by GitHub
parent 2d3d3ae46e
commit aff9342647
15 changed files with 194 additions and 69 deletions
+69 -5
View File
@@ -7,16 +7,18 @@
#include "controllers/hotkeys/HotkeyController.hpp"
#include "messages/Message.hpp"
#include "messages/MessageThread.hpp"
#include "providers/twitch/ChannelPointReward.hpp"
#include "providers/twitch/TwitchAccount.hpp"
#include "providers/twitch/TwitchChannel.hpp"
#include "singletons/Settings.hpp"
#include "util/LayoutCreator.hpp"
#include "widgets/helper/Button.hpp"
#include "widgets/helper/ChannelView.hpp"
#include "widgets/helper/ResizingTextEdit.hpp"
#include "widgets/Scrollbar.hpp"
#include "widgets/splits/Split.hpp"
#include "widgets/splits/SplitInput.hpp"
#include <QCheckBox>
const QString TEXT_TITLE("Reply Thread - @%1 in #%2");
namespace chatterino {
@@ -72,9 +74,6 @@ ReplyThreadPopup::ReplyThreadPopup(bool closeAutomatically, QWidget *parent,
this->shortcuts_ = getApp()->hotkeys->shortcutsForCategory(
HotkeyCategory::PopupWindow, actions, this);
auto layout = LayoutCreator<QWidget>(this->getLayoutContainer())
.setLayoutType<QVBoxLayout>();
// initialize UI
this->ui_.threadView =
new ChannelView(this, this->split_, ChannelView::Context::ReplyThread);
@@ -110,10 +109,57 @@ ReplyThreadPopup::ReplyThreadPopup(bool closeAutomatically, QWidget *parent,
}
});
auto layout = LayoutCreator<QWidget>(this->getLayoutContainer())
.setLayoutType<QVBoxLayout>();
layout->setSpacing(0);
// provide draggable margin if frameless
auto marginPx = closeAutomatically ? 15 : 1;
layout->setContentsMargins(marginPx, marginPx, marginPx, marginPx);
// Top Row
bool addCheckbox = getSettings()->enableThreadHighlight;
if (addCheckbox || closeAutomatically)
{
auto *hbox = new QHBoxLayout();
if (addCheckbox)
{
this->ui_.notificationCheckbox =
new QCheckBox("Subscribe to thread", this);
QObject::connect(this->ui_.notificationCheckbox,
&QCheckBox::toggled, [this](bool checked) {
if (!this->thread_ ||
this->thread_->subscribed() == checked)
{
return;
}
if (checked)
{
this->thread_->markSubscribed();
}
else
{
this->thread_->markUnsubscribed();
}
});
hbox->addWidget(this->ui_.notificationCheckbox, 1);
}
if (closeAutomatically)
{
hbox->addWidget(this->createPinButton(), 0, Qt::AlignRight);
hbox->setContentsMargins(0, 0, 0, 5);
}
else
{
hbox->setContentsMargins(10, 0, 0, 4);
}
layout->addLayout(hbox, 1);
}
layout->addWidget(this->ui_.threadView, 1);
layout->addWidget(this->ui_.replyInput);
}
@@ -124,6 +170,24 @@ void ReplyThreadPopup::setThread(std::shared_ptr<MessageThread> thread)
this->ui_.replyInput->setReply(this->thread_);
this->addMessagesFromThread();
this->updateInputUI();
if (!this->thread_) [[unlikely]]
{
this->replySubscriptionSignal_ = boost::signals2::scoped_connection{};
return;
}
auto updateCheckbox = [this]() {
if (this->ui_.notificationCheckbox)
{
this->ui_.notificationCheckbox->setChecked(
this->thread_->subscribed());
}
};
updateCheckbox();
this->replySubscriptionSignal_ =
this->thread_->subscriptionUpdated.connect(updateCheckbox);
}
void ReplyThreadPopup::addMessagesFromThread()
+5
View File
@@ -7,6 +7,8 @@
#include <pajlada/signals/scoped-connection.hpp>
#include <pajlada/signals/signal.hpp>
class QCheckBox;
namespace chatterino {
class MessageThread;
@@ -41,10 +43,13 @@ private:
struct {
ChannelView *threadView = nullptr;
SplitInput *replyInput = nullptr;
QCheckBox *notificationCheckbox = nullptr;
} ui_;
std::unique_ptr<pajlada::Signals::ScopedConnection> messageConnection_;
std::vector<boost::signals2::scoped_connection> bSignals_;
boost::signals2::scoped_connection replySubscriptionSignal_;
};
} // namespace chatterino
+1 -32
View File
@@ -142,7 +142,6 @@ UserInfoPopup::UserInfoPopup(bool closeAutomatically, QWidget *parent,
"split being nullptr causes lots of bugs down the road");
this->setWindowTitle("Usercard");
this->setStayInScreenRect(true);
this->updateFocusLoss();
HotkeyController::HotkeyMap actions{
{"delete",
@@ -361,17 +360,7 @@ UserInfoPopup::UserInfoPopup(bool closeAutomatically, QWidget *parent,
// button to pin the window (only if we close automatically)
if (this->closeAutomatically_)
{
this->ui_.pinButton = box.emplace<Button>().getElement();
this->ui_.pinButton->setPixmap(
getApp()->themes->buttons.pin);
this->ui_.pinButton->setScaleIndependantSize(18, 18);
this->ui_.pinButton->setToolTip("Pin Window");
QObject::connect(this->ui_.pinButton, &Button::leftClicked,
[this]() {
this->closeAutomatically_ =
!this->closeAutomatically_;
this->updateFocusLoss();
});
box->addWidget(this->createPinButton());
}
}
@@ -920,26 +909,6 @@ void UserInfoPopup::updateUserData()
this->ui_.ignoreHighlights->setEnabled(false);
}
void UserInfoPopup::updateFocusLoss()
{
if (this->closeAutomatically_)
{
this->setActionOnFocusLoss(BaseWindow::Delete);
if (this->ui_.pinButton != nullptr)
{
this->ui_.pinButton->setPixmap(getApp()->themes->buttons.pin);
}
}
else
{
this->setActionOnFocusLoss(BaseWindow::Nothing);
if (this->ui_.pinButton != nullptr)
{
this->ui_.pinButton->setPixmap(getResources().buttons.pinEnabled);
}
}
}
void UserInfoPopup::loadAvatar(const QUrl &url)
{
QNetworkRequest req(url);
-3
View File
@@ -37,7 +37,6 @@ private:
void installEvents();
void updateUserData();
void updateLatestMessages();
void updateFocusLoss();
void loadAvatar(const QUrl &url);
bool isMod_;
@@ -73,8 +72,6 @@ private:
Label *followerCountLabel = nullptr;
Label *createdDateLabel = nullptr;
Label *userIDLabel = nullptr;
// Can be uninitialized if usercard is not configured to close on focus loss
Button *pinButton = nullptr;
Label *followageLabel = nullptr;
Label *subageLabel = nullptr;