diff --git a/chatterino.pro b/chatterino.pro index 0230bba30..169711a94 100644 --- a/chatterino.pro +++ b/chatterino.pro @@ -180,6 +180,7 @@ SOURCES += \ src/util/JsonQuery.cpp \ src/util/RapidjsonHelpers.cpp \ src/util/StreamLink.cpp \ + src/util/NuulsUploader.cpp \ src/widgets/AccountSwitchPopup.cpp \ src/widgets/AccountSwitchWidget.cpp \ src/widgets/AttachedWindow.cpp \ @@ -369,6 +370,7 @@ HEADERS += \ src/util/SharedPtrElementLess.hpp \ src/util/StandardItemHelper.hpp \ src/util/StreamLink.hpp \ + src/util/NuulsUploader.hpp \ src/widgets/AccountSwitchPopup.hpp \ src/widgets/AccountSwitchWidget.hpp \ src/widgets/AttachedWindow.hpp \ diff --git a/docs/ENV.md b/docs/ENV.md index 727503ff4..bddef4687 100644 --- a/docs/ENV.md +++ b/docs/ENV.md @@ -18,3 +18,13 @@ Used to change the URL that Chatterino2 uses when trying to get emote set inform Default value: `https://braize.pajlada.com/chatterino/twitchemotes/set/%1/` Arguments: - `%1` = Emote set ID + +### CHATTERINO2_IMAGE_PASTE_SITE_URL +Used to change the URL that Chatterino2 uses when uploading an image by pasting it into the input box. +Default value: `https://i.nuuls.com/upload` + +Arguments: + - None + +Notes: + - The server that's running the web page MUST be compatible with [Nuuls' filehost](https://github.com/nuuls/filehost) diff --git a/src/common/Env.cpp b/src/common/Env.cpp index ff711ec47..046febf53 100644 --- a/src/common/Env.cpp +++ b/src/common/Env.cpp @@ -28,6 +28,8 @@ Env::Env() , twitchEmoteSetResolverUrl(readStringEnv( "CHATTERINO2_TWITCH_EMOTE_SET_RESOLVER_URL", "https://braize.pajlada.com/chatterino/twitchemotes/set/%1/")) + , imagePasteSiteUrl(readStringEnv("CHATTERINO2_IMAGE_PASTE_SITE_URL", + "https://i.nuuls.com/upload")) { } diff --git a/src/common/Env.hpp b/src/common/Env.hpp index 2dc7fa1ba..a47dd3aff 100644 --- a/src/common/Env.hpp +++ b/src/common/Env.hpp @@ -14,6 +14,7 @@ public: const QString recentMessagesApiUrl; const QString linkResolverUrl; const QString twitchEmoteSetResolverUrl; + const QString imagePasteSiteUrl; }; } // namespace chatterino diff --git a/src/widgets/helper/ResizingTextEdit.cpp b/src/widgets/helper/ResizingTextEdit.cpp index edaa11738..4ed3ba0cd 100644 --- a/src/widgets/helper/ResizingTextEdit.cpp +++ b/src/widgets/helper/ResizingTextEdit.cpp @@ -1,7 +1,9 @@ -#include "widgets/helper/ResizingTextEdit.hpp" +#include + #include "common/Common.hpp" #include "common/CompletionModel.hpp" #include "singletons/Settings.hpp" +#include "widgets/helper/ResizingTextEdit.hpp" namespace chatterino { @@ -22,6 +24,7 @@ ResizingTextEdit::ResizingTextEdit() [this] { this->completionInProgress_ = false; }); this->setFocusPolicy(Qt::ClickFocus); + setAcceptDrops(true); } QSize ResizingTextEdit::sizeHint() const @@ -257,11 +260,7 @@ void ResizingTextEdit::insertCompletion(const QString &completion) bool ResizingTextEdit::canInsertFromMimeData(const QMimeData *source) const { - if (source->hasImage()) - { - return false; - } - else if (source->hasFormat("text/plain")) + if (source->hasImage() || source->hasFormat("text/plain")) { return true; } @@ -270,12 +269,35 @@ bool ResizingTextEdit::canInsertFromMimeData(const QMimeData *source) const void ResizingTextEdit::insertFromMimeData(const QMimeData *source) { - if (!source->hasImage()) + if (source->hasImage() || source->hasUrls()) + { + this->pastedImage.invoke(source); + } + else { insertPlainText(source->text()); } } +void ResizingTextEdit::dragEnterEvent(QDragEnterEvent *event) +{ + if (event->mimeData()->hasImage() || event->mimeData()->hasUrls()) + { + event->acceptProposedAction(); + } + // QTextEdit doesn't implement dragEnterEvent, so there's nothing to call here. +} +void ResizingTextEdit::dropEvent(QDropEvent *event) +{ + if (event->mimeData()->hasImage() || event->mimeData()->hasUrls()) + { + this->pastedImage.invoke(event->mimeData()); + } + else // allow for previous functionality of dropping text. + { + QTextEdit::dropEvent(event); + } +} QCompleter *ResizingTextEdit::getCompleter() const { return this->completer_; diff --git a/src/widgets/helper/ResizingTextEdit.hpp b/src/widgets/helper/ResizingTextEdit.hpp index ff79cddb4..df6649048 100644 --- a/src/widgets/helper/ResizingTextEdit.hpp +++ b/src/widgets/helper/ResizingTextEdit.hpp @@ -19,6 +19,7 @@ public: pajlada::Signals::Signal keyPressed; pajlada::Signals::NoArgSignal focused; pajlada::Signals::NoArgSignal focusLost; + pajlada::Signals::Signal pastedImage; void setCompleter(QCompleter *c); QCompleter *getCompleter() const; @@ -33,6 +34,9 @@ protected: bool canInsertFromMimeData(const QMimeData *source) const override; void insertFromMimeData(const QMimeData *source) override; + void dragEnterEvent(QDragEnterEvent *event); + void dropEvent(QDropEvent *event); + private: // hadSpace is set to true in case the "textUnderCursor" word was after a // space diff --git a/src/widgets/splits/Split.cpp b/src/widgets/splits/Split.cpp index 209baa028..361b1adee 100644 --- a/src/widgets/splits/Split.cpp +++ b/src/widgets/splits/Split.cpp @@ -1,16 +1,18 @@ #include "widgets/splits/Split.hpp" #include "common/Common.hpp" +#include "common/Env.hpp" #include "common/NetworkRequest.hpp" #include "controllers/accounts/AccountController.hpp" #include "debug/Log.hpp" #include "providers/twitch/EmoteValue.hpp" #include "providers/twitch/TwitchChannel.hpp" -#include "providers/twitch/TwitchMessageBuilder.hpp" #include "providers/twitch/TwitchIrcServer.hpp" +#include "providers/twitch/TwitchMessageBuilder.hpp" #include "singletons/Settings.hpp" #include "singletons/Theme.hpp" #include "singletons/WindowManager.hpp" +#include "util/NuulsUploader.hpp" #include "util/Shortcut.hpp" #include "util/StreamLink.hpp" #include "widgets/Notebook.hpp" @@ -205,6 +207,11 @@ Split::Split(QWidget *parent) [this] { this->focused.invoke(); }); this->input_->ui_.textEdit->focusLost.connect( [this] { this->focusLost.invoke(); }); + this->input_->ui_.textEdit->pastedImage.connect( + [this](const QMimeData *source) { + pasteFromClipboard(source, this->getChannel(), + *this->input_->ui_.textEdit); + }); } Split::~Split()