summaryrefslogtreecommitdiff
path: root/src/managers/DonationNagManager.cpp
diff options
context:
space:
mode:
authorVaxry <43317083+vaxerski@users.noreply.github.com>2025-01-10 19:09:40 +0100
committerGitHub <noreply@github.com>2025-01-10 18:09:40 +0000
commitb5fb6110ab1f75440b4b90d09f95d304d8c2080b (patch)
treedd1d01b42da490b8e0925b1d913744739d79f9a8 /src/managers/DonationNagManager.cpp
parentda9252a23e69fc4d34beca73ebcc90b03af0ed2a (diff)
core: Add a periodic donation request (#8981)
Will fire once in december and july. Disableable with `ecosystem:no_donation:nag`
Diffstat (limited to 'src/managers/DonationNagManager.cpp')
-rw-r--r--src/managers/DonationNagManager.cpp114
1 files changed, 114 insertions, 0 deletions
diff --git a/src/managers/DonationNagManager.cpp b/src/managers/DonationNagManager.cpp
new file mode 100644
index 00000000..d7eab9ae
--- /dev/null
+++ b/src/managers/DonationNagManager.cpp
@@ -0,0 +1,114 @@
+#include "DonationNagManager.hpp"
+#include "../debug/Log.hpp"
+#include "VersionKeeperManager.hpp"
+#include "eventLoop/EventLoopManager.hpp"
+#include "../config/ConfigValue.hpp"
+
+#include <chrono>
+#include <format>
+
+#include "../helpers/fs/FsUtils.hpp"
+
+#include <hyprutils/os/Process.hpp>
+using namespace Hyprutils::OS;
+
+constexpr const char* LAST_NAG_FILE_NAME = "lastNag";
+constexpr uint64_t DAY_IN_SECONDS = 3600ULL * 24;
+constexpr uint64_t MONTH_IN_SECONDS = DAY_IN_SECONDS * 30;
+
+struct SNagDatePoint {
+ // Counted from 1, as in Jan 1st is 1, 1
+ // No month-boundaries because I am lazy
+ uint8_t month = 0, dayStart = 0, dayEnd = 0;
+};
+
+// clang-format off
+const std::vector<SNagDatePoint> NAG_DATE_POINTS = {
+ SNagDatePoint {
+ 7, 20, 31,
+ },
+ SNagDatePoint {
+ 12, 1, 28
+ },
+};
+// clang-format on
+
+CDonationNagManager::CDonationNagManager() {
+ static auto PNONAG = CConfigValue<Hyprlang::INT>("ecosystem:no_donation_nag");
+
+ if (g_pVersionKeeperMgr->fired() || *PNONAG)
+ return;
+
+ const auto DATAROOT = NFsUtils::getDataHome();
+
+ if (!DATAROOT)
+ return;
+
+ const auto EPOCH = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
+
+ const auto LASTNAGSTR = NFsUtils::readFileAsString(*DATAROOT + "/" + LAST_NAG_FILE_NAME);
+
+ if (!LASTNAGSTR) {
+ const auto EPOCHSTR = std::format("{}", EPOCH);
+ NFsUtils::writeToFile(*DATAROOT + "/" + LAST_NAG_FILE_NAME, EPOCHSTR);
+ return;
+ }
+
+ uint64_t LAST_EPOCH = 0;
+
+ try {
+ LAST_EPOCH = std::stoull(*LASTNAGSTR);
+ } catch (std::exception& e) {
+ Debug::log(ERR, "DonationNag: Last epoch invalid? Failed to parse \"{}\". Setting to today.", *LASTNAGSTR);
+ const auto EPOCHSTR = std::format("{}", EPOCH);
+ NFsUtils::writeToFile(*DATAROOT + "/" + LAST_NAG_FILE_NAME, EPOCHSTR);
+ return;
+ }
+
+ // don't nag if the last nag was less than a month ago. This is
+ // mostly for first-time nags, as other nags happen in specific time frames shorter than a month
+ if (EPOCH - LAST_EPOCH < MONTH_IN_SECONDS) {
+ Debug::log(LOG, "DonationNag: last nag was {} days ago, too early for a nag.", (int)std::round((EPOCH - LAST_EPOCH) / (double)MONTH_IN_SECONDS));
+ return;
+ }
+
+ if (!NFsUtils::executableExistsInPath("hyprland-donate-screen")) {
+ Debug::log(ERR, "DonationNag: executable doesn't exist, skipping.");
+ return;
+ }
+
+ auto tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
+ auto local = *localtime(&tt);
+
+ const auto MONTH = local.tm_mon + 1;
+ const auto DAY = local.tm_mday;
+
+ for (const auto& nagPoint : NAG_DATE_POINTS) {
+ if (MONTH != nagPoint.month)
+ continue;
+
+ if (DAY < nagPoint.dayStart || DAY > nagPoint.dayEnd)
+ continue;
+
+ Debug::log(LOG, "DonationNag: hit nag month {} days {}-{}, it's {} today, nagging", MONTH, nagPoint.dayStart, nagPoint.dayEnd, DAY);
+
+ m_bFired = true;
+
+ const auto EPOCHSTR = std::format("{}", EPOCH);
+ NFsUtils::writeToFile(*DATAROOT + "/" + LAST_NAG_FILE_NAME, EPOCHSTR);
+
+ g_pEventLoopManager->doLater([] {
+ CProcess proc("hyprland-donate-screen", {});
+ proc.runAsync();
+ });
+
+ break;
+ }
+
+ if (!m_bFired)
+ Debug::log(LOG, "DonationNag: didn't hit any nagging periods");
+}
+
+bool CDonationNagManager::fired() {
+ return m_bFired;
+} \ No newline at end of file