diff --git a/CHANGELOG.md b/CHANGELOG.md index dc19e9781..33d1a159f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unversioned +- Minor: Added an option to only open channels specified in command line with `-c` parameter. You can also use `--help` to display short help message (#1940) - Minor: Added customizable timeout buttons to the user info popup - Minor: Deprecate loading of "v1" window layouts. If you haven't updated Chatterino in more than 2 years, there's a chance you will lose your window layout. - Minor: Disable checking for updates on unsupported platforms (#1874) diff --git a/resources/contributors.txt b/resources/contributors.txt index a04562ecc..69d6e6bf4 100644 --- a/resources/contributors.txt +++ b/resources/contributors.txt @@ -32,6 +32,7 @@ Mm2PL | https://github.com/mm2pl | | Contributor gempir | https://github.com/gempir | | Contributor mfmarlow | https://github.com/mfmarlow | | Contributor dnsge | https://github.com/dnsge | | Contributor +zneix | https://github.com/zneix | | Contributor # If you are a contributor add yourself above this line Defman21 | https://github.com/Defman21 | | Documentation diff --git a/src/BrowserExtension.cpp b/src/BrowserExtension.cpp index de869e2d6..602a3f1f5 100644 --- a/src/BrowserExtension.cpp +++ b/src/BrowserExtension.cpp @@ -86,12 +86,6 @@ namespace { } } // namespace -bool shouldRunBrowserExtensionHost(const QStringList &args) -{ - return args.size() > 0 && (args[0].startsWith("chrome-extension://") || - args[0].endsWith(".json")); -} - void runBrowserExtensionHost() { initFileMode(); diff --git a/src/BrowserExtension.hpp b/src/BrowserExtension.hpp index 0232ac2b8..101ce5f25 100644 --- a/src/BrowserExtension.hpp +++ b/src/BrowserExtension.hpp @@ -1,10 +1,7 @@ #pragma once -class QStringList; - namespace chatterino { -bool shouldRunBrowserExtensionHost(const QStringList &args); void runBrowserExtensionHost(); } // namespace chatterino diff --git a/src/RunGui.cpp b/src/RunGui.cpp index e025d7f21..b1e842d48 100644 --- a/src/RunGui.cpp +++ b/src/RunGui.cpp @@ -9,6 +9,7 @@ #include #include "Application.hpp" +#include "common/Args.hpp" #include "common/Modes.hpp" #include "common/NetworkManager.hpp" #include "singletons/Paths.hpp" @@ -215,7 +216,10 @@ void runGui(QApplication &a, Paths &paths, Settings &settings) removeRunningFile(runningPath); - pajlada::Settings::SettingManager::gSave(); + if (!getArgs().dontSaveSettings) + { + pajlada::Settings::SettingManager::gSave(); + } chatterino::NetworkManager::deinit(); diff --git a/src/common/Args.cpp b/src/common/Args.cpp index 0eaf5b355..15e151ca5 100644 --- a/src/common/Args.cpp +++ b/src/common/Args.cpp @@ -1,27 +1,87 @@ #include "Args.hpp" +#include +#include +#include +#include +#include +#include +#include + namespace chatterino { -Args::Args(const QStringList &args) +Args::Args(const QApplication &app) { - for (auto &&arg : args) + QCommandLineParser parser; + parser.setApplicationDescription("Chatterino 2 Client for Twitch Chat"); + parser.addHelpOption(); + + // Used internally by app to restart after unexpected crashes + QCommandLineOption crashRecoveryOption("crash-recovery"); + crashRecoveryOption.setHidden(true); + + parser.addOptions({ + {{"v", "version"}, "Displays version information."}, + crashRecoveryOption, + }); + parser.addOption(QCommandLineOption( + {"c", "channels"}, + "Joins only supplied channels on startup. Use letters with colons to " + "specify platform. Only twitch channels are supported at the moment.\n" + "If platform isn't specified, default is Twitch.", + "t:channel1;t:channel2;...")); + parser.process(app); + + const QStringList args = parser.positionalArguments(); + this->shouldRunBrowserExtensionHost = + (args.size() > 0 && (args[0].startsWith("chrome-extension://") || + args[0].endsWith(".json"))); + + if (parser.isSet("c")) { - if (arg == "--crash-recovery") + QJsonArray channelArray; + QStringList channelArgList = parser.value("c").split(";"); + for (QString channelArg : channelArgList) { - this->crashRecovery = true; + // Twitch is default platform + QString platform = "t"; + QString channelName = channelArg; + + const QRegExp regExp("(.):(.*)"); + if (regExp.indexIn(channelArg) != -1) + { + platform = regExp.cap(1); + channelName = regExp.cap(2); + } + + // Twitch (default) + if (platform == "t") + { + // TODO: try not to parse JSON + QString channelObjectString = + "{\"splits2\": { \"data\": { \"name\": \"" + channelName + + "\", \"type\": \"twitch\" }, \"type\": \"split\" }}"; + channelArray.push_back( + QJsonDocument::fromJson(channelObjectString.toUtf8()) + .object()); + } } - else if (arg == "--version") + if (channelArray.size() > 0) { - this->printVersion = true; + this->dontSaveSettings = true; + this->channelsToJoin = channelArray; } } + + this->printVersion = parser.isSet("v"); + this->crashRecovery = parser.isSet("crash-recovery"); } static Args *instance = nullptr; -void initArgs(const QStringList &args) +void initArgs(const QApplication &app) { - instance = new Args(args); + instance = new Args(app); } const Args &getArgs() diff --git a/src/common/Args.hpp b/src/common/Args.hpp index cde9538bf..54a64e7e0 100644 --- a/src/common/Args.hpp +++ b/src/common/Args.hpp @@ -1,6 +1,7 @@ #pragma once -#include +#include +#include namespace chatterino { @@ -8,13 +9,16 @@ namespace chatterino { class Args { public: - Args(const QStringList &args); + Args(const QApplication &app); bool printVersion{}; bool crashRecovery{}; + bool shouldRunBrowserExtensionHost{}; + bool dontSaveSettings{}; + QJsonArray channelsToJoin{}; }; -void initArgs(const QStringList &args); +void initArgs(const QApplication &app); const Args &getArgs(); } // namespace chatterino diff --git a/src/main.cpp b/src/main.cpp index 67a05b7b9..4202654d5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -25,14 +26,10 @@ int main(int argc, char **argv) QCoreApplication::setApplicationVersion(CHATTERINO_VERSION); QCoreApplication::setOrganizationDomain("https://www.chatterino.com"); - // convert char** to QStringList - auto args = QStringList(); - std::transform(argv + 1, argv + argc, std::back_inserter(args), - [&](auto s) { return s; }); - initArgs(args); + initArgs(a); // run in gui mode or browser extension host mode - if (shouldRunBrowserExtensionHost(args)) + if (getArgs().shouldRunBrowserExtensionHost) { runBrowserExtensionHost(); } diff --git a/src/singletons/WindowManager.cpp b/src/singletons/WindowManager.cpp index d31b09ef9..aa9bb9ecc 100644 --- a/src/singletons/WindowManager.cpp +++ b/src/singletons/WindowManager.cpp @@ -12,6 +12,7 @@ #include #include "Application.hpp" +#include "common/Args.hpp" #include "debug/AssertInGuiThread.hpp" #include "messages/MessageElement.hpp" #include "providers/irc/Irc2.hpp" @@ -326,6 +327,10 @@ void WindowManager::initialize(Settings &settings, Paths &paths) void WindowManager::save() { + if (getArgs().dontSaveSettings) + { + return; + } qDebug() << "[WindowManager] Saving"; assertInGuiThread(); QJsonDocument document; diff --git a/src/widgets/dialogs/SettingsDialog.cpp b/src/widgets/dialogs/SettingsDialog.cpp index fce8b325e..3da3e3aa9 100644 --- a/src/widgets/dialogs/SettingsDialog.cpp +++ b/src/widgets/dialogs/SettingsDialog.cpp @@ -1,6 +1,7 @@ #include "widgets/dialogs/SettingsDialog.hpp" #include "Application.hpp" +#include "common/Args.hpp" #include "singletons/Resources.hpp" #include "util/LayoutCreator.hpp" #include "util/Shortcut.hpp" @@ -315,7 +316,10 @@ void SettingsDialog::showEvent(QShowEvent *) ///// Widget creation helpers void SettingsDialog::onOkClicked() { - pajlada::Settings::SettingManager::gSave(); + if (!getArgs().dontSaveSettings) + { + pajlada::Settings::SettingManager::gSave(); + } this->close(); }