Merge pull request #1316 from Chatterino/moderation

Pausing while key is pressed + no more moving highlights
This commit is contained in:
fourtf 2019-09-18 16:15:01 +02:00 committed by GitHub
commit ffd63d9407
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 171 additions and 28 deletions

View file

@ -51,4 +51,38 @@ using IntSetting = ChatterinoSetting<int>;
using StringSetting = ChatterinoSetting<std::string>;
using QStringSetting = ChatterinoSetting<QString>;
template <typename Enum>
class EnumSetting
: public ChatterinoSetting<typename std::underlying_type<Enum>::type>
{
using Underlying = typename std::underlying_type<Enum>::type;
public:
using ChatterinoSetting<Underlying>::ChatterinoSetting;
EnumSetting(const std::string &path, const Enum &defaultValue)
: ChatterinoSetting<Underlying>(path, Underlying(defaultValue))
{
_registerSetting(this->getData());
}
template <typename T2>
EnumSetting<Enum> &operator=(Enum newValue)
{
this->setValue(Underlying(newValue));
return *this;
}
operator Enum()
{
return Enum(this->getValue());
}
Enum getEnum()
{
return Enum(this->getValue());
}
};
} // namespace AB_NAMESPACE

View file

@ -102,7 +102,9 @@ public:
BoolSetting prefixOnlyEmoteCompletion = {
"/behaviour/autocompletion/prefixOnlyCompletion", true};
BoolSetting pauseChatOnHover = {"/behaviour/pauseChatHover", false};
FloatSetting pauseOnHoverDuration = {"/behaviour/pauseOnHoverDuration", 0};
EnumSetting<Qt::KeyboardModifier> pauseChatModifier = {
"/behaviour/pauseChatModifier", Qt::KeyboardModifier::NoModifier};
BoolSetting autorun = {"/behaviour/autorun", false};
BoolSetting mentionUsersWithComma = {"/behaviour/mentionUsersWithComma",
true};

View file

@ -241,6 +241,14 @@ void ChannelView::unpause(PauseReason reason)
this->pauses_.erase(reason);
this->updatePauseTimer();
/// Move selection
this->selection_.selectionMin.messageIndex -= this->pauseSelectionOffset_;
this->selection_.selectionMax.messageIndex -= this->pauseSelectionOffset_;
this->selection_.start.messageIndex -= this->pauseSelectionOffset_;
this->selection_.end.messageIndex -= this->pauseSelectionOffset_;
this->pauseSelectionOffset_ = 0;
}
void ChannelView::updatePauseTimer()
@ -527,64 +535,64 @@ ChannelPtr ChannelView::channel()
return this->channel_;
}
void ChannelView::setChannel(ChannelPtr newChannel)
void ChannelView::setChannel(ChannelPtr channel)
{
/// Clear connections from the last channel
this->channelConnections_.clear();
this->clearMessages();
this->scrollBar_->clearHighlights();
// on new message
this->channelConnections_.push_back(newChannel->messageAppended.connect(
this->channelConnections_.push_back(channel->messageAppended.connect(
[this](MessagePtr &message,
boost::optional<MessageFlags> overridingFlags) {
this->messageAppended(message, overridingFlags);
}));
this->channelConnections_.push_back(
newChannel->messagesAddedAtStart.connect(
[this](std::vector<MessagePtr> &messages) {
this->messageAddedAtStart(messages);
}));
this->channelConnections_.push_back(channel->messagesAddedAtStart.connect(
[this](std::vector<MessagePtr> &messages) {
this->messageAddedAtStart(messages);
}));
// on message removed
this->channelConnections_.push_back(
newChannel->messageRemovedFromStart.connect(
[this](MessagePtr &message) {
this->messageRemoveFromStart(message);
}));
channel->messageRemovedFromStart.connect([this](MessagePtr &message) {
this->messageRemoveFromStart(message);
}));
// on message replaced
this->channelConnections_.push_back(newChannel->messageReplaced.connect(
this->channelConnections_.push_back(channel->messageReplaced.connect(
[this](size_t index, MessagePtr replacement) {
this->messageReplaced(index, replacement);
}));
auto snapshot = newChannel->getMessageSnapshot();
auto snapshot = channel->getMessageSnapshot();
for (size_t i = 0; i < snapshot.size(); i++)
{
MessageLayoutPtr deleted;
auto messageRef = new MessageLayout(snapshot[i]);
auto messageLayout = new MessageLayout(snapshot[i]);
if (this->lastMessageHasAlternateBackground_)
{
messageRef->flags.set(MessageLayoutFlag::AlternateBackground);
messageLayout->flags.set(MessageLayoutFlag::AlternateBackground);
}
this->lastMessageHasAlternateBackground_ =
!this->lastMessageHasAlternateBackground_;
this->messages_.pushBack(MessageLayoutPtr(messageRef), deleted);
this->messages_.pushBack(MessageLayoutPtr(messageLayout), deleted);
this->scrollBar_->addHighlight(snapshot[i]->getScrollBarHighlight());
}
this->channel_ = newChannel;
this->channel_ = channel;
this->queueLayout();
this->queueUpdate();
// Notifications
if (auto tc = dynamic_cast<TwitchChannel *>(newChannel.get()))
if (auto tc = dynamic_cast<TwitchChannel *>(channel.get()))
{
this->connections_.push_back(tc->liveStatusChanged.connect([this]() {
this->liveStatusChanged.invoke(); //
@ -697,10 +705,17 @@ void ChannelView::messageAddedAtStart(std::vector<MessagePtr> &messages)
void ChannelView::messageRemoveFromStart(MessagePtr &message)
{
this->selection_.selectionMin.messageIndex--;
this->selection_.selectionMax.messageIndex--;
this->selection_.start.messageIndex--;
this->selection_.end.messageIndex--;
if (this->paused())
{
this->pauseSelectionOffset_ += 1;
}
else
{
this->selection_.selectionMin.messageIndex--;
this->selection_.selectionMax.messageIndex--;
this->selection_.start.messageIndex--;
this->selection_.end.messageIndex--;
}
this->queueLayout();
}
@ -1023,9 +1038,14 @@ void ChannelView::mouseMoveEvent(QMouseEvent *event)
}
/// Pause on hover
if (getSettings()->pauseChatOnHover.getValue())
if (float pauseTime = getSettings()->pauseOnHoverDuration;
pauseTime > 0.001f)
{
this->pause(PauseReason::Mouse, 500);
this->pause(PauseReason::Mouse, uint(pauseTime * 1000.f));
}
else if (pauseTime < -0.5f)
{
this->pause(PauseReason::Mouse);
}
auto tooltipWidget = TooltipWidget::getInstance();

View file

@ -44,6 +44,7 @@ enum class PauseReason {
Mouse,
Selection,
DoubleClick,
KeyboardModifier,
};
using SteadyClock = std::chrono::steady_clock;
@ -162,6 +163,7 @@ private:
pauses_;
boost::optional<SteadyClock::time_point> pauseEnd_;
int pauseScrollOffset_ = 0;
int pauseSelectionOffset_ = 0;
boost::optional<MessageElementFlags> overrideFlags_;
MessageLayoutPtr lastReadMessage_;

View file

@ -21,9 +21,56 @@
#define FIREFOX_EXTENSION_LINK \
"https://addons.mozilla.org/en-US/firefox/addon/chatterino-native-host/"
// define to highlight sections in editor
#define addTitle addTitle
#ifdef Q_OS_WIN
# define META_KEY "Windows"
#else
# define META_KEY "Meta"
#endif
namespace chatterino {
namespace {
void addKeyboardModifierSetting(SettingsLayout &layout,
const QString &title,
EnumSetting<Qt::KeyboardModifier> &setting)
{
layout.addDropdown<std::underlying_type<Qt::KeyboardModifier>::type>(
title, {"None", "Shift", "Control", "Alt", META_KEY}, setting,
[](int index) {
switch (index)
{
case Qt::ShiftModifier:
return 1;
case Qt::ControlModifier:
return 2;
case Qt::AltModifier:
return 3;
case Qt::MetaModifier:
return 4;
default:
return 0;
}
},
[](DropdownArgs args) {
switch (args.index)
{
case 1:
return Qt::ShiftModifier;
case 2:
return Qt::ControlModifier;
case 3:
return Qt::AltModifier;
case 4:
return Qt::MetaModifier;
default:
return Qt::NoModifier;
}
},
false);
}
} // namespace
TitleLabel *SettingsLayout::addTitle(const QString &title)
{
@ -272,7 +319,28 @@ void GeneralPage::initLayout(SettingsLayout &layout)
layout.addCheckbox("Smooth scrolling", s.enableSmoothScrolling);
layout.addCheckbox("Smooth scrolling on new messages",
s.enableSmoothScrollingNewMessages);
layout.addCheckbox("Pause on hover", s.pauseChatOnHover);
layout.addDropdown<float>(
"Pause on hover", {"Disabled", "0.5s", "1s", "2s", "5s", "Indefinite"},
s.pauseOnHoverDuration,
[](auto val) {
if (val < -0.5f)
return QString("Indefinite");
else if (val < 0.001f)
return QString("Disabled");
else
return QString::number(val) + "s";
},
[](auto args) {
if (args.index == 0)
return 0.0f;
else if (args.value == "Indefinite")
return -1.0f;
else
return fuzzyToFloat(args.value,
std::numeric_limits<float>::infinity());
});
addKeyboardModifierSetting(layout, "Pause while holding a key",
s.pauseChatModifier);
layout.addCheckbox("Show input when it's empty", s.showEmptyInput);
layout.addCheckbox("Show message length while typing", s.showMessageLength);
if (!BaseWindow::supportsCustomWindowFrame())
@ -401,8 +469,7 @@ void GeneralPage::initLayout(SettingsLayout &layout)
s.mentionUsersWithComma);
layout.addCheckbox("Show joined users (< 1000 chatters)", s.showJoins);
layout.addCheckbox("Show parted users (< 1000 chatters)", s.showParts);
layout.addCheckbox("Lowercase domains (anti-phisching)",
s.lowercaseDomains);
layout.addCheckbox("Lowercase domains (anti-phishing)", s.lowercaseDomains);
layout.addCheckbox("Bold @usernames", s.boldUsernames);
layout.addDropdown<float>(
"Username font weight", {"50", "Default", "75", "100"}, s.boldScale,

View file

@ -14,6 +14,7 @@
#include "util/Shortcut.hpp"
#include "util/StreamLink.hpp"
#include "widgets/Notebook.hpp"
#include "widgets/TooltipWidget.hpp"
#include "widgets/Window.hpp"
#include "widgets/dialogs/QualityPopup.hpp"
#include "widgets/dialogs/SelectChannelDialog.hpp"
@ -188,6 +189,16 @@ Split::Split(QWidget *parent)
{
this->overlay_->hide();
}
if (getSettings()->pauseChatModifier.getEnum() != Qt::NoModifier &&
status == getSettings()->pauseChatModifier.getEnum())
{
this->view_->pause(PauseReason::KeyboardModifier);
}
else
{
this->view_->unpause(PauseReason::KeyboardModifier);
}
});
this->input_->ui_.textEdit->focused.connect(
@ -401,6 +412,8 @@ void Split::leaveEvent(QEvent *event)
this->overlay_->hide();
TooltipWidget::getInstance()->hide();
this->handleModifiers(QGuiApplication::queryKeyboardModifiers());
}

View file

@ -301,6 +301,11 @@ std::unique_ptr<QMenu> SplitHeader::createMainMenu()
// sub menu
auto moreMenu = new QMenu("More", this);
moreMenu->addAction("Toggle moderation mode", this->split_, [this]() {
this->split_->setModerationMode(!this->split_->getModerationMode());
});
if (dynamic_cast<TwitchChannel *>(this->split_->getChannel().get()))
{
moreMenu->addAction("Show viewer list", this->split_,