diff options
| author | Vaxry <43317083+vaxerski@users.noreply.github.com> | 2025-01-10 19:09:40 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-01-10 18:09:40 +0000 |
| commit | b5fb6110ab1f75440b4b90d09f95d304d8c2080b (patch) | |
| tree | dd1d01b42da490b8e0925b1d913744739d79f9a8 /src/managers/DonationNagManager.cpp | |
| parent | da9252a23e69fc4d34beca73ebcc90b03af0ed2a (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.cpp | 114 |
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 |
