diff --git a/src/common/NetworkRequest.cpp b/src/common/NetworkRequest.cpp index c6d882551..352762c3f 100644 --- a/src/common/NetworkRequest.cpp +++ b/src/common/NetworkRequest.cpp @@ -2,11 +2,12 @@ #include "Application.hpp" #include "common/NetworkManager.hpp" +#include "debug/Log.hpp" #include "providers/twitch/TwitchCommon.hpp" #include "singletons/Paths.hpp" +#include "util/DebugCount.hpp" #include - #include namespace chatterino { @@ -165,6 +166,8 @@ Outcome NetworkRequest::tryLoadCachedFile() void NetworkRequest::doRequest() { + DebugCount::increase("http request started"); + NetworkRequester requester; NetworkWorker *worker = new NetworkWorker; @@ -223,6 +226,8 @@ void NetworkRequest::doRequest() data->writeToCache(bytes); NetworkResult result(bytes); + + DebugCount::increase("http request success"); data->onSuccess_(result); reply->deleteLater(); diff --git a/src/main.cpp b/src/main.cpp index 04a7b934e..5f259a8be 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,6 +6,8 @@ #include #include +#include + using namespace chatterino; int main(int argc, char **argv) diff --git a/src/providers/twitch/TwitchServer.cpp b/src/providers/twitch/TwitchServer.cpp index 1eb6ff1c5..8a5e48cab 100644 --- a/src/providers/twitch/TwitchServer.cpp +++ b/src/providers/twitch/TwitchServer.cpp @@ -96,8 +96,6 @@ void TwitchServer::privateMessageReceived(Communi::IrcPrivateMessage *message) void TwitchServer::messageReceived(Communi::IrcMessage *message) { - qDebug() << message->toData(); - // this->readConnection if (message->type() == Communi::IrcMessage::Type::Private) { // We already have a handler for private messages diff --git a/src/singletons/Theme.cpp b/src/singletons/Theme.cpp index 5140db09a..c5aa16b71 100644 --- a/src/singletons/Theme.cpp +++ b/src/singletons/Theme.cpp @@ -220,8 +220,8 @@ void Theme::actuallyUpdate(double hue, double multiplier) this->scrollbars.background = QColor(0, 0, 0, 0); // this->scrollbars.background = splits.background; // this->scrollbars.background.setAlphaF(qreal(0.2)); - this->scrollbars.thumb = getColor(0, sat, 0.80); - this->scrollbars.thumbSelected = getColor(0, sat, 0.7); + this->scrollbars.thumb = getColor(0, sat, 0.70); + this->scrollbars.thumbSelected = getColor(0, sat, 0.65); // tooltip this->tooltip.background = QColor(0, 0, 0); diff --git a/src/widgets/dialogs/LogsPopup.cpp b/src/widgets/dialogs/LogsPopup.cpp index b524c3462..04aa78fb4 100644 --- a/src/widgets/dialogs/LogsPopup.cpp +++ b/src/widgets/dialogs/LogsPopup.cpp @@ -147,8 +147,8 @@ void LogsPopup::getOverrustleLogs() NetworkRequest req(url); req.setCaller(QThread::currentThread()); - req.onError([this, channelName](int errorCode) { - this->close(); + req.onError([channelName](int errorCode) { + // this->close(); auto box = new QMessageBox( QMessageBox::Information, "Error getting logs", "No logs could be found for channel " + channelName); diff --git a/src/widgets/dialogs/UserInfoPopup.cpp b/src/widgets/dialogs/UserInfoPopup.cpp index b244b8888..1c8a58a71 100644 --- a/src/widgets/dialogs/UserInfoPopup.cpp +++ b/src/widgets/dialogs/UserInfoPopup.cpp @@ -83,7 +83,7 @@ UserInfoPopup::UserInfoPopup() user.emplace("Ignore highlights") .assign(&this->ui_.ignoreHighlights); auto viewLogs = user.emplace(this); - viewLogs->getLabel().setText("Logs"); + viewLogs->getLabel().setText("Online logs"); auto mod = user.emplace(this); mod->setPixmap(app->resources->buttons.mod); diff --git a/src/widgets/helper/RippleEffectButton.cpp b/src/widgets/helper/RippleEffectButton.cpp index 83a6a05b6..fa0d1d253 100644 --- a/src/widgets/helper/RippleEffectButton.cpp +++ b/src/widgets/helper/RippleEffectButton.cpp @@ -1,9 +1,12 @@ #include "RippleEffectButton.hpp" +#include #include +#include #include #include "singletons/Theme.hpp" +#include "util/FunctionEventFilter.hpp" namespace chatterino { @@ -76,6 +79,20 @@ const QColor &RippleEffectButton::getBorderColor() const return this->borderColor_; } +void RippleEffectButton::setMenu(std::unique_ptr menu) +{ + this->menu_ = std::move(menu); + + this->menu_->installEventFilter( + new FunctionEventFilter(this, [this](QObject *, QEvent *event) { + if (event->type() == QEvent::Hide) { + QTimer::singleShot(20, this, + [this] { this->menuVisible_ = false; }); + } + return false; + })); +} + void RippleEffectButton::paintEvent(QPaintEvent *) { QPainter painter(this); @@ -177,6 +194,10 @@ void RippleEffectButton::mousePressEvent(QMouseEvent *event) this->mouseDown_ = true; emit this->leftMousePress(); + + if (this->menu_ && !this->menuVisible_) { + QTimer::singleShot(80, this, [this] { this->showMenu(); }); + } } void RippleEffectButton::mouseReleaseEvent(QMouseEvent *event) @@ -251,4 +272,26 @@ void RippleEffectButton::onMouseEffectTimeout() } } +void RippleEffectButton::showMenu() +{ + if (!this->menu_) return; + + auto point = [this] { + auto bounds = QApplication::desktop()->availableGeometry(this); + + auto point = this->mapToGlobal( + QPoint(this->width() - this->menu_->width(), this->height())); + + if (point.y() + this->menu_->height() > bounds.bottom()) { + point.setY(point.y() - this->menu_->height() - this->height()); + } + + return point; + }; + + this->menu_->popup(point()); + this->menu_->move(point()); + this->menuVisible_ = true; +} + } // namespace chatterino diff --git a/src/widgets/helper/RippleEffectButton.hpp b/src/widgets/helper/RippleEffectButton.hpp index 1211cddf0..0e7b8fcdc 100644 --- a/src/widgets/helper/RippleEffectButton.hpp +++ b/src/widgets/helper/RippleEffectButton.hpp @@ -4,6 +4,7 @@ #include "widgets/BaseWidget.hpp" +#include #include #include #include @@ -43,6 +44,8 @@ public: void setBorderColor(const QColor &color); const QColor &getBorderColor() const; + void setMenu(std::unique_ptr menu); + signals: void clicked(); void leftMousePress(); @@ -57,22 +60,25 @@ protected: void fancyPaint(QPainter &painter); - bool enabled_ = true; - bool selected_ = false; - bool mouseOver_ = false; - bool mouseDown_ = false; + bool enabled_{true}; + bool selected_{false}; + bool mouseOver_{false}; + bool mouseDown_{false}; + bool menuVisible_{false}; private: void onMouseEffectTimeout(); + void showMenu(); - QColor borderColor_; - QPixmap pixmap_; - bool dimPixmap_ = true; - QPoint mousePos_; - double hoverMultiplier_ = 0.0; - QTimer effectTimer_; - std::vector clickEffects_; - boost::optional mouseEffectColor_ = boost::none; + QColor borderColor_{}; + QPixmap pixmap_{}; + bool dimPixmap_{true}; + QPoint mousePos_{}; + double hoverMultiplier_{0.0}; + QTimer effectTimer_{}; + std::vector clickEffects_{}; + boost::optional mouseEffectColor_{}; + std::unique_ptr menu_{}; }; } // namespace chatterino diff --git a/src/widgets/splits/SplitContainer.cpp b/src/widgets/splits/SplitContainer.cpp index 0afbebbbe..371bfcef5 100644 --- a/src/widgets/splits/SplitContainer.cpp +++ b/src/widgets/splits/SplitContainer.cpp @@ -1140,9 +1140,13 @@ void SplitContainer::ResizeHandle::paintEvent(QPaintEvent *) } } -void SplitContainer::ResizeHandle::mousePressEvent(QMouseEvent *) +void SplitContainer::ResizeHandle::mousePressEvent(QMouseEvent *event) { this->isMouseDown_ = true; + + if (event->button() == Qt::RightButton) { + this->resetFlex(); + } } void SplitContainer::ResizeHandle::mouseReleaseEvent(QMouseEvent *) @@ -1211,6 +1215,11 @@ void SplitContainer::ResizeHandle::mouseDoubleClickEvent(QMouseEvent *event) { event->accept(); + this->resetFlex(); +} + +void SplitContainer::ResizeHandle::resetFlex() +{ for (auto &sibling : this->node->getParent()->getChildren()) { sibling->flexH_ = 1; sibling->flexV_ = 1; diff --git a/src/widgets/splits/SplitContainer.hpp b/src/widgets/splits/SplitContainer.hpp index 27d7f25be..7bd2ced1a 100644 --- a/src/widgets/splits/SplitContainer.hpp +++ b/src/widgets/splits/SplitContainer.hpp @@ -161,6 +161,8 @@ private: friend class SplitContainer; private: + void resetFlex(); + bool vertical_; bool isMouseDown_ = false; }; diff --git a/src/widgets/splits/SplitHeader.cpp b/src/widgets/splits/SplitHeader.cpp index 211d0b485..c27014080 100644 --- a/src/widgets/splits/SplitHeader.cpp +++ b/src/widgets/splits/SplitHeader.cpp @@ -6,7 +6,6 @@ #include "providers/twitch/TwitchServer.hpp" #include "singletons/Resources.hpp" #include "singletons/Theme.hpp" -#include "util/FunctionEventFilter.hpp" #include "util/LayoutCreator.hpp" #include "widgets/Label.hpp" #include "widgets/TooltipWidget.hpp" @@ -17,6 +16,7 @@ #include #include #include +#include #include #include @@ -55,15 +55,7 @@ SplitHeader::SplitHeader(Split *_split) this->setupModeLabel(*mode); - QObject::connect( - mode.getElement(), &RippleEffectLabel::clicked, this, [this] { - QTimer::singleShot(80, this, [&, this] { - ChannelPtr _channel = this->split_->getChannel(); - if (_channel->hasModRights()) { - this->modeMenu_.popup(QCursor::pos()); - } - }); - }); + mode->setMenu(this->createChatModeMenu()); // moderation mode auto moderator = layout.emplace(this).assign( @@ -86,14 +78,9 @@ SplitHeader::SplitHeader(Split *_split) dropdown->setMouseTracking(true); // dropdown->setPixmap(*app->resources->splitHeaderContext->getPixmap()); // dropdown->setScaleIndependantSize(23, 23); - this->addDropdownItems(dropdown.getElement()); + dropdown->setMenu(this->createMainMenu()); QObject::connect(dropdown.getElement(), - &RippleEffectButton::leftMousePress, this, [this] { - if (!this->menuVisible_) { - QTimer::singleShot( - 80, this, [this] { this->showMenu(); }); - } - }); + &RippleEffectButton::leftMousePress, this, [this] {}); } // ---- misc @@ -111,8 +98,6 @@ SplitHeader::SplitHeader(Split *_split) this->managedConnect(app->accounts->twitch.currentUserChanged, [this] { this->updateModerationModeIcon(); }); - this->addModeActions(this->modeMenu_); - this->setMouseTracking(true); // Update title on title-settings-change @@ -128,15 +113,6 @@ SplitHeader::SplitHeader(Split *_split) getSettings()->showUptime.connect( [this](const auto &, const auto &) { this->updateChannelText(); }, this->managedConnections_); - - this->dropdownMenu_.installEventFilter( - new FunctionEventFilter(this, [this](QObject *, QEvent *event) { - if (event->type() == QEvent::Hide) { - QTimer::singleShot(20, this, - [this] { this->menuVisible_ = false; }); - } - return false; - })); } SplitHeader::~SplitHeader() @@ -144,63 +120,129 @@ SplitHeader::~SplitHeader() this->onlineStatusChangedConnection_.disconnect(); } -void SplitHeader::addDropdownItems(RippleEffectButton *) +std::unique_ptr SplitHeader::createMainMenu() { - // clang-format off - this->dropdownMenu_.addAction("New split", this->split_, &Split::doAddSplit, QKeySequence(tr("Ctrl+T"))); - this->dropdownMenu_.addAction("Close split", this->split_, &Split::doCloseSplit, QKeySequence(tr("Ctrl+W"))); - this->dropdownMenu_.addAction("Change channel", this->split_, &Split::doChangeChannel, QKeySequence(tr("Ctrl+R"))); - this->dropdownMenu_.addSeparator(); - this->dropdownMenu_.addAction("Viewer list", this->split_, &Split::showViewerList); - this->dropdownMenu_.addAction("Search", this->split_, &Split::showSearchPopup, QKeySequence(tr("Ctrl+F"))); - this->dropdownMenu_.addSeparator(); - this->dropdownMenu_.addAction("Popup", this->split_, &Split::doPopup); + auto menu = std::make_unique(); + menu->addAction("New split", this->split_, &Split::doAddSplit, + QKeySequence(tr("Ctrl+T"))); + menu->addAction("Close split", this->split_, &Split::doCloseSplit, + QKeySequence(tr("Ctrl+W"))); + menu->addAction("Change channel", this->split_, &Split::doChangeChannel, + QKeySequence(tr("Ctrl+R"))); + menu->addSeparator(); + menu->addAction("Viewer list", this->split_, &Split::showViewerList); + menu->addAction("Search", this->split_, &Split::showSearchPopup, + QKeySequence(tr("Ctrl+F"))); + menu->addSeparator(); + menu->addAction("Popup", this->split_, &Split::doPopup); #ifdef USEWEBENGINE - this->dropdownMenu.addAction("Start watching", this, [this]{ + this->dropdownMenu.addAction("Start watching", this, [this] { ChannelPtr _channel = this->split->getChannel(); TwitchChannel *tc = dynamic_cast(_channel.get()); if (tc != nullptr) { - StreamView *view = new StreamView(_channel, "https://player.twitch.tv/?channel=" + tc->name); + StreamView *view = new StreamView( + _channel, "https://player.twitch.tv/?channel=" + tc->name); view->setAttribute(Qt::WA_DeleteOnClose, true); view->show(); } }); #endif - this->dropdownMenu_.addAction("Open browser", this->split_, &Split::openInBrowser); + menu->addAction("Open in browser", this->split_, &Split::openInBrowser); #ifndef USEWEBENGINE - this->dropdownMenu_.addAction("Open browser popup", this->split_, &Split::openInPopupPlayer); + menu->addAction("Open player in browser", this->split_, + &Split::openInPopupPlayer); #endif - this->dropdownMenu_.addAction("Open streamlink", this->split_, &Split::openInStreamlink); - this->dropdownMenu_.addSeparator(); - this->dropdownMenu_.addAction("Reload channel emotes", this, SLOT(menuReloadChannelEmotes())); - this->dropdownMenu_.addAction("Reconnect", this, SLOT(menuManualReconnect())); - this->dropdownMenu_.addAction("Clear messages", this->split_, &Split::doClearChat); -// this->dropdownMenu.addSeparator(); -// this->dropdownMenu.addAction("Show changelog", this, SLOT(menuShowChangelog())); - // clang-format on + menu->addAction("Open streamlink", this->split_, &Split::openInStreamlink); + menu->addSeparator(); + menu->addAction("Reload channel emotes", this, + SLOT(menuReloadChannelEmotes())); + menu->addAction("Reconnect", this, SLOT(menuManualReconnect())); + // menu->addAction("Clear messages", this->split_, &Split::doClearChat); + // menu->addSeparator(); + // menu->addAction("Show changelog", this, SLOT(menuShowChangelog())); + + return menu; } -void SplitHeader::showMenu() +std::unique_ptr SplitHeader::createChatModeMenu() { - auto point = [this] { - auto bounds = QApplication::desktop()->availableGeometry(this); + auto menu = std::make_unique(); - auto point = this->dropdownButton_->mapToGlobal( - QPoint(this->dropdownButton_->width() - this->dropdownMenu_.width(), - this->dropdownButton_->height())); + auto setSub = new QAction("Subscriber only", this); + auto setEmote = new QAction("Emote only", this); + auto setSlow = new QAction("Slow", this); + auto setR9k = new QAction("R9K", this); - if (point.y() + this->dropdownMenu_.height() > bounds.bottom()) { - point.setY(point.y() - this->dropdownMenu_.height() - - this->dropdownButton_->height()); - } + setSub->setCheckable(true); + setEmote->setCheckable(true); + setSlow->setCheckable(true); + setR9k->setCheckable(true); - return point; + menu->addAction(setEmote); + menu->addAction(setSub); + menu->addAction(setSlow); + menu->addAction(setR9k); + + this->managedConnections_.push_back(this->modeUpdateRequested_.connect( // + [this, setSub, setEmote, setSlow, setR9k]() { + auto twitchChannel = + dynamic_cast(this->split_->getChannel().get()); + if (twitchChannel == nullptr) { + this->modeButton_->hide(); + return; + } + + auto roomModes = twitchChannel->accessRoomModes(); + + setR9k->setChecked(roomModes->r9k); + setSlow->setChecked(roomModes->slowMode); + setEmote->setChecked(roomModes->emoteOnly); + setSub->setChecked(roomModes->submode); + })); + + auto toggle = [this](const QString &_command, QAction *action) mutable { + QString command = _command; + + if (!action->isChecked()) { + command += "off"; + }; + action->setChecked(!action->isChecked()); + + qDebug() << command; + this->split_->getChannel().get()->sendMessage(command); }; - this->dropdownMenu_.popup(point()); - this->dropdownMenu_.move(point()); - this->menuVisible_ = true; + QObject::connect( + setSub, &QAction::triggered, this, + [setSub, toggle]() mutable { toggle("/subscribers", setSub); }); + + QObject::connect( + setEmote, &QAction::triggered, this, + [setEmote, toggle]() mutable { toggle("/emoteonly", setEmote); }); + + QObject::connect(setSlow, &QAction::triggered, this, [setSlow, this]() { + if (!setSlow->isChecked()) { + this->split_->getChannel().get()->sendMessage("/slowoff"); + setSlow->setChecked(false); + return; + }; + bool ok; + int slowSec = QInputDialog::getInt(this, "", "Seconds:", 10, 0, 500, 1, + &ok, Qt::FramelessWindowHint); + if (ok) { + this->split_->getChannel().get()->sendMessage( + QString("/slow %1").arg(slowSec)); + } else { + setSlow->setChecked(false); + } + }); + + QObject::connect( + setR9k, &QAction::triggered, this, + [setR9k, toggle]() mutable { toggle("/r9kbeta", setR9k); }); + + return menu; } void SplitHeader::updateRoomModes() @@ -263,82 +305,6 @@ void SplitHeader::setupModeLabel(RippleEffectLabel &label) })); } -void SplitHeader::addModeActions(QMenu &menu) -{ - auto setSub = new QAction("Subscriber only", this); - auto setEmote = new QAction("Emote only", this); - auto setSlow = new QAction("Slow", this); - auto setR9k = new QAction("R9K", this); - - setSub->setCheckable(true); - setEmote->setCheckable(true); - setSlow->setCheckable(true); - setR9k->setCheckable(true); - - menu.addAction(setEmote); - menu.addAction(setSub); - menu.addAction(setSlow); - menu.addAction(setR9k); - - this->managedConnections_.push_back(this->modeUpdateRequested_.connect( // - [this, setSub, setEmote, setSlow, setR9k]() { - auto twitchChannel = - dynamic_cast(this->split_->getChannel().get()); - if (twitchChannel == nullptr) { - this->modeButton_->hide(); - return; - } - - auto roomModes = twitchChannel->accessRoomModes(); - - setR9k->setChecked(roomModes->r9k); - setSlow->setChecked(roomModes->slowMode); - setEmote->setChecked(roomModes->emoteOnly); - setSub->setChecked(roomModes->submode); - })); - - auto toggle = [this](const QString &_command, QAction *action) mutable { - QString command = _command; - - if (!action->isChecked()) { - command += "off"; - }; - action->setChecked(!action->isChecked()); - - qDebug() << command; - this->split_->getChannel().get()->sendMessage(command); - }; - - QObject::connect( - setSub, &QAction::triggered, this, - [setSub, toggle]() mutable { toggle("/subscribers", setSub); }); - - QObject::connect( - setEmote, &QAction::triggered, this, - [setEmote, toggle]() mutable { toggle("/emoteonly", setEmote); }); - - QObject::connect(setSlow, &QAction::triggered, this, [setSlow, this]() { - if (!setSlow->isChecked()) { - this->split_->getChannel().get()->sendMessage("/slowoff"); - setSlow->setChecked(false); - return; - }; - bool ok; - int slowSec = QInputDialog::getInt(this, "", "Seconds:", 10, 0, 500, 1, - &ok, Qt::FramelessWindowHint); - if (ok) { - this->split_->getChannel().get()->sendMessage( - QString("/slow %1").arg(slowSec)); - } else { - setSlow->setChecked(false); - } - }); - - QObject::connect( - setR9k, &QAction::triggered, this, - [setR9k, toggle]() mutable { toggle("/r9kbeta", setR9k); }); -} - void SplitHeader::initializeChannelSignals() { // Disconnect any previous signal first @@ -438,9 +404,9 @@ void SplitHeader::updateModerationModeIcon() bool modButtonVisible = false; ChannelPtr channel = this->split_->getChannel(); - TwitchChannel *tc = dynamic_cast(channel.get()); + auto twitchChannel = dynamic_cast(channel.get()); - if (tc != nullptr && tc->hasModRights()) { + if (twitchChannel != nullptr && twitchChannel->hasModRights()) { modButtonVisible = true; } diff --git a/src/widgets/splits/SplitHeader.hpp b/src/widgets/splits/SplitHeader.hpp index 9250eda3f..4846829fe 100644 --- a/src/widgets/splits/SplitHeader.hpp +++ b/src/widgets/splits/SplitHeader.hpp @@ -51,12 +51,11 @@ protected: private: void rightButtonClicked(); void initializeChannelSignals(); - void addModeActions(QMenu &menu); void setupModeLabel(RippleEffectLabel &label); - void addDropdownItems(RippleEffectButton *label); - void showMenu(); + std::unique_ptr createMainMenu(); + std::unique_ptr createChatModeMenu(); - Split *const split_; + Split *split_; QPoint dragStart_; bool dragging_ = false; @@ -71,9 +70,6 @@ private: RippleEffectLabel *modeButton_{}; RippleEffectButton *moderationButton_{}; - QMenu dropdownMenu_; - QMenu modeMenu_; - bool menuVisible_{}; pajlada::Signals::NoArgSignal modeUpdateRequested_; diff --git a/tools/windows-fix-directory-case-sensitivity.sh b/tools/windows-fix-directory-case-sensitivity.sh new file mode 100644 index 000000000..c68aa96e1 --- /dev/null +++ b/tools/windows-fix-directory-case-sensitivity.sh @@ -0,0 +1 @@ +find . -not -path "*.git*" -exec fsutil.exe file setCaseSensitiveInfo {} disable \;