source: add mangadex
This commit is contained in:
parent
1a40116e1d
commit
3d6b07de02
47 changed files with 1695 additions and 98 deletions
|
|
@ -58,4 +58,11 @@ class Manga {
|
|||
});
|
||||
}
|
||||
|
||||
enum Status { ongoing, completed, canceled, unknown, onHiatus }
|
||||
enum Status {
|
||||
ongoing,
|
||||
completed,
|
||||
canceled,
|
||||
unknown,
|
||||
onHiatus,
|
||||
publishingFinished
|
||||
}
|
||||
|
|
|
|||
|
|
@ -276,6 +276,7 @@ const _MangastatusEnumValueMap = {
|
|||
'canceled': 2,
|
||||
'unknown': 3,
|
||||
'onHiatus': 4,
|
||||
'publishingFinished': 5,
|
||||
};
|
||||
const _MangastatusValueEnumMap = {
|
||||
0: Status.ongoing,
|
||||
|
|
@ -283,6 +284,7 @@ const _MangastatusValueEnumMap = {
|
|||
2: Status.canceled,
|
||||
3: Status.unknown,
|
||||
4: Status.onHiatus,
|
||||
5: Status.publishingFinished,
|
||||
};
|
||||
|
||||
Id _mangaGetId(Manga object) {
|
||||
|
|
|
|||
|
|
@ -68,5 +68,7 @@ enum TypeSource {
|
|||
|
||||
heancms,
|
||||
|
||||
madara
|
||||
madara,
|
||||
|
||||
mangadex
|
||||
}
|
||||
|
|
|
|||
|
|
@ -261,6 +261,7 @@ const _SourcetypeSourceEnumValueMap = {
|
|||
'mmrcms': 3,
|
||||
'heancms': 4,
|
||||
'madara': 5,
|
||||
'mangadex': 6,
|
||||
};
|
||||
const _SourcetypeSourceValueEnumMap = {
|
||||
0: TypeSource.single,
|
||||
|
|
@ -269,6 +270,7 @@ const _SourcetypeSourceValueEnumMap = {
|
|||
3: TypeSource.mmrcms,
|
||||
4: TypeSource.heancms,
|
||||
5: TypeSource.madara,
|
||||
6: TypeSource.mangadex,
|
||||
};
|
||||
|
||||
Id _sourceGetId(Source object) {
|
||||
|
|
|
|||
|
|
@ -89,8 +89,8 @@ class SourceSearchScreen extends ConsumerWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final search = ref
|
||||
.watch(searchMangaProvider(source: source.sourceName!, query: query));
|
||||
final search = ref.watch(searchMangaProvider(
|
||||
source: source.sourceName!, query: query, lang: source.lang!));
|
||||
return Scaffold(
|
||||
body: SizedBox(
|
||||
height: 260,
|
||||
|
|
|
|||
|
|
@ -473,7 +473,7 @@ class ChapterFilterBookmarkedStateProvider
|
|||
}
|
||||
|
||||
String _$chapterFilterResultStateHash() =>
|
||||
r'efd09e7ec1bc7f63ffdcc82c5c2760de94d704e6';
|
||||
r'ed7adcf7a9d34c3614547735b48789bb004f49cd';
|
||||
|
||||
abstract class _$ChapterFilterResultState
|
||||
extends BuildlessAutoDisposeNotifier<bool> {
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ class ReadMoreWidgetState extends State<ReadMoreWidget>
|
|||
left: 0,
|
||||
child: Container(
|
||||
width: mediaWidth(context, 1),
|
||||
height: 20,
|
||||
height: 30,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).scaffoldBackgroundColor,
|
||||
gradient: LinearGradient(
|
||||
|
|
|
|||
|
|
@ -54,14 +54,20 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (_selectedIndex == 2 && _isSearch && _query.isNotEmpty) {
|
||||
_getManga = ref.watch(
|
||||
searchMangaProvider(source: widget.mangaType.source!, query: _query));
|
||||
_getManga = ref.watch(searchMangaProvider(
|
||||
source: widget.mangaType.source!,
|
||||
query: _query,
|
||||
lang: widget.mangaType.lang!));
|
||||
} else if (_selectedIndex == 1 && !_isSearch && _query.isEmpty) {
|
||||
_getManga = ref.watch(getLatestUpdatesMangaProvider(
|
||||
source: widget.mangaType.source!, page: 1));
|
||||
source: widget.mangaType.source!,
|
||||
page: 1,
|
||||
lang: widget.mangaType.lang!));
|
||||
} else if (_selectedIndex == 0 && !_isSearch && _query.isEmpty) {
|
||||
_getManga = ref.watch(
|
||||
getPopularMangaProvider(source: widget.mangaType.source!, page: 1));
|
||||
_getManga = ref.watch(getPopularMangaProvider(
|
||||
source: widget.mangaType.source!,
|
||||
page: 1,
|
||||
lang: widget.mangaType.lang!));
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
|
|
@ -205,7 +211,8 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
|||
.watch(getPopularMangaProvider(
|
||||
source:
|
||||
widget.mangaType.source!,
|
||||
page: _page)
|
||||
page: _page,
|
||||
lang: widget.mangaType.lang!)
|
||||
.future)
|
||||
.then(
|
||||
(value) {
|
||||
|
|
@ -270,7 +277,9 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
|||
}
|
||||
ref
|
||||
.watch(getPopularMangaProvider(
|
||||
source: widget.mangaType.source!, page: _page)
|
||||
source: widget.mangaType.source!,
|
||||
page: _page,
|
||||
lang: widget.mangaType.lang!)
|
||||
.future)
|
||||
.then(
|
||||
(value) {
|
||||
|
|
|
|||
|
|
@ -101,7 +101,8 @@ class SearchResultScreen extends ConsumerWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final search = ref.watch(searchMangaProvider(source: source, query: query));
|
||||
final search = ref
|
||||
.watch(searchMangaProvider(source: source, query: query, lang: lang));
|
||||
return Scaffold(
|
||||
appBar: viewOnly
|
||||
? AppBar(
|
||||
|
|
|
|||
|
|
@ -959,7 +959,6 @@ class _MangaChapterPageGalleryState
|
|||
preloadPagesCount: _isZoom
|
||||
? 0
|
||||
: widget.readerController.getPageLength(widget.url),
|
||||
pageSnapping: false,
|
||||
canScrollPage: (GestureDetails? gestureDetails) {
|
||||
return gestureDetails != null
|
||||
? !(gestureDetails.totalScale! > 1.0)
|
||||
|
|
|
|||
|
|
@ -54,7 +54,8 @@ class ReaderController extends _$ReaderController {
|
|||
|
||||
void setReaderMode(ReaderMode newReaderMode) {
|
||||
List<PersonalReaderMode>? personalReaderModeLists = [];
|
||||
for (var personalReaderMode in getIsarSetting().personalReaderModeList!) {
|
||||
for (var personalReaderMode
|
||||
in getIsarSetting().personalReaderModeList ?? []) {
|
||||
if (personalReaderMode.mangaId != getManga().id) {
|
||||
personalReaderModeLists.add(personalReaderMode);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ class CurrentIndexProvider
|
|||
}
|
||||
}
|
||||
|
||||
String _$readerControllerHash() => r'cca2c3646d9bd18af9252785e61cd4416deb83b2';
|
||||
String _$readerControllerHash() => r'65ce80e436f72efffea6ba9b1b6f87be702b79cd';
|
||||
|
||||
abstract class _$ReaderController extends BuildlessAutoDisposeNotifier<void> {
|
||||
late final Chapter chapter;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import 'package:mangayomi/providers/storage_provider.dart';
|
|||
import 'package:mangayomi/sources/multisrc/heancms/heancms.dart';
|
||||
import 'package:mangayomi/sources/multisrc/madara/src/madara.dart';
|
||||
import 'package:mangayomi/sources/src/all/comick/src/comick.dart';
|
||||
import 'package:mangayomi/sources/src/all/mangadex/src/mangadex.dart';
|
||||
import 'package:mangayomi/sources/src/en/mangahere/src/mangahere.dart';
|
||||
import 'package:mangayomi/sources/src/fr/japscan/src/japscan.dart';
|
||||
import 'package:mangayomi/sources/src/fr/mangakawaii/src/mangakawaii.dart';
|
||||
|
|
@ -125,6 +126,14 @@ Future<GetChapterUrlModel> getChapterUrl(
|
|||
pageUrls = await Madara().getChapterUrl(chapter: chapter, ref: ref);
|
||||
}
|
||||
|
||||
/***********/
|
||||
/*mangadex*/
|
||||
/***********/
|
||||
|
||||
else if (getMangaTypeSource(source) == TypeSource.mangadex) {
|
||||
pageUrls = await MangaDex().getChapterUrl(chapter: chapter, ref: ref);
|
||||
}
|
||||
|
||||
if (pageUrls.isNotEmpty) {
|
||||
if (!incognitoMode) {
|
||||
List<ChapterPageurls>? chapterPageUrls = [];
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'get_chapter_url.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$getChapterUrlHash() => r'2e7729424ee0fc2b9a38bb0e25a1d109e7f3a3f7';
|
||||
String _$getChapterUrlHash() => r'7d96750b6f404a08c44cc58be552ad291c5e18f8';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import 'package:mangayomi/sources/multisrc/heancms/heancms.dart';
|
|||
import 'package:mangayomi/sources/multisrc/madara/src/madara.dart';
|
||||
import 'package:mangayomi/sources/service.dart';
|
||||
import 'package:mangayomi/sources/src/all/comick/src/comick.dart';
|
||||
import 'package:mangayomi/sources/src/all/mangadex/src/mangadex.dart';
|
||||
import 'package:mangayomi/sources/src/en/mangahere/src/mangahere.dart';
|
||||
import 'package:mangayomi/sources/src/fr/japscan/src/japscan.dart';
|
||||
import 'package:mangayomi/sources/src/fr/mangakawaii/src/mangakawaii.dart';
|
||||
|
|
@ -14,8 +15,12 @@ import 'package:riverpod_annotation/riverpod_annotation.dart';
|
|||
part 'get_latest_updates_manga.g.dart';
|
||||
|
||||
@riverpod
|
||||
Future<List<GetManga?>> getLatestUpdatesManga(GetLatestUpdatesMangaRef ref,
|
||||
{required String source, required int page}) async {
|
||||
Future<List<GetManga?>> getLatestUpdatesManga(
|
||||
GetLatestUpdatesMangaRef ref, {
|
||||
required String source,
|
||||
required int page,
|
||||
required String lang,
|
||||
}) async {
|
||||
List<GetManga?>? latestUpdatesManga;
|
||||
source = source.toLowerCase();
|
||||
|
||||
|
|
@ -23,24 +28,24 @@ Future<List<GetManga?>> getLatestUpdatesManga(GetLatestUpdatesMangaRef ref,
|
|||
/*comick*/
|
||||
/*******/
|
||||
if (getMangaTypeSource(source) == TypeSource.comick) {
|
||||
latestUpdatesManga =
|
||||
await Comick().getLatestUpdatesManga(source: source, page: page, ref: ref);
|
||||
latestUpdatesManga = await Comick().getLatestUpdatesManga(
|
||||
source: source, page: page, ref: ref, lang: lang);
|
||||
}
|
||||
|
||||
/***************/
|
||||
/*mangathemesia*/
|
||||
/**************/
|
||||
if (getMangaTypeSource(source) == TypeSource.mangathemesia) {
|
||||
latestUpdatesManga = await MangaThemeSia()
|
||||
.getLatestUpdatesManga(source: source, page: page, ref: ref);
|
||||
latestUpdatesManga = await MangaThemeSia().getLatestUpdatesManga(
|
||||
source: source, page: page, ref: ref, lang: lang);
|
||||
}
|
||||
|
||||
/***********/
|
||||
/*mangakawaii*/
|
||||
/***********/
|
||||
if (source == "mangakawaii") {
|
||||
latestUpdatesManga = await MangaKawaii()
|
||||
.getLatestUpdatesManga(source: source, page: page, ref: ref);
|
||||
latestUpdatesManga = await MangaKawaii().getLatestUpdatesManga(
|
||||
source: source, page: page, ref: ref, lang: lang);
|
||||
}
|
||||
|
||||
/***********/
|
||||
|
|
@ -48,38 +53,47 @@ Future<List<GetManga?>> getLatestUpdatesManga(GetLatestUpdatesMangaRef ref,
|
|||
/***********/
|
||||
|
||||
else if (getMangaTypeSource(source) == TypeSource.mmrcms) {
|
||||
latestUpdatesManga =
|
||||
await Mmrcms().getLatestUpdatesManga(source: source, page: page, ref: ref);
|
||||
latestUpdatesManga = await Mmrcms().getLatestUpdatesManga(
|
||||
source: source, page: page, ref: ref, lang: lang);
|
||||
}
|
||||
|
||||
/***********/
|
||||
/*mangahere*/
|
||||
/***********/
|
||||
else if (source == "mangahere") {
|
||||
latestUpdatesManga =
|
||||
await Mangahere().getLatestUpdatesManga(source: source, page: page, ref: ref);
|
||||
latestUpdatesManga = await Mangahere().getLatestUpdatesManga(
|
||||
source: source, page: page, ref: ref, lang: lang);
|
||||
}
|
||||
/***********/
|
||||
/*japscan*/
|
||||
/***********/
|
||||
else if (source == "japscan") {
|
||||
latestUpdatesManga =
|
||||
await Japscan().getLatestUpdatesManga(source: source, page: page, ref: ref);
|
||||
latestUpdatesManga = await Japscan().getLatestUpdatesManga(
|
||||
source: source, page: page, ref: ref, lang: lang);
|
||||
}
|
||||
|
||||
/***********/
|
||||
/*heancms*/
|
||||
/***********/
|
||||
else if (getMangaTypeSource(source) == TypeSource.heancms) {
|
||||
latestUpdatesManga =
|
||||
await HeanCms().getLatestUpdatesManga(source: source, page: page, ref: ref);
|
||||
latestUpdatesManga = await HeanCms().getLatestUpdatesManga(
|
||||
source: source, page: page, ref: ref, lang: lang);
|
||||
}
|
||||
|
||||
/***********/
|
||||
/*madara*/
|
||||
/***********/
|
||||
else if (getMangaTypeSource(source) == TypeSource.madara) {
|
||||
latestUpdatesManga =
|
||||
await Madara().getLatestUpdatesManga(source: source, page: page, ref: ref);
|
||||
latestUpdatesManga = await Madara().getLatestUpdatesManga(
|
||||
source: source, page: page, ref: ref, lang: lang);
|
||||
}
|
||||
|
||||
/***********/
|
||||
/*mangadex*/
|
||||
/***********/
|
||||
else if (getMangaTypeSource(source) == TypeSource.mangadex) {
|
||||
latestUpdatesManga = await MangaDex().getLatestUpdatesManga(
|
||||
source: source, page: page, ref: ref, lang: lang);
|
||||
}
|
||||
return latestUpdatesManga!;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ part of 'get_latest_updates_manga.dart';
|
|||
// **************************************************************************
|
||||
|
||||
String _$getLatestUpdatesMangaHash() =>
|
||||
r'2f6c7714feca588ada6c6dd98ad62849042e9bae';
|
||||
r'c5ddc8739ee5b7c085cdeede7c55743bfc7f5120';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
@ -46,10 +46,12 @@ class GetLatestUpdatesMangaFamily extends Family<AsyncValue<List<GetManga?>>> {
|
|||
GetLatestUpdatesMangaProvider call({
|
||||
required String source,
|
||||
required int page,
|
||||
required String lang,
|
||||
}) {
|
||||
return GetLatestUpdatesMangaProvider(
|
||||
source: source,
|
||||
page: page,
|
||||
lang: lang,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -60,6 +62,7 @@ class GetLatestUpdatesMangaFamily extends Family<AsyncValue<List<GetManga?>>> {
|
|||
return call(
|
||||
source: provider.source,
|
||||
page: provider.page,
|
||||
lang: provider.lang,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -85,11 +88,13 @@ class GetLatestUpdatesMangaProvider
|
|||
GetLatestUpdatesMangaProvider({
|
||||
required this.source,
|
||||
required this.page,
|
||||
required this.lang,
|
||||
}) : super.internal(
|
||||
(ref) => getLatestUpdatesManga(
|
||||
ref,
|
||||
source: source,
|
||||
page: page,
|
||||
lang: lang,
|
||||
),
|
||||
from: getLatestUpdatesMangaProvider,
|
||||
name: r'getLatestUpdatesMangaProvider',
|
||||
|
|
@ -104,12 +109,14 @@ class GetLatestUpdatesMangaProvider
|
|||
|
||||
final String source;
|
||||
final int page;
|
||||
final String lang;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is GetLatestUpdatesMangaProvider &&
|
||||
other.source == source &&
|
||||
other.page == page;
|
||||
other.page == page &&
|
||||
other.lang == lang;
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -117,6 +124,7 @@ class GetLatestUpdatesMangaProvider
|
|||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||
hash = _SystemHash.combine(hash, source.hashCode);
|
||||
hash = _SystemHash.combine(hash, page.hashCode);
|
||||
hash = _SystemHash.combine(hash, lang.hashCode);
|
||||
|
||||
return _SystemHash.finish(hash);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import 'package:mangayomi/sources/multisrc/heancms/heancms.dart';
|
|||
import 'package:mangayomi/sources/multisrc/madara/src/madara.dart';
|
||||
import 'package:mangayomi/sources/service.dart';
|
||||
import 'package:mangayomi/sources/src/all/comick/src/comick.dart';
|
||||
import 'package:mangayomi/sources/src/all/mangadex/src/mangadex.dart';
|
||||
import 'package:mangayomi/sources/src/en/mangahere/src/mangahere.dart';
|
||||
import 'package:mangayomi/sources/src/fr/japscan/src/japscan.dart';
|
||||
import 'package:mangayomi/sources/src/fr/mangakawaii/src/mangakawaii.dart';
|
||||
|
|
@ -87,5 +88,14 @@ Future<GetManga> getMangaDetail(GetMangaDetailRef ref,
|
|||
mangadetail = await Madara()
|
||||
.getMangaDetail(manga: manga, lang: lang, source: source, ref: ref);
|
||||
}
|
||||
|
||||
/***********/
|
||||
/*mangadex*/
|
||||
/***********/
|
||||
|
||||
else if (getMangaTypeSource(source.toLowerCase()) == TypeSource.mangadex) {
|
||||
mangadetail = await MangaDex()
|
||||
.getMangaDetail(manga: manga, lang: lang, source: source, ref: ref);
|
||||
}
|
||||
return mangadetail!;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'get_manga_detail.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$getMangaDetailHash() => r'ecad72288b8df330f295949d2b452b1bffa132a9';
|
||||
String _$getMangaDetailHash() => r'009422e0d88c595e2a8183e2360708ad2e13a955';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import 'package:mangayomi/sources/multisrc/heancms/heancms.dart';
|
|||
import 'package:mangayomi/sources/multisrc/madara/src/madara.dart';
|
||||
import 'package:mangayomi/sources/service.dart';
|
||||
import 'package:mangayomi/sources/src/all/comick/src/comick.dart';
|
||||
import 'package:mangayomi/sources/src/all/mangadex/src/mangadex.dart';
|
||||
import 'package:mangayomi/sources/src/en/mangahere/src/mangahere.dart';
|
||||
import 'package:mangayomi/sources/src/fr/japscan/src/japscan.dart';
|
||||
import 'package:mangayomi/sources/src/fr/mangakawaii/src/mangakawaii.dart';
|
||||
|
|
@ -15,7 +16,7 @@ part 'get_popular_manga.g.dart';
|
|||
|
||||
@riverpod
|
||||
Future<List<GetManga?>> getPopularManga(GetPopularMangaRef ref,
|
||||
{required String source, required int page}) async {
|
||||
{required String source, required int page, required String lang}) async {
|
||||
List<GetManga?>? popularManga;
|
||||
source = source.toLowerCase();
|
||||
|
||||
|
|
@ -23,8 +24,8 @@ Future<List<GetManga?>> getPopularManga(GetPopularMangaRef ref,
|
|||
/*comick*/
|
||||
/*******/
|
||||
if (getMangaTypeSource(source) == TypeSource.comick) {
|
||||
popularManga =
|
||||
await Comick().getPopularManga(source: source, page: page, ref: ref);
|
||||
popularManga = await Comick()
|
||||
.getPopularManga(source: source, page: page, ref: ref, lang: lang);
|
||||
}
|
||||
|
||||
/***************/
|
||||
|
|
@ -32,7 +33,7 @@ Future<List<GetManga?>> getPopularManga(GetPopularMangaRef ref,
|
|||
/**************/
|
||||
if (getMangaTypeSource(source) == TypeSource.mangathemesia) {
|
||||
popularManga = await MangaThemeSia()
|
||||
.getPopularManga(source: source, page: page, ref: ref);
|
||||
.getPopularManga(source: source, page: page, ref: ref, lang: lang);
|
||||
}
|
||||
|
||||
/***********/
|
||||
|
|
@ -40,7 +41,7 @@ Future<List<GetManga?>> getPopularManga(GetPopularMangaRef ref,
|
|||
/***********/
|
||||
if (source == "mangakawaii") {
|
||||
popularManga = await MangaKawaii()
|
||||
.getPopularManga(source: source, page: page, ref: ref);
|
||||
.getPopularManga(source: source, page: page, ref: ref, lang: lang);
|
||||
}
|
||||
|
||||
/***********/
|
||||
|
|
@ -48,38 +49,46 @@ Future<List<GetManga?>> getPopularManga(GetPopularMangaRef ref,
|
|||
/***********/
|
||||
|
||||
else if (getMangaTypeSource(source) == TypeSource.mmrcms) {
|
||||
popularManga =
|
||||
await Mmrcms().getPopularManga(source: source, page: page, ref: ref);
|
||||
popularManga = await Mmrcms()
|
||||
.getPopularManga(source: source, page: page, ref: ref, lang: lang);
|
||||
}
|
||||
|
||||
/***********/
|
||||
/*mangahere*/
|
||||
/***********/
|
||||
else if (source == "mangahere") {
|
||||
popularManga =
|
||||
await Mangahere().getPopularManga(source: source, page: page, ref: ref);
|
||||
popularManga = await Mangahere()
|
||||
.getPopularManga(source: source, page: page, ref: ref, lang: lang);
|
||||
}
|
||||
/***********/
|
||||
/*japscan*/
|
||||
/***********/
|
||||
else if (source == "japscan") {
|
||||
popularManga =
|
||||
await Japscan().getPopularManga(source: source, page: page, ref: ref);
|
||||
popularManga = await Japscan()
|
||||
.getPopularManga(source: source, page: page, ref: ref, lang: lang);
|
||||
}
|
||||
|
||||
/***********/
|
||||
/*heancms*/
|
||||
/***********/
|
||||
else if (getMangaTypeSource(source) == TypeSource.heancms) {
|
||||
popularManga =
|
||||
await HeanCms().getPopularManga(source: source, page: page, ref: ref);
|
||||
popularManga = await HeanCms()
|
||||
.getPopularManga(source: source, page: page, ref: ref, lang: lang);
|
||||
}
|
||||
/***********/
|
||||
/*madara*/
|
||||
/***********/
|
||||
else if (getMangaTypeSource(source) == TypeSource.madara) {
|
||||
popularManga =
|
||||
await Madara().getPopularManga(source: source, page: page, ref: ref);
|
||||
popularManga = await Madara()
|
||||
.getPopularManga(source: source, page: page, ref: ref, lang: lang);
|
||||
}
|
||||
|
||||
/***********/
|
||||
/*mangadex*/
|
||||
/***********/
|
||||
else if (getMangaTypeSource(source) == TypeSource.mangadex) {
|
||||
popularManga = await MangaDex()
|
||||
.getPopularManga(source: source, page: page, ref: ref, lang: lang);
|
||||
}
|
||||
return popularManga!;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'get_popular_manga.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$getPopularMangaHash() => r'e973741f7105e38032412a7ae160003565779463';
|
||||
String _$getPopularMangaHash() => r'4fe87d57b93957bbc848b9b814dd3c9aa94b89c5';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
@ -44,10 +44,12 @@ class GetPopularMangaFamily extends Family<AsyncValue<List<GetManga?>>> {
|
|||
GetPopularMangaProvider call({
|
||||
required String source,
|
||||
required int page,
|
||||
required String lang,
|
||||
}) {
|
||||
return GetPopularMangaProvider(
|
||||
source: source,
|
||||
page: page,
|
||||
lang: lang,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -58,6 +60,7 @@ class GetPopularMangaFamily extends Family<AsyncValue<List<GetManga?>>> {
|
|||
return call(
|
||||
source: provider.source,
|
||||
page: provider.page,
|
||||
lang: provider.lang,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -83,11 +86,13 @@ class GetPopularMangaProvider
|
|||
GetPopularMangaProvider({
|
||||
required this.source,
|
||||
required this.page,
|
||||
required this.lang,
|
||||
}) : super.internal(
|
||||
(ref) => getPopularManga(
|
||||
ref,
|
||||
source: source,
|
||||
page: page,
|
||||
lang: lang,
|
||||
),
|
||||
from: getPopularMangaProvider,
|
||||
name: r'getPopularMangaProvider',
|
||||
|
|
@ -102,12 +107,14 @@ class GetPopularMangaProvider
|
|||
|
||||
final String source;
|
||||
final int page;
|
||||
final String lang;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is GetPopularMangaProvider &&
|
||||
other.source == source &&
|
||||
other.page == page;
|
||||
other.page == page &&
|
||||
other.lang == lang;
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -115,6 +122,7 @@ class GetPopularMangaProvider
|
|||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||
hash = _SystemHash.combine(hash, source.hashCode);
|
||||
hash = _SystemHash.combine(hash, page.hashCode);
|
||||
hash = _SystemHash.combine(hash, lang.hashCode);
|
||||
|
||||
return _SystemHash.finish(hash);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ Future<dynamic> httpGet(HttpGetRef ref,
|
|||
{required String url,
|
||||
required String source,
|
||||
required bool resDom,
|
||||
Map<String, String>? headers,
|
||||
bool useUserAgent = false}) async {
|
||||
bool isCloudflaree = isCloudflare(source);
|
||||
if (resDom) {
|
||||
|
|
@ -22,7 +23,8 @@ Future<dynamic> httpGet(HttpGetRef ref,
|
|||
.future);
|
||||
} else {
|
||||
dom = await httpResToDom(
|
||||
url: url, headers: ref.watch(headersProvider(source: source)));
|
||||
url: url,
|
||||
headers: headers ?? ref.watch(headersProvider(source: source)));
|
||||
}
|
||||
return dom;
|
||||
} else {
|
||||
|
|
@ -34,7 +36,7 @@ Future<dynamic> httpGet(HttpGetRef ref,
|
|||
} else {
|
||||
try {
|
||||
final response = await http.get(Uri.parse(url),
|
||||
headers: ref.watch(headersProvider(source: source)));
|
||||
headers: headers ?? ref.watch(headersProvider(source: source)));
|
||||
resHtml = response.body;
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'http_service.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$httpGetHash() => r'57b50256bd7577a4d795cf74f9429d3a4434792f';
|
||||
String _$httpGetHash() => r'115d7fdde9392d32055ddefe661731c37b2b584e';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
@ -45,12 +45,14 @@ class HttpGetFamily extends Family<AsyncValue<dynamic>> {
|
|||
required String url,
|
||||
required String source,
|
||||
required bool resDom,
|
||||
Map<String, String>? headers,
|
||||
bool useUserAgent = false,
|
||||
}) {
|
||||
return HttpGetProvider(
|
||||
url: url,
|
||||
source: source,
|
||||
resDom: resDom,
|
||||
headers: headers,
|
||||
useUserAgent: useUserAgent,
|
||||
);
|
||||
}
|
||||
|
|
@ -63,6 +65,7 @@ class HttpGetFamily extends Family<AsyncValue<dynamic>> {
|
|||
url: provider.url,
|
||||
source: provider.source,
|
||||
resDom: provider.resDom,
|
||||
headers: provider.headers,
|
||||
useUserAgent: provider.useUserAgent,
|
||||
);
|
||||
}
|
||||
|
|
@ -89,6 +92,7 @@ class HttpGetProvider extends AutoDisposeFutureProvider<dynamic> {
|
|||
required this.url,
|
||||
required this.source,
|
||||
required this.resDom,
|
||||
this.headers,
|
||||
this.useUserAgent = false,
|
||||
}) : super.internal(
|
||||
(ref) => httpGet(
|
||||
|
|
@ -96,6 +100,7 @@ class HttpGetProvider extends AutoDisposeFutureProvider<dynamic> {
|
|||
url: url,
|
||||
source: source,
|
||||
resDom: resDom,
|
||||
headers: headers,
|
||||
useUserAgent: useUserAgent,
|
||||
),
|
||||
from: httpGetProvider,
|
||||
|
|
@ -111,6 +116,7 @@ class HttpGetProvider extends AutoDisposeFutureProvider<dynamic> {
|
|||
final String url;
|
||||
final String source;
|
||||
final bool resDom;
|
||||
final Map<String, String>? headers;
|
||||
final bool useUserAgent;
|
||||
|
||||
@override
|
||||
|
|
@ -119,6 +125,7 @@ class HttpGetProvider extends AutoDisposeFutureProvider<dynamic> {
|
|||
other.url == url &&
|
||||
other.source == source &&
|
||||
other.resDom == resDom &&
|
||||
other.headers == headers &&
|
||||
other.useUserAgent == useUserAgent;
|
||||
}
|
||||
|
||||
|
|
@ -128,6 +135,7 @@ class HttpGetProvider extends AutoDisposeFutureProvider<dynamic> {
|
|||
hash = _SystemHash.combine(hash, url.hashCode);
|
||||
hash = _SystemHash.combine(hash, source.hashCode);
|
||||
hash = _SystemHash.combine(hash, resDom.hashCode);
|
||||
hash = _SystemHash.combine(hash, headers.hashCode);
|
||||
hash = _SystemHash.combine(hash, useUserAgent.hashCode);
|
||||
|
||||
return _SystemHash.finish(hash);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import 'package:mangayomi/sources/multisrc/heancms/heancms.dart';
|
|||
import 'package:mangayomi/sources/multisrc/madara/src/madara.dart';
|
||||
import 'package:mangayomi/sources/service.dart';
|
||||
import 'package:mangayomi/sources/src/all/comick/src/comick.dart';
|
||||
import 'package:mangayomi/sources/src/all/mangadex/src/mangadex.dart';
|
||||
import 'package:mangayomi/sources/src/en/mangahere/src/mangahere.dart';
|
||||
import 'package:mangayomi/sources/src/fr/japscan/src/japscan.dart';
|
||||
import 'package:mangayomi/sources/src/fr/mangakawaii/src/mangakawaii.dart';
|
||||
|
|
@ -13,8 +14,12 @@ import 'package:riverpod_annotation/riverpod_annotation.dart';
|
|||
part 'search_manga.g.dart';
|
||||
|
||||
@riverpod
|
||||
Future<List<GetManga?>> searchManga(SearchMangaRef ref,
|
||||
{required String source, required String query}) async {
|
||||
Future<List<GetManga?>> searchManga(
|
||||
SearchMangaRef ref, {
|
||||
required String source,
|
||||
required String query,
|
||||
required String lang,
|
||||
}) async {
|
||||
List<GetManga?>? manga;
|
||||
source = source.toLowerCase();
|
||||
|
||||
|
|
@ -23,7 +28,8 @@ Future<List<GetManga?>> searchManga(SearchMangaRef ref,
|
|||
/********/
|
||||
|
||||
if (getMangaTypeSource(source) == TypeSource.comick) {
|
||||
manga = await Comick().searchManga(source: source, query: query, ref: ref);
|
||||
manga = await Comick()
|
||||
.searchManga(source: source, query: query, ref: ref, lang: lang);
|
||||
}
|
||||
|
||||
/***************/
|
||||
|
|
@ -32,7 +38,7 @@ Future<List<GetManga?>> searchManga(SearchMangaRef ref,
|
|||
|
||||
else if (getMangaTypeSource(source) == TypeSource.mangathemesia) {
|
||||
manga = await MangaThemeSia()
|
||||
.searchManga(source: source, query: query, ref: ref);
|
||||
.searchManga(source: source, query: query, ref: ref, lang: lang);
|
||||
}
|
||||
|
||||
/***********/
|
||||
|
|
@ -40,8 +46,8 @@ Future<List<GetManga?>> searchManga(SearchMangaRef ref,
|
|||
/***********/
|
||||
|
||||
else if (source == "mangakawaii") {
|
||||
manga =
|
||||
await MangaKawaii().searchManga(source: source, query: query, ref: ref);
|
||||
manga = await MangaKawaii()
|
||||
.searchManga(source: source, query: query, ref: ref, lang: lang);
|
||||
}
|
||||
|
||||
/***********/
|
||||
|
|
@ -49,7 +55,8 @@ Future<List<GetManga?>> searchManga(SearchMangaRef ref,
|
|||
/***********/
|
||||
|
||||
else if (getMangaTypeSource(source) == TypeSource.mmrcms) {
|
||||
manga = await Mmrcms().searchManga(source: source, query: query, ref: ref);
|
||||
manga = await Mmrcms()
|
||||
.searchManga(source: source, query: query, ref: ref, lang: lang);
|
||||
}
|
||||
|
||||
/***********/
|
||||
|
|
@ -57,8 +64,8 @@ Future<List<GetManga?>> searchManga(SearchMangaRef ref,
|
|||
/***********/
|
||||
|
||||
else if (source == "mangahere") {
|
||||
manga =
|
||||
await Mangahere().searchManga(source: source, query: query, ref: ref);
|
||||
manga = await Mangahere()
|
||||
.searchManga(source: source, query: query, ref: ref, lang: lang);
|
||||
}
|
||||
|
||||
/***********/
|
||||
|
|
@ -66,7 +73,8 @@ Future<List<GetManga?>> searchManga(SearchMangaRef ref,
|
|||
/***********/
|
||||
|
||||
else if (source == "japscan") {
|
||||
manga = await Japscan().searchManga(source: source, query: query, ref: ref);
|
||||
manga = await Japscan()
|
||||
.searchManga(source: source, query: query, ref: ref, lang: lang);
|
||||
}
|
||||
|
||||
/***********/
|
||||
|
|
@ -74,7 +82,8 @@ Future<List<GetManga?>> searchManga(SearchMangaRef ref,
|
|||
/***********/
|
||||
|
||||
else if (getMangaTypeSource(source) == TypeSource.heancms) {
|
||||
manga = await HeanCms().searchManga(source: source, query: query, ref: ref);
|
||||
manga = await HeanCms()
|
||||
.searchManga(source: source, query: query, ref: ref, lang: lang);
|
||||
}
|
||||
|
||||
/***********/
|
||||
|
|
@ -82,8 +91,17 @@ Future<List<GetManga?>> searchManga(SearchMangaRef ref,
|
|||
/***********/
|
||||
|
||||
else if (getMangaTypeSource(source) == TypeSource.madara) {
|
||||
manga = await Madara().searchManga(source: source, query: query, ref: ref);
|
||||
manga = await Madara()
|
||||
.searchManga(source: source, query: query, ref: ref, lang: lang);
|
||||
}
|
||||
|
||||
/***********/
|
||||
/*mangadex*/
|
||||
/***********/
|
||||
|
||||
else if (getMangaTypeSource(source) == TypeSource.mangadex) {
|
||||
manga = await MangaDex()
|
||||
.searchManga(source: source, query: query, ref: ref, lang: lang);
|
||||
}
|
||||
return manga!;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'search_manga.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$searchMangaHash() => r'5f2a70ca38af7448f546f70db81cbe55a79a5fba';
|
||||
String _$searchMangaHash() => r'0448881ce3785ac0c670a87914590008ae19fdd5';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
@ -44,10 +44,12 @@ class SearchMangaFamily extends Family<AsyncValue<List<GetManga?>>> {
|
|||
SearchMangaProvider call({
|
||||
required String source,
|
||||
required String query,
|
||||
required String lang,
|
||||
}) {
|
||||
return SearchMangaProvider(
|
||||
source: source,
|
||||
query: query,
|
||||
lang: lang,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -58,6 +60,7 @@ class SearchMangaFamily extends Family<AsyncValue<List<GetManga?>>> {
|
|||
return call(
|
||||
source: provider.source,
|
||||
query: provider.query,
|
||||
lang: provider.lang,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -82,11 +85,13 @@ class SearchMangaProvider extends AutoDisposeFutureProvider<List<GetManga?>> {
|
|||
SearchMangaProvider({
|
||||
required this.source,
|
||||
required this.query,
|
||||
required this.lang,
|
||||
}) : super.internal(
|
||||
(ref) => searchManga(
|
||||
ref,
|
||||
source: source,
|
||||
query: query,
|
||||
lang: lang,
|
||||
),
|
||||
from: searchMangaProvider,
|
||||
name: r'searchMangaProvider',
|
||||
|
|
@ -101,12 +106,14 @@ class SearchMangaProvider extends AutoDisposeFutureProvider<List<GetManga?>> {
|
|||
|
||||
final String source;
|
||||
final String query;
|
||||
final String lang;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is SearchMangaProvider &&
|
||||
other.source == source &&
|
||||
other.query == query;
|
||||
other.query == query &&
|
||||
other.lang == lang;
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -114,6 +121,7 @@ class SearchMangaProvider extends AutoDisposeFutureProvider<List<GetManga?>> {
|
|||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||
hash = _SystemHash.combine(hash, source.hashCode);
|
||||
hash = _SystemHash.combine(hash, query.hashCode);
|
||||
hash = _SystemHash.combine(hash, lang.hashCode);
|
||||
|
||||
return _SystemHash.finish(hash);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ class HeanCms extends MangaYomiServices {
|
|||
Future<List<GetManga>> getPopularManga(
|
||||
{required String source,
|
||||
required int page,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
var request = http.Request(
|
||||
'POST', Uri.parse('${getMangaAPIUrl(source)}series/querysearch'));
|
||||
|
|
@ -136,6 +137,7 @@ class HeanCms extends MangaYomiServices {
|
|||
Future<List<GetManga?>> searchManga(
|
||||
{required String source,
|
||||
required String query,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
var request = http.Request(
|
||||
'POST', Uri.parse('${getMangaAPIUrl(source)}series/search'));
|
||||
|
|
@ -172,6 +174,7 @@ class HeanCms extends MangaYomiServices {
|
|||
Future<List<GetManga?>> getLatestUpdatesManga(
|
||||
{required String source,
|
||||
required int page,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
var request = http.Request(
|
||||
'POST', Uri.parse('${getMangaAPIUrl(source)}series/querysearch'));
|
||||
|
|
|
|||
|
|
@ -208,6 +208,7 @@ class Madara extends MangaYomiServices {
|
|||
Future<List<GetManga?>> getPopularManga(
|
||||
{required String source,
|
||||
required int page,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
String? html;
|
||||
html = await ref.watch(httpGetProvider(
|
||||
|
|
@ -246,6 +247,7 @@ class Madara extends MangaYomiServices {
|
|||
Future<List<GetManga?>> searchManga(
|
||||
{required String source,
|
||||
required String query,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
final html = await ref.watch(httpGetProvider(
|
||||
url: '${getMangaBaseUrl(source)}/?s=$query&post_type=wp-manga',
|
||||
|
|
@ -263,6 +265,7 @@ class Madara extends MangaYomiServices {
|
|||
Future<List<GetManga?>> getLatestUpdatesManga(
|
||||
{required String source,
|
||||
required int page,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
String? html;
|
||||
html = await ref.watch(httpGetProvider(
|
||||
|
|
|
|||
|
|
@ -144,6 +144,7 @@ class MangaThemeSia extends MangaYomiServices {
|
|||
Future<List<GetManga?>> getPopularManga(
|
||||
{required String source,
|
||||
required int page,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
source = source.toLowerCase();
|
||||
final dom = await ref.watch(httpGetProvider(
|
||||
|
|
@ -194,6 +195,7 @@ class MangaThemeSia extends MangaYomiServices {
|
|||
Future<List<GetManga?>> searchManga(
|
||||
{required String source,
|
||||
required String query,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
final dom = await ref.watch(httpGetProvider(
|
||||
url: '${getMangaBaseUrl(source)}/?s=${query.trim()}',
|
||||
|
|
@ -282,6 +284,7 @@ class MangaThemeSia extends MangaYomiServices {
|
|||
Future<List<GetManga?>> getLatestUpdatesManga(
|
||||
{required String source,
|
||||
required int page,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
source = source.toLowerCase();
|
||||
final dom = await ref.watch(httpGetProvider(
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ class Mmrcms extends MangaYomiServices {
|
|||
Future<List<GetManga?>> getPopularManga(
|
||||
{required String source,
|
||||
required int page,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
final dom = await ref.watch(httpGetProvider(
|
||||
url:
|
||||
|
|
@ -138,6 +139,7 @@ class Mmrcms extends MangaYomiServices {
|
|||
Future<List<GetManga?>> searchManga(
|
||||
{required String source,
|
||||
required String query,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
final response = await ref.watch(httpGetProvider(
|
||||
url: '${getMangaBaseUrl(source)}/search?query=${query.trim()}',
|
||||
|
|
@ -197,6 +199,7 @@ class Mmrcms extends MangaYomiServices {
|
|||
Future<List<GetManga?>> getLatestUpdatesManga(
|
||||
{required String source,
|
||||
required int page,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
final dom = await ref.watch(httpGetProvider(
|
||||
url: '${getMangaBaseUrl(source)}/latest-release?page=$page',
|
||||
|
|
|
|||
|
|
@ -66,10 +66,12 @@ abstract class MangaYomiServices {
|
|||
Future<List<GetManga?>> getPopularManga(
|
||||
{required String source,
|
||||
required int page,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref});
|
||||
Future<List<GetManga?>> getLatestUpdatesManga(
|
||||
{required String source,
|
||||
required int page,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref});
|
||||
Future<GetManga?> getMangaDetail(
|
||||
{required GetManga manga,
|
||||
|
|
@ -81,6 +83,7 @@ abstract class MangaYomiServices {
|
|||
Future<List<GetManga?>> searchManga(
|
||||
{required String source,
|
||||
required String query,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/sources/multisrc/heancms/heancms_source_list.dart';
|
||||
import 'package:mangayomi/sources/src/all/comick/comick_source_list.dart';
|
||||
import 'package:mangayomi/sources/src/all/mangadex/mangadex_source_list.dart';
|
||||
import 'package:mangayomi/sources/src/en/mangahere/mangahere_source.dart';
|
||||
import 'package:mangayomi/sources/src/fr/japscan/japscan_source.dart';
|
||||
import 'package:mangayomi/sources/multisrc/mangathemesia/mangathemesia_source_list.dart';
|
||||
|
|
@ -16,5 +17,6 @@ List<Source> _sourcesList = [
|
|||
...mmrcmsSourcesList,
|
||||
japscanSource,
|
||||
...heanCmsSourcesList,
|
||||
...madaraSourcesList
|
||||
...madaraSourcesList,
|
||||
...mangaDexSourcesList
|
||||
];
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ class Comick extends MangaYomiServices {
|
|||
@override
|
||||
Future<List<GetManga?>> getPopularManga(
|
||||
{required String source,
|
||||
required String lang,
|
||||
required int page,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
source = source.toLowerCase();
|
||||
|
|
@ -100,6 +101,7 @@ class Comick extends MangaYomiServices {
|
|||
Future<List<GetManga?>> searchManga(
|
||||
{required String source,
|
||||
required String query,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
final response = await ref.watch(httpGetProvider(
|
||||
url:
|
||||
|
|
@ -141,11 +143,11 @@ class Comick extends MangaYomiServices {
|
|||
return pageUrls;
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
Future<List<GetManga?>> getLatestUpdatesManga(
|
||||
{required String source,
|
||||
required int page,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
source = source.toLowerCase();
|
||||
final response = await ref.watch(httpGetProvider(
|
||||
|
|
|
|||
179
lib/sources/src/all/mangadex/mangadex_source_list.dart
Normal file
179
lib/sources/src/all/mangadex/mangadex_source_list.dart
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
import 'package:mangayomi/models/source.dart';
|
||||
|
||||
const logoUrl = '';
|
||||
const apiUrl = 'https://api.mangadex.org';
|
||||
const baseUrl = 'https://mangadex.org';
|
||||
const isNsfw = true;
|
||||
List<Source> get mangaDexSourcesList => _mangaDexSourcesList;
|
||||
List<Source> _mangaDexSourcesList = [
|
||||
Source(
|
||||
sourceName: 'MangaDex',
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'en',
|
||||
typeSource: TypeSource.mangadex,
|
||||
logoUrl: logoUrl,
|
||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss+SSS",
|
||||
isNsfw: isNsfw,
|
||||
dateFormatLocale: 'en_Us'),
|
||||
Source(
|
||||
sourceName: 'MangaDex',
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'ar',
|
||||
typeSource: TypeSource.mangadex,
|
||||
logoUrl: logoUrl,
|
||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss+SSS",
|
||||
isNsfw: isNsfw,
|
||||
dateFormatLocale: 'en_Us'),
|
||||
Source(
|
||||
sourceName: 'MangaDex',
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'pt',
|
||||
typeSource: TypeSource.mangadex,
|
||||
logoUrl: logoUrl,
|
||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss+SSS",
|
||||
isNsfw: isNsfw,
|
||||
dateFormatLocale: 'en_Us'),
|
||||
Source(
|
||||
sourceName: 'MangaDex',
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'pt-br',
|
||||
typeSource: TypeSource.mangadex,
|
||||
logoUrl: logoUrl,
|
||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss+SSS",
|
||||
isNsfw: isNsfw,
|
||||
dateFormatLocale: 'en_Us'),
|
||||
Source(
|
||||
sourceName: 'MangaDex',
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'it',
|
||||
typeSource: TypeSource.mangadex,
|
||||
logoUrl: logoUrl,
|
||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss+SSS",
|
||||
isNsfw: isNsfw,
|
||||
dateFormatLocale: 'en_Us'),
|
||||
Source(
|
||||
sourceName: 'MangaDex',
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'ru',
|
||||
typeSource: TypeSource.mangadex,
|
||||
logoUrl: logoUrl,
|
||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss+SSS",
|
||||
isNsfw: isNsfw,
|
||||
dateFormatLocale: 'en_Us'),
|
||||
Source(
|
||||
sourceName: 'MangaDex',
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'es',
|
||||
typeSource: TypeSource.mangadex,
|
||||
logoUrl: logoUrl,
|
||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss+SSS",
|
||||
isNsfw: isNsfw,
|
||||
dateFormatLocale: 'en_Us'),
|
||||
Source(
|
||||
sourceName: 'MangaDex',
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'es-419',
|
||||
typeSource: TypeSource.mangadex,
|
||||
logoUrl: logoUrl,
|
||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss+SSS",
|
||||
isNsfw: isNsfw,
|
||||
dateFormatLocale: 'en_Us'),
|
||||
Source(
|
||||
sourceName: 'MangaDex',
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'id',
|
||||
typeSource: TypeSource.mangadex,
|
||||
logoUrl: logoUrl,
|
||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss+SSS",
|
||||
isNsfw: isNsfw,
|
||||
dateFormatLocale: 'en_Us'),
|
||||
Source(
|
||||
sourceName: 'MangaDex',
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'hi',
|
||||
typeSource: TypeSource.mangadex,
|
||||
logoUrl: logoUrl,
|
||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss+SSS",
|
||||
isNsfw: isNsfw,
|
||||
dateFormatLocale: 'en_Us'),
|
||||
Source(
|
||||
sourceName: 'MangaDex',
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'de',
|
||||
typeSource: TypeSource.mangadex,
|
||||
logoUrl: logoUrl,
|
||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss+SSS",
|
||||
isNsfw: isNsfw,
|
||||
dateFormatLocale: 'en_Us'),
|
||||
Source(
|
||||
sourceName: 'MangaDex',
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'ja',
|
||||
typeSource: TypeSource.mangadex,
|
||||
logoUrl: logoUrl,
|
||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss+SSS",
|
||||
isNsfw: isNsfw,
|
||||
dateFormatLocale: 'en_Us'),
|
||||
Source(
|
||||
sourceName: 'MangaDex',
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'tr',
|
||||
typeSource: TypeSource.mangadex,
|
||||
logoUrl: logoUrl,
|
||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss+SSS",
|
||||
isNsfw: isNsfw,
|
||||
dateFormatLocale: 'en_Us'),
|
||||
Source(
|
||||
sourceName: 'MangaDex',
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'pl',
|
||||
typeSource: TypeSource.mangadex,
|
||||
logoUrl: logoUrl,
|
||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss+SSS",
|
||||
isNsfw: isNsfw,
|
||||
dateFormatLocale: 'en_Us'),
|
||||
Source(
|
||||
sourceName: 'MangaDex',
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'zh',
|
||||
typeSource: TypeSource.mangadex,
|
||||
logoUrl: logoUrl,
|
||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss+SSS",
|
||||
isNsfw: isNsfw,
|
||||
dateFormatLocale: 'en_Us'),
|
||||
Source(
|
||||
sourceName: 'MangaDex',
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'zh-hk',
|
||||
typeSource: TypeSource.mangadex,
|
||||
logoUrl: logoUrl,
|
||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss+SSS",
|
||||
isNsfw: isNsfw,
|
||||
dateFormatLocale: 'en_Us'),
|
||||
Source(
|
||||
sourceName: 'MangaDex',
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'fr',
|
||||
typeSource: TypeSource.mangadex,
|
||||
logoUrl: logoUrl,
|
||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss+SSS",
|
||||
isNsfw: isNsfw,
|
||||
dateFormatLocale: 'en_Us'),
|
||||
];
|
||||
52
lib/sources/src/all/mangadex/model/aggregate.dart
Normal file
52
lib/sources/src/all/mangadex/model/aggregate.dart
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
|
||||
class Aggregate {
|
||||
String? result;
|
||||
Map<String, AggregateVolumes>? volumes;
|
||||
|
||||
Aggregate({this.result, this.volumes});
|
||||
|
||||
Aggregate.fromJson(Map<String, dynamic> json) {
|
||||
result = json['result'];
|
||||
if (json['volumes'] is List<dynamic>) {
|
||||
volumes = (json['volumes'] as List<dynamic>).asMap().map((key, value) =>
|
||||
MapEntry(key.toString(),
|
||||
AggregateVolumes.fromJson(value as Map<String, dynamic>)));
|
||||
} else {
|
||||
volumes = (json['volumes'] as Map<String, dynamic>?)?.map((key, value) =>
|
||||
MapEntry(
|
||||
key, AggregateVolumes.fromJson(value as Map<String, dynamic>)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AggregateVolumes {
|
||||
String? volume;
|
||||
String? count;
|
||||
Map<String, AggregateChapter>? chapters;
|
||||
|
||||
AggregateVolumes({this.volume, this.chapters, this.count});
|
||||
AggregateVolumes.fromJson(Map<String, dynamic> json) {
|
||||
volume = json['volume'];
|
||||
count = json['count'].toString();
|
||||
if (json['chapters'] is List<dynamic>) {
|
||||
chapters = (json['chapters'] as List<dynamic>).asMap().map((key, value) =>
|
||||
MapEntry(key.toString(),
|
||||
AggregateChapter.fromJson(value as Map<String, dynamic>)));
|
||||
} else {
|
||||
chapters = (json['chapters'] as Map<String, dynamic>?)?.map(
|
||||
(key, value) => MapEntry(
|
||||
key, AggregateChapter.fromJson(value as Map<String, dynamic>)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AggregateChapter {
|
||||
String? chapter;
|
||||
String? count;
|
||||
|
||||
AggregateChapter({this.chapter, this.count});
|
||||
AggregateChapter.fromJson(Map<String, dynamic> json) {
|
||||
chapter = json['chapter'];
|
||||
count = json['count'].toString();
|
||||
}
|
||||
}
|
||||
108
lib/sources/src/all/mangadex/model/chapter.dart
Normal file
108
lib/sources/src/all/mangadex/model/chapter.dart
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
class ChapterMDX {
|
||||
String? result;
|
||||
String? response;
|
||||
List<Data>? data;
|
||||
int? limit;
|
||||
int? offset;
|
||||
int? total;
|
||||
|
||||
ChapterMDX(
|
||||
{this.result,
|
||||
this.response,
|
||||
this.data,
|
||||
this.limit,
|
||||
this.offset,
|
||||
this.total});
|
||||
|
||||
ChapterMDX.fromJson(Map<String, dynamic> json) {
|
||||
result = json['result'];
|
||||
response = json['response'];
|
||||
if (json['data'] != null) {
|
||||
data = <Data>[];
|
||||
json['data'].forEach((v) {
|
||||
data!.add(Data.fromJson(v));
|
||||
});
|
||||
}
|
||||
limit = json['limit'];
|
||||
offset = json['offset'];
|
||||
total = json['total'];
|
||||
}
|
||||
}
|
||||
|
||||
class Data {
|
||||
String? id;
|
||||
String? type;
|
||||
Attributes? attributes;
|
||||
List<Relationships>? relationships;
|
||||
|
||||
Data({this.id, this.type, this.attributes, this.relationships});
|
||||
|
||||
Data.fromJson(Map<String, dynamic> json) {
|
||||
id = json['id'];
|
||||
type = json['type'];
|
||||
attributes = json['attributes'] != null
|
||||
? Attributes.fromJson(json['attributes'])
|
||||
: null;
|
||||
if (json['relationships'] != null) {
|
||||
relationships = <Relationships>[];
|
||||
json['relationships'].forEach((v) {
|
||||
relationships!.add(Relationships.fromJson(v));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Attributes {
|
||||
String? volume;
|
||||
String? chapter;
|
||||
String? title;
|
||||
String? translatedLanguage;
|
||||
|
||||
String? publishAt;
|
||||
String? readableAt;
|
||||
String? createdAt;
|
||||
String? updatedAt;
|
||||
int? pages;
|
||||
int? version;
|
||||
|
||||
Attributes(
|
||||
{this.volume,
|
||||
this.chapter,
|
||||
this.title,
|
||||
this.translatedLanguage,
|
||||
this.publishAt,
|
||||
this.readableAt,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.pages,
|
||||
this.version});
|
||||
|
||||
Attributes.fromJson(Map<String, dynamic> json) {
|
||||
volume = json['volume'];
|
||||
chapter = json['chapter'];
|
||||
title = json['title'];
|
||||
translatedLanguage = json['translatedLanguage'];
|
||||
|
||||
publishAt = json['publishAt'];
|
||||
readableAt = json['readableAt'];
|
||||
createdAt = json['createdAt'];
|
||||
updatedAt = json['updatedAt'];
|
||||
pages = json['pages'];
|
||||
version = json['version'];
|
||||
}
|
||||
}
|
||||
|
||||
class Relationships {
|
||||
String? id;
|
||||
String? type;
|
||||
|
||||
Relationships({
|
||||
this.id,
|
||||
this.type,
|
||||
});
|
||||
|
||||
Relationships.fromJson(Map<String, dynamic> json) {
|
||||
id = json['id'];
|
||||
type = json['type'];
|
||||
}
|
||||
}
|
||||
140
lib/sources/src/all/mangadex/model/cover.dart
Normal file
140
lib/sources/src/all/mangadex/model/cover.dart
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
class CoverAA {
|
||||
String? result;
|
||||
String? response;
|
||||
List<CoverData>? data;
|
||||
int? limit;
|
||||
int? offset;
|
||||
int? total;
|
||||
|
||||
CoverAA(
|
||||
{this.result,
|
||||
this.response,
|
||||
this.data,
|
||||
this.limit,
|
||||
this.offset,
|
||||
this.total});
|
||||
|
||||
CoverAA.fromJson(Map<String, dynamic> json) {
|
||||
result = json['result'];
|
||||
response = json['response'];
|
||||
if (json['data'] != null) {
|
||||
data = <CoverData>[];
|
||||
json['data'].forEach((v) {
|
||||
data!.add(CoverData.fromJson(v));
|
||||
});
|
||||
}
|
||||
limit = json['limit'];
|
||||
offset = json['offset'];
|
||||
total = json['total'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = <String, dynamic>{};
|
||||
data['result'] = result;
|
||||
data['response'] = response;
|
||||
if (this.data != null) {
|
||||
data['data'] = this.data!.map((v) => v.toJson()).toList();
|
||||
}
|
||||
data['limit'] = limit;
|
||||
data['offset'] = offset;
|
||||
data['total'] = total;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
class CoverData {
|
||||
String? id;
|
||||
String? type;
|
||||
Attributes? attributes;
|
||||
List<Relationships>? relationships;
|
||||
|
||||
CoverData({this.id, this.type, this.attributes, this.relationships});
|
||||
|
||||
CoverData.fromJson(Map<String, dynamic> json) {
|
||||
id = json['id'];
|
||||
type = json['type'];
|
||||
attributes = json['attributes'] != null
|
||||
? Attributes.fromJson(json['attributes'])
|
||||
: null;
|
||||
if (json['relationships'] != null) {
|
||||
relationships = <Relationships>[];
|
||||
json['relationships'].forEach((v) {
|
||||
relationships!.add(Relationships.fromJson(v));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = <String, dynamic>{};
|
||||
data['id'] = id;
|
||||
data['type'] = type;
|
||||
if (attributes != null) {
|
||||
data['attributes'] = attributes!.toJson();
|
||||
}
|
||||
if (relationships != null) {
|
||||
data['relationships'] =
|
||||
relationships!.map((v) => v.toJson()).toList();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
class Attributes {
|
||||
String? description;
|
||||
String? volume;
|
||||
String? fileName;
|
||||
String? locale;
|
||||
String? createdAt;
|
||||
String? updatedAt;
|
||||
int? version;
|
||||
|
||||
Attributes(
|
||||
{this.description,
|
||||
this.volume,
|
||||
this.fileName,
|
||||
this.locale,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.version});
|
||||
|
||||
Attributes.fromJson(Map<String, dynamic> json) {
|
||||
description = json['description'];
|
||||
volume = json['volume'];
|
||||
fileName = json['fileName'];
|
||||
locale = json['locale'];
|
||||
createdAt = json['createdAt'];
|
||||
updatedAt = json['updatedAt'];
|
||||
version = json['version'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = <String, dynamic>{};
|
||||
data['description'] = description;
|
||||
data['volume'] = volume;
|
||||
data['fileName'] = fileName;
|
||||
data['locale'] = locale;
|
||||
data['createdAt'] = createdAt;
|
||||
data['updatedAt'] = updatedAt;
|
||||
data['version'] = version;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
class Relationships {
|
||||
String? id;
|
||||
String? type;
|
||||
|
||||
Relationships({this.id, this.type});
|
||||
|
||||
Relationships.fromJson(Map<String, dynamic> json) {
|
||||
id = json['id'];
|
||||
type = json['type'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = <String, dynamic>{};
|
||||
data['id'] = id;
|
||||
data['type'] = type;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
28
lib/sources/src/all/mangadex/model/get_chapter_url.dart
Normal file
28
lib/sources/src/all/mangadex/model/get_chapter_url.dart
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
class GetChapterUrl {
|
||||
String? result;
|
||||
String? baseUrl;
|
||||
Chapter? chapter;
|
||||
|
||||
GetChapterUrl({this.result, this.baseUrl, this.chapter});
|
||||
|
||||
GetChapterUrl.fromJson(Map<String, dynamic> json) {
|
||||
result = json['result'];
|
||||
baseUrl = json['baseUrl'];
|
||||
chapter =
|
||||
json['chapter'] != null ? Chapter.fromJson(json['chapter']) : null;
|
||||
}
|
||||
}
|
||||
|
||||
class Chapter {
|
||||
String? hash;
|
||||
List<String>? data;
|
||||
List<String>? dataSaver;
|
||||
|
||||
Chapter({this.hash, this.data, this.dataSaver});
|
||||
|
||||
Chapter.fromJson(Map<String, dynamic> json) {
|
||||
hash = json['hash'];
|
||||
data = json['data'].cast<String>();
|
||||
dataSaver = json['dataSaver'].cast<String>();
|
||||
}
|
||||
}
|
||||
330
lib/sources/src/all/mangadex/model/manga.dart
Normal file
330
lib/sources/src/all/mangadex/model/manga.dart
Normal file
|
|
@ -0,0 +1,330 @@
|
|||
class MangaDexDto {
|
||||
String? result;
|
||||
String? response;
|
||||
List<Data>? data;
|
||||
int? limit;
|
||||
int? offset;
|
||||
int? total;
|
||||
|
||||
MangaDexDto(
|
||||
{this.result,
|
||||
this.response,
|
||||
this.data,
|
||||
this.limit,
|
||||
this.offset,
|
||||
this.total});
|
||||
|
||||
MangaDexDto.fromJson(Map<String, dynamic> json) {
|
||||
result = json['result'];
|
||||
response = json['response'];
|
||||
if (json['data'] != null) {
|
||||
data = <Data>[];
|
||||
json['data'].forEach((v) {
|
||||
data!.add(Data.fromJson(v));
|
||||
});
|
||||
}
|
||||
limit = json['limit'];
|
||||
offset = json['offset'];
|
||||
total = json['total'];
|
||||
}
|
||||
}
|
||||
|
||||
class Data {
|
||||
String? id;
|
||||
String? type;
|
||||
Attributes? attributes;
|
||||
List<Relationships>? relationships;
|
||||
|
||||
Data({this.id, this.type, this.attributes, this.relationships});
|
||||
|
||||
Data.fromJson(Map<String, dynamic> json) {
|
||||
id = json['id'];
|
||||
type = json['type'];
|
||||
attributes = json['attributes'] != null
|
||||
? Attributes.fromJson(json['attributes'])
|
||||
: null;
|
||||
if (json['relationships'] != null) {
|
||||
relationships = <Relationships>[];
|
||||
json['relationships'].forEach((v) {
|
||||
relationships!.add(Relationships.fromJson(v));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Attributes {
|
||||
Map<String, dynamic>? title;
|
||||
List<dynamic>? altTitles;
|
||||
Description? description;
|
||||
bool? isLocked;
|
||||
Links? links;
|
||||
String? originalLanguage;
|
||||
String? lastVolume;
|
||||
String? lastChapter;
|
||||
String? publicationDemographic;
|
||||
String? status;
|
||||
int? year;
|
||||
String? contentRating;
|
||||
List<Tags>? tags;
|
||||
String? state;
|
||||
bool? chapterNumbersResetOnNewVolume;
|
||||
String? createdAt;
|
||||
String? updatedAt;
|
||||
int? version;
|
||||
List<String>? availableTranslatedLanguages;
|
||||
String? latestUploadedChapter;
|
||||
|
||||
Attributes(
|
||||
{this.title,
|
||||
this.altTitles,
|
||||
this.description,
|
||||
this.isLocked,
|
||||
this.links,
|
||||
this.originalLanguage,
|
||||
this.lastVolume,
|
||||
this.lastChapter,
|
||||
this.publicationDemographic,
|
||||
this.status,
|
||||
this.year,
|
||||
this.contentRating,
|
||||
this.tags,
|
||||
this.state,
|
||||
this.chapterNumbersResetOnNewVolume,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.version,
|
||||
this.availableTranslatedLanguages,
|
||||
this.latestUploadedChapter});
|
||||
|
||||
Attributes.fromJson(Map<String, dynamic> json) {
|
||||
title = json['title'] as Map<String, dynamic>;
|
||||
if (json['altTitles'] != null) {
|
||||
altTitles = json['altTitles'];
|
||||
}
|
||||
description = json['description'] != null
|
||||
? Description.fromJson(json['description'])
|
||||
: null;
|
||||
isLocked = json['isLocked'];
|
||||
links = json['links'] != null ? Links.fromJson(json['links']) : null;
|
||||
originalLanguage = json['originalLanguage'];
|
||||
lastVolume = json['lastVolume'];
|
||||
lastChapter = json['lastChapter'];
|
||||
publicationDemographic = json['publicationDemographic'];
|
||||
status = json['status'];
|
||||
year = json['year'];
|
||||
contentRating = json['contentRating'];
|
||||
if (json['tags'] != null) {
|
||||
tags = <Tags>[];
|
||||
json['tags'].forEach((v) {
|
||||
tags!.add(Tags.fromJson(v));
|
||||
});
|
||||
}
|
||||
state = json['state'];
|
||||
chapterNumbersResetOnNewVolume = json['chapterNumbersResetOnNewVolume'];
|
||||
createdAt = json['createdAt'];
|
||||
updatedAt = json['updatedAt'];
|
||||
version = json['version'];
|
||||
availableTranslatedLanguages =
|
||||
json['availableTranslatedLanguages'].cast<String>();
|
||||
latestUploadedChapter = json['latestUploadedChapter'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
class Description {
|
||||
String? en;
|
||||
String? fr;
|
||||
String? pt;
|
||||
String? ptBr;
|
||||
String? zhHk;
|
||||
String? ru;
|
||||
String? es;
|
||||
String? ja;
|
||||
String? tr;
|
||||
String? uk;
|
||||
String? esLa;
|
||||
String? ko;
|
||||
String? de;
|
||||
String? id;
|
||||
String? it;
|
||||
String? pl;
|
||||
String? th;
|
||||
String? zh;
|
||||
String? cs;
|
||||
|
||||
Description(
|
||||
{this.en,
|
||||
this.fr,
|
||||
this.pt,
|
||||
this.ptBr,
|
||||
this.zhHk,
|
||||
this.ru,
|
||||
this.es,
|
||||
this.ja,
|
||||
this.tr,
|
||||
this.uk,
|
||||
this.esLa,
|
||||
this.ko,
|
||||
this.de,
|
||||
this.id,
|
||||
this.it,
|
||||
this.pl,
|
||||
this.th,
|
||||
this.zh,
|
||||
this.cs});
|
||||
|
||||
Description.fromJson(Map<String, dynamic> json) {
|
||||
en = json['en'];
|
||||
fr = json['fr'];
|
||||
pt = json['pt'];
|
||||
ptBr = json['pt-br'];
|
||||
zhHk = json['zh-hk'];
|
||||
ru = json['ru'];
|
||||
es = json['es'];
|
||||
ja = json['ja'];
|
||||
tr = json['tr'];
|
||||
uk = json['uk'];
|
||||
esLa = json['es-la'];
|
||||
ko = json['ko'];
|
||||
de = json['de'];
|
||||
id = json['id'];
|
||||
it = json['it'];
|
||||
pl = json['pl'];
|
||||
th = json['th'];
|
||||
zh = json['zh'];
|
||||
cs = json['cs'];
|
||||
}
|
||||
}
|
||||
|
||||
class Links {
|
||||
String? al;
|
||||
String? mu;
|
||||
String? amz;
|
||||
String? mal;
|
||||
String? engtl;
|
||||
String? kt;
|
||||
String? cdj;
|
||||
String? ebj;
|
||||
String? raw;
|
||||
String? ap;
|
||||
String? bw;
|
||||
String? nu;
|
||||
|
||||
Links(
|
||||
{this.al,
|
||||
this.mu,
|
||||
this.amz,
|
||||
this.mal,
|
||||
this.engtl,
|
||||
this.kt,
|
||||
this.cdj,
|
||||
this.ebj,
|
||||
this.raw,
|
||||
this.ap,
|
||||
this.bw,
|
||||
this.nu});
|
||||
|
||||
Links.fromJson(Map<String, dynamic> json) {
|
||||
al = json['al'];
|
||||
mu = json['mu'];
|
||||
amz = json['amz'];
|
||||
mal = json['mal'];
|
||||
engtl = json['engtl'];
|
||||
kt = json['kt'];
|
||||
cdj = json['cdj'];
|
||||
ebj = json['ebj'];
|
||||
raw = json['raw'];
|
||||
ap = json['ap'];
|
||||
bw = json['bw'];
|
||||
nu = json['nu'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = <String, dynamic>{};
|
||||
data['al'] = al;
|
||||
data['mu'] = mu;
|
||||
data['amz'] = amz;
|
||||
data['mal'] = mal;
|
||||
data['engtl'] = engtl;
|
||||
data['kt'] = kt;
|
||||
data['cdj'] = cdj;
|
||||
data['ebj'] = ebj;
|
||||
data['raw'] = raw;
|
||||
data['ap'] = ap;
|
||||
data['bw'] = bw;
|
||||
data['nu'] = nu;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
class Tags {
|
||||
TagAttributes? attributes;
|
||||
|
||||
Tags({
|
||||
this.attributes,
|
||||
});
|
||||
|
||||
Tags.fromJson(Map<String, dynamic> json) {
|
||||
attributes = json['attributes'] != null
|
||||
? TagAttributes.fromJson(json['attributes'])
|
||||
: null;
|
||||
}
|
||||
}
|
||||
|
||||
class TagAttributes {
|
||||
String? group;
|
||||
|
||||
TagAttributes({this.group});
|
||||
|
||||
TagAttributes.fromJson(Map<String, dynamic> json) {
|
||||
group = json['group'];
|
||||
}
|
||||
}
|
||||
|
||||
class Relationships {
|
||||
String? id;
|
||||
String? type;
|
||||
RAttributes? attributes;
|
||||
String? related;
|
||||
|
||||
Relationships({this.id, this.type, this.attributes, this.related});
|
||||
|
||||
Relationships.fromJson(Map<String, dynamic> json) {
|
||||
id = json['id'];
|
||||
type = json['type'];
|
||||
attributes = json['attributes'] != null
|
||||
? RAttributes.fromJson(json['attributes'])
|
||||
: null;
|
||||
related = json['related'];
|
||||
}
|
||||
}
|
||||
|
||||
class RAttributes {
|
||||
String? description;
|
||||
String? volume;
|
||||
String? fileName;
|
||||
String? locale;
|
||||
String? createdAt;
|
||||
String? updatedAt;
|
||||
int? version;
|
||||
|
||||
RAttributes(
|
||||
{this.description,
|
||||
this.volume,
|
||||
this.fileName,
|
||||
this.locale,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.version});
|
||||
|
||||
RAttributes.fromJson(Map<String, dynamic> json) {
|
||||
description = json['description'];
|
||||
volume = json['volume'];
|
||||
fileName = json['fileName'];
|
||||
locale = json['locale'];
|
||||
createdAt = json['createdAt'];
|
||||
updatedAt = json['updatedAt'];
|
||||
version = json['version'];
|
||||
}
|
||||
}
|
||||
209
lib/sources/src/all/mangadex/model/mdx_detail.dart
Normal file
209
lib/sources/src/all/mangadex/model/mdx_detail.dart
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
class MDXDetail {
|
||||
String? result;
|
||||
String? response;
|
||||
Dataa? data;
|
||||
|
||||
MDXDetail({this.result, this.response, this.data});
|
||||
|
||||
MDXDetail.fromJson(Map<String, dynamic> json) {
|
||||
result = json['result'];
|
||||
response = json['response'];
|
||||
data = json['data'] != null ? Dataa.fromJson(json['data']) : null;
|
||||
}
|
||||
}
|
||||
|
||||
class Dataa {
|
||||
String? id;
|
||||
String? type;
|
||||
Attributes? attributes;
|
||||
List<Relationships>? relationships;
|
||||
|
||||
Dataa({this.id, this.type, this.attributes, this.relationships});
|
||||
|
||||
Dataa.fromJson(Map<String, dynamic> json) {
|
||||
id = json['id'];
|
||||
type = json['type'];
|
||||
attributes = json['attributes'] != null
|
||||
? Attributes.fromJson(json['attributes'])
|
||||
: null;
|
||||
if (json['relationships'] != null) {
|
||||
relationships = <Relationships>[];
|
||||
json['relationships'].forEach((v) {
|
||||
relationships!.add(Relationships.fromJson(v));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Attributes {
|
||||
Title? title;
|
||||
|
||||
Map<String, dynamic>? description;
|
||||
bool? isLocked;
|
||||
String? originalLanguage;
|
||||
String? lastVolume;
|
||||
String? lastChapter;
|
||||
String? publicationDemographic;
|
||||
String? status;
|
||||
int? year;
|
||||
String? contentRating;
|
||||
List<Tags>? tags;
|
||||
String? state;
|
||||
bool? chapterNumbersResetOnNewVolume;
|
||||
String? createdAt;
|
||||
String? updatedAt;
|
||||
int? version;
|
||||
List<String>? availableTranslatedLanguages;
|
||||
String? latestUploadedChapter;
|
||||
|
||||
Attributes(
|
||||
{this.title,
|
||||
this.description,
|
||||
this.isLocked,
|
||||
this.originalLanguage,
|
||||
this.lastVolume,
|
||||
this.lastChapter,
|
||||
this.publicationDemographic,
|
||||
this.status,
|
||||
this.year,
|
||||
this.contentRating,
|
||||
this.tags,
|
||||
this.state,
|
||||
this.chapterNumbersResetOnNewVolume,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.version,
|
||||
this.availableTranslatedLanguages,
|
||||
this.latestUploadedChapter});
|
||||
|
||||
Attributes.fromJson(Map<String, dynamic> json) {
|
||||
title = json['title'] != null ? Title.fromJson(json['title']) : null;
|
||||
description = json['description'];
|
||||
isLocked = json['isLocked'];
|
||||
|
||||
originalLanguage = json['originalLanguage'];
|
||||
lastVolume = json['lastVolume'];
|
||||
lastChapter = json['lastChapter'];
|
||||
publicationDemographic = json['publicationDemographic'];
|
||||
status = json['status'];
|
||||
year = json['year'];
|
||||
contentRating = json['contentRating'];
|
||||
if (json['tags'] != null) {
|
||||
tags = <Tags>[];
|
||||
json['tags'].forEach((v) {
|
||||
tags!.add(Tags.fromJson(v));
|
||||
});
|
||||
}
|
||||
state = json['state'];
|
||||
chapterNumbersResetOnNewVolume = json['chapterNumbersResetOnNewVolume'];
|
||||
createdAt = json['createdAt'];
|
||||
updatedAt = json['updatedAt'];
|
||||
version = json['version'];
|
||||
availableTranslatedLanguages =
|
||||
json['availableTranslatedLanguages'].cast<String>();
|
||||
latestUploadedChapter = json['latestUploadedChapter'];
|
||||
}
|
||||
}
|
||||
|
||||
class Title {
|
||||
String? en;
|
||||
|
||||
Title({this.en});
|
||||
|
||||
Title.fromJson(Map<String, dynamic> json) {
|
||||
en = json['en'];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class Tags {
|
||||
String? id;
|
||||
String? type;
|
||||
TAttributes? attributes;
|
||||
|
||||
Tags({this.id, this.type, this.attributes});
|
||||
|
||||
Tags.fromJson(Map<String, dynamic> json) {
|
||||
id = json['id'];
|
||||
type = json['type'];
|
||||
attributes = json['attributes'] != null
|
||||
? TAttributes.fromJson(json['attributes'])
|
||||
: null;
|
||||
}
|
||||
}
|
||||
|
||||
class TAttributes {
|
||||
Title? name;
|
||||
Map<String, dynamic>? description;
|
||||
String? group;
|
||||
int? version;
|
||||
|
||||
TAttributes({this.name, this.description, this.group, this.version});
|
||||
|
||||
TAttributes.fromJson(Map<String, dynamic> json) {
|
||||
name = json['name'] != null ? Title.fromJson(json['name']) : null;
|
||||
description = json['description'];
|
||||
group = json['group'];
|
||||
version = json['version'];
|
||||
}
|
||||
}
|
||||
|
||||
class Relationships {
|
||||
String? id;
|
||||
String? type;
|
||||
RAttributes? attributes;
|
||||
String? related;
|
||||
|
||||
Relationships({this.id, this.type, this.attributes, this.related});
|
||||
|
||||
Relationships.fromJson(Map<String, dynamic> json) {
|
||||
id = json['id'];
|
||||
type = json['type'];
|
||||
attributes = json['attributes'] != null
|
||||
? RAttributes.fromJson(json['attributes'])
|
||||
: null;
|
||||
related = json['related'];
|
||||
}
|
||||
}
|
||||
|
||||
class RAttributes {
|
||||
String? name;
|
||||
Title? biography;
|
||||
String? twitter;
|
||||
|
||||
String? createdAt;
|
||||
String? updatedAt;
|
||||
int? version;
|
||||
String? description;
|
||||
String? volume;
|
||||
String? fileName;
|
||||
String? locale;
|
||||
|
||||
RAttributes(
|
||||
{this.name,
|
||||
this.biography,
|
||||
this.twitter,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.version,
|
||||
this.description,
|
||||
this.volume,
|
||||
this.fileName,
|
||||
this.locale});
|
||||
|
||||
RAttributes.fromJson(Map<String, dynamic> json) {
|
||||
name = json['name'];
|
||||
|
||||
biography =
|
||||
json['biography'] != null ? Title.fromJson(json['biography']) : null;
|
||||
twitter = json['twitter'];
|
||||
createdAt = json['createdAt'];
|
||||
updatedAt = json['updatedAt'];
|
||||
version = json['version'];
|
||||
description = json['description'];
|
||||
volume = json['volume'];
|
||||
fileName = json['fileName'];
|
||||
locale = json['locale'];
|
||||
}
|
||||
}
|
||||
299
lib/sources/src/all/mangadex/src/mangadex.dart
Normal file
299
lib/sources/src/all/mangadex/src/mangadex.dart
Normal file
|
|
@ -0,0 +1,299 @@
|
|||
import 'dart:convert';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/services/http_service/http_service.dart';
|
||||
import 'package:mangayomi/sources/service.dart';
|
||||
import 'package:mangayomi/sources/src/all/mangadex/model/chapter.dart' as mdx;
|
||||
import 'package:mangayomi/sources/src/all/mangadex/model/cover.dart';
|
||||
import 'package:mangayomi/sources/src/all/mangadex/model/aggregate.dart';
|
||||
import 'package:mangayomi/sources/src/all/mangadex/model/get_chapter_url.dart'
|
||||
as get_chap_url;
|
||||
import 'package:mangayomi/sources/src/all/mangadex/model/manga.dart'
|
||||
as manga_dx;
|
||||
import 'package:mangayomi/sources/src/all/mangadex/model/mdx_detail.dart'
|
||||
as mdx_detail;
|
||||
import 'package:mangayomi/sources/src/all/mangadex/src/utils/utils.dart';
|
||||
import 'package:mangayomi/sources/utils/utils.dart';
|
||||
|
||||
class MangaDex extends MangaYomiServices {
|
||||
@override
|
||||
Future<List<String>> getChapterUrl(
|
||||
{required Chapter chapter,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
String chapterId = chapter.url!.split('/').last;
|
||||
String source = chapter.manga.value!.source!;
|
||||
final response = await ref.watch(httpGetProvider(
|
||||
url: '${getMangaAPIUrl(source)}/at-home/server/$chapterId',
|
||||
source: source,
|
||||
resDom: false)
|
||||
.future) as String?;
|
||||
final result = jsonDecode(response!) as Map<String, dynamic>;
|
||||
final atHome = get_chap_url.GetChapterUrl.fromJson(result);
|
||||
final host = atHome.baseUrl;
|
||||
final hash = atHome.chapter!.hash!;
|
||||
List<String> pageSuffix = [];
|
||||
for (var data in atHome.chapter!.data!) {
|
||||
pageSuffix.add("/data/$hash/$data");
|
||||
}
|
||||
for (var url in pageSuffix) {
|
||||
pageUrls.add("$host$url");
|
||||
}
|
||||
|
||||
return pageUrls;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<GetManga?>> getLatestUpdatesManga(
|
||||
{required String source,
|
||||
required int page,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
final response = await ref.watch(httpGetProvider(
|
||||
url:
|
||||
'${getMangaAPIUrl(source)}/chapter?limit=20&offset=${(20 * (page - 1))}&translatedLanguage[]=$lang&includeFutureUpdates=0${getMDXContentRating()}&order[publishAt]=desc&includeFuturePublishAt=0&includeEmptyPages=0',
|
||||
source: source,
|
||||
resDom: false,
|
||||
).future) as String?;
|
||||
final result = jsonDecode(response!) as Map<String, dynamic>;
|
||||
final chapterList = mdx.ChapterMDX.fromJson(result);
|
||||
List<String> mangaIds = [];
|
||||
for (var element in chapterList.data!) {
|
||||
for (var el in element.relationships!) {
|
||||
mangaIds.add(el.id!);
|
||||
}
|
||||
}
|
||||
mangaIds = mangaIds.toSet().toList();
|
||||
String manga = "";
|
||||
for (var id in mangaIds) {
|
||||
manga = "$manga&ids[]=$id";
|
||||
}
|
||||
|
||||
final mangaResponse = await ref.watch(httpGetProvider(
|
||||
url:
|
||||
'${getMangaAPIUrl(source)}/manga?includes[]=cover_art&limit=${mangaIds.length}${getMDXContentRating()}$manga',
|
||||
source: source,
|
||||
resDom: false,
|
||||
).future) as String?;
|
||||
final res = jsonDecode(mangaResponse!) as Map<String, dynamic>;
|
||||
final resultt = manga_dx.MangaDexDto.fromJson(res);
|
||||
|
||||
final firstVolumeCovers =
|
||||
await fetchFirstVolumeCovers(resultt.data, source, ref);
|
||||
for (var da in resultt.data!) {
|
||||
url.add("/manga/${da.id}");
|
||||
name.add(findTitle(da.attributes!.altTitles, da.attributes!.title, lang));
|
||||
image.add(
|
||||
"https://uploads.mangadex.org/covers/${da.id}/${getFileName(da.id!, resultt.data, firstVolumeCovers)}");
|
||||
}
|
||||
return mangaRes();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<GetManga?> getMangaDetail(
|
||||
{required GetManga manga,
|
||||
required String lang,
|
||||
required String source,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
final response = await ref.watch(httpGetProvider(
|
||||
url:
|
||||
'${getMangaAPIUrl(source)}${manga.url}?includes[]=cover_art&includes[]=author&includes[]=artist',
|
||||
source: source,
|
||||
resDom: false,
|
||||
).future) as String?;
|
||||
final res = jsonDecode(response!) as Map<String, dynamic>;
|
||||
final result = mdx_detail.MDXDetail.fromJson(res);
|
||||
final aggregate = await fetchSimpleChapterList(result, lang, source, ref);
|
||||
|
||||
List<String> authors = [];
|
||||
for (var element in result.data!.relationships!) {
|
||||
if (element.attributes != null) {
|
||||
authors.add(element.attributes!.name ?? "");
|
||||
}
|
||||
}
|
||||
final attr = result.data!.attributes!;
|
||||
author = authors.join(", ");
|
||||
Map<String, dynamic>? descrip = attr.description;
|
||||
description = descrip![lang] ?? descrip["en"] ?? "";
|
||||
for (var element in attr.tags!) {
|
||||
if (element.attributes != null) {
|
||||
genre.add(element.attributes!.name!.en!);
|
||||
}
|
||||
}
|
||||
genre = [
|
||||
...genre,
|
||||
attr.publicationDemographic ?? "",
|
||||
attr.contentRating != null && attr.contentRating!.toLowerCase() != "safe"
|
||||
? "Content rating: ${attr.contentRating}"
|
||||
: ""
|
||||
].where((element) => element.isNotEmpty).toList();
|
||||
|
||||
status = getPublicationStatus(aggregate, attr);
|
||||
String mangaId = manga.url!.split('/').last;
|
||||
final paginatedChapterList =
|
||||
await paginatedChapterListRequest(mangaId, 0, ref, source, lang);
|
||||
final rres = jsonDecode(paginatedChapterList) as Map<String, dynamic>;
|
||||
final chapterListResponse = mdx.ChapterMDX.fromJson(rres);
|
||||
final chapterListResults = chapterListResponse.data;
|
||||
var limit = chapterListResponse.limit!;
|
||||
var offset = chapterListResponse.offset!;
|
||||
var hasMoreResults = (limit + offset) < chapterListResponse.total!;
|
||||
|
||||
while (hasMoreResults) {
|
||||
offset += limit;
|
||||
var newRequest =
|
||||
await paginatedChapterListRequest(mangaId, offset, ref, source, lang);
|
||||
final rres = jsonDecode(newRequest) as Map<String, dynamic>;
|
||||
var newChapterList = mdx.ChapterMDX.fromJson(rres);
|
||||
|
||||
chapterListResults!.addAll(newChapterList.data!);
|
||||
hasMoreResults = (limit + offset) < newChapterList.total!;
|
||||
}
|
||||
|
||||
for (var chapterData in chapterListResults!) {
|
||||
List<String> chapName = [];
|
||||
var chapAttr = chapterData.attributes!;
|
||||
if (chapAttr.volume != null && chapAttr.volume!.isNotEmpty) {
|
||||
chapName.add("Vol.${chapAttr.volume}");
|
||||
}
|
||||
if (chapAttr.chapter != null && chapAttr.chapter!.isNotEmpty) {
|
||||
chapName.add("Ch.${chapAttr.chapter}");
|
||||
}
|
||||
if (chapAttr.title != null && chapAttr.title!.isNotEmpty) {
|
||||
if (chapName.isNotEmpty) {
|
||||
chapName.add("-");
|
||||
}
|
||||
chapName.add(chapAttr.title!);
|
||||
}
|
||||
if (chapName.isEmpty) {
|
||||
chapName.add("Oneshot");
|
||||
}
|
||||
chapterUrl.add("/chapter/${chapterData.id}");
|
||||
chapterTitle.add(chapName.join(" "));
|
||||
chapterDate.add(parseDate(chapAttr.publishAt!, source));
|
||||
}
|
||||
|
||||
return mangadetailRes(manga: manga, source: source);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<GetManga?>> getPopularManga(
|
||||
{required String source,
|
||||
required int page,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
final response = await ref.watch(httpGetProvider(
|
||||
url:
|
||||
'${getMangaAPIUrl(source)}/manga?limit=20&offset=${(20 * (page - 1))}&availableTranslatedLanguage[]=$lang&includes[]=cover_art${getMDXContentRating()}&order[followedCount]=desc',
|
||||
source: source,
|
||||
resDom: false,
|
||||
).future) as String?;
|
||||
final res = jsonDecode(response!) as Map<String, dynamic>;
|
||||
final result = manga_dx.MangaDexDto.fromJson(res);
|
||||
|
||||
final firstVolumeCovers =
|
||||
await fetchFirstVolumeCovers(result.data, source, ref);
|
||||
for (var da in result.data!) {
|
||||
url.add("/manga/${da.id}");
|
||||
name.add(findTitle(da.attributes!.altTitles, da.attributes!.title, lang));
|
||||
image.add(
|
||||
"https://uploads.mangadex.org/covers/${da.id}/${getFileName(da.id!, result.data, firstVolumeCovers)}");
|
||||
}
|
||||
|
||||
return mangaRes();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<GetManga?>> searchManga(
|
||||
{required String source,
|
||||
required String query,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
final response = await ref.watch(httpGetProvider(
|
||||
url:
|
||||
'${getMangaAPIUrl(source)}/manga?includes[]=cover_art&offset=0&limit=20&title=${query.toLowerCase().trim()}${getMDXContentRating()}&order[followedCount]=desc&availableTranslatedLanguage[]=$lang',
|
||||
source: source,
|
||||
resDom: false,
|
||||
).future) as String?;
|
||||
final res = jsonDecode(response!) as Map<String, dynamic>;
|
||||
final resultt = manga_dx.MangaDexDto.fromJson(res);
|
||||
final firstVolumeCovers =
|
||||
await fetchFirstVolumeCovers(resultt.data, source, ref);
|
||||
for (var da in resultt.data!) {
|
||||
url.add("/manga/${da.id}");
|
||||
name.add(findTitle(da.attributes!.altTitles, da.attributes!.title, lang));
|
||||
image.add(
|
||||
"https://uploads.mangadex.org/covers/${da.id}/${getFileName(da.id!, resultt.data, firstVolumeCovers)}");
|
||||
}
|
||||
|
||||
return mangaRes();
|
||||
}
|
||||
|
||||
Future<List<CoverData>?> fetchFirstVolumeCovers(List<manga_dx.Data>? data,
|
||||
String source, AutoDisposeFutureProviderRef ref) async {
|
||||
List<String> mangaIds = [];
|
||||
List<String> locales = [];
|
||||
for (var element in data!) {
|
||||
final attributes = element.attributes;
|
||||
if (attributes!.originalLanguage != null &&
|
||||
attributes.originalLanguage!.isNotEmpty) {
|
||||
mangaIds.add(element.id!);
|
||||
locales.add(attributes.originalLanguage!);
|
||||
}
|
||||
}
|
||||
|
||||
int limit = (mangaIds.length * locales.length);
|
||||
if (limit > 100) {
|
||||
limit = 100;
|
||||
}
|
||||
String manga = "";
|
||||
for (var id in mangaIds) {
|
||||
manga = "$manga&manga[]=$id";
|
||||
}
|
||||
String locale = "";
|
||||
for (var loc in locales.toSet()) {
|
||||
locale = "$locale&locales[]=$loc";
|
||||
}
|
||||
final response = await ref.watch(httpGetProvider(
|
||||
url:
|
||||
'${getMangaAPIUrl(source)}/cover?order[volume]=asc&limit=$limit&offset=0$manga$locale',
|
||||
source: source,
|
||||
resDom: false,
|
||||
).future) as String?;
|
||||
|
||||
final res = jsonDecode(response!) as Map<String, dynamic>;
|
||||
|
||||
final result = CoverAA.fromJson(res).data;
|
||||
result!.sort(
|
||||
(a, b) => a.relationships!.firstOrNull!.id!
|
||||
.compareTo(b.relationships!.firstOrNull!.id!),
|
||||
);
|
||||
|
||||
return result.where((element) {
|
||||
return mangaIds.contains(element.relationships!.first.id);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
Future<Aggregate>? fetchSimpleChapterList(mdx_detail.MDXDetail? data,
|
||||
String lang, String source, AutoDisposeFutureProviderRef ref) async {
|
||||
final response = await ref.watch(httpGetProvider(
|
||||
url:
|
||||
'${getMangaAPIUrl(source)}/manga/${data!.data!.id}/aggregate?translatedLanguage[]=$lang',
|
||||
source: source,
|
||||
resDom: false,
|
||||
).future) as String?;
|
||||
final res = jsonDecode(response!) as Map<String, dynamic>;
|
||||
|
||||
return Aggregate.fromJson(res);
|
||||
}
|
||||
|
||||
Future<String> paginatedChapterListRequest(String mangaId, int offset,
|
||||
AutoDisposeFutureProviderRef ref, String source, String lang) async {
|
||||
final response = await ref.watch(httpGetProvider(
|
||||
url:
|
||||
'${getMangaAPIUrl(source)}/manga/$mangaId/feed?limit=500&offset=$offset&includes[]=user&includes[]=scanlation_group&order[volume]=desc&order[chapter]=desc&translatedLanguage[]=$lang&includeFuturePublishAt=0&includeEmptyPages=0&contentRating[]=safe&contentRating[]=suggestive&contentRating[]=erotica&contentRating[]=pornographic',
|
||||
source: source,
|
||||
resDom: false,
|
||||
).future) as String?;
|
||||
return response!;
|
||||
}
|
||||
}
|
||||
89
lib/sources/src/all/mangadex/src/utils/utils.dart
Normal file
89
lib/sources/src/all/mangadex/src/utils/utils.dart
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/sources/src/all/mangadex/model/aggregate.dart';
|
||||
import 'package:mangayomi/sources/src/all/mangadex/model/cover.dart';
|
||||
import 'package:mangayomi/sources/src/all/mangadex/model/manga.dart';
|
||||
import 'package:mangayomi/sources/src/all/mangadex/model/mdx_detail.dart'
|
||||
as mdx_detail;
|
||||
|
||||
String getMDXContentRating() {
|
||||
List<String> contentRating = [
|
||||
"suggestive",
|
||||
"safe",
|
||||
"erotica",
|
||||
"pornographic"
|
||||
];
|
||||
String ctnRating = "";
|
||||
for (var rating in contentRating) {
|
||||
ctnRating = "$ctnRating&contentRating[]=$rating";
|
||||
}
|
||||
return ctnRating;
|
||||
}
|
||||
|
||||
findTitle(
|
||||
List<dynamic>? altTitles, Map<String, dynamic>? enTitle, String lang) {
|
||||
final altTitle = altTitles!
|
||||
.where((element) =>
|
||||
element[lang].toString().isNotEmpty ||
|
||||
element["en"].toString().isNotEmpty)
|
||||
.toList();
|
||||
String? altTitless = altTitle.isNotEmpty
|
||||
? altTitle.firstOrNull[lang] ?? altTitle.firstOrNull["en"]
|
||||
: null;
|
||||
return enTitle!.values.firstOrNull ?? altTitless ?? "";
|
||||
}
|
||||
|
||||
getFileName(String id, List<Data>? data, List<CoverData>? firstVolumeCovers) {
|
||||
final mangaMap =
|
||||
data!.asMap().map((key, value) => MapEntry(value.id, value.attributes));
|
||||
final firstVolumeCoversF = firstVolumeCovers!
|
||||
.where((element) =>
|
||||
element.attributes!.locale == mangaMap[id]!.originalLanguage!)
|
||||
.where((element) =>
|
||||
element.attributes!.fileName != null &&
|
||||
element.attributes!.fileName!.isNotEmpty)
|
||||
.toList()
|
||||
.asMap()
|
||||
.map((key, value) =>
|
||||
MapEntry(value.relationships!.first.id, value.attributes!.fileName));
|
||||
|
||||
final datas = data
|
||||
.where((element) => element.id == id)
|
||||
.toList()
|
||||
.firstOrNull!
|
||||
.relationships!
|
||||
.firstOrNull!
|
||||
.attributes;
|
||||
return firstVolumeCoversF.isNotEmpty
|
||||
? firstVolumeCoversF[id]
|
||||
: datas != null
|
||||
? datas.fileName
|
||||
: "";
|
||||
}
|
||||
|
||||
Status getPublicationStatus(Aggregate? aggregate, mdx_detail.Attributes attr) {
|
||||
List<String> chaptersList = [];
|
||||
for (var element in aggregate!.volumes!.values) {
|
||||
for (var elem in element.chapters!.values) {
|
||||
chaptersList.add(elem.chapter!);
|
||||
}
|
||||
}
|
||||
var tempStatus = switch (attr.status) {
|
||||
"ongoing" => Status.ongoing,
|
||||
"cancelled" => Status.canceled,
|
||||
"completed" => Status.publishingFinished,
|
||||
"hiatus" => Status.onHiatus,
|
||||
_ => Status.unknown,
|
||||
};
|
||||
var publishedOrCancelled =
|
||||
tempStatus == Status.publishingFinished || tempStatus == Status.canceled;
|
||||
var isOneShot = attr.tags!.any((element) => element.id == tagOneShotUuid) &&
|
||||
attr.tags!.where((element) => (element.id == tagAnthologyUuid)).isEmpty;
|
||||
return chaptersList.contains(attr.lastChapter) && publishedOrCancelled
|
||||
? Status.completed
|
||||
: isOneShot
|
||||
? Status.completed
|
||||
: tempStatus;
|
||||
}
|
||||
|
||||
const tagAnthologyUuid = "51d83883-4103-437c-b4b1-731cb73d786c";
|
||||
const tagOneShotUuid = "0234a31e-a729-4e28-9d6a-3f87c4966b9e";
|
||||
|
|
@ -118,6 +118,7 @@ class Mangahere extends MangaYomiServices {
|
|||
Future<List<GetManga?>> getPopularManga(
|
||||
{required String source,
|
||||
required int page,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
final dom = await ref.watch(httpGetProvider(
|
||||
url: '${getMangaBaseUrl(source)}/directory/$page.htm',
|
||||
|
|
@ -151,6 +152,7 @@ class Mangahere extends MangaYomiServices {
|
|||
Future<List<GetManga?>> searchManga(
|
||||
{required String source,
|
||||
required String query,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
final dom = await ref.watch(httpGetProvider(
|
||||
url:
|
||||
|
|
@ -307,6 +309,7 @@ class Mangahere extends MangaYomiServices {
|
|||
Future<List<GetManga?>> getLatestUpdatesManga(
|
||||
{required String source,
|
||||
required int page,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
final dom = await ref.watch(httpGetProvider(
|
||||
url: '${getMangaBaseUrl(source)}/directory/$page.htm?latest',
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ class Japscan extends MangaYomiServices {
|
|||
Future<List<GetManga?>> getPopularManga(
|
||||
{required String source,
|
||||
required int page,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
final dom = await ref.watch(httpGetProvider(
|
||||
url: "${getMangaBaseUrl(source)}/", source: source, resDom: true)
|
||||
|
|
@ -145,6 +146,7 @@ class Japscan extends MangaYomiServices {
|
|||
Future<List<GetManga?>> searchManga(
|
||||
{required String source,
|
||||
required String query,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
final dom = await ref.watch(httpGetProvider(
|
||||
url:
|
||||
|
|
@ -262,6 +264,7 @@ class Japscan extends MangaYomiServices {
|
|||
Future<List<GetManga?>> getLatestUpdatesManga(
|
||||
{required String source,
|
||||
required int page,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
final dom = await ref.watch(httpGetProvider(
|
||||
url: "${getMangaBaseUrl(source)}/", source: source, resDom: true)
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ class MangaKawaii extends MangaYomiServices {
|
|||
Future<List<GetManga?>> getPopularManga(
|
||||
{required String source,
|
||||
required int page,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
final dom = await ref.watch(httpGetProvider(
|
||||
url: 'https://www.mangakawaii.io/', source: source, resDom: true)
|
||||
|
|
@ -143,7 +144,7 @@ class MangaKawaii extends MangaYomiServices {
|
|||
.toList();
|
||||
for (var ur in url) {
|
||||
image.add(
|
||||
"https://cdn.mangakawaii.pics/uploads$ur/cover/cover_250x350.jpg");
|
||||
"https://cdn.mangakawaii.pics/uploads$ur/cover/cover_250x350.jpg");
|
||||
}
|
||||
}
|
||||
return mangaRes();
|
||||
|
|
@ -152,7 +153,7 @@ class MangaKawaii extends MangaYomiServices {
|
|||
@override
|
||||
Future<List<GetManga?>> searchManga(
|
||||
{required String source,
|
||||
required String query,
|
||||
required String query, required String lang,
|
||||
required AutoDisposeFutureProviderRef ref}) async {
|
||||
final dom = await ref.watch(httpGetProvider(
|
||||
url:
|
||||
|
|
@ -218,6 +219,7 @@ class MangaKawaii extends MangaYomiServices {
|
|||
Future<List<GetManga?>> getLatestUpdatesManga(
|
||||
{required String source,
|
||||
required int page,
|
||||
required String lang,
|
||||
required AutoDisposeFutureProviderRef ref}) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,17 @@ String getMangaAPIUrl(String source) {
|
|||
return url;
|
||||
}
|
||||
|
||||
String getMangaLang(String source) {
|
||||
|
||||
String lang = "";
|
||||
for (var i = 0; i < sourcesList.length; i++) {
|
||||
if (sourcesList[i].sourceName!.toLowerCase() == source.toLowerCase()) {
|
||||
lang = sourcesList[i].lang!;
|
||||
}
|
||||
}
|
||||
return lang;
|
||||
}
|
||||
|
||||
TypeSource getMangaTypeSource(String source) {
|
||||
TypeSource? typeSource;
|
||||
for (var i = 0; i < sourcesList.length; i++) {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ String getMangaStatusName(Status status) {
|
|||
Status.onHiatus => "On hiatus",
|
||||
Status.canceled => "Canceled",
|
||||
Status.completed => "Completed",
|
||||
Status.publishingFinished => "Publishing finished",
|
||||
_ => "Unknown",
|
||||
};
|
||||
}
|
||||
|
|
@ -19,7 +20,8 @@ IconData getMangaStatusIcon(Status status) {
|
|||
Status.ongoing => Icons.schedule_rounded,
|
||||
Status.onHiatus => Icons.pause_circle_rounded,
|
||||
Status.canceled => Icons.cancel_rounded,
|
||||
Status.completed => Icons.done_all_rounded,
|
||||
Status.completed => Icons.done,
|
||||
Status.publishingFinished => Icons.done,
|
||||
_ => Icons.block_outlined,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,23 +14,29 @@ Map<String, String> headers(HeadersRef ref, {String source = ""}) {
|
|||
final baseUrl = getMangaBaseUrl(source);
|
||||
return getMangaTypeSource(source) == TypeSource.madara
|
||||
? {"Referer": "$baseUrl/"}
|
||||
: switch (source) {
|
||||
"mangakawaii" => {
|
||||
'Referer': '$baseUrl/',
|
||||
'User-Agent': userAgent,
|
||||
'Accept-Language': 'fr'
|
||||
},
|
||||
"mangahere" => {"Referer": "$baseUrl/", "Cookie": "isAdult=1"},
|
||||
"japscan" => {
|
||||
'User-Agent': userAgent,
|
||||
'Referer': "$baseUrl/",
|
||||
"Cookie": cookie
|
||||
},
|
||||
"sushiscan" => {
|
||||
'User-Agent': userAgent,
|
||||
'Referer': "$baseUrl/",
|
||||
"Cookie": cookie
|
||||
},
|
||||
_ => {},
|
||||
};
|
||||
: getMangaTypeSource(source) == TypeSource.mangadex ||
|
||||
getMangaTypeSource(source) == TypeSource.comick
|
||||
? {
|
||||
"Referer": "$baseUrl/",
|
||||
'User-Agent': "Tachiyomi $userAgent",
|
||||
}
|
||||
: switch (source) {
|
||||
"mangakawaii" => {
|
||||
'Referer': '$baseUrl/',
|
||||
'User-Agent': userAgent,
|
||||
'Accept-Language': 'fr'
|
||||
},
|
||||
"mangahere" => {"Referer": "$baseUrl/", "Cookie": "isAdult=1"},
|
||||
"japscan" => {
|
||||
'User-Agent': userAgent,
|
||||
'Referer': "$baseUrl/",
|
||||
"Cookie": cookie
|
||||
},
|
||||
"sushiscan" => {
|
||||
'User-Agent': userAgent,
|
||||
'Referer': "$baseUrl/",
|
||||
"Cookie": cookie
|
||||
},
|
||||
_ => {},
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'headers.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$headersHash() => r'b25fd0415020bf0585f8ecad168689935188bfad';
|
||||
String _$headersHash() => r'77be1cf7504cf673ff5da1646a367e2d21f2893a';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
Loading…
Reference in a new issue