diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 7b91dc20..fe6bff5e 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -476,5 +476,6 @@ "return_to_the_list_of_chapters": "Return to the list of chapters", "hwdec": "Hardware Decoder", "track_library_add": "Add to local library", - "track_library_add_confirm": "Add tracked item to local library" + "track_library_add_confirm": "Add tracked item to local library", + "track_library_not_logged": "Login to the corresponding tracker to use this feature!" } \ No newline at end of file diff --git a/lib/l10n/generated/app_localizations.dart b/lib/l10n/generated/app_localizations.dart index b23933d4..e77aec25 100644 --- a/lib/l10n/generated/app_localizations.dart +++ b/lib/l10n/generated/app_localizations.dart @@ -2981,6 +2981,12 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'Add tracked item to local library'** String get track_library_add_confirm; + + /// No description provided for @track_library_not_logged. + /// + /// In en, this message translates to: + /// **'Login to the corresponding tracker to use this feature!'** + String get track_library_not_logged; } class _AppLocalizationsDelegate diff --git a/lib/l10n/generated/app_localizations_ar.dart b/lib/l10n/generated/app_localizations_ar.dart index b1dd9ce9..6f2214ed 100644 --- a/lib/l10n/generated/app_localizations_ar.dart +++ b/lib/l10n/generated/app_localizations_ar.dart @@ -1523,4 +1523,8 @@ class AppLocalizationsAr extends AppLocalizations { @override String get track_library_add_confirm => 'Add tracked item to local library'; + + @override + String get track_library_not_logged => + 'Login to the corresponding tracker to use this feature!'; } diff --git a/lib/l10n/generated/app_localizations_de.dart b/lib/l10n/generated/app_localizations_de.dart index c3339885..5a6a09ed 100644 --- a/lib/l10n/generated/app_localizations_de.dart +++ b/lib/l10n/generated/app_localizations_de.dart @@ -1534,4 +1534,8 @@ class AppLocalizationsDe extends AppLocalizations { @override String get track_library_add_confirm => 'Add tracked item to local library'; + + @override + String get track_library_not_logged => + 'Login to the corresponding tracker to use this feature!'; } diff --git a/lib/l10n/generated/app_localizations_en.dart b/lib/l10n/generated/app_localizations_en.dart index c5451cb2..04589fb8 100644 --- a/lib/l10n/generated/app_localizations_en.dart +++ b/lib/l10n/generated/app_localizations_en.dart @@ -1523,4 +1523,8 @@ class AppLocalizationsEn extends AppLocalizations { @override String get track_library_add_confirm => 'Add tracked item to local library'; + + @override + String get track_library_not_logged => + 'Login to the corresponding tracker to use this feature!'; } diff --git a/lib/l10n/generated/app_localizations_es.dart b/lib/l10n/generated/app_localizations_es.dart index 710c1a42..b7f9abe1 100644 --- a/lib/l10n/generated/app_localizations_es.dart +++ b/lib/l10n/generated/app_localizations_es.dart @@ -1540,6 +1540,10 @@ class AppLocalizationsEs extends AppLocalizations { @override String get track_library_add_confirm => 'Add tracked item to local library'; + + @override + String get track_library_not_logged => + 'Login to the corresponding tracker to use this feature!'; } /// The translations for Spanish Castilian, as used in Latin America and the Caribbean (`es_419`). diff --git a/lib/l10n/generated/app_localizations_fr.dart b/lib/l10n/generated/app_localizations_fr.dart index 685d04e3..9eaae6e2 100644 --- a/lib/l10n/generated/app_localizations_fr.dart +++ b/lib/l10n/generated/app_localizations_fr.dart @@ -1545,4 +1545,8 @@ class AppLocalizationsFr extends AppLocalizations { @override String get track_library_add_confirm => 'Add tracked item to local library'; + + @override + String get track_library_not_logged => + 'Login to the corresponding tracker to use this feature!'; } diff --git a/lib/l10n/generated/app_localizations_id.dart b/lib/l10n/generated/app_localizations_id.dart index 9cc3c166..0fce0934 100644 --- a/lib/l10n/generated/app_localizations_id.dart +++ b/lib/l10n/generated/app_localizations_id.dart @@ -1529,4 +1529,8 @@ class AppLocalizationsId extends AppLocalizations { @override String get track_library_add_confirm => 'Add tracked item to local library'; + + @override + String get track_library_not_logged => + 'Login to the corresponding tracker to use this feature!'; } diff --git a/lib/l10n/generated/app_localizations_it.dart b/lib/l10n/generated/app_localizations_it.dart index c5ca5550..1ee64993 100644 --- a/lib/l10n/generated/app_localizations_it.dart +++ b/lib/l10n/generated/app_localizations_it.dart @@ -1539,4 +1539,8 @@ class AppLocalizationsIt extends AppLocalizations { @override String get track_library_add_confirm => 'Add tracked item to local library'; + + @override + String get track_library_not_logged => + 'Login to the corresponding tracker to use this feature!'; } diff --git a/lib/l10n/generated/app_localizations_pt.dart b/lib/l10n/generated/app_localizations_pt.dart index a6c821d0..3199c159 100644 --- a/lib/l10n/generated/app_localizations_pt.dart +++ b/lib/l10n/generated/app_localizations_pt.dart @@ -1537,6 +1537,10 @@ class AppLocalizationsPt extends AppLocalizations { @override String get track_library_add_confirm => 'Add tracked item to local library'; + + @override + String get track_library_not_logged => + 'Login to the corresponding tracker to use this feature!'; } /// The translations for Portuguese, as used in Brazil (`pt_BR`). diff --git a/lib/l10n/generated/app_localizations_ru.dart b/lib/l10n/generated/app_localizations_ru.dart index eb0fd83b..5f0314c2 100644 --- a/lib/l10n/generated/app_localizations_ru.dart +++ b/lib/l10n/generated/app_localizations_ru.dart @@ -1539,4 +1539,8 @@ class AppLocalizationsRu extends AppLocalizations { @override String get track_library_add_confirm => 'Add tracked item to local library'; + + @override + String get track_library_not_logged => + 'Login to the corresponding tracker to use this feature!'; } diff --git a/lib/l10n/generated/app_localizations_th.dart b/lib/l10n/generated/app_localizations_th.dart index c211a536..9c6636c8 100644 --- a/lib/l10n/generated/app_localizations_th.dart +++ b/lib/l10n/generated/app_localizations_th.dart @@ -1524,4 +1524,8 @@ class AppLocalizationsTh extends AppLocalizations { @override String get track_library_add_confirm => 'Add tracked item to local library'; + + @override + String get track_library_not_logged => + 'Login to the corresponding tracker to use this feature!'; } diff --git a/lib/l10n/generated/app_localizations_tr.dart b/lib/l10n/generated/app_localizations_tr.dart index 8d8fe75b..fa5dae13 100644 --- a/lib/l10n/generated/app_localizations_tr.dart +++ b/lib/l10n/generated/app_localizations_tr.dart @@ -1530,4 +1530,8 @@ class AppLocalizationsTr extends AppLocalizations { @override String get track_library_add_confirm => 'Add tracked item to local library'; + + @override + String get track_library_not_logged => + 'Login to the corresponding tracker to use this feature!'; } diff --git a/lib/l10n/generated/app_localizations_zh.dart b/lib/l10n/generated/app_localizations_zh.dart index 1d662e5a..1cb3af64 100644 --- a/lib/l10n/generated/app_localizations_zh.dart +++ b/lib/l10n/generated/app_localizations_zh.dart @@ -1492,4 +1492,8 @@ class AppLocalizationsZh extends AppLocalizations { @override String get track_library_add_confirm => 'Add tracked item to local library'; + + @override + String get track_library_not_logged => + 'Login to the corresponding tracker to use this feature!'; } diff --git a/lib/modules/manga/detail/providers/track_state_providers.dart b/lib/modules/manga/detail/providers/track_state_providers.dart index d7f80ab5..3e186fe9 100644 --- a/lib/modules/manga/detail/providers/track_state_providers.dart +++ b/lib/modules/manga/detail/providers/track_state_providers.dart @@ -139,15 +139,15 @@ class TrackState extends _$TrackState { return await tracker.search(query, _isManga); } - Future?> fetchGeneralData({ - String rankingType = "airing", - }) async { + Future?> fetchGeneralData({String? rankingType}) async { final syncId = track!.syncId!; final tracker = getNotifier(syncId); - return await tracker.fetchGeneralData( - isManga: _isManga, - rankingType: rankingType, - ); + return rankingType != null + ? await tracker.fetchGeneralData( + isManga: _isManga, + rankingType: rankingType, + ) + : await tracker.fetchGeneralData(isManga: _isManga); } Future?> fetchUserData() async { diff --git a/lib/modules/manga/detail/providers/track_state_providers.g.dart b/lib/modules/manga/detail/providers/track_state_providers.g.dart index 718848a6..c4449b4d 100644 --- a/lib/modules/manga/detail/providers/track_state_providers.g.dart +++ b/lib/modules/manga/detail/providers/track_state_providers.g.dart @@ -6,7 +6,7 @@ part of 'track_state_providers.dart'; // RiverpodGenerator // ************************************************************************** -String _$trackStateHash() => r'b10c02c2e50eb1f044a76560093a8dcf232487c5'; +String _$trackStateHash() => r'b70770f8524a0d9059ffd3f52b42634c16672a0f'; /// Copied from Dart SDK class _SystemHash { diff --git a/lib/modules/more/settings/browse/providers/browse_state_provider.g.dart b/lib/modules/more/settings/browse/providers/browse_state_provider.g.dart index 7d0ade03..2a58eb3d 100644 --- a/lib/modules/more/settings/browse/providers/browse_state_provider.g.dart +++ b/lib/modules/more/settings/browse/providers/browse_state_provider.g.dart @@ -175,7 +175,7 @@ final onlyIncludePinnedSourceStateProvider = typedef _$OnlyIncludePinnedSourceState = AutoDisposeNotifier; String _$extensionsRepoStateHash() => - r'9e59b257433ed7f999dd4800f6ecb8c13c8b2c6a'; + r'3ea91c79a9bc24f086fce49de2c61a1e06bad1fe'; abstract class _$ExtensionsRepoState extends BuildlessAutoDisposeNotifier> { diff --git a/lib/modules/tracker_library/tracker_library_screen.dart b/lib/modules/tracker_library/tracker_library_screen.dart index 03da3135..676367d9 100644 --- a/lib/modules/tracker_library/tracker_library_screen.dart +++ b/lib/modules/tracker_library/tracker_library_screen.dart @@ -3,11 +3,11 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:go_router/go_router.dart'; import 'package:isar/isar.dart'; import 'package:mangayomi/main.dart'; import 'package:mangayomi/models/manga.dart'; import 'package:mangayomi/models/track.dart'; +import 'package:mangayomi/models/track_preference.dart'; import 'package:mangayomi/models/track_search.dart'; import 'package:mangayomi/modules/manga/detail/providers/track_state_providers.dart'; import 'package:mangayomi/modules/tracker_library/tracker_item_card.dart'; @@ -59,6 +59,7 @@ class TrackerLibraryScreen extends ConsumerStatefulWidget { class _TrackerLibraryScreenState extends ConsumerState { @override Widget build(BuildContext context) { + final l10n = l10nLocalizations(context)!; final sections = switch (widget.trackerProvider.syncId) { 1 => _sectionsMAL(), 2 => _sectionsAL(), @@ -70,15 +71,36 @@ class _TrackerLibraryScreenState extends ConsumerState { appBar: AppBar(title: Text(widget.trackerProvider.name)), body: Padding( padding: const EdgeInsets.all(15), - child: SuperListView.builder( - itemCount: sections.length, - extentPrecalculationPolicy: SuperPrecalculationPolicy(), - itemBuilder: (context, index) { - final section = sections[index]; - return SizedBox( - height: 260, - child: TrackerSectionScreen(section: section), - ); + child: StreamBuilder( + stream: isar.trackPreferences + .filter() + .syncIdEqualTo(widget.trackerProvider.syncId) + .watch(fireImmediately: true), + builder: (context, snapshot) { + List entries = snapshot.hasData + ? snapshot.data ?? [] + : []; + return entries.isNotEmpty + ? SuperListView.builder( + itemCount: sections.length, + extentPrecalculationPolicy: SuperPrecalculationPolicy(), + itemBuilder: (context, index) { + final section = sections[index]; + return SizedBox( + height: 260, + child: TrackerSectionScreen(section: section), + ); + }, + ) + : Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [Text(l10n.track_library_not_logged)], + ), + ], + ); }, ), ), @@ -133,18 +155,18 @@ class _TrackerLibraryScreenState extends ConsumerState { List _sectionsKitsu() { return [ TrackLibrarySection( - name: "Airing Anime", + name: "Popular Anime", func: _fetchGeneralData(ItemType.anime), itemType: ItemType.anime, ), TrackLibrarySection( - name: "Popular Anime", - func: _fetchGeneralData(ItemType.anime, rankingType: "bypopularity"), + name: "Latest Anime", + func: _fetchGeneralData(ItemType.anime, rankingType: "-updatedAt"), itemType: ItemType.anime, ), TrackLibrarySection( - name: "Upcoming Anime", - func: _fetchGeneralData(ItemType.anime, rankingType: "upcoming"), + name: "Best Rated Anime", + func: _fetchGeneralData(ItemType.anime, rankingType: "-averageRating"), itemType: ItemType.anime, ), TrackLibrarySection( @@ -154,11 +176,15 @@ class _TrackerLibraryScreenState extends ConsumerState { ), TrackLibrarySection( name: "Popular Manga", - func: _fetchGeneralData(ItemType.manga, rankingType: "bypopularity"), + func: _fetchGeneralData(ItemType.manga), ), TrackLibrarySection( - name: "Top Manga", - func: _fetchGeneralData(ItemType.manga, rankingType: "manga"), + name: "Latest Manga", + func: _fetchGeneralData(ItemType.manga, rankingType: "-updatedAt"), + ), + TrackLibrarySection( + name: "Best Rated Manga", + func: _fetchGeneralData(ItemType.manga, rankingType: "-averageRating"), ), TrackLibrarySection( name: "Continue reading", @@ -170,18 +196,33 @@ class _TrackerLibraryScreenState extends ConsumerState { List _sectionsAL() { return [ TrackLibrarySection( - name: "Airing Anime", + name: "Upcoming Anime", func: _fetchGeneralData(ItemType.anime), itemType: ItemType.anime, ), TrackLibrarySection( name: "Popular Anime", - func: _fetchGeneralData(ItemType.anime, rankingType: "bypopularity"), + func: _fetchGeneralData( + ItemType.anime, + rankingType: "sort: POPULARITY_DESC", + ), itemType: ItemType.anime, ), TrackLibrarySection( - name: "Upcoming Anime", - func: _fetchGeneralData(ItemType.anime, rankingType: "upcoming"), + name: "Trending Anime", + func: _fetchGeneralData( + ItemType.anime, + rankingType: "sort: TRENDING_DESC", + ), + itemType: ItemType.anime, + ), + TrackLibrarySection( + name: "Latest Anime", + func: _fetchGeneralData( + ItemType.anime, + rankingType: + "sort: [UPDATED_AT_DESC, POPULARITY_DESC], status: RELEASING", + ), itemType: ItemType.anime, ), TrackLibrarySection( @@ -189,21 +230,31 @@ class _TrackerLibraryScreenState extends ConsumerState { func: _fetchUserData(ItemType.anime), itemType: ItemType.anime, ), + TrackLibrarySection( + name: "Upcoming Manga", + func: _fetchGeneralData(ItemType.manga), + ), TrackLibrarySection( name: "Popular Manga", - func: _fetchGeneralData(ItemType.manga, rankingType: "bypopularity"), + func: _fetchGeneralData( + ItemType.manga, + rankingType: "sort: POPULARITY_DESC", + ), ), TrackLibrarySection( - name: "Top Manga", - func: _fetchGeneralData(ItemType.manga, rankingType: "manga"), + name: "Trending Manga", + func: _fetchGeneralData( + ItemType.manga, + rankingType: "sort: TRENDING_DESC", + ), ), TrackLibrarySection( - name: "Top Manhwa", - func: _fetchGeneralData(ItemType.manga, rankingType: "manhwa"), - ), - TrackLibrarySection( - name: "Top Manhua", - func: _fetchGeneralData(ItemType.manga, rankingType: "manhua"), + name: "Latest Manga", + func: _fetchGeneralData( + ItemType.manga, + rankingType: + "sort: [UPDATED_AT_DESC, POPULARITY_DESC], status: RELEASING", + ), ), TrackLibrarySection( name: "Continue reading", @@ -214,7 +265,7 @@ class _TrackerLibraryScreenState extends ConsumerState { Future?> Function() _fetchGeneralData( ItemType itemType, { - String rankingType = "airing", + String? rankingType, }) { return () async => await ref .read( @@ -279,6 +330,7 @@ class _TrackerSectionScreenState extends State { _isLoading = false; }); } + rethrow; } } diff --git a/lib/services/trackers/anilist.dart b/lib/services/trackers/anilist.dart index 64c67a28..3e6af970 100644 --- a/lib/services/trackers/anilist.dart +++ b/lib/services/trackers/anilist.dart @@ -221,6 +221,136 @@ class Anilist extends _$Anilist { ..totalChapter = jsonRes['media'][contentUnit] as int? ?? 0; } + Future> fetchGeneralData({ + bool isManga = true, + String rankingType = + "status: NOT_YET_RELEASED, sort: [POPULARITY_DESC, TRENDING_DESC]", + }) async { + final type = isManga ? "MANGA" : "ANIME"; + final contentUnit = isManga ? "chapters" : "episodes"; + final query = + ''' + query { + Page(perPage: 50) { + media(type: $type, format_not_in: [NOVEL], $rankingType) { + id + title { userPreferred } + coverImage { large } + format + status + $contentUnit + description + startDate { year month day } + averageScore + } + } + } + '''; + + final Map vars = {}; + + final data = await _executeGraphQL(query, vars); + + final entries = List>.from( + data['Page']['media'] as List, + ); + return entries + .map( + (jsonRes) => TrackSearch( + libraryId: jsonRes['id'], + syncId: syncId, + trackingUrl: "", + mediaId: jsonRes['id'], + summary: jsonRes['description'] ?? "", + totalChapter: jsonRes[contentUnit] ?? 0, + coverUrl: jsonRes['coverImage']['large'] ?? "", + title: jsonRes['title']['userPreferred'], + startDate: + jsonRes["start_date"] ?? + DateTime.fromMillisecondsSinceEpoch( + parseDate(jsonRes, 'startDate'), + ).toString(), + publishingType: "", + publishingStatus: jsonRes['status'], + score: jsonRes["averageScore"] != null + ? jsonRes["averageScore"] * 1.0 + : 0, + ), + ) + .toList(); + } + + Future> fetchUserData({bool isManga = true}) async { + final userId = int.parse( + ref.watch(tracksProvider(syncId: syncId))!.username!, + ); + final type = isManga ? "MANGA" : "ANIME"; + final contentUnit = isManga ? "chapters" : "episodes"; + + final query = + ''' + query(\$id: Int!) { + Page { + mediaList(userId: \$id, type: $type) { + id + status + scoreRaw: score(format: POINT_100) + progress + startedAt { year month day } + completedAt { year month day } + media { + id + title { userPreferred } + coverImage { large } + format + status + $contentUnit + description + startDate { year month day } + averageScore + } + } + } + } + '''; + + final vars = {"id": userId}; + + final data = await _executeGraphQL(query, vars); + + final entries = List>.from( + data['Page']['mediaList'] as List, + ); + return entries + .map( + (jsonRes) => TrackSearch( + libraryId: jsonRes['id'], + syncId: syncId, + trackingUrl: "", + mediaId: jsonRes['media']['id'], + summary: jsonRes['media']['description'] ?? "", + totalChapter: jsonRes['media'][contentUnit] ?? 0, + coverUrl: jsonRes['media']['coverImage']['large'] ?? "", + title: jsonRes['media']['title']['userPreferred'], + startDate: + jsonRes['media']["start_date"] ?? + DateTime.fromMillisecondsSinceEpoch( + parseDate(jsonRes['media'], 'startDate'), + ).toString(), + publishingType: "", + publishingStatus: jsonRes['media']['status'], + score: jsonRes['media']['averageScore'] != null + ? jsonRes['media']['averageScore'] * 1.0 + : 0, + status: _getALTrackStatus(jsonRes['status'], isManga).name, + lastChapterRead: jsonRes['progress'] as int? ?? 0, + startedReadingDate: parseDate(jsonRes, 'startedAt'), + finishedReadingDate: parseDate(jsonRes, 'completedAt'), + ), + ) + .toList(); + } + Future> _executeGraphQL( String document, Map variables, diff --git a/lib/services/trackers/anilist.g.dart b/lib/services/trackers/anilist.g.dart index 703c90a8..0b5fdfd8 100644 --- a/lib/services/trackers/anilist.g.dart +++ b/lib/services/trackers/anilist.g.dart @@ -6,7 +6,7 @@ part of 'anilist.dart'; // RiverpodGenerator // ************************************************************************** -String _$anilistHash() => r'd672e47052f0b40088dd477b7918dc1e06654b48'; +String _$anilistHash() => r'6f84817b91a4d9cbea7beacbaf1a77cbdeac9290'; /// Copied from Dart SDK class _SystemHash { diff --git a/lib/services/trackers/kitsu.dart b/lib/services/trackers/kitsu.dart index a94aaf18..9ed870ef 100644 --- a/lib/services/trackers/kitsu.dart +++ b/lib/services/trackers/kitsu.dart @@ -174,63 +174,97 @@ class Kitsu extends _$Kitsu { Future> fetchGeneralData({ bool isManga = true, - String rankingType = "airing", // /anime?sort=-updatedAt + String rankingType = "popularityRank", }) async { - final response = await http.get(Uri.parse("$_baseUrl/trending/anime")); + final response = await http.get( + Uri.parse("$_baseUrl${isManga ? "manga" : "anime"}?sort=$rankingType"), + ); final data = json.decode(response.body); final entries = List>.from( - data['hits'], + data['data'], ).where((element) => element["subtype"] != "novel").toList(); final totalChapter = isManga ? "chapterCount" : "episodeCount"; - return entries - .map( - (jsonRes) => TrackSearch( - libraryId: jsonRes['id'], - syncId: syncId, - trackingUrl: _mediaUrl(isManga ? 'manga' : 'anime', jsonRes['id']), - mediaId: jsonRes['id'], - summary: jsonRes['synopsis'] ?? "", - totalChapter: (jsonRes[totalChapter] ?? 0), - coverUrl: jsonRes['posterImage']['original'] ?? "", - title: jsonRes['canonicalTitle'], - startDate: "", - publishingType: (jsonRes["subtype"] ?? ""), - publishingStatus: jsonRes['endDate'] == null - ? "Publishing" - : "Finished", - ), - ) - .toList(); + return entries.map((jsonRes) { + final mediaId = jsonRes['id'] is String + ? int.parse(jsonRes['id']) + : jsonRes['id']; + final score = jsonRes['attributes']['averageRating'] is String + ? double.parse(jsonRes['attributes']['averageRating']) + : jsonRes['attributes']['averageRating']; + return TrackSearch( + libraryId: mediaId, + syncId: syncId, + trackingUrl: _mediaUrl(isManga ? 'manga' : 'anime', mediaId), + mediaId: mediaId, + summary: jsonRes['attributes']['synopsis'] ?? "", + totalChapter: (jsonRes['attributes'][totalChapter] ?? 0), + coverUrl: jsonRes['attributes']['posterImage']['original'] ?? "", + title: jsonRes['attributes']['canonicalTitle'], + startDate: "", + score: score, + publishingType: (jsonRes['attributes']['subtype'] ?? ""), + publishingStatus: jsonRes['attributes']['endDate'] == null + ? "Publishing" + : "Finished", + ); + }).toList(); } Future> fetchUserData({bool isManga = true}) async { - final response = await http.get(Uri.parse("$_baseUrl/trending/anime")); + final type = isManga ? "manga" : "anime"; + final userId = _getUserId(); + final accessToken = _getAccessToken(); + final response = await _makeGetRequest( + Uri.parse("${_baseUrl}library-entries").replace( + queryParameters: { + 'filter[user_id]': userId, + 'filter[kind]': type, + 'page[limit]': "100", + 'sort': "status,-progressed_at", + 'include': type, + }, + ), + accessToken, + ); final data = json.decode(response.body); - final entries = List>.from( - data['hits'], - ).where((element) => element["subtype"] != "novel").toList(); - final totalChapter = isManga ? "chapterCount" : "episodeCount"; - return entries - .map( - (jsonRes) => TrackSearch( - libraryId: jsonRes['id'], - syncId: syncId, - trackingUrl: _mediaUrl(isManga ? 'manga' : 'anime', jsonRes['id']), - mediaId: jsonRes['id'], - summary: jsonRes['synopsis'] ?? "", - totalChapter: (jsonRes[totalChapter] ?? 0), - coverUrl: jsonRes['posterImage']['original'] ?? "", - title: jsonRes['canonicalTitle'], - startDate: "", - publishingType: (jsonRes["subtype"] ?? ""), - publishingStatus: jsonRes['endDate'] == null - ? "Publishing" - : "Finished", - ), - ) - .toList(); + final totalChapter = type == 'manga' ? "chapterCount" : "episodeCount"; + + final List result = []; + final List dataList = data['data']; + final List includedList = data['included']; + for (int i = 0; i < dataList.length; i++) { + final obj = dataList[i]; + final attributes = obj["attributes"]; + final included = includedList[i]["attributes"]; + final id = int.parse(obj["id"]); + result.add( + TrackSearch( + libraryId: id, + mediaId: id, + syncId: syncId, + trackingUrl: _mediaUrl(type, id), + summary: included['synopsis'] ?? "", + totalChapter: included[totalChapter] ?? 0, + coverUrl: included['posterImage']['original'] ?? "", + title: included['canonicalTitle'], + startDate: "", + publishingType: (included["subtype"] ?? ""), + publishingStatus: included['endDate'] == null + ? "Publishing" + : "Finished", + score: included['averageRating'] is String + ? double.parse(included['averageRating']) + : included['averageRating'], + status: getKitsuTrackStatus(attributes["status"], type).name, + lastChapterRead: attributes["progress"], + startedReadingDate: _parseDate(attributes["startedAt"]), + finishedReadingDate: _parseDate(attributes["finishedAt"]), + ), + ); + } + return result; } Future findLibItem(Track track, bool isManga) async { diff --git a/lib/services/trackers/kitsu.g.dart b/lib/services/trackers/kitsu.g.dart index 2ad0f2bd..6ac7e3b1 100644 --- a/lib/services/trackers/kitsu.g.dart +++ b/lib/services/trackers/kitsu.g.dart @@ -6,7 +6,7 @@ part of 'kitsu.dart'; // RiverpodGenerator // ************************************************************************** -String _$kitsuHash() => r'59e556e6382198c1cbef094491d6329861ff2e75'; +String _$kitsuHash() => r'bcedbbc9460d79b4a026210261f63f77ec9958fd'; /// Copied from Dart SDK class _SystemHash { diff --git a/lib/services/trackers/myanimelist.dart b/lib/services/trackers/myanimelist.dart index 38d2d7e9..05e4f56f 100644 --- a/lib/services/trackers/myanimelist.dart +++ b/lib/services/trackers/myanimelist.dart @@ -152,7 +152,7 @@ class MyAnimeList extends _$MyAnimeList { Future> fetchGeneralData({ bool isManga = true, String rankingType = - "airing", // bypopularity, tv, upcoming - all, manga, manhwa, manhua + "airing", }) async { final accessToken = await _getAccessToken(); final item = isManga ? "manga" : "anime"; diff --git a/lib/services/trackers/myanimelist.g.dart b/lib/services/trackers/myanimelist.g.dart index cd13b058..a5fb9915 100644 --- a/lib/services/trackers/myanimelist.g.dart +++ b/lib/services/trackers/myanimelist.g.dart @@ -6,7 +6,7 @@ part of 'myanimelist.dart'; // RiverpodGenerator // ************************************************************************** -String _$myAnimeListHash() => r'eb483b6451d34e595bb770eefc0f673df13275b3'; +String _$myAnimeListHash() => r'5e1144313509b9556bd0da4246f9fb22d00722a5'; /// Copied from Dart SDK class _SystemHash {