Skip to content

Commit 74a9662

Browse files
committed
feat: extensions search
1 parent 8c0d495 commit 74a9662

File tree

7 files changed

+127
-52
lines changed

7 files changed

+127
-52
lines changed

lib/Screens/Detail/MediaScreenViewModel.dart

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1+
import 'package:dantotsu/Theme/LanguageSwitcher.dart';
12
import 'package:flutter/material.dart';
23
import 'package:get/get.dart';
34
import 'package:provider/provider.dart';
45

56
import '../../DataClass/Media.dart';
67
import '../../Services/ServiceSwitcher.dart';
7-
import 'package:dantotsu/Theme/LanguageSwitcher.dart';
8-
98

109
class MediaPageViewModel extends GetxController {
1110
var dataLoaded = false.obs;
@@ -27,7 +26,9 @@ class MediaPageViewModel extends GetxController {
2726
var theme = Theme.of(context).colorScheme;
2827
if (mediaData.userStatus != null) {
2928
spans.add(TextSpan(
30-
text: mediaData.anime != null ? getString.watchStatus : getString.readStatus,
29+
text: mediaData.anime != null
30+
? "${getString.watchStatus} "
31+
: "${getString.readStatus} ",
3132
));
3233
spans.add(TextSpan(
3334
text: "${mediaData.userProgress}",
@@ -36,18 +37,23 @@ class MediaPageViewModel extends GetxController {
3637
color: theme.secondary,
3738
),
3839
));
39-
spans.add(TextSpan(text: getString.outOf));
40+
spans.add(TextSpan(text: " ${getString.outOf} "));
4041
} else {
41-
spans.add(TextSpan(text: getString.totalOf));
42+
spans.add(TextSpan(text: "${getString.totalOf} "));
4243
}
4344

4445
if (mediaData.anime != null) {
4546
if (mediaData.anime!.nextAiringEpisode != -1 &&
4647
mediaData.anime!.nextAiringEpisode != null) {
47-
spans.add(TextSpan(
48+
spans.add(
49+
TextSpan(
4850
text: "${mediaData.anime!.nextAiringEpisode}",
4951
style: TextStyle(
50-
color: theme.onSurface, fontWeight: FontWeight.bold)));
52+
color: theme.onSurface,
53+
fontWeight: FontWeight.bold,
54+
),
55+
),
56+
);
5157
spans.add(const TextSpan(
5258
text: " / ",
5359
));

lib/api/EpisodeDetails/Anify/Anify.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ class Anify {
1212
static Future<Map<String, Episode>> fetchAndParseMetadata(
1313
Media mediaData) async {
1414
var ids = [105310]; // hardcode incorrect ids
15-
15+
if(mediaData.idAnilist == null) return {};
1616
if (ids.contains(mediaData.id)) return {};
1717

1818
final response = await http.get(
19-
Uri.parse('https://anify.eltik.cc/content-metadata/${mediaData.id}'));
19+
Uri.parse('https://anify.eltik.cc/content-metadata/${mediaData.idAnilist}'));
2020
if (response.statusCode == 200) {
2121
final List<dynamic> jsonResponse =
2222
jsonDecode(response.body) as List<dynamic>;

lib/api/EpisodeDetails/GetMediaIDs/GetMediaIDs.dart

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'dart:convert';
22

3+
import 'package:dantotsu/Preferences/PrefManager.dart';
34
import 'package:flutter/material.dart';
45
import 'package:get/get.dart';
56
import 'package:http/http.dart' as http;
@@ -76,18 +77,40 @@ class GetMediaIDs {
7677
if (_animeListFuture != null) {
7778
return _animeListFuture;
7879
}
79-
final url = Uri.parse(
80-
'https://raw.githubusercontent.com/Fribb/anime-lists/refs/heads/master/anime-list-full.json');
81-
final response = await http.get(url);
8280

83-
if (response.statusCode == 200) {
84-
List<dynamic> jsonData = jsonDecode(response.body);
85-
_animeListFuture = jsonData.map((e) => AnimeID.fromJson(e)).toList();
81+
return await loadFromCache();
82+
}
83+
static Future<List<AnimeID>?> loadFromCache() async {
84+
var data = loadCustomData<String?>('animeIDSList');
85+
var time = loadCustomData<int>('animeIDSListTime');
86+
bool checkTime() {
87+
if (time == null) return true;
88+
return DateTime.now()
89+
.difference(DateTime.fromMillisecondsSinceEpoch(time))
90+
.inDays >
91+
7;
92+
}
93+
94+
if (data != null && !checkTime()) {
95+
var jsonData = jsonDecode(data);
96+
_animeListFuture = jsonData.map((e) => AnimeID.fromJson(e)).whereType<AnimeID>().toList();
8697
loading.value = false;
8798
return _animeListFuture;
8899
} else {
89-
debugPrint('Failed to load data: ${response.statusCode}');
90-
return null;
100+
final url = Uri.parse(
101+
'https://raw.githubusercontent.com/Fribb/anime-lists/refs/heads/master/anime-list-full.json');
102+
final response = await http.get(url);
103+
if (response.statusCode == 200) {
104+
List<dynamic> jsonData = jsonDecode(response.body);
105+
_animeListFuture = jsonData.map((e) => AnimeID.fromJson(e)).toList();
106+
saveCustomData('animeIDSList', response.body);
107+
saveCustomData('animeIDSListTime', DateTime.now().millisecondsSinceEpoch);
108+
loading.value = false;
109+
return _animeListFuture;
110+
} else {
111+
debugPrint('Failed to load data: ${response.statusCode}');
112+
return null;
113+
}
91114
}
92115
}
93116
}

lib/api/EpisodeDetails/Jikan/Jikan.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class Jikan {
1212
static const String apiUrl = "https://api.jikan.moe/v4";
1313

1414
static Future<Map<String, Episode>> getEpisodes(Media mediaData) async {
15+
if(mediaData.idMAL == null) return {};
1516
final Map<String, Episode> eps = {};
1617
int page = 0;
1718

lib/api/EpisodeDetails/Kitsu/Kitsu.dart

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,33 @@ part 'Kitsu.g.dart';
1212
class Kitsu {
1313
static Future<Map<String, Episode>?> getKitsuEpisodesDetails(
1414
Media mediaData) async {
15-
final query = '''
15+
if (mediaData.idAnilist == null && mediaData.idMAL == null) return {};
16+
final query = mediaData.idAnilist == null ? '''
1617
query {
17-
lookupMapping(externalId: ${mediaData.id}, externalSite: ANILIST_ANIME) {
18+
lookupMapping(externalId: ${mediaData.idAnilist}, externalSite: ANILIST_ANIME) {
19+
__typename
20+
... on Anime {
21+
id
22+
episodes(first: 2000) {
23+
nodes {
24+
number
25+
titles {
26+
canonicalLocale
27+
}
28+
description
29+
thumbnail {
30+
original {
31+
url
32+
}
33+
}
34+
}
35+
}
36+
}
37+
}
38+
}
39+
''' : '''
40+
query {
41+
lookupMapping(externalId: ${mediaData.idMAL}, externalSite: MYANIMELIST_ANIME) {
1842
__typename
1943
... on Anime {
2044
id
@@ -45,16 +69,16 @@ class Kitsu {
4569
mediaData.idKitsu = result.id;
4670

4771
final episodesMap = result.episodes?.nodes?.asMap().map((_, ep) {
48-
return MapEntry(
49-
ep?.number?.toString() ?? '',
50-
Episode(
51-
number: ep?.number.toString() ?? '',
52-
title: ep?.titles?.canonical,
53-
desc: ep?.description?.en,
54-
thumb: ep?.thumbnail?.original?.url,
55-
),
56-
);
57-
}) ??
72+
return MapEntry(
73+
ep?.number?.toString() ?? '',
74+
Episode(
75+
number: ep?.number.toString() ?? '',
76+
title: ep?.titles?.canonical,
77+
desc: ep?.description?.en,
78+
thumb: ep?.thumbnail?.original?.url,
79+
),
80+
);
81+
}) ??
5882
{};
5983

6084
return episodesMap;

lib/api/MyAnimeList/MalQueries/GetAnimeMangaListData.dart

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,26 @@ extension on MalQueries {
5151
final results =
5252
await Future.wait(endpoints.map(executeQuery<MediaResponse>));
5353
int resultIndex = 1;
54-
queryMappings.forEach((key, _) async {
54+
List<Future> futures = [];
55+
56+
queryMappings.forEach((key, _) {
5557
if (animeLayoutMap[key] == true) {
56-
resultIndex++;
57-
list[key.camelCase!] = await processMediaResponse(results[resultIndex]);
58+
futures.add(() async {
59+
resultIndex++;
60+
list[key.camelCase!] = await processMediaResponse(results[resultIndex]);
61+
}());
5862
}
5963
});
6064

61-
list["popularAnime"] = await processMediaResponse(results[0]);
62-
list["trendingAnime"] = await processMediaResponse(results[1]);
65+
futures.add(() async {
66+
list["popularAnime"] = await processMediaResponse(results[0]);
67+
}());
68+
69+
futures.add(() async {
70+
list["trendingAnime"] = await processMediaResponse(results[1]);
71+
}());
6372

73+
await Future.wait(futures);
6474
return list;
6575
}
6676

@@ -96,19 +106,30 @@ extension on MalQueries {
96106
await Future.wait(endpoints.map(executeQuery<MediaResponse>));
97107

98108
int resultIndex = 1;
99-
queryMappings.forEach((key, _) async {
109+
List<Future> futures = [];
110+
111+
queryMappings.forEach((key, _) {
100112
if (mangaLayoutMap[key] == true) {
101-
resultIndex++;
102-
list[key.camelCase!] = await processMediaResponse(results[resultIndex]);
113+
futures.add(() async {
114+
resultIndex++;
115+
list[key.camelCase!] = await processMediaResponse(results[resultIndex]);
116+
}());
103117
}
104118
});
105-
list["popularManga"] = await processMediaResponse(results[0]);
106-
list["trendingManga"] = await processMediaResponse(results[1]);
119+
120+
futures.add(() async {
121+
list["popularManga"] = await processMediaResponse(results[0]);
122+
}());
123+
futures.add(() async {
124+
list["trendingManga"] = await processMediaResponse(results[1]);
125+
}());
126+
127+
await Future.wait(futures);
107128
return list;
108129
}
109130

110131
Future<List<Media>> _getTrending({String? year, String? season}) async {
111-
// season also gets manga type
132+
// season is also used to gets manga type
112133
var anime =
113134
'${MalStrings.endPoint}anime/season/$year/$season?limit=15&offset=1&sort=anime_num_list_users&$field';
114135
var manga =

lib/api/MyAnimeList/MalQueries/GetHomePageData.dart

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,23 @@ extension on MalQueries {
1111
'https://api.myanimelist.net/v2/users/@me/mangalist?$field&limit=1000&sort=list_updated_at&nsfw=1'
1212
};
1313
final results = await Future.wait(list.map(executeQuery<MediaResponse>));
14+
final responses = await Future.wait([
15+
() async {
16+
results[0]?.data?.forEach((m) => m.node?.mediaType = 'anime');
17+
return await processMediaResponse(results[0]);
18+
}(),
19+
() async {
20+
results[1]?.data?.forEach((m) => m.node?.mediaType = 'manga');
21+
return await processMediaResponse(results[1]);
22+
}(),
23+
]);
1424

15-
results[0]?.data?.forEach((m) {
16-
m.node?.mediaType = 'anime';
17-
});
18-
19-
results[1]?.data?.forEach((m) {
20-
m.node?.mediaType = 'manga';
21-
});
25+
var animeList = groupBy(responses[0], (m) => m.userStatus ?? 'other');
26+
var mangaList = groupBy(responses[1], (m) => m.userStatus ?? 'other');
2227

2328
final removeList = PrefManager.getVal(PrefName.malRemoveList);
2429
List<Media> removedMedia = [];
2530

26-
var animeList = groupBy(await processMediaResponse(results[0]),
27-
(m) => m.userStatus ?? 'other');
28-
var mangaList = groupBy(await processMediaResponse(results[1]),
29-
(m) => m.userStatus ?? 'other');
30-
3131
Map<String, List<Media>> returnMap = {};
3232

3333
if (animeList['watching'] != null) {

0 commit comments

Comments
 (0)