mirror of
https://github.com/kodjodevf/mangayomi.git
synced 2026-04-21 11:51:57 +00:00
merged trackers together and added search
This commit is contained in:
parent
6088ac22f4
commit
92c167d585
28 changed files with 962 additions and 537 deletions
|
|
@ -477,5 +477,6 @@
|
|||
"hwdec": "Hardware Decoder",
|
||||
"track_library_add": "Add 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!"
|
||||
"track_library_not_logged": "Login to the corresponding tracker to use this feature!",
|
||||
"track_library_switch": "Switch to another tracker"
|
||||
}
|
||||
|
|
@ -2987,6 +2987,12 @@ abstract class AppLocalizations {
|
|||
/// In en, this message translates to:
|
||||
/// **'Login to the corresponding tracker to use this feature!'**
|
||||
String get track_library_not_logged;
|
||||
|
||||
/// No description provided for @track_library_switch.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Switch to another tracker'**
|
||||
String get track_library_switch;
|
||||
}
|
||||
|
||||
class _AppLocalizationsDelegate
|
||||
|
|
|
|||
|
|
@ -1527,4 +1527,7 @@ class AppLocalizationsAr extends AppLocalizations {
|
|||
@override
|
||||
String get track_library_not_logged =>
|
||||
'Login to the corresponding tracker to use this feature!';
|
||||
|
||||
@override
|
||||
String get track_library_switch => 'Switch to another tracker';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1538,4 +1538,7 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
@override
|
||||
String get track_library_not_logged =>
|
||||
'Login to the corresponding tracker to use this feature!';
|
||||
|
||||
@override
|
||||
String get track_library_switch => 'Switch to another tracker';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1527,4 +1527,7 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
@override
|
||||
String get track_library_not_logged =>
|
||||
'Login to the corresponding tracker to use this feature!';
|
||||
|
||||
@override
|
||||
String get track_library_switch => 'Switch to another tracker';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1544,6 +1544,9 @@ class AppLocalizationsEs extends AppLocalizations {
|
|||
@override
|
||||
String get track_library_not_logged =>
|
||||
'Login to the corresponding tracker to use this feature!';
|
||||
|
||||
@override
|
||||
String get track_library_switch => 'Switch to another tracker';
|
||||
}
|
||||
|
||||
/// The translations for Spanish Castilian, as used in Latin America and the Caribbean (`es_419`).
|
||||
|
|
|
|||
|
|
@ -1549,4 +1549,7 @@ class AppLocalizationsFr extends AppLocalizations {
|
|||
@override
|
||||
String get track_library_not_logged =>
|
||||
'Login to the corresponding tracker to use this feature!';
|
||||
|
||||
@override
|
||||
String get track_library_switch => 'Switch to another tracker';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1533,4 +1533,7 @@ class AppLocalizationsId extends AppLocalizations {
|
|||
@override
|
||||
String get track_library_not_logged =>
|
||||
'Login to the corresponding tracker to use this feature!';
|
||||
|
||||
@override
|
||||
String get track_library_switch => 'Switch to another tracker';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1543,4 +1543,7 @@ class AppLocalizationsIt extends AppLocalizations {
|
|||
@override
|
||||
String get track_library_not_logged =>
|
||||
'Login to the corresponding tracker to use this feature!';
|
||||
|
||||
@override
|
||||
String get track_library_switch => 'Switch to another tracker';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1541,6 +1541,9 @@ class AppLocalizationsPt extends AppLocalizations {
|
|||
@override
|
||||
String get track_library_not_logged =>
|
||||
'Login to the corresponding tracker to use this feature!';
|
||||
|
||||
@override
|
||||
String get track_library_switch => 'Switch to another tracker';
|
||||
}
|
||||
|
||||
/// The translations for Portuguese, as used in Brazil (`pt_BR`).
|
||||
|
|
|
|||
|
|
@ -1543,4 +1543,7 @@ class AppLocalizationsRu extends AppLocalizations {
|
|||
@override
|
||||
String get track_library_not_logged =>
|
||||
'Login to the corresponding tracker to use this feature!';
|
||||
|
||||
@override
|
||||
String get track_library_switch => 'Switch to another tracker';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1528,4 +1528,7 @@ class AppLocalizationsTh extends AppLocalizations {
|
|||
@override
|
||||
String get track_library_not_logged =>
|
||||
'Login to the corresponding tracker to use this feature!';
|
||||
|
||||
@override
|
||||
String get track_library_switch => 'Switch to another tracker';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1534,4 +1534,7 @@ class AppLocalizationsTr extends AppLocalizations {
|
|||
@override
|
||||
String get track_library_not_logged =>
|
||||
'Login to the corresponding tracker to use this feature!';
|
||||
|
||||
@override
|
||||
String get track_library_switch => 'Switch to another tracker';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1496,4 +1496,7 @@ class AppLocalizationsZh extends AppLocalizations {
|
|||
@override
|
||||
String get track_library_not_logged =>
|
||||
'Login to the corresponding tracker to use this feature!';
|
||||
|
||||
@override
|
||||
String get track_library_switch => 'Switch to another tracker';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -242,6 +242,8 @@ class Settings {
|
|||
|
||||
bool? clearChapterCacheOnAppLaunch;
|
||||
|
||||
String? lastTrackerLibraryLocation;
|
||||
|
||||
Settings({
|
||||
this.id = 227,
|
||||
this.displayType = DisplayType.compactGrid,
|
||||
|
|
@ -349,6 +351,7 @@ class Settings {
|
|||
this.mangaExtensionsRepo,
|
||||
this.animeExtensionsRepo,
|
||||
this.novelExtensionsRepo,
|
||||
this.lastTrackerLibraryLocation,
|
||||
});
|
||||
|
||||
Settings.fromJson(Map<String, dynamic> json) {
|
||||
|
|
@ -562,6 +565,7 @@ class Settings {
|
|||
.map((e) => Repo.fromJson(e))
|
||||
.toList();
|
||||
}
|
||||
lastTrackerLibraryLocation = json['lastTrackerLibraryLocation'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
|
|
@ -692,6 +696,7 @@ class Settings {
|
|||
'mangaExtensionsRepo': mangaExtensionsRepo?.map((e) => e.toJson()).toList(),
|
||||
'animeExtensionsRepo': animeExtensionsRepo?.map((e) => e.toJson()).toList(),
|
||||
'novelExtensionsRepo': novelExtensionsRepo?.map((e) => e.toJson()).toList(),
|
||||
'lastTrackerLibraryLocation': lastTrackerLibraryLocation,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -52,4 +52,38 @@ class TrackSearch {
|
|||
this.startDate = '',
|
||||
this.summary = '',
|
||||
});
|
||||
|
||||
TrackSearch.fromJson(Map<String, dynamic> json) {
|
||||
id = json['id'];
|
||||
libraryId = json['libraryId'];
|
||||
mediaId = json['mediaId'];
|
||||
syncId = json['syncId'];
|
||||
title = json['title'];
|
||||
lastChapterRead = json['lastChapterRead'];
|
||||
totalChapter = json['totalChapter'];
|
||||
score = json['score'];
|
||||
status = json['status'];
|
||||
startedReadingDate = json['startedReadingDate'];
|
||||
finishedReadingDate = json['finishedReadingDate'];
|
||||
trackingUrl = json['trackingUrl'];
|
||||
coverUrl = json['coverUrl'];
|
||||
publishingStatus = json['publishingStatus'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'id': id,
|
||||
'libraryId': libraryId,
|
||||
'mediaId': mediaId,
|
||||
'syncId': syncId,
|
||||
'title': title,
|
||||
'lastChapterRead': lastChapterRead,
|
||||
'totalChapter': totalChapter,
|
||||
'score': score,
|
||||
'status': status,
|
||||
'startedReadingDate': startedReadingDate,
|
||||
'finishedReadingDate': finishedReadingDate,
|
||||
'trackingUrl': trackingUrl,
|
||||
'coverUrl': coverUrl,
|
||||
'publishingStatus': publishingStatus,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -329,39 +329,13 @@ class _MainScreenState extends ConsumerState<MainScreen> {
|
|||
),
|
||||
);
|
||||
}
|
||||
if (dest.contains("/trackerLibrary/anilist")) {
|
||||
destinations[dest.indexOf(
|
||||
"/trackerLibrary/anilist",
|
||||
)] = NavigationRailDestination(
|
||||
if (dest.contains("/trackerLibrary")) {
|
||||
destinations[dest.indexOf("/trackerLibrary")] = NavigationRailDestination(
|
||||
selectedIcon: const Icon(Icons.account_tree),
|
||||
icon: const Icon(Icons.account_tree_outlined),
|
||||
label: Padding(
|
||||
padding: const EdgeInsets.only(top: 5),
|
||||
child: Text("AL"),
|
||||
),
|
||||
);
|
||||
}
|
||||
if (dest.contains("/trackerLibrary/kitsu")) {
|
||||
destinations[dest.indexOf(
|
||||
"/trackerLibrary/kitsu",
|
||||
)] = NavigationRailDestination(
|
||||
selectedIcon: const Icon(Icons.account_tree),
|
||||
icon: const Icon(Icons.account_tree_outlined),
|
||||
label: Padding(
|
||||
padding: const EdgeInsets.only(top: 5),
|
||||
child: Text("Kitsu"),
|
||||
),
|
||||
);
|
||||
}
|
||||
if (dest.contains("/trackerLibrary/mal")) {
|
||||
destinations[dest.indexOf(
|
||||
"/trackerLibrary/mal",
|
||||
)] = NavigationRailDestination(
|
||||
selectedIcon: const Icon(Icons.account_tree),
|
||||
icon: const Icon(Icons.account_tree_outlined),
|
||||
label: Padding(
|
||||
padding: const EdgeInsets.only(top: 5),
|
||||
child: Text("MAL"),
|
||||
child: Text(l10n.tracking),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
@ -448,29 +422,11 @@ class _MainScreenState extends ConsumerState<MainScreen> {
|
|||
label: l10n.more,
|
||||
);
|
||||
}
|
||||
if (dest.contains("/trackerLibrary/anilist")) {
|
||||
destinations[dest.indexOf(
|
||||
"/trackerLibrary/anilist",
|
||||
)] = NavigationDestination(
|
||||
if (dest.contains("/trackerLibrary")) {
|
||||
destinations[dest.indexOf("/trackerLibrary")] = NavigationDestination(
|
||||
selectedIcon: const Icon(Icons.account_tree),
|
||||
icon: const Icon(Icons.account_tree_outlined),
|
||||
label: "AL",
|
||||
);
|
||||
}
|
||||
if (dest.contains("/trackerLibrary/kitsu")) {
|
||||
destinations[dest.indexOf(
|
||||
"/trackerLibrary/kitsu",
|
||||
)] = NavigationDestination(
|
||||
selectedIcon: const Icon(Icons.account_tree),
|
||||
icon: const Icon(Icons.account_tree_outlined),
|
||||
label: "Kitsu",
|
||||
);
|
||||
}
|
||||
if (dest.contains("/trackerLibrary/mal")) {
|
||||
destinations[dest.indexOf("/trackerLibrary/mal")] = NavigationDestination(
|
||||
selectedIcon: const Icon(Icons.account_tree),
|
||||
icon: const Icon(Icons.account_tree_outlined),
|
||||
label: "MAL",
|
||||
label: l10n.tracking,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -592,9 +548,7 @@ class _TabletLayout extends StatelessWidget {
|
|||
'/updates',
|
||||
'/browse',
|
||||
'/more',
|
||||
'/trackerLibrary/anilist',
|
||||
'/trackerLibrary/kitsu',
|
||||
'/trackerLibrary/mal',
|
||||
'/trackerLibrary',
|
||||
};
|
||||
|
||||
return (location == null || validLocations.contains(location)) ? 100 : 0;
|
||||
|
|
@ -662,9 +616,7 @@ class _MobileBottomNavigation extends StatelessWidget {
|
|||
'/updates',
|
||||
'/browse',
|
||||
'/more',
|
||||
'/trackerLibrary/anilist',
|
||||
'/trackerLibrary/kitsu',
|
||||
'/trackerLibrary/mal',
|
||||
'/trackerLibrary',
|
||||
};
|
||||
|
||||
return (location == null || validLocations.contains(location)) ? null : 0;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/models/settings.dart';
|
||||
import 'package:mangayomi/models/track.dart';
|
||||
import 'package:mangayomi/models/track_search.dart';
|
||||
import 'package:mangayomi/modules/more/settings/track/providers/track_providers.dart';
|
||||
import 'package:mangayomi/modules/tracker_library/tracker_library_screen.dart';
|
||||
import 'package:mangayomi/services/trackers/anilist.dart';
|
||||
import 'package:mangayomi/services/trackers/kitsu.dart';
|
||||
import 'package:mangayomi/services/trackers/myanimelist.dart';
|
||||
|
|
@ -156,3 +159,26 @@ class TrackState extends _$TrackState {
|
|||
return await tracker.fetchUserData(isManga: _isManga);
|
||||
}
|
||||
}
|
||||
|
||||
@riverpod
|
||||
class LastTrackerLibraryLocationState
|
||||
extends _$LastTrackerLibraryLocationState {
|
||||
@override
|
||||
(int, bool) build() {
|
||||
final value = isar.settings.getSync(227)!.lastTrackerLibraryLocation;
|
||||
if (value != null) {
|
||||
final data = value.split(",");
|
||||
return (int.parse(data[0]), bool.parse(data[1]));
|
||||
}
|
||||
return (TrackerProviders.myAnimeList.syncId, false);
|
||||
}
|
||||
|
||||
void set((int, bool) value) {
|
||||
final settings = isar.settings.getSync(227);
|
||||
final val = "${value.$1},${value.$2}";
|
||||
state = value;
|
||||
isar.writeTxnSync(
|
||||
() => isar.settings.putSync(settings!..lastTrackerLibraryLocation = val),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -193,5 +193,23 @@ class _TrackStateProviderElement
|
|||
@override
|
||||
ItemType? get itemType => (origin as TrackStateProvider).itemType;
|
||||
}
|
||||
|
||||
String _$lastTrackerLibraryLocationStateHash() =>
|
||||
r'f1e13ed88277e26123c2384fbfd4992678ad498a';
|
||||
|
||||
/// See also [LastTrackerLibraryLocationState].
|
||||
@ProviderFor(LastTrackerLibraryLocationState)
|
||||
final lastTrackerLibraryLocationStateProvider = AutoDisposeNotifierProvider<
|
||||
LastTrackerLibraryLocationState, (int, bool)>.internal(
|
||||
LastTrackerLibraryLocationState.new,
|
||||
name: r'lastTrackerLibraryLocationStateProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$lastTrackerLibraryLocationStateHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef _$LastTrackerLibraryLocationState = AutoDisposeNotifier<(int, bool)>;
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
||||
|
|
|
|||
|
|
@ -25,9 +25,7 @@ final navigationItems = {
|
|||
"/history": "History",
|
||||
"/browse": "Browse",
|
||||
"/more": "More",
|
||||
"/trackerLibrary/anilist": "AL",
|
||||
"/trackerLibrary/kitsu": "Kitsu",
|
||||
"/trackerLibrary/mal": "MAL",
|
||||
"/trackerLibrary": "Tracking",
|
||||
};
|
||||
|
||||
class SettingsSection extends StatelessWidget {
|
||||
|
|
|
|||
|
|
@ -157,9 +157,7 @@ class NavigationOrderState extends _$NavigationOrderState {
|
|||
'/history',
|
||||
'/browse',
|
||||
'/more',
|
||||
'/trackerLibrary/anilist',
|
||||
'/trackerLibrary/kitsu',
|
||||
'/trackerLibrary/mal',
|
||||
'/trackerLibrary',
|
||||
];
|
||||
|
||||
@override
|
||||
|
|
@ -189,12 +187,7 @@ class NavigationOrderState extends _$NavigationOrderState {
|
|||
class HideItemsState extends _$HideItemsState {
|
||||
@override
|
||||
List<String> build() {
|
||||
return isar.settings.getSync(227)!.hideItems ??
|
||||
[
|
||||
'/trackerLibrary/anilist',
|
||||
'/trackerLibrary/kitsu',
|
||||
'/trackerLibrary/mal',
|
||||
];
|
||||
return isar.settings.getSync(227)!.hideItems ?? ['/trackerLibrary'];
|
||||
}
|
||||
|
||||
void set(List<String> values) {
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ final fullScreenReaderStateProvider =
|
|||
|
||||
typedef _$FullScreenReaderState = AutoDisposeNotifier<bool>;
|
||||
String _$navigationOrderStateHash() =>
|
||||
r'f300869743afaccfd47210115f341d25fec522bb';
|
||||
r'15ad6f31d8c5f3acd8cd6f4e4131e7536914cfc6';
|
||||
|
||||
/// See also [NavigationOrderState].
|
||||
@ProviderFor(NavigationOrderState)
|
||||
|
|
@ -174,7 +174,7 @@ final navigationOrderStateProvider =
|
|||
);
|
||||
|
||||
typedef _$NavigationOrderState = AutoDisposeNotifier<List<String>>;
|
||||
String _$hideItemsStateHash() => r'6844a05786f6c547a7cba261f742e82d871b6cb1';
|
||||
String _$hideItemsStateHash() => r'312605bf45a83d7628d9c1da0597bb151362052b';
|
||||
|
||||
/// See also [HideItemsState].
|
||||
@ProviderFor(HideItemsState)
|
||||
|
|
|
|||
|
|
@ -2,8 +2,11 @@
|
|||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_qjs/quickjs/ffi.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/l10n/generated/app_localizations.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/models/track.dart';
|
||||
|
|
@ -44,13 +47,8 @@ class TrackLibrarySection {
|
|||
}
|
||||
|
||||
class TrackerLibraryScreen extends ConsumerStatefulWidget {
|
||||
final TrackerProviders trackerProvider;
|
||||
final String? presetInput;
|
||||
const TrackerLibraryScreen({
|
||||
required this.trackerProvider,
|
||||
required this.presetInput,
|
||||
super.key,
|
||||
});
|
||||
const TrackerLibraryScreen({required this.presetInput, super.key});
|
||||
|
||||
@override
|
||||
ConsumerState<TrackerLibraryScreen> createState() =>
|
||||
|
|
@ -61,30 +59,40 @@ class _TrackerLibraryScreenState extends ConsumerState<TrackerLibraryScreen> {
|
|||
late final _textEditingController = TextEditingController();
|
||||
late String _query = "";
|
||||
late bool _isSearch = false;
|
||||
List<TrackLibrarySection> _sections = [];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = l10nLocalizations(context)!;
|
||||
final sections = switch (widget.trackerProvider.syncId) {
|
||||
1 => _sectionsMAL(),
|
||||
2 => _sectionsAL(),
|
||||
3 => _sectionsKitsu(),
|
||||
final lastLocation = ref.watch(lastTrackerLibraryLocationStateProvider);
|
||||
final trackerProvider =
|
||||
TrackerProviders.values.firstWhereOrNull(
|
||||
(t) => t.syncId == lastLocation.$1,
|
||||
) ??
|
||||
TrackerProviders.myAnimeList;
|
||||
final itemType = lastLocation.$2 ? ItemType.manga : ItemType.anime;
|
||||
_sections = switch (trackerProvider.syncId) {
|
||||
1 => _sectionsMAL(trackerProvider.syncId, itemType),
|
||||
2 => _sectionsAL(trackerProvider.syncId, itemType),
|
||||
3 => _sectionsKitsu(trackerProvider.syncId, itemType),
|
||||
_ => [],
|
||||
};
|
||||
if (_isSearch && _query.isNotEmpty) {
|
||||
sections.insert(
|
||||
_sections.insert(
|
||||
0,
|
||||
TrackLibrarySection(
|
||||
name: "Search results",
|
||||
func: _fetchGeneralData(ItemType.anime),
|
||||
itemType: ItemType.anime,
|
||||
func: _fetchSearch(trackerProvider.syncId, _query, itemType),
|
||||
itemType: itemType,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(widget.trackerProvider.name),
|
||||
title: Text(
|
||||
"${trackerProvider.name} | ${itemType == ItemType.anime ? l10n.anime : l10n.manga}",
|
||||
),
|
||||
leading: !_isSearch ? null : Container(),
|
||||
actions: [
|
||||
_isSearch
|
||||
|
|
@ -98,19 +106,15 @@ class _TrackerLibraryScreenState extends ConsumerState<TrackerLibraryScreen> {
|
|||
},
|
||||
onChanged: (value) {},
|
||||
onSuffixPressed: () {
|
||||
_textEditingController.clear();
|
||||
_query = "";
|
||||
_textEditingController.clear();
|
||||
setState(() {});
|
||||
},
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
if (_textEditingController.text.isEmpty) {
|
||||
_isSearch = false;
|
||||
_query = "";
|
||||
_textEditingController.clear();
|
||||
} else {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
_isSearch = false;
|
||||
_query = "";
|
||||
_textEditingController.clear();
|
||||
});
|
||||
},
|
||||
controller: _textEditingController,
|
||||
|
|
@ -127,25 +131,32 @@ class _TrackerLibraryScreenState extends ConsumerState<TrackerLibraryScreen> {
|
|||
IconButton(
|
||||
splashRadius: 20,
|
||||
onPressed: () {
|
||||
// open dialog to switch between trackers / item types
|
||||
_openSwitchDialog(l10n);
|
||||
},
|
||||
icon: CircleAvatar(
|
||||
radius: 14,
|
||||
backgroundColor: Theme.of(context).primaryColorLight,
|
||||
child: Image.asset(
|
||||
"assets/trackers_icons/tracker_mal.webp",
|
||||
height: 30,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: trackInfos(trackerProvider.syncId).$3,
|
||||
),
|
||||
width: 60,
|
||||
height: 70,
|
||||
child: Image.asset(
|
||||
trackInfos(trackerProvider.syncId).$1,
|
||||
height: 30,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(15),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 5),
|
||||
child: StreamBuilder(
|
||||
stream: isar.trackPreferences
|
||||
.filter()
|
||||
.syncIdEqualTo(widget.trackerProvider.syncId)
|
||||
.syncIdEqualTo(trackerProvider.syncId)
|
||||
.watch(fireImmediately: true),
|
||||
builder: (context, snapshot) {
|
||||
List<TrackPreference> entries = snapshot.hasData
|
||||
|
|
@ -153,13 +164,16 @@ class _TrackerLibraryScreenState extends ConsumerState<TrackerLibraryScreen> {
|
|||
: [];
|
||||
return entries.isNotEmpty
|
||||
? SuperListView.builder(
|
||||
itemCount: sections.length,
|
||||
itemCount: _sections.length,
|
||||
extentPrecalculationPolicy: SuperPrecalculationPolicy(),
|
||||
itemBuilder: (context, index) {
|
||||
final section = sections[index];
|
||||
final section = _sections[index];
|
||||
return SizedBox(
|
||||
height: 260,
|
||||
child: TrackerSectionScreen(section: section),
|
||||
child: TrackerSectionScreen(
|
||||
key: Key(section.name),
|
||||
section: section,
|
||||
),
|
||||
);
|
||||
},
|
||||
)
|
||||
|
|
@ -178,192 +192,311 @@ class _TrackerLibraryScreenState extends ConsumerState<TrackerLibraryScreen> {
|
|||
);
|
||||
}
|
||||
|
||||
List<TrackLibrarySection> _sectionsMAL() {
|
||||
return [
|
||||
TrackLibrarySection(
|
||||
name: "Airing Anime",
|
||||
func: _fetchGeneralData(ItemType.anime),
|
||||
itemType: ItemType.anime,
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Popular Anime",
|
||||
func: _fetchGeneralData(ItemType.anime, rankingType: "bypopularity"),
|
||||
itemType: ItemType.anime,
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Upcoming Anime",
|
||||
func: _fetchGeneralData(ItemType.anime, rankingType: "upcoming"),
|
||||
itemType: ItemType.anime,
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Continue watching",
|
||||
func: _fetchUserData(ItemType.anime),
|
||||
itemType: ItemType.anime,
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Popular Manga",
|
||||
func: _fetchGeneralData(ItemType.manga, rankingType: "bypopularity"),
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Top Manga",
|
||||
func: _fetchGeneralData(ItemType.manga, rankingType: "manga"),
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Top Manhwa",
|
||||
func: _fetchGeneralData(ItemType.manga, rankingType: "manhwa"),
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Top Manhua",
|
||||
func: _fetchGeneralData(ItemType.manga, rankingType: "manhua"),
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Continue reading",
|
||||
func: _fetchUserData(ItemType.manga),
|
||||
),
|
||||
];
|
||||
List<TrackLibrarySection> _sectionsMAL(int syncId, ItemType itemType) {
|
||||
return itemType == ItemType.anime
|
||||
? [
|
||||
TrackLibrarySection(
|
||||
name: "Airing Anime",
|
||||
func: _fetchGeneralData(syncId, ItemType.anime),
|
||||
itemType: ItemType.anime,
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Popular Anime",
|
||||
func: _fetchGeneralData(
|
||||
syncId,
|
||||
ItemType.anime,
|
||||
rankingType: "bypopularity",
|
||||
),
|
||||
itemType: ItemType.anime,
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Upcoming Anime",
|
||||
func: _fetchGeneralData(
|
||||
syncId,
|
||||
ItemType.anime,
|
||||
rankingType: "upcoming",
|
||||
),
|
||||
itemType: ItemType.anime,
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Continue watching",
|
||||
func: _fetchUserData(syncId, ItemType.anime),
|
||||
itemType: ItemType.anime,
|
||||
),
|
||||
]
|
||||
: [
|
||||
TrackLibrarySection(
|
||||
name: "Popular Manga",
|
||||
func: _fetchGeneralData(
|
||||
syncId,
|
||||
ItemType.manga,
|
||||
rankingType: "bypopularity",
|
||||
),
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Top Manga",
|
||||
func: _fetchGeneralData(
|
||||
syncId,
|
||||
ItemType.manga,
|
||||
rankingType: "manga",
|
||||
),
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Top Manhwa",
|
||||
func: _fetchGeneralData(
|
||||
syncId,
|
||||
ItemType.manga,
|
||||
rankingType: "manhwa",
|
||||
),
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Top Manhua",
|
||||
func: _fetchGeneralData(
|
||||
syncId,
|
||||
ItemType.manga,
|
||||
rankingType: "manhua",
|
||||
),
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Continue reading",
|
||||
func: _fetchUserData(syncId, ItemType.manga),
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
List<TrackLibrarySection> _sectionsKitsu() {
|
||||
return [
|
||||
TrackLibrarySection(
|
||||
name: "Popular Anime",
|
||||
func: _fetchGeneralData(ItemType.anime),
|
||||
itemType: ItemType.anime,
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Latest Anime",
|
||||
func: _fetchGeneralData(ItemType.anime, rankingType: "-updatedAt"),
|
||||
itemType: ItemType.anime,
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Best Rated Anime",
|
||||
func: _fetchGeneralData(ItemType.anime, rankingType: "-averageRating"),
|
||||
itemType: ItemType.anime,
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Continue watching",
|
||||
func: _fetchUserData(ItemType.anime),
|
||||
itemType: ItemType.anime,
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Popular Manga",
|
||||
func: _fetchGeneralData(ItemType.manga),
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Latest Manga",
|
||||
func: _fetchGeneralData(ItemType.manga, rankingType: "-updatedAt"),
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Best Rated Manga",
|
||||
func: _fetchGeneralData(ItemType.manga, rankingType: "-averageRating"),
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Continue reading",
|
||||
func: _fetchUserData(ItemType.manga),
|
||||
),
|
||||
];
|
||||
List<TrackLibrarySection> _sectionsKitsu(int syncId, ItemType itemType) {
|
||||
return itemType == ItemType.anime
|
||||
? [
|
||||
TrackLibrarySection(
|
||||
name: "Popular Anime",
|
||||
func: _fetchGeneralData(syncId, ItemType.anime),
|
||||
itemType: ItemType.anime,
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Latest Anime",
|
||||
func: _fetchGeneralData(
|
||||
syncId,
|
||||
ItemType.anime,
|
||||
rankingType: "-updatedAt",
|
||||
),
|
||||
itemType: ItemType.anime,
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Best Rated Anime",
|
||||
func: _fetchGeneralData(
|
||||
syncId,
|
||||
ItemType.anime,
|
||||
rankingType: "-averageRating",
|
||||
),
|
||||
itemType: ItemType.anime,
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Continue watching",
|
||||
func: _fetchUserData(syncId, ItemType.anime),
|
||||
itemType: ItemType.anime,
|
||||
),
|
||||
]
|
||||
: [
|
||||
TrackLibrarySection(
|
||||
name: "Popular Manga",
|
||||
func: _fetchGeneralData(syncId, ItemType.manga),
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Latest Manga",
|
||||
func: _fetchGeneralData(
|
||||
syncId,
|
||||
ItemType.manga,
|
||||
rankingType: "-updatedAt",
|
||||
),
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Best Rated Manga",
|
||||
func: _fetchGeneralData(
|
||||
syncId,
|
||||
ItemType.manga,
|
||||
rankingType: "-averageRating",
|
||||
),
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Continue reading",
|
||||
func: _fetchUserData(syncId, ItemType.manga),
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
List<TrackLibrarySection> _sectionsAL() {
|
||||
return [
|
||||
TrackLibrarySection(
|
||||
name: "Upcoming Anime",
|
||||
func: _fetchGeneralData(ItemType.anime),
|
||||
itemType: ItemType.anime,
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Popular Anime",
|
||||
func: _fetchGeneralData(
|
||||
ItemType.anime,
|
||||
rankingType: "sort: POPULARITY_DESC",
|
||||
),
|
||||
itemType: ItemType.anime,
|
||||
),
|
||||
TrackLibrarySection(
|
||||
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(
|
||||
name: "Continue watching",
|
||||
func: _fetchUserData(ItemType.anime),
|
||||
itemType: ItemType.anime,
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Upcoming Manga",
|
||||
func: _fetchGeneralData(ItemType.manga),
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Popular Manga",
|
||||
func: _fetchGeneralData(
|
||||
ItemType.manga,
|
||||
rankingType: "sort: POPULARITY_DESC",
|
||||
),
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Trending Manga",
|
||||
func: _fetchGeneralData(
|
||||
ItemType.manga,
|
||||
rankingType: "sort: TRENDING_DESC",
|
||||
),
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Latest Manga",
|
||||
func: _fetchGeneralData(
|
||||
ItemType.manga,
|
||||
rankingType:
|
||||
"sort: [UPDATED_AT_DESC, POPULARITY_DESC], status: RELEASING",
|
||||
),
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Continue reading",
|
||||
func: _fetchUserData(ItemType.manga),
|
||||
),
|
||||
];
|
||||
List<TrackLibrarySection> _sectionsAL(int syncId, ItemType itemType) {
|
||||
return itemType == ItemType.anime
|
||||
? [
|
||||
TrackLibrarySection(
|
||||
name: "Upcoming Anime",
|
||||
func: _fetchGeneralData(syncId, ItemType.anime),
|
||||
itemType: ItemType.anime,
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Popular Anime",
|
||||
func: _fetchGeneralData(
|
||||
syncId,
|
||||
ItemType.anime,
|
||||
rankingType: "sort: POPULARITY_DESC",
|
||||
),
|
||||
itemType: ItemType.anime,
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Trending Anime",
|
||||
func: _fetchGeneralData(
|
||||
syncId,
|
||||
ItemType.anime,
|
||||
rankingType: "sort: TRENDING_DESC",
|
||||
),
|
||||
itemType: ItemType.anime,
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Latest Anime",
|
||||
func: _fetchGeneralData(
|
||||
syncId,
|
||||
ItemType.anime,
|
||||
rankingType:
|
||||
"sort: [UPDATED_AT_DESC, POPULARITY_DESC], status: RELEASING",
|
||||
),
|
||||
itemType: ItemType.anime,
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Continue watching",
|
||||
func: _fetchUserData(syncId, ItemType.anime),
|
||||
itemType: ItemType.anime,
|
||||
),
|
||||
]
|
||||
: [
|
||||
TrackLibrarySection(
|
||||
name: "Upcoming Manga",
|
||||
func: _fetchGeneralData(syncId, ItemType.manga),
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Popular Manga",
|
||||
func: _fetchGeneralData(
|
||||
syncId,
|
||||
ItemType.manga,
|
||||
rankingType: "sort: POPULARITY_DESC",
|
||||
),
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Trending Manga",
|
||||
func: _fetchGeneralData(
|
||||
syncId,
|
||||
ItemType.manga,
|
||||
rankingType: "sort: TRENDING_DESC",
|
||||
),
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Latest Manga",
|
||||
func: _fetchGeneralData(
|
||||
syncId,
|
||||
ItemType.manga,
|
||||
rankingType:
|
||||
"sort: [UPDATED_AT_DESC, POPULARITY_DESC], status: RELEASING",
|
||||
),
|
||||
),
|
||||
TrackLibrarySection(
|
||||
name: "Continue reading",
|
||||
func: _fetchUserData(syncId, ItemType.manga),
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
Future<List<TrackSearch>?> Function() _fetchSearch(
|
||||
int syncId,
|
||||
String query,
|
||||
ItemType itemType,
|
||||
) {
|
||||
return () async => await ref
|
||||
.read(
|
||||
trackStateProvider(
|
||||
track: Track(syncId: syncId, status: TrackStatus.completed),
|
||||
itemType: itemType,
|
||||
).notifier,
|
||||
)
|
||||
.search(query);
|
||||
}
|
||||
|
||||
Future<List<TrackSearch>?> Function() _fetchGeneralData(
|
||||
int syncId,
|
||||
ItemType itemType, {
|
||||
String? rankingType,
|
||||
}) {
|
||||
return () async => await ref
|
||||
.read(
|
||||
trackStateProvider(
|
||||
track: Track(
|
||||
syncId: widget.trackerProvider.syncId,
|
||||
status: TrackStatus.completed,
|
||||
),
|
||||
track: Track(syncId: syncId, status: TrackStatus.completed),
|
||||
itemType: itemType,
|
||||
).notifier,
|
||||
)
|
||||
.fetchGeneralData(rankingType: rankingType);
|
||||
}
|
||||
|
||||
Future<List<TrackSearch>?> Function() _fetchUserData(ItemType itemType) {
|
||||
Future<List<TrackSearch>?> Function() _fetchUserData(
|
||||
int syncId,
|
||||
ItemType itemType,
|
||||
) {
|
||||
return () async => await ref
|
||||
.read(
|
||||
trackStateProvider(
|
||||
track: Track(
|
||||
syncId: widget.trackerProvider.syncId,
|
||||
status: TrackStatus.completed,
|
||||
),
|
||||
track: Track(syncId: syncId, status: TrackStatus.completed),
|
||||
itemType: itemType,
|
||||
).notifier,
|
||||
)
|
||||
.fetchUserData();
|
||||
}
|
||||
|
||||
void _openSwitchDialog(AppLocalizations l10n) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (ctx) {
|
||||
return AlertDialog(
|
||||
title: Text(l10n.track_library_switch),
|
||||
content: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
_getListile(l10n, TrackerProviders.myAnimeList.syncId, true),
|
||||
_getListile(l10n, TrackerProviders.myAnimeList.syncId, false),
|
||||
_getListile(l10n, TrackerProviders.anilist.syncId, true),
|
||||
_getListile(l10n, TrackerProviders.anilist.syncId, false),
|
||||
_getListile(l10n, TrackerProviders.kitsu.syncId, true),
|
||||
_getListile(l10n, TrackerProviders.kitsu.syncId, false),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _getListile(AppLocalizations l10n, int syncId, bool isManga) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 5),
|
||||
child: ListTile(
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
|
||||
leading: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: trackInfos(syncId).$3,
|
||||
),
|
||||
width: 60,
|
||||
height: 70,
|
||||
child: Image.asset(trackInfos(syncId).$1, height: 30),
|
||||
),
|
||||
title: Text(
|
||||
"${trackInfos(syncId).$2} | ${isManga ? l10n.manga : l10n.anime}",
|
||||
),
|
||||
onTap: () {
|
||||
ref.read(lastTrackerLibraryLocationStateProvider.notifier).set((
|
||||
syncId,
|
||||
isManga,
|
||||
));
|
||||
context.pop();
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class TrackerSectionScreen extends StatefulWidget {
|
||||
|
|
@ -376,33 +509,14 @@ class TrackerSectionScreen extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _TrackerSectionScreenState extends State<TrackerSectionScreen> {
|
||||
String _errorMessage = "";
|
||||
bool _isLoading = true;
|
||||
List<TrackSearch> _tracks = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_init();
|
||||
}
|
||||
|
||||
String _errorMessage = "";
|
||||
bool _isLoading = true;
|
||||
List<TrackSearch> tracks = [];
|
||||
_init() async {
|
||||
try {
|
||||
_errorMessage = "";
|
||||
tracks = await widget.section.func() ?? [];
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_errorMessage = e.toString();
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
rethrow;
|
||||
}
|
||||
_fetchData();
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -423,15 +537,15 @@ class _TrackerSectionScreenState extends State<TrackerSectionScreen> {
|
|||
if (_errorMessage.isNotEmpty) {
|
||||
return Center(child: Text(_errorMessage));
|
||||
}
|
||||
if (tracks.isNotEmpty) {
|
||||
if (_tracks.isNotEmpty) {
|
||||
return SuperListView.builder(
|
||||
extentPrecalculationPolicy:
|
||||
SuperPrecalculationPolicy(),
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: tracks.length,
|
||||
itemCount: _tracks.length,
|
||||
itemBuilder: (context, index) {
|
||||
return TrackerLibraryImageCard(
|
||||
track: tracks[index],
|
||||
track: _tracks[index],
|
||||
itemType: widget.section.itemType,
|
||||
);
|
||||
},
|
||||
|
|
@ -446,6 +560,25 @@ class _TrackerSectionScreenState extends State<TrackerSectionScreen> {
|
|||
),
|
||||
);
|
||||
}
|
||||
|
||||
_fetchData() async {
|
||||
try {
|
||||
_errorMessage = "";
|
||||
_tracks = await widget.section.func() ?? [];
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_errorMessage = e.toString();
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TrackerLibraryImageCard extends ConsumerStatefulWidget {
|
||||
|
|
@ -499,20 +632,52 @@ class _TrackerLibraryImageCardState
|
|||
}
|
||||
return ClipRRect(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
child: cachedNetworkImage(
|
||||
imageUrl: toImgUrl(
|
||||
hasData
|
||||
? snapshot
|
||||
.data!
|
||||
.first
|
||||
.customCoverFromTracker ??
|
||||
snapshot.data!.first.imageUrl ??
|
||||
""
|
||||
: trackData.coverUrl ?? "",
|
||||
),
|
||||
width: 110,
|
||||
height: 150,
|
||||
fit: BoxFit.cover,
|
||||
child: Stack(
|
||||
children: [
|
||||
cachedNetworkImage(
|
||||
imageUrl: toImgUrl(
|
||||
hasData
|
||||
? snapshot
|
||||
.data!
|
||||
.first
|
||||
.customCoverFromTracker ??
|
||||
snapshot.data!.first.imageUrl ??
|
||||
""
|
||||
: trackData.coverUrl ?? "",
|
||||
),
|
||||
width: 110,
|
||||
height: 150,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
Positioned(
|
||||
top: 0,
|
||||
right: 0,
|
||||
child: Text.rich(
|
||||
TextSpan(
|
||||
style: TextStyle(
|
||||
background: Paint()
|
||||
..color = Theme.of(context)
|
||||
.scaffoldBackgroundColor
|
||||
.withValues(alpha: 0.75)
|
||||
..strokeWidth = 20.0
|
||||
..strokeJoin = StrokeJoin.round
|
||||
..style = PaintingStyle.stroke,
|
||||
),
|
||||
children: [
|
||||
WidgetSpan(
|
||||
child: Icon(
|
||||
Icons.star,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
),
|
||||
TextSpan(
|
||||
text: " ${trackData.score ?? "?"}",
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
|
|
@ -546,20 +711,6 @@ class _TrackerLibraryImageCardState
|
|||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
child: Text.rich(
|
||||
TextSpan(
|
||||
children: [
|
||||
WidgetSpan(
|
||||
child: Icon(Icons.star, color: context.primaryColor),
|
||||
),
|
||||
TextSpan(text: " ${trackData.score ?? "?"}"),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -125,25 +125,8 @@ class RouterNotifier extends ChangeNotifier {
|
|||
LibraryScreen(itemType: ItemType.novel, presetInput: id),
|
||||
),
|
||||
_genericRoute<String?>(
|
||||
name: "trackerLibrary/anilist",
|
||||
builder: (id) => TrackerLibraryScreen(
|
||||
trackerProvider: TrackerProviders.anilist,
|
||||
presetInput: id,
|
||||
),
|
||||
),
|
||||
_genericRoute<String?>(
|
||||
name: "trackerLibrary/kitsu",
|
||||
builder: (id) => TrackerLibraryScreen(
|
||||
trackerProvider: TrackerProviders.kitsu,
|
||||
presetInput: id,
|
||||
),
|
||||
),
|
||||
_genericRoute<String?>(
|
||||
name: "trackerLibrary/mal",
|
||||
builder: (id) => TrackerLibraryScreen(
|
||||
trackerProvider: TrackerProviders.myAnimeList,
|
||||
presetInput: id,
|
||||
),
|
||||
name: "trackerLibrary",
|
||||
builder: (id) => TrackerLibraryScreen(presetInput: id),
|
||||
),
|
||||
_genericRoute(name: "history", child: const HistoryScreen()),
|
||||
_genericRoute(name: "updates", child: const UpdatesScreen()),
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ class Anilist extends _$Anilist {
|
|||
$contentUnit
|
||||
description
|
||||
startDate { year month day }
|
||||
averageScore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -160,6 +161,9 @@ class Anilist extends _$Anilist {
|
|||
).toString(),
|
||||
publishingType: "",
|
||||
publishingStatus: jsonRes['status'],
|
||||
score: jsonRes["averageScore"] != null
|
||||
? jsonRes["averageScore"] * 1.0
|
||||
: 0,
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
|
|
|
|||
|
|
@ -167,6 +167,9 @@ class Kitsu extends _$Kitsu {
|
|||
publishingStatus: jsonRes['endDate'] == null
|
||||
? "Publishing"
|
||||
: "Finished",
|
||||
score: jsonRes['averageRating'] is String
|
||||
? double.parse(jsonRes['averageRating'])
|
||||
: jsonRes['averageRating'],
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ class MyAnimeList extends _$MyAnimeList {
|
|||
final url = Uri.parse('$baseApiUrl/$item/$id').replace(
|
||||
queryParameters: {
|
||||
'fields':
|
||||
'id,title,synopsis,$contentUnit,main_picture,status,media_type,start_date',
|
||||
'id,title,synopsis,$contentUnit,main_picture,status,media_type,start_date,mean',
|
||||
},
|
||||
);
|
||||
|
||||
|
|
@ -146,6 +146,7 @@ class MyAnimeList extends _$MyAnimeList {
|
|||
publishingType: res["media_type"].toString().replaceAll("_", " "),
|
||||
publishingStatus: res["status"].toString().replaceAll("_", " "),
|
||||
trackingUrl: "https://myanimelist.net/$item/${res["id"]}",
|
||||
score: res["mean"],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue