changeset 231:69f4768a820c

chore: merge divergent branches
author Paper <paper@paper.us.eu.org>
date Sat, 13 Jan 2024 09:43:41 -0500
parents 2f5a9247e501 (current diff) d030b30526d5 (diff)
children ff0061e75f0f
files src/core/strings.cc src/track/media.cc
diffstat 18 files changed, 674 insertions(+), 326 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Sat Jan 13 09:42:02 2024 -0500
+++ b/CMakeLists.txt	Sat Jan 13 09:43:41 2024 -0500
@@ -89,6 +89,7 @@
 	src/gui/dialog/settings/services.cc
 	src/gui/dialog/settings/torrents.cc
 	src/gui/dialog/settings/recognition.cc
+	src/gui/dialog/settings/library.cc
 
 	# Translate
 	src/gui/translate/anime.cc
--- a/dep/animia/include/animia/util.h	Sat Jan 13 09:42:02 2024 -0500
+++ b/dep/animia/include/animia/util.h	Sat Jan 13 09:43:41 2024 -0500
@@ -2,6 +2,7 @@
 #define __animia__animia__util_h
 
 #include <string>
+#include <sstream>
 
 namespace animia::internal::util {
 
@@ -12,6 +13,14 @@
 bool TrimLeft(std::string& str, const char* chars);
 bool TrimRight(std::string& str, const char* chars);
 
+template<typename T = int,
+         std::enable_if_t<std::is_integral<T>::value, bool> = true>
+T StringToInt(const std::string& str, T def = 0) {
+	std::istringstream s(str);
+	s >> std::noboolalpha >> def;
+	return def;
+}
+
 } // namespace animia::internal::util
 
-#endif // __animia__animia__util_h
\ No newline at end of file
+#endif // __animia__animia__util_h
--- a/dep/animia/src/win/wayland.cc	Sat Jan 13 09:42:02 2024 -0500
+++ b/dep/animia/src/win/wayland.cc	Sat Jan 13 09:43:41 2024 -0500
@@ -1,6 +1,7 @@
 #include "animia/win/wayland.h"
 #include "animia.h"
 #include "animia/win.h"
+#include "animia/util.h"
 
 #include <cstring>
 #include <iostream>
@@ -90,9 +91,10 @@
 		reinterpret_cast<Window*>(data)->text = title;
 }
 
-static void ext_foreign_handle_handle_identifier(void*, ext_foreign_toplevel_handle_v1*, const char* identifier) {
-	if (identifier)
-		reinterpret_cast<Window*>(data)->id = identifier;
+static void ext_foreign_handle_handle_identifier(void* data, ext_foreign_toplevel_handle_v1* handle, const char* identifier) {
+	if (identifier) {
+		reinterpret_cast<Window*>(data)->id = util::StringToInt(identifier, 0);
+	}
 }
 
 static void ext_foreign_handle_handle_done(void* data, struct ext_foreign_toplevel_handle_v1* handle) {
--- a/include/core/config.h	Sat Jan 13 09:42:02 2024 -0500
+++ b/include/core/config.h	Sat Jan 13 09:43:41 2024 -0500
@@ -9,6 +9,7 @@
 
 #include <string>
 #include <vector>
+#include <set>
 #include <utility>
 
 struct MediaPlayer {
@@ -34,12 +35,9 @@
 			bool highlighted_anime_above_others;
 		} anime_list;
 
-		/* these should preferably be in an
-		   "auth" struct... */
 		struct {
 			struct {
 				std::string auth_token;
-				std::string username;
 				int user_id;
 			} anilist;
 		} auth;
@@ -54,7 +52,8 @@
 		} torrents;
 
 		struct {
-			std::vector<std::string> paths;
+			bool real_time_monitor;
+			std::set<std::string> paths;
 		} library;
 };
 
--- a/include/core/strings.h	Sat Jan 13 09:42:02 2024 -0500
+++ b/include/core/strings.h	Sat Jan 13 09:43:41 2024 -0500
@@ -3,6 +3,7 @@
 
 #include <string>
 #include <vector>
+#include <set>
 #include <sstream>
 
 #include <cstdint>
@@ -16,6 +17,7 @@
  * into a string, separated by delimiters.
 */
 std::string Implode(const std::vector<std::string>& vector, const std::string& delimiter);
+std::string Implode(const std::set<std::string>& set, const std::string& delimiter);
 std::vector<std::string> Split(const std::string &text, const std::string& delimiter);
 
 /* Substring removal functions */
--- a/include/gui/dialog/settings.h	Sat Jan 13 09:42:02 2024 -0500
+++ b/include/gui/dialog/settings.h	Sat Jan 13 09:43:41 2024 -0500
@@ -86,6 +86,19 @@
 		decltype(session.config.recognition.players) players;
 };
 
+class SettingsPageLibrary final : public SettingsPage {
+		Q_OBJECT
+
+	public:
+		SettingsPageLibrary(QWidget* parent = nullptr);
+		void SaveInfo() override;
+
+	private:
+		QWidget* CreateFoldersWidget();
+		decltype(session.config.library.paths) paths;
+		decltype(session.config.library.real_time_monitor) real_time_monitor;
+};
+
 class SettingsDialog final : public QDialog {
 		Q_OBJECT
 
--- a/include/library/library.h	Sat Jan 13 09:42:02 2024 -0500
+++ b/include/library/library.h	Sat Jan 13 09:43:41 2024 -0500
@@ -6,9 +6,13 @@
 #include <unordered_map>
 #include <string>
 
+namespace Library {
+
 // int = anime id, map = episode, paths
 extern std::unordered_map<int, std::unordered_map<int, std::string>> library;
 
 void SearchLibraryFolders();
 
-#endif // __library__library_h
\ No newline at end of file
+}
+
+#endif // __library__library_h
--- a/rc/locale/en_GB.ts	Sat Jan 13 09:42:02 2024 -0500
+++ b/rc/locale/en_GB.ts	Sat Jan 13 09:43:41 2024 -0500
@@ -4,10 +4,50 @@
 <context>
     <name>AboutWindow</name>
     <message>
-        <location filename="../../src/gui/dialog/about.cc" line="42"/>
+        <location filename="../../src/gui/dialog/about.cc" line="41"/>
         <source>About Minori</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <location filename="../../src/gui/dialog/about.cc" line="52"/>
+        <source>Author:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/gui/dialog/about.cc" line="56"/>
+        <source>Third party components:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/gui/dialog/about.cc" line="72"/>
+        <source>Special thanks:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/gui/dialog/about.cc" line="75"/>
+        <source>for creating Taiga</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/gui/dialog/about.cc" line="76"/>
+        <source>and</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/gui/dialog/about.cc" line="77"/>
+        <source>for creating BreezeStyleSheets, on which the dark theme in this program is based off of</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/gui/dialog/about.cc" line="79"/>
+        <source>for providing some sample code for detecting dark mode on Windows and macOS</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/gui/dialog/about.cc" line="81"/>
+        <source>for providing information on getting open file descriptors on macOS</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>AnimeInfoWidget</name>
@@ -40,28 +80,28 @@
 <context>
     <name>AnimeListPage</name>
     <message>
-        <location filename="../../src/gui/pages/anime_list.cc" line="233"/>
-        <location filename="../../src/gui/pages/anime_list.cc" line="271"/>
+        <location filename="../../src/gui/pages/anime_list.cc" line="236"/>
+        <location filename="../../src/gui/pages/anime_list.cc" line="274"/>
         <source>Column visibility</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/pages/anime_list.cc" line="259"/>
+        <location filename="../../src/gui/pages/anime_list.cc" line="262"/>
         <source>Reset to defaults</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/pages/anime_list.cc" line="288"/>
+        <location filename="../../src/gui/pages/anime_list.cc" line="291"/>
         <source>Information</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/pages/anime_list.cc" line="300"/>
+        <location filename="../../src/gui/pages/anime_list.cc" line="303"/>
         <source>Edit</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/pages/anime_list.cc" line="311"/>
+        <location filename="../../src/gui/pages/anime_list.cc" line="314"/>
         <source>Delete from list...</source>
         <translation type="unfinished"></translation>
     </message>
@@ -190,37 +230,37 @@
 <context>
     <name>MainWindow</name>
     <message>
-        <location filename="../../src/gui/window.cc" line="130"/>
+        <location filename="../../src/gui/window.cc" line="133"/>
         <source>Now Playing</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="132"/>
+        <location filename="../../src/gui/window.cc" line="135"/>
         <source>Anime List</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="133"/>
+        <location filename="../../src/gui/window.cc" line="136"/>
         <source>History</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="134"/>
+        <location filename="../../src/gui/window.cc" line="137"/>
         <source>Statistics</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="136"/>
+        <location filename="../../src/gui/window.cc" line="139"/>
         <source>Search</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="137"/>
+        <location filename="../../src/gui/window.cc" line="140"/>
         <source>Seasons</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="138"/>
+        <location filename="../../src/gui/window.cc" line="141"/>
         <source>Torrents</source>
         <translation type="unfinished"></translation>
     </message>
@@ -235,38 +275,37 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="170"/>
+        <location filename="../../src/gui/window.cc" line="185"/>
         <source>&amp;Add new folder...</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="175"/>
+        <location filename="../../src/gui/window.cc" line="186"/>
+        <source>Open Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/gui/window.cc" line="200"/>
         <source>&amp;Scan available episodes</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="388"/>
-        <location filename="../../src/gui/window.cc" line="402"/>
-        <source>...</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location filename="../../src/gui/window.cc" line="193"/>
+        <location filename="../../src/gui/window.cc" line="220"/>
         <source>E&amp;xit</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="199"/>
+        <location filename="../../src/gui/window.cc" line="227"/>
         <source>&amp;Services</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="202"/>
+        <location filename="../../src/gui/window.cc" line="230"/>
         <source>Synchronize &amp;list</source>
         <translation>Synchronise &amp;list</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="233"/>
+        <location filename="../../src/gui/window.cc" line="261"/>
         <source>&amp;Tools</source>
         <translation type="unfinished"></translation>
     </message>
@@ -275,87 +314,87 @@
         <translation type="vanished">Enable &amp;auto synchronisation</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="268"/>
+        <location filename="../../src/gui/window.cc" line="296"/>
         <source>&amp;Settings</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="278"/>
+        <location filename="../../src/gui/window.cc" line="306"/>
         <source>&amp;View</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="288"/>
+        <location filename="../../src/gui/window.cc" line="316"/>
         <source>&amp;Now Playing</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="294"/>
+        <location filename="../../src/gui/window.cc" line="322"/>
         <source>&amp;Anime List</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="301"/>
+        <location filename="../../src/gui/window.cc" line="329"/>
         <source>&amp;History</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="307"/>
+        <location filename="../../src/gui/window.cc" line="335"/>
         <source>&amp;Statistics</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="313"/>
+        <location filename="../../src/gui/window.cc" line="341"/>
         <source>S&amp;earch</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="319"/>
+        <location filename="../../src/gui/window.cc" line="347"/>
         <source>Se&amp;asons</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="325"/>
+        <location filename="../../src/gui/window.cc" line="353"/>
         <source>&amp;Torrents</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="347"/>
+        <location filename="../../src/gui/window.cc" line="375"/>
         <source>&amp;Help</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="351"/>
-        <source>&amp;About Minori</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location filename="../../src/gui/window.cc" line="359"/>
-        <source>About &amp;Qt</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
         <location filename="../../src/gui/window.cc" line="379"/>
+        <source>&amp;About Minori</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/gui/window.cc" line="387"/>
+        <source>About &amp;Qt</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/gui/window.cc" line="407"/>
         <source>&amp;Synchronize</source>
         <translation>&amp;Synchronise</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="413"/>
+        <location filename="../../src/gui/window.cc" line="461"/>
         <source>S&amp;ettings</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="428"/>
+        <location filename="../../src/gui/window.cc" line="476"/>
         <source>Error synchronizing with service!</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="429"/>
+        <location filename="../../src/gui/window.cc" line="477"/>
         <source>It seems you haven&apos;t yet selected a service to use.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="430"/>
+        <location filename="../../src/gui/window.cc" line="478"/>
         <source>Would you like to select one now?</source>
         <translation type="unfinished"></translation>
     </message>
@@ -371,212 +410,172 @@
 <context>
     <name>QCoreApplication</name>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="182"/>
+        <location filename="../../src/gui/translate/anime.cc" line="185"/>
         <source>Currently watching</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="183"/>
-        <source>Plan to watch</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location filename="../../src/gui/translate/anime.cc" line="184"/>
-        <source>Completed</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location filename="../../src/gui/translate/anime.cc" line="185"/>
-        <source>Dropped</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
         <location filename="../../src/gui/translate/anime.cc" line="186"/>
+        <source>Plan to watch</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/gui/translate/anime.cc" line="187"/>
+        <source>Completed</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/gui/translate/anime.cc" line="188"/>
+        <source>Dropped</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/gui/translate/anime.cc" line="189"/>
         <source>On hold</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="188"/>
+        <location filename="../../src/gui/translate/anime.cc" line="191"/>
         <source>Not in list</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="194"/>
+        <location filename="../../src/gui/translate/anime.cc" line="197"/>
         <source>TV</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="195"/>
-        <source>TV short</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location filename="../../src/gui/translate/anime.cc" line="196"/>
-        <source>OVA</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
         <location filename="../../src/gui/translate/anime.cc" line="198"/>
+        <source>TV short</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/gui/translate/anime.cc" line="199"/>
+        <source>OVA</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/gui/translate/anime.cc" line="201"/>
         <source>Special</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="199"/>
+        <location filename="../../src/gui/translate/anime.cc" line="202"/>
         <source>ONA</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="200"/>
+        <location filename="../../src/gui/translate/anime.cc" line="203"/>
         <source>Music</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="202"/>
-        <location filename="../../src/gui/translate/anime.cc" line="213"/>
-        <location filename="../../src/gui/translate/anime.cc" line="225"/>
+        <location filename="../../src/gui/translate/anime.cc" line="205"/>
+        <location filename="../../src/gui/translate/anime.cc" line="216"/>
+        <location filename="../../src/gui/translate/anime.cc" line="228"/>
         <source>Unknown</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="208"/>
+        <location filename="../../src/gui/translate/anime.cc" line="211"/>
         <source>Winter</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="209"/>
+        <location filename="../../src/gui/translate/anime.cc" line="212"/>
         <source>Summer</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="248"/>
+        <location filename="../../src/gui/translate/anime.cc" line="251"/>
         <source>3-point</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="249"/>
+        <location filename="../../src/gui/translate/anime.cc" line="252"/>
         <source>5-point</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="250"/>
+        <location filename="../../src/gui/translate/anime.cc" line="253"/>
         <source>10-point</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="251"/>
+        <location filename="../../src/gui/translate/anime.cc" line="254"/>
         <source>10-point (Decimal)</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="253"/>
+        <location filename="../../src/gui/translate/anime.cc" line="256"/>
         <source>100-point</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="197"/>
+        <location filename="../../src/gui/translate/anime.cc" line="200"/>
         <source>Movie</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="210"/>
+        <location filename="../../src/gui/translate/anime.cc" line="213"/>
         <source>Fall</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="211"/>
+        <location filename="../../src/gui/translate/anime.cc" line="214"/>
         <source>Spring</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="219"/>
+        <location filename="../../src/gui/translate/anime.cc" line="222"/>
         <source>Currently airing</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="220"/>
+        <location filename="../../src/gui/translate/anime.cc" line="223"/>
         <source>Finished airing</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="221"/>
+        <location filename="../../src/gui/translate/anime.cc" line="224"/>
         <source>Not yet aired</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="222"/>
+        <location filename="../../src/gui/translate/anime.cc" line="225"/>
         <source>Cancelled</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="223"/>
+        <location filename="../../src/gui/translate/anime.cc" line="226"/>
         <source>On hiatus</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="231"/>
+        <location filename="../../src/gui/translate/anime.cc" line="234"/>
         <source>AniList</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="233"/>
+        <location filename="../../src/gui/translate/anime.cc" line="236"/>
         <source>None</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="239"/>
+        <location filename="../../src/gui/translate/anime.cc" line="242"/>
         <source>Native</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="240"/>
+        <location filename="../../src/gui/translate/anime.cc" line="243"/>
         <source>English</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="242"/>
+        <location filename="../../src/gui/translate/anime.cc" line="245"/>
         <source>Romaji</source>
         <translation type="unfinished"></translation>
     </message>
-    <message>
-        <location filename="../../src/gui/dialog/about.cc" line="53"/>
-        <source>Author:</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location filename="../../src/gui/dialog/about.cc" line="57"/>
-        <source>Third party components:</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location filename="../../src/gui/dialog/about.cc" line="73"/>
-        <source>Special thanks:</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location filename="../../src/gui/dialog/about.cc" line="76"/>
-        <source>for creating Taiga</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location filename="../../src/gui/dialog/about.cc" line="77"/>
-        <source>and</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location filename="../../src/gui/dialog/about.cc" line="78"/>
-        <source>for creating BreezeStyleSheets, on which the dark theme in this program is based off of</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location filename="../../src/gui/dialog/about.cc" line="80"/>
-        <source>for providing some sample code for detecting dark mode on Windows and macOS</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location filename="../../src/gui/dialog/about.cc" line="82"/>
-        <source>for providing information on getting open file descriptors on macOS</source>
-        <translation type="unfinished"></translation>
-    </message>
 </context>
 <context>
     <name>SettingsDialog</name>
@@ -872,22 +871,22 @@
 <context>
     <name>TorrentsPage</name>
     <message>
-        <location filename="../../src/gui/pages/torrents.cc" line="299"/>
+        <location filename="../../src/gui/pages/torrents.cc" line="303"/>
         <source>&amp;Check new torrents</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/pages/torrents.cc" line="309"/>
+        <location filename="../../src/gui/pages/torrents.cc" line="313"/>
         <source>Download &amp;marked torrents</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/pages/torrents.cc" line="313"/>
+        <location filename="../../src/gui/pages/torrents.cc" line="317"/>
         <source>&amp;Discard all</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/pages/torrents.cc" line="319"/>
+        <location filename="../../src/gui/pages/torrents.cc" line="323"/>
         <source>&amp;Settings</source>
         <translation type="unfinished"></translation>
     </message>
@@ -895,57 +894,57 @@
 <context>
     <name>TorrentsPageListModel</name>
     <message>
-        <location filename="../../src/gui/pages/torrents.cc" line="157"/>
+        <location filename="../../src/gui/pages/torrents.cc" line="161"/>
         <source>Anime title</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/pages/torrents.cc" line="158"/>
-        <source>Episode</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location filename="../../src/gui/pages/torrents.cc" line="159"/>
-        <source>Group</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location filename="../../src/gui/pages/torrents.cc" line="160"/>
-        <source>Size</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location filename="../../src/gui/pages/torrents.cc" line="161"/>
-        <source>Resolution</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
         <location filename="../../src/gui/pages/torrents.cc" line="162"/>
-        <source>Seeding</source>
+        <source>Episode</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
         <location filename="../../src/gui/pages/torrents.cc" line="163"/>
-        <source>Leeching</source>
+        <source>Group</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
         <location filename="../../src/gui/pages/torrents.cc" line="164"/>
-        <source>Downloading</source>
+        <source>Size</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
         <location filename="../../src/gui/pages/torrents.cc" line="165"/>
-        <source>Description</source>
+        <source>Resolution</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
         <location filename="../../src/gui/pages/torrents.cc" line="166"/>
+        <source>Seeding</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/gui/pages/torrents.cc" line="167"/>
+        <source>Leeching</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/gui/pages/torrents.cc" line="168"/>
+        <source>Downloading</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/gui/pages/torrents.cc" line="169"/>
+        <source>Description</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../../src/gui/pages/torrents.cc" line="170"/>
         <source>Filename</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/pages/torrents.cc" line="167"/>
+        <location filename="../../src/gui/pages/torrents.cc" line="171"/>
         <source>Release date</source>
         <translation type="unfinished"></translation>
     </message>
--- a/rc/locale/es.ts	Sat Jan 13 09:42:02 2024 -0500
+++ b/rc/locale/es.ts	Sat Jan 13 09:43:41 2024 -0500
@@ -4,10 +4,50 @@
 <context>
     <name>AboutWindow</name>
     <message>
-        <location filename="../../src/gui/dialog/about.cc" line="42"/>
+        <location filename="../../src/gui/dialog/about.cc" line="41"/>
         <source>About Minori</source>
         <translation>Acerca de Minori</translation>
     </message>
+    <message>
+        <location filename="../../src/gui/dialog/about.cc" line="52"/>
+        <source>Author:</source>
+        <translation type="unfinished">Autor:</translation>
+    </message>
+    <message>
+        <location filename="../../src/gui/dialog/about.cc" line="56"/>
+        <source>Third party components:</source>
+        <translation type="unfinished">Componentes de terceros:</translation>
+    </message>
+    <message>
+        <location filename="../../src/gui/dialog/about.cc" line="72"/>
+        <source>Special thanks:</source>
+        <translation type="unfinished">Agradecimientos especiales:</translation>
+    </message>
+    <message>
+        <location filename="../../src/gui/dialog/about.cc" line="75"/>
+        <source>for creating Taiga</source>
+        <translation type="unfinished">para crear Taiga</translation>
+    </message>
+    <message>
+        <location filename="../../src/gui/dialog/about.cc" line="76"/>
+        <source>and</source>
+        <translation type="unfinished">y</translation>
+    </message>
+    <message>
+        <location filename="../../src/gui/dialog/about.cc" line="77"/>
+        <source>for creating BreezeStyleSheets, on which the dark theme in this program is based off of</source>
+        <translation type="unfinished">para crear BreezeStyleSheets, en el que se basa el tema oscuro de este programa</translation>
+    </message>
+    <message>
+        <location filename="../../src/gui/dialog/about.cc" line="79"/>
+        <source>for providing some sample code for detecting dark mode on Windows and macOS</source>
+        <translation type="unfinished">por proporcionar algunos ejemplos de código para detectar el modo oscuro en Windows y macOS</translation>
+    </message>
+    <message>
+        <location filename="../../src/gui/dialog/about.cc" line="81"/>
+        <source>for providing information on getting open file descriptors on macOS</source>
+        <translation type="unfinished">para obtener información sobre descriptores de archivos abiertos en macOS</translation>
+    </message>
 </context>
 <context>
     <name>AnimeInfoWidget</name>
@@ -45,28 +85,28 @@
 <context>
     <name>AnimeListPage</name>
     <message>
-        <location filename="../../src/gui/pages/anime_list.cc" line="233"/>
-        <location filename="../../src/gui/pages/anime_list.cc" line="271"/>
+        <location filename="../../src/gui/pages/anime_list.cc" line="236"/>
+        <location filename="../../src/gui/pages/anime_list.cc" line="274"/>
         <source>Column visibility</source>
         <translation>Visibilidad de la columna</translation>
     </message>
     <message>
-        <location filename="../../src/gui/pages/anime_list.cc" line="259"/>
+        <location filename="../../src/gui/pages/anime_list.cc" line="262"/>
         <source>Reset to defaults</source>
         <translation>Restablecer valores predeterminado</translation>
     </message>
     <message>
-        <location filename="../../src/gui/pages/anime_list.cc" line="288"/>
+        <location filename="../../src/gui/pages/anime_list.cc" line="291"/>
         <source>Information</source>
         <translation>Información</translation>
     </message>
     <message>
-        <location filename="../../src/gui/pages/anime_list.cc" line="300"/>
+        <location filename="../../src/gui/pages/anime_list.cc" line="303"/>
         <source>Edit</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/pages/anime_list.cc" line="311"/>
+        <location filename="../../src/gui/pages/anime_list.cc" line="314"/>
         <source>Delete from list...</source>
         <translation>Borrar de la lista...</translation>
     </message>
@@ -195,37 +235,37 @@
 <context>
     <name>MainWindow</name>
     <message>
-        <location filename="../../src/gui/window.cc" line="130"/>
+        <location filename="../../src/gui/window.cc" line="133"/>
         <source>Now Playing</source>
         <translation>Jugando ahora</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="132"/>
+        <location filename="../../src/gui/window.cc" line="135"/>
         <source>Anime List</source>
         <translation>Lista de anime</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="133"/>
+        <location filename="../../src/gui/window.cc" line="136"/>
         <source>History</source>
         <translation>Historia</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="134"/>
+        <location filename="../../src/gui/window.cc" line="137"/>
         <source>Statistics</source>
         <translation>Estadísticas</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="136"/>
+        <location filename="../../src/gui/window.cc" line="139"/>
         <source>Search</source>
         <translation>Buscar</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="137"/>
+        <location filename="../../src/gui/window.cc" line="140"/>
         <source>Seasons</source>
         <translation>Temporadas</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="138"/>
+        <location filename="../../src/gui/window.cc" line="141"/>
         <source>Torrents</source>
         <translation type="unfinished"></translation>
     </message>
@@ -240,20 +280,19 @@
         <translation>Directorios de la biblioteca (&amp;L)</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="170"/>
+        <location filename="../../src/gui/window.cc" line="185"/>
         <source>&amp;Add new folder...</source>
         <translation>&amp;Añadir una nueva directorios...</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="175"/>
-        <source>&amp;Scan available episodes</source>
-        <translation>E&amp;scanear episodios disponibles</translation>
+        <location filename="../../src/gui/window.cc" line="186"/>
+        <source>Open Directory</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="388"/>
-        <location filename="../../src/gui/window.cc" line="402"/>
-        <source>...</source>
-        <translation type="unfinished"></translation>
+        <location filename="../../src/gui/window.cc" line="200"/>
+        <source>&amp;Scan available episodes</source>
+        <translation>E&amp;scanear episodios disponibles</translation>
     </message>
     <message>
         <source>Play &amp;next episode</source>
@@ -264,17 +303,17 @@
         <translation type="vanished">Ver episodio aleato&amp;rio</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="193"/>
+        <location filename="../../src/gui/window.cc" line="220"/>
         <source>E&amp;xit</source>
         <translation>Salida (&amp;X)</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="199"/>
+        <location filename="../../src/gui/window.cc" line="227"/>
         <source>&amp;Services</source>
         <translation>&amp;Servicios</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="202"/>
+        <location filename="../../src/gui/window.cc" line="230"/>
         <source>Synchronize &amp;list</source>
         <translation>Sincronizar &amp;lista</translation>
     </message>
@@ -315,7 +354,7 @@
         <translation type="vanished">Ir a mi &amp;historia</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="233"/>
+        <location filename="../../src/gui/window.cc" line="261"/>
         <source>&amp;Tools</source>
         <translation>Ins&amp;trumentos</translation>
     </message>
@@ -344,47 +383,47 @@
         <translation type="vanished">Activar la sincronización &amp;automática</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="268"/>
+        <location filename="../../src/gui/window.cc" line="296"/>
         <source>&amp;Settings</source>
         <translation>Configuración (&amp;S)</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="278"/>
+        <location filename="../../src/gui/window.cc" line="306"/>
         <source>&amp;View</source>
         <translation>&amp;Ver</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="288"/>
+        <location filename="../../src/gui/window.cc" line="316"/>
         <source>&amp;Now Playing</source>
         <translation>Jugando ahora (&amp;N)</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="294"/>
+        <location filename="../../src/gui/window.cc" line="322"/>
         <source>&amp;Anime List</source>
         <translation>Lista de &amp;anime</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="301"/>
+        <location filename="../../src/gui/window.cc" line="329"/>
         <source>&amp;History</source>
         <translation>&amp;Historia</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="307"/>
+        <location filename="../../src/gui/window.cc" line="335"/>
         <source>&amp;Statistics</source>
         <translation>E&amp;stadísticas</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="313"/>
+        <location filename="../../src/gui/window.cc" line="341"/>
         <source>S&amp;earch</source>
         <translation>Buscar (&amp;S)</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="319"/>
+        <location filename="../../src/gui/window.cc" line="347"/>
         <source>Se&amp;asons</source>
         <translation>Tempor&amp;adas</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="325"/>
+        <location filename="../../src/gui/window.cc" line="353"/>
         <source>&amp;Torrents</source>
         <translation type="unfinished"></translation>
     </message>
@@ -393,22 +432,22 @@
         <translation type="vanished">Mostrar barra lateral</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="347"/>
+        <location filename="../../src/gui/window.cc" line="375"/>
         <source>&amp;Help</source>
         <translation>Ayuda (&amp;H)</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="351"/>
+        <location filename="../../src/gui/window.cc" line="379"/>
         <source>&amp;About Minori</source>
         <translation>&amp;Acerca de Minori</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="359"/>
+        <location filename="../../src/gui/window.cc" line="387"/>
         <source>About &amp;Qt</source>
         <translation>Acerca de &amp;Qt</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="379"/>
+        <location filename="../../src/gui/window.cc" line="407"/>
         <source>&amp;Synchronize</source>
         <translation>&amp;Sincronice</translation>
     </message>
@@ -421,22 +460,22 @@
         <translation type="vanished">Marcador de posición</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="413"/>
+        <location filename="../../src/gui/window.cc" line="461"/>
         <source>S&amp;ettings</source>
         <translation>Configuración (&amp;S)</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="428"/>
+        <location filename="../../src/gui/window.cc" line="476"/>
         <source>Error synchronizing with service!</source>
         <translation>Error al sincronizar con el servicio!</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="429"/>
+        <location filename="../../src/gui/window.cc" line="477"/>
         <source>It seems you haven&apos;t yet selected a service to use.</source>
         <translation>Parece que aún no has seleccionado un servicio para usar.</translation>
     </message>
     <message>
-        <location filename="../../src/gui/window.cc" line="430"/>
+        <location filename="../../src/gui/window.cc" line="478"/>
         <source>Would you like to select one now?</source>
         <translation>¿Quieres seleccionar uno ahora?</translation>
     </message>
@@ -452,211 +491,203 @@
 <context>
     <name>QCoreApplication</name>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="182"/>
+        <location filename="../../src/gui/translate/anime.cc" line="185"/>
         <source>Currently watching</source>
         <translation>Actualmente viendo</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="183"/>
+        <location filename="../../src/gui/translate/anime.cc" line="186"/>
         <source>Plan to watch</source>
         <translation>Plan para ver</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="184"/>
+        <location filename="../../src/gui/translate/anime.cc" line="187"/>
         <source>Completed</source>
         <translation>Completado</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="185"/>
+        <location filename="../../src/gui/translate/anime.cc" line="188"/>
         <source>Dropped</source>
         <translation>Dejado</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="186"/>
+        <location filename="../../src/gui/translate/anime.cc" line="189"/>
         <source>On hold</source>
         <translation>En espera</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="188"/>
+        <location filename="../../src/gui/translate/anime.cc" line="191"/>
         <source>Not in list</source>
         <translation>No en la lista</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="194"/>
+        <location filename="../../src/gui/translate/anime.cc" line="197"/>
         <source>TV</source>
         <translation>TV</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="195"/>
+        <location filename="../../src/gui/translate/anime.cc" line="198"/>
         <source>TV short</source>
         <translation>Corto</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="196"/>
+        <location filename="../../src/gui/translate/anime.cc" line="199"/>
         <source>OVA</source>
         <translation>OVA</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="197"/>
+        <location filename="../../src/gui/translate/anime.cc" line="200"/>
         <source>Movie</source>
         <translation>Película</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="198"/>
+        <location filename="../../src/gui/translate/anime.cc" line="201"/>
         <source>Special</source>
         <translation>Especial</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="199"/>
+        <location filename="../../src/gui/translate/anime.cc" line="202"/>
         <source>ONA</source>
         <translation>ONA</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="200"/>
+        <location filename="../../src/gui/translate/anime.cc" line="203"/>
         <source>Music</source>
         <translation>Música</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="202"/>
-        <location filename="../../src/gui/translate/anime.cc" line="213"/>
-        <location filename="../../src/gui/translate/anime.cc" line="225"/>
+        <location filename="../../src/gui/translate/anime.cc" line="205"/>
+        <location filename="../../src/gui/translate/anime.cc" line="216"/>
+        <location filename="../../src/gui/translate/anime.cc" line="228"/>
         <source>Unknown</source>
         <translation>Desconocido</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="208"/>
+        <location filename="../../src/gui/translate/anime.cc" line="211"/>
         <source>Winter</source>
         <translation>Invierno</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="209"/>
+        <location filename="../../src/gui/translate/anime.cc" line="212"/>
         <source>Summer</source>
         <translation>Verano</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="210"/>
+        <location filename="../../src/gui/translate/anime.cc" line="213"/>
         <source>Fall</source>
         <translation>Otoño</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="211"/>
+        <location filename="../../src/gui/translate/anime.cc" line="214"/>
         <source>Spring</source>
         <translation>Primavera</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="219"/>
+        <location filename="../../src/gui/translate/anime.cc" line="222"/>
         <source>Currently airing</source>
         <translation>En emisión</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="220"/>
+        <location filename="../../src/gui/translate/anime.cc" line="223"/>
         <source>Finished airing</source>
         <translation>Emisión terminada</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="221"/>
+        <location filename="../../src/gui/translate/anime.cc" line="224"/>
         <source>Not yet aired</source>
         <translation>Aún no emitido</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="222"/>
+        <location filename="../../src/gui/translate/anime.cc" line="225"/>
         <source>Cancelled</source>
         <translation>Cancelado</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="223"/>
+        <location filename="../../src/gui/translate/anime.cc" line="226"/>
         <source>On hiatus</source>
         <translation>En pausa</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="231"/>
+        <location filename="../../src/gui/translate/anime.cc" line="234"/>
         <source>AniList</source>
         <translation>AniList</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="233"/>
+        <location filename="../../src/gui/translate/anime.cc" line="236"/>
         <source>None</source>
         <translation>Ninguno</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="239"/>
+        <location filename="../../src/gui/translate/anime.cc" line="242"/>
         <source>Native</source>
         <translation>Nativo</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="240"/>
+        <location filename="../../src/gui/translate/anime.cc" line="243"/>
         <source>English</source>
         <translation>Inglés</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="242"/>
+        <location filename="../../src/gui/translate/anime.cc" line="245"/>
         <source>Romaji</source>
         <translation>Romaji</translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="248"/>
+        <location filename="../../src/gui/translate/anime.cc" line="251"/>
         <source>3-point</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="249"/>
+        <location filename="../../src/gui/translate/anime.cc" line="252"/>
         <source>5-point</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="250"/>
+        <location filename="../../src/gui/translate/anime.cc" line="253"/>
         <source>10-point</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="251"/>
+        <location filename="../../src/gui/translate/anime.cc" line="254"/>
         <source>10-point (Decimal)</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/translate/anime.cc" line="253"/>
+        <location filename="../../src/gui/translate/anime.cc" line="256"/>
         <source>100-point</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../../src/gui/dialog/about.cc" line="53"/>
         <source>Author:</source>
-        <translation>Autor:</translation>
+        <translation type="vanished">Autor:</translation>
     </message>
     <message>
-        <location filename="../../src/gui/dialog/about.cc" line="57"/>
         <source>Third party components:</source>
-        <translation>Componentes de terceros:</translation>
+        <translation type="vanished">Componentes de terceros:</translation>
     </message>
     <message>
-        <location filename="../../src/gui/dialog/about.cc" line="73"/>
         <source>Special thanks:</source>
-        <translation>Agradecimientos especiales:</translation>
+        <translation type="vanished">Agradecimientos especiales:</translation>
     </message>
     <message>
-        <location filename="../../src/gui/dialog/about.cc" line="76"/>
         <source>for creating Taiga</source>
-        <translation>para crear Taiga</translation>
+        <translation type="vanished">para crear Taiga</translation>
     </message>
     <message>
-        <location filename="../../src/gui/dialog/about.cc" line="77"/>
         <source>and</source>
-        <translation>y</translation>
+        <translation type="vanished">y</translation>
     </message>
     <message>
-        <location filename="../../src/gui/dialog/about.cc" line="78"/>
         <source>for creating BreezeStyleSheets, on which the dark theme in this program is based off of</source>
-        <translation>para crear BreezeStyleSheets, en el que se basa el tema oscuro de este programa</translation>
+        <translation type="vanished">para crear BreezeStyleSheets, en el que se basa el tema oscuro de este programa</translation>
     </message>
     <message>
-        <location filename="../../src/gui/dialog/about.cc" line="80"/>
         <source>for providing some sample code for detecting dark mode on Windows and macOS</source>
-        <translation>por proporcionar algunos ejemplos de código para detectar el modo oscuro en Windows y macOS</translation>
+        <translation type="vanished">por proporcionar algunos ejemplos de código para detectar el modo oscuro en Windows y macOS</translation>
     </message>
     <message>
-        <location filename="../../src/gui/dialog/about.cc" line="82"/>
         <source>for providing information on getting open file descriptors on macOS</source>
-        <translation>para obtener información sobre descriptores de archivos abiertos en macOS</translation>
+        <translation type="vanished">para obtener información sobre descriptores de archivos abiertos en macOS</translation>
     </message>
 </context>
 <context>
@@ -967,22 +998,22 @@
 <context>
     <name>TorrentsPage</name>
     <message>
-        <location filename="../../src/gui/pages/torrents.cc" line="299"/>
+        <location filename="../../src/gui/pages/torrents.cc" line="303"/>
         <source>&amp;Check new torrents</source>
         <translation>&amp;Comprueba nuevos torrentes</translation>
     </message>
     <message>
-        <location filename="../../src/gui/pages/torrents.cc" line="309"/>
+        <location filename="../../src/gui/pages/torrents.cc" line="313"/>
         <source>Download &amp;marked torrents</source>
         <translation>Descargar torrents &amp;marcados</translation>
     </message>
     <message>
-        <location filename="../../src/gui/pages/torrents.cc" line="313"/>
+        <location filename="../../src/gui/pages/torrents.cc" line="317"/>
         <source>&amp;Discard all</source>
         <translation>&amp;Descartar todo</translation>
     </message>
     <message>
-        <location filename="../../src/gui/pages/torrents.cc" line="319"/>
+        <location filename="../../src/gui/pages/torrents.cc" line="323"/>
         <source>&amp;Settings</source>
         <translation>Configuración (&amp;S)</translation>
     </message>
@@ -990,57 +1021,57 @@
 <context>
     <name>TorrentsPageListModel</name>
     <message>
-        <location filename="../../src/gui/pages/torrents.cc" line="157"/>
+        <location filename="../../src/gui/pages/torrents.cc" line="161"/>
         <source>Anime title</source>
         <translation>Título del anime</translation>
     </message>
     <message>
-        <location filename="../../src/gui/pages/torrents.cc" line="158"/>
+        <location filename="../../src/gui/pages/torrents.cc" line="162"/>
         <source>Episode</source>
         <translation>Episodio</translation>
     </message>
     <message>
-        <location filename="../../src/gui/pages/torrents.cc" line="159"/>
+        <location filename="../../src/gui/pages/torrents.cc" line="163"/>
         <source>Group</source>
         <translation>Grupo</translation>
     </message>
     <message>
-        <location filename="../../src/gui/pages/torrents.cc" line="160"/>
+        <location filename="../../src/gui/pages/torrents.cc" line="164"/>
         <source>Size</source>
         <translation>Tamaño del archivo</translation>
     </message>
     <message>
-        <location filename="../../src/gui/pages/torrents.cc" line="161"/>
+        <location filename="../../src/gui/pages/torrents.cc" line="165"/>
         <source>Resolution</source>
         <translation>Resolución</translation>
     </message>
     <message>
-        <location filename="../../src/gui/pages/torrents.cc" line="162"/>
+        <location filename="../../src/gui/pages/torrents.cc" line="166"/>
         <source>Seeding</source>
         <translation>Siembra</translation>
     </message>
     <message>
-        <location filename="../../src/gui/pages/torrents.cc" line="163"/>
+        <location filename="../../src/gui/pages/torrents.cc" line="167"/>
         <source>Leeching</source>
         <translation>Sanguijuela</translation>
     </message>
     <message>
-        <location filename="../../src/gui/pages/torrents.cc" line="164"/>
+        <location filename="../../src/gui/pages/torrents.cc" line="168"/>
         <source>Downloading</source>
         <translation>Descargando</translation>
     </message>
     <message>
-        <location filename="../../src/gui/pages/torrents.cc" line="165"/>
+        <location filename="../../src/gui/pages/torrents.cc" line="169"/>
         <source>Description</source>
         <translation>Descripción</translation>
     </message>
     <message>
-        <location filename="../../src/gui/pages/torrents.cc" line="166"/>
+        <location filename="../../src/gui/pages/torrents.cc" line="170"/>
         <source>Filename</source>
         <translation>Nombre del archivo</translation>
     </message>
     <message>
-        <location filename="../../src/gui/pages/torrents.cc" line="167"/>
+        <location filename="../../src/gui/pages/torrents.cc" line="171"/>
         <source>Release date</source>
         <translation>Fecha de lanzamiento</translation>
     </message>
--- a/src/core/config.cc	Sat Jan 13 09:42:02 2024 -0500
+++ b/src/core/config.cc	Sat Jan 13 09:43:41 2024 -0500
@@ -25,12 +25,15 @@
 
 /* I'll use an INI-based config file instead of using an
  * XML file like Taiga.
+ *
+ * It technically isn't to spec, because I'm making these case-sensitive.
+ * Boohoo.
 */
 
 int Config::Load() {
 	std::filesystem::path cfg_path = Filesystem::GetConfigPath();
 
-	mINI::INIFile file(cfg_path.string());
+	mINI::INIFile file(cfg_path.u8string());
 	mINI::INIStructure ini;
 	file.read(ini);
 
@@ -90,6 +93,14 @@
 
 	theme.SetTheme(Translate::ToTheme(INI::GetIniValue<std::string>(ini, "Appearance", "Theme", "Default")));
 
+	{
+		std::vector<std::string> v = Strings::Split(INI::GetIniValue<std::string>(ini, "Library", "Folders", ""), ";");
+		library.paths = std::set(std::make_move_iterator(v.begin()),
+								 std::make_move_iterator(v.end()));
+	}
+
+	library.real_time_monitor = INI::GetIniValue<bool>(ini, "Library", "Real-time monitor", true);
+
 	return 0;
 }
 
@@ -131,6 +142,9 @@
 		}
 	}
 
+	INI::SetIniValue(ini, "Library", "Folders", Strings::Implode(library.paths, ";"));
+	INI::SetIniValue(ini, "Library", "Real-time monitor", library.real_time_monitor);
+
 	file.write(ini);
 
 	return 0;
--- a/src/core/strings.cc	Sat Jan 13 09:42:02 2024 -0500
+++ b/src/core/strings.cc	Sat Jan 13 09:43:41 2024 -0500
@@ -36,6 +36,21 @@
 	return out;
 }
 
+std::string Implode(const std::set<std::string>& set, const std::string& delimiter) {
+	if (set.size() < 1)
+		return "-";
+
+	std::string out;
+
+	for (auto it = set.cbegin(); it != set.cend(); it++) {
+		out.append(*it);
+		if (it != std::prev(set.cend(), 1))
+			out.append(delimiter);
+	}
+
+	return out;
+}
+
 std::vector<std::string> Split(const std::string &text, const std::string& delimiter) {
 	std::vector<std::string> tokens;
 
--- a/src/gui/dialog/about.cc	Sat Jan 13 09:42:02 2024 -0500
+++ b/src/gui/dialog/about.cc	Sat Jan 13 09:43:41 2024 -0500
@@ -49,11 +49,11 @@
 		"<body>"
 		"  <h2 style=\"font-weight: normal;\"><strong>Minori</strong> v" + Strings::ToQString(session.version.to_string()) + "</h2>"
 		"  <p>"
-		"    <strong>" + QCoreApplication::tr("Author:") + "</strong><br>"
+		"    <strong>" + tr("Author:") + "</strong><br>"
 		"    Paper (@mrpapersonic)"
 		"  </p>"
 		"  <p>"
-		"    <strong>" + QCoreApplication::tr("Third party components:") + "</strong><br>"
+		"    <strong>" + tr("Third party components:") + "</strong><br>"
 		    "<a href=\"https://curl.se/\">libcurl v") + get_curl_version() + "</a>"
 		    ", "
 		    "<a href=\"https://p.yusukekamiyamane.com/\">Fugue Icons v3.5.6</a>"
@@ -69,16 +69,16 @@
 		    "<a href=\"https://github.com/pulzed/mINI\">mINI v0.9.14</a>"
 		"  </p>"
 		"<span>"
-		"<strong>" + QCoreApplication::tr("Special thanks:") + "</strong>"
+		"<strong>" + tr("Special thanks:") + "</strong>"
 		"</span>"
 		"  <ul style=\"margin-top: 0px; margin-bottom: 0px; margin-left: 15px; margin-right: 0px; -qt-list-indent:0;\">"
-		"    <li><strong>Eren Okka</strong> " + QCoreApplication::tr("for creating Taiga") + "</li>"
-		"    <li><strong>Alex Huszagh</strong> " + QCoreApplication::tr("and") + " <strong>Colin Duquesnoy</strong> " +
-		        QCoreApplication::tr("for creating BreezeStyleSheets, on which the dark theme in this program is "
+		"    <li><strong>Eren Okka</strong> " + tr("for creating Taiga") + "</li>"
+		"    <li><strong>Alex Huszagh</strong> " + tr("and") + " <strong>Colin Duquesnoy</strong> " +
+		        tr("for creating BreezeStyleSheets, on which the dark theme in this program is "
 		        "based off of") + "</li>"
-		"    <li><strong>Andy Brice</strong> " + QCoreApplication::tr("for providing some sample code for "
+		"    <li><strong>Andy Brice</strong> " + tr("for providing some sample code for "
 		        "detecting dark mode on Windows and macOS") + "</li>"
-		"    <li><strong>Manuel Wudka-Robles</strong> " + QCoreApplication::tr("for providing information on "
+		"    <li><strong>Manuel Wudka-Robles</strong> " + tr("for providing information on "
 		        "getting open file descriptors on macOS") + "</li>"
 		"  </ul>"
 		"</body>";
--- a/src/gui/dialog/settings.cc	Sat Jan 13 09:42:02 2024 -0500
+++ b/src/gui/dialog/settings.cc	Sat Jan 13 09:43:41 2024 -0500
@@ -88,7 +88,7 @@
 			sidebar = new SideBar(widget);
 
 			sidebar->setCurrentItem(sidebar->AddItem(tr("Services"), SideBar::CreateIcon(":/icons/24x24/globe.png")));
-			// sidebar->AddItem(tr("Library"), SideBar::CreateIcon(":/icons/24x24/inbox-film.png"));
+			sidebar->AddItem(tr("Library"), SideBar::CreateIcon(":/icons/24x24/inbox-film.png"));
 			sidebar->AddItem(tr("Application"), SideBar::CreateIcon(":/icons/24x24/application-sidebar-list.png"));
 			sidebar->AddItem(tr("Recognition"), SideBar::CreateIcon(":/icons/24x24/question.png"));
 			// sidebar->AddItem(tr("Sharing"), SideBar::CreateIcon(":/icons/24x24/megaphone.png"));
@@ -109,6 +109,7 @@
 		{
 			stacked = new QStackedWidget(widget);
 			stacked->addWidget(new SettingsPageServices(stacked));
+			stacked->addWidget(new SettingsPageLibrary(stacked));
 			stacked->addWidget(new SettingsPageApplication(stacked));
 			stacked->addWidget(new SettingsPageRecognition(stacked));
 			stacked->addWidget(new SettingsPageTorrents(stacked));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gui/dialog/settings/library.cc	Sat Jan 13 09:43:41 2024 -0500
@@ -0,0 +1,207 @@
+#include "core/session.h"
+#include "core/strings.h"
+#include "gui/dialog/settings.h"
+
+#include <QListWidget>
+#include <QListWidgetItem>
+#include <QGroupBox>
+#include <QCheckBox>
+#include <QLabel>
+#include <QSizePolicy>
+#include <QVBoxLayout>
+#include <QDir>
+#include <QFileDialog>
+#include <QFileInfo>
+#include <QPushButton>
+#include <QDropEvent>
+#include <QMimeData>
+
+#include <algorithm>
+#include <iostream>
+
+class DroppableListWidget : public QListWidget {
+	Q_OBJECT
+
+public:
+	explicit DroppableListWidget(QWidget* parent);
+
+signals:
+	void FilesDropped(QStringList list);
+
+protected:
+	void dragEnterEvent(QDragEnterEvent* event) override;
+	void dragMoveEvent(QDragMoveEvent* event) override;
+	void dropEvent(QDropEvent* event) override;
+};
+
+DroppableListWidget::DroppableListWidget(QWidget* parent) : QListWidget(parent) {
+	setAcceptDrops(true);
+}
+
+void DroppableListWidget::dragMoveEvent(QDragMoveEvent* event) {
+    if (event->mimeData()->hasUrls())
+        event->acceptProposedAction();
+}
+
+void DroppableListWidget::dragEnterEvent(QDragEnterEvent* event) {
+    if (event->mimeData()->hasUrls())
+        event->acceptProposedAction();
+}
+
+void DroppableListWidget::dropEvent(QDropEvent* event) {
+	const QMimeData* mime_data = event->mimeData();
+
+	if (!mime_data->hasUrls())
+		return;
+
+	QStringList path_list;
+	QList<QUrl> url_list = mime_data->urls();
+
+	for (const auto& url : url_list) {
+		if (!url.isLocalFile())
+			continue;
+
+		const QString file = url.toLocalFile();
+		const QFileInfo fileinfo(file);
+		if (fileinfo.exists() && fileinfo.isDir())
+			path_list.append(file);
+	}
+
+	if (!path_list.isEmpty())
+		emit FilesDropped(path_list);
+
+	event->acceptProposedAction();
+}
+
+QWidget* SettingsPageLibrary::CreateFoldersWidget() {
+	QWidget* result = new QWidget(this);
+	result->setAutoFillBackground(true);
+	result->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
+
+	QVBoxLayout* full_layout = new QVBoxLayout(result);
+
+	{
+		QGroupBox* group_box = new QGroupBox(tr("Library folders"), result);
+		group_box->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
+
+		QVBoxLayout* group_box_layout = new QVBoxLayout(group_box);
+
+		{
+			QLabel* label = new QLabel(tr("These folders will be scanned and monitored for new episodes."), group_box);
+			group_box_layout->addWidget(label);
+		}
+
+		{
+			DroppableListWidget* listwidget = new DroppableListWidget(group_box);
+			listwidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
+
+			for (const auto& path : paths) {
+				QListWidgetItem* item = new QListWidgetItem(listwidget);
+				item->setText(Strings::ToQString(path));
+				/* add icons as well soon */
+			}
+
+			connect(listwidget, &DroppableListWidget::FilesDropped, this, [this, listwidget](QStringList list){
+				for (const auto& dir : list) {
+					paths.insert(Strings::ToUtf8String(dir));
+					QListWidgetItem* item = new QListWidgetItem(listwidget);
+					item->setText(dir);
+				}
+			});
+
+			group_box_layout->addWidget(listwidget);
+
+			{
+				QWidget* widget = new QWidget(group_box);
+				QHBoxLayout* widget_layout = new QHBoxLayout(widget);
+
+				{
+					QLabel* label = new QLabel(tr("Tip: You can drag and drop folders here."), widget);
+					widget_layout->addWidget(label);
+				}
+
+				widget_layout->addStretch();
+
+				{
+					QPushButton* button = new QPushButton(tr("Add new..."), widget);
+
+					connect(button, &QPushButton::clicked, this, [this, listwidget]{
+						const QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"),
+																			QDir::homePath(),
+																			QFileDialog::ShowDirsOnly
+																			| QFileDialog::DontResolveSymlinks);
+						if (dir.isEmpty())
+							return;
+						paths.insert(Strings::ToUtf8String(dir));
+						QListWidgetItem* item = new QListWidgetItem(listwidget);
+						item->setText(dir);
+					});
+
+					widget_layout->addWidget(button);
+				}
+
+				{
+					QPushButton* button = new QPushButton(tr("Remove"), widget);
+
+					connect(listwidget, &QListWidget::itemSelectionChanged, this, [button, listwidget]{
+						QList<QListWidgetItem*> selection = listwidget->selectedItems();
+						button->setEnabled(selection.size() > 0);
+					});
+
+					connect(button, &QPushButton::clicked, this, [this, listwidget]{
+						QList<QListWidgetItem*> selection = listwidget->selectedItems();
+						for (const auto& item : selection) {
+							paths.erase(Strings::ToUtf8String(item->text()));
+							delete item;
+						}
+					});
+
+					widget_layout->addWidget(button);
+				}
+
+				group_box_layout->addWidget(widget);
+			}
+		}
+
+		full_layout->addWidget(group_box);
+	}
+
+	{
+		QGroupBox* group_box = new QGroupBox(tr("Real-time monitor"), result);
+		group_box->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
+
+		QVBoxLayout* group_box_layout = new QVBoxLayout(group_box);
+
+		{
+			QCheckBox* checkbox = new QCheckBox(tr("Detect new files and folders under library folders"), group_box);
+			checkbox->setCheckState(real_time_monitor ? Qt::Checked : Qt::Unchecked);
+
+			connect(checkbox, &QCheckBox::stateChanged, this, [this](int state) {
+				real_time_monitor = (state != Qt::Unchecked);
+			});
+
+			group_box_layout->addWidget(checkbox);
+		}
+
+		full_layout->addWidget(group_box);
+	}
+
+	full_layout->setSpacing(10);
+	full_layout->addStretch();
+
+	return result;
+}
+
+void SettingsPageLibrary::SaveInfo() {
+	session.config.library.paths = paths;
+	session.config.library.real_time_monitor = real_time_monitor;
+}
+
+SettingsPageLibrary::SettingsPageLibrary(QWidget* parent)
+	: SettingsPage(parent, tr("Library")),
+	  paths(session.config.library.paths) {
+	real_time_monitor = session.config.library.real_time_monitor;
+	AddTab(CreateFoldersWidget(), tr("Folder"));
+}
+
+#include "gui/dialog/settings/library.moc"
--- a/src/gui/window.cc	Sat Jan 13 09:42:02 2024 -0500
+++ b/src/gui/window.cc	Sat Jan 13 09:43:41 2024 -0500
@@ -16,13 +16,16 @@
 #include "gui/widgets/sidebar.h"
 #include "services/services.h"
 #include "track/media.h"
+#include "library/library.h"
 
 #include "anitomy/anitomy.h"
 
 #include <QActionGroup>
 #include <QApplication>
 #include <QDebug>
+#include <QDesktopServices>
 #include <QFile>
+#include <QFileDialog>
 #include <QHBoxLayout>
 #include <QMainWindow>
 #include <QMenuBar>
@@ -154,25 +157,52 @@
 }
 
 void MainWindow::CreateBars() {
-	/* Menu Bar
-	   The notation of these might seem ugly at first, but it's actually very nice
-	   (just trust me). It makes it much easier to edit the lists and makes it clear
-	   if you're in submenu or not. */
 	QMenuBar* menubar = new QMenuBar(this);
+	QMenu* folder_menu; /* this is used twice, so we declare it here */
 
 	{
 		/* File */
 		QMenu* menu = menubar->addMenu(tr("&File"));
 
 		{
-			QMenu* submenu = menu->addMenu(tr("&Library folders"));
+			folder_menu = menu->addMenu(tr("&Library folders"));
+
+			/* add in all of our existing folders... */
+			std::size_t i = 0;
+			for (const auto& path : session.config.library.paths) {
+				const QString folder = Strings::ToQString(path);
+				QAction* action = folder_menu->addAction(folder, [folder]{
+					QDesktopServices::openUrl(QUrl::fromLocalFile(folder));
+				});
+				if (i < 9)
+					action->setShortcut(QKeySequence(Qt::ALT | static_cast<Qt::Modifier>(Qt::Key_1 + i)));
+				else if (i == 9)
+					action->setShortcut(QKeySequence(Qt::ALT | Qt::Key_0));
+				/* don't bother with a shortcut in case of more... */
+				i++;
+			}
+
+			folder_menu->addSeparator();
+
 			{
-				QAction* action = submenu->addAction(tr("&Add new folder..."));
+				folder_menu->addAction(tr("&Add new folder..."), [this]{
+					const QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"),
+																		  QDir::homePath(),
+																		  QFileDialog::ShowDirsOnly
+																		  | QFileDialog::DontResolveSymlinks);
+					if (dir.isEmpty())
+						return;
+					session.config.library.paths.insert(Strings::ToUtf8String(dir));
+					/* we have to recreate the menu bar to add the new folder */
+					CreateBars();
+				});
 			}
 		}
 
 		{
-			QAction* action = menu->addAction(tr("&Scan available episodes"));
+			menu->addAction(tr("&Scan available episodes"), []{
+				Library::SearchLibraryFolders();
+			});
 		}
 
 		menu->addSeparator();
@@ -191,6 +221,7 @@
 
 		{
 			QAction* action = menu->addAction(tr("E&xit"), qApp, &QApplication::quit);
+			action->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q));
 		}
 	}
 
@@ -384,10 +415,7 @@
 		{
 			QToolButton* button = new QToolButton(toolbar);
 			{
-				QMenu* menu = new QMenu(button);
-				QAction* action = menu->addAction(tr("..."));
-
-				button->setMenu(menu);
+				button->setMenu(folder_menu);
 			}
 			button->setIcon(QIcon(":/icons/24x24/folder-open.png"));
 			button->setPopupMode(QToolButton::InstantPopup);
@@ -398,8 +426,31 @@
 			QToolButton* button = new QToolButton(toolbar);
 
 			{
+				/* links */
 				QMenu* menu = new QMenu(button);
-				QAction* action = menu->addAction(tr("..."));
+				menu->addAction("Hibari", []{
+					QDesktopServices::openUrl(QUrl("https://hb.wopian.me/"));
+				});
+				menu->addAction("MALgraph", []{
+					QDesktopServices::openUrl(QUrl("https://graph.anime.plus/"));
+				});
+				menu->addSeparator();
+				menu->addAction("AniChart", []{
+					QDesktopServices::openUrl(QUrl("https://anichart.net/airing"));
+				});
+				menu->addAction("Monthly.moe", []{
+					QDesktopServices::openUrl(QUrl("https://www.monthly.moe/weekly"));
+				});
+				menu->addAction("Senpai Anime Charts", []{
+					QDesktopServices::openUrl(QUrl("https://www.senpai.moe/?mode=calendar"));
+				});
+				menu->addSeparator();
+				menu->addAction("Anime Streaming Search Engine", []{
+					QDesktopServices::openUrl(QUrl("https://because.moe/"));
+				});
+				menu->addAction("The Fansub Database", []{
+					QDesktopServices::openUrl(QUrl("https://fansubdb.com"));
+				});
 
 				button->setMenu(menu);
 			}
--- a/src/library/library.cc	Sat Jan 13 09:42:02 2024 -0500
+++ b/src/library/library.cc	Sat Jan 13 09:43:41 2024 -0500
@@ -9,19 +9,23 @@
 #include <unordered_map>
 #include <string>
 
+#include <iostream>
+
+namespace Library {
+
 // int = anime id, map = episode, paths
 std::unordered_map<int, std::unordered_map<int, std::string>> library;
 
 void SearchLibraryFolders() {
 	library.clear();
 
-	for (const auto& spath : session.config.library.paths) {
-		const std::filesystem::path path(spath);
-		for (const auto& entry : std::filesystem::recursive_directory_iterator(path)) {
-			if (!std::filesystem::is_regular_file(entry.path()))
+	for (const auto& folder : session.config.library.paths) {
+		for (const auto& entry : std::filesystem::recursive_directory_iterator(folder)) {
+			const std::filesystem::path path = entry.path();
+			if (!std::filesystem::is_regular_file(path))
 				continue;
 
-			const std::string basename = path.filename();
+			const std::string basename = path.filename().u8string();
 
 			anitomy::Anitomy anitomy;
 			anitomy.Parse(Strings::ToWstring(basename));
@@ -34,10 +38,12 @@
 			if (id <= 0)
 				continue;
 
-			const int episode = Strings::ToInt(Strings::ToUtf8String(elements.get(anitomy::kElementAnimeTitle)));
+			const int episode = Strings::ToInt(Strings::ToUtf8String(elements.get(anitomy::kElementEpisodeNumber)));
 
 			// we have an ID now!
-			library[id][episode] = entry.path();
+			library[id][episode] = path.u8string();
 		}
 	}
 }
+
+}
--- a/src/services/anilist.cc	Sat Jan 13 09:42:02 2024 -0500
+++ b/src/services/anilist.cc	Sat Jan 13 09:43:41 2024 -0500
@@ -30,9 +30,6 @@
 
 class Account {
 	public:
-		std::string Username() const { return session.config.auth.anilist.username; }
-		void SetUsername(std::string const& username) { session.config.auth.anilist.username = username; }
-
 		int UserId() const { return session.config.auth.anilist.user_id; }
 		void SetUserId(const int id) { session.config.auth.anilist.user_id = id; }
 
@@ -300,7 +297,6 @@
 }
 
 int ParseUser(const nlohmann::json& json) {
-	account.SetUsername(JSON::GetString<std::string>(json, "/name"_json_pointer, ""));
 	account.SetUserId(JSON::GetNumber(json, "/id"_json_pointer, 0));
 	return account.UserId();
 }
--- a/src/track/media.cc	Sat Jan 13 09:42:02 2024 -0500
+++ b/src/track/media.cc	Sat Jan 13 09:43:41 2024 -0500
@@ -11,8 +11,6 @@
 #include <vector>
 #include <filesystem>
 
-#include <iostream>
-
 #include "animia.h"
 
 namespace Track {