From decca6e9064fbc82b23e5d37bd561db82aba62f6 Mon Sep 17 00:00:00 2001 From: Michael Fabian 'Xaymar' Dirks Date: Sat, 11 Dec 2021 17:40:40 +0100 Subject: [PATCH] ui/about: Use auto-generated credits for "About StreamFX" As contributors and translators always increase in number and never decrease, it was getting difficult to thank everyone properly with every update. So instead of manually writing each entry we should take advantage of the power of automation and use APIs to gather this information properly. As long as the user is not actively hiding their profile, they will be thanked properly. This also includes a potential fix for the problem with multi-lingual text in the About StreamFX window. --- source/ui/ui-about-entry.cpp | 6 - source/ui/ui-about.cpp | 567 ++++++++++------------------------- source/ui/ui-about.hpp | 3 - ui/about-entry.ui | 12 +- ui/about.ui | 14 + 5 files changed, 181 insertions(+), 421 deletions(-) diff --git a/source/ui/ui-about-entry.cpp b/source/ui/ui-about-entry.cpp index cd6b4222..8345f6d1 100644 --- a/source/ui/ui-about-entry.cpp +++ b/source/ui/ui-about-entry.cpp @@ -21,10 +21,7 @@ constexpr std::string_view i18n_role_contributor = "UI.About.Role.Contributor"; constexpr std::string_view i18n_role_translator = "UI.About.Role.Translator"; -constexpr std::string_view i18n_role_family = "UI.About.Role.Family"; -constexpr std::string_view i18n_role_friend = "UI.About.Role.Friend"; constexpr std::string_view i18n_role_supporter = "UI.About.Role.Supporter"; -constexpr std::string_view i18n_role_creator = "UI.About.Role.Creator"; streamfx::ui::about_entry::about_entry(QWidget* parent, const streamfx::ui::about::entry& entry) : QWidget(parent), _link() @@ -45,9 +42,6 @@ streamfx::ui::about_entry::about_entry(QWidget* parent, const streamfx::ui::abou case streamfx::ui::about::role_type::SUPPORTER: title->setText(D_TRANSLATE(i18n_role_supporter.data())); break; - case streamfx::ui::about::role_type::CREATOR: - title->setText(D_TRANSLATE(i18n_role_creator.data())); - break; default: break; } diff --git a/source/ui/ui-about.cpp b/source/ui/ui-about.cpp index 0660f6f6..5ea18e92 100644 --- a/source/ui/ui-about.cpp +++ b/source/ui/ui-about.cpp @@ -18,10 +18,17 @@ */ #include "ui-about.hpp" -#include +#include +#include +#include #include #include + +#include +#include +#include "plugin.hpp" #include "ui-about-entry.hpp" +#include "util/util-logging.hpp" #ifdef _MSC_VER #pragma warning(push) @@ -33,10 +40,19 @@ #pragma warning(pop) #endif -constexpr std::string_view text_social_facebook = "Facebook"; -constexpr std::string_view text_social_twitch = "Twitch"; -constexpr std::string_view text_social_twitter = "Twitter"; -constexpr std::string_view text_social_youtube = "YouTube"; +#ifdef _DEBUG +#define ST_PREFIX "<%s> " +#define D_LOG_ERROR(x, ...) P_LOG_ERROR(ST_PREFIX##x, __FUNCTION_SIG__, __VA_ARGS__) +#define D_LOG_WARNING(x, ...) P_LOG_WARN(ST_PREFIX##x, __FUNCTION_SIG__, __VA_ARGS__) +#define D_LOG_INFO(x, ...) P_LOG_INFO(ST_PREFIX##x, __FUNCTION_SIG__, __VA_ARGS__) +#define D_LOG_DEBUG(x, ...) P_LOG_DEBUG(ST_PREFIX##x, __FUNCTION_SIG__, __VA_ARGS__) +#else +#define ST_PREFIX " " +#define D_LOG_ERROR(...) P_LOG_ERROR(ST_PREFIX __VA_ARGS__) +#define D_LOG_WARNING(...) P_LOG_WARN(ST_PREFIX __VA_ARGS__) +#define D_LOG_INFO(...) P_LOG_INFO(ST_PREFIX __VA_ARGS__) +#define D_LOG_DEBUG(...) P_LOG_DEBUG(ST_PREFIX __VA_ARGS__) +#endif static const std::vector _thankyous = { ":/thankyou/thankyou_cat", @@ -44,422 +60,159 @@ static const std::vector _thankyous = { ":/thankyou/thankyou_fox", }; -static const streamfx::ui::about::entry _entries[] = { - // Contributers (Updated on 2021-04-23) - // - 2021 - streamfx::ui::about::entry{"Michael \"Xaymar\" Dirks", streamfx::ui::about::role_type::CONTRIBUTOR, "", - "https://xaymar.com"}, - streamfx::ui::about::entry{"cpyarger", streamfx::ui::about::role_type::CONTRIBUTOR, "", - "https://github.com/cpyarger"}, - streamfx::ui::about::entry{"tyten652", streamfx::ui::about::role_type::CONTRIBUTOR, "", - "https://github.com/tytan652"}, - streamfx::ui::about::entry{"kilinbox", streamfx::ui::about::role_type::CONTRIBUTOR, "", - "https://github.com/kilinbox"}, - // - 2020 - streamfx::ui::about::entry{"Oncorporation", streamfx::ui::about::role_type::CONTRIBUTOR, "", - "https://github.com/Oncorporation"}, - streamfx::ui::about::entry{"dghodgson", streamfx::ui::about::role_type::CONTRIBUTOR, "", - "https://github.com/dghodgson"}, - streamfx::ui::about::entry{"danimo", streamfx::ui::about::role_type::CONTRIBUTOR, "", "https://github.com/danimo"}, - streamfx::ui::about::entry{"brandonedens", streamfx::ui::about::role_type::CONTRIBUTOR, "", - "https://github.com/brandonedens"}, - streamfx::ui::about::entry{"rjmoggach", streamfx::ui::about::role_type::CONTRIBUTOR, "", - "https://github.com/rjmoggach"}, - // - 2019 - streamfx::ui::about::entry{"catb0t", streamfx::ui::about::role_type::CONTRIBUTOR, "", "https://github.com/catb0t"}, - streamfx::ui::about::entry{"Vainock", streamfx::ui::about::role_type::CONTRIBUTOR, "", - "https://github.com/Vainock"}, - streamfx::ui::about::entry{"wwj402", streamfx::ui::about::role_type::CONTRIBUTOR, "", "https://github.com/wwj402"}, - // - 2018 - - // Supporters (Updated on 2021-04-23) - streamfx::ui::about::entry{"dangerbeard", streamfx::ui::about::role_type::SUPPORTER, "", - "https://twitch.tv/thedangerbeard"}, // https://www.patreon.com/thedangerbeard - streamfx::ui::about::entry{"GranDroidTonight", streamfx::ui::about::role_type::SUPPORTER, "", - "https://www.twitch.tv/GranDroidTonight"}, // https://github.com/GranDroidTonight - streamfx::ui::about::entry{"Jahan", streamfx::ui::about::role_type::SUPPORTER, "", - "https://twitch.tv/1twohikaru"}, // https://www.patreon.com/user?u=152960 - streamfx::ui::about::entry{"Joefisx20s", streamfx::ui::about::role_type::SUPPORTER, "", - "https://www.twitch.tv/joefisx20s"}, // https://github.com/Joefis-x20s - streamfx::ui::about::entry{"KrisCheetah", streamfx::ui::about::role_type::SUPPORTER, "", - ""}, // https://www.patreon.com/user?u=5208869 - streamfx::ui::about::entry{"ragesaq", streamfx::ui::about::role_type::SUPPORTER, "", - ""}, // https://www.patreon.com/user?u=34519727 - streamfx::ui::about::entry{"Rayxcer", streamfx::ui::about::role_type::SUPPORTER, "", - "https://twitter.com/Rayxcer1"}, // https://www.patreon.com/user?u=5086308 - streamfx::ui::about::entry{"SadeN", streamfx::ui::about::role_type::SUPPORTER, "", - "https://twitch.tv/saden_0"}, // https://www.patreon.com/vox_oculi - streamfx::ui::about::entry{"SunsetsBrew", streamfx::ui::about::role_type::SUPPORTER, "", - "http://twitch.tv/torpidnetwork"}, // https://www.patreon.com/user?u=915823 - streamfx::ui::about::entry{"ThePooN", streamfx::ui::about::role_type::SUPPORTER, "", - "https://twitch.tv/ThePooN"}, // https://github.com/ThePooN - streamfx::ui::about::entry{"tsukasa", streamfx::ui::about::role_type::SUPPORTER, "", - "https://tsukasa.eu/"}, // https://www.patreon.com/user?u=23383875 - streamfx::ui::about::entry{"Vensire Studios", streamfx::ui::about::role_type::SUPPORTER, "", - "https://www.facebook.com/vensirestudios"}, // https://github.com/VensireStudios - streamfx::ui::about::entry{"y0himba", streamfx::ui::about::role_type::SUPPORTER, "", - "https://twitch.tv/y0himba"}, // https://www.patreon.com/y0himba - - // Separator - streamfx::ui::about::entry{"", streamfx::ui::about::role_type::THANKYOU, "", ""}, - - // Translators (Updated on 2021-04-23) - streamfx::ui::about::entry{"Adolfo Jayme", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/fitoschido"}, // https://crowdin.com/profile/fitoschido - streamfx::ui::about::entry{"Alex E. D. B.", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/alexedb"}, // https://crowdin.com/profile/alexedb - streamfx::ui::about::entry{ - "Alexander Haffer", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/AlexanderHaffer"}, // https://crowdin.com/profile/AlexanderHaffer - streamfx::ui::about::entry{"Arcan Yiğit Taşkan", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/karamizahim"}, // https://crowdin.com/profile/karamizahim - streamfx::ui::about::entry{"Arda Gamer", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/noobumpls"}, // https://crowdin.com/profile/noobumpls - streamfx::ui::about::entry{"Artem4ik", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Artem4ik"}, // https://crowdin.com/profile/Artem4ik - streamfx::ui::about::entry{"Arthur", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Skor_X"}, // https://crowdin.com/profile/Skor_X - streamfx::ui::about::entry{"Aurora Robb Kristiansen", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Ridge"}, // https://crowdin.com/profile/Ridge - streamfx::ui::about::entry{"Billy_la_menace", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Symor"}, // https://crowdin.com/profile/Symor - streamfx::ui::about::entry{ - "Boris Grigorov", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/boris.grigorov26"}, // https://crowdin.com/profile/boris.grigorov26 - streamfx::ui::about::entry{"Bruno Pinho", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/BPinho"}, // https://crowdin.com/profile/BPinho - streamfx::ui::about::entry{"Cedric Günther", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/LeNinjaHD"}, // https://crowdin.com/profile/LeNinjaHD - streamfx::ui::about::entry{"Chris BDS", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/HakuKaze"}, // https://crowdin.com/profile/HakuKaze - streamfx::ui::about::entry{ - "Claudio Nunes", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/_claudionunes_"}, // https://crowdin.com/profile/_claudionunes_ - streamfx::ui::about::entry{"ColdusT", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/ColdusT"}, // https://crowdin.com/profile/ColdusT - streamfx::ui::about::entry{"CyberspeedCz", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/CyberspeedCz"}, // https://crowdin.com/profile/CyberspeedCz - streamfx::ui::about::entry{"Damian Soler", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Under_RL"}, // https://crowdin.com/profile/Under_RL - streamfx::ui::about::entry{"Danil Sarvensky", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/sarvensky"}, // https://crowdin.com/profile/sarvensky - streamfx::ui::about::entry{"David Zheng", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/msdz"}, // https://crowdin.com/profile/msdz - streamfx::ui::about::entry{"Deadbringer", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Deadbringer"}, // https://crowdin.com/profile/Deadbringer - streamfx::ui::about::entry{"DmJacky", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/DmJacky"}, // https://crowdin.com/profile/DmJacky - streamfx::ui::about::entry{ - "EDNVKjldr8vyu9", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/EDNVKjldr8vyu9"}, // https://crowdin.com/profile/EDNVKjldr8vyu9 - streamfx::ui::about::entry{"EMRE ÇELİK", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/emre0447"}, // https://crowdin.com/profile/emre0447 - streamfx::ui::about::entry{"Emanuel Messias, R.d.S.", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/MessiasOF"}, // https://crowdin.com/profile/MessiasOF - streamfx::ui::about::entry{"Enrique Castillo", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/ecastillo"}, // https://crowdin.com/profile/ecastillo - streamfx::ui::about::entry{"Eryk Pazoła", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/erykpaz2004"}, // https://crowdin.com/profile/erykpaz2004 - streamfx::ui::about::entry{"Fire KM127PL", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/KM127PL"}, // https://crowdin.com/profile/KM127PL - streamfx::ui::about::entry{"Francesco Maria Poerio", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/fracchiomon"}, // https://crowdin.com/profile/fracchiomon - streamfx::ui::about::entry{"Frederico Maia", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/omaster"}, // https://crowdin.com/profile/omaster - streamfx::ui::about::entry{ - "Gabriele Arena", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/teamexpert2013"}, // https://crowdin.com/profile/teamexpert2013 - streamfx::ui::about::entry{"Gol D. Ace", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/goldace"}, // https://crowdin.com/profile/goldace - streamfx::ui::about::entry{"Guillaume Turchini", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/orion78fr"}, // https://crowdin.com/profile/orion78fr - streamfx::ui::about::entry{"Hackebein", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Hackebein"}, // https://crowdin.com/profile/Hackebein - streamfx::ui::about::entry{"Holger Sinn", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Holger-Sinn"}, // https://crowdin.com/profile/Holger-Sinn - streamfx::ui::about::entry{"Itukii", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Itukii"}, // https://crowdin.com/profile/Itukii - streamfx::ui::about::entry{"Ivo Sestren Junior", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/IvoSestren"}, // https://crowdin.com/profile/IvoSestren - streamfx::ui::about::entry{"Jeffrey Chapuis", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/ashyni1987"}, // https://crowdin.com/profile/ashyni1987 - streamfx::ui::about::entry{"Jelmer", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Luxizzle"}, // https://crowdin.com/profile/Luxizzle - streamfx::ui::about::entry{"Jens Fischer", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/JensFZ"}, // https://crowdin.com/profile/JensFZ - streamfx::ui::about::entry{"Jessy HACHET", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/jessy.hachet"}, // https://crowdin.com/profile/jessy.hachet - streamfx::ui::about::entry{"Job Diógenes Ribeiro Borges", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/jobdiogenes"}, // https://crowdin.com/profile/jobdiogenes - streamfx::ui::about::entry{"Kim Bech", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/kimbech"}, // https://crowdin.com/profile/kimbech - streamfx::ui::about::entry{"Kokosnuss.exe", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/KokosnussDEV"}, // https://crowdin.com/profile/KokosnussDEV - streamfx::ui::about::entry{"Krit789", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Krit789"}, // https://crowdin.com/profile/Krit789 - streamfx::ui::about::entry{"Kurozumi", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Kurozumi"}, // https://crowdin.com/profile/Kurozumi - streamfx::ui::about::entry{ - "LANCERRR", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/dongxujiayou88"}, // https://crowdin.com/profile/dongxujiayou88 - streamfx::ui::about::entry{"Leonardo Fries", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/LeoNerdinho"}, // https://crowdin.com/profile/LeoNerdinho - streamfx::ui::about::entry{"Lifeely", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Lifeely"}, // https://crowdin.com/profile/Lifeely - streamfx::ui::about::entry{"Loïc", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Ozachi"}, // https://crowdin.com/profile/Ozachi - streamfx::ui::about::entry{"LucN31", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/LucN31"}, // https://crowdin.com/profile/LucN31 - streamfx::ui::about::entry{"Léo Roubaud", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/hydargos"}, // https://crowdin.com/profile/hydargos - streamfx::ui::about::entry{"Maciej4535", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Maciej4535"}, // https://crowdin.com/profile/Maciej4535 - streamfx::ui::about::entry{"Marco Túlio Pires", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/mtrpires"}, // https://crowdin.com/profile/mtrpires - streamfx::ui::about::entry{"Martin Hybner", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/hybner"}, // https://crowdin.com/profile/hybner - streamfx::ui::about::entry{"Michael Fabian Dirks", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Xaymar"}, // https://crowdin.com/profile/Xaymar - streamfx::ui::about::entry{"Mikhail", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Migelius74"}, // https://crowdin.com/profile/Migelius74 - streamfx::ui::about::entry{"MkHere-YT", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/MkHere"}, // https://crowdin.com/profile/MkHere - streamfx::ui::about::entry{"Mnr. Volkstaat", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/malapradex"}, // https://crowdin.com/profile/malapradex - streamfx::ui::about::entry{"Monsteer", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Monsteer"}, // https://crowdin.com/profile/Monsteer - streamfx::ui::about::entry{"Mr Gohst", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Gohst"}, // https://crowdin.com/profile/Gohst - streamfx::ui::about::entry{"NOYB", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/NOYB"}, // https://crowdin.com/profile/NOYB - streamfx::ui::about::entry{"Nanito Morillas", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/hellnano"}, // https://crowdin.com/profile/hellnano - streamfx::ui::about::entry{"Nikola Perović", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Fooftilly"}, // https://crowdin.com/profile/Fooftilly - streamfx::ui::about::entry{"Nooody FR", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/nooodyfr"}, // https://crowdin.com/profile/nooodyfr - streamfx::ui::about::entry{"Origami", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Origami"}, // https://crowdin.com/profile/Origami - streamfx::ui::about::entry{"Peter Grindem", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/1pete1"}, // https://crowdin.com/profile/1pete1 - streamfx::ui::about::entry{"Proryanator", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Proryanator"}, // https://crowdin.com/profile/Proryanator - streamfx::ui::about::entry{ - "Renaud G.", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/obiwankennedy"}, // https://crowdin.com/profile/obiwankennedy - streamfx::ui::about::entry{ - "Richie Bendall", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/richiebendall"}, // https://crowdin.com/profile/richiebendall - streamfx::ui::about::entry{"Romeo Bunić", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Romz"}, // https://crowdin.com/profile/Romz - streamfx::ui::about::entry{"SDUX1s44c", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/SDUX1s44c"}, // https://crowdin.com/profile/SDUX1s44c - streamfx::ui::about::entry{"SKYQWER", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/mine17288"}, // https://crowdin.com/profile/mine17288 - streamfx::ui::about::entry{ - "SMG music display", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/SMGMusicDisplay"}, // https://crowdin.com/profile/SMGMusicDisplay - streamfx::ui::about::entry{"Sade", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Sade"}, // https://crowdin.com/profile/Sade - streamfx::ui::about::entry{"Sandschi", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/sandschi"}, // https://crowdin.com/profile/sandschi - streamfx::ui::about::entry{"ScottInTokyo", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/ScottInTokyo"}, // https://crowdin.com/profile/ScottInTokyo - streamfx::ui::about::entry{"StanislavPro", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/StanislavPro"}, // https://crowdin.com/profile/StanislavPro - streamfx::ui::about::entry{"StarFang208", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/StarFang208"}, // https://crowdin.com/profile/StarFang208 - streamfx::ui::about::entry{"Store", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/HelaBasa"}, // https://crowdin.com/profile/HelaBasa - streamfx::ui::about::entry{"Syskoh", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Syskoh"}, // https://crowdin.com/profile/Syskoh - streamfx::ui::about::entry{ - "Szymon Szewc", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/szymonszewcjr"}, // https://crowdin.com/profile/szymonszewcjr - streamfx::ui::about::entry{"TOWUK", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/towuk118"}, // https://crowdin.com/profile/towuk118 - streamfx::ui::about::entry{"ThePooN", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/ThePooN"}, // https://crowdin.com/profile/ThePooN - streamfx::ui::about::entry{"Thom Knepper", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/MrKnepp"}, // https://crowdin.com/profile/MrKnepp - streamfx::ui::about::entry{"Tim Cordes", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/t1mc0rd35"}, // https://crowdin.com/profile/t1mc0rd35 - streamfx::ui::about::entry{"TonyWin Somprasong", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/mga1627"}, // https://crowdin.com/profile/mga1627 - streamfx::ui::about::entry{"Tuna", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/zentoryny"}, // https://crowdin.com/profile/zentoryny - streamfx::ui::about::entry{"Vane Brain", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/vanebrain3"}, // https://crowdin.com/profile/vanebrain3 - streamfx::ui::about::entry{"Viginox", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Viginox"}, // https://crowdin.com/profile/Viginox - streamfx::ui::about::entry{"WhiteyChannel", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/zvd.pro"}, // https://crowdin.com/profile/zvd.pro - streamfx::ui::about::entry{"WoWnik", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/wownik98"}, // https://crowdin.com/profile/wownik98 - streamfx::ui::about::entry{"Yoinks DBD", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/izzyfazt"}, // https://crowdin.com/profile/izzyfazt - streamfx::ui::about::entry{"Yurlyn", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Yurlyn"}, // https://crowdin.com/profile/Yurlyn - streamfx::ui::about::entry{"Zero Team", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/ZERO_TEAM"}, // https://crowdin.com/profile/ZERO_TEAM - streamfx::ui::about::entry{"Zoop", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Zoop"}, // https://crowdin.com/profile/Zoop - streamfx::ui::about::entry{"erichardouin", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/erichardouin"}, // https://crowdin.com/profile/erichardouin - streamfx::ui::about::entry{"exeldro", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/exeldro"}, // https://crowdin.com/profile/exeldro - streamfx::ui::about::entry{"itsolutek", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/itsolutek"}, // https://crowdin.com/profile/itsolutek - streamfx::ui::about::entry{"jh KIm", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/kkhmn1"}, // https://crowdin.com/profile/kkhmn1 - streamfx::ui::about::entry{ - "lukazivanovic", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/lukazivanovic"}, // https://crowdin.com/profile/lukazivanovic - streamfx::ui::about::entry{"mochaaP", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/mochaaP"}, // https://crowdin.com/profile/mochaaP - streamfx::ui::about::entry{"mudse", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/mudse"}, // https://crowdin.com/profile/mudse - streamfx::ui::about::entry{"multi.flexi", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/multi.flexi"}, // https://crowdin.com/profile/multi.flexi - streamfx::ui::about::entry{"mwessen", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/sh3ph3r6"}, // https://crowdin.com/profile/sh3ph3r6 - streamfx::ui::about::entry{"ozaki", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/OzakIOne"}, // https://crowdin.com/profile/OzakIOne - streamfx::ui::about::entry{"petro770", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/petro770"}, // https://crowdin.com/profile/petro770 - streamfx::ui::about::entry{"rufus20145", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/rufus20145"}, // https://crowdin.com/profile/rufus20145 - streamfx::ui::about::entry{"sasagar", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/sasagar"}, // https://crowdin.com/profile/sasagar - streamfx::ui::about::entry{"sasha2002", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/sasha2002"}, // https://crowdin.com/profile/sasha2002 - streamfx::ui::about::entry{"saygo1125", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/saygo1125"}, // https://crowdin.com/profile/saygo1125 - streamfx::ui::about::entry{"shugen002", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/shugen002"}, // https://crowdin.com/profile/shugen002 - streamfx::ui::about::entry{"spring jungle", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/springjungle"}, // https://crowdin.com/profile/springjungle - streamfx::ui::about::entry{"tpo0508", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/tpo0508"}, // https://crowdin.com/profile/tpo0508 - streamfx::ui::about::entry{"tytan652", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/tytan652"}, // https://crowdin.com/profile/tytan652 - streamfx::ui::about::entry{ - "wwj402_github", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/wwj402_github"}, // https://crowdin.com/profile/wwj402_github - streamfx::ui::about::entry{"Anonymous User", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/xaymarsdaddy"}, // https://crowdin.com/profile/xaymarsdaddy - streamfx::ui::about::entry{"Вадим Казанцев", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/Rutboy"}, // https://crowdin.com/profile/Rutboy - streamfx::ui::about::entry{"Вадим Якшин", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/tayler2013"}, // https://crowdin.com/profile/tayler2013 - streamfx::ui::about::entry{ - "Денис Полозихин", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/denispolozihin"}, // https://crowdin.com/profile/denispolozihin - streamfx::ui::about::entry{ - "Дмитрий Балуев", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/darkinsonic13"}, // https://crowdin.com/profile/darkinsonic13 - streamfx::ui::about::entry{"Евгений Шестяков", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/anfogor"}, // https://crowdin.com/profile/anfogor - streamfx::ui::about::entry{"十六夜楓", streamfx::ui::about::role_type::TRANSLATOR, "", - "https://crowdin.com/profile/fy1208557958"}, // https://crowdin.com/profile/fy1208557958 - - // Separator - streamfx::ui::about::entry{"", streamfx::ui::about::role_type::THANKYOU, "", ""}, - - // Creators - streamfx::ui::about::entry{"Andilippi", streamfx::ui::about::role_type::CREATOR, "", - "https://www.youtube.com/channel/UCp70l75kpG3ISyxpIsL6hfQ"}, - streamfx::ui::about::entry{"Axelle", streamfx::ui::about::role_type::CREATOR, "", - "https://www.twitch.tv/axelle123"}, - streamfx::ui::about::entry{"EposVox", streamfx::ui::about::role_type::CREATOR, "", - "https://www.youtube.com/channel/UCRBHiacaQb5S70pljtJYB2g"}, - streamfx::ui::about::entry{"Nordern", streamfx::ui::about::role_type::CREATOR, "", - "https://www.youtube.com/channel/UCX2I5pSP-b-iD8sPGiCO1dA"}, -}; - streamfx::ui::about::about() : QDialog(reinterpret_cast(obs_frontend_get_main_window())) { + std::deque entries; + + // Set-up UI. setupUi(this); + setWindowFlag(Qt::WindowContextHelpButtonHint, false); // Remove Help button. + content->setSizePolicy(QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Maximum); - // Remove some extra styling. - setWindowFlag(Qt::WindowContextHelpButtonHint, false); // Remove the unimplemented help button. + // Create a uniform + std::mt19937_64 generator; + std::uniform_int_distribution rnd; - // Random thing - auto rnd = std::uniform_int_distribution(size_t(0), _thankyous.size() - 1); - std::mt19937_64 rnde; - - // Thank every single helper. - bool column_selector = false; - size_t row_selector = 0; - QGridLayout* content_layout = dynamic_cast(content->layout()); - for (const auto& entry : _entries) { - if (entry.role == role_type::SPACER) { - row_selector += 2; - column_selector = 0; - - // Add a separator line. - auto separator = new QFrame(content); - { - auto sp = separator->sizePolicy(); - sp.setVerticalPolicy(QSizePolicy::Fixed); - separator->setSizePolicy(sp); - } - separator->setFrameShape(QFrame::HLine); - separator->setFrameShadow(QFrame::Sunken); - separator->setMaximumHeight(1); - separator->setMinimumHeight(1); - separator->setFixedHeight(1); - separator->setLineWidth(1); - content_layout->addWidget(separator, static_cast(row_selector - 1), 0, 1, 2); - content_layout->setRowStretch(static_cast(row_selector - 1), 0); - } else if (entry.role == role_type::THANKYOU) { - row_selector += 2; - column_selector = 0; - - auto element = new QLabel(content); - - auto elrnd = rnd(rnde); - element->setPixmap(QPixmap(_thankyous.at(elrnd).data())); - - element->setScaledContents(true); - element->setFixedSize(384, 384); - - content_layout->addWidget(element, static_cast(row_selector - 1), 0, 1, 2, - Qt::AlignTop | Qt::AlignHCenter); - content_layout->setRowStretch(static_cast(row_selector - 1), 0); - } else { - streamfx::ui::about_entry* v = new streamfx::ui::about_entry(content, entry); - - content_layout->addWidget(v, static_cast(row_selector), column_selector ? 1 : 0); - content_layout->setRowStretch(static_cast(row_selector), 0); - - if (column_selector) { - row_selector++; - } - column_selector = !column_selector; + // Load entries from 'thanks.json' + try { + auto file = streamfx::data_file_path("thanks.json"); + D_LOG_DEBUG("Attempting to load '%s'...", file.generic_string().c_str()); + if (!std::filesystem::exists(file)) { + // Crash if this file is missing. + throw std::runtime_error("File 'thanks.json' is missing."); } + + std::ifstream fils{file}; + if (fils.bad() || fils.eof()) { + // Crash if this file is corrupt. + throw std::runtime_error("File 'thanks.json' is corrupted."); + } + + auto data = nlohmann::json::parse(fils); + if (auto iter = data.find("contributor"); iter != data.end()) { + D_LOG_DEBUG(" Found %" PRIu64 " contributor entries.", iter->size()); + auto kvs = iter->items(); + for (auto kv : kvs) { + D_LOG_DEBUG(" '%s' => '%s'", kv.key().c_str(), kv.value().get().c_str()); + entries.push_back( + ui::about::entry{kv.key(), role_type::CONTRIBUTOR, "", kv.value().get()}); + } + } + if (auto iter = data.find("translator"); iter != data.end()) { + D_LOG_DEBUG(" Found %" PRIu64 " translator entries.", iter->size()); + auto kvs = iter->items(); + for (auto kv : kvs) { + D_LOG_DEBUG(" '%s' => '%s'", kv.key().c_str(), kv.value().get().c_str()); + entries.push_back(ui::about::entry{kv.key(), role_type::TRANSLATOR, "", kv.value().get()}); + } + } + if (auto iter = data.find("supporter"); iter != data.end()) { + auto data2 = *iter; + if (auto iter2 = data2.find("github"); iter2 != data2.end()) { + D_LOG_DEBUG(" Found %" PRIu64 " GitHub supporter entries.", iter2->size()); + auto kvs = iter2->items(); + for (auto kv : kvs) { + D_LOG_DEBUG(" '%s' => '%s'", kv.key().c_str(), kv.value().get().c_str()); + entries.push_back( + ui::about::entry{kv.key(), role_type::SUPPORTER, "GitHub", kv.value().get()}); + } + } + if (auto iter2 = data2.find("patreon"); iter2 != data2.end()) { + D_LOG_DEBUG(" Found %" PRIu64 " Patreon supporter entries.", iter2->size()); + auto kvs = iter2->items(); + for (auto kv : kvs) { + D_LOG_DEBUG(" '%s' => '%s'", kv.key().c_str(), kv.value().get().c_str()); + entries.push_back( + ui::about::entry{kv.key(), role_type::SUPPORTER, "Patreon", kv.value().get()}); + } + } + } + } catch (const std::exception& ex) { + D_LOG_ERROR("Loading '%s' failed with error: %s", "thanks.json", ex.what()); + throw std::runtime_error("File 'thanks.json' is invalid."); } + + // Build a grid of random entries. { - row_selector++; - auto padder = new QFrame(content); - { - auto sp = padder->sizePolicy(); + QGridLayout* layout = dynamic_cast(content->layout()); + int row = 0; + int column = 0; + int thanks = 0; + int spacer = 0; + + // Fix columns being stretched for no reason. + layout->setColumnStretch(0, 1); + layout->setColumnStretch(1, 1); + + // Randomize the list. + std::shuffle(entries.begin(), entries.end(), generator); + for (auto entry : entries) { + // Create a new entry. + streamfx::ui::about_entry* v = new streamfx::ui::about_entry(content, entry); + layout->addWidget(v, row, column); + layout->setRowStretch(row, 0); + + // Proceed down the grid. + column += 1; + if (column >= 2) { + column = 0; + row += 1; + thanks += 1; + spacer += 1; + + if (thanks % 9 == 8) { // "Thank you" every 8 rows. + auto image = new QLabel(content); + auto idx = rnd(generator) % _thankyous.size(); + image->setPixmap(QPixmap(_thankyous.at(idx).data())); + image->setScaledContents(true); + image->setFixedSize(384, 384); + layout->addWidget(image, row, 0, 1, 2, Qt::AlignTop | Qt::AlignHCenter); + layout->setRowStretch(row, 0); + + thanks = 0; + row += 1; + } else if (spacer % 6 == 5) { // Spacer every 5 rows. + auto separator = new QFrame(content); + separator->setFrameShape(QFrame::HLine); + separator->setFrameShadow(QFrame::Sunken); + separator->setMaximumHeight(1); + separator->setMinimumHeight(1); + separator->setFixedHeight(1); + separator->setLineWidth(1); + { + auto sp = separator->sizePolicy(); + sp.setVerticalPolicy(QSizePolicy::Fixed); + separator->setSizePolicy(sp); + } + layout->addWidget(separator, row, 0, 1, 2); + layout->setRowStretch(row, 0); + + spacer = 0; + row += 1; + } + } + } + + { // Fix weird automatic scaling done by Qt at the end of the list. + if (column != 0) { + row += 1; + column = 0; + } + + auto padder = new QFrame(content); + auto sp = padder->sizePolicy(); sp.setVerticalPolicy(QSizePolicy::Minimum); sp.setVerticalStretch(1); padder->setSizePolicy(sp); + padder->setObjectName("PaddleMeDaddy"); + padder->setMaximumHeight(QWIDGETSIZE_MAX); + padder->setMinimumHeight(1); + padder->setFrameShape(QFrame::NoFrame); + layout->addWidget(padder, row, 0, 1, 2); + layout->setRowStretch(row, std::numeric_limits::max()); } - padder->setObjectName("PaddleMeDaddy"); - padder->setMaximumHeight(QWIDGETSIZE_MAX); - padder->setMinimumHeight(1); - padder->setFrameShape(QFrame::NoFrame); - content_layout->addWidget(padder, static_cast(row_selector), 0, 1, 2); - content_layout->setRowStretch(static_cast(row_selector), 9999); } - content_layout->setColumnStretch(0, 1); - content_layout->setColumnStretch(1, 1); - content->setSizePolicy(QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Maximum); - // Update the Version information. version->setText(STREAMFX_VERSION_STRING); diff --git a/source/ui/ui-about.hpp b/source/ui/ui-about.hpp index f4fa53c3..aaae9b7a 100644 --- a/source/ui/ui-about.hpp +++ b/source/ui/ui-about.hpp @@ -37,12 +37,9 @@ namespace streamfx::ui { public: enum class role_type : int32_t { NONE, - SPACER, - THANKYOU, CONTRIBUTOR, TRANSLATOR, SUPPORTER, - CREATOR, }; struct entry { diff --git a/ui/about-entry.ui b/ui/about-entry.ui index 9854495e..d3dbccea 100644 --- a/ui/about-entry.ui +++ b/ui/about-entry.ui @@ -65,13 +65,15 @@ QWidget[objectName="title"] { 14 - 75 - true - PreferAntialias + + QWidget { + font-family: "MS Shell Dlg 2", "MS Gothic", "Malgun Gothic"; +} + - Supporter Name + Name Qt::AlignCenter @@ -92,7 +94,7 @@ QWidget[objectName="title"] { - Supporter Title + Title Qt::AlignCenter diff --git a/ui/about.ui b/ui/about.ui index 4f3f4a0e..a7a902a5 100644 --- a/ui/about.ui +++ b/ui/about.ui @@ -29,6 +29,7 @@ QWidget { background: transparent; color: hsl(0, 0%, 100%); + font-family: "MS Shell Dlg 2", "MS Gothic", "Malgun Gothic"; } QWidget[objectName="About"], @@ -36,10 +37,23 @@ QWidget[objectName="contentContainer"], QWidget[objectName="content"] { background: hsl(0, 0%, 10%); border: 0; + font-family: "MS Shell Dlg 2", "MS Gothic", "Malgun Gothic"; } QWidget[objectName="PaddleMeDaddy"] { background: hsl(0, 0%, 10%); +} + +a, +a:link, +a:visited { + color: hsl(200, 100%, 50%); + font-family: "MS Shell Dlg 2", "MS Gothic", "Malgun Gothic"; +} + +a:hover, +a:focus { + color: hsl(200, 100%, 70%); }