changeset 305:91ac90a34003

core/time: remove Duration class, use regular functions instead this class was pretty useless anyway
author Paper <paper@paper.us.eu.org>
date Sun, 19 May 2024 15:56:20 -0400
parents 2115488eb302
children f4538a4c91ba
files include/core/time.h include/gui/dialog/information.h src/core/anime.cc src/core/time.cc src/gui/dialog/information.cc src/gui/pages/anime_list.cc src/gui/pages/search.cc src/gui/pages/statistics.cc src/gui/theme.cc src/gui/widgets/sidebar.cc src/services/anilist.cc
diffstat 11 files changed, 132 insertions(+), 150 deletions(-) [+]
line wrap: on
line diff
--- a/include/core/time.h	Mon May 13 17:02:35 2024 -0400
+++ b/include/core/time.h	Sun May 19 15:56:20 2024 -0400
@@ -5,19 +5,17 @@
 #include <string>
 namespace Time {
 
-class Duration {
-public:
-	Duration(int64_t l);
-	int64_t InSeconds();
-	int64_t InMinutes();
-	int64_t InHours();
-	int64_t InDays();
-	std::string AsRelativeString();
+/* this is in SECONDS */
+using Timestamp = uint64_t;
 
-private:
-	int64_t length;
+enum class Units {
+	Seconds,
+	Minutes
 };
 
+std::string GetSecondsAsRelativeString(Timestamp length);
+std::string GetSecondsAsAbsoluteString(Units unit_cutoff, Timestamp amount, double unit_in_seconds = 1.0);
+
 int64_t GetSystemTime();
 
 }; // namespace Time
--- a/include/gui/dialog/information.h	Mon May 13 17:02:35 2024 -0400
+++ b/include/gui/dialog/information.h	Sun May 19 15:56:20 2024 -0400
@@ -15,14 +15,14 @@
 		PAGE_MY_LIST
 	};
 
-	InformationDialog(Anime::Anime& anime, std::function<void()> accept = {}, enum Pages page = Pages::PAGE_MAIN_INFO,
+	InformationDialog(Anime::Anime* anime, std::function<void(Anime::Anime*)> accept = {}, enum Pages page = Pages::PAGE_MAIN_INFO,
 	                  QWidget* parent = nullptr);
 
 protected:
 	void showEvent(QShowEvent* event) override;
 
 private:
-	void SaveData(Anime::Anime& anime);
+	void SaveData(Anime::Anime* anime);
 	unsigned int _progress;
 	unsigned int _score;
 	bool _rewatching;
--- a/src/core/anime.cc	Mon May 13 17:02:35 2024 -0400
+++ b/src/core/anime.cc	Sun May 19 15:56:20 2024 -0400
@@ -13,6 +13,8 @@
 #include <vector>
 #include <cassert>
 
+#include <iostream>
+
 namespace Anime {
 
 /* User list data */
--- a/src/core/time.cc	Mon May 13 17:02:35 2024 -0400
+++ b/src/core/time.cc	Sun May 19 15:56:20 2024 -0400
@@ -9,29 +9,37 @@
 
 namespace Time {
 
-Duration::Duration(int64_t l) {
-	length = l;
+static int64_t GetSecondsInMinutes(Timestamp length) {
+	return std::llround(static_cast<double>(length) / 60.0);
 }
 
-std::string Duration::AsRelativeString() {
+static int64_t GetSecondsInHours(Timestamp length) {
+	return std::llround(static_cast<double>(length) / 3600.0);
+}
+
+static int64_t GetSecondsInDays(Timestamp length) {
+	return std::llround(static_cast<double>(length) / 86400.0);
+}
+
+std::string GetSecondsAsRelativeString(Timestamp length) {
 	std::string result;
 
 	auto get = [](int64_t val, const std::string& s, const std::string& p) {
 		return Strings::ToUtf8String(val) + " " + (val == 1 ? s : p);
 	};
 
-	if (InSeconds() < 60)
-		result = get(InSeconds(), "second", "seconds");
-	else if (InMinutes() < 60)
-		result = get(InMinutes(), "minute", "minutes");
-	else if (InHours() < 24)
-		result = get(InHours(), "hour", "hours");
-	else if (InDays() < 28)
-		result = get(InDays(), "day", "days");
-	else if (InDays() < 365)
-		result = get(InDays() / 30, "month", "months");
+	if (length < 60)
+		result = get(length, "second", "seconds");
+	else if (GetSecondsInMinutes(length) < 60)
+		result = get(GetSecondsInMinutes(length), "minute", "minutes");
+	else if (GetSecondsInHours(length) < 24)
+		result = get(GetSecondsInHours(length), "hour", "hours");
+	else if (GetSecondsInDays(length) < 28)
+		result = get(GetSecondsInDays(length), "day", "days");
+	else if (GetSecondsInDays(length) < 365)
+		result = get(GetSecondsInDays(length) / 30, "month", "months");
 	else
-		result = get(InDays() / 365, "year", "years");
+		result = get(GetSecondsInDays(length) / 365, "year", "years");
 
 	if (length < 0)
 		result = "In " + result;
@@ -41,26 +49,51 @@
 	return result;
 }
 
-int64_t Duration::InSeconds() {
-	return length;
-}
+std::string GetSecondsAsAbsoluteString(Units unit_cutoff, Timestamp amount, double unit_in_seconds) {
+	/* avoid calculating this twice */
+	const double years_conv = (31556952.0 / unit_in_seconds);
+	const double months_conv = (2629746.0 / unit_in_seconds);
+	const double days_conv = (86400.0 / unit_in_seconds);
+	const double hours_conv = (3600.0 / unit_in_seconds);
+	const double minutes_conv = (60.0 / unit_in_seconds);
+	const double seconds_conv = (1.0 / unit_in_seconds);
+
+	const int years = amount / years_conv;
+	const int months = std::fmod(amount, years_conv) / months_conv;
+	const int days = std::fmod(amount, months_conv) / days_conv;
+	const int hours = std::fmod(amount, days_conv) / hours_conv;
+	const int minutes = std::fmod(amount, hours_conv) / minutes_conv;
+	const int seconds = std::fmod(amount, minutes_conv) / seconds_conv;
 
-int64_t Duration::InMinutes() {
-	return std::llround(static_cast<double>(length) / 60.0);
-}
+	const auto add_time_segment = [](std::ostringstream& str, int64_t amount, const std::string_view& singular,
+	                                 const std::string_view& plural, bool always = false) {
+		if (amount > 0 || always)
+			str << amount << ((amount == 1) ? singular : plural);
+	};
+
+	/* for now, this function is very en_US specific */
 
-int64_t Duration::InHours() {
-	return std::llround(static_cast<double>(length) / 3600.0);
-}
+	std::ostringstream string;
+	add_time_segment(string, years, " year ", " years ");
+	add_time_segment(string, months, " month ", " months ");
+	add_time_segment(string, days, " day ", " days ");
+	add_time_segment(string, hours, " hour ", " hours ");
 
-int64_t Duration::InDays() {
-	return std::llround(static_cast<double>(length) / 86400.0);
+	if (unit_cutoff == Units::Minutes) {
+		add_time_segment(string, minutes, " minute", " minutes", true);
+		return string.str();
+	} else {
+		add_time_segment(string, minutes, " minute ", " minutes ");
+	}
+
+	add_time_segment(string, seconds, " second", " seconds", true);
+	return string.str();
 }
 
 int64_t GetSystemTime() {
 	static_assert(sizeof(int64_t) >= sizeof(time_t));
 	time_t t = std::time(nullptr);
-	return *reinterpret_cast<int64_t*>(&t);
+	return reinterpret_cast<int64_t>(t);
 }
 
 } // namespace Time
--- a/src/gui/dialog/information.cc	Mon May 13 17:02:35 2024 -0400
+++ b/src/gui/dialog/information.cc	Sun May 19 15:56:20 2024 -0400
@@ -25,28 +25,29 @@
 #include <QVBoxLayout>
 
 #include <functional>
+#include <iostream>
 #ifdef WIN32
 #	include "sys/win32/dark_theme.h"
 #endif
 
 /* TODO: Taiga disables rendering of the tab widget entirely when the anime is not part of a list,
    which sucks. Think of a better way to implement this later. */
-void InformationDialog::SaveData(Anime::Anime& anime) {
-	if (!anime.IsInUserList())
+void InformationDialog::SaveData(Anime::Anime* anime) {
+	if (!anime->IsInUserList())
 		return;
 
-	anime.SetUserProgress(_progress);
-	anime.SetUserScore(_score);
-	anime.SetUserIsRewatching(_rewatching);
-	anime.SetUserStatus(_status);
-	anime.SetUserNotes(_notes);
-	anime.SetUserDateStarted(_started);
-	anime.SetUserDateCompleted(_completed);
+	anime->SetUserProgress(_progress);
+	anime->SetUserScore(_score);
+	anime->SetUserIsRewatching(_rewatching);
+	anime->SetUserStatus(_status);
+	anime->SetUserNotes(_notes);
+	anime->SetUserDateStarted(_started);
+	anime->SetUserDateCompleted(_completed);
 }
 
-InformationDialog::InformationDialog(Anime::Anime& anime, std::function<void()> accept, enum Pages page,
+InformationDialog::InformationDialog(Anime::Anime* anime, std::function<void(Anime::Anime*)> accept, enum Pages page,
                                      QWidget* parent)
-    : QDialog(parent) {
+	: QDialog(parent) {
 	/* ack. lots of brackets here, but MUCH, MUCH MUCH better than what it used to be */
 	setFixedSize(842, 613);
 	setWindowTitle(tr("Anime Information"));
@@ -71,7 +72,7 @@
 			QVBoxLayout* sidebar_layout = new QVBoxLayout(sidebar);
 			{
 				/* Poster */
-				Poster* poster = new Poster(anime, sidebar);
+				Poster* poster = new Poster(*anime, sidebar);
 				sidebar_layout->addWidget(poster);
 			}
 			sidebar_layout->setContentsMargins(0, 0, 0, 0);
@@ -89,7 +90,7 @@
 			{
 				/* Anime title */
 				TextWidgets::Title* anime_title =
-				    new TextWidgets::Title(Strings::ToQString(anime.GetUserPreferredTitle()), main_widget);
+				    new TextWidgets::Title(Strings::ToQString(anime->GetUserPreferredTitle()), main_widget);
 				main_layout->addWidget(anime_title);
 			}
 
@@ -100,11 +101,11 @@
 
 				{
 					/* Main information */
-					AnimeInfoWidget* main_information_widget = new AnimeInfoWidget(anime, tabbed_widget);
+					AnimeInfoWidget* main_information_widget = new AnimeInfoWidget(*anime, tabbed_widget);
 					tabbed_widget->addTab(main_information_widget, tr("Main information"));
 				}
 
-				if (anime.IsInUserList()) {
+				if (anime->IsInUserList()) {
 					/* My list and settings */
 					QWidget* settings_widget = new QWidget(tabbed_widget);
 					settings_widget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
@@ -143,9 +144,9 @@
 								QSpinBox* spin_box = new QSpinBox(section);
 								connect(spin_box, QOverload<int>::of(&QSpinBox::valueChanged), this,
 								        [this](int i) { _progress = i; });
-								spin_box->setRange(0, anime.GetEpisodes());
+								spin_box->setRange(0, anime->GetEpisodes());
 								spin_box->setSingleStep(1);
-								spin_box->setValue(_progress = anime.GetUserProgress());
+								spin_box->setValue(_progress = anime->GetUserProgress());
 								spin_box->setFixedWidth(LAYOUT_ITEM_WIDTH);
 								layout->addWidget(spin_box, 1, 0);
 							}
@@ -155,8 +156,8 @@
 								QCheckBox* checkbox = new QCheckBox(tr("Rewatching"));
 								connect(checkbox, QOverload<int>::of(&QCheckBox::stateChanged), this,
 								        [this](int state) { _rewatching = (state == Qt::Checked); });
-								checkbox->setCheckState((_rewatching = anime.GetUserIsRewatching()) ? Qt::Checked
-								                                                                    : Qt::Unchecked);
+								checkbox->setCheckState((_rewatching = anime->GetUserIsRewatching()) ? Qt::Checked
+								                                                                     : Qt::Unchecked);
 								checkbox->setFixedWidth(LAYOUT_ITEM_WIDTH);
 								layout->addWidget(checkbox, 1, 1);
 							}
@@ -170,9 +171,13 @@
 
 								QComboBox* combo_box = new QComboBox(section);
 
-								for (unsigned int i = 0; i < Anime::ListStatuses.size(); i++)
+								_status = anime->GetUserStatus();
+								for (unsigned int i = 0; i < Anime::ListStatuses.size(); i++) {
 									combo_box->addItem(Strings::ToQString(Translate::ToLocalString(Anime::ListStatuses[i])),
 									                   static_cast<int>(Anime::ListStatuses[i]));
+									if (Anime::ListStatuses[i] == _status)
+										combo_box->setCurrentIndex(i);
+								}
 
 								connect(combo_box, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
 								        [this, combo_box](int) {
@@ -180,7 +185,6 @@
 								        });
 
 								/* this should NEVER, EVER, be NOT_IN_LIST */
-								combo_box->setCurrentIndex(static_cast<int>(_status = anime.GetUserStatus()) - 1);
 								combo_box->setFixedWidth(LAYOUT_ITEM_WIDTH);
 								layout->addWidget(combo_box, 1, 0);
 							}
@@ -194,7 +198,7 @@
 								        [this](int i) { _score = i; });
 								spin_box->setRange(0, 100);
 								spin_box->setSingleStep(5);
-								spin_box->setValue(_score = anime.GetUserScore());
+								spin_box->setValue(_score = anime->GetUserScore());
 								spin_box->setFixedWidth(LAYOUT_ITEM_WIDTH);
 								layout->addWidget(spin_box, 1, 1);
 							}
@@ -209,7 +213,7 @@
 								/* this sucks but I don't really want to implement anything smarter :) */
 								_notes = Strings::ToUtf8String(text);
 							});
-							line_edit->setText(Strings::ToQString(_notes = anime.GetUserNotes()));
+							line_edit->setText(Strings::ToQString(_notes = anime->GetUserNotes()));
 							line_edit->setPlaceholderText(tr("Enter your notes about this anime"));
 							layout->addWidget(line_edit, 1, 0);
 						});
@@ -223,10 +227,10 @@
 								connect(date, &OptionalDate::DataChanged, this,
 								        [this](bool enabled, Date date) { _started = enabled ? date : Date(); });
 								date->setFixedWidth(LAYOUT_ITEM_WIDTH);
-								_started = anime.GetUserDateStarted();
+								_started = anime->GetUserDateStarted();
 								if (!_started.IsValid()) {
 									date->SetEnabled(false);
-									_started = anime.GetAirDate();
+									_started = anime->GetAirDate();
 								}
 								date->SetDate(_started);
 								layout->addWidget(date, 1, 0);
@@ -240,10 +244,10 @@
 								connect(date, &OptionalDate::DataChanged, this,
 								        [this](bool enabled, Date date) { _completed = enabled ? date : Date(); });
 								date->setFixedWidth(LAYOUT_ITEM_WIDTH);
-								_completed = anime.GetUserDateCompleted();
+								_completed = anime->GetUserDateCompleted();
 								if (!_completed.IsValid()) {
 									date->SetEnabled(false);
-									_completed = anime.GetAirDate();
+									_completed = anime->GetAirDate();
 								}
 								date->SetDate(_completed);
 								layout->addWidget(date, 1, 1);
@@ -301,9 +305,9 @@
 	{
 		/* Dialog box buttons */
 		QDialogButtonBox* button_box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
-		connect(button_box, &QDialogButtonBox::accepted, this, [this, accept, &anime] {
+		connect(button_box, &QDialogButtonBox::accepted, this, [this, accept, anime] {
 			SaveData(anime);
-			accept();
+			accept(anime);
 			QDialog::accept();
 		});
 		connect(button_box, &QDialogButtonBox::rejected, this, &QDialog::reject);
--- a/src/gui/pages/anime_list.cc	Mon May 13 17:02:35 2024 -0400
+++ b/src/gui/pages/anime_list.cc	Sun May 19 15:56:20 2024 -0400
@@ -140,7 +140,7 @@
 				case AL_SEASON: {
 					std::optional<unsigned int> year = list[index.row()].GetAirDate().GetYear();
 					if (!year)
-						return "Unknown Unknown";
+						return tr("Unknown Unknown");
 					return Strings::ToQString(Translate::ToLocalString(list[index.row()].GetSeason()) + " " +
 											  Strings::ToUtf8String(year.value()));
 				}
@@ -150,8 +150,7 @@
 				case AL_UPDATED: {
 					if (list[index.row()].GetUserTimeUpdated() == 0)
 						return QString("-");
-					Time::Duration duration(Time::GetSystemTime() - list[index.row()].GetUserTimeUpdated());
-					return Strings::ToQString(duration.AsRelativeString());
+					return Strings::ToQString(Time::GetSecondsAsRelativeString(Time::GetSystemTime() - list[index.row()].GetUserTimeUpdated()));
 				}
 				case AL_NOTES: return Strings::ToQString(list[index.row()].GetUserNotes());
 				default: return "";
@@ -203,11 +202,9 @@
 
 	list.clear();
 
-	for (const auto& a : Anime::db.items) {
-		if (a.second.IsInUserList() && a.second.GetUserStatus() == status) {
+	for (const auto& a : Anime::db.items)
+		if (a.second.IsInUserList() && a.second.GetUserStatus() == status)
 			list.push_back(a.second);
-		}
-	}
 
 	endResetModel();
 }
@@ -315,7 +312,7 @@
 	menu->addAction(tr("Information"), [this, animes] {
 		for (auto& anime : animes) {
 			InformationDialog* dialog = new InformationDialog(
-				*anime, [this, anime] { UpdateAnime(anime->GetId()); }, InformationDialog::PAGE_MAIN_INFO, this);
+				anime, [this](Anime::Anime* anime) { UpdateAnime(anime->GetId()); }, InformationDialog::PAGE_MAIN_INFO, this);
 
 			dialog->show();
 			dialog->raise();
@@ -327,7 +324,7 @@
 	menu->addAction(tr("Edit"), [this, animes] {
 		for (auto& anime : animes) {
 			InformationDialog* dialog = new InformationDialog(
-				*anime, [this, anime] { UpdateAnime(anime->GetId()); }, InformationDialog::PAGE_MY_LIST, this);
+				anime, [this](Anime::Anime* anime) { UpdateAnime(anime->GetId()); }, InformationDialog::PAGE_MY_LIST, this);
 
 			dialog->show();
 			dialog->raise();
@@ -358,7 +355,7 @@
 	Anime::Anime* anime = source_model->GetAnimeFromIndex(index);
 
 	InformationDialog* dialog = new InformationDialog(
-		*anime, [this, anime] { UpdateAnime(anime->GetId()); }, InformationDialog::PAGE_MAIN_INFO, this);
+		anime, [this](Anime::Anime* anime) { UpdateAnime(anime->GetId()); }, InformationDialog::PAGE_MAIN_INFO, this);
 
 	dialog->show();
 	dialog->raise();
--- a/src/gui/pages/search.cc	Mon May 13 17:02:35 2024 -0400
+++ b/src/gui/pages/search.cc	Sun May 19 15:56:20 2024 -0400
@@ -196,8 +196,8 @@
 	menu->addAction(tr("Information"), [this, animes] {
 		for (auto& anime : animes) {
 			InformationDialog* dialog = new InformationDialog(
-			    *anime,
-			    [this, anime] {
+			    anime,
+			    [this](Anime::Anime* anime) {
 				    // UpdateAnime(anime->GetId());
 			    },
 			    InformationDialog::PAGE_MAIN_INFO, this);
@@ -235,8 +235,8 @@
 	Anime::Anime* anime = model->GetAnimeFromIndex(index);
 
 	InformationDialog* dialog = new InformationDialog(
-	    *anime,
-	    [this, anime] {
+	    anime,
+	    [this](Anime::Anime* anime) {
 		    // UpdateAnime(anime->GetId());
 	    },
 	    InformationDialog::PAGE_MAIN_INFO, this);
--- a/src/gui/pages/statistics.cc	Mon May 13 17:02:35 2024 -0400
+++ b/src/gui/pages/statistics.cc	Sun May 19 15:56:20 2024 -0400
@@ -2,6 +2,7 @@
 #include "core/anime_db.h"
 #include "core/session.h"
 #include "core/strings.h"
+#include "core/time.h"
 #include "gui/pages/anime_list.h"
 #include "gui/widgets/graph.h"
 #include "gui/widgets/text.h"
@@ -16,11 +17,6 @@
 #include <cmath>
 #include <sstream>
 
-enum class TimeUnits {
-	SECONDS,
-	MINUTES
-};
-
 StatisticsPage::StatisticsPage(QWidget* parent) : QFrame(parent) {
 	setBackgroundRole(QPalette::Base);
 
@@ -79,54 +75,6 @@
 	UpdateStatistics();
 }
 
-/*  [in] enum TimeUnits unit:
- *       which unit to stop on
- *  [in] int amount:
- *       amount of units to parse
- *  [in, defaults to 1.0] double unit_in_seconds:
- *       equivalent of one of 'amount' in seconds, e.g. minutes would be 60.0
- */
-static std::string TimeToDateString(TimeUnits unit, int amount, double unit_in_seconds = 1.0) {
-	/* avoid calculating this twice */
-	const double years_conv = (31556952.0 / unit_in_seconds);
-	const double months_conv = (2629746.0 / unit_in_seconds);
-	const double days_conv = (86400.0 / unit_in_seconds);
-	const double hours_conv = (3600.0 / unit_in_seconds);
-	const double minutes_conv = (60.0 / unit_in_seconds);
-	const double seconds_conv = (1.0 / unit_in_seconds);
-
-	const int years = amount / years_conv;
-	const int months = std::fmod(amount, years_conv) / months_conv;
-	const int days = std::fmod(amount, months_conv) / days_conv;
-	const int hours = std::fmod(amount, days_conv) / hours_conv;
-	const int minutes = std::fmod(amount, hours_conv) / minutes_conv;
-	const int seconds = std::fmod(amount, minutes_conv) / seconds_conv;
-
-	const auto add_time_segment = [](std::ostringstream& str, int amount, const std::string_view& singular,
-	                                 const std::string_view& plural, bool always = false) {
-		if (amount > 0 || always)
-			str << amount << ((amount == 1) ? singular : plural);
-	};
-
-	/* for now, this function is very en_US specific */
-
-	std::ostringstream string;
-	add_time_segment(string, years, " year ", " years ");
-	add_time_segment(string, months, " month ", " months ");
-	add_time_segment(string, days, " day ", " days ");
-	add_time_segment(string, hours, " hour ", " hours ");
-
-	if (unit == TimeUnits::MINUTES) {
-		add_time_segment(string, minutes, " minute", " minutes", true);
-		return string.str();
-	} else {
-		add_time_segment(string, minutes, " minute ", " minutes ");
-	}
-
-	add_time_segment(string, seconds, " second", " seconds", true);
-	return string.str();
-}
-
 inline int GetTotalWithScore(const int score) {
 	int count = 0;
 	for (const auto& item : Anime::db.items)
@@ -141,8 +89,8 @@
 	QTextStream ts(&string);
 	ts << Anime::db.GetTotalAnimeAmount() << '\n';
 	ts << Anime::db.GetTotalEpisodeAmount() << '\n';
-	ts << Strings::ToQString(TimeToDateString(TimeUnits::MINUTES, Anime::db.GetTotalWatchedAmount(), 60.0)) << '\n';
-	ts << Strings::ToQString(TimeToDateString(TimeUnits::MINUTES, Anime::db.GetTotalPlannedAmount(), 60.0)) << '\n';
+	ts << Strings::ToQString(Time::GetSecondsAsAbsoluteString(Time::Units::Minutes, Anime::db.GetTotalWatchedAmount(), 60.0)) << '\n';
+	ts << Strings::ToQString(Time::GetSecondsAsAbsoluteString(Time::Units::Minutes, Anime::db.GetTotalPlannedAmount(), 60.0)) << '\n';
 	ts << Anime::db.GetAverageScore() << '\n';
 	ts << Anime::db.GetScoreDeviation();
 	_anime_list->GetData()->setText(string);
@@ -152,7 +100,7 @@
 		_score_distribution_graph->AddItem(i, GetTotalWithScore(i));
 
 	string = "";
-	ts << Strings::ToQString(TimeToDateString(TimeUnits::SECONDS, session.uptime() / 1000)) << '\n';
+	ts << Strings::ToQString(Time::GetSecondsAsAbsoluteString(Time::Units::Seconds, session.uptime() / 1000)) << '\n';
 	ts << session.GetRequests();
 	/* Application */
 	// UiUtils::SetPlainTextEditData(application_data, QString::number(session.uptime() / 1000));
--- a/src/gui/theme.cc	Mon May 13 17:02:35 2024 -0400
+++ b/src/gui/theme.cc	Sun May 19 15:56:20 2024 -0400
@@ -93,7 +93,8 @@
 			const QColor black(25, 25, 25);
 			const QColor blue(42, 130, 218);
 
-			QPalette pal(QApplication::style()->standardPalette());
+			QPalette pal;
+
 			pal.setColor(QPalette::Window, darkGray);
 			pal.setColor(QPalette::WindowText, Qt::white);
 			pal.setColor(QPalette::Base, black);
@@ -112,6 +113,7 @@
 			pal.setColor(QPalette::Disabled, QPalette::WindowText, gray);
 			pal.setColor(QPalette::Disabled, QPalette::Text, gray);
 			pal.setColor(QPalette::Disabled, QPalette::Light, darkGray);
+
 			qApp->setPalette(pal);
 
 #ifdef WIN32
@@ -127,7 +129,7 @@
 			break;
 		}
 		default:
-			/* this sucks. */
+			/* this sucks */
 			QPalette pal(QApplication::style()->standardPalette());
 #ifdef WIN32 /* fuck you Qt 6 */
 			pal.setColor(QPalette::Window, QColor(0xF0, 0xF0, 0xF0));
--- a/src/gui/widgets/sidebar.cc	Mon May 13 17:02:35 2024 -0400
+++ b/src/gui/widgets/sidebar.cc	Sun May 19 15:56:20 2024 -0400
@@ -11,7 +11,7 @@
 	setSelectionMode(QAbstractItemView::SingleSelection);
 	setSelectionBehavior(QAbstractItemView::SelectItems);
 	setMouseTracking(true);
-	/* FIXME: is there an easy way to do this with palettes? */
+
 	setStyleSheet("QListWidget::item:disabled { background: transparent }");
 
 	SetBackgroundTransparent(true);
--- a/src/services/anilist.cc	Mon May 13 17:02:35 2024 -0400
+++ b/src/services/anilist.cc	Sun May 19 15:56:20 2024 -0400
@@ -136,17 +136,15 @@
 }
 
 static void ParseTitle(const nlohmann::json& json, Anime::Anime& anime) {
-	nlohmann::json::json_pointer g = "/native"_json_pointer;
-	if (json.contains(g) && json[g].is_string())
-		anime.SetTitle(Anime::TitleLanguage::Native, json[g]);
+	static const std::unordered_map<Anime::TitleLanguage, nlohmann::json::json_pointer> map = {
+		{Anime::TitleLanguage::Native, "/native"_json_pointer},
+		{Anime::TitleLanguage::English, "/english"_json_pointer},
+		{Anime::TitleLanguage::Romaji, "/romaji"_json_pointer},
+	};
 
-	g = "/english"_json_pointer;
-	if (json.contains(g) && json[g].is_string())
-		anime.SetTitle(Anime::TitleLanguage::English, json[g]);
-
-	g = "/romaji"_json_pointer;
-	if (json.contains(g) && json[g].is_string())
-		anime.SetTitle(Anime::TitleLanguage::Romaji, json[g]);
+	for (const auto& [language, ptr] : map)
+		if (json.contains(ptr) && json[ptr].is_string())
+			anime.SetTitle(language, json[ptr]);
 }
 
 static int ParseMediaJson(const nlohmann::json& json) {