From c949aa9b78cd7f901ab43c8d270f1c0b32e78f16 Mon Sep 17 00:00:00 2001 From: WaTh Date: Sat, 24 Jan 2026 21:09:26 +0100 Subject: [PATCH 1/2] feat: Add donation key functionality for faster downloads --- lib/main.dart | 7 ++++++ lib/services/annas_archieve.dart | 32 ++++++++++++++++++------- lib/state/state.dart | 5 +++- lib/ui/settings_page.dart | 40 ++++++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 10 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 63f6889..27e383a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -38,6 +38,7 @@ import 'package:openlib/state/state.dart' autoRankInstancesProvider, userAgentProvider, cookieProvider, + donationKeyProvider, selectedTypeState, selectedSortState, selectedFileTypeState, @@ -111,6 +112,11 @@ void main(List args) async { .catchError((e) => 'All') as String? ?? 'All'; + String savedDonationKey = await dataBase + .getPreference('donationKey') + .catchError((e) => '') as String? ?? + ''; + // Check onboarding status bool onboardingCompleted = await dataBase .getPreference('onboardingCompleted') @@ -136,6 +142,7 @@ void main(List args) async { .overrideWith((ref) => openEpubwithExternalapp), showManualDownloadButtonProvider .overrideWith((ref) => showManualDownloadButton), + donationKeyProvider.overrideWith((ref) => savedDonationKey), userAgentProvider.overrideWith((ref) => browserUserAgent), cookieProvider.overrideWith((ref) => browserCookie), selectedTypeState.overrideWith((ref) => savedType), diff --git a/lib/services/annas_archieve.dart b/lib/services/annas_archieve.dart index fd9d27a..5f9ab4c 100644 --- a/lib/services/annas_archieve.dart +++ b/lib/services/annas_archieve.dart @@ -285,18 +285,31 @@ class AnnasArchieve { // _bookInfoParser FUNCTION (Detail Page - Fixed 'unable to get data' error) // -------------------------------------------------------------------- Future _bookInfoParser( - resData, url, String currentBaseUrl) async { + resData, url, String currentBaseUrl, String? donationKey) async { var document = parse(resData.toString()); final main = document.querySelector('div.main-inner'); if (main == null) return null; // --- Mirror Link Extraction --- String? mirror; - final slowDownloadLinks = - main.querySelectorAll('ul.list-inside a[href*="/slow_download/"]'); - if (slowDownloadLinks.isNotEmpty && - slowDownloadLinks.first.attributes['href'] != null) { - mirror = currentBaseUrl + slowDownloadLinks.first.attributes['href']!; + + if (donationKey != null && donationKey.isNotEmpty) { + final fastDownloadLinks = + main.querySelectorAll('ul.list-inside a[href*="/fast_download/"]'); + if (fastDownloadLinks.isNotEmpty && + fastDownloadLinks.first.attributes['href'] != null) { + mirror = + "$currentBaseUrl${fastDownloadLinks.first.attributes['href']!}?key=$donationKey"; + } + } + + if (mirror == null) { + final slowDownloadLinks = + main.querySelectorAll('ul.list-inside a[href*="/slow_download/"]'); + if (slowDownloadLinks.isNotEmpty && + slowDownloadLinks.first.attributes['href'] != null) { + mirror = currentBaseUrl + slowDownloadLinks.first.attributes['href']!; + } } // -------------------------------- @@ -487,7 +500,8 @@ class AnnasArchieve { } } - Future bookInfo({required String url}) async { + Future bookInfo( + {required String url, String? donationKey}) async { _logger.info('Fetching book info', tag: 'AnnasArchive', metadata: {'url': url}); @@ -524,8 +538,8 @@ class AnnasArchieve { ); } - BookInfoData? data = - await _bookInfoParser(response.data, adjustedUrl, currentBaseUrl); + BookInfoData? data = await _bookInfoParser( + response.data, adjustedUrl, currentBaseUrl, donationKey); if (data != null) { return data; } else { diff --git a/lib/state/state.dart b/lib/state/state.dart index 8377f0b..194cfe7 100644 --- a/lib/state/state.dart +++ b/lib/state/state.dart @@ -173,6 +173,7 @@ final searchQueryProvider = StateProvider((ref) => ""); final enableFiltersState = StateProvider((ref) => true); // Web/Download States +final donationKeyProvider = StateProvider((ref) => ""); final cookieProvider = StateProvider((ref) => ""); final userAgentProvider = StateProvider((ref) => ""); final webViewLoadingState = StateProvider.autoDispose((ref) => true); @@ -346,7 +347,9 @@ final searchProvider = FutureProvider.family final bookInfoProvider = FutureProvider.family((ref, url) async { final AnnasArchieve annasArchieve = AnnasArchieve(); - BookInfoData data = await annasArchieve.bookInfo(url: url); + final donationKey = ref.watch(donationKeyProvider); + BookInfoData data = + await annasArchieve.bookInfo(url: url, donationKey: donationKey); return data; }); diff --git a/lib/ui/settings_page.dart b/lib/ui/settings_page.dart index 3330f0d..4788952 100644 --- a/lib/ui/settings_page.dart +++ b/lib/ui/settings_page.dart @@ -30,6 +30,7 @@ import 'package:openlib/state/state.dart' instanceManagerProvider, currentInstanceProvider, archiveInstancesProvider, + donationKeyProvider, myLibraryProvider; // Scans a directory for book files (epub, pdf) and imports them to the library database @@ -252,6 +253,45 @@ class SettingsPage extends ConsumerWidget { dataBase.savePreference('showManualDownloadButton', val); }, ), + _buildSettingTile( + context, + title: "Anna's Archive Donation Key", + subtitle: "Enter key for faster downloads", + icon: Icons.key, + onTap: () { + final currentKey = ref.read(donationKeyProvider); + final controller = TextEditingController(text: currentKey); + showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text("Donation Key"), + content: TextField( + controller: controller, + decoration: const InputDecoration( + hintText: "Enter your key", + helperText: + "Used for faster downloads on Anna's Archive", + ), + ), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: const Text("Cancel"), + ), + TextButton( + onPressed: () { + final newKey = controller.text.trim(); + ref.read(donationKeyProvider.notifier).state = newKey; + dataBase.savePreference('donationKey', newKey); + Navigator.pop(context); + }, + child: const Text("Save"), + ), + ], + ), + ); + }, + ), const SizedBox(height: 20), _buildSectionHeader(context, "About"), _buildSettingTile( From 055b4bf14ea18de6ad4f06bd00b9d10f1c9798f2 Mon Sep 17 00:00:00 2001 From: WaTh Date: Sat, 24 Jan 2026 21:29:41 +0100 Subject: [PATCH 2/2] update theme --- lib/ui/settings_page.dart | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/ui/settings_page.dart b/lib/ui/settings_page.dart index 4788952..e1499e3 100644 --- a/lib/ui/settings_page.dart +++ b/lib/ui/settings_page.dart @@ -276,7 +276,15 @@ class SettingsPage extends ConsumerWidget { actions: [ TextButton( onPressed: () => Navigator.pop(context), - child: const Text("Cancel"), + child: Text( + "Cancel", + style: TextStyle( + color: + Theme.of(context).brightness == Brightness.light + ? Colors.black + : Colors.white, + ), + ), ), TextButton( onPressed: () { @@ -285,7 +293,15 @@ class SettingsPage extends ConsumerWidget { dataBase.savePreference('donationKey', newKey); Navigator.pop(context); }, - child: const Text("Save"), + child: Text( + "Save", + style: TextStyle( + color: + Theme.of(context).brightness == Brightness.light + ? Colors.black + : Colors.white, + ), + ), ), ], ),